1(* ========================================================================= *)
2(*                                                                           *)
3(*                Elementary Topology in Euclidean Space (R^1)               *)
4(*                                                                           *)
5(*        (c) Copyright, John Harrison 1998-2015                             *)
6(*        (c) Copyright, Valentina Bruno 2010                                *)
7(*        (c) Copyright, Marco Maggesi 2014-2015                             *)
8(*        (c) Copyright 2015,                                                *)
9(*                       Muhammad Qasim,                                     *)
10(*                       Osman Hasan,                                        *)
11(*                       Hardware Verification Group,                        *)
12(*                       Concordia University                                *)
13(*            Contact:  <m_qasi@ece.concordia.ca>                            *)
14(*                                                                           *)
15(*    Note: This theory was ported from HOL Light                            *)
16(*                                                                           *)
17(* ========================================================================= *)
18
19open HolKernel Parse boolLib bossLib;
20
21open numTheory numLib unwindLib tautLib Arith prim_recTheory RealArith
22     combinTheory quotientTheory arithmeticTheory realTheory
23     jrhUtils pairTheory boolTheory pred_setTheory optionTheory
24     sumTheory InductiveDefinition ind_typeTheory listTheory mesonLib
25     seqTheory limTheory transcTheory realLib topologyTheory metricTheory;
26
27open wellorderTheory cardinalTheory iterateTheory productTheory hurdUtils;
28
29val _ = new_theory "real_topology";
30
31fun MESON ths tm = prove(tm,MESON_TAC ths);
32fun METIS ths tm = prove(tm,METIS_TAC ths);
33
34val DISC_RW_KILL = DISCH_TAC THEN ONCE_ASM_REWRITE_TAC [] THEN
35                   POP_ASSUM K_TAC;
36
37fun ASSERT_TAC tm = SUBGOAL_THEN tm STRIP_ASSUME_TAC;
38
39val ASM_ARITH_TAC = REPEAT (POP_ASSUM MP_TAC) THEN ARITH_TAC;
40val ASM_REAL_ARITH_TAC = REAL_ASM_ARITH_TAC;
41
42(* Minimal hol-light compatibility layer *)
43val IMP_CONJ      = CONJ_EQ_IMP;     (* cardinalTheory *)
44val FINITE_SUBSET = SUBSET_FINITE_I; (* pred_setTheory *)
45val LE_0          = ZERO_LESS_EQ;    (* arithmeticTheory *)
46
47(* ------------------------------------------------------------------------- *)
48(* Pairwise property over sets and lists.                                    *)
49(* ------------------------------------------------------------------------- *)
50
51val pairwise = new_definition ("pairwise",
52  ``pairwise r s <=> !x y. x IN s /\ y IN s /\ ~(x = y) ==> r x y``);
53
54val PAIRWISE_EMPTY = store_thm ("PAIRWISE_EMPTY",
55 ``!r. pairwise r {} <=> T``,
56  REWRITE_TAC[pairwise, NOT_IN_EMPTY] THEN MESON_TAC[]);
57
58val PAIRWISE_SING = store_thm ("PAIRWISE_SING",
59 ``!r x. pairwise r {x} <=> T``,
60  REWRITE_TAC[pairwise, IN_SING] THEN MESON_TAC[]);
61
62val PAIRWISE_MONO = store_thm ("PAIRWISE_MONO",
63 ``!r s t. pairwise r s /\ t SUBSET s ==> pairwise r t``,
64  REWRITE_TAC[pairwise] THEN SET_TAC[]);
65
66val PAIRWISE_INSERT = store_thm ("PAIRWISE_INSERT",
67 ``!r x s.
68        pairwise r (x INSERT s) <=>
69        (!y. y IN s /\ ~(y = x) ==> r x y /\ r y x) /\
70        pairwise r s``,
71  REWRITE_TAC[pairwise, IN_INSERT] THEN MESON_TAC[]);
72
73val PAIRWISE_IMAGE = store_thm ("PAIRWISE_IMAGE",
74 ``!r f. pairwise r (IMAGE f s) <=>
75         pairwise (\x y. ~(f x = f y) ==> r (f x) (f y)) s``,
76  REWRITE_TAC[pairwise, IN_IMAGE] THEN MESON_TAC[]);
77
78(* ------------------------------------------------------------------------- *)
79(* Permutes                                                                  *)
80(* ------------------------------------------------------------------------- *)
81
82val _ = set_fixity "permutes" (Infix(NONASSOC, 450));
83
84(* This is different with pred_setTheory.PERMUTES *)
85val permutes = new_definition ("permutes",
86 ``p permutes s <=> (!x. ~(x IN s) ==> (p(x) = x)) /\ (!y. ?!x. (p x = y))``);
87
88val PERMUTES_IMAGE = store_thm ("PERMUTES_IMAGE",
89 ``!p s. p permutes s ==> (IMAGE p s = s)``,
90  REWRITE_TAC[permutes, EXTENSION, IN_IMAGE] THEN MESON_TAC[]);
91
92val PERMUTES_INJECTIVE = store_thm ("PERMUTES_INJECTIVE",
93 ``!p s. p permutes s ==> !x y. (p(x) = p(y)) <=> (x = y)``,
94  REWRITE_TAC[permutes] THEN MESON_TAC[]);
95
96val EXISTS_IN_INSERT = store_thm ("EXISTS_IN_INSERT",
97 ``!P a s. (?x. x IN (a INSERT s) /\ P x) <=> P a \/ ?x. x IN s /\ P x``,
98  REWRITE_TAC[IN_INSERT] THEN MESON_TAC[]);
99
100val DEPENDENT_CHOICE_FIXED = store_thm ("DEPENDENT_CHOICE_FIXED",
101 ``!P R a:'a. P 0 a /\ (!n x. P n x ==> ?y. P (SUC n) y /\ R n x y) ==>
102          ?f. (f 0 = a) /\ (!n. P n (f n)) /\ (!n. R n (f n) (f(SUC n)))``,
103  REPEAT STRIP_TAC THEN KNOW_TAC ``(?f. (f 0 = (a:'a)) /\
104    (!n. f(SUC n) = (@y. P (SUC n) y /\ R n (f n) y)))`` THENL
105  [RW_TAC std_ss [num_Axiom], ALL_TAC] THEN
106  STRIP_TAC THEN EXISTS_TAC ``f:num->'a`` THEN ASM_REWRITE_TAC [] THEN
107  ONCE_REWRITE_TAC[METIS [] ``(!n. P n (f n)) = (!n. (\n. P n (f n)) n)``] THEN
108  GEN_REWR_TAC LAND_CONV
109   [MESON[num_CASES] ``(!n. P n) <=> P 0 /\ !n. P(SUC n)``] THEN
110  ASM_SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN INDUCT_TAC THEN METIS_TAC[]);
111
112val DEPENDENT_CHOICE = store_thm ("DEPENDENT_CHOICE",
113 ``!P R:num->'a->'a->bool. (?a. P 0 a) /\
114   (!n x. P n x ==> ?y. P (SUC n) y /\ R n x y) ==>
115   ?f. (!n. P n (f n)) /\ (!n. R n (f n) (f(SUC n)))``,
116  MESON_TAC[DEPENDENT_CHOICE_FIXED]);
117
118val BIGUNION_MONO_IMAGE = store_thm ("BIGUNION_MONO_IMAGE",
119 ``(!x. x IN s ==> f x SUBSET g x) ==>
120    BIGUNION(IMAGE f s) SUBSET BIGUNION(IMAGE g s)``,
121  SET_TAC[]);
122(** proof without SET_TAC
123    RW_TAC std_ss [SUBSET_DEF, IN_BIGUNION_IMAGE]
124 >> rename1 `y IN s`
125 >> Q.EXISTS_TAC `y` >> ASM_REWRITE_TAC []
126 >> FIRST_X_ASSUM irule
127 >> ASM_REWRITE_TAC []
128 *)
129
130val BIGUNION_MONO = store_thm ("BIGUNION_MONO",
131 ``(!x. x IN s ==> ?y. y IN t /\ x SUBSET y) ==> BIGUNION s SUBSET BIGUNION t``,
132  SET_TAC[]);
133(** proof without SET_TAC
134    rpt STRIP_TAC
135 >> RW_TAC std_ss [SUBSET_DEF, IN_BIGUNION]
136 >> rename1 `x IN y`
137 >> Q.PAT_X_ASSUM `!x. x IN s ==> P` (MP_TAC o (Q.SPEC `y`))
138 >> RW_TAC std_ss [SUBSET_DEF]
139 >> rename1 `z IN t`
140 >> Q.EXISTS_TAC `z` >> ASM_REWRITE_TAC []
141 >> POP_ASSUM MATCH_MP_TAC
142 >> ASM_REWRITE_TAC []
143 *)
144
145(* unused lemma
146val th =
147  REWRITE_RULE[IN_UNIV]
148    (ISPECL [``f:'a->'b``, ``UNIV:'a->bool``] INJECTIVE_ON_LEFT_INVERSE);
149 *)
150
151(* ------------------------------------------------------------------------- *)
152(* Metric function for R^1.                                                  *)
153(* ------------------------------------------------------------------------- *)
154
155(* new definition based on metricTheory *)
156Definition dist_def :
157    Dist = dist mr1
158End
159
160(* old definition (now becomes a theorem) *)
161Theorem dist :
162    !x y. Dist(x:real,y:real) = abs(x - y)
163Proof
164    RW_TAC std_ss [dist_def, MR1_DEF]
165 >> REAL_ARITH_TAC
166QED
167
168val _ = overload_on ("dist",``Dist``);
169
170val DIST_REFL = store_thm ("DIST_REFL",
171 ``!x. dist(x,x) = &0``,
172  SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
173
174val DIST_SYM = store_thm ("DIST_SYM",
175 ``!x y. dist(x,y) = dist(y,x)``,
176  SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
177
178val DIST_TRIANGLE = store_thm ("DIST_TRIANGLE",
179 ``!x:real y z. dist(x,z) <= dist(x,y) + dist(y,z)``,
180  SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
181
182val DIST_TRIANGLE_ALT = store_thm ("DIST_TRIANGLE_ALT",
183 ``!x y z. dist(y,z) <= dist(x,y) + dist(x,z)``,
184  SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
185
186val DIST_EQ_0 = store_thm ("DIST_EQ_0",
187 ``!x y. (dist(x,y) = 0:real) <=> (x = y)``,
188  SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
189
190val DIST_POS_LT = store_thm ("DIST_POS_LT",
191 ``!x y. ~(x = y) ==> &0 < dist(x,y)``,
192  SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
193
194val DIST_NZ = store_thm ("DIST_NZ",
195 ``!x y. ~(x = y) <=> &0 < dist(x,y)``,
196  SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
197
198val DIST_TRIANGLE_LE = store_thm ("DIST_TRIANGLE_LE",
199 ``!x y z e. dist(x,z) + dist(y,z) <= e ==> dist(x,y) <= e``,
200  SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
201
202val DIST_TRIANGLE_LT = store_thm ("DIST_TRIANGLE_LT",
203 ``!x y z e. dist(x,z) + dist(y,z) < e ==> dist(x,y) < e``,
204  SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
205
206val DIST_TRIANGLE_HALF_L = store_thm ("DIST_TRIANGLE_HALF_L",
207 ``!x1 x2 y. dist(x1,y) < e / &2 /\ dist(x2,y) < e / &2 ==> dist(x1,x2) < e``,
208  REPEAT STRIP_TAC THEN KNOW_TAC `` dist (x1,y) + dist (x2,y) < e`` THENL
209  [METIS_TAC [REAL_LT_ADD2, REAL_HALF_DOUBLE],
210   DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
211   EXISTS_TAC ``dist (x1,y) + dist (x2,y)`` THEN
212   METIS_TAC [DIST_TRIANGLE, DIST_SYM]]);
213
214val DIST_TRIANGLE_HALF_R = store_thm ("DIST_TRIANGLE_HALF_R",
215 ``!x1 x2 y. dist(y,x1) < e / &2 /\ dist(y,x2) < e / &2 ==> dist(x1,x2) < e``,
216  REPEAT STRIP_TAC THEN KNOW_TAC `` dist (y, x1) + dist (y, x2) < e`` THENL
217  [METIS_TAC [REAL_LT_ADD2, REAL_HALF_DOUBLE],
218   DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
219   EXISTS_TAC ``dist (y, x1) + dist (y, x2)`` THEN
220   METIS_TAC [DIST_TRIANGLE, DIST_SYM]]);
221
222val DIST_TRIANGLE_ADD = store_thm ("DIST_TRIANGLE_ADD",
223 ``!x x' y y'. dist(x + y,x' + y') <= dist(x,x') + dist(y,y')``,
224  SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
225
226val DIST_MUL = store_thm ("DIST_MUL",
227 ``!x y c. dist(c * x,c * y) = abs(c) * dist(x,y)``,
228  REWRITE_TAC[dist, GSYM ABS_MUL] THEN REAL_ARITH_TAC);
229
230val DIST_TRIANGLE_ADD_HALF = store_thm ("DIST_TRIANGLE_ADD_HALF",
231 ``!x x' y y':real.
232    dist(x,x') < e / &2 /\ dist(y,y') < e / &2 ==> dist(x + y,x' + y') < e``,
233  REPEAT STRIP_TAC THEN KNOW_TAC `` dist (x, x') + dist (y, y') < e`` THENL
234  [METIS_TAC [REAL_LT_ADD2, REAL_HALF_DOUBLE],
235   DISCH_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
236   EXISTS_TAC ``dist (x, x') + dist (y, y')`` THEN
237   METIS_TAC [DIST_TRIANGLE_ADD, DIST_SYM]]);
238
239val DIST_LE_0 = store_thm ("DIST_LE_0",
240 ``!x y. dist(x,y) <= &0 <=> (x = y)``,
241  SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
242
243val DIST_POS_LE = store_thm ("DIST_POS_LE",
244 ``!x y. &0 <= dist(x,y)``,
245  METIS_TAC [DIST_EQ_0, DIST_NZ, REAL_LE_LT]);
246
247val DIST_EQ = store_thm ("DIST_EQ",
248 ``!w x y z. (dist(w,x) = dist(y,z)) <=> (dist(w,x) pow 2 = dist(y,z) pow 2)``,
249  REPEAT GEN_TAC THEN EQ_TAC THENL [RW_TAC std_ss [],
250  DISCH_TAC THEN MATCH_MP_TAC POW_EQ THEN EXISTS_TAC ``1:num`` THEN
251  RW_TAC arith_ss [DIST_POS_LE]]);
252
253val DIST_0 = store_thm ("DIST_0",
254 ``!x. (dist(x,0) = abs(x)) /\ (dist(0,x) = abs(x))``,
255  RW_TAC arith_ss [dist, REAL_SUB_RZERO, REAL_SUB_LZERO, ABS_NEG]);
256
257val REAL_CHOOSE_DIST = store_thm ("REAL_CHOOSE_DIST",
258 ``!x e. &0 <= e ==> (?y. dist (x,y) = e)``,
259  REPEAT STRIP_TAC THEN EXISTS_TAC ``x - e:real`` THEN
260  ASM_REWRITE_TAC [dist, REAL_SUB_SUB2, ABS_REFL]);
261
262(* ------------------------------------------------------------------------- *)
263(* Linear functions.                                                         *)
264(* ------------------------------------------------------------------------- *)
265
266val linear = new_definition ("linear",
267  ``linear (f:real->real) <=>
268        (!x y. f(x + y) = f(x) + f(y)) /\
269        (!c x. f(c * x) = c * f(x))``);
270
271val LINEAR_SCALING = store_thm ("LINEAR_SCALING",
272 ``!c. linear(\x:real. c * x)``,
273 SIMP_TAC std_ss [linear] THEN REAL_ARITH_TAC);
274
275val LINEAR_COMPOSE_CMUL = store_thm ("LINEAR_COMPOSE_CMUL",
276 ``!f c. linear f ==> linear (\x. c * f(x))``,
277  SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC);
278
279val LINEAR_COMPOSE_NEG = store_thm ("LINEAR_COMPOSE_NEG",
280 ``!f. linear f ==> linear (\x. -(f(x)))``,
281  SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC);
282
283val LINEAR_COMPOSE_ADD = store_thm ("LINEAR_COMPOSE_ADD",
284 ``!f g. linear f /\ linear g ==> linear (\x. f(x) + g(x))``,
285  SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC);
286
287val LINEAR_COMPOSE_SUB = store_thm ("LINEAR_COMPOSE_SUB",
288 ``!f g. linear f /\ linear g ==> linear (\x. f(x) - g(x))``,
289  SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC);
290
291val LINEAR_COMPOSE = store_thm ("LINEAR_COMPOSE",
292 ``!f g. linear f /\ linear g ==> linear (g o f)``,
293  SIMP_TAC std_ss [linear, o_THM]);
294
295val LINEAR_ID = store_thm ("LINEAR_ID",
296 ``linear (\x. x)``,
297  SIMP_TAC std_ss [linear]);
298
299val LINEAR_ZERO = store_thm ("LINEAR_ZERO",
300 ``linear (\x. 0)``,
301  SIMP_TAC std_ss [linear] THEN CONJ_TAC THEN REAL_ARITH_TAC);
302
303val LINEAR_NEGATION = store_thm ("LINEAR_NEGATION",
304 ``linear (\x. -x)``,
305  SIMP_TAC std_ss [linear] THEN REAL_ARITH_TAC);
306
307val LINEAR_COMPOSE_SUM = store_thm ("LINEAR_COMPOSE_SUM",
308 ``!f s. FINITE s /\ (!a. a IN s ==> linear(f a))
309         ==> linear(\x. sum s (\a. f a x))``,
310  GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN GEN_TAC THEN
311  KNOW_TAC
312    ``((!a. a IN s ==> linear (f a)) ==> linear (\x. sum s (\a. f a x))) =
313     (\s. (!a. a IN s ==> linear (f a)) ==> linear (\x. sum s (\a. f a x))) s``
314  THENL [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
315  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
316  SIMP_TAC std_ss [SUM_CLAUSES, LINEAR_ZERO] THEN REPEAT STRIP_TAC THEN
317  KNOW_TAC ``(linear (\x. f e x + sum s (\a. f a x))) =
318              linear (\x. (\x. f e x) x + (\x. sum s (\a. f a x)) x)`` THENL
319  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
320  MATCH_MP_TAC LINEAR_COMPOSE_ADD THEN METIS_TAC [IN_INSERT]);
321
322val LINEAR_MUL_COMPONENT = store_thm ("LINEAR_MUL_COMPONENT",
323 ``!f:real->real v.
324     linear f ==> linear (\x. f(x) * v)``,
325  SIMP_TAC std_ss [linear] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC);
326
327val LINEAR_0 = store_thm ("LINEAR_0",
328 ``!f. linear f ==> (f(0) = 0)``,
329  METIS_TAC [REAL_MUL_LZERO, linear]);
330
331val LINEAR_CMUL = store_thm ("LINEAR_CMUL",
332 ``!f c x. linear f ==> (f(c * x) = c * f(x))``,
333  SIMP_TAC std_ss [linear]);
334
335val LINEAR_NEG = store_thm ("LINEAR_NEG",
336 ``!f x. linear f ==> (f(-x) = -(f x))``,
337  ONCE_REWRITE_TAC[REAL_NEG_MINUS1] THEN SIMP_TAC std_ss [LINEAR_CMUL]);
338
339val LINEAR_ADD = store_thm ("LINEAR_ADD",
340 ``!f x y. linear f ==> (f(x + y) = f(x) + f(y))``,
341  SIMP_TAC std_ss [linear]);
342
343val LINEAR_SUB = store_thm ("LINEAR_SUB",
344 ``!f x y. linear f ==> (f(x - y) = f(x) - f(y))``,
345  SIMP_TAC std_ss [real_sub, LINEAR_ADD, LINEAR_NEG]);
346
347val LINEAR_SUM = store_thm ("LINEAR_SUM",
348 ``!f g s. linear f /\ FINITE s ==> (f(sum s g) = sum s (f o g))``,
349  GEN_TAC THEN GEN_TAC THEN SIMP_TAC std_ss [GSYM AND_IMP_INTRO, RIGHT_FORALL_IMP_THM] THEN
350  DISCH_TAC THEN GEN_TAC THEN
351  KNOW_TAC ``(f (sum s g) = sum s (f o g)) =
352          (\s. (f (sum s g) = sum s (f o g))) s`` THENL
353  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
354  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
355  SIMP_TAC std_ss [SUM_CLAUSES] THEN FIRST_ASSUM(fn th =>
356    SIMP_TAC std_ss [MATCH_MP LINEAR_0 th, MATCH_MP LINEAR_ADD th, o_THM]));
357
358val LINEAR_SUM_MUL = store_thm ("LINEAR_SUM_MUL",
359 ``!f s c v.
360        linear f /\ FINITE s
361        ==> (f(sum s (\i. c i * v i)) = sum s (\i. c(i) * f(v i)))``,
362  SIMP_TAC std_ss [LINEAR_SUM, o_DEF, LINEAR_CMUL]);
363
364val lemma = prove (
365 ``x = sum (1:num..1:num) (\i. x * &i)``,
366  REWRITE_TAC [SUM_SING_NUMSEG] THEN BETA_TAC THEN REAL_ARITH_TAC);
367
368val LINEAR_BOUNDED = store_thm ("LINEAR_BOUNDED",
369 ``!f:real->real. linear f ==> ?B. !x. abs(f x) <= B * abs(x)``,
370  REPEAT STRIP_TAC THEN EXISTS_TAC
371   ``sum(1:num..1:num) (\i. abs((f:real->real)(&i)))`` THEN
372  GEN_TAC THEN
373  GEN_REWR_TAC (LAND_CONV o funpow 2 RAND_CONV) [lemma] THEN
374  ASM_SIMP_TAC std_ss [LINEAR_SUM, FINITE_NUMSEG] THEN
375  ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM SUM_LMUL] THEN
376  MATCH_MP_TAC SUM_ABS_LE THEN REWRITE_TAC [FINITE_NUMSEG, IN_NUMSEG] THEN
377  BETA_TAC THEN ONCE_REWRITE_TAC [REAL_MUL_COMM] THEN
378  ASM_SIMP_TAC std_ss [o_DEF, ABS_MUL, LINEAR_CMUL] THEN
379  METIS_TAC [REAL_LE_RMUL, ABS_POS, REAL_LE_LT, REAL_MUL_COMM]);
380
381val LINEAR_BOUNDED_POS = store_thm ("LINEAR_BOUNDED_POS",
382 ``!f:real->real. linear f ==> ?B. &0 < B /\ !x. abs(f x) <= B * abs(x)``,
383  REPEAT STRIP_TAC THEN
384  FIRST_ASSUM(X_CHOOSE_TAC ``B:real`` o MATCH_MP LINEAR_BOUNDED) THEN
385  EXISTS_TAC ``abs(B) + &1:real`` THEN CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN
386  GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x:real`) THEN
387  MATCH_MP_TAC(REAL_ARITH ``a <= b ==> x <= a ==> x <= b:real``) THEN
388  MATCH_MP_TAC REAL_LE_RMUL_IMP THEN REWRITE_TAC[ABS_POS] THEN
389  REAL_ARITH_TAC);
390
391val SYMMETRIC_LINEAR_IMAGE = store_thm ("SYMMETRIC_LINEAR_IMAGE",
392 ``!f s. (!x. x IN s ==> -x IN s) /\ linear f
393          ==> !x. x IN (IMAGE f s) ==> -x IN (IMAGE f s)``,
394  SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN
395  SIMP_TAC std_ss [GSYM LINEAR_NEG] THEN SET_TAC[]);
396
397(* ------------------------------------------------------------------------- *)
398(* Bilinear functions.                                                       *)
399(* ------------------------------------------------------------------------- *)
400
401val bilinear = new_definition ("bilinear",
402  ``bilinear f <=> (!x. linear(\y. f x y)) /\ (!y. linear(\x. f x y))``);
403
404val BILINEAR_SWAP = store_thm ("BILINEAR_SWAP",
405 ``!op:real->real->real.
406        bilinear(\x y. op y x) <=> bilinear op``,
407  SIMP_TAC std_ss [bilinear, ETA_AX] THEN METIS_TAC[]);
408
409val BILINEAR_LADD = store_thm ("BILINEAR_LADD",
410 ``!h x y z. bilinear h ==> (h (x + y) z = (h x z) + (h y z))``,
411  SIMP_TAC std_ss [bilinear, linear]);
412
413val BILINEAR_RADD = store_thm ("BILINEAR_RADD",
414 ``!h x y z. bilinear h ==> (h x (y + z) = (h x y) + (h x z))``,
415  SIMP_TAC std_ss [bilinear, linear]);
416
417val BILINEAR_LMUL = store_thm ("BILINEAR_LMUL",
418 ``!h c x y. bilinear h ==> (h (c * x) y = c * (h x y))``,
419  SIMP_TAC std_ss [bilinear, linear]);
420
421val BILINEAR_RMUL = store_thm ("BILINEAR_RMUL",
422 ``!h c x y. bilinear h ==> (h x (c * y) = c * (h x y))``,
423  SIMP_TAC std_ss [bilinear, linear]);
424
425val BILINEAR_LNEG = store_thm ("BILINEAR_LNEG",
426 ``!h x y. bilinear h ==> (h (-x) y = -(h x y))``,
427  ONCE_REWRITE_TAC[REAL_NEG_MINUS1] THEN SIMP_TAC std_ss [BILINEAR_LMUL]);
428
429val BILINEAR_RNEG = store_thm ("BILINEAR_RNEG",
430 ``!h x y. bilinear h ==> (h x (-y) = -(h x y))``,
431  ONCE_REWRITE_TAC[REAL_NEG_MINUS1] THEN SIMP_TAC std_ss [BILINEAR_RMUL]);
432
433val BILINEAR_LZERO = store_thm ("BILINEAR_LZERO",
434 ``!h x. bilinear h ==> (h (0) x = 0)``,
435  ONCE_REWRITE_TAC[REAL_ARITH ``(x = 0:real) <=> (x + x = x)``] THEN
436  SIMP_TAC std_ss [GSYM BILINEAR_LADD, REAL_ADD_LID]);
437
438val BILINEAR_RZERO = store_thm ("BILINEAR_RZERO",
439 ``!h x. bilinear h ==> (h x (0) = 0)``,
440  ONCE_REWRITE_TAC[REAL_ARITH ``(x = 0:real) <=> (x + x = x)``] THEN
441  SIMP_TAC std_ss [GSYM BILINEAR_RADD, REAL_ADD_LID]);
442
443val BILINEAR_LSUB = store_thm ("BILINEAR_LSUB",
444 ``!h x y z. bilinear h ==> (h (x - y) z = (h x z) - (h y z))``,
445  SIMP_TAC std_ss [real_sub, BILINEAR_LNEG, BILINEAR_LADD]);
446
447val BILINEAR_RSUB = store_thm ("BILINEAR_RSUB",
448 ``!h x y z. bilinear h ==> (h x (y - z) = (h x y) - (h x z))``,
449  SIMP_TAC std_ss [real_sub, BILINEAR_RNEG, BILINEAR_RADD]);
450
451val lemma = prove (
452 ``!s t. s CROSS t = {(x,y) | x IN s /\ y IN t}``,
453  REWRITE_TAC [CROSS_DEF] THEN
454  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD]);
455
456val BILINEAR_SUM = store_thm ("BILINEAR_SUM",
457 ``!h:real->real->real.
458       bilinear h /\ FINITE s /\ FINITE t
459       ==> (h (sum s f) (sum t g) = sum (s CROSS t) (\(i,j). h (f i) (g j)))``,
460  REPEAT GEN_TAC THEN REWRITE_TAC [bilinear] THEN
461  KNOW_TAC ``(!x. linear (\y. h:real->real->real x y)) = (!x. linear (h x))`` THENL
462  [METIS_TAC [ETA_AX], ALL_TAC] THEN DISC_RW_KILL THEN
463  ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c /\ d <=> (a /\ d) /\ (b /\ c)`] THEN
464  DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
465  KNOW_TAC ``((!y. linear (\x. h:real->real->real x y)) /\ FINITE s) =
466             ((!y. linear (\x. h x y) /\ FINITE s))`` THENL
467  [SIMP_TAC std_ss [LEFT_AND_FORALL_THM], ALL_TAC] THEN
468  DISC_RW_KILL THEN DISCH_TAC THEN
469  FIRST_ASSUM(MP_TAC o GEN_ALL o MATCH_MP LINEAR_SUM o SPEC_ALL) THEN
470  SIMP_TAC std_ss [] THEN
471  ASM_SIMP_TAC std_ss [LINEAR_SUM, o_DEF, SUM_SUM_PRODUCT] THEN
472  SIMP_TAC std_ss [lemma]);
473
474val lemma = prove (
475 ``!x. x = sum (1:num..1:num) (\i. x * &i)``,
476  REWRITE_TAC [SUM_SING_NUMSEG] THEN BETA_TAC THEN REAL_ARITH_TAC);
477
478val BILINEAR_BOUNDED = store_thm ("BILINEAR_BOUNDED",
479 ``!h:real->real->real.
480        bilinear h ==> ?B. !x y. abs(h x y) <= B * abs(x) * abs(y)``,
481  REPEAT STRIP_TAC THEN
482  EXISTS_TAC ``sum ((1:num..1:num) CROSS (1:num..1:num))
483                  (\ (i,j). abs((h:real->real->real)
484                                (&i) (&j)))`` THEN
485  REPEAT GEN_TAC THEN GEN_REWR_TAC
486   (LAND_CONV o RAND_CONV o BINOP_CONV) [lemma] THEN
487  ASM_SIMP_TAC std_ss [BILINEAR_SUM, FINITE_NUMSEG] THEN
488  ONCE_REWRITE_TAC [REAL_ARITH ``a * b * c = b * c * a:real``] THEN
489  REWRITE_TAC[GSYM SUM_LMUL] THEN MATCH_MP_TAC SUM_ABS_LE THEN
490  SIMP_TAC std_ss [FINITE_CROSS, FINITE_NUMSEG, FORALL_PROD, IN_CROSS] THEN
491  REWRITE_TAC[IN_NUMSEG] THEN REPEAT STRIP_TAC THEN
492  ASM_SIMP_TAC std_ss [BILINEAR_LMUL, ABS_MUL] THEN
493  ASM_SIMP_TAC std_ss [BILINEAR_RMUL, ABS_MUL, REAL_MUL_ASSOC] THEN
494  METIS_TAC [REAL_LE_LT]);
495
496val BILINEAR_BOUNDED_POS = store_thm ("BILINEAR_BOUNDED_POS",
497 ``!h. bilinear h
498       ==> ?B. &0 < B /\ !x y. abs(h x y) <= B * abs(x) * abs(y)``,
499  REPEAT STRIP_TAC THEN
500  FIRST_ASSUM(X_CHOOSE_TAC ``B:real`` o MATCH_MP BILINEAR_BOUNDED) THEN
501  EXISTS_TAC ``abs(B) + &1:real`` THEN CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN
502  REPEAT GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPECL [`x:real`, `y:real`]) THEN
503  MATCH_MP_TAC(REAL_ARITH ``a <= b ==> x <= a ==> x <= b:real``) THEN
504  REPEAT(MATCH_MP_TAC REAL_LE_RMUL_IMP THEN
505         SIMP_TAC std_ss [ABS_POS, REAL_LE_MUL]) THEN
506  REAL_ARITH_TAC);
507
508val BILINEAR_SUM_PARTIAL_SUC = store_thm ("BILINEAR_SUM_PARTIAL_SUC",
509 ``!f g h:real->real->real m n.
510        bilinear h
511        ==> (sum (m..n) (\k. h (f k) (g(k + 1) - g(k))) =
512                if m <= n then h (f(n + 1)) (g(n + 1)) - h (f m) (g m) -
513                               sum (m..n) (\k. h (f(k + 1) - f(k)) (g(k + 1)))
514                else 0)``,
515  SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
516  GEN_TAC THEN INDUCT_TAC THEN
517  COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [SUM_TRIV_NUMSEG, NOT_LESS_EQ] THEN
518  ASM_REWRITE_TAC[SUM_CLAUSES_NUMSEG] THENL
519   [COND_CASES_TAC THEN ASM_SIMP_TAC arith_ss [] THENL
520     [ASM_SIMP_TAC std_ss [BILINEAR_RSUB, BILINEAR_LSUB] THEN REAL_ARITH_TAC,
521      FULL_SIMP_TAC std_ss [bilinear, linear]], FULL_SIMP_TAC std_ss [bilinear, linear],
522  POP_ASSUM MP_TAC THEN REWRITE_TAC [LE] THEN
523  DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THENL [ALL_TAC, ASM_REWRITE_TAC []] THEN
524  ASM_SIMP_TAC std_ss [GSYM NOT_LESS, SUM_TRIV_NUMSEG, ARITH_PROVE ``n < SUC n``] THEN
525  ASM_SIMP_TAC std_ss [GSYM ADD1, ADD_CLAUSES] THEN
526  ASM_SIMP_TAC std_ss [BILINEAR_RSUB, BILINEAR_LSUB] THEN REAL_ARITH_TAC,
527  ALL_TAC] THEN POP_ASSUM MP_TAC THEN REWRITE_TAC [LE] THEN
528  REWRITE_TAC [DE_MORGAN_THM] THEN
529  ASM_SIMP_TAC std_ss [GSYM NOT_LESS, SUM_TRIV_NUMSEG, ARITH_PROVE ``n < SUC n``] THEN
530  ASM_SIMP_TAC std_ss [GSYM ADD1, ADD_CLAUSES] THEN
531  ASM_SIMP_TAC std_ss [BILINEAR_RSUB, BILINEAR_LSUB] THEN REAL_ARITH_TAC);
532
533val BILINEAR_SUM_PARTIAL_PRE = store_thm ("BILINEAR_SUM_PARTIAL_PRE",
534 ``!f g h:real->real->real m n.
535        bilinear h
536        ==> (sum (m..n) (\k. h (f k) (g(k) - g(k - 1))) =
537                if m <= n then h (f(n + 1)) (g(n)) - h (f m) (g(m - 1)) -
538                               sum (m..n) (\k. h (f(k + 1) - f(k)) (g(k)))
539                else 0)``,
540  REPEAT STRIP_TAC THEN
541  FIRST_ASSUM(MP_TAC o ISPECL [``f:num->real``, ``\k. (g:num->real)(k - 1)``,
542                 ``m:num``, ``n:num``] o MATCH_MP BILINEAR_SUM_PARTIAL_SUC) THEN
543  BETA_TAC THEN REWRITE_TAC[ADD_SUB] THEN DISCH_THEN SUBST1_TAC THEN
544  COND_CASES_TAC THEN REWRITE_TAC[]);
545
546(* ------------------------------------------------------------------------- *)
547(* A bit of linear algebra.                                                  *)
548(* ------------------------------------------------------------------------- *)
549
550val subspace = new_definition ("subspace",
551 ``subspace s <=>
552        (0:real) IN s /\
553        (!x y. x IN s /\ y IN s ==> (x + y) IN s) /\
554        (!c x. x IN s ==> (c * x) IN s)``);
555
556val span = new_definition ("span",
557  ``span s = subspace hull s``);
558
559val dependent = new_definition ("dependent",
560 ``dependent s <=> ?a. a IN s /\ a IN span(s DELETE a)``);
561
562val independent = new_definition ("independent",
563 ``independent s <=> ~(dependent s)``);
564
565(* ------------------------------------------------------------------------- *)
566(* Closure properties of subspaces.                                          *)
567(* ------------------------------------------------------------------------- *)
568
569val SUBSPACE_UNIV = store_thm ("SUBSPACE_UNIV",
570 ``subspace(UNIV:real->bool)``,
571  REWRITE_TAC[subspace, IN_UNIV]);
572
573val SUBSPACE_IMP_NONEMPTY = store_thm ("SUBSPACE_IMP_NONEMPTY",
574 ``!s. subspace s ==> ~(s = {})``,
575  REWRITE_TAC[subspace] THEN SET_TAC[]);
576
577val SUBSPACE_0 = store_thm ("SUBSPACE_0",
578 ``subspace s ==> (0:real) IN s``,
579  SIMP_TAC std_ss [subspace]);
580
581val SUBSPACE_ADD = store_thm ("SUBSPACE_ADD",
582 ``!x y s. subspace s /\ x IN s /\ y IN s ==> (x + y) IN s``,
583  SIMP_TAC std_ss [subspace]);
584
585val SUBSPACE_MUL = store_thm ("SUBSPACE_MUL",
586 ``!x c s. subspace s /\ x IN s ==> (c * x) IN s``,
587  SIMP_TAC std_ss [subspace]);
588
589val SUBSPACE_NEG = store_thm ("SUBSPACE_NEG",
590 ``!x s. subspace s /\ x IN s ==> (-x) IN s``,
591  METIS_TAC [REAL_ARITH ``-x = -(&1) * x:real``, SUBSPACE_MUL]);
592
593val SUBSPACE_SUB = store_thm ("SUBSPACE_SUB",
594 ``!x y s. subspace s /\ x IN s /\ y IN s ==> (x - y) IN s``,
595  SIMP_TAC std_ss [real_sub, SUBSPACE_ADD, SUBSPACE_NEG]);
596
597val SUBSPACE_SUM = store_thm ("SUBSPACE_SUM",
598 ``!s f t. subspace s /\ FINITE t /\ (!x. x IN t ==> f(x) IN s)
599           ==> (sum t f) IN s``,
600  SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN
601  GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
602  ONCE_REWRITE_TAC [METIS [] ``!t. ((!x. x IN t ==> f x IN s) ==> sum t f IN s) =
603                               (\t. (!x. x IN t ==> f x IN s) ==> sum t f IN s) t``] THEN
604  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
605  ASM_SIMP_TAC std_ss [SUM_CLAUSES, SUBSPACE_0, IN_INSERT, SUBSPACE_ADD]);
606
607val SUBSPACE_LINEAR_IMAGE = store_thm ("SUBSPACE_LINEAR_IMAGE",
608 ``!f s. linear f /\ subspace s ==> subspace(IMAGE f s)``,
609  SIMP_TAC std_ss [subspace, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN
610  SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE] THEN
611  METIS_TAC [linear, LINEAR_0]);
612
613val SUBSPACE_LINEAR_PREIMAGE = store_thm ("SUBSPACE_LINEAR_PREIMAGE",
614 ``!f s. linear f /\ subspace s ==> subspace {x | f(x) IN s}``,
615  SIMP_TAC std_ss [subspace, GSPECIFICATION] THEN
616  METIS_TAC [linear, LINEAR_0]);
617
618val SUBSPACE_TRIVIAL = store_thm ("SUBSPACE_TRIVIAL",
619 ``subspace {0}``,
620  SIMP_TAC std_ss [subspace, IN_SING] THEN CONJ_TAC THEN REAL_ARITH_TAC);
621
622val SUBSPACE_INTER = store_thm ("SUBSPACE_INTER",
623 ``!s t. subspace s /\ subspace t ==> subspace (s INTER t)``,
624  REWRITE_TAC[subspace, IN_INTER] THEN METIS_TAC []);
625
626val SUBSPACE_BIGINTER = store_thm ("SUBSPACE_BIGINTER",
627 ``!f. (!s. s IN f ==> subspace s) ==> subspace(BIGINTER f)``,
628  SIMP_TAC std_ss [subspace, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, IN_BIGINTER]);
629
630val LINEAR_INJECTIVE_0_SUBSPACE = store_thm ("LINEAR_INJECTIVE_0_SUBSPACE",
631 ``!f:real->real s.
632        linear f /\ subspace s
633         ==> ((!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) <=>
634              (!x. x IN s /\ (f x = 0) ==> (x = 0)))``,
635  REPEAT STRIP_TAC THEN
636  GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_SUB_0] THEN
637  ASM_SIMP_TAC std_ss [GSYM LINEAR_SUB] THEN
638  METIS_TAC [REAL_SUB_RZERO, SUBSPACE_SUB, SUBSPACE_0]);
639
640val SUBSPACE_UNION_CHAIN = store_thm ("SUBSPACE_UNION_CHAIN",
641 ``!s t:real->bool.
642        subspace s /\ subspace t /\ subspace(s UNION t)
643         ==> s SUBSET t \/ t SUBSET s``,
644  REPEAT STRIP_TAC THEN REWRITE_TAC [SET_RULE
645   ``s SUBSET t \/ t SUBSET s <=>
646    ~(?x y. x IN s /\ ~(x IN t) /\ y IN t /\ ~(y IN s))``] THEN
647  STRIP_TAC THEN SUBGOAL_THEN ``(x + y:real) IN (s UNION t)`` MP_TAC THENL
648   [MATCH_MP_TAC SUBSPACE_ADD THEN ASM_REWRITE_TAC[] THEN ASM_SET_TAC[],
649    REWRITE_TAC[IN_UNION, DE_MORGAN_THM] THEN
650    METIS_TAC [SUBSPACE_SUB, REAL_ARITH
651     ``((x + y) - x:real = y) /\ ((x + y) - y:real = x)``]]);
652
653(* ------------------------------------------------------------------------- *)
654(* Lemmas.                                                                   *)
655(* ------------------------------------------------------------------------- *)
656
657val SPAN_SPAN = store_thm ("SPAN_SPAN",
658 ``!s. span(span s) = span s``,
659  REWRITE_TAC[span, HULL_HULL]);
660
661val SPAN_MONO = store_thm ("SPAN_MONO",
662 ``!s t. s SUBSET t ==> span s SUBSET span t``,
663  REWRITE_TAC[span, HULL_MONO]);
664
665val SUBSPACE_SPAN = store_thm ("SUBSPACE_SPAN",
666 ``!s. subspace(span s)``,
667  GEN_TAC THEN REWRITE_TAC[span] THEN MATCH_MP_TAC P_HULL THEN
668  SIMP_TAC std_ss [subspace, IN_BIGINTER]);
669
670val SPAN_CLAUSES = store_thm ("SPAN_CLAUSES",
671 ``(!a s. a IN s ==> a IN span s) /\
672   ((0) IN span s) /\
673   (!x y s. x IN span s /\ y IN span s ==> (x + y) IN span s) /\
674   (!x c s. x IN span s ==> (c * x) IN span s)``,
675  MESON_TAC[span, HULL_SUBSET, SUBSET_DEF, SUBSPACE_SPAN, subspace]);
676
677val SPAN_INDUCT = store_thm ("SPAN_INDUCT",
678 ``!s h. (!x. x IN s ==> x IN h) /\ subspace h ==> !x. x IN span(s) ==> h(x)``,
679  REWRITE_TAC[span] THEN MESON_TAC[SUBSET_DEF, HULL_MINIMAL, IN_DEF]);
680
681val SPAN_EMPTY = store_thm ("SPAN_EMPTY",
682 ``span {} = {0}``,
683  REWRITE_TAC[span] THEN MATCH_MP_TAC HULL_UNIQUE THEN
684  SIMP_TAC std_ss [subspace, SUBSET_DEF, IN_SING, NOT_IN_EMPTY] THEN
685  REPEAT STRIP_TAC THEN REAL_ARITH_TAC);
686
687val INDEPENDENT_EMPTY = store_thm ("INDEPENDENT_EMPTY",
688 ``independent {}``,
689  REWRITE_TAC[independent, dependent, NOT_IN_EMPTY]);
690
691val INDEPENDENT_NONZERO = store_thm ("INDEPENDENT_NONZERO",
692 ``!s. independent s ==> ~(0 IN s)``,
693  REWRITE_TAC[independent, dependent] THEN MESON_TAC[SPAN_CLAUSES]);
694
695val INDEPENDENT_MONO = store_thm ("INDEPENDENT_MONO",
696 ``!s t. independent t /\ s SUBSET t ==> independent s``,
697  REWRITE_TAC[independent, dependent] THEN
698  ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_DELETE]);
699
700val DEPENDENT_MONO = store_thm ("DEPENDENT_MONO",
701 ``!s t:real->bool. dependent s /\ s SUBSET t ==> dependent t``,
702  ONCE_REWRITE_TAC[TAUT `p /\ q ==> r <=> ~r /\ q ==> ~p`] THEN
703  REWRITE_TAC[GSYM independent, INDEPENDENT_MONO]);
704
705val SPAN_SUBSPACE = store_thm ("SPAN_SUBSPACE",
706 ``!b s. b SUBSET s /\ s SUBSET (span b) /\ subspace s ==> (span b = s)``,
707  MESON_TAC[SUBSET_ANTISYM, span, HULL_MINIMAL]);
708
709val SPAN_INDUCT_ALT = store_thm ("SPAN_INDUCT_ALT",
710 ``!s h. h(0) /\
711         (!c x y. x IN s /\ h(y) ==> h(c * x + y))
712          ==> !x:real. x IN span(s) ==> h(x)``,
713  REPEAT GEN_TAC THEN DISCH_TAC THEN
714  FIRST_ASSUM(MP_TAC o prove_nonschematic_inductive_relations_exist bool_monoset o concl) THEN
715  DISCH_THEN(X_CHOOSE_THEN ``g:real->bool`` STRIP_ASSUME_TAC) THEN
716  SUBGOAL_THEN ``!x:real. x IN span(s) ==> g(x)``
717   (fn th => METIS_TAC [th]) THEN
718  MATCH_MP_TAC SPAN_INDUCT THEN SIMP_TAC std_ss [subspace, GSPECIFICATION] THEN
719  SIMP_TAC std_ss [IN_DEF, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN
720  ONCE_REWRITE_TAC [METIS [] ``(g x ==> g (c * x)) = (\c x:real. g x ==> g (c * x)) c x``] THEN
721  ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN
722  REPEAT CONJ_TAC THENL
723  [METIS_TAC [IN_DEF, REAL_ADD_LID, REAL_ADD_ASSOC, REAL_ADD_SYM,
724                REAL_MUL_LID, REAL_MUL_RZERO],
725   METIS_TAC [IN_DEF, REAL_ADD_LID, REAL_ADD_ASSOC, REAL_ADD_SYM,
726                REAL_MUL_LID, REAL_MUL_RZERO],
727   ONCE_REWRITE_TAC [METIS [] ``!x. (!y. g y ==> g (x + y)) =
728                              (\x. !y. g y ==> g (x + y)) (x:real)``] THEN
729   FIRST_X_ASSUM MATCH_MP_TAC THEN
730   SIMP_TAC std_ss [REAL_ADD_LDISTRIB, REAL_MUL_ASSOC] THEN
731   ASM_MESON_TAC [IN_DEF, REAL_ADD_LID, REAL_ADD_ASSOC, REAL_ADD_SYM,
732                REAL_MUL_LID, REAL_MUL_RZERO],
733   ONCE_REWRITE_TAC [METIS [] ``(!x. g (x * y)) =
734                            (\y.!x. g (x * y)) (y:real)``] THEN
735   FIRST_X_ASSUM MATCH_MP_TAC THEN
736   SIMP_TAC std_ss [REAL_ADD_LDISTRIB, REAL_MUL_ASSOC] THEN
737   ASM_MESON_TAC [IN_DEF, REAL_ADD_LID, REAL_ADD_ASSOC, REAL_ADD_SYM,
738                REAL_MUL_LID, REAL_MUL_RZERO]]);
739
740(* ------------------------------------------------------------------------- *)
741(* Individual closure properties.                                            *)
742(* ------------------------------------------------------------------------- *)
743
744val SPAN_SUPERSET = store_thm ("SPAN_SUPERSET",
745 ``!x. x IN s ==> x IN span s``,
746  MESON_TAC[SPAN_CLAUSES]);
747
748val SPAN_INC = store_thm ("SPAN_INC",
749 ``!s. s SUBSET span s``,
750  REWRITE_TAC[SUBSET_DEF, SPAN_SUPERSET]);
751
752val SPAN_UNION_SUBSET = store_thm ("SPAN_UNION_SUBSET",
753 ``!s t. span s UNION span t SUBSET span(s UNION t)``,
754  REWRITE_TAC[span, HULL_UNION_SUBSET]);
755
756val SPAN_UNIV = store_thm ("SPAN_UNIV",
757 ``span univ(:real) = univ(:real)``,
758  SIMP_TAC std_ss [SPAN_INC, SET_RULE ``UNIV SUBSET s ==> (s = UNIV)``]);
759
760val SPAN_0 = store_thm ("SPAN_0",
761 ``(0) IN span s``,
762  MESON_TAC[SUBSPACE_SPAN, SUBSPACE_0]);
763
764val SPAN_ADD = store_thm ("SPAN_ADD",
765 ``!x y s. x IN span s /\ y IN span s ==> (x + y) IN span s``,
766  MESON_TAC[SUBSPACE_SPAN, SUBSPACE_ADD]);
767
768val SPAN_MUL = store_thm ("SPAN_MUL",
769 ``!x c s. x IN span s ==> (c * x) IN span s``,
770  MESON_TAC[SUBSPACE_SPAN, SUBSPACE_MUL]);
771
772val SPAN_MUL_EQ = store_thm ("SPAN_MUL_EQ",
773 ``!x:real c s. ~(c = &0) ==> ((c * x) IN span s <=> x IN span s)``,
774  REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN ASM_SIMP_TAC std_ss [SPAN_MUL] THEN
775  SUBGOAL_THEN ``(inv(c) * c * x:real) IN span s`` MP_TAC THENL
776   [REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC std_ss [SPAN_MUL],
777    ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID]]);
778
779val SPAN_NEG = store_thm ("SPAN_NEG",
780 ``!x s. x IN span s ==> (-x) IN span s``,
781  MESON_TAC[SUBSPACE_SPAN, SUBSPACE_NEG]);
782
783val SPAN_NEG_EQ = store_thm ("SPAN_NEG_EQ",
784 ``!x s. -x IN span s <=> x IN span s``,
785  MESON_TAC[SPAN_NEG, REAL_NEG_NEG]);
786
787val SPAN_SUB = store_thm ("SPAN_SUB",
788 ``!x y s. x IN span s /\ y IN span s ==> (x - y) IN span s``,
789  MESON_TAC[SUBSPACE_SPAN, SUBSPACE_SUB]);
790
791val SPAN_SUM = store_thm ("SPAN_SUM",
792 ``!s f t. FINITE t /\ (!x. x IN t ==> f(x) IN span(s))
793           ==> (sum t f) IN span(s)``,
794  MESON_TAC[SUBSPACE_SPAN, SUBSPACE_SUM]);
795
796val SPAN_ADD_EQ = store_thm ("SPAN_ADD_EQ",
797 ``!s x y. x IN span s ==> ((x + y) IN span s <=> y IN span s)``,
798  MESON_TAC[SPAN_ADD, SPAN_SUB, REAL_ARITH ``(x + y) - x:real = y``]);
799
800val SPAN_EQ_SELF = store_thm ("SPAN_EQ_SELF",
801 ``!s. (span s = s) <=> subspace s``,
802  GEN_TAC THEN EQ_TAC THENL [MESON_TAC[SUBSPACE_SPAN], ALL_TAC] THEN
803  DISCH_TAC THEN MATCH_MP_TAC SPAN_SUBSPACE THEN
804  ASM_REWRITE_TAC[SUBSET_REFL, SPAN_INC]);
805
806val SPAN_SUBSET_SUBSPACE = store_thm ("SPAN_SUBSET_SUBSPACE",
807 ``!s t:real->bool. s SUBSET t /\ subspace t ==> span s SUBSET t``,
808  MESON_TAC[SPAN_MONO, SPAN_EQ_SELF]);
809
810val SURJECTIVE_IMAGE_EQ = store_thm ("SURJECTIVE_IMAGE_EQ",
811 ``!s t. (!y. y IN t ==> ?x. f x = y) /\ (!x. (f x) IN t <=> x IN s)
812         ==> (IMAGE f s = t)``,
813  SET_TAC[]);
814
815val SUBSPACE_TRANSLATION_SELF = store_thm ("SUBSPACE_TRANSLATION_SELF",
816 ``!s a. subspace s /\ a IN s ==> (IMAGE (\x. a + x) s = s)``,
817  REPEAT STRIP_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
818  FIRST_ASSUM(SUBST1_TAC o SYM o REWRITE_RULE [GSYM SPAN_EQ_SELF]) THEN
819  ASM_SIMP_TAC std_ss [SPAN_ADD_EQ, SPAN_CLAUSES] THEN
820  REWRITE_TAC[REAL_ARITH ``(a + x:real = y) <=> (x = y - a)``, EXISTS_REFL]);
821
822val SUBSPACE_TRANSLATION_SELF_EQ = store_thm ("SUBSPACE_TRANSLATION_SELF_EQ",
823 ``!s a:real. subspace s ==> ((IMAGE (\x. a + x) s = s) <=> a IN s)``,
824  REPEAT STRIP_TAC THEN EQ_TAC THEN
825  ASM_SIMP_TAC std_ss [SUBSPACE_TRANSLATION_SELF] THEN
826  DISCH_THEN(MP_TAC o AP_TERM ``\s. (a:real) IN s``) THEN
827  SIMP_TAC std_ss [] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
828  REWRITE_TAC[IN_IMAGE] THEN EXISTS_TAC ``0:real`` THEN
829  ASM_MESON_TAC[subspace, REAL_ADD_RID]);
830
831val SUBSPACE_SUMS = store_thm ("SUBSPACE_SUMS",
832 ``!s t. subspace s /\ subspace t
833         ==> subspace {x + y | x IN s /\ y IN t}``,
834  SIMP_TAC std_ss [subspace, FORALL_IN_GSPEC, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN
835  SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN REPEAT STRIP_TAC THENL
836   [ASM_MESON_TAC[REAL_ADD_LID],
837    ONCE_REWRITE_TAC[REAL_ARITH
838     ``(x + y) + (x' + y'):real = (x + x') + (y + y')``] THEN
839    ASM_MESON_TAC[],
840    REWRITE_TAC[REAL_ADD_LDISTRIB] THEN ASM_MESON_TAC[]]);
841
842val SPAN_UNION = store_thm ("SPAN_UNION",
843 ``!s t. span(s UNION t) = {x + y:real | x IN span s /\ y IN span t}``,
844  REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
845   [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN
846    SIMP_TAC std_ss [SUBSPACE_SUMS, SUBSPACE_SPAN] THEN
847    SIMP_TAC std_ss [SUBSET_DEF, IN_UNION, GSPECIFICATION, EXISTS_PROD] THEN
848    X_GEN_TAC ``x:real`` THEN STRIP_TAC THENL
849     [MAP_EVERY EXISTS_TAC [``x:real``, ``0:real``] THEN
850      ASM_SIMP_TAC std_ss [SPAN_SUPERSET, SPAN_0, REAL_ADD_RID],
851      MAP_EVERY EXISTS_TAC [``0:real``, ``x:real``] THEN
852      ASM_SIMP_TAC std_ss [SPAN_SUPERSET, SPAN_0, REAL_ADD_LID]],
853    SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_GSPEC] THEN
854    REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_ADD THEN
855    ASM_MESON_TAC[SPAN_MONO, SUBSET_UNION, SUBSET_DEF]]);
856
857(* ------------------------------------------------------------------------- *)
858(* Equality in Cauchy-Schwarz and triangle inequalities.                     *)
859(* ------------------------------------------------------------------------- *)
860
861val ABS_CAUCHY_SCHWARZ_EQ = store_thm
862  ("ABS_CAUCHY_SCHWARZ_EQ",
863 ``!x:real y. (x * y = abs(x) * abs(y)) <=> (abs(x) * y = abs(y) * x)``,
864   REPEAT GEN_TAC THEN ASM_CASES_TAC ``0 <= x:real`` THEN
865  (ASM_CASES_TAC ``0 <= y:real``) THEN ASM_REWRITE_TAC [abs] THENL
866  [ASM_REAL_ARITH_TAC, ALL_TAC, ALL_TAC, ASM_REAL_ARITH_TAC] THEN
867  ((MP_TAC o SPECL [``x:real``,``y:real``]) REAL_LT_TOTAL THEN STRIP_TAC THEN
868  TRY (ASM_REAL_ARITH_TAC)) THEN COND_CASES_TAC THEN EQ_TAC THEN
869  TRY (ASM_REAL_ARITH_TAC));
870
871val ABS_CAUCHY_SCHWARZ_ABS_EQ = store_thm
872  ("ABS_CAUCHY_SCHWARZ_ABS_EQ",
873 ``!x:real y. (abs(x * y) = abs(x) * abs(y)) <=>
874                (abs(x) * y = abs(y) * x) \/ (abs(x) * y = -abs(y) * x)``,
875  SIMP_TAC std_ss [REAL_ARITH ``&0 <= a ==> ((abs x = a) <=> (x = a) \/ (-x = a:real))``,
876           REAL_LE_MUL, ABS_POS, REAL_MUL_RNEG] THEN
877  REAL_ARITH_TAC);
878
879val REAL_EQ_LINV = store_thm
880  ("REAL_EQ_LINV", ``!x. (-x = (x :real)) <=> (x = 0)``,
881    GEN_TAC
882 >> REWRITE_TAC [SYM (Q.SPECL [`x`, `-x`, `x`] REAL_EQ_LADD)]
883 >> REWRITE_TAC [REAL_ADD_RINV, REAL_DOUBLE]
884 >> RW_TAC real_ss [REAL_ENTIRE]);
885
886val REAL_EQ_RINV = store_thm
887  ("REAL_EQ_RINV", ``!x. ((x :real) = -x) <=> (x = 0)``,
888    GEN_TAC
889 >> REWRITE_TAC [SYM (Q.SPECL [`x`, `x`, `-x`] REAL_EQ_LADD)]
890 >> REWRITE_TAC [REAL_ADD_RINV, REAL_DOUBLE]
891 >> RW_TAC real_ss [REAL_ENTIRE]);
892
893(* this proof is too advanced in realScript *)
894val ABS_TRIANGLE_EQ = store_thm ("ABS_TRIANGLE_EQ",
895  ``!x y:real. (abs(x + y) = abs(x) + abs(y)) <=> (abs(x) * y = abs(y) * x)``,
896    rpt GEN_TAC
897 >> ASM_CASES_TAC ``0 <= x:real``
898 >> ASM_CASES_TAC ``0 <= y:real``
899 >> ASM_REWRITE_TAC [abs]
900 >- ( `0 <= x + y` by PROVE_TAC [REAL_LE_ADD] \\
901      ASM_SIMP_TAC bool_ss [] >> REAL_ARITH_TAC )
902 >| [ (* goal 1 (of 3) *)
903      Cases_on `0 <= x + y`
904      >- ( ASM_SIMP_TAC bool_ss [REAL_EQ_LADD, Once REAL_MUL_SYM] \\
905           EQ_TAC >- PROVE_TAC [] \\
906           REWRITE_TAC [REAL_EQ_RMUL] \\
907           STRIP_TAC >> FULL_SIMP_TAC bool_ss [REAL_ADD_LID] ) \\
908      ASM_SIMP_TAC bool_ss [REAL_NEG_ADD, REAL_EQ_RADD, Once REAL_MUL_SYM] \\
909      `(-x = x) = (x = 0)` by PROVE_TAC [REAL_EQ_LINV] \\
910      POP_ASSUM (REWRITE_TAC o wrap) \\
911      REWRITE_TAC [REAL_EQ_RMUL] \\
912      EQ_TAC >- PROVE_TAC [] \\
913      STRIP_TAC \\
914      `y = 0` by PROVE_TAC [REAL_EQ_RINV] \\
915      FULL_SIMP_TAC bool_ss [REAL_ADD_RID],
916      (* goal 2 (of 3) *)
917      Cases_on `0 <= x + y`
918      >- ( ASM_SIMP_TAC bool_ss [REAL_EQ_RADD, Once REAL_MUL_SYM] \\
919           EQ_TAC >- PROVE_TAC [] \\
920           REWRITE_TAC [REAL_EQ_LMUL] \\
921           reverse STRIP_TAC >- ( MATCH_MP_TAC EQ_SYM >> ASM_REWRITE_TAC [] ) \\
922           REWRITE_TAC [REAL_EQ_RINV] \\
923           FULL_SIMP_TAC bool_ss [REAL_ADD_RID] ) \\
924      FULL_SIMP_TAC bool_ss [REAL_NEG_ADD] \\
925      REWRITE_TAC [REAL_EQ_LADD, REAL_EQ_LINV, Once REAL_MUL_SYM] \\
926      EQ_TAC >- RW_TAC real_ss [] \\
927      REWRITE_TAC [REAL_EQ_LMUL, REAL_EQ_LINV] >> STRIP_TAC \\
928      FULL_SIMP_TAC bool_ss [REAL_ADD_LID],
929      (* goal 3 (of 3) *)
930      Know `~(0 <= x + y)`
931      >- (FULL_SIMP_TAC bool_ss [REAL_NOT_LE] \\
932          PROVE_TAC [REAL_LT_ADD2, REAL_ADD_RID]) \\
933      DISCH_TAC >> ASM_SIMP_TAC bool_ss [] \\
934      REWRITE_TAC [REAL_NEG_ADD] \\
935      PROVE_TAC [REAL_NEG_RMUL, REAL_MUL_SYM] ]);
936
937val DIST_TRIANGLE_EQ = store_thm ("DIST_TRIANGLE_EQ",
938 ``!x y z:real. (dist(x,z) = dist(x,y) + dist(y,z)) <=>
939                (abs (x - y) * (y - z) = abs (y - z) * (x - y))``,
940  REWRITE_TAC[GSYM ABS_TRIANGLE_EQ, dist] THEN REAL_ARITH_TAC);
941
942(* ------------------------------------------------------------------------- *)
943(* Collinearity.                                                             *)
944(* ------------------------------------------------------------------------- *)
945
946val _ = hide "collinear";
947
948val collinear = new_definition ("collinear",
949 ``collinear s <=> ?u. !x y:real. x IN s /\ y IN s ==> ?c. x - y = c * u``);
950
951val COLLINEAR_SUBSET = store_thm ("COLLINEAR_SUBSET",
952 ``!s t. collinear t /\ s SUBSET t ==> collinear s``,
953  REWRITE_TAC[collinear] THEN SET_TAC[]);
954
955val COLLINEAR_EMPTY = store_thm ("COLLINEAR_EMPTY",
956 ``collinear {}``,
957  REWRITE_TAC[collinear, NOT_IN_EMPTY]);
958
959val COLLINEAR_SING = store_thm ("COLLINEAR_SING",
960 ``!x:real. collinear {x}``,
961  SIMP_TAC std_ss [collinear, IN_SING, REAL_SUB_REFL] THEN
962  METIS_TAC [REAL_MUL_LZERO]);
963
964val COLLINEAR_2 = store_thm ("COLLINEAR_2",
965 ``!x y:real. collinear {x;y}``,
966  REPEAT GEN_TAC THEN REWRITE_TAC[collinear, IN_INSERT, NOT_IN_EMPTY] THEN
967  EXISTS_TAC ``x - y:real`` THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THENL
968   [EXISTS_TAC ``&0:real``, EXISTS_TAC ``&1:real``,
969    EXISTS_TAC ``- &1:real``, EXISTS_TAC ``&0:real``] THEN
970  REAL_ARITH_TAC);
971
972val COLLINEAR_SMALL = store_thm ("COLLINEAR_SMALL",
973 ``!s. FINITE s /\ CARD s <= 2 ==> collinear s``,
974  REWRITE_TAC[ARITH_PROVE ``s <= 2 <=> (s = 0) \/ (s = 1) \/ (s = 2:num)``] THEN
975  REWRITE_TAC[LEFT_AND_OVER_OR, GSYM HAS_SIZE] THEN
976  REWRITE_TAC [ONE, TWO, HAS_SIZE_CLAUSES] THEN
977  REPEAT STRIP_TAC THEN
978  ASM_REWRITE_TAC[COLLINEAR_EMPTY, COLLINEAR_SING, COLLINEAR_2]);
979
980val COLLINEAR_3 = store_thm ("COLLINEAR_3",
981 ``!x y z. collinear {x;y;z} <=> collinear {0;x - y;z - y}``,
982  REPEAT GEN_TAC THEN
983  SIMP_TAC std_ss [collinear, FORALL_IN_INSERT, CONJ_EQ_IMP,
984                   RIGHT_FORALL_IMP_THM, NOT_IN_EMPTY] THEN
985  AP_TERM_TAC THEN ABS_TAC THEN
986  METIS_TAC [REAL_ARITH ``x - y = (x - y) - 0:real``,
987             REAL_ARITH ``y - x = 0 - (x - y:real)``,
988             REAL_ARITH ``x - z:real = (x - y) - (z - y)``]);
989
990val COLLINEAR_LEMMA = store_thm ("COLLINEAR_LEMMA",
991 ``!x y:real. collinear {0;x;y} <=>
992                   (x = 0) \/ (y = 0) \/ ?c. y = c * x``,
993  REPEAT GEN_TAC THEN
994  MAP_EVERY ASM_CASES_TAC [``x:real = 0``, ``y:real = 0``] THEN
995  TRY(ONCE_REWRITE_TAC [INSERT_COMM] THEN
996      ASM_REWRITE_TAC[INSERT_INSERT, COLLINEAR_SING, COLLINEAR_2] THEN NO_TAC) THEN
997  ASM_REWRITE_TAC[collinear] THEN EQ_TAC THENL
998   [DISCH_THEN(X_CHOOSE_THEN ``u:real``
999     (fn th => MP_TAC(SPECL [``x:real``, ``0:real``] th) THEN
1000                MP_TAC(SPECL [``y:real``, ``0:real``] th))) THEN
1001    REWRITE_TAC[IN_INSERT, REAL_SUB_RZERO] THEN
1002    DISCH_THEN(X_CHOOSE_THEN ``e:real`` SUBST_ALL_TAC) THEN
1003    DISCH_THEN(X_CHOOSE_THEN ``d:real`` SUBST_ALL_TAC) THEN
1004    EXISTS_TAC ``e / d:real`` THEN REWRITE_TAC[REAL_MUL_ASSOC] THEN
1005    RULE_ASSUM_TAC(REWRITE_RULE[REAL_ENTIRE, DE_MORGAN_THM]) THEN
1006    ASM_SIMP_TAC real_ss [REAL_DIV_RMUL],
1007    STRIP_TAC THEN EXISTS_TAC ``x:real`` THEN ASM_REWRITE_TAC[] THEN
1008    REWRITE_TAC[IN_INSERT, NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN
1009    ASM_REWRITE_TAC[] THENL
1010     [EXISTS_TAC ``&0:real``, EXISTS_TAC ``- &1:real``, EXISTS_TAC ``-c:real``,
1011      EXISTS_TAC ``&1:real``, EXISTS_TAC ``&0:real``, EXISTS_TAC ``&1 - c:real``,
1012      EXISTS_TAC ``c:real``, EXISTS_TAC ``c - &1:real``, EXISTS_TAC ``&0:real``] THEN
1013    REAL_ARITH_TAC]);
1014
1015val COLLINEAR_LEMMA_ALT = store_thm ("COLLINEAR_LEMMA_ALT",
1016 ``!x y. collinear {0;x;y} <=> (x = 0) \/ ?c. y = c * x``,
1017  REWRITE_TAC[COLLINEAR_LEMMA] THEN METIS_TAC [REAL_MUL_LZERO]);
1018
1019val ABS_CAUCHY_SCHWARZ_EQUAL = store_thm ("ABS_CAUCHY_SCHWARZ_EQUAL",
1020 ``!x y:real. (abs(x * y) = abs(x) * abs(y)) <=> collinear {0;x;y}``,
1021  REPEAT GEN_TAC THEN REWRITE_TAC[ABS_CAUCHY_SCHWARZ_ABS_EQ] THEN
1022  MAP_EVERY ASM_CASES_TAC [``x:real = 0``, ``y:real = 0``] THEN
1023  TRY(ONCE_ASM_REWRITE_TAC [INSERT_COMM] THEN
1024      ASM_REWRITE_TAC[INSERT_INSERT, COLLINEAR_SING, COLLINEAR_2, ABS_0,
1025                      REAL_MUL_LZERO, REAL_MUL_RZERO] THEN NO_TAC) THEN
1026  ASM_REWRITE_TAC[COLLINEAR_LEMMA] THEN EQ_TAC THENL
1027   [STRIP_TAC THENL
1028     [EXISTS_TAC ``y / x:real``, EXISTS_TAC ``y / x:real``] THEN
1029    ASM_SIMP_TAC std_ss [REAL_DIV_RMUL],
1030    ASM_REAL_ARITH_TAC]);
1031
1032val MUL_CAUCHY_SCHWARZ_EQUAL = store_thm ("MUL_CAUCHY_SCHWARZ_EQUAL",
1033 ``!x y:real.
1034        ((x * y) pow 2 = (x * x) * (y * y)) <=>
1035        collinear {0;x;y}``,
1036  REWRITE_TAC[GSYM ABS_CAUCHY_SCHWARZ_EQUAL] THEN
1037  REPEAT GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH
1038   ``&0 <= y /\ ((u:real = v) <=> (x = abs y)) ==> ((u = v) <=> (x = y:real))``) THEN
1039  SIMP_TAC std_ss [ABS_POS, REAL_LE_MUL] THEN
1040  REWRITE_TAC[REAL_EQ_SQUARE_ABS] THEN REWRITE_TAC[POW_MUL, GSYM POW_2] THEN
1041  REWRITE_TAC [POW_2] THEN REAL_ARITH_TAC);
1042
1043val COLLINEAR_3_EXPAND = store_thm ("COLLINEAR_3_EXPAND",
1044 ``!a b c:real. collinear{a;b;c} <=> ((a = c) \/ ?u. b = u * a + (&1 - u) * c)``,
1045  REPEAT GEN_TAC THEN
1046  ONCE_REWRITE_TAC[SET_RULE ``{a;b;c} = {a;c;b}``] THEN
1047  ONCE_REWRITE_TAC[COLLINEAR_3] THEN
1048  REWRITE_TAC[COLLINEAR_LEMMA, REAL_SUB_0] THEN
1049  ASM_CASES_TAC ``a:real = c`` THEN ASM_REWRITE_TAC[] THEN
1050  ASM_CASES_TAC ``b:real = c`` THEN
1051  ASM_REWRITE_TAC[REAL_ARITH ``u * c + (&1 - u) * c = c:real``] THENL
1052   [EXISTS_TAC ``&0:real`` THEN REAL_ARITH_TAC,
1053     AP_TERM_TAC THEN ABS_TAC THEN REAL_ARITH_TAC]);
1054
1055val COLLINEAR_TRIPLES = store_thm ("COLLINEAR_TRIPLES",
1056 ``!s a b:real.
1057        ~(a = b)
1058        ==> (collinear(a INSERT b INSERT s) <=>
1059             !x. x IN s ==> collinear{a;b;x})``,
1060  REPEAT STRIP_TAC THEN EQ_TAC THENL
1061   [REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
1062     (REWRITE_RULE[CONJ_EQ_IMP] COLLINEAR_SUBSET)) THEN
1063    ASM_SET_TAC[],
1064    ONCE_REWRITE_TAC[SET_RULE ``{a;b;x} = {a;x;b}``] THEN
1065    ASM_REWRITE_TAC[COLLINEAR_3_EXPAND] THEN DISCH_TAC THEN
1066    SUBGOAL_THEN
1067     ``!x:real. x IN (a INSERT b INSERT s) ==> ?u. x = u * a + (&1 - u) * b``
1068    MP_TAC THENL
1069     [ASM_SIMP_TAC real_ss [FORALL_IN_INSERT] THEN CONJ_TAC THENL
1070       [EXISTS_TAC ``&1:real`` THEN REAL_ARITH_TAC,
1071        EXISTS_TAC ``&0:real`` THEN REAL_ARITH_TAC],
1072      POP_ASSUM_LIST(K ALL_TAC) THEN DISCH_TAC THEN
1073      REWRITE_TAC[collinear] THEN EXISTS_TAC ``b - a:real`` THEN
1074      MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN
1075      FIRST_X_ASSUM(fn th => MP_TAC(SPEC ``x:real`` th) THEN MP_TAC(SPEC
1076        ``y:real`` th)) THEN
1077      ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
1078      ASM_REWRITE_TAC[REAL_ARITH
1079       ``(u * a + (&1 - u) * b) - (v * a + (&1 - v) * b):real =
1080         (v - u) * (b - a)``] THEN
1081      METIS_TAC []]]);
1082
1083val COLLINEAR_4_3 = store_thm ("COLLINEAR_4_3",
1084 ``!a b c d:real.
1085        ~(a = b)
1086        ==> (collinear {a;b;c;d} <=> collinear{a;b;c} /\ collinear{a;b;d})``,
1087  REPEAT STRIP_TAC THEN
1088  MP_TAC(ISPECL [``{c:real;d}``, ``a:real``, ``b:real``]
1089    COLLINEAR_TRIPLES) THEN
1090  ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN
1091  SIMP_TAC real_ss [FORALL_IN_INSERT, NOT_IN_EMPTY]);
1092
1093val COLLINEAR_3_TRANS = store_thm ("COLLINEAR_3_TRANS",
1094 ``!a b c d:real.
1095        collinear{a;b;c} /\ collinear{b;c;d} /\ ~(b = c) ==> collinear{a;b;d}``,
1096  REPEAT STRIP_TAC THEN MATCH_MP_TAC COLLINEAR_SUBSET THEN
1097  EXISTS_TAC ``{b:real;c;a;d}`` THEN ASM_SIMP_TAC std_ss [COLLINEAR_4_3] THEN
1098  CONJ_TAC THENL [ALL_TAC, SET_TAC[]] THEN
1099  ONCE_ASM_REWRITE_TAC [SET_RULE ``{b;c;a} = {a;b;c}``] THEN METIS_TAC []);
1100
1101(* ------------------------------------------------------------------------- *)
1102(* Between-ness.                                                             *)
1103(* ------------------------------------------------------------------------- *)
1104
1105val between = new_definition ("between",
1106 ``between x (a,b) <=> (dist(a,b) = dist(a,x) + dist(x,b))``);
1107
1108val BETWEEN_REFL = store_thm ("BETWEEN_REFL",
1109 ``!a b. between a (a,b) /\ between b (a,b) /\ between a (a,a)``,
1110  REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC);
1111
1112val BETWEEN_REFL_EQ = store_thm ("BETWEEN_REFL_EQ",
1113 ``!a x. between x (a,a) <=> (x = a)``,
1114  REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC);
1115
1116val BETWEEN_SYM = store_thm ("BETWEEN_SYM",
1117 ``!a b x. between x (a,b) <=> between x (b,a)``,
1118  REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC);
1119
1120val BETWEEN_ANTISYM = store_thm ("BETWEEN_ANTISYM",
1121 ``!a b c. between a (b,c) /\ between b (a,c) ==> (a = b)``,
1122  REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC);
1123
1124val BETWEEN_TRANS = store_thm ("BETWEEN_TRANS",
1125 ``!a b c d. between a (b,c) /\ between d (a,c) ==> between d (b,c)``,
1126  REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC);
1127
1128val BETWEEN_TRANS_2 = store_thm ("BETWEEN_TRANS_2",
1129 ``!a b c d. between a (b,c) /\ between d (a,b) ==> between a (c,d)``,
1130  REWRITE_TAC[between, dist] THEN REAL_ARITH_TAC);
1131
1132val BETWEEN_ABS = store_thm ("BETWEEN_ABS",
1133 ``!a b x:real.
1134     between x (a,b) <=> (abs(x - a) * (b - x) = abs(b - x) * (x - a))``,
1135  REPEAT GEN_TAC THEN REWRITE_TAC[between, DIST_TRIANGLE_EQ] THEN
1136  GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [ABS_SUB] THEN REAL_ARITH_TAC);
1137
1138val BETWEEN_IMP_COLLINEAR = store_thm ("BETWEEN_IMP_COLLINEAR",
1139 ``!a b x:real. between x (a,b) ==> collinear {a;x;b}``,
1140  REPEAT GEN_TAC THEN ASM_CASES_TAC ``x:real = a`` THENL
1141  [ONCE_REWRITE_TAC[COLLINEAR_3, BETWEEN_ABS] THEN
1142   DISCH_TAC THEN ASM_REWRITE_TAC[COLLINEAR_LEMMA, REAL_SUB_REFL] THEN
1143   ASM_REAL_ARITH_TAC,
1144   ONCE_REWRITE_TAC[COLLINEAR_3, BETWEEN_ABS] THEN
1145   DISCH_TAC THEN ASM_REWRITE_TAC[COLLINEAR_LEMMA] THEN
1146   DISJ2_TAC THEN DISJ2_TAC THEN EXISTS_TAC ``(b - x) / (a - x:real)`` THEN
1147   RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH
1148                   ``(x <> a) = ((a - x) <> 0:real)``]) THEN
1149   ASM_SIMP_TAC real_ss [REAL_DIV_RMUL]]);
1150
1151val COLLINEAR_BETWEEN_CASES = store_thm ("COLLINEAR_BETWEEN_CASES",
1152 ``!a b c:real.
1153        collinear {a;b;c} <=>
1154        between a (b,c) \/ between b (c,a) \/ between c (a,b)``,
1155  REPEAT STRIP_TAC THEN EQ_TAC THENL
1156   [REWRITE_TAC[COLLINEAR_3_EXPAND] THEN
1157    ASM_CASES_TAC ``c:real = a`` THEN ASM_REWRITE_TAC[BETWEEN_REFL] THEN
1158    STRIP_TAC THEN ASM_REWRITE_TAC[between, dist] THEN
1159    ASM_REAL_ARITH_TAC,
1160    DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN (MP_TAC o MATCH_MP
1161      BETWEEN_IMP_COLLINEAR)) THEN
1162    METIS_TAC[INSERT_COMM]]);
1163
1164val COLLINEAR_DIST_BETWEEN = store_thm ("COLLINEAR_DIST_BETWEEN",
1165 ``!a b x. collinear {x;a;b} /\
1166           dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)
1167           ==> between x (a,b)``,
1168  SIMP_TAC std_ss [COLLINEAR_BETWEEN_CASES, between, dist] THEN REAL_ARITH_TAC);
1169
1170val COLLINEAR_1 = store_thm ("COLLINEAR_1",
1171 ``!s:real->bool. collinear s``,
1172  GEN_TAC THEN MATCH_MP_TAC COLLINEAR_SUBSET THEN
1173  EXISTS_TAC ``(0:real) INSERT (1:real) INSERT s`` THEN
1174  CONJ_TAC THENL [ALL_TAC, SET_TAC[]] THEN
1175  W(MP_TAC o PART_MATCH (lhs o rand) COLLINEAR_TRIPLES o snd) THEN
1176  REWRITE_TAC[REAL_ARITH ``0 <> 1:real``] THEN DISCH_THEN SUBST1_TAC THEN
1177  REWRITE_TAC[COLLINEAR_BETWEEN_CASES] THEN
1178  REWRITE_TAC[between, dist, ABS_N] THEN
1179  REAL_ARITH_TAC);
1180
1181(* ------------------------------------------------------------------------- *)
1182(* Midpoint between two points.                                              *)
1183(* ------------------------------------------------------------------------- *)
1184
1185val midpoint = new_definition ("midpoint",
1186 ``midpoint(a,b) = inv(&2:real) * (a + b)``);
1187
1188Theorem MIDPOINT_REFL: !x. midpoint(x,x) = x
1189Proof
1190  REWRITE_TAC[midpoint, REAL_DOUBLE, REAL_MUL_ASSOC] THEN
1191  SIMP_TAC std_ss [REAL_MUL_LINV, REAL_ARITH ``2 <> 0:real``] THEN
1192  REAL_ARITH_TAC
1193QED
1194
1195val MIDPOINT_SYM = store_thm ("MIDPOINT_SYM",
1196 ``!a b. midpoint(a,b) = midpoint(b,a)``,
1197  METIS_TAC[midpoint, REAL_ADD_SYM]);
1198
1199val DIST_MIDPOINT = store_thm ("DIST_MIDPOINT",
1200 ``!a b. (dist(a,midpoint(a,b)) = dist(a,b) / &2) /\
1201         (dist(b,midpoint(a,b)) = dist(a,b) / &2) /\
1202         (dist(midpoint(a,b),a) = dist(a,b) / &2) /\
1203         (dist(midpoint(a,b),b) = dist(a,b) / &2)``,
1204  REWRITE_TAC[midpoint, dist] THEN
1205  SIMP_TAC std_ss [REAL_EQ_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
1206  ONCE_REWRITE_TAC [GSYM ABS_N] THEN
1207  REWRITE_TAC [GSYM ABS_MUL, REAL_SUB_RDISTRIB] THEN REWRITE_TAC [ABS_N] THEN
1208  ONCE_REWRITE_TAC [REAL_ARITH ``a * b * c = a * c * b:real``] THEN
1209  SIMP_TAC std_ss [REAL_MUL_LINV, REAL_ARITH ``2 <> 0:real``] THEN
1210  REAL_ARITH_TAC);
1211
1212val MIDPOINT_EQ_ENDPOINT = store_thm ("MIDPOINT_EQ_ENDPOINT",
1213 ``!a b. ((midpoint(a,b) = a) <=> (a = b)) /\
1214         ((midpoint(a,b) = b) <=> (a = b)) /\
1215         ((a = midpoint(a,b)) <=> (a = b)) /\
1216         ((b = midpoint(a,b)) <=> (a = b))``,
1217  REWRITE_TAC[midpoint] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN
1218  REWRITE_TAC [GSYM real_div] THEN
1219  SIMP_TAC std_ss
1220    [REAL_EQ_RDIV_EQ, REAL_EQ_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
1221  REAL_ARITH_TAC);
1222
1223val BETWEEN_MIDPOINT = store_thm ("BETWEEN_MIDPOINT",
1224 ``!a b. between (midpoint(a,b)) (a,b) /\ between (midpoint(a,b)) (b,a)``,
1225  REWRITE_TAC[between, midpoint] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN
1226  REWRITE_TAC [dist, GSYM real_div] THEN
1227  ONCE_REWRITE_TAC [REAL_ARITH ``a / 2 - b = a / 2 - b * 1:real``] THEN
1228  ONCE_REWRITE_TAC [REAL_ARITH ``b - a / 2 = b * 1 - a / 2:real``] THEN
1229  REWRITE_TAC [
1230    METIS [REAL_DIV_REFL, REAL_ARITH ``2 <> 0:real``] ``1 = 2/2:real``] THEN
1231  REWRITE_TAC [real_div, REAL_MUL_ASSOC, real_sub] THEN
1232  REWRITE_TAC [REAL_ARITH ``-(a * b) = -a * b:real``] THEN
1233  REWRITE_TAC [GSYM real_div] THEN SIMP_TAC std_ss [REAL_DIV_ADD] THEN
1234  REWRITE_TAC [real_div, ABS_MUL] THEN
1235  SIMP_TAC std_ss [ABS_N, ABS_INV, REAL_ARITH ``2 <> 0:real``] THEN
1236  REWRITE_TAC [GSYM REAL_ADD_RDISTRIB] THEN REWRITE_TAC [GSYM real_div] THEN
1237  SIMP_TAC std_ss [REAL_EQ_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
1238  REAL_ARITH_TAC);
1239
1240val MIDPOINT_LINEAR_IMAGE = store_thm ("MIDPOINT_LINEAR_IMAGE",
1241 ``!f a b. linear f ==> (midpoint(f a,f b) = f(midpoint(a,b)))``,
1242  SIMP_TAC std_ss [midpoint, LINEAR_ADD, LINEAR_CMUL]);
1243
1244val COLLINEAR_MIDPOINT = store_thm ("COLLINEAR_MIDPOINT",
1245 ``!a b. collinear{a;midpoint(a,b);b}``,
1246  REPEAT GEN_TAC THEN REWRITE_TAC[COLLINEAR_3_EXPAND, midpoint] THEN
1247  DISJ2_TAC THEN REWRITE_TAC [REAL_ARITH ``u * a + (1 - u) * b =
1248                                           a * u - b * u + b:real``] THEN
1249  EXISTS_TAC ``inv &2:real`` THEN GEN_REWR_TAC LAND_CONV [REAL_MUL_SYM] THEN
1250  REWRITE_TAC [REAL_ADD_RDISTRIB] THEN
1251  GEN_REWR_TAC (RAND_CONV o RAND_CONV) [GSYM REAL_HALF] THEN
1252  REWRITE_TAC [GSYM real_div] THEN REAL_ARITH_TAC);
1253
1254Theorem MIDPOINT_COLLINEAR:
1255   !a b c:real.
1256     a <> c ==>
1257     ((b = midpoint(a,c)) <=> collinear{a;b;c} /\ (dist(a,b) = dist(b,c)))
1258Proof
1259  REPEAT STRIP_TAC THEN
1260  MATCH_MP_TAC(TAUT `(a ==> b) /\ (b ==> (a <=> c)) ==> (a <=> b /\ c)`) THEN
1261  SIMP_TAC std_ss [COLLINEAR_MIDPOINT] THEN
1262  ASM_REWRITE_TAC[COLLINEAR_3_EXPAND] THEN
1263  STRIP_TAC THEN ASM_REWRITE_TAC[midpoint, dist] THEN
1264  REWRITE_TAC
1265   [REAL_ARITH ``a - (u * a + (&1 - u) * c) = (&1 - u) * (a - c:real)``,
1266    REAL_ARITH ``(u * a + (&1 - u) * c) - c = u * (a - c:real)``] THEN
1267  ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN
1268  SIMP_TAC std_ss [REAL_EQ_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
1269  ASM_REAL_ARITH_TAC
1270QED
1271
1272(* ------------------------------------------------------------------------ *)
1273(*  MISC                                                                    *)
1274(* ------------------------------------------------------------------------ *)
1275
1276val INDEPENDENT_MONO = store_thm ("INDEPENDENT_MONO",
1277 ``!s t. independent t /\ s SUBSET t ==> independent s``,
1278 SIMP_TAC std_ss [independent, dependent] THEN
1279 ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_DELETE]);
1280
1281val SPAN_BREAKDOWN = store_thm ("SPAN_BREAKDOWN",
1282 ``!b s a:real. b IN s /\ a IN span s ==> ?k. (a - k * b) IN span(s DELETE b)``,
1283  SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN
1284  REPEAT GEN_TAC THEN DISCH_TAC THEN
1285  ONCE_REWRITE_TAC [METIS []
1286   ``(?k:real. a - k * b IN span (s DELETE b)) =
1287     (\a. ?k. a - k * b IN span (s DELETE b)) a``] THEN
1288  MATCH_MP_TAC SPAN_INDUCT THEN
1289  SIMP_TAC std_ss [subspace, GSPECIFICATION] THEN CONJ_TAC THENL
1290   [GEN_TAC THEN DISCH_TAC THEN ASM_CASES_TAC ``x:real = b``, ALL_TAC] THEN
1291  ASM_SIMP_TAC std_ss [IN_DEF] THENL
1292  [EXISTS_TAC ``1:real`` THEN SIMP_TAC real_ss [] THEN
1293   ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN REWRITE_TAC [SPAN_CLAUSES],
1294   EXISTS_TAC ``0:real`` THEN SIMP_TAC real_ss [] THEN
1295   ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN MATCH_MP_TAC SPAN_SUPERSET THEN
1296   ASM_SET_TAC [],
1297   ALL_TAC] THEN REPEAT CONJ_TAC THENL
1298   [EXISTS_TAC ``0:real`` THEN SIMP_TAC real_ss [] THEN
1299    ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN REWRITE_TAC [SPAN_CLAUSES],
1300    REPEAT STRIP_TAC THEN EXISTS_TAC ``k + k':real`` THEN
1301    ONCE_REWRITE_TAC [REAL_ARITH
1302     ``(x + y - (k + k') * b) = ((x - k * b) + (y - k' * b:real))``] THEN
1303    ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN
1304    RULE_ASSUM_TAC (ONCE_REWRITE_RULE [GSYM SPECIFICATION]) THEN
1305    METIS_TAC [SPAN_ADD],
1306    REPEAT STRIP_TAC THEN EXISTS_TAC ``c * k:real`` THEN
1307    ONCE_REWRITE_TAC [
1308      REAL_ARITH ``(c * x - (c * k) * y = c * (x - k * y:real))``] THEN
1309    ONCE_REWRITE_TAC [GSYM SPECIFICATION] THEN
1310    RULE_ASSUM_TAC (ONCE_REWRITE_RULE [GSYM SPECIFICATION]) THEN
1311    METIS_TAC [SPAN_CLAUSES]]);
1312
1313val IN_SPAN_INSERT = store_thm ("IN_SPAN_INSERT",
1314 ``!a b:real s. a IN span(b INSERT s) /\ ~(a IN span s)
1315   ==> b IN span(a INSERT s)``,
1316  REPEAT STRIP_TAC THEN
1317  MP_TAC(ISPECL [``b:real``, ``(b:real) INSERT s``, ``a:real``]
1318    SPAN_BREAKDOWN) THEN ASM_REWRITE_TAC[IN_INSERT] THEN
1319  DISCH_THEN(X_CHOOSE_THEN ``k:real`` MP_TAC) THEN
1320  ASM_CASES_TAC ``k = &0:real`` THEN
1321  ASM_REWRITE_TAC[REAL_ARITH ``a - &0 * b = a:real``, DELETE_INSERT] THENL
1322   [ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, DELETE_SUBSET], ALL_TAC] THEN
1323  DISCH_THEN(MP_TAC o SPEC ``inv(k:real)`` o MATCH_MP SPAN_MUL) THEN
1324  ASM_SIMP_TAC real_ss [REAL_SUB_LDISTRIB, REAL_MUL_ASSOC, REAL_MUL_LINV] THEN
1325  DISCH_TAC THEN SUBST1_TAC(REAL_ARITH
1326   ``b:real = inv(k) * a - (inv(k) * a - b)``) THEN
1327  MATCH_MP_TAC SPAN_SUB THEN
1328  FULL_SIMP_TAC std_ss [SPAN_CLAUSES, IN_INSERT, SUBSET_DEF, IN_DELETE,
1329                        SPAN_MONO] THEN
1330  POP_ASSUM MP_TAC THEN ABBREV_TAC ``y = inv k * a - b:real`` THEN
1331  SPEC_TAC (``y:real``, ``y:real``) THEN REWRITE_TAC [GSYM SUBSET_DEF] THEN
1332  MATCH_MP_TAC SPAN_MONO THEN ASM_SET_TAC []);
1333
1334val INDEPENDENT_INSERT = store_thm ("INDEPENDENT_INSERT",
1335 ``!a:real s. independent(a INSERT s) <=>
1336    if a IN s then independent s else independent s /\ ~(a IN span s)``,
1337  REPEAT GEN_TAC THEN ASM_CASES_TAC ``(a:real) IN s`` THEN
1338  ASM_SIMP_TAC std_ss [SET_RULE ``x IN s ==> (x INSERT s = s)``] THEN
1339  EQ_TAC THENL
1340   [DISCH_TAC THEN CONJ_TAC THENL
1341     [ASM_MESON_TAC[INDEPENDENT_MONO, SUBSET_DEF, IN_INSERT],
1342      POP_ASSUM MP_TAC THEN REWRITE_TAC[independent, dependent] THEN
1343      ASM_MESON_TAC[IN_INSERT, SET_RULE
1344        ``~(a IN s) ==> ((a INSERT s) DELETE a = s)``]],
1345    ALL_TAC] THEN
1346  SIMP_TAC std_ss [independent, dependent, NOT_EXISTS_THM] THEN
1347  STRIP_TAC THEN X_GEN_TAC ``b:real`` THEN
1348  REWRITE_TAC[IN_INSERT] THEN ASM_CASES_TAC ``b:real = a`` THEN
1349  ASM_SIMP_TAC std_ss [
1350    SET_RULE ``~(a IN s) ==> ((a INSERT s) DELETE a = s)``] THEN
1351  ASM_SIMP_TAC std_ss [SET_RULE ``~(a IN s) /\ ~(b = a)
1352     ==> ((a INSERT s) DELETE b = a INSERT (s DELETE b))``] THEN
1353  ASM_MESON_TAC[IN_SPAN_INSERT, SET_RULE
1354    ``b IN s ==> (b INSERT (s DELETE b) = s)``]);
1355
1356val INDEPENDENT_EMPTY = store_thm ("INDEPENDENT_EMPTY",
1357 ``independent {}``,
1358  REWRITE_TAC[independent, dependent, NOT_IN_EMPTY]);
1359
1360val INDEPENDENT_SING = store_thm ("INDEPENDENT_SING",
1361 ``!x. independent {x} <=> ~(x = 0)``,
1362  REWRITE_TAC[INDEPENDENT_INSERT, NOT_IN_EMPTY, SPAN_EMPTY] THEN
1363  REWRITE_TAC[INDEPENDENT_EMPTY] THEN SET_TAC[]);
1364
1365val INDEPENDENT_STDBASIS = store_thm ("INDEPENDENT_STDBASIS",
1366 ``independent {i:real | 1 <= i /\ i <= 1}``,
1367 REWRITE_TAC [REAL_LE_ANTISYM, GSPEC_EQ2] THEN
1368 REWRITE_TAC [INDEPENDENT_SING] THEN REAL_ARITH_TAC);
1369
1370val SPANNING_SUBSET_INDEPENDENT = store_thm ("SPANNING_SUBSET_INDEPENDENT",
1371 ``!s t:real->bool.
1372        t SUBSET s /\ independent s /\ s SUBSET span(t) ==> (s = t)``,
1373  REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
1374  ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET_DEF] THEN
1375  X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN
1376  UNDISCH_TAC ``independent s`` THEN DISCH_TAC THEN
1377  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [independent]) THEN
1378  SIMP_TAC std_ss [dependent, NOT_EXISTS_THM] THEN
1379  DISCH_THEN(MP_TAC o SPEC ``a:real``) THEN ASM_REWRITE_TAC[] THEN
1380  ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_DELETE]);
1381
1382val IN_SPAN_DELETE = store_thm ("IN_SPAN_DELETE",
1383 ``!a b s.
1384         a IN span s /\ ~(a IN span (s DELETE b))
1385         ==> b IN span (a INSERT (s DELETE b))``,
1386  ASM_MESON_TAC[IN_SPAN_INSERT, SPAN_MONO, SUBSET_DEF, IN_INSERT, IN_DELETE]);
1387
1388val SPAN_TRANS = store_thm ("SPAN_TRANS",
1389 ``!x y:real s. x IN span(s) /\ y IN span(x INSERT s) ==> y IN span(s)``,
1390  REPEAT STRIP_TAC THEN
1391  MP_TAC(SPECL [``x:real``, ``(x:real) INSERT s``, ``y:real``]
1392         SPAN_BREAKDOWN) THEN
1393  ASM_SIMP_TAC std_ss [IN_INSERT] THEN
1394  DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN
1395  SUBST1_TAC(REAL_ARITH ``y:real = (y - k * x) + k * x``) THEN
1396  MATCH_MP_TAC SPAN_ADD THEN ASM_SIMP_TAC std_ss [SPAN_MUL] THEN
1397  ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_INSERT, IN_DELETE]);
1398
1399val EXCHANGE_LEMMA = store_thm ("EXCHANGE_LEMMA",
1400 ``!s t:real->bool.
1401        FINITE t /\ independent s /\ s SUBSET span t
1402        ==> ?t'. t' HAS_SIZE (CARD t) /\
1403                 s SUBSET t' /\ t' SUBSET (s UNION t) /\ s SUBSET (span t')``,
1404  REPEAT GEN_TAC THEN
1405  completeInduct_on `CARD(t DIFF s :real->bool)` THEN
1406  GEN_TAC THEN GEN_TAC THEN DISCH_TAC THEN FULL_SIMP_TAC std_ss [] THEN
1407  POP_ASSUM K_TAC THEN
1408  KNOW_TAC ``(!m. m < CARD (t:real->bool DIFF s) ==>
1409    !t:real->bool s:real->bool. (m = CARD (t DIFF s)) ==>
1410      FINITE t /\ independent s /\ s SUBSET span t ==>
1411      ?t'. t' HAS_SIZE CARD t /\ s SUBSET t' /\ t' SUBSET s UNION t /\
1412        s SUBSET span t') ==>
1413    (!t'':real->bool s':real->bool'. (CARD (t'' DIFF s') < CARD (t DIFF s)) ==>
1414      FINITE t'' /\ independent s' /\ s' SUBSET span t'' ==>
1415      ?t'. t' HAS_SIZE CARD t'' /\ s' SUBSET t' /\ t' SUBSET s' UNION t'' /\
1416        s' SUBSET span t')`` THENL
1417  [METIS_TAC [], ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN DISCH_TAC] THEN
1418  ASM_CASES_TAC ``(s:real->bool) SUBSET t`` THENL
1419   [ASM_MESON_TAC[HAS_SIZE, SUBSET_UNION], ALL_TAC] THEN
1420  ASM_CASES_TAC ``t SUBSET (s:real->bool)`` THENL
1421   [ASM_MESON_TAC[SPANNING_SUBSET_INDEPENDENT, HAS_SIZE], ALL_TAC] THEN
1422  STRIP_TAC THEN UNDISCH_TAC ``~(t SUBSET s:real->bool)`` THEN DISCH_TAC THEN
1423  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN
1424  SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP] THEN
1425  DISCH_THEN(X_CHOOSE_THEN ``b:real`` STRIP_ASSUME_TAC) THEN
1426  ASM_CASES_TAC ``s SUBSET span(t DELETE (b:real))`` THENL
1427   [FIRST_X_ASSUM(MP_TAC o
1428     SPECL [``t DELETE (b:real)``, ``s:real->bool``]) THEN
1429    ASM_REWRITE_TAC[SET_RULE ``s DELETE a DIFF t = (s DIFF t) DELETE a``] THEN
1430    ASM_SIMP_TAC arith_ss [CARD_DELETE, FINITE_DIFF, IN_DIFF, FINITE_DELETE,
1431                 CARD_EQ_0, ARITH_PROVE ``n - 1 < n <=> ~(n = 0:num)``] THEN
1432    KNOW_TAC ``t DIFF s <> {}:real->bool`` THENL
1433     [UNDISCH_TAC ``~((s:real->bool) SUBSET t)`` THEN ASM_SET_TAC[],
1434      DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
1435    DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN
1436    EXISTS_TAC ``(b:real) INSERT u`` THEN
1437    ASM_SIMP_TAC std_ss [SUBSET_INSERT, INSERT_SUBSET, IN_UNION] THEN
1438    CONJ_TAC THENL
1439     [UNDISCH_TAC ``(u:real->bool) HAS_SIZE CARD(t:real->bool) - 1`` THEN
1440      SIMP_TAC std_ss [HAS_SIZE, FINITE_EMPTY, FINITE_INSERT, CARD_EMPTY,
1441                       CARD_INSERT] THEN
1442      STRIP_TAC THEN COND_CASES_TAC THENL
1443       [ASM_MESON_TAC[SUBSET_DEF, IN_UNION, IN_DELETE], ALL_TAC] THEN
1444      ASM_MESON_TAC[ARITH_PROVE ``~(n = 0) ==> (SUC(n - 1) = n)``,
1445                    CARD_EQ_0, MEMBER_NOT_EMPTY], ALL_TAC] THEN
1446    CONJ_TAC THENL
1447     [UNDISCH_TAC ``u SUBSET s UNION (t DELETE (b:real))`` THEN SET_TAC[],
1448      ASM_MESON_TAC[SUBSET_DEF, SPAN_MONO, IN_INSERT]],
1449    ALL_TAC] THEN
1450  UNDISCH_TAC ``~(s SUBSET span (t DELETE (b:real)))`` THEN
1451  GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SUBSET_DEF] THEN
1452  SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP] THEN
1453  DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN
1454  SUBGOAL_THEN ``~(a:real = b)`` ASSUME_TAC THENL
1455    [ASM_MESON_TAC[], ALL_TAC] THEN
1456  SUBGOAL_THEN ``~((a:real) IN t)`` ASSUME_TAC THENL
1457   [ASM_MESON_TAC[IN_DELETE, SPAN_CLAUSES], ALL_TAC] THEN
1458  FIRST_X_ASSUM(MP_TAC o SPECL
1459   [``(a:real) INSERT (t DELETE b)``, ``s:real->bool``]) THEN
1460  KNOW_TAC ``CARD ((a INSERT t DELETE b) DIFF s) < CARD (t DIFF s:real->bool)``
1461  THENL
1462   [ASM_SIMP_TAC std_ss [SET_RULE
1463     ``a IN s ==> ((a INSERT (t DELETE b)) DIFF s = (t DIFF s) DELETE b)``] THEN
1464    KNOW_TAC ``(b:real) IN (t DIFF s)``
1465      THENL [METIS_TAC [IN_DIFF], DISCH_TAC] THEN
1466    KNOW_TAC ``FINITE (t DIFF s:real->bool)``
1467      THENL [METIS_TAC [FINITE_DIFF], ALL_TAC] THEN
1468    SIMP_TAC std_ss [CARD_DELETE] THEN ASM_REWRITE_TAC [] THEN DISCH_TAC THEN
1469    ASM_SIMP_TAC std_ss [ARITH_PROVE ``n - 1 < n <=> ~(n = 0:num)``, CARD_EQ_0,
1470                 FINITE_DIFF] THEN
1471    UNDISCH_TAC ``~((s:real->bool) SUBSET t)`` THEN ASM_SET_TAC[],
1472    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
1473  KNOW_TAC ``FINITE ((a:real) INSERT t DELETE b) /\
1474             s SUBSET span (a INSERT t DELETE b)`` THENL
1475   [ASM_SIMP_TAC std_ss [FINITE_EMPTY, FINITE_INSERT, FINITE_DELETE] THEN
1476    REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN
1477    DISCH_TAC THEN MATCH_MP_TAC SPAN_TRANS THEN EXISTS_TAC ``b:real`` THEN
1478    ASM_MESON_TAC[IN_SPAN_DELETE, SUBSET_DEF, SPAN_MONO,
1479                  SET_RULE ``t SUBSET (b INSERT (a INSERT (t DELETE b)))``],
1480    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
1481  DISCH_THEN (X_CHOOSE_TAC ``u:real->bool``) THEN
1482  EXISTS_TAC ``u:real->bool`` THEN
1483  POP_ASSUM MP_TAC THEN
1484  ASM_SIMP_TAC std_ss [HAS_SIZE, CARD_EMPTY, CARD_INSERT, CARD_DELETE,
1485                       FINITE_DELETE,
1486                       IN_DELETE, ARITH_PROVE ``(SUC(n - 1) = n) <=> ~(n = 0)``,
1487                       CARD_EQ_0] THEN
1488  UNDISCH_TAC ``(b:real) IN t`` THEN ASM_SET_TAC[]);
1489
1490val CARD_STDBASIS = store_thm ("CARD_STDBASIS",
1491 ``CARD {1:real} = 1``,
1492   MESON_TAC[CARD_SING]);
1493
1494val INDEPENDENT_SPAN_BOUND = store_thm ("INDEPENDENT_SPAN_BOUND",
1495 ``!s t. FINITE t /\ independent s /\ s SUBSET span(t)
1496         ==> FINITE s /\ CARD(s) <= CARD(t)``,
1497  REPEAT GEN_TAC THEN DISCH_TAC THEN
1498  FIRST_ASSUM(MP_TAC o MATCH_MP EXCHANGE_LEMMA) THEN
1499  ASM_MESON_TAC[HAS_SIZE, CARD_SUBSET, SUBSET_FINITE_I]);
1500
1501val INDEPENDENT_BOUND = store_thm ("INDEPENDENT_BOUND",
1502 ``!s:real->bool.
1503        independent s ==> FINITE s /\ CARD(s) <= 1:num``,
1504  REPEAT GEN_TAC THEN DISCH_TAC THEN
1505  ONCE_REWRITE_TAC[GSYM CARD_STDBASIS] THEN
1506  MATCH_MP_TAC INDEPENDENT_SPAN_BOUND THEN
1507  KNOW_TAC ``span {1} = univ(:real)`` THENL
1508  [SIMP_TAC std_ss [EXTENSION, span, hull, IN_BIGINTER, IN_UNIV] THEN
1509   SIMP_TAC std_ss [SING_SUBSET, GSPECIFICATION, subspace] THEN
1510   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_MUL_RID] THEN
1511   FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC [],
1512   DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
1513  ASM_REWRITE_TAC[FINITE_SING, SUBSET_UNIV]);
1514
1515val MAXIMAL_INDEPENDENT_SUBSET_EXTEND = store_thm ("MAXIMAL_INDEPENDENT_SUBSET_EXTEND",
1516 ``!s v:real->bool. s SUBSET v /\ independent s ==> ?b. s SUBSET b /\ b SUBSET v /\
1517   independent b /\ v SUBSET (span b)``,
1518  REPEAT GEN_TAC THEN
1519  completeInduct_on `(1:num) - CARD(s:real->bool)` THEN
1520  GEN_TAC THEN DISCH_TAC THEN FULL_SIMP_TAC std_ss [] THEN POP_ASSUM K_TAC THEN
1521  REPEAT STRIP_TAC THEN
1522  ASM_CASES_TAC ``v SUBSET (span(s:real->bool))`` THENL
1523   [ASM_MESON_TAC[SUBSET_REFL], ALL_TAC] THEN
1524  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN
1525  SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP] THEN
1526  DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN
1527  KNOW_TAC ``(!(m :num). m < (1 :num) - CARD (s :real -> bool) ==>
1528        !(s :real -> bool). (m = (1 :num) - CARD s) ==>
1529          s SUBSET (v :real -> bool) /\ independent s ==>
1530          ?(b :real -> bool).
1531            s SUBSET b /\ b SUBSET v /\ independent b /\ v SUBSET span b) ==>
1532        !s'. (1 - CARD s' < 1 - CARD s) ==> s' SUBSET v /\ independent s' ==>
1533          ?b. s' SUBSET b /\ b SUBSET v /\ independent b /\ v SUBSET span b`` THENL
1534  [METIS_TAC [], ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN
1535  FIRST_X_ASSUM(MP_TAC o SPEC ``(a:real) INSERT s``) THEN
1536  REWRITE_TAC[AND_IMP_INTRO] THEN
1537  KNOW_TAC ``1 - CARD (a INSERT s) < 1 - CARD s /\ a INSERT s SUBSET v /\
1538              independent (a INSERT s:real->bool)`` THENL
1539   [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
1540             MESON_TAC[INSERT_SUBSET]] THEN
1541  SUBGOAL_THEN ``independent ((a:real) INSERT s)`` ASSUME_TAC THENL
1542   [ASM_REWRITE_TAC[INDEPENDENT_INSERT, COND_ID], ALL_TAC] THEN
1543  ASM_REWRITE_TAC[INSERT_SUBSET] THEN
1544  MATCH_MP_TAC(ARITH_PROVE ``(b = a + 1) /\ b <= n ==> n - b < n - a:num``) THEN
1545  ASM_SIMP_TAC std_ss [CARD_EMPTY, CARD_INSERT, INDEPENDENT_BOUND] THEN
1546  METIS_TAC[SPAN_SUPERSET, ADD1]);
1547
1548val MAXIMAL_INDEPENDENT_SUBSET = store_thm ("MAXIMAL_INDEPENDENT_SUBSET",
1549 ``!v:real->bool. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b)``,
1550  MP_TAC(SPEC ``EMPTY:real->bool`` MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN
1551  REWRITE_TAC[EMPTY_SUBSET, INDEPENDENT_EMPTY]);
1552
1553val SPAN_BREAKDOWN_EQ = store_thm ("SPAN_BREAKDOWN_EQ",
1554 ``!a:real s. (x IN span(a INSERT s) <=> (?k. (x - k * a) IN span s))``,
1555  REPEAT STRIP_TAC THEN EQ_TAC THENL
1556   [DISCH_THEN(MP_TAC o CONJ(SET_RULE ``(a:real) IN (a INSERT s)``)) THEN
1557    DISCH_THEN(MP_TAC o MATCH_MP SPAN_BREAKDOWN) THEN
1558    DISCH_THEN (X_CHOOSE_TAC ``k:real``) THEN EXISTS_TAC ``k:real`` THEN
1559    POP_ASSUM MP_TAC THEN SPEC_TAC(``x - k * a:real``,``y:real``) THEN
1560    REWRITE_TAC[GSYM SUBSET_DEF] THEN MATCH_MP_TAC SPAN_MONO THEN SET_TAC[],
1561    DISCH_THEN(X_CHOOSE_TAC ``k:real``) THEN
1562    SUBST1_TAC(REAL_ARITH ``x = (x - k * a) + k * a:real``) THEN
1563    MATCH_MP_TAC SPAN_ADD THEN
1564    ASM_MESON_TAC[SPAN_MONO, SUBSET_DEF, IN_INSERT, SPAN_CLAUSES]]);
1565
1566val LINEAR_INDEPENDENT_EXTEND_LEMMA = store_thm ("LINEAR_INDEPENDENT_EXTEND_LEMMA",
1567 ``!f b. FINITE b ==> independent b ==>
1568    ?g:real->real. (!x y. x IN span b /\ y IN span b ==>
1569     (g(x + y) = g(x) + g(y))) /\ (!x c. x IN span b ==>
1570     (g(c * x) = c * g(x))) /\ (!x. x IN b ==> (g x = f x))``,
1571  GEN_TAC THEN
1572  ONCE_REWRITE_TAC [METIS []
1573   ``!b. (independent b ==>
1574  ?g. (!x y. x IN span b /\ y IN span b ==> (g (x + y) = g x + g y)) /\
1575    (!x c. x IN span b ==> (g (c * x) = c * g x)) /\
1576    !x. x IN b ==> (g x = f x)) =
1577    (\b. independent b ==>
1578  ?g. (!x y. x IN span b /\ y IN span b ==> (g (x + y) = g x + g y)) /\
1579    (!x c. x IN span b ==> (g (c * x) = c * g x)) /\
1580    !x. x IN b ==> (g x = f x)) b``] THEN
1581  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
1582  REWRITE_TAC[NOT_IN_EMPTY, INDEPENDENT_INSERT] THEN CONJ_TAC THENL
1583   [REPEAT STRIP_TAC THEN EXISTS_TAC ``(\x. 0):real->real`` THEN
1584    SIMP_TAC std_ss [SPAN_EMPTY] THEN REPEAT STRIP_TAC THEN REAL_ARITH_TAC,
1585    ALL_TAC] THEN
1586  SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN
1587  MAP_EVERY X_GEN_TAC [``b:real->bool``, ``a:real``] THEN
1588  REWRITE_TAC [AND_IMP_INTRO] THEN ONCE_REWRITE_TAC [CONJ_SYM] THEN
1589  REWRITE_TAC [CONJ_EQ_IMP] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
1590  DISCH_TAC THEN DISCH_TAC THEN REWRITE_TAC [AND_IMP_INTRO] THEN
1591  DISCH_THEN (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
1592  DISCH_THEN(X_CHOOSE_THEN ``g:real->real`` STRIP_ASSUME_TAC) THEN
1593  ABBREV_TAC ``h = \z:real. @k. (z - k * a) IN span b`` THEN
1594  SUBGOAL_THEN ``!z:real. z IN span(a INSERT b)
1595                    ==> (z - h(z) * a) IN span(b) /\
1596                        !k. (z - k * a) IN span(b) ==> (k = h(z))``
1597  MP_TAC THENL
1598   [GEN_TAC THEN DISCH_TAC THEN
1599    MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
1600     [EXPAND_TAC "h" THEN CONV_TAC SELECT_CONV THEN
1601      ASM_MESON_TAC[SPAN_BREAKDOWN_EQ],
1602      ALL_TAC] THEN
1603    SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM, AND_IMP_INTRO] THEN GEN_TAC THEN
1604    DISCH_THEN(MP_TAC o MATCH_MP SPAN_SUB) THEN
1605    REWRITE_TAC[REAL_ARITH ``(z - a * v) - (z - b * v) = (b - a) * v:real``] THEN
1606    ASM_CASES_TAC ``k = (h:real->real) z`` THEN ASM_REWRITE_TAC[] THEN
1607    DISCH_THEN(MP_TAC o SPEC ``inv(k - (h:real->real) z)`` o
1608               MATCH_MP SPAN_MUL) THEN
1609    ASM_SIMP_TAC real_ss [REAL_MUL_LINV, REAL_MUL_ASSOC, REAL_SUB_0],
1610    ALL_TAC] THEN
1611  SIMP_TAC std_ss [TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN
1612  SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM, AND_IMP_INTRO] THEN
1613  DISCH_THEN (MP_TAC o SIMP_RULE std_ss [FORALL_AND_THM]) THEN STRIP_TAC THEN
1614  EXISTS_TAC ``\z:real. h(z) * (f:real->real)(a) + g(z - h(z) * a)`` THEN
1615  ONCE_REWRITE_TAC [CONJ_SYM] THEN REPEAT CONJ_TAC THENL
1616   [MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN
1617    SUBGOAL_THEN ``(h:real->real)(x + y) = h(x) + h(y)`` ASSUME_TAC THENL
1618     [CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
1619      REWRITE_TAC[REAL_ARITH
1620       ``(x + y) - (k + l) * a = (x - k * a) + (y - l * a:real)``] THEN
1621      CONJ_TAC THEN MATCH_MP_TAC SPAN_ADD THEN ASM_REWRITE_TAC[] THEN
1622      ASM_SIMP_TAC std_ss [],
1623      ALL_TAC] THEN
1624    ASM_SIMP_TAC std_ss [REAL_ARITH
1625       ``(x + y) - (k + l) * a = (x - k * a) + (y - l * a:real)``] THEN
1626    ASM_SIMP_TAC std_ss [] THEN REAL_ARITH_TAC,
1627    MAP_EVERY X_GEN_TAC [``x:real``, ``c:real``] THEN STRIP_TAC THEN
1628    SUBGOAL_THEN ``(h:real->real)(c * x) = c * h(x)`` ASSUME_TAC THENL
1629     [CONV_TAC SYM_CONV THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
1630      REWRITE_TAC[REAL_ARITH
1631       ``c * x - (c * k) * a = c * (x - k * a:real)``] THEN
1632      CONJ_TAC THEN MATCH_MP_TAC SPAN_MUL THEN ASM_REWRITE_TAC[] THEN
1633      ASM_SIMP_TAC std_ss [],
1634      ALL_TAC] THEN
1635    ASM_SIMP_TAC std_ss [REAL_ARITH
1636       ``c * x - (c * k) * a = c * (x - k * a:real)``] THEN
1637    ASM_SIMP_TAC std_ss [] THEN REAL_ARITH_TAC,
1638    ALL_TAC] THEN
1639  X_GEN_TAC ``x:real`` THEN SIMP_TAC std_ss [IN_INSERT] THEN
1640  DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THENL
1641   [SUBGOAL_THEN ``&1:real = h(a:real)`` (SUBST1_TAC o SYM) THENL
1642     [FIRST_X_ASSUM MATCH_MP_TAC, ALL_TAC] THEN
1643    REWRITE_TAC[REAL_ARITH ``a - &1 * a = 0:real``, SPAN_0] THENL
1644     [ASM_MESON_TAC[SPAN_SUPERSET, SUBSET_DEF, IN_INSERT], ALL_TAC] THEN
1645    UNDISCH_TAC ``!x y:real. x IN span b /\ y IN span b ==>
1646                        ((g:real->real) (x + y) = g x + g y)`` THEN
1647    DISCH_TAC THEN SIMP_TAC std_ss [] THEN
1648    FIRST_X_ASSUM(MP_TAC o SPECL [``0:real``, ``0:real``]) THEN
1649    SIMP_TAC real_ss [SPAN_0, REAL_ADD_LID] THEN
1650    REWRITE_TAC[REAL_ARITH ``(a = a + a) <=> (a = 0:real)``] THEN
1651    DISCH_THEN SUBST1_TAC THEN REAL_ARITH_TAC,
1652    ALL_TAC] THEN
1653  SUBGOAL_THEN ``&0:real = h(x:real)`` (SUBST1_TAC o SYM) THENL
1654   [FIRST_X_ASSUM MATCH_MP_TAC, ALL_TAC] THEN
1655  SIMP_TAC std_ss [REAL_ADD_LID, REAL_MUL_LZERO, REAL_SUB_RZERO] THEN
1656  ASM_MESON_TAC[SUBSET_DEF, IN_INSERT, SPAN_SUPERSET]);
1657
1658val LINEAR_INDEPENDENT_EXTEND = store_thm ("LINEAR_INDEPENDENT_EXTEND",
1659 ``!f b. independent b ==> ?g:real->real. linear g /\ (!x. x IN b ==> (g x = f x))``,
1660  REPEAT STRIP_TAC THEN
1661  MP_TAC(ISPECL [``b:real->bool``, ``univ(:real)``]
1662           MAXIMAL_INDEPENDENT_SUBSET_EXTEND) THEN
1663  ASM_SIMP_TAC std_ss [SUBSET_UNIV, UNIV_SUBSET] THEN
1664  REWRITE_TAC[EXTENSION, IN_UNIV] THEN
1665  DISCH_THEN(X_CHOOSE_THEN ``c:real->bool`` STRIP_ASSUME_TAC) THEN
1666  MP_TAC(ISPECL [``f:real->real``, ``c:real->bool``]
1667    LINEAR_INDEPENDENT_EXTEND_LEMMA) THEN
1668  ASM_SIMP_TAC std_ss [INDEPENDENT_BOUND, linear] THEN
1669  ASM_MESON_TAC[SUBSET_DEF]);
1670
1671val SUBSPACE_KERNEL = store_thm ("SUBSPACE_KERNEL",
1672 ``!f. linear f ==> subspace {x | f(x) = 0}``,
1673  SIMP_TAC std_ss [subspace, GSPECIFICATION] THEN
1674  SIMP_TAC std_ss [LINEAR_ADD, LINEAR_CMUL, REAL_ADD_LID, REAL_MUL_RZERO] THEN
1675  MESON_TAC[LINEAR_0]);
1676
1677val LINEAR_EQ_0_SPAN = store_thm ("LINEAR_EQ_0_SPAN",
1678 ``!f:real->real b. linear f /\ (!x. x IN b ==> (f(x) = 0))
1679   ==> !x. x IN span(b) ==> (f(x) = 0)``,
1680  REPEAT GEN_TAC THEN STRIP_TAC THEN RULE_ASSUM_TAC(SIMP_RULE std_ss [IN_DEF]) THEN
1681  ONCE_REWRITE_TAC [METIS [] ``(f x = 0) = (\x. (f:real->real) x = 0) x``] THEN
1682  MATCH_MP_TAC SPAN_INDUCT THEN ASM_SIMP_TAC std_ss [IN_DEF] THEN
1683  MP_TAC(ISPEC ``f:real->real`` SUBSPACE_KERNEL) THEN ASM_REWRITE_TAC[] THEN
1684  MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN
1685  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_DEF]);
1686
1687val LINEAR_EQ_0 = store_thm ("LINEAR_EQ_0",
1688 ``!f b s. linear f /\ s SUBSET (span b) /\
1689   (!x. x IN b ==> (f(x) = 0)) ==> !x. x IN s ==> (f(x) = 0)``,
1690  MESON_TAC[LINEAR_EQ_0_SPAN, SUBSET_DEF]);
1691
1692val LINEAR_EQ = store_thm ("LINEAR_EQ",
1693 ``!f g b s. linear f /\ linear g /\ s SUBSET (span b) /\
1694    (!x. x IN b ==> (f(x) = g(x))) ==> !x. x IN s ==> (f(x) = g(x))``,
1695  REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN STRIP_TAC THEN
1696  ONCE_REWRITE_TAC [METIS [] ``(f x - g x = 0) = ((\x. (f:real->real) x - g x) x = 0)``] THEN
1697  MATCH_MP_TAC LINEAR_EQ_0 THEN SIMP_TAC std_ss [] THEN METIS_TAC[LINEAR_COMPOSE_SUB]);
1698
1699val LINEAR_EQ_STDBASIS = store_thm ("LINEAR_EQ_STDBASIS",
1700 ``!f:real->real g. linear f /\ linear g /\
1701   (!i. 1 <= i /\ i <= 1 ==> (f i = g i)) ==> (f = g)``,
1702  REPEAT STRIP_TAC THEN
1703  SUBGOAL_THEN ``!x. x IN UNIV ==> ((f:real->real) x = g x)``
1704   (fn th => MP_TAC th THEN SIMP_TAC std_ss [FUN_EQ_THM, IN_UNIV]) THEN
1705  MATCH_MP_TAC LINEAR_EQ THEN
1706  EXISTS_TAC ``{i :real | 1 <= i /\ i <= 1}`` THEN
1707  ASM_SIMP_TAC std_ss [SUBSET_REFL, GSPECIFICATION] THEN
1708  REWRITE_TAC [REAL_LE_ANTISYM, GSPEC_EQ2] THEN
1709  KNOW_TAC ``span {1} = univ(:real)`` THENL
1710  [ALL_TAC, SIMP_TAC std_ss [SUBSET_REFL]] THEN
1711  SIMP_TAC std_ss [EXTENSION, span, hull, IN_BIGINTER, IN_UNIV] THEN
1712  SIMP_TAC std_ss [SING_SUBSET, GSPECIFICATION, subspace] THEN
1713  REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_MUL_RID] THEN
1714  FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC []);
1715
1716val LINEAR_INJECTIVE_LEFT_INVERSE = store_thm ("LINEAR_INJECTIVE_LEFT_INVERSE",
1717 ``!f:real->real. linear f /\ (!x y. (f x = f y) ==> (x = y))
1718                  ==> ?g. linear g /\ (g o f = (\x. x))``,
1719  REWRITE_TAC[INJECTIVE_LEFT_INVERSE] THEN REPEAT STRIP_TAC THEN
1720  SUBGOAL_THEN ``?h. linear(h:real->real) /\
1721                    !x. x IN IMAGE (f:real->real) {i | 1 <= i /\ i <= 1}
1722                  ==> (h x = g x)`` MP_TAC THENL
1723  [MATCH_MP_TAC LINEAR_INDEPENDENT_EXTEND THEN
1724   SIMP_TAC std_ss [REAL_LE_ANTISYM, GSPEC_EQ2, IMAGE_SING] THEN
1725   SIMP_TAC std_ss [INDEPENDENT_SING] THEN
1726   KNOW_TAC ``?g. !x. g ((f:real->real) x) = x`` THENL
1727   [METIS_TAC [], REWRITE_TAC [GSYM INJECTIVE_LEFT_INVERSE] THEN DISCH_TAC] THEN
1728   FULL_SIMP_TAC std_ss [linear] THEN KNOW_TAC ``0 = (f:real->real) 0`` THENL
1729   [UNDISCH_TAC ``!c x. (f:real->real) (c * x) = c * f x`` THEN
1730    DISCH_THEN (MP_TAC o SPECL [``0:real``, ``0:real``]) THEN REAL_ARITH_TAC,
1731    DISCH_TAC THEN ONCE_ASM_REWRITE_TAC []] THEN DISCH_TAC THEN
1732   UNDISCH_TAC ``!x y. ((f:real->real) x = f y) ==> (x = y)`` THEN
1733   DISCH_THEN (MP_TAC o SPECL [``1:real``,``0:real``]) THEN
1734   POP_ASSUM MP_TAC THEN REAL_ARITH_TAC,
1735   DISCH_THEN (X_CHOOSE_TAC ``h:real->real``) THEN EXISTS_TAC ``h:real->real`` THEN
1736   POP_ASSUM MP_TAC THEN
1737   ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE, GSPECIFICATION] THEN STRIP_TAC THEN
1738   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC LINEAR_EQ_STDBASIS THEN
1739   ASM_SIMP_TAC std_ss [LINEAR_ID, LINEAR_COMPOSE, LINEAR_ID, o_THM] THEN
1740   ASM_MESON_TAC[]]);
1741
1742val dim = new_definition ("dim",
1743  ``dim v = @n. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b) /\
1744                   b HAS_SIZE n``);
1745
1746val BASIS_EXISTS = store_thm ("BASIS_EXISTS",
1747 ``!v. ?b. b SUBSET v /\ independent b /\ v SUBSET (span b) /\ b HAS_SIZE (dim v)``,
1748  GEN_TAC THEN REWRITE_TAC[dim] THEN CONV_TAC SELECT_CONV THEN
1749  MESON_TAC[MAXIMAL_INDEPENDENT_SUBSET, HAS_SIZE, INDEPENDENT_BOUND]);
1750
1751val INDEPENDENT_CARD_LE_DIM = store_thm ("INDEPENDENT_CARD_LE_DIM",
1752 ``!v b:real->bool. b SUBSET v /\ independent b ==> FINITE b /\ CARD(b) <= dim v``,
1753  METIS_TAC[BASIS_EXISTS, INDEPENDENT_SPAN_BOUND, HAS_SIZE, SUBSET_TRANS]);
1754
1755val CARD_GE_DIM_INDEPENDENT = store_thm ("CARD_GE_DIM_INDEPENDENT",
1756 ``!v b:real->bool. b SUBSET v /\ independent b /\ dim v <= CARD(b)
1757        ==> v SUBSET (span b)``,
1758  REPEAT STRIP_TAC THEN
1759  SUBGOAL_THEN ``!a:real. ~(a IN v /\ ~(a IN span b))`` MP_TAC THENL
1760   [ALL_TAC, SET_TAC[]] THEN
1761  X_GEN_TAC ``a:real`` THEN STRIP_TAC THEN
1762  SUBGOAL_THEN ``independent((a:real) INSERT b)`` ASSUME_TAC THENL
1763   [METIS_TAC[INDEPENDENT_INSERT], ALL_TAC] THEN
1764  MP_TAC(ISPECL [``v:real->bool``, ``(a:real) INSERT b``]
1765                INDEPENDENT_CARD_LE_DIM) THEN
1766  ASM_SIMP_TAC std_ss [INSERT_SUBSET, CARD_EMPTY, CARD_INSERT, INDEPENDENT_BOUND] THEN
1767  METIS_TAC[SPAN_SUPERSET, SUBSET_DEF, ARITH_PROVE
1768    ``x <= y ==> ~(SUC y <= x)``]);
1769
1770val SPAN_EXPLICIT = store_thm ("SPAN_EXPLICIT",
1771 ``!(p:real -> bool). span p =
1772    {y | ?s u. FINITE s /\ s SUBSET p /\ (sum s (\v. u v * v) = y)}``,
1773  GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
1774   [ALL_TAC,
1775    SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN
1776    REPEAT STRIP_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
1777    MATCH_MP_TAC SPAN_SUM THEN ASM_REWRITE_TAC[] THEN
1778    ASM_MESON_TAC[SPAN_SUPERSET, SPAN_MUL]] THEN
1779  SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN
1780  ONCE_REWRITE_TAC [METIS []
1781   ``(?s u. FINITE s /\ (!x. x IN s ==> x IN p) /\ (sum s (\v. u v * v) = x)) =
1782     (\x. ?s u. FINITE s /\ (!x. x IN s ==> x IN p) /\ (sum s (\v. u v * v) = x)) x``] THEN
1783  MATCH_MP_TAC SPAN_INDUCT_ALT THEN SIMP_TAC std_ss [] THEN CONJ_TAC THENL
1784   [EXISTS_TAC ``{}:real->bool`` THEN
1785    SIMP_TAC std_ss [FINITE_EMPTY, FINITE_INSERT, SUM_CLAUSES,
1786     EMPTY_SUBSET, NOT_IN_EMPTY], ALL_TAC] THEN
1787  MAP_EVERY X_GEN_TAC [``c:real``, ``x:real``, ``y:real``] THEN
1788  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
1789  SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN
1790  MAP_EVERY X_GEN_TAC [``s:real->bool``, ``u:real->real``] THEN
1791  STRIP_TAC THEN EXISTS_TAC ``(x:real) INSERT s`` THEN
1792  EXISTS_TAC ``\y. if y = x then (if x IN s then (u:real->real) y + c else c)
1793                  else u y`` THEN
1794  ASM_SIMP_TAC std_ss [FINITE_INSERT, IN_INSERT, SUM_CLAUSES] THEN
1795  CONJ_TAC THENL [ASM_MESON_TAC[], ALL_TAC] THEN
1796  FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
1797  COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
1798   [FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE
1799     ``x IN s ==> (s = x INSERT (s DELETE x))``)) THEN
1800    ASM_SIMP_TAC std_ss [SUM_CLAUSES, FINITE_INSERT, FINITE_DELETE, IN_DELETE] THEN
1801    MATCH_MP_TAC(REAL_ARITH
1802      ``(y = z) ==> ((c + d) * x + y = d * x + (c * x + z:real))``),
1803    AP_TERM_TAC] THEN
1804  MATCH_MP_TAC SUM_EQ THEN METIS_TAC[IN_DELETE]);
1805
1806val DEPENDENT_EXPLICIT = store_thm ("DEPENDENT_EXPLICIT",
1807 ``!p. dependent (p:real -> bool) <=>
1808       ?s u. FINITE s /\ s SUBSET p /\ (?v. v IN s /\ ~(u v = &0)) /\
1809             (sum s (\v. u v * v) = 0)``,
1810  GEN_TAC THEN SIMP_TAC std_ss [dependent, SPAN_EXPLICIT, GSPECIFICATION] THEN
1811  SIMP_TAC std_ss [GSYM RIGHT_EXISTS_AND_THM, GSYM LEFT_EXISTS_AND_THM] THEN
1812  EQ_TAC THEN SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THENL
1813   [MAP_EVERY X_GEN_TAC [``s:real->bool``, ``u:real->real``] THEN
1814    STRIP_TAC THEN ABBREV_TAC ``a = sum s (\v. (u:real->real) v * v)`` THEN
1815    MAP_EVERY EXISTS_TAC
1816     [``(a:real) INSERT s``,
1817      ``\y. if y = a then - &1 else (u:real->real) y``,
1818      ``a:real``] THEN
1819    ASM_REWRITE_TAC[IN_INSERT, INSERT_SUBSET, FINITE_INSERT] THEN
1820    CONJ_TAC THENL [ASM_SET_TAC[], ASM_SIMP_TAC real_ss []] THEN
1821    ASM_SIMP_TAC std_ss [SUM_CLAUSES] THEN
1822    COND_CASES_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
1823    REWRITE_TAC[REAL_ARITH ``(-&1 * a + s = 0) <=> (a = s:real)``] THEN
1824    FIRST_X_ASSUM(fn th => GEN_REWR_TAC LAND_CONV [SYM th]) THEN
1825    MATCH_MP_TAC SUM_EQ THEN ASM_SET_TAC[],
1826    MAP_EVERY X_GEN_TAC [``s:real->bool``, ``u:real->real``, ``a:real``] THEN
1827    STRIP_TAC THEN MAP_EVERY EXISTS_TAC
1828     [``s DELETE (a:real)``,
1829      ``\i. -((u:real->real) i) / (u (a:real))``] THEN
1830    ASM_SIMP_TAC std_ss [SUM_DELETE, FINITE_DELETE] THEN
1831    KNOW_TAC ``sum s (\v. -u v / (u:real->real) a * v) - -u a / u a * a = a`` THENL
1832    [REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
1833     REWRITE_TAC [REAL_MUL_ASSOC] THEN SIMP_TAC real_ss [SUM_RMUL, SUM_NEG] THEN
1834     RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_MUL_SYM]) THEN ASM_REWRITE_TAC [] THEN
1835     ASM_SIMP_TAC real_ss [REAL_MUL_LNEG, GSYM REAL_MUL_ASSOC,
1836                           REAL_MUL_RNEG, REAL_MUL_RZERO] THEN
1837     ASM_SIMP_TAC real_ss [REAL_MUL_RINV], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
1838    ASM_SET_TAC []]);
1839
1840val INDEPENDENT_INJECTIVE_IMAGE_GEN = store_thm ("INDEPENDENT_INJECTIVE_IMAGE_GEN",
1841 ``!f:real->real s. independent s /\ linear f /\
1842     (!x y. x IN span s /\ y IN span s /\ (f(x) = f(y)) ==> (x = y))
1843    ==> independent (IMAGE f s)``,
1844  REPEAT GEN_TAC THEN
1845  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
1846  ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN
1847  SIMP_TAC std_ss [independent, DEPENDENT_EXPLICIT] THEN
1848  REWRITE_TAC[CONJ_ASSOC, FINITE_SUBSET_IMAGE] THEN DISCH_TAC THEN
1849  KNOW_TAC ``(?s':real->bool u:real->real. (FINITE s' /\ s' SUBSET s) /\
1850      (?v. v IN IMAGE f s' /\ ~(u v = &0)) /\
1851      (sum (IMAGE f s') (\v. u v * v) = 0))`` THENL
1852  [METIS_TAC [], POP_ASSUM K_TAC] THEN
1853  SIMP_TAC std_ss [EXISTS_IN_IMAGE, LEFT_IMP_EXISTS_THM] THEN
1854  MAP_EVERY X_GEN_TAC [``t:real->bool``, ``u:real->real``] THEN
1855  DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
1856  MAP_EVERY EXISTS_TAC
1857   [``t:real->bool``, ``(u:real->real) o (f:real->real)``] THEN
1858  ASM_REWRITE_TAC[o_THM] THEN
1859  FIRST_ASSUM MATCH_MP_TAC THEN REPEAT CONJ_TAC THENL
1860   [MATCH_MP_TAC SPAN_SUM THEN ASM_SIMP_TAC std_ss [] THEN
1861    REPEAT STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN
1862    MATCH_MP_TAC SPAN_SUPERSET THEN ASM_SET_TAC[],
1863    REWRITE_TAC[SPAN_0],
1864    ASM_SIMP_TAC std_ss [LINEAR_SUM] THEN
1865    FIRST_ASSUM(SUBST1_TAC o MATCH_MP LINEAR_0) THEN
1866    FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN CONV_TAC SYM_CONV THEN
1867    W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o lhand o snd) THEN
1868    ASM_SIMP_TAC std_ss [o_DEF] THEN ASM_SIMP_TAC std_ss [LINEAR_CMUL] THEN
1869    DISCH_THEN MATCH_MP_TAC THEN ASM_MESON_TAC[SPAN_SUPERSET, SUBSET_DEF]]);
1870
1871val INDEPENDENT_INJECTIVE_IMAGE = store_thm ("INDEPENDENT_INJECTIVE_IMAGE",
1872 ``!f:real->real s. independent s /\ linear f /\
1873     (!x y. (f(x) = f(y)) ==> (x = y)) ==> independent (IMAGE f s)``,
1874  REPEAT STRIP_TAC THEN MATCH_MP_TAC INDEPENDENT_INJECTIVE_IMAGE_GEN THEN
1875  ASM_MESON_TAC[]);
1876
1877Theorem SPAN_LINEAR_IMAGE :
1878    !f:real->real s. linear f ==> (span(IMAGE f s) = IMAGE f (span s))
1879Proof
1880  REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN
1881  X_GEN_TAC ``x:real`` THEN EQ_TAC THENL
1882   [ONCE_REWRITE_TAC [METIS [] ``x IN IMAGE f (span s) <=>
1883                            (\x. x IN IMAGE f (span s)) x``] THEN
1884    SPEC_TAC(``x:real``, ``x:real``) THEN MATCH_MP_TAC SPAN_INDUCT THEN
1885    SIMP_TAC std_ss [SET_RULE ``(\x. x IN s) = s``] THEN
1886    ASM_SIMP_TAC std_ss [SUBSPACE_SPAN, SUBSPACE_LINEAR_IMAGE] THEN
1887    SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN REWRITE_TAC[IN_IMAGE] THEN
1888    MESON_TAC[SPAN_SUPERSET, SUBSET_DEF],
1889    SPEC_TAC(``x:real``, ``x:real``) THEN SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN
1890    ONCE_REWRITE_TAC [METIS [] ``f x IN span (IMAGE f s) <=>
1891                            (\x. f x IN span (IMAGE f s)) x``] THEN
1892    MATCH_MP_TAC SPAN_INDUCT THEN
1893    SIMP_TAC std_ss [SET_RULE ``(\x. f x IN span(s)) = {x | f(x) IN span s}``] THEN
1894    ASM_SIMP_TAC std_ss [SUBSPACE_LINEAR_PREIMAGE, SUBSPACE_SPAN] THEN
1895    SIMP_TAC std_ss [GSPECIFICATION] THEN
1896    MESON_TAC[SPAN_SUPERSET, SUBSET_DEF, IN_IMAGE]]
1897QED
1898
1899(* ------------------------------------------------------------------------- *)
1900(* An injective map real->real is also surjective.                       *)
1901(* ------------------------------------------------------------------------- *)
1902
1903val LINEAR_INJECTIVE_IMP_SURJECTIVE = store_thm ("LINEAR_INJECTIVE_IMP_SURJECTIVE",
1904 ``!f:real->real. linear f /\ (!x y. (f(x) = f(y)) ==> (x = y))
1905                 ==> !y. ?x. f(x) = y``,
1906  REPEAT STRIP_TAC THEN
1907  MP_TAC(ISPEC ``univ(:real)`` BASIS_EXISTS) THEN
1908  REWRITE_TAC[SUBSET_UNIV, HAS_SIZE] THEN
1909  DISCH_THEN(X_CHOOSE_THEN ``b:real->bool`` STRIP_ASSUME_TAC) THEN
1910  SUBGOAL_THEN ``UNIV SUBSET span(IMAGE (f:real->real) b)`` MP_TAC THENL
1911   [MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN
1912    ASM_MESON_TAC[INDEPENDENT_INJECTIVE_IMAGE, LESS_EQ_REFL,
1913                  SUBSET_UNIV, CARD_IMAGE_INJ],
1914    ASM_SIMP_TAC std_ss [SPAN_LINEAR_IMAGE] THEN
1915    ASM_MESON_TAC[SUBSET_DEF, IN_IMAGE, IN_UNIV]]);
1916
1917(* ------------------------------------------------------------------------- *)
1918(* Left-invertible linear transformation has a lower bound.                  *)
1919(* ------------------------------------------------------------------------- *)
1920
1921val LINEAR_INVERTIBLE_BOUNDED_BELOW_POS = store_thm ("LINEAR_INVERTIBLE_BOUNDED_BELOW_POS",
1922 ``!f:real->real g. linear f /\ linear g /\ (g o f = I)
1923   ==> ?B. &0 < B /\ !x. B * abs(x) <= abs(f x)``,
1924  REPEAT STRIP_TAC THEN
1925  MP_TAC(ISPEC ``g:real->real`` LINEAR_BOUNDED_POS) THEN
1926  ASM_REWRITE_TAC[] THEN
1927  DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN
1928  EXISTS_TAC ``inv B:real`` THEN ASM_SIMP_TAC real_ss [REAL_LT_INV_EQ] THEN
1929  X_GEN_TAC ``x:real`` THEN MATCH_MP_TAC REAL_LE_TRANS THEN
1930  EXISTS_TAC ``inv(B) * abs(((g:real->real) o (f:real->real)) x)`` THEN
1931  CONJ_TAC THENL [ASM_SIMP_TAC real_ss [I_THM, REAL_LE_REFL], ALL_TAC] THEN
1932  ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN
1933  ASM_SIMP_TAC real_ss [o_THM, REAL_LE_LDIV_EQ] THEN
1934  ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_REWRITE_TAC[]);
1935
1936val LINEAR_INVERTIBLE_BOUNDED_BELOW = store_thm ("LINEAR_INVERTIBLE_BOUNDED_BELOW",
1937 ``!f:real->real g. linear f /\ linear g /\ (g o f = I) ==>
1938   ?B. !x. B * abs(x) <= abs(f x)``,
1939  MESON_TAC[LINEAR_INVERTIBLE_BOUNDED_BELOW_POS]);
1940
1941val LINEAR_INJECTIVE_BOUNDED_BELOW_POS = store_thm ("LINEAR_INJECTIVE_BOUNDED_BELOW_POS",
1942 ``!f:real->real. linear f /\ (!x y. (f x = f y) ==> (x = y))
1943    ==> ?B. &0 < B /\ !x. abs(x) * B <= abs(f x)``,
1944  REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
1945  MATCH_MP_TAC LINEAR_INVERTIBLE_BOUNDED_BELOW_POS THEN
1946  METIS_TAC[LINEAR_INJECTIVE_LEFT_INVERSE, I_THM]);
1947
1948(* ------------------------------------------------------------------------- *)
1949(* Consequences of independence or spanning for cardinality.                 *)
1950(* ------------------------------------------------------------------------- *)
1951
1952val INDEPENDENT_CARD_LE_DIM = store_thm ("INDEPENDENT_CARD_LE_DIM",
1953 ``!v b:real->bool. b SUBSET v /\ independent b ==> FINITE b /\ CARD(b) <= dim v``,
1954  METIS_TAC[BASIS_EXISTS, INDEPENDENT_SPAN_BOUND, HAS_SIZE, SUBSET_TRANS]);
1955
1956val SPAN_CARD_GE_DIM = store_thm ("SPAN_CARD_GE_DIM",
1957 ``!v b:real->bool. v SUBSET (span b) /\ FINITE b ==> dim(v) <= CARD(b)``,
1958  METIS_TAC[BASIS_EXISTS, INDEPENDENT_SPAN_BOUND, HAS_SIZE, SUBSET_TRANS]);
1959
1960val BASIS_CARD_EQ_DIM = store_thm ("BASIS_CARD_EQ_DIM",
1961 ``!v b. b SUBSET v /\ v SUBSET (span b) /\ independent b
1962   ==> FINITE b /\ (CARD b = dim v)``,
1963  METIS_TAC[LESS_EQUAL_ANTISYM, INDEPENDENT_CARD_LE_DIM, SPAN_CARD_GE_DIM]);
1964
1965val BASIS_HAS_SIZE_DIM = store_thm ("BASIS_HAS_SIZE_DIM",
1966 ``!v b. independent b /\ (span b = v) ==> b HAS_SIZE (dim v)``,
1967  REPEAT STRIP_TAC THEN REWRITE_TAC[HAS_SIZE] THEN
1968  MATCH_MP_TAC BASIS_CARD_EQ_DIM THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN
1969  FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[SPAN_INC]);
1970
1971val DIM_UNIQUE = store_thm ("DIM_UNIQUE",
1972 ``!v b. b SUBSET v /\ v SUBSET (span b) /\ independent b /\ b HAS_SIZE n
1973        ==> (dim v = n)``,
1974  MESON_TAC[BASIS_CARD_EQ_DIM, HAS_SIZE]);
1975
1976val DIM_LE_CARD = store_thm ("DIM_LE_CARD",
1977 ``!s. FINITE s ==> dim s <= CARD s``,
1978  GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC SPAN_CARD_GE_DIM THEN
1979  ASM_REWRITE_TAC[SPAN_INC, SUBSET_REFL]);
1980
1981(* ------------------------------------------------------------------------- *)
1982(* Standard bases are a spanning set, and obviously finite.                  *)
1983(* ------------------------------------------------------------------------- *)
1984
1985val SPAN_STDBASIS = store_thm ("SPAN_STDBASIS",
1986 ``span {i :real | 1 <= i /\ i <= 1} = UNIV``,
1987  REWRITE_TAC [REAL_LE_ANTISYM, GSPEC_EQ2] THEN
1988  SIMP_TAC std_ss [EXTENSION, span, hull, IN_BIGINTER, IN_UNIV] THEN
1989  SIMP_TAC std_ss [SING_SUBSET, GSPECIFICATION, subspace] THEN
1990  REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_MUL_RID] THEN
1991  FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC []);
1992
1993val HAS_SIZE_STDBASIS = store_thm ("HAS_SIZE_STDBASIS",
1994 ``{i :real | 1 <= i /\ i <= 1} HAS_SIZE 1``,
1995  REWRITE_TAC [REAL_LE_ANTISYM, GSPEC_EQ2, HAS_SIZE] THEN
1996  REWRITE_TAC [FINITE_SING, CARD_SING]);
1997
1998(* ------------------------------------------------------------------------- *)
1999(* More lemmas about dimension.                                              *)
2000(* ------------------------------------------------------------------------- *)
2001
2002val DIM_UNIV = store_thm ("DIM_UNIV",
2003 ``dim univ(:real) = 1:num``,
2004  MATCH_MP_TAC DIM_UNIQUE THEN EXISTS_TAC ``{i :real | &1 <= i /\ i <= &1}`` THEN
2005  REWRITE_TAC[SUBSET_UNIV, SPAN_STDBASIS, HAS_SIZE_STDBASIS, INDEPENDENT_STDBASIS]);
2006
2007val DIM_SUBSET = store_thm ("DIM_SUBSET",
2008 ``!s t:real->bool. s SUBSET t ==> dim(s) <= dim(t)``,
2009  MESON_TAC[BASIS_EXISTS, INDEPENDENT_SPAN_BOUND, SUBSET_DEF, HAS_SIZE]);
2010
2011val DIM_SUBSET_UNIV = store_thm ("DIM_SUBSET_UNIV",
2012 ``!s:real->bool. dim(s) <= (1:num)``,
2013  GEN_TAC THEN REWRITE_TAC[GSYM DIM_UNIV] THEN
2014  MATCH_MP_TAC DIM_SUBSET THEN REWRITE_TAC[SUBSET_UNIV]);
2015
2016(* ------------------------------------------------------------------------- *)
2017(* Open and closed sets                                                      *)
2018(* ------------------------------------------------------------------------- *)
2019
2020val open_def = new_definition ("open_def",
2021  ``Open s <=> !x. x IN s ==> ?e. &0 < e /\ !x'. dist(x',x) < e ==> x' IN s``);
2022
2023val _ = overload_on ("open",``Open``);
2024
2025val closed_def = new_definition ("closed_def",
2026  ``Closed(s:real->bool) <=> open(UNIV DIFF s)``);
2027
2028val _ = overload_on ("closed",``Closed``);
2029
2030val euclidean = new_definition ("euclidean",
2031 ``euclidean = topology open``);
2032
2033val OPEN_EMPTY = store_thm ("OPEN_EMPTY",
2034  ``open {}``,
2035  REWRITE_TAC[open_def, NOT_IN_EMPTY]);
2036
2037val OPEN_UNIV = store_thm ("OPEN_UNIV",
2038 ``open univ(:real)``,
2039  REWRITE_TAC[open_def, IN_UNIV] THEN MESON_TAC[REAL_LT_01]);
2040
2041val OPEN_INTER = store_thm ("OPEN_INTER",
2042  ``!s t. open s /\ open t ==> open (s INTER t)``,
2043  REPEAT GEN_TAC THEN REWRITE_TAC [open_def] THEN
2044  SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REWRITE_TAC [IN_INTER] THEN
2045  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN
2046  STRIP_TAC THEN STRIP_TAC THEN FULL_SIMP_TAC real_ss [] THEN
2047  Cases_on `e < e'` THENL [EXISTS_TAC ``e:real`` THEN
2048  ASM_REWRITE_TAC [] THEN GEN_TAC THEN
2049  UNDISCH_TAC (Term `!x'. dist (x',x) < e ==> x' IN s`) THEN
2050  DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN RW_TAC std_ss [] THEN
2051  UNDISCH_TAC (Term `!x'. dist (x',x) < e' ==> x' IN t`) THEN
2052  DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN
2053  KNOW_TAC ``dist (x',x) < e'`` THENL [MATCH_MP_TAC REAL_LT_TRANS THEN
2054  EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC [], ALL_TAC] THEN
2055  RW_TAC std_ss [] THEN Cases_on `e' < e` THEN
2056  EXISTS_TAC ``e':real`` THEN ASM_REWRITE_TAC [],
2057  Cases_on `e' < e` THENL [EXISTS_TAC ``e':real`` THEN
2058  ASM_REWRITE_TAC [] THEN GEN_TAC THEN
2059  UNDISCH_TAC (Term `!x'. dist (x',x) < e' ==> x' IN t`) THEN
2060  DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN
2061  RW_TAC std_ss [] THEN
2062  UNDISCH_TAC (Term `!x'. dist (x',x) < e ==> x' IN s`) THEN
2063  DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN
2064  KNOW_TAC ``dist (x',x) < e`` THENL [MATCH_MP_TAC REAL_LT_TRANS THEN
2065  EXISTS_TAC ``e':real`` THEN ASM_REWRITE_TAC [], ALL_TAC] THEN
2066  RW_TAC std_ss [],
2067  FULL_SIMP_TAC std_ss [REAL_NOT_LT] THEN KNOW_TAC ``(e:real) = e'`` THENL
2068  [METIS_TAC [REAL_LE_ANTISYM], ALL_TAC] THEN DISCH_TAC THEN
2069  EXISTS_TAC ``e:real`` THEN CONJ_TAC THEN FULL_SIMP_TAC real_ss []]]);
2070
2071val OPEN_BIGUNION = store_thm ("OPEN_BIGUNION",
2072 ``(!s. s IN f ==> open s) ==> open(BIGUNION f)``,
2073  REWRITE_TAC[open_def, IN_BIGUNION] THEN MESON_TAC[]);
2074
2075val OPEN_EXISTS_IN = store_thm ("OPEN_EXISTS_IN",
2076 ``!P Q:'a->real->bool.
2077        (!a. P a ==> open {x | Q a x}) ==> open {x | ?a. P a /\ Q a x}``,
2078  REPEAT STRIP_TAC THEN
2079  SUBGOAL_THEN ``open(BIGUNION {{x | Q (a:'a) (x:real)} | P a})`` MP_TAC THENL
2080   [MATCH_MP_TAC OPEN_BIGUNION THEN ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN
2081    METIS_TAC [], MATCH_MP_TAC (TAUT `(a <=> b) ==> a ==> b`) THEN AP_TERM_TAC THEN
2082    SIMP_TAC std_ss [EXTENSION, IN_BIGUNION, GSPECIFICATION] THEN
2083    SET_TAC[]]);
2084
2085val OPEN_EXISTS = store_thm ("OPEN_EXISTS",
2086 ``!Q:'a->real->bool. (!a. open {x | Q a x}) ==> open {x | ?a. Q a x}``,
2087  MP_TAC(ISPEC ``\x:'a. T`` OPEN_EXISTS_IN) THEN REWRITE_TAC[]);
2088
2089val OPEN_IN = store_thm ("OPEN_IN",
2090 ``!s:real->bool. open s <=> open_in euclidean s``,
2091  GEN_TAC THEN REWRITE_TAC[euclidean] THEN CONV_TAC SYM_CONV THEN
2092  AP_THM_TAC THEN REWRITE_TAC[GSYM(CONJUNCT2 topology_tybij)] THEN
2093  SIMP_TAC std_ss [REWRITE_RULE[IN_DEF] istopology] THEN
2094  REWRITE_TAC[OPEN_EMPTY, OPEN_INTER, SUBSET_DEF] THEN
2095  MESON_TAC[IN_DEF, OPEN_BIGUNION]);
2096
2097val TOPSPACE_EUCLIDEAN = store_thm ("TOPSPACE_EUCLIDEAN",
2098 ``topspace euclidean = univ(:real)``,
2099  SIMP_TAC std_ss [topspace, EXTENSION, IN_UNIV, IN_BIGUNION, GSPECIFICATION] THEN
2100  MESON_TAC[OPEN_UNIV, IN_UNIV, OPEN_IN]);
2101
2102val TOPSPACE_EUCLIDEAN_SUBTOPOLOGY = store_thm ("TOPSPACE_EUCLIDEAN_SUBTOPOLOGY",
2103 ``!s. topspace (subtopology euclidean s) = s``,
2104  REWRITE_TAC[TOPSPACE_EUCLIDEAN, TOPSPACE_SUBTOPOLOGY, INTER_UNIV]);
2105
2106val OPEN_IN_REFL = store_thm ("OPEN_IN_REFL",
2107 ``!s:real->bool. open_in (subtopology euclidean s) s``,
2108  REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL, TOPSPACE_EUCLIDEAN, SUBSET_UNIV]);
2109
2110val CLOSED_IN_REFL = store_thm ("CLOSED_IN_REFL",
2111 ``!s:real->bool. closed_in (subtopology euclidean s) s``,
2112  REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY_REFL, TOPSPACE_EUCLIDEAN, SUBSET_UNIV]);
2113
2114val CLOSED_IN = store_thm ("CLOSED_IN",
2115 ``!s:real->bool. closed s <=> closed_in euclidean s``,
2116  REWRITE_TAC[closed_def, closed_in, TOPSPACE_EUCLIDEAN, OPEN_IN, SUBSET_UNIV]);
2117
2118val OPEN_UNION = store_thm ("OPEN_UNION",
2119 ``!s t. open s /\ open t ==> open(s UNION t)``,
2120  REWRITE_TAC [open_def] THEN REPEAT STRIP_TAC THEN POP_ASSUM MP_TAC THEN
2121  POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN
2122  POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN
2123  REPEAT STRIP_TAC THEN Cases_on `x IN s` THENL
2124  [FULL_SIMP_TAC std_ss [] THEN EXISTS_TAC ``e:real`` THEN
2125   FULL_SIMP_TAC std_ss [IN_UNION], FULL_SIMP_TAC std_ss [IN_UNION] THEN
2126   EXISTS_TAC ``e:real`` THEN FULL_SIMP_TAC std_ss [IN_UNION]]);
2127
2128val OPEN_SUB_OPEN = store_thm ("OPEN_SUB_OPEN",
2129 ``!s. open s <=> !x. x IN s ==> ?t. open t /\ x IN t /\ t SUBSET s``,
2130 GEN_TAC THEN EQ_TAC THENL
2131 [RW_TAC std_ss [] THEN EXISTS_TAC ``s:real->bool`` THEN
2132  ASM_REWRITE_TAC [SUBSET_REFL], DISCH_TAC THEN
2133  REWRITE_TAC [open_def] THEN GEN_TAC THEN
2134  POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN DISCH_TAC THEN DISCH_TAC THEN
2135  FULL_SIMP_TAC std_ss [open_def] THEN
2136  UNDISCH_TAC (Term `!x. x IN t ==> ?e. 0 < e /\ !x'. dist (x',x) < e ==> x' IN t `)
2137  THEN DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x`) THEN
2138  RW_TAC std_ss [] THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC []
2139  THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN
2140  RW_TAC std_ss [] THEN METIS_TAC [SUBSET_DEF]]);
2141
2142val CLOSED_EMPTY = store_thm ("CLOSED_EMPTY",
2143 ``closed {}``,
2144  REWRITE_TAC[CLOSED_IN, CLOSED_IN_EMPTY]);
2145
2146val CLOSED_UNIV = store_thm ("CLOSED_UNIV",
2147 ``closed(UNIV:real->bool)``,
2148  REWRITE_TAC[CLOSED_IN, GSYM TOPSPACE_EUCLIDEAN, CLOSED_IN_TOPSPACE]);
2149
2150val CLOSED_UNION = store_thm ("CLOSED_UNION",
2151 ``!s t. closed s /\ closed t ==> closed(s UNION t)``,
2152  REWRITE_TAC[CLOSED_IN, CLOSED_IN_UNION]);
2153
2154val CLOSED_INTER = store_thm ("CLOSED_INTER",
2155 ``!s t. closed s /\ closed t ==> closed(s INTER t)``,
2156  REWRITE_TAC[CLOSED_IN, CLOSED_IN_INTER]);
2157
2158val CLOSED_BIGINTER = store_thm ("CLOSED_BIGINTER",
2159 ``!f. (!s:real->bool. s IN f ==> closed s) ==> closed(BIGINTER f)``,
2160  REWRITE_TAC[CLOSED_IN] THEN REPEAT STRIP_TAC THEN
2161  ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THEN
2162  ASM_SIMP_TAC std_ss [CLOSED_IN_BIGINTER, BIGINTER_EMPTY] THEN
2163  REWRITE_TAC[GSYM TOPSPACE_EUCLIDEAN, CLOSED_IN_TOPSPACE]);
2164
2165val BIGINTER_GSPEC = store_thm ("BIGINTER_GSPEC",
2166 ``(!P f. BIGINTER {f x | P x} = {a | !x. P x ==> a IN (f x)}) /\
2167   (!P f. BIGINTER {f x y | P x y} = {a | !x y. P x y ==> a IN (f x y)}) /\
2168   (!P f. BIGINTER {f x y z | P x y z} =
2169                {a | !x y z. P x y z ==> a IN (f x y z)})``,
2170  REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN
2171  SIMP_TAC std_ss [IN_BIGINTER, GSPECIFICATION, EXISTS_PROD] THEN MESON_TAC[]);
2172
2173val CLOSED_FORALL_IN = store_thm ("CLOSED_FORALL_IN",
2174 ``!P Q:'a->real->bool.
2175        (!a. P a ==> closed {x | Q a x}) ==> closed {x | !a. P a ==> Q a x}``,
2176  REPEAT STRIP_TAC THEN
2177  SUBGOAL_THEN ``closed(BIGINTER {{x | Q (a:'a) (x:real)} | P a})`` MP_TAC THENL
2178   [MATCH_MP_TAC CLOSED_BIGINTER THEN ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC],
2179    MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN SIMP_TAC std_ss [BIGINTER_GSPEC] THEN
2180    SET_TAC[]]);
2181
2182val CLOSED_FORALL = store_thm ("CLOSED_FORALL",
2183 ``!Q:'a->real->bool. (!a. closed {x | Q a x}) ==> closed {x | !a. Q a x}``,
2184  MP_TAC(ISPEC ``\x:'a. T`` CLOSED_FORALL_IN) THEN REWRITE_TAC[]);
2185
2186val OPEN_CLOSED = store_thm ("OPEN_CLOSED",
2187 ``!s:real->bool. open s <=> closed(UNIV DIFF s)``,
2188  SIMP_TAC std_ss [OPEN_IN, CLOSED_IN, TOPSPACE_EUCLIDEAN, SUBSET_UNIV,
2189           OPEN_IN_CLOSED_IN_EQ]);
2190
2191val OPEN_DIFF = store_thm ("OPEN_DIFF",
2192 ``!s t. open s /\ closed t ==> open(s DIFF t)``,
2193  REWRITE_TAC[OPEN_IN, CLOSED_IN, OPEN_IN_DIFF]);
2194
2195val CLOSED_DIFF = store_thm ("CLOSED_DIFF",
2196 ``!s t. closed s /\ open t ==> closed(s DIFF t)``,
2197  REWRITE_TAC[OPEN_IN, CLOSED_IN, CLOSED_IN_DIFF]);
2198
2199val OPEN_BIGINTER = store_thm ("OPEN_BIGINTER",
2200  ``!s. FINITE s /\ (!t. t IN s ==> open t) ==> (open (BIGINTER s))``,
2201  REWRITE_TAC [GSYM AND_IMP_INTRO] THEN GEN_TAC THEN
2202  KNOW_TAC `` (!t. t IN s ==> open t) ==> open (BIGINTER s) <=>
2203         (\x. (!t. t IN x ==> open t) ==> open (BIGINTER x)) s`` THENL
2204  [SIMP_TAC std_ss [GSPECIFICATION] THEN DISCH_TAC THEN
2205   ASM_REWRITE_TAC [], ALL_TAC] THEN DISC_RW_KILL THEN
2206   MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
2207   REWRITE_TAC [BIGINTER_INSERT, BIGINTER_EMPTY, OPEN_UNIV,
2208   IN_INSERT] THEN MESON_TAC [OPEN_INTER]);
2209
2210val CLOSED_BIGUNION = store_thm ("CLOSED_BIGUNION",
2211 ``!s. FINITE s /\ (!t. t IN s ==> closed t) ==> closed(BIGUNION s)``,
2212  REWRITE_TAC[GSYM AND_IMP_INTRO] THEN
2213  KNOW_TAC ``!s. ((!t. t IN s ==> closed t) ==> closed(BIGUNION s)) <=>
2214             (\s. (!t. t IN s ==> closed t) ==> closed(BIGUNION s)) s`` THENL
2215  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
2216  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
2217  REWRITE_TAC[BIGUNION_INSERT, BIGUNION_EMPTY, CLOSED_EMPTY, IN_INSERT] THEN
2218  MESON_TAC[CLOSED_UNION]);
2219
2220(* ------------------------------------------------------------------------- *)
2221(* Open and closed balls.                                                    *)
2222(* ------------------------------------------------------------------------- *)
2223
2224(* new definition based on metricTheory *)
2225Definition ball_def :
2226    ball = metric$B(mr1)
2227End
2228
2229(* old definition now becomes a theorem *)
2230Theorem ball :
2231    !x e. ball(x,e) = { y | dist(x,y) < e}
2232Proof
2233    RW_TAC std_ss [ball_def, dist_def, metricTheory.ball,
2234                   Once EXTENSION, GSPECIFICATION]
2235 >> rw [IN_APP]
2236QED
2237
2238val cball = new_definition ("cball",
2239  ``cball(x,e) = { y | dist(x,y) <= e}``);
2240
2241val sphere = new_definition ("sphere",
2242  ``sphere(x,e) = { y | dist(x,y) = e}``);
2243
2244val IN_BALL = store_thm ("IN_BALL",
2245 ``!x y e. y IN ball(x,e) <=> dist(x,y) < e``,
2246  REPEAT GEN_TAC THEN FULL_SIMP_TAC std_ss [ball, GSPECIFICATION]);
2247
2248val IN_CBALL = store_thm ("IN_CBALL",
2249 ``!x y e. y IN cball(x,e) <=> dist(x,y) <= e``,
2250  REPEAT GEN_TAC THEN FULL_SIMP_TAC std_ss [cball, GSPECIFICATION]);
2251
2252val IN_SPHERE = store_thm ("IN_SPHERE",
2253 ``!x y e. y IN sphere(x,e) <=> (dist(x,y) = e)``,
2254  REPEAT GEN_TAC THEN FULL_SIMP_TAC std_ss [sphere, GSPECIFICATION]);
2255
2256val IN_BALL_0 = store_thm ("IN_BALL_0",
2257 ``!x e. x IN ball(0,e) <=> abs(x) < e``,
2258  REWRITE_TAC [IN_BALL, dist, REAL_SUB_LZERO, ABS_NEG]);
2259
2260val IN_CBALL_0 = store_thm ("IN_CBALL_0",
2261 ``!x e. x IN cball(0,e) <=> abs(x) <= e``,
2262  REWRITE_TAC[IN_CBALL, dist, REAL_SUB_LZERO, ABS_NEG]);
2263
2264val IN_SPHERE_0 = store_thm ("IN_SPHERE_0",
2265 ``!x e. x IN sphere(0,e) <=> (abs(x) = e)``,
2266  REWRITE_TAC[IN_SPHERE, dist, REAL_SUB_LZERO, ABS_NEG]);
2267
2268val BALL_TRIVIAL = store_thm ("BALL_TRIVIAL",
2269 ``!x. ball(x,&0) = {}``,
2270  REWRITE_TAC[EXTENSION, IN_BALL, IN_SING, NOT_IN_EMPTY, dist] THEN REAL_ARITH_TAC);
2271
2272val CBALL_TRIVIAL = store_thm ("CBALL_TRIVIAL",
2273 ``!x. cball(x,&0) = {x}``,
2274  REWRITE_TAC[EXTENSION, IN_CBALL, IN_SING, NOT_IN_EMPTY, dist] THEN REAL_ARITH_TAC);
2275
2276val CENTRE_IN_CBALL = store_thm ("CENTRE_IN_CBALL",
2277 ``!x e. x IN cball(x,e) <=> &0 <= e``,
2278  MESON_TAC[IN_CBALL, DIST_REFL]);
2279
2280val BALL_SUBSET_CBALL = store_thm ("BALL_SUBSET_CBALL",
2281 ``!x e. ball(x,e) SUBSET cball(x,e)``,
2282  REWRITE_TAC[IN_BALL, IN_CBALL, SUBSET_DEF] THEN REAL_ARITH_TAC);
2283
2284val SPHERE_SUBSET_CBALL = store_thm ("SPHERE_SUBSET_CBALL",
2285 ``!x e. sphere(x,e) SUBSET cball(x,e)``,
2286  REWRITE_TAC[IN_SPHERE, IN_CBALL, SUBSET_DEF] THEN REAL_ARITH_TAC);
2287
2288val SUBSET_BALL = store_thm ("SUBSET_BALL",
2289 ``!x d e. d <= e ==> ball(x,d) SUBSET ball(x,e)``,
2290  REWRITE_TAC[SUBSET_DEF, IN_BALL] THEN MESON_TAC[REAL_LTE_TRANS]);
2291
2292val SUBSET_CBALL = store_thm ("SUBSET_CBALL",
2293 ``!x d e. d <= e ==> cball(x,d) SUBSET cball(x,e)``,
2294  REWRITE_TAC[SUBSET_DEF, IN_CBALL] THEN MESON_TAC[REAL_LE_TRANS]);
2295
2296val BALL_MAX_UNION = store_thm ("BALL_MAX_UNION",
2297  ``!a r s. ball(a,max r s) = ball(a,r) UNION ball(a,s)``,
2298    rpt GEN_TAC
2299 >> REWRITE_TAC [IN_BALL, IN_UNION, EXTENSION, dist]
2300 >> GEN_TAC >> Q.ABBREV_TAC `b = abs (a - x)`
2301 >> REWRITE_TAC [REAL_LT_MAX]);
2302
2303val BALL_MIN_INTER = store_thm ("BALL_MIN_INTER",
2304  ``!a r s. ball(a,min r s) = ball(a,r) INTER ball(a,s)``,
2305    rpt GEN_TAC
2306 >> REWRITE_TAC [IN_BALL, IN_INTER, EXTENSION, dist]
2307 >> GEN_TAC >> Q.ABBREV_TAC `b = abs (a - x)`
2308 >> REWRITE_TAC [REAL_LT_MIN]);
2309
2310val CBALL_MAX_UNION = store_thm ("CBALL_MAX_UNION",
2311  ``!a r s. cball(a,max r s) = cball(a,r) UNION cball(a,s)``,
2312    rpt GEN_TAC
2313 >> REWRITE_TAC [IN_CBALL, IN_UNION, EXTENSION, dist]
2314 >> GEN_TAC >> Q.ABBREV_TAC `b = abs (a - x)`
2315 >> REWRITE_TAC [REAL_LE_MAX]);
2316
2317val CBALL_MIN_INTER = store_thm ("CBALL_MIN_INTER",
2318  ``!x d e. cball(x,min d e) = cball(x,d) INTER cball(x,e)``,
2319    rpt GEN_TAC
2320 >> REWRITE_TAC [EXTENSION, IN_INTER, IN_CBALL, dist]
2321 >> Q.X_GEN_TAC `a` >> Q.ABBREV_TAC `b = abs (x - a)`
2322 >> REWRITE_TAC [REAL_LE_MIN]);
2323
2324val BALL_TRANSLATION = store_thm ("BALL_TRANSLATION",
2325 ``!a x r. ball(a + x,r) = IMAGE (\y. a + y) (ball(x,r))``,
2326  REPEAT GEN_TAC THEN REWRITE_TAC [EXTENSION, IN_BALL, IN_IMAGE, dist] THEN
2327  GEN_TAC THEN EQ_TAC THENL [DISCH_TAC THEN EXISTS_TAC ``x' - a:real`` THEN
2328  RW_TAC std_ss [REAL_SUB_ADD2] THEN
2329  ASM_REWRITE_TAC [REAL_ARITH ``x - (x' - a) = a + x - x':real``],
2330  RW_TAC std_ss [] THEN
2331  METIS_TAC [REAL_ARITH ``a - (b + c) = a - b - c:real``, REAL_ADD_SUB]]);
2332
2333val CBALL_TRANSLATION = store_thm ("CBALL_TRANSLATION",
2334 ``!a x r. cball(a + x,r) = IMAGE (\y. a + y) (cball(x,r))``,
2335  REPEAT GEN_TAC THEN REWRITE_TAC [EXTENSION, IN_CBALL, IN_IMAGE, dist] THEN
2336  GEN_TAC THEN EQ_TAC THENL [DISCH_TAC THEN EXISTS_TAC ``x' - a:real`` THEN
2337  RW_TAC std_ss [REAL_SUB_ADD2] THEN
2338  ASM_REWRITE_TAC [REAL_ARITH ``x - (x' - a) = a + x - x':real``],
2339  RW_TAC std_ss [] THEN
2340  METIS_TAC [REAL_ARITH ``a - (b + c) = a - b - c:real``, REAL_ADD_SUB]]);
2341
2342val SPHERE_TRANSLATION = store_thm ("SPHERE_TRANSLATION",
2343 ``!a x r. sphere(a + x,r) = IMAGE (\y. a + y) (sphere(x,r))``,
2344  REPEAT GEN_TAC THEN REWRITE_TAC [EXTENSION, IN_SPHERE, IN_IMAGE, dist] THEN
2345  GEN_TAC THEN EQ_TAC THENL [DISCH_TAC THEN EXISTS_TAC ``x' - a:real`` THEN
2346  RW_TAC std_ss [REAL_SUB_ADD2] THEN
2347  ASM_REWRITE_TAC [REAL_ARITH ``x - (x' - a) = a + x - x':real``],
2348  RW_TAC std_ss [] THEN
2349  METIS_TAC [REAL_ARITH ``a - (b + c) = a - b - c:real``, REAL_ADD_SUB]]);
2350
2351val BALL_LINEAR_IMAGE = store_thm ("BALL_LINEAR_IMAGE",
2352 ``!f:real->real x r.
2353        linear f /\ (!y. ?x. f x = y) /\ (!x. abs(f x) = abs x)
2354        ==> (ball(f x,r) = IMAGE f (ball(x,r)))``,
2355  REWRITE_TAC[ball] THEN
2356  SIMP_TAC std_ss [linear, IN_IMAGE, dist, EXTENSION, GSPECIFICATION] THEN
2357  REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL
2358  [UNDISCH_TAC ``!y. ?x. (f:real->real) x = y`` THEN DISCH_TAC THEN
2359   POP_ASSUM (MP_TAC o SPEC ``x':real``) THEN STRIP_TAC THEN
2360   EXISTS_TAC ``x'':real`` THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN
2361   ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x. abs ((f:real->real) x) = abs x`` THEN
2362   DISCH_THEN (MP_TAC o SYM o SPEC ``x - x'':real``) THEN DISCH_TAC THEN
2363   ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN
2364   DISCH_THEN (MP_TAC o SPECL [``x:real``, ``-x'':real``]) THEN
2365   REWRITE_TAC [GSYM real_sub] THEN DISCH_TAC THEN
2366   ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-x = -1 * x:real``] THEN
2367   UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN
2368   DISCH_THEN (MP_TAC o SPECL [``-1:real``,``x'':real``]) THEN ASM_REAL_ARITH_TAC,
2369   ASM_REWRITE_TAC [real_sub] THEN REWRITE_TAC [REAL_ARITH ``-(f:real->real) x = -1 * f x``] THEN
2370   UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN
2371   DISCH_THEN (MP_TAC o SYM o SPECL [``-1:real``,``x'':real``]) THEN DISCH_TAC THEN
2372   ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-1 * x:real = -x``] THEN
2373   UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN
2374   DISCH_THEN (MP_TAC o SYM o SPECL [``x:real``, ``-x'':real``]) THEN DISCH_TAC THEN
2375   ASM_REWRITE_TAC [GSYM real_sub]]);
2376
2377val CBALL_LINEAR_IMAGE = store_thm ("CBALL_LINEAR_IMAGE",
2378 ``!f:real->real x r.
2379        linear f /\ (!y. ?x. f x = y) /\ (!x. abs(f x) = abs x)
2380        ==> (cball(f x,r) = IMAGE f (cball(x,r)))``,
2381  REWRITE_TAC[cball] THEN
2382  SIMP_TAC std_ss [linear, IN_IMAGE, dist, EXTENSION, GSPECIFICATION] THEN
2383  REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL
2384  [UNDISCH_TAC ``!y. ?x. (f:real->real) x = y`` THEN DISCH_TAC THEN
2385   POP_ASSUM (MP_TAC o SPEC ``x':real``) THEN STRIP_TAC THEN
2386   EXISTS_TAC ``x'':real`` THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN
2387   ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x. abs ((f:real->real) x) = abs x`` THEN
2388   DISCH_THEN (MP_TAC o SYM o SPEC ``x - x'':real``) THEN DISCH_TAC THEN
2389   ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN
2390   DISCH_THEN (MP_TAC o SPECL [``x:real``, ``-x'':real``]) THEN
2391   REWRITE_TAC [GSYM real_sub] THEN DISCH_TAC THEN
2392   ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-x = -1 * x:real``] THEN
2393   UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN
2394   DISCH_THEN (MP_TAC o SPECL [``-1:real``,``x'':real``]) THEN ASM_REAL_ARITH_TAC,
2395   ASM_REWRITE_TAC [real_sub] THEN REWRITE_TAC [REAL_ARITH ``-(f:real->real) x = -1 * f x``] THEN
2396   UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN
2397   DISCH_THEN (MP_TAC o SYM o SPECL [``-1:real``,``x'':real``]) THEN DISCH_TAC THEN
2398   ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-1 * x:real = -x``] THEN
2399   UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN
2400   DISCH_THEN (MP_TAC o SYM o SPECL [``x:real``, ``-x'':real``]) THEN DISCH_TAC THEN
2401   ASM_REWRITE_TAC [GSYM real_sub]]);
2402
2403val SPHERE_LINEAR_IMAGE = store_thm ("SPHERE_LINEAR_IMAGE",
2404 ``!f:real->real x r.
2405        linear f /\ (!y. ?x. f x = y) /\ (!x. abs(f x) = abs x)
2406        ==> (sphere(f x,r) = IMAGE f (sphere(x,r)))``,
2407  REWRITE_TAC[sphere] THEN
2408  SIMP_TAC std_ss [linear, IN_IMAGE, dist, EXTENSION, GSPECIFICATION] THEN
2409  REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL
2410  [UNDISCH_TAC ``!y. ?x. (f:real->real) x = y`` THEN DISCH_TAC THEN
2411   POP_ASSUM (MP_TAC o SPEC ``x':real``) THEN STRIP_TAC THEN
2412   EXISTS_TAC ``x'':real`` THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN
2413   ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x. abs ((f:real->real) x) = abs x`` THEN
2414   DISCH_THEN (MP_TAC o SYM o SPEC ``x - x'':real``) THEN DISCH_TAC THEN
2415   ASM_REWRITE_TAC [] THEN UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN
2416   DISCH_THEN (MP_TAC o SPECL [``x:real``, ``-x'':real``]) THEN
2417   REWRITE_TAC [GSYM real_sub] THEN DISCH_TAC THEN
2418   ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-x = -1 * x:real``] THEN
2419   UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN
2420   DISCH_THEN (MP_TAC o SPECL [``-1:real``,``x'':real``]) THEN ASM_REAL_ARITH_TAC,
2421   ASM_REWRITE_TAC [real_sub] THEN REWRITE_TAC [REAL_ARITH ``-(f:real->real) x = -1 * f x``] THEN
2422   UNDISCH_TAC ``!c x. f (c * x) = c * (f:real->real) x`` THEN
2423   DISCH_THEN (MP_TAC o SYM o SPECL [``-1:real``,``x'':real``]) THEN DISCH_TAC THEN
2424   ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ARITH ``-1 * x:real = -x``] THEN
2425   UNDISCH_TAC ``!x y. (f:real->real) (x + y) = f x + f y`` THEN
2426   DISCH_THEN (MP_TAC o SYM o SPECL [``x:real``, ``-x'':real``]) THEN DISCH_TAC THEN
2427   ASM_REWRITE_TAC [GSYM real_sub]]);
2428
2429val BALL_SCALING = store_thm ("BALL_SCALING",
2430 ``!c. &0 < c ==> !x r. ball(c * x,c * r) = IMAGE (\x. c * x) (ball(x,r))``,
2431  REWRITE_TAC [IMAGE_DEF, IN_BALL] THEN BETA_TAC THEN
2432  SIMP_TAC std_ss [ball, EXTENSION, GSPECIFICATION, dist] THEN
2433  REPEAT STRIP_TAC THEN EQ_TAC THENL [DISCH_TAC THEN
2434  EXISTS_TAC ``x' / c:real`` THEN
2435  FULL_SIMP_TAC std_ss [REAL_DIV_LMUL, REAL_POS_NZ] THEN
2436  KNOW_TAC `` abs (x - x' / c) < r <=> abs c * abs (x - x' / c) < c * r:real`` THENL
2437  [FULL_SIMP_TAC std_ss [abs, REAL_LT_IMP_LE, REAL_LT_LMUL], ALL_TAC] THEN
2438  DISC_RW_KILL THEN REWRITE_TAC [GSYM ABS_MUL] THEN
2439  FULL_SIMP_TAC std_ss [REAL_SUB_LDISTRIB, REAL_DIV_LMUL, REAL_POS_NZ],
2440  STRIP_TAC THEN FULL_SIMP_TAC std_ss [GSYM dist, DIST_MUL, abs,
2441                 REAL_LT_IMP_LE, REAL_LT_LMUL]]);
2442
2443val CBALL_SCALING = store_thm ("CBALL_SCALING",
2444 ``!c. &0 < c ==> !x r. cball(c * x,c * r) = IMAGE (\x. c * x) (cball(x,r))``,
2445  REWRITE_TAC [IMAGE_DEF, IN_CBALL] THEN BETA_TAC THEN
2446  SIMP_TAC std_ss [cball, EXTENSION, GSPECIFICATION, dist] THEN
2447  REPEAT STRIP_TAC THEN EQ_TAC THENL [DISCH_TAC THEN
2448  EXISTS_TAC ``x' / c:real`` THEN
2449  FULL_SIMP_TAC std_ss [REAL_DIV_LMUL, REAL_POS_NZ] THEN
2450  KNOW_TAC `` abs (x - x' / c) <= r <=> abs c * abs (x - x' / c) <= c * r:real`` THENL
2451  [FULL_SIMP_TAC std_ss [abs, REAL_LT_IMP_LE, REAL_LE_LMUL], ALL_TAC] THEN
2452  DISC_RW_KILL THEN REWRITE_TAC [GSYM ABS_MUL] THEN
2453  FULL_SIMP_TAC std_ss [REAL_SUB_LDISTRIB, REAL_DIV_LMUL, REAL_POS_NZ],
2454  STRIP_TAC THEN FULL_SIMP_TAC std_ss [GSYM dist, DIST_MUL, abs,
2455                 REAL_LT_IMP_LE, REAL_LE_LMUL]]);
2456
2457val CBALL_DIFF_BALL = store_thm ("CBALL_DIFF_BALL",
2458 ``!a r. cball(a,r) DIFF ball(a,r) = sphere(a,r)``,
2459  SIMP_TAC std_ss [ball, cball, sphere, EXTENSION, IN_DIFF, GSPECIFICATION] THEN
2460  REAL_ARITH_TAC);
2461
2462val BALL_UNION_SPHERE = store_thm ("BALL_UNION_SPHERE",
2463 ``!a r. ball(a,r) UNION sphere(a,r) = cball(a,r)``,
2464  SIMP_TAC std_ss [ball, cball, sphere, EXTENSION, IN_UNION, GSPECIFICATION] THEN
2465  REAL_ARITH_TAC);
2466
2467val SPHERE_UNION_BALL = store_thm ("SPHERE_UNION_BALL",
2468 ``!a r. sphere(a,r) UNION ball(a,r)  = cball(a,r)``,
2469  SIMP_TAC std_ss [ball, cball, sphere, EXTENSION, IN_UNION, GSPECIFICATION] THEN
2470  REAL_ARITH_TAC);
2471
2472val CBALL_DIFF_SPHERE = store_thm ("CBALL_DIFF_SPHERE",
2473 ``!a r. cball(a,r) DIFF sphere(a,r) = ball(a,r)``,
2474  REWRITE_TAC[EXTENSION, IN_DIFF, IN_SPHERE, IN_BALL, IN_CBALL] THEN
2475  REAL_ARITH_TAC);
2476
2477val OPEN_BALL = store_thm ("OPEN_BALL",
2478 ``!x e. open(ball(x,e))``,
2479  REPEAT GEN_TAC THEN REWRITE_TAC[open_def, ball] THEN
2480  FULL_SIMP_TAC std_ss [GSPECIFICATION] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
2481  MESON_TAC [REAL_SUB_LT, REAL_LT_SUB_LADD, REAL_ADD_SYM, REAL_LET_TRANS,
2482  DIST_TRIANGLE_ALT]);
2483
2484val CENTRE_IN_BALL = store_thm ("CENTRE_IN_BALL",
2485 ``!x e. x IN ball(x,e) <=> &0 < e``,
2486  MESON_TAC[IN_BALL, DIST_REFL]);
2487
2488val OPEN_CONTAINS_BALL = store_thm ("OPEN_CONTAINS_BALL",
2489 ``!s. open s <=> !x. x IN s ==> ?e. &0 < e /\ ball(x,e) SUBSET s``,
2490  REWRITE_TAC[open_def, SUBSET_DEF, IN_BALL] THEN SIMP_TAC std_ss [DIST_SYM]);
2491
2492val OPEN_CONTAINS_BALL_EQ = store_thm ("OPEN_CONTAINS_BALL_EQ",
2493 ``!s. open s ==> (!x. x IN s <=> ?e. &0 < e /\ ball(x,e) SUBSET s)``,
2494  MESON_TAC[OPEN_CONTAINS_BALL, SUBSET_DEF, CENTRE_IN_BALL]);
2495
2496val BALL_EQ_EMPTY = store_thm ("BALL_EQ_EMPTY",
2497 ``!x e. (ball(x,e) = {}) <=> e <= &0``,
2498  REWRITE_TAC[EXTENSION, IN_BALL, NOT_IN_EMPTY, REAL_NOT_LT] THEN
2499  MESON_TAC[DIST_POS_LE, REAL_LE_TRANS, DIST_REFL]);
2500
2501val BALL_EMPTY = store_thm ("BALL_EMPTY",
2502 ``!x e. e <= &0 ==> (ball(x,e) = {})``,
2503  REWRITE_TAC[BALL_EQ_EMPTY]);
2504
2505val OPEN_CONTAINS_CBALL = store_thm ("OPEN_CONTAINS_CBALL",
2506 ``!s. open s <=> !x. x IN s ==> ?e. &0 < e /\ cball(x,e) SUBSET s``,
2507  GEN_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN EQ_TAC THENL
2508   [ALL_TAC, ASM_MESON_TAC[SUBSET_TRANS, BALL_SUBSET_CBALL]] THEN
2509   KNOW_TAC ``!x. (x IN s ==> ?e. 0 < e /\ cball (x,e) SUBSET s) =
2510         (\x:real. x IN s ==> ?e. 0 < e /\ cball (x,e) SUBSET s) x`` THENL
2511   [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
2512   KNOW_TAC ``!x. (x IN s ==> ?e. 0 < e /\ ball (x,e) SUBSET s) =
2513         (\x:real. x IN s ==> ?e. 0 < e /\ ball (x,e) SUBSET s) x`` THENL
2514  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
2515  MATCH_MP_TAC MONO_ALL THEN GEN_TAC THEN BETA_TAC THEN
2516  MATCH_MP_TAC MONO_IMP THEN
2517  REWRITE_TAC[SUBSET_DEF, IN_BALL, IN_CBALL] THEN
2518  DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
2519  EXISTS_TAC ``e / &2:real`` THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN
2520  SUBGOAL_THEN ``e / &2 < e:real`` (fn th => ASM_MESON_TAC[th, REAL_LET_TRANS]) THEN
2521  UNDISCH_TAC ``0 < e:real`` THEN SIMP_TAC arith_ss [REAL_LT_HALF2]);
2522
2523val OPEN_CONTAINS_CBALL_EQ = store_thm ("OPEN_CONTAINS_CBALL_EQ",
2524 ``!s. open s ==> (!x. x IN s <=> ?e. &0 < e /\ cball(x,e) SUBSET s)``,
2525  MESON_TAC[OPEN_CONTAINS_CBALL, SUBSET_DEF, REAL_LT_IMP_LE, CENTRE_IN_CBALL]);
2526
2527val SPHERE_EQ_EMPTY = store_thm ("SPHERE_EQ_EMPTY",
2528 ``!a:real r. (sphere(a,r) = {}) <=> r < &0``,
2529  SIMP_TAC std_ss [sphere, EXTENSION, GSPECIFICATION, NOT_IN_EMPTY] THEN
2530  REPEAT GEN_TAC THEN EQ_TAC THENL [CCONTR_TAC THEN
2531  FULL_SIMP_TAC std_ss [REAL_NOT_LT] THEN
2532  UNDISCH_TAC ``!x. dist (a,x) <> r`` THEN
2533  FULL_SIMP_TAC std_ss [REAL_LE_LT, dist] THENL
2534  [EXISTS_TAC ``a - r:real`` THEN POP_ASSUM MP_TAC THEN
2535  REAL_ARITH_TAC, EXISTS_TAC ``a:real`` THEN
2536  METIS_TAC [REAL_SUB_REFL, EQ_SYM_EQ, ABS_0]], DISCH_TAC THEN
2537  ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN CCONTR_TAC THEN
2538  UNDISCH_TAC ``r < 0:real`` THEN FULL_SIMP_TAC std_ss [REAL_NOT_LT, DIST_POS_LE]]);
2539
2540val SPHERE_EMPTY = store_thm ("SPHERE_EMPTY",
2541 ``!a:real r. r < &0 ==> (sphere(a,r) = {})``,
2542  REWRITE_TAC[SPHERE_EQ_EMPTY]);
2543
2544val NEGATIONS_BALL = store_thm ("NEGATIONS_BALL",
2545 ``!r. IMAGE (\x:real. -x) (ball(0:real,r)) = ball(0,r)``,
2546  GEN_TAC THEN SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_BALL_0] THEN
2547  GEN_TAC THEN EQ_TAC THENL [METIS_TAC [ABS_NEG], DISCH_TAC THEN
2548  EXISTS_TAC ``-x:real`` THEN
2549  FULL_SIMP_TAC std_ss [ABS_NEG, REAL_NEG_NEG]]);
2550
2551val NEGATIONS_CBALL = store_thm ("NEGATIONS_CBALL",
2552 ``!r. IMAGE (\x. -x) (cball(0:real,r)) = cball(0,r)``,
2553  GEN_TAC THEN SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_CBALL_0] THEN
2554  GEN_TAC THEN EQ_TAC THENL [METIS_TAC [ABS_NEG], DISCH_TAC THEN
2555  EXISTS_TAC ``-x:real`` THEN
2556  FULL_SIMP_TAC std_ss [ABS_NEG, REAL_NEG_NEG]]);
2557
2558val NEGATIONS_SPHERE = store_thm ("NEGATIONS_SPHERE",
2559 ``!r. IMAGE (\x. -x) (sphere(0:real,r)) = sphere(0,r)``,
2560  GEN_TAC THEN SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_SPHERE_0] THEN
2561  GEN_TAC THEN EQ_TAC THENL [METIS_TAC [ABS_NEG], DISCH_TAC THEN
2562  EXISTS_TAC ``-x:real`` THEN
2563  FULL_SIMP_TAC std_ss [ABS_NEG, REAL_NEG_NEG]]);
2564
2565(* ------------------------------------------------------------------------- *)
2566(* Basic "localization" results are handy for connectedness.                 *)
2567(* ------------------------------------------------------------------------- *)
2568
2569val OPEN_IN_OPEN = store_thm ("OPEN_IN_OPEN",
2570 ``!s:real->bool u.
2571        open_in (subtopology euclidean u) s <=> ?t. open t /\ (s = u INTER t)``,
2572  REPEAT STRIP_TAC THEN SIMP_TAC std_ss [OPEN_IN_SUBTOPOLOGY, GSYM OPEN_IN] THEN
2573  SIMP_TAC std_ss [INTER_ACI]);
2574
2575val OPEN_IN_INTER_OPEN = store_thm ("OPEN_IN_INTER_OPEN",
2576 ``!s t u:real->bool.
2577        open_in (subtopology euclidean u) s /\ open t
2578        ==> open_in (subtopology euclidean u) (s INTER t)``,
2579  SIMP_TAC std_ss [OPEN_IN_OPEN] THEN REPEAT STRIP_TAC THEN
2580  ASM_MESON_TAC[INTER_ASSOC, OPEN_INTER]);
2581
2582val OPEN_IN_OPEN_INTER = store_thm ("OPEN_IN_OPEN_INTER",
2583 ``!u s. open s ==> open_in (subtopology euclidean u) (u INTER s)``,
2584  REWRITE_TAC[OPEN_IN_OPEN] THEN MESON_TAC[]);
2585
2586val OPEN_OPEN_IN_TRANS = store_thm ("OPEN_OPEN_IN_TRANS",
2587 ``!s t. open s /\ open t /\ t SUBSET s
2588         ==> open_in (subtopology euclidean s) t``,
2589  MESON_TAC[OPEN_IN_OPEN_INTER, SET_RULE ``(t:real->bool) SUBSET s ==> (t = s INTER t)``]);
2590
2591val OPEN_SUBSET = store_thm ("OPEN_SUBSET",
2592 ``!s t:real->bool.
2593        s SUBSET t /\ open s ==> open_in (subtopology euclidean t) s``,
2594  REPEAT STRIP_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN
2595  EXISTS_TAC ``s:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]);
2596
2597val CLOSED_IN_CLOSED = store_thm ("CLOSED_IN_CLOSED",
2598 ``!s:real->bool u.
2599    closed_in (subtopology euclidean u) s <=> ?t. closed t /\ (s = u INTER t)``,
2600  REPEAT STRIP_TAC THEN SIMP_TAC std_ss [CLOSED_IN_SUBTOPOLOGY, GSYM CLOSED_IN] THEN
2601  SIMP_TAC std_ss [INTER_ACI]);
2602
2603val CLOSED_SUBSET_EQ = store_thm ("CLOSED_SUBSET_EQ",
2604 ``!u s:real->bool.
2605        closed s ==> (closed_in (subtopology euclidean u) s <=> s SUBSET u)``,
2606  REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
2607   [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN
2608    REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY],
2609    REWRITE_TAC[CLOSED_IN_CLOSED] THEN EXISTS_TAC ``s:real->bool`` THEN
2610    REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]]);
2611
2612val CLOSED_IN_INTER_CLOSED = store_thm ("CLOSED_IN_INTER_CLOSED",
2613 ``!s t u:real->bool.
2614        closed_in (subtopology euclidean u) s /\ closed t
2615        ==> closed_in (subtopology euclidean u) (s INTER t)``,
2616  SIMP_TAC std_ss [CLOSED_IN_CLOSED] THEN REPEAT STRIP_TAC THEN
2617  ASM_MESON_TAC[INTER_ASSOC, CLOSED_INTER]);
2618
2619val CLOSED_IN_CLOSED_INTER = store_thm ("CLOSED_IN_CLOSED_INTER",
2620 ``!u s. closed s ==> closed_in (subtopology euclidean u) (u INTER s)``,
2621  REWRITE_TAC[CLOSED_IN_CLOSED] THEN MESON_TAC[]);
2622
2623val CLOSED_SUBSET = store_thm ("CLOSED_SUBSET",
2624 ``!s t:real->bool.
2625        s SUBSET t /\ closed s ==> closed_in (subtopology euclidean t) s``,
2626  REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN
2627  EXISTS_TAC ``s:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]);
2628
2629val OPEN_IN_SUBSET_TRANS = store_thm ("OPEN_IN_SUBSET_TRANS",
2630 ``!s t u:real->bool.
2631        open_in (subtopology euclidean u) s /\ s SUBSET t /\ t SUBSET u
2632        ==> open_in (subtopology euclidean t) s``,
2633  REPEAT GEN_TAC THEN SIMP_TAC std_ss [OPEN_IN_OPEN, LEFT_EXISTS_AND_THM] THEN
2634  SET_TAC[]);
2635
2636val CLOSED_IN_SUBSET_TRANS = store_thm ("CLOSED_IN_SUBSET_TRANS",
2637 ``!s t u:real->bool.
2638        closed_in (subtopology euclidean u) s /\ s SUBSET t /\ t SUBSET u
2639        ==> closed_in (subtopology euclidean t) s``,
2640  REPEAT GEN_TAC THEN SIMP_TAC std_ss [CLOSED_IN_CLOSED] THEN
2641  REPEAT STRIP_TAC THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]);
2642
2643val open_in = store_thm ("open_in",
2644 ``!u s:real->bool.
2645        open_in (subtopology euclidean u) s <=>
2646          s SUBSET u /\
2647          !x. x IN s ==> ?e. &0 < e /\
2648                             !x'. x' IN u /\ dist(x',x) < e ==> x' IN s``,
2649  REPEAT GEN_TAC THEN
2650  SIMP_TAC std_ss [OPEN_IN_SUBTOPOLOGY, GSYM OPEN_IN] THEN EQ_TAC THENL
2651   [REWRITE_TAC[open_def] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[INTER_SUBSET, IN_INTER],
2652    ALL_TAC] THEN
2653  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN DISCH_TAC THEN
2654  FULL_SIMP_TAC std_ss [GSYM RIGHT_EXISTS_IMP_THM] THEN POP_ASSUM MP_TAC THEN
2655  SIMP_TAC std_ss [SKOLEM_THM] THEN DISCH_THEN(X_CHOOSE_TAC ``d:real->real``) THEN
2656  EXISTS_TAC ``BIGUNION {b | ?x:real. (b = ball(x,d x)) /\ x IN s}`` THEN
2657  CONJ_TAC THENL
2658   [MATCH_MP_TAC OPEN_BIGUNION THEN
2659    ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN METIS_TAC [LEFT_EXISTS_IMP_THM, OPEN_BALL],
2660    GEN_REWR_TAC I [EXTENSION] THEN
2661    SIMP_TAC std_ss [IN_INTER, IN_BIGUNION, GSPECIFICATION] THEN
2662    ASM_MESON_TAC[SUBSET_DEF, DIST_REFL, DIST_SYM, IN_BALL]]);
2663
2664val OPEN_IN_CONTAINS_BALL = store_thm ("OPEN_IN_CONTAINS_BALL",
2665 ``!s t:real->bool.
2666        open_in (subtopology euclidean t) s <=>
2667        s SUBSET t /\
2668        !x. x IN s ==> ?e. &0 < e /\ ball(x,e) INTER t SUBSET s``,
2669  SIMP_TAC std_ss [open_in, INTER_DEF, SUBSET_DEF, GSPECIFICATION, IN_BALL] THEN
2670  MESON_TAC[DIST_SYM]);
2671
2672val OPEN_IN_CONTAINS_CBALL = store_thm ("OPEN_IN_CONTAINS_CBALL",
2673 ``!s t:real->bool.
2674        open_in (subtopology euclidean t) s <=>
2675        s SUBSET t /\
2676        !x. x IN s ==> ?e. &0 < e /\ cball(x,e) INTER t SUBSET s``,
2677  REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_CONTAINS_BALL] THEN
2678  AP_TERM_TAC THEN REWRITE_TAC[IN_BALL, IN_INTER, SUBSET_DEF, IN_CBALL] THEN
2679  MESON_TAC[METIS [REAL_LT_HALF1, REAL_LT_HALF2, REAL_LET_TRANS]
2680    ``&0 < e:real ==> &0 < e / &2 /\ (x <= e / &2 ==> x < e)``,
2681            REAL_LT_IMP_LE]);
2682
2683(* ------------------------------------------------------------------------- *)
2684(* These "transitivity" results are handy too.                               *)
2685(* ------------------------------------------------------------------------- *)
2686
2687val OPEN_IN_TRANS = store_thm ("OPEN_IN_TRANS",
2688 ``!s t u. open_in (subtopology euclidean t) s /\
2689           open_in (subtopology euclidean u) t
2690           ==> open_in (subtopology euclidean u) s``,
2691  ASM_MESON_TAC[OPEN_IN_OPEN, OPEN_IN, OPEN_INTER, INTER_ASSOC]);
2692
2693val OPEN_IN_TRANS_EQ = store_thm ("OPEN_IN_TRANS_EQ",
2694 ``!s t:real->bool.
2695        (!u. open_in (subtopology euclidean t) u
2696             ==> open_in (subtopology euclidean s) t)
2697        <=> open_in (subtopology euclidean s) t``,
2698  MESON_TAC[OPEN_IN_TRANS, OPEN_IN_REFL]);
2699
2700val OPEN_IN_OPEN_TRANS = store_thm ("OPEN_IN_OPEN_TRANS",
2701 ``!s t. open_in (subtopology euclidean t) s /\ open t ==> open s``,
2702  REWRITE_TAC[ONCE_REWRITE_RULE[GSYM SUBTOPOLOGY_UNIV] OPEN_IN] THEN
2703  REWRITE_TAC[OPEN_IN_TRANS]);
2704
2705val CLOSED_IN_TRANS = store_thm ("CLOSED_IN_TRANS",
2706 ``!s t u. closed_in (subtopology euclidean t) s /\
2707           closed_in (subtopology euclidean u) t
2708           ==> closed_in (subtopology euclidean u) s``,
2709  ASM_MESON_TAC[CLOSED_IN_CLOSED, CLOSED_IN, CLOSED_INTER, INTER_ASSOC]);
2710
2711val CLOSED_IN_TRANS_EQ = store_thm ("CLOSED_IN_TRANS_EQ",
2712 ``!s t:real->bool.
2713        (!u. closed_in (subtopology euclidean t) u
2714             ==> closed_in (subtopology euclidean s) t)
2715        <=> closed_in (subtopology euclidean s) t``,
2716  MESON_TAC[CLOSED_IN_TRANS, CLOSED_IN_REFL]);
2717
2718val CLOSED_IN_CLOSED_TRANS = store_thm ("CLOSED_IN_CLOSED_TRANS",
2719 ``!s t. closed_in (subtopology euclidean t) s /\ closed t ==> closed s``,
2720  REWRITE_TAC[ONCE_REWRITE_RULE[GSYM SUBTOPOLOGY_UNIV] CLOSED_IN] THEN
2721  REWRITE_TAC[CLOSED_IN_TRANS]);
2722
2723val OPEN_IN_SUBTOPOLOGY_INTER_SUBSET = store_thm ("OPEN_IN_SUBTOPOLOGY_INTER_SUBSET",
2724 ``!s u v. open_in (subtopology euclidean u) (u INTER s) /\ v SUBSET u
2725           ==> open_in (subtopology euclidean v) (v INTER s)``,
2726  REPEAT GEN_TAC THEN SIMP_TAC std_ss [OPEN_IN_OPEN, GSYM LEFT_EXISTS_AND_THM] THEN
2727  STRIP_TAC THEN EXISTS_TAC ``t:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]);
2728
2729val OPEN_IN_OPEN_EQ = store_thm ("OPEN_IN_OPEN_EQ",
2730 ``!s t. open s
2731         ==> (open_in (subtopology euclidean s) t <=> open t /\ t SUBSET s)``,
2732  MESON_TAC[OPEN_OPEN_IN_TRANS, OPEN_IN_OPEN_TRANS, open_in]);
2733
2734val CLOSED_IN_CLOSED_EQ = store_thm ("CLOSED_IN_CLOSED_EQ",
2735 ``!s t. closed s
2736         ==> (closed_in (subtopology euclidean s) t <=>
2737              closed t /\ t SUBSET s)``,
2738  MESON_TAC[CLOSED_SUBSET, CLOSED_IN_CLOSED_TRANS, closed_in,
2739            TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]);
2740
2741(* ------------------------------------------------------------------------- *)
2742(* Line segments, with open/closed overloading of (a,b) and [a,b].           *)
2743(* ------------------------------------------------------------------------- *)
2744
2745val closed_segment = new_definition ("closed_segment",
2746  ``closed_segment (l:(real#real)list) =
2747   {((&1:real) - u) * FST(HD l) + u * SND(HD l) | &0 <= u /\ u <= &1}``);
2748
2749val open_segment = new_definition ("open_segment",
2750 ``open_segment(a,b) = closed_segment[a,b] DIFF {a;b}``);
2751
2752val OPEN_SEGMENT_ALT = store_thm ("OPEN_SEGMENT_ALT",
2753 ``!a b:real.
2754        ~(a = b)
2755        ==> (open_segment(a,b) = {(&1 - u) * a + u * b | &0 < u /\ u < &1:real})``,
2756  REPEAT STRIP_TAC THEN REWRITE_TAC[open_segment, closed_segment, FST, SND, HD] THEN
2757  SIMP_TAC std_ss [EXTENSION, IN_DIFF, IN_INSERT, NOT_IN_EMPTY, GSPECIFICATION] THEN
2758  X_GEN_TAC ``x:real`` THEN SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM] THEN
2759  AP_TERM_TAC THEN SIMP_TAC std_ss [FUN_EQ_THM] THEN
2760  X_GEN_TAC ``u:real`` THEN ASM_CASES_TAC ``x:real = (&1 - u) * a + u * b`` THEN
2761  ASM_REWRITE_TAC[REAL_LE_LT,
2762    REAL_ARITH ``((&1 - u) * a + u * b = a) <=> (u * (b - a) = 0:real)``,
2763    REAL_ARITH ``((&1 - u) * a + u * b = b) <=> ((&1 - u) * (b - a) = 0:real)``,
2764    REAL_ENTIRE, REAL_SUB_0] THEN UNDISCH_TAC ``a <> b:real`` THEN DISCH_TAC THEN
2765        POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN DISCH_TAC THEN
2766        ASM_REWRITE_TAC [] THEN REAL_ARITH_TAC);
2767
2768val _ = overload_on ("segment", ``open_segment``);
2769val _ = overload_on ("segment", ``closed_segment``);
2770
2771val segment = store_thm ("segment",
2772 ``(segment[a,b] = {(&1 - u) * a + u * b | &0 <= u /\ u <= &1:real}) /\
2773   (segment(a,b) = segment[a,b] DIFF {a;b:real})``,
2774  REWRITE_TAC[open_segment, closed_segment, HD]);
2775
2776val SEGMENT_REFL = store_thm ("SEGMENT_REFL",
2777 ``(!a. segment[a,a] = {a}) /\
2778   (!a. segment(a,a) = {})``,
2779  REWRITE_TAC[segment, REAL_ARITH ``(&1 - u) * a + u * a = a:real``] THEN
2780  CONJ_TAC THENL [ALL_TAC, SET_TAC[REAL_POS]] THEN
2781  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION] THEN REPEAT GEN_TAC THEN
2782  EQ_TAC THEN REWRITE_TAC [IN_SING] THENL [METIS_TAC [], ALL_TAC] THEN DISCH_TAC THEN
2783  ASM_REWRITE_TAC [] THEN EXISTS_TAC ``1:real`` THEN REAL_ARITH_TAC);
2784
2785val IN_SEGMENT = store_thm ("IN_SEGMENT",
2786 ``!a b x:real.
2787        ((x IN segment[a,b] <=>
2788         ?u. &0 <= u /\ u <= &1 /\ (x = (&1 - u) * a + u * b:real))) /\
2789        ((x IN segment(a,b) <=>
2790         ~(a = b) /\ ?u. &0 < u /\ u < &1 /\ (x = (&1 - u) * a + u * b:real)))``,
2791  REPEAT STRIP_TAC THENL
2792   [SIMP_TAC std_ss [segment, GSPECIFICATION, CONJ_ASSOC], ALL_TAC] THEN
2793  ASM_CASES_TAC ``a:real = b`` THEN
2794  ASM_REWRITE_TAC[SEGMENT_REFL, NOT_IN_EMPTY] THEN
2795  ASM_SIMP_TAC std_ss [OPEN_SEGMENT_ALT, GSPECIFICATION, CONJ_ASSOC] THEN METIS_TAC []);
2796
2797val SEGMENT_SYM = store_thm ("SEGMENT_SYM",
2798 ``(!a b:real. segment[a,b] = segment[b,a]) /\
2799   (!a b:real. segment(a,b) = segment(b,a))``,
2800  MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN
2801  SIMP_TAC std_ss [open_segment] THEN
2802  CONJ_TAC THENL [ALL_TAC, SIMP_TAC std_ss [INSERT_COMM, INSERT_INSERT]] THEN
2803  REWRITE_TAC[EXTENSION, IN_SEGMENT] THEN REPEAT GEN_TAC THEN EQ_TAC THEN
2804  DISCH_THEN(X_CHOOSE_TAC ``u:real``) THEN EXISTS_TAC ``&1 - u:real`` THEN
2805  ASM_REWRITE_TAC[] THEN
2806  REPEAT CONJ_TAC THEN TRY ASM_ARITH_TAC THEN ASM_REAL_ARITH_TAC);
2807
2808val ENDS_IN_SEGMENT = store_thm ("ENDS_IN_SEGMENT",
2809 ``!a b. a IN segment[a,b] /\ b IN segment[a,b]``,
2810  REPEAT STRIP_TAC THEN SIMP_TAC std_ss [segment, GSPECIFICATION] THENL
2811   [EXISTS_TAC ``&0:real``, EXISTS_TAC ``&1:real``] THEN
2812  (CONJ_TAC THENL [REAL_ARITH_TAC, REAL_ARITH_TAC]));
2813
2814val ENDS_NOT_IN_SEGMENT =  store_thm ("ENDS_NOT_IN_SEGMENT",
2815 ``!a b. ~(a IN segment(a,b)) /\ ~(b IN segment(a,b))``,
2816  REWRITE_TAC[open_segment] THEN SET_TAC[]);
2817
2818val SEGMENT_CLOSED_OPEN = store_thm ("SEGMENT_CLOSED_OPEN",
2819 ``!a b. segment[a,b] = segment(a,b) UNION {a;b}``,
2820  REPEAT GEN_TAC THEN REWRITE_TAC[open_segment] THEN MATCH_MP_TAC(SET_RULE
2821   ``a IN s /\ b IN s ==> (s = (s DIFF {a;b}) UNION {a;b})``) THEN
2822  REWRITE_TAC[ENDS_IN_SEGMENT]);
2823
2824val SEGMENT_OPEN_SUBSET_CLOSED = store_thm ("SEGMENT_OPEN_SUBSET_CLOSED",
2825 ``!a b. segment(a,b) SUBSET segment[a,b]``,
2826  REWRITE_TAC[CONJUNCT2(SPEC_ALL segment)] THEN SET_TAC[]);
2827
2828val MIDPOINT_IN_SEGMENT = store_thm ("MIDPOINT_IN_SEGMENT",
2829 ``(!a b:real. midpoint(a,b) IN segment[a,b]) /\
2830   (!a b:real. midpoint(a,b) IN segment(a,b) <=> ~(a = b))``,
2831  REWRITE_TAC[IN_SEGMENT] THEN REPEAT STRIP_TAC THENL
2832   [ALL_TAC, ASM_CASES_TAC ``a:real = b`` THEN ASM_REWRITE_TAC[]] THEN
2833  EXISTS_TAC ``&1 / &2:real`` THEN REWRITE_TAC[midpoint] THEN
2834  REWRITE_TAC [REAL_HALF_BETWEEN] THEN
2835  REWRITE_TAC [METIS [REAL_HALF_DOUBLE, REAL_EQ_SUB_RADD]
2836   ``1 - 1 / 2 = 1 / 2:real``] THEN REWRITE_TAC [GSYM REAL_LDISTRIB] THEN
2837   REWRITE_TAC [REAL_INV_1OVER]);
2838
2839val BETWEEN_IN_SEGMENT = store_thm ("BETWEEN_IN_SEGMENT",
2840 ``!x a b:real. between x (a,b) <=> x IN segment[a,b]``,
2841  REPEAT GEN_TAC THEN REWRITE_TAC[between] THEN
2842  ASM_CASES_TAC ``a:real = b`` THEN
2843  ASM_REWRITE_TAC[SEGMENT_REFL, IN_SING] THENL
2844  [REWRITE_TAC [dist] THEN REAL_ARITH_TAC, ALL_TAC] THEN
2845  SIMP_TAC std_ss [segment, GSPECIFICATION] THEN EQ_TAC THENL
2846   [DISCH_THEN(ASSUME_TAC o SYM) THEN
2847    EXISTS_TAC ``dist(a:real,x) / dist(a,b)`` THEN
2848    ASM_SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_LE_RDIV_EQ, DIST_POS_LT] THEN CONJ_TAC
2849    THENL [FIRST_ASSUM(SUBST1_TAC o SYM) THEN
2850    ASM_REWRITE_TAC [dist] THEN REWRITE_TAC [REAL_SUB_RDISTRIB, REAL_MUL_LID] THEN
2851        ONCE_REWRITE_TAC [REAL_ARITH ``(x = a - y + z) = (y - z = a - x:real)``] THEN
2852        REWRITE_TAC [GSYM REAL_SUB_LDISTRIB] THEN KNOW_TAC ``(a - b:real) <> 0`` THENL
2853        [ASM_REAL_ARITH_TAC, DISCH_TAC] THEN ASM_SIMP_TAC std_ss [GSYM ABS_DIV] THEN
2854        Cases_on `0 < a - b:real` THENL
2855        [ASM_SIMP_TAC std_ss [GSYM REAL_EQ_RDIV_EQ] THEN REWRITE_TAC [ABS_REFL] THEN
2856         ASM_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_MUL_LZERO] THEN
2857         FULL_SIMP_TAC std_ss [dist] THEN ASM_REAL_ARITH_TAC,
2858         FULL_SIMP_TAC std_ss [REAL_NOT_LT, REAL_LE_LT] THENL
2859         [ALL_TAC, ASM_REAL_ARITH_TAC] THEN
2860         POP_ASSUM MP_TAC THEN GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_LT_NEG] THEN
2861         ONCE_REWRITE_TAC [REAL_ARITH ``(-0 = 0:real) /\ (-(a - b) = (b - a:real))``] THEN
2862         DISCH_TAC THEN ONCE_REWRITE_TAC [REAL_ARITH ``((a - b) = -(b - a:real))``] THEN
2863         ONCE_ASM_REWRITE_TAC [REAL_ARITH ``a * -b = -a * b:real``] THEN
2864         ASM_SIMP_TAC std_ss [GSYM REAL_EQ_RDIV_EQ] THEN REWRITE_TAC [real_div] THEN
2865         ONCE_REWRITE_TAC [REAL_ARITH ``(-a * b = -(a * b:real))``] THEN
2866         REWRITE_TAC [REAL_EQ_NEG] THEN KNOW_TAC ``(b - a:real) <> 0`` THENL
2867         [ASM_REAL_ARITH_TAC, DISCH_TAC] THEN ASM_SIMP_TAC std_ss [GSYM REAL_NEG_INV] THEN
2868         ONCE_REWRITE_TAC [REAL_ARITH ``(-(a * b) = (a * -b:real))``] THEN
2869         FULL_SIMP_TAC std_ss [REAL_NEG_NEG, dist] THEN
2870         REWRITE_TAC [ABS_REFL, GSYM real_div] THEN
2871         ASM_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_MUL_LZERO] THEN
2872         ASM_REAL_ARITH_TAC], ALL_TAC] THEN FULL_SIMP_TAC std_ss [dist] THEN
2873         ASM_REAL_ARITH_TAC, ALL_TAC] THEN
2874    STRIP_TAC THEN ASM_REWRITE_TAC[dist] THEN
2875    SIMP_TAC std_ss [REAL_ARITH ``a - ((&1 - u) * a + u * b) = u * (a - b:real)``,
2876                REAL_ARITH ``((&1 - u) * a + u * b) - b = (&1 - u) * (a - b:real)``,
2877                ABS_MUL, GSYM REAL_ADD_RDISTRIB] THEN
2878        FULL_SIMP_TAC std_ss [REAL_ARITH ``u <= 1 <=> 0 <= 1 - u:real``, GSYM ABS_REFL] THEN
2879        REAL_ARITH_TAC);
2880
2881val REAL_CONVEX_BOUND_LE = store_thm ("REAL_CONVEX_BOUND_LE",
2882 ``!x y a u v. x <= a /\ y <= a /\ &0 <= u /\ &0 <= v /\ (u + v = &1:real)
2883   ==> u * x + v * y <= a:real``,
2884  REPEAT STRIP_TAC THEN
2885  MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``(u + v) * a:real`` THEN
2886  CONJ_TAC THENL [ALL_TAC, ASM_SIMP_TAC std_ss [REAL_LE_REFL, REAL_MUL_LID]] THEN
2887  ASM_SIMP_TAC std_ss [REAL_ADD_RDISTRIB] THEN MATCH_MP_TAC REAL_LE_ADD2 THEN
2888  UNDISCH_TAC ``0 <= v:real`` THEN GEN_REWR_TAC LAND_CONV [REAL_LE_LT] THEN
2889  STRIP_TAC THEN UNDISCH_TAC ``0 <= u:real`` THEN
2890  GEN_REWR_TAC LAND_CONV [REAL_LE_LT] THEN STRIP_TAC THEN
2891  ASM_SIMP_TAC std_ss [REAL_LE_LMUL] THEN POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN
2892  POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN DISCH_TAC THEN
2893  DISCH_TAC THEN ASM_REWRITE_TAC [REAL_LE_LT, REAL_MUL_LZERO]);
2894
2895val IN_SEGMENT_COMPONENT = store_thm ("IN_SEGMENT_COMPONENT",
2896 ``!a b x:real i. x IN segment[a,b]
2897        ==> min (a) (b) <= x /\ x <= max (a) (b)``,
2898  REPEAT STRIP_TAC THEN
2899  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [IN_SEGMENT]) THEN
2900  DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
2901  FIRST_X_ASSUM(X_CHOOSE_THEN ``t:real`` STRIP_ASSUME_TAC) THEN
2902  ASM_REWRITE_TAC [] THEN
2903  SIMP_TAC std_ss [REAL_ARITH ``c <= u * a + t * b <=> u * -a + t * -b <= -c:real``] THEN
2904  MATCH_MP_TAC REAL_CONVEX_BOUND_LE THEN
2905  RW_TAC real_ss [] THEN
2906  ASM_REAL_ARITH_TAC);
2907
2908val SEGMENT_TRANSLATION = store_thm ("SEGMENT_TRANSLATION",
2909 ``(!c a b. segment[c + a,c + b] = IMAGE (\x. c + x) (segment[a,b])) /\
2910   (!c a b. segment(c + a,c + b) = IMAGE (\x. c + x) (segment(a,b)))``,
2911  SIMP_TAC std_ss [EXTENSION, IN_SEGMENT, IN_IMAGE] THEN
2912  SIMP_TAC std_ss [REAL_ARITH ``(&1 - u) * (c + a) + u * (c + b) =
2913                            c + (&1 - u) * a + u * b:real``] THEN
2914  SIMP_TAC std_ss [REAL_ARITH ``(c + a:real = c + b) <=> (a = b)``] THEN
2915  CONJ_TAC THEN
2916  (REPEAT GEN_TAC THEN EQ_TAC THENL
2917   [REPEAT STRIP_TAC THEN EXISTS_TAC ``(1 - u) * a + u * b:real`` THEN
2918    ASM_SIMP_TAC std_ss [REAL_ADD_ASSOC] THEN EXISTS_TAC ``u:real`` THEN
2919        ASM_SIMP_TAC std_ss [],
2920        REPEAT STRIP_TAC THEN EXISTS_TAC ``u:real`` THEN
2921        ASM_SIMP_TAC std_ss [REAL_ADD_ASSOC]]));
2922
2923val CLOSED_SEGMENT_LINEAR_IMAGE = store_thm ("CLOSED_SEGMENT_LINEAR_IMAGE",
2924 ``!f a b. linear f
2925           ==> (segment[f a,f b] = IMAGE f (segment[a,b]))``,
2926  REPEAT STRIP_TAC THEN REWRITE_TAC[EXTENSION, IN_IMAGE, IN_SEGMENT] THEN
2927  FIRST_ASSUM(fn th => REWRITE_TAC[GSYM(MATCH_MP LINEAR_CMUL th)]) THEN
2928  FIRST_ASSUM(fn th => REWRITE_TAC[GSYM(MATCH_MP LINEAR_ADD th)]) THEN
2929  MESON_TAC[]);
2930
2931val OPEN_SEGMENT_LINEAR_IMAGE = store_thm ("OPEN_SEGMENT_LINEAR_IMAGE",
2932 ``!f:real->real a b.
2933        linear f /\ (!x y. (f x = f y) ==> (x = y))
2934        ==> (segment(f a,f b) = IMAGE f (segment(a,b)))``,
2935  REWRITE_TAC[open_segment, closed_segment, FST, SND, HD] THEN
2936  SIMP_TAC std_ss [linear, IN_IMAGE, dist, EXTENSION, GSPECIFICATION, IN_DIFF] THEN
2937  REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL
2938  [EXISTS_TAC ``(1 - u) * a + u * b:real`` THEN
2939   CONJ_TAC THENL [METIS_TAC [], ALL_TAC] THEN
2940   CONJ_TAC THENL [EXISTS_TAC ``u:real`` THEN ASM_REWRITE_TAC [], ALL_TAC] THEN
2941   ASM_SET_TAC [],
2942   CONJ_TAC THENL [EXISTS_TAC ``u:real`` THEN METIS_TAC [], ALL_TAC] THEN
2943   ASM_SET_TAC []]);
2944
2945val IN_OPEN_SEGMENT = store_thm ("IN_OPEN_SEGMENT",
2946 ``!a b x:real.
2947        x IN segment(a,b) <=> x IN segment[a,b] /\ ~(x = a) /\ ~(x = b)``,
2948  REPEAT GEN_TAC THEN REWRITE_TAC[open_segment, IN_DIFF] THEN SET_TAC[]);
2949
2950val IN_OPEN_SEGMENT_ALT = store_thm ("IN_OPEN_SEGMENT_ALT",
2951 ``!a b x:real.
2952        x IN segment(a,b) <=>
2953        x IN segment[a,b] /\ ~(x = a) /\ ~(x = b) /\ ~(a = b)``,
2954  REPEAT GEN_TAC THEN ASM_CASES_TAC ``a:real = b`` THEN
2955  ASM_REWRITE_TAC[SEGMENT_REFL, IN_SING, NOT_IN_EMPTY] THEN
2956  ASM_MESON_TAC[IN_OPEN_SEGMENT]);
2957
2958val COLLINEAR_DIST_IN_CLOSED_SEGMENT = store_thm ("COLLINEAR_DIST_IN_CLOSED_SEGMENT",
2959 ``!a b x. collinear {x;a;b} /\
2960           dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)
2961           ==> x IN segment[a,b]``,
2962  REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT, COLLINEAR_DIST_BETWEEN]);
2963
2964val COLLINEAR_DIST_IN_OPEN_SEGMENT = store_thm ("COLLINEAR_DIST_IN_OPEN_SEGMENT",
2965 ``!a b x. collinear {x;a;b} /\
2966           dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b)
2967           ==> x IN segment(a,b)``,
2968  REWRITE_TAC[IN_OPEN_SEGMENT] THEN
2969  METIS_TAC[COLLINEAR_DIST_IN_CLOSED_SEGMENT, REAL_LT_LE, DIST_SYM]);
2970
2971val DIST_IN_OPEN_CLOSED_SEGMENT = store_thm ("DIST_IN_OPEN_CLOSED_SEGMENT",
2972 ``(!a b x:real.
2973    x IN segment[a,b] ==> dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)) /\
2974   (!a b x:real.
2975    x IN segment(a,b) ==> dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b))``,
2976  SIMP_TAC std_ss [IN_SEGMENT, GSYM RIGHT_EXISTS_AND_THM, LEFT_IMP_EXISTS_THM, dist,
2977           REAL_ARITH
2978    ``(((&1 - u) * a + u * b) - a:real = u * (b - a)) /\
2979      (((&1 - u) * a + u * b) - b = -(&1 - u) * (b - a))``] THEN
2980  REWRITE_TAC[ABS_MUL, ABS_NEG] THEN ONCE_REWRITE_TAC [ABS_SUB] THEN CONJ_TAC THEN
2981  REPEAT GEN_TAC THEN STRIP_TAC THENL
2982   [ONCE_REWRITE_TAC [REAL_ARITH
2983     ``x * y <= abs (b - a) <=> x * y <= abs (a - b:real)``] THEN
2984    REWRITE_TAC[REAL_ARITH ``x * y <= y <=> x * y <= &1 * y:real``] THEN
2985    CONJ_TAC THEN MATCH_MP_TAC REAL_LE_RMUL_IMP THEN
2986    REWRITE_TAC[ABS_POS] THEN ASM_REAL_ARITH_TAC,
2987    ONCE_REWRITE_TAC [REAL_ARITH
2988     ``x * y < abs (b - a) <=> x * y < abs (a - b:real)``] THEN
2989    REWRITE_TAC[REAL_ARITH ``x * y < y <=> x * y < &1 * y:real``] THEN
2990    CONJ_TAC THEN MATCH_MP_TAC REAL_LT_RMUL_IMP THEN
2991    ASM_REAL_ARITH_TAC]);
2992
2993val DIST_IN_CLOSED_SEGMENT = store_thm ("DIST_IN_CLOSED_SEGMENT",
2994  ``(!a b x:real.
2995    x IN segment[a,b] ==> dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b))``,
2996  REWRITE_TAC [DIST_IN_OPEN_CLOSED_SEGMENT]);
2997
2998val DIST_IN_OPEN_SEGMENT = store_thm ("DIST_IN_OPEN_SEGMENT",
2999  ``(!a b x:real.
3000    x IN segment(a,b) ==> dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b))``,
3001  REWRITE_TAC [DIST_IN_OPEN_CLOSED_SEGMENT]);
3002
3003(* ------------------------------------------------------------------------- *)
3004(* Connectedness.                                                            *)
3005(* ------------------------------------------------------------------------- *)
3006
3007val connected = new_definition ("connected",
3008  ``connected s <=>
3009      ~(?e1 e2. open e1 /\ open e2 /\ s SUBSET (e1 UNION e2) /\
3010                (e1 INTER e2 INTER s = {}) /\
3011                ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))``);
3012
3013val CONNECTED_CLOSED = store_thm ("CONNECTED_CLOSED",
3014 ``!s:real->bool.
3015        connected s <=>
3016        ~(?e1 e2. closed e1 /\ closed e2 /\ s SUBSET (e1 UNION e2) /\
3017                  (e1 INTER e2 INTER s = {}) /\
3018                  ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))``,
3019  GEN_TAC THEN REWRITE_TAC[connected] THEN AP_TERM_TAC THEN
3020  EQ_TAC THEN STRIP_TAC THEN
3021  MAP_EVERY EXISTS_TAC [``univ(:real) DIFF e1``, ``univ(:real) DIFF e2``] THEN
3022  ASM_REWRITE_TAC[GSYM closed_def, GSYM OPEN_CLOSED] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]);
3023
3024val CONNECTED_OPEN_IN = store_thm ("CONNECTED_OPEN_IN",
3025 ``!s. connected s <=>
3026           ~(?e1 e2.
3027                 open_in (subtopology euclidean s) e1 /\
3028                 open_in (subtopology euclidean s) e2 /\
3029                 s SUBSET e1 UNION e2 /\
3030                 (e1 INTER e2 = {}) /\
3031                 ~(e1 = {}) /\
3032                 ~(e2 = {}))``,
3033  GEN_TAC THEN REWRITE_TAC[connected, OPEN_IN_OPEN] THEN
3034  SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM, GSYM RIGHT_EXISTS_AND_THM] THEN
3035  REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN SET_TAC[]);
3036
3037val CONNECTED_OPEN_IN_EQ = store_thm ("CONNECTED_OPEN_IN_EQ",
3038 ``!s. connected s <=>
3039           ~(?e1 e2.
3040                 open_in (subtopology euclidean s) e1 /\
3041                 open_in (subtopology euclidean s) e2 /\
3042                 (e1 UNION e2 = s) /\ (e1 INTER e2 = {}) /\
3043                 ~(e1 = {}) /\ ~(e2 = {}))``,
3044  GEN_TAC THEN REWRITE_TAC[CONNECTED_OPEN_IN] THEN
3045  AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
3046  EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN
3047  RULE_ASSUM_TAC(REWRITE_RULE[OPEN_IN_CLOSED_IN_EQ,
3048   TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]) THEN
3049  REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]);
3050
3051val CONNECTED_CLOSED_IN = store_thm ("CONNECTED_CLOSED_IN",
3052 ``!s. connected s <=>
3053           ~(?e1 e2.
3054                 closed_in (subtopology euclidean s) e1 /\
3055                 closed_in (subtopology euclidean s) e2 /\
3056                 s SUBSET e1 UNION e2 /\
3057                 (e1 INTER e2 = {}) /\
3058                 ~(e1 = {}) /\
3059                 ~(e2 = {}))``,
3060  GEN_TAC THEN REWRITE_TAC[CONNECTED_CLOSED, CLOSED_IN_CLOSED] THEN
3061  SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM, GSYM RIGHT_EXISTS_AND_THM] THEN
3062  REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN SET_TAC[]);
3063
3064val CONNECTED_CLOSED_IN_EQ = store_thm ("CONNECTED_CLOSED_IN_EQ",
3065 ``!s. connected s <=>
3066           ~(?e1 e2.
3067                 closed_in (subtopology euclidean s) e1 /\
3068                 closed_in (subtopology euclidean s) e2 /\
3069                 (e1 UNION e2 = s) /\ (e1 INTER e2 = {}) /\
3070                 ~(e1 = {}) /\ ~(e2 = {}))``,
3071  GEN_TAC THEN REWRITE_TAC[CONNECTED_CLOSED_IN] THEN
3072  AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
3073  EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN
3074  RULE_ASSUM_TAC(REWRITE_RULE[closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]) THEN
3075  REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]);
3076
3077val EXISTS_DIFF = store_thm ("EXISTS_DIFF",
3078 ``(?s:'a->bool. P(UNIV DIFF s)) <=> (?s. P s)``,
3079  MESON_TAC[prove(``UNIV DIFF (UNIV DIFF s) = s``,SET_TAC[])]);
3080
3081val CONNECTED_CLOPEN = store_thm ("CONNECTED_CLOPEN",
3082 ``!s. connected s <=>
3083        !t. open_in (subtopology euclidean s) t /\
3084            closed_in (subtopology euclidean s) t ==> (t = {}) \/ (t = s)``,
3085  GEN_TAC THEN REWRITE_TAC[connected, OPEN_IN_OPEN, CLOSED_IN_CLOSED] THEN
3086  REWRITE_TAC [METIS [GSYM EXISTS_DIFF] ``!e1. (?e2. open e2) <=>
3087                              ?e2. open (univ(:real) DIFF e2)``] THEN
3088  KNOW_TAC ``(?e1 e2. open e1 /\ open e2 /\ s SUBSET e1 UNION e2 /\
3089        (e1 INTER e2 INTER s = {}) /\ e1 INTER s <> {} /\
3090        e2 INTER s <> {}) <=>
3091             (?e1 e2. open e1 /\ open (univ(:real) DIFF e2) /\
3092                    s SUBSET e1 UNION (univ(:real) DIFF e2) /\
3093        (e1 INTER (univ(:real) DIFF e2) INTER s = {}) /\ e1 INTER s <> {} /\
3094        (univ(:real) DIFF e2) INTER s <> {})`` THENL
3095  [EQ_TAC THENL [STRIP_TAC THEN EXISTS_TAC ``e1:real->bool`` THEN
3096   ASM_SIMP_TAC std_ss [EXISTS_DIFF] THEN METIS_TAC [],
3097   METIS_TAC [GSYM EXISTS_DIFF]], ALL_TAC] THEN DISC_RW_KILL THEN
3098  ONCE_REWRITE_TAC[TAUT `(~a <=> b) <=> (a <=> ~b)`] THEN
3099  SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, GSYM CONJ_ASSOC, DE_MORGAN_THM] THEN
3100  ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> b /\ a /\ c /\ d`] THEN
3101  KNOW_TAC ``(?t. (?t'. closed t' /\ (t = s INTER t')) /\
3102      (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s) <=>
3103             (?t t'. (closed t' /\ (t = s INTER t')) /\
3104      (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s)`` THENL
3105  [SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM], ALL_TAC] THEN DISC_RW_KILL THEN
3106  REWRITE_TAC [GSYM closed_def] THEN
3107  KNOW_TAC ``((?e1 e2. closed e2 /\ open e1 /\ s SUBSET e1 UNION (univ(:real) DIFF e2) /\
3108       (e1 INTER (univ(:real) DIFF e2) INTER s = {}) /\ e1 INTER s <> {} /\
3109       (univ(:real) DIFF e2) INTER s <> {}) <=> ?t t'. (closed t' /\ (t = s INTER t')) /\
3110      (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s) <=>
3111            ((?e2 e1. closed e2 /\ open e1 /\ s SUBSET e1 UNION (univ(:real) DIFF e2) /\
3112       (e1 INTER (univ(:real) DIFF e2) INTER s = {}) /\ e1 INTER s <> {} /\
3113       (univ(:real) DIFF e2) INTER s <> {}) <=> ?t' t. (closed t' /\ (t = s INTER t')) /\
3114      (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s)`` THENL
3115  [METIS_TAC [], ALL_TAC] THEN DISC_RW_KILL THEN AP_TERM_TAC THEN ABS_TAC THEN
3116  KNOW_TAC ``(?t. (closed e2 /\ (t = s INTER e2)) /\
3117      (?t'. open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s) <=>
3118             (?t' t.(closed e2 /\ (t = s INTER e2)) /\
3119      (open t' /\ (t = s INTER t')) /\ t <> {} /\ t <> s)`` THENL
3120  [METIS_TAC [GSYM LEFT_EXISTS_AND_THM, GSYM RIGHT_EXISTS_AND_THM], ALL_TAC] THEN
3121  DISC_RW_KILL THEN AP_TERM_TAC THEN ABS_TAC THEN
3122  REWRITE_TAC[TAUT `(a /\ b) /\ (c /\ d) /\ e <=> a /\ c /\ b /\ d /\ e`] THEN
3123  SIMP_TAC std_ss [RIGHT_EXISTS_AND_THM, UNWIND_THM2] THEN
3124  AP_TERM_TAC THEN AP_TERM_TAC THEN SET_TAC[]);
3125
3126val CONNECTED_CLOSED_SET = store_thm ("CONNECTED_CLOSED_SET",
3127 ``!s:real->bool.
3128        closed s
3129        ==> (connected s <=>
3130             ~(?e1 e2. closed e1 /\ closed e2 /\ ~(e1 = {}) /\ ~(e2 = {}) /\
3131                       (e1 UNION e2 = s) /\ (e1 INTER e2 = {})))``,
3132  REPEAT STRIP_TAC THEN EQ_TAC THENL
3133   [REWRITE_TAC [CONNECTED_CLOSED, GSYM MONO_NOT_EQ] THEN
3134    STRIP_TAC THEN EXISTS_TAC ``e1:real->bool`` THEN
3135    EXISTS_TAC ``e2:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN
3136    REWRITE_TAC [AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN
3137    SIMP_TAC std_ss [] THEN SET_TAC[],
3138    REWRITE_TAC [CONNECTED_CLOSED_IN, GSYM MONO_NOT_EQ] THEN
3139    SIMP_TAC std_ss [PULL_EXISTS] THEN
3140    SIMP_TAC std_ss [CLOSED_IN_CLOSED, LEFT_IMP_EXISTS_THM, GSYM AND_IMP_INTRO] THEN
3141    SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN
3142    REWRITE_TAC[AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN
3143    MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
3144    STRIP_TAC THEN MAP_EVERY EXISTS_TAC
3145     [``s INTER u:real->bool``, ``s INTER v:real->bool``] THEN
3146    ASM_SIMP_TAC std_ss [CLOSED_INTER] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]]);
3147
3148val CONNECTED_OPEN_SET = store_thm ("CONNECTED_OPEN_SET",
3149 ``!s:real->bool.
3150        open s
3151        ==> (connected s <=>
3152             ~(?e1 e2. open e1 /\ open e2 /\ ~(e1 = {}) /\ ~(e2 = {}) /\
3153                       (e1 UNION e2 = s) /\ (e1 INTER e2 = {})))``,
3154  REPEAT STRIP_TAC THEN EQ_TAC THENL
3155   [REWRITE_TAC[connected, GSYM MONO_NOT_EQ] THEN
3156    STRIP_TAC THEN EXISTS_TAC ``e1:real->bool`` THEN
3157    EXISTS_TAC ``e2:real->bool`` THEN REPEAT (POP_ASSUM MP_TAC) THEN
3158    REWRITE_TAC [AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN
3159    SIMP_TAC std_ss [] THEN SET_TAC[],
3160    REWRITE_TAC [CONNECTED_OPEN_IN, GSYM MONO_NOT_EQ] THEN
3161    SIMP_TAC std_ss [PULL_EXISTS] THEN
3162    SIMP_TAC std_ss [OPEN_IN_OPEN, LEFT_IMP_EXISTS_THM, GSYM AND_IMP_INTRO] THEN
3163    SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN
3164    REWRITE_TAC[AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN
3165    MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
3166    STRIP_TAC THEN MAP_EVERY EXISTS_TAC
3167     [``s INTER u:real->bool``, ``s INTER v:real->bool``] THEN
3168    ASM_SIMP_TAC std_ss [OPEN_INTER] THEN REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]]);
3169
3170val CONNECTED_IFF_CONNECTABLE_POINTS = store_thm ("CONNECTED_IFF_CONNECTABLE_POINTS",
3171 ``!s:real->bool.
3172        connected s <=>
3173        !a b. a IN s /\ b IN s
3174              ==> ?t. connected t /\ t SUBSET s /\ a IN t /\ b IN t``,
3175  GEN_TAC THEN EQ_TAC THENL [MESON_TAC[SUBSET_REFL], DISCH_TAC] THEN
3176  SIMP_TAC std_ss [connected, NOT_EXISTS_THM] THEN
3177  MAP_EVERY X_GEN_TAC [``e1:real->bool``, ``e2:real->bool``] THEN
3178  REWRITE_TAC [METIS [DE_MORGAN_THM]
3179                    ``~a \/ ~b \/ ~c \/ (d <> e) \/ (f = g) \/ (h = i) <=>
3180                      ~(a /\ b /\ c /\ (d = e) /\ (f <> g) /\ (h <> i))``] THEN
3181  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3182  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3183  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3184  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3185  REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_INTER] THEN DISCH_THEN(CONJUNCTS_THEN2
3186   (X_CHOOSE_TAC ``a:real``) (X_CHOOSE_TAC ``b:real``)) THEN
3187  FIRST_X_ASSUM(MP_TAC o SPECL [``a:real``, ``b:real``]) THEN
3188  ASM_REWRITE_TAC[connected] THEN
3189  DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN
3190  REWRITE_TAC[] THEN
3191  MAP_EVERY EXISTS_TAC [``e1:real->bool``, ``e2:real->bool``] THEN
3192  ASM_SET_TAC[]);
3193
3194val CONNECTED_EMPTY = store_thm ("CONNECTED_EMPTY",
3195 ``connected {}``,
3196  REWRITE_TAC[connected, INTER_EMPTY]);
3197
3198val CONNECTED_SING = store_thm ("CONNECTED_SING",
3199 ``!a. connected{a}``,
3200  REWRITE_TAC[connected] THEN SET_TAC[]);
3201
3202val CONNECTED_REAL_LEMMA = store_thm ("CONNECTED_REAL_LEMMA",
3203 ``!f:real->real a b e1 e2.
3204        a <= b /\ f(a) IN e1 /\ f(b) IN e2 /\
3205        (!e x. a <= x /\ x <= b /\ &0 < e
3206               ==> ?d. &0 < d /\
3207                       !y. abs(y - x) < d ==> dist(f(y),f(x)) < e) /\
3208        (!y. y IN e1 ==> ?e. &0 < e /\ !y'. dist(y',y) < e ==> y' IN e1) /\
3209        (!y. y IN e2 ==> ?e. &0 < e /\ !y'. dist(y',y) < e ==> y' IN e2) /\
3210        ~(?x. a <= x /\ x <= b /\ f(x) IN e1 /\ f(x) IN e2)
3211        ==> ?x. a <= x /\ x <= b /\ ~(f(x) IN e1) /\ ~(f(x) IN e2)``,
3212  REWRITE_TAC[EXTENSION, NOT_IN_EMPTY] THEN REPEAT STRIP_TAC THEN
3213  MP_TAC(SPEC ``\c. !x:real. a <= x /\ x <= c ==> (f(x):real) IN e1``
3214              REAL_COMPLETE) THEN
3215  SIMP_TAC std_ss [] THEN
3216  KNOW_TAC ``(?x:real. !x'. a <= x' /\ x' <= x ==> (f x'):real IN e1) /\
3217     (?M. !x. (!x'. a <= x' /\ x' <= x ==> f x' IN e1) ==> x <= M)`` THENL
3218  [METIS_TAC[REAL_LT_IMP_LE, REAL_LE_TOTAL, REAL_LE_ANTISYM],
3219   DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
3220  DISCH_THEN (X_CHOOSE_TAC ``x:real``) THEN EXISTS_TAC ``x:real`` THEN
3221  POP_ASSUM MP_TAC THEN STRIP_TAC THEN
3222  SUBGOAL_THEN ``a <= x /\ x <= b:real`` STRIP_ASSUME_TAC THENL
3223  [METIS_TAC[REAL_LT_IMP_LE, REAL_LE_TOTAL, REAL_LE_ANTISYM], ALL_TAC] THEN
3224  ASM_REWRITE_TAC[] THEN
3225  SUBGOAL_THEN ``!z:real. a <= z /\ z < x ==> (f(z):real) IN e1`` ASSUME_TAC THENL
3226   [METIS_TAC[REAL_NOT_LT, REAL_LT_IMP_LE], ALL_TAC] THEN
3227  REPEAT STRIP_TAC THENL
3228   [SUBGOAL_THEN
3229     ``?d:real. &0 < d /\ !y. abs(y - x) < d ==> (f(y):real) IN e1``
3230    STRIP_ASSUME_TAC THENL [METIS_TAC[], ALL_TAC] THEN
3231    METIS_TAC[REAL_ARITH ``z <= x + e /\ e < d ==> z < x \/ abs(z - x) < d:real``,
3232                  REAL_ARITH ``&0 < e ==> ~(x + e <= x:real)``, REAL_DOWN],
3233    SUBGOAL_THEN
3234     ``?d:real. &0 < d /\ !y. abs(y - x) < d ==> (f(y):real) IN e2``
3235    STRIP_ASSUME_TAC THENL [METIS_TAC[], ALL_TAC] THEN
3236    MP_TAC(SPECL [``x - a:real``, ``d:real``] REAL_DOWN2) THEN
3237    KNOW_TAC ``0 < x - a:real /\ 0 < d:real`` THENL
3238     [METIS_TAC[REAL_LT_LE, REAL_SUB_LT], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
3239    METIS_TAC[REAL_ARITH ``e < x - a ==> a <= x - e:real``,
3240                  REAL_ARITH ``&0 < e /\ x <= b ==> x - e <= b:real``,
3241      REAL_ARITH ``&0 < e /\ e < d ==> x - e < x /\ abs((x - e) - x) < d:real``]]);
3242
3243val CONNECTED_SEGMENT = store_thm ("CONNECTED_SEGMENT",
3244 ``(!a b:real. connected(segment[a,b])) /\
3245   (!a b:real. connected(segment(a,b)))``,
3246  CONJ_TAC THEN REPEAT GEN_TAC THENL
3247 [ASM_CASES_TAC ``b:real = a`` THEN
3248  ASM_SIMP_TAC std_ss [SEGMENT_REFL, CONNECTED_EMPTY, CONNECTED_SING] THEN
3249  ASM_SIMP_TAC std_ss [connected, OPEN_SEGMENT_ALT, CONJUNCT1 segment,
3250               NOT_EXISTS_THM] THEN
3251  REWRITE_TAC [METIS [DE_MORGAN_THM]
3252   ``~a \/ ~b \/ ~c \/ (d <> e) \/ (f = g) \/ (h = i) <=>
3253     ~(a /\ b /\ c /\ (d = e) /\ (f <> g) /\ (h <> i))`` ] THEN
3254  MAP_EVERY X_GEN_TAC [``e1:real->bool``, ``e2:real->bool``] THEN
3255  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
3256  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
3257  PURE_ONCE_REWRITE_TAC[INTER_COMM] THEN
3258  PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REWRITE_TAC [IN_INTER] THEN
3259  DISCH_TAC THEN DISCH_TAC THEN
3260  POP_ASSUM (MP_TAC o SIMP_RULE std_ss [EXISTS_IN_GSPEC]) THEN
3261  POP_ASSUM (MP_TAC o SIMP_RULE std_ss [EXISTS_IN_GSPEC]) THEN
3262  REWRITE_TAC [GSYM CONJ_ASSOC] THEN
3263  SIMP_TAC std_ss [NOT_EXISTS_THM, LEFT_IMP_EXISTS_THM] THEN
3264  SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN
3265  MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN
3266  POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
3267  MAP_EVERY (fn t => SPEC_TAC(t,t))
3268   [``e2:real->bool``, ``e1:real->bool``, ``v:real``, ``u:real``] THEN
3269  KNOW_TAC ``!(u :real) (v :real). (\u v. !(e1 :real -> bool) (e2 :real -> bool).
3270      (e1 INTER e2 INTER
3271       {((1 :real) - u) * (a :real) + u * (b :real) |
3272        (0 :real) <= u /\ u <= (1 :real)} =
3273       ({} :real -> bool)) /\
3274      {((1 :real) - u) * a + u * b |
3275       (0 :real) <= u /\ u <= (1 :real)} SUBSET e1 UNION e2 /\
3276      (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==>
3277      (0 :real) <= u /\ u <= (1 :real) /\
3278      ((1 :real) - u) * a + u * b IN e1 ==>
3279      ~((0 :real) <= v) \/ ~(v <= (1 :real)) \/
3280      ((1 :real) - v) * a + v * b NOTIN e2) u v`` THENL
3281  [ALL_TAC, METIS_TAC []] THEN
3282  MATCH_MP_TAC REAL_WLOG_LE THEN CONJ_TAC THENL
3283   [MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN BETA_TAC THEN
3284    GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV)
3285        [UNION_COMM, INTER_COMM] THEN
3286   KNOW_TAC ``(!(e1 :real -> bool) (e2 :real -> bool).
3287       (e1 INTER e2 INTER
3288        {((1 :real) - u) * (a :real) + u * (b :real) |
3289         (0 :real) <= u /\ u <= (1 :real)} =
3290        ({} :real -> bool)) /\
3291       {((1 :real) - u) * a + u * b |
3292        (0 :real) <= u /\ u <= (1 :real)} SUBSET e1 UNION e2 /\
3293       (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==>
3294       (0 :real) <= (u :real) /\ u <= (1 :real) /\
3295       ((1 :real) - u) * a + u * b IN e1 ==>
3296       ~((0 :real) <= (v :real)) \/ ~(v <= (1 :real)) \/
3297       ((1 :real) - v) * a + v * b NOTIN e2) <=>
3298    !(e2 :real -> bool) (e1 :real -> bool).
3299      ({((1 :real) - u) * a + u * b |
3300        (0 :real) <= u /\ u <= (1 :real)} INTER (e1 INTER e2) =
3301       ({} :real -> bool)) /\
3302      {((1 :real) - u) * a + u * b |
3303       (0 :real) <= u /\ u <= (1 :real)} SUBSET e2 UNION e1 /\
3304      (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==>
3305      (0 :real) <= v /\ v <= (1 :real) /\
3306      ((1 :real) - v) * a + v * b IN e1 ==>
3307      ~((0 :real) <= u) \/ ~(u <= (1 :real)) \/
3308      ((1 :real) - u) * a + u * b NOTIN e2`` THENL
3309        [ALL_TAC, METIS_TAC [SWAP_FORALL_THM]] THEN
3310    REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
3311    SIMP_TAC std_ss [UNION_ACI, INTER_ACI] THEN METIS_TAC[],
3312    ALL_TAC] THEN
3313  MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN
3314  SIMP_TAC std_ss [] THEN
3315  REPEAT STRIP_TAC THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
3316  MP_TAC(ISPECL
3317   [``\u. (&1 - u) * a + u * b:real``, ``u:real``, ``v:real``,
3318    ``e1:real->bool``, ``e2:real->bool``]
3319    CONNECTED_REAL_LEMMA) THEN BETA_TAC THEN
3320  ASM_REWRITE_TAC [GSYM open_def, REAL_POS, NOT_IMP] THEN
3321  REWRITE_TAC[GSYM CONJ_ASSOC] THEN CONJ_TAC THENL
3322   [MAP_EVERY X_GEN_TAC [``e:real``, ``x:real``] THEN STRIP_TAC THEN
3323    EXISTS_TAC ``e / dist(a:real,b)`` THEN
3324    ASM_SIMP_TAC std_ss [REAL_LT_DIV, GSYM DIST_NZ] THEN
3325    GEN_TAC THEN REWRITE_TAC[dist] THEN STRIP_TAC THEN
3326    ASM_SIMP_TAC std_ss [ABS_MUL, GSYM REAL_LT_RDIV_EQ, GSYM ABS_NZ, REAL_SUB_0,
3327                 ABS_NEG, REAL_ARITH
3328     ``((&1 - y') * a + y' * b) - ((&1 - x') * a + x' * b):real =
3329       -((y' - x') * (a - b))``],
3330    RULE_ASSUM_TAC(SIMP_RULE std_ss [EXTENSION, IN_INTER, GSPECIFICATION,
3331                                SUBSET_DEF, IN_UNION, NOT_IN_EMPTY]) THEN
3332    METIS_TAC[REAL_LE_TRANS, REAL_LET_TRANS, REAL_LTE_TRANS]], ALL_TAC] THEN
3333  ASM_CASES_TAC ``b:real = a`` THEN
3334  ASM_SIMP_TAC std_ss [SEGMENT_REFL, CONNECTED_EMPTY, CONNECTED_SING] THEN
3335  ASM_SIMP_TAC std_ss [connected, OPEN_SEGMENT_ALT, CONJUNCT1 segment,
3336               NOT_EXISTS_THM] THEN
3337  REWRITE_TAC [METIS [DE_MORGAN_THM]
3338   ``~a \/ ~b \/ ~c \/ (d <> e) \/ (f = g) \/ (h = i) <=>
3339     ~(a /\ b /\ c /\ (d = e) /\ (f <> g) /\ (h <> i))`` ] THEN
3340  MAP_EVERY X_GEN_TAC [``e1:real->bool``, ``e2:real->bool``] THEN
3341  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
3342  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
3343  PURE_ONCE_REWRITE_TAC[INTER_COMM] THEN
3344  PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REWRITE_TAC [IN_INTER] THEN
3345  DISCH_TAC THEN DISCH_TAC THEN
3346  POP_ASSUM (MP_TAC o SIMP_RULE std_ss [EXISTS_IN_GSPEC]) THEN
3347  POP_ASSUM (MP_TAC o SIMP_RULE std_ss [EXISTS_IN_GSPEC]) THEN
3348  REWRITE_TAC [GSYM CONJ_ASSOC] THEN
3349  SIMP_TAC std_ss [NOT_EXISTS_THM, LEFT_IMP_EXISTS_THM] THEN
3350  SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN
3351  MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN
3352  POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
3353  MAP_EVERY (fn t => SPEC_TAC(t,t))
3354   [``e2:real->bool``, ``e1:real->bool``, ``v:real``, ``u:real``] THEN
3355  KNOW_TAC ``!(u :real) (v :real). (\u v. !(e1 :real -> bool) (e2 :real -> bool).
3356      (e1 INTER e2 INTER
3357       {((1 :real) - u) * (a :real) + u * (b :real) |
3358        (0 :real) < u /\ u < (1 :real)} =
3359       ({} :real -> bool)) /\
3360      {((1 :real) - u) * a + u * b | (0 :real) < u /\ u < (1 :real)} SUBSET
3361      e1 UNION e2 /\ (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==>
3362      (0 :real) < u /\ u < (1 :real) /\
3363      ((1 :real) - u) * a + u * b IN e1 ==>
3364      ~((0 :real) < v) \/ ~(v < (1 :real)) \/
3365      ((1 :real) - v) * a + v * b NOTIN e2) u v`` THENL
3366  [ALL_TAC, METIS_TAC []] THEN
3367  MATCH_MP_TAC REAL_WLOG_LE THEN CONJ_TAC THENL
3368   [MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN BETA_TAC THEN
3369    GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV)
3370        [UNION_COMM, INTER_COMM] THEN
3371   KNOW_TAC `` (!(e1 :real -> bool) (e2 :real -> bool).
3372       (e1 INTER e2 INTER
3373        {((1 :real) - u) * (a :real) + u * (b :real) |
3374         (0 :real) < u /\ u < (1 :real)} =
3375        ({} :real -> bool)) /\
3376       {((1 :real) - u) * a + u * b | (0 :real) < u /\ u < (1 :real)} SUBSET
3377       e1 UNION e2 /\ (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==>
3378       (0 :real) < (u :real) /\ u < (1 :real) /\
3379       ((1 :real) - u) * a + u * b IN e1 ==>
3380       ~((0 :real) < (v :real)) \/ ~(v < (1 :real)) \/
3381       ((1 :real) - v) * a + v * b NOTIN e2) <=>
3382    !(e2 :real -> bool) (e1 :real -> bool).
3383      ({((1 :real) - u) * a + u * b | (0 :real) < u /\ u < (1 :real)} INTER
3384       (e1 INTER e2) =
3385       ({} :real -> bool)) /\
3386      {((1 :real) - u) * a + u * b | (0 :real) < u /\ u < (1 :real)} SUBSET
3387      e2 UNION e1 /\ (open e2 :bool) /\ (open e1 :bool) /\ b <> a ==>
3388      (0 :real) < v /\ v < (1 :real) /\
3389      ((1 :real) - v) * a + v * b IN e1 ==>
3390      ~((0 :real) < u) \/ ~(u < (1 :real)) \/
3391      ((1 :real) - u) * a + u * b NOTIN e2`` THENL
3392        [ALL_TAC, METIS_TAC [SWAP_FORALL_THM]] THEN
3393    REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
3394    SIMP_TAC std_ss [UNION_ACI, INTER_ACI] THEN METIS_TAC[],
3395    ALL_TAC] THEN
3396  MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN
3397  SIMP_TAC std_ss [] THEN
3398  REPEAT STRIP_TAC THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
3399  MP_TAC(ISPECL
3400   [``\u. (&1 - u) * a + u * b:real``, ``u:real``, ``v:real``,
3401    ``e1:real->bool``, ``e2:real->bool``]
3402    CONNECTED_REAL_LEMMA) THEN BETA_TAC THEN
3403  ASM_REWRITE_TAC [GSYM open_def, REAL_POS, NOT_IMP] THEN
3404  REWRITE_TAC[GSYM CONJ_ASSOC] THEN CONJ_TAC THENL
3405   [MAP_EVERY X_GEN_TAC [``e:real``, ``x:real``] THEN STRIP_TAC THEN
3406    EXISTS_TAC ``e / dist(a:real,b)`` THEN
3407    ASM_SIMP_TAC std_ss [REAL_LT_DIV, GSYM DIST_NZ] THEN
3408    GEN_TAC THEN REWRITE_TAC[dist] THEN STRIP_TAC THEN
3409    ASM_SIMP_TAC std_ss [ABS_MUL, GSYM REAL_LT_RDIV_EQ, GSYM ABS_NZ, REAL_SUB_0,
3410                 ABS_NEG, REAL_ARITH
3411     ``((&1 - y') * a + y' * b) - ((&1 - x') * a + x' * b):real =
3412       -((y' - x') * (a - b))``],
3413    RULE_ASSUM_TAC(SIMP_RULE std_ss [EXTENSION, IN_INTER, GSPECIFICATION,
3414                                SUBSET_DEF, IN_UNION, NOT_IN_EMPTY]) THEN
3415    METIS_TAC[REAL_LE_TRANS, REAL_LET_TRANS, REAL_LTE_TRANS]]);
3416
3417val CONNECTED_UNIV = store_thm ("CONNECTED_UNIV",
3418 ``connected univ(:real)``,
3419  ONCE_REWRITE_TAC[CONNECTED_IFF_CONNECTABLE_POINTS] THEN
3420  MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``] THEN
3421  REWRITE_TAC[IN_UNIV, SUBSET_UNIV] THEN
3422  EXISTS_TAC ``segment[a:real,b]`` THEN
3423  ASM_SIMP_TAC std_ss [CONNECTED_SEGMENT, ENDS_IN_SEGMENT]);
3424
3425val CLOPEN = store_thm ("CLOPEN",
3426 ``!s. closed s /\ open s <=> (s = {}) \/ (s = univ(:real))``,
3427  GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN
3428  ASM_REWRITE_TAC[CLOSED_EMPTY, OPEN_EMPTY, CLOSED_UNIV, OPEN_UNIV] THEN
3429  MATCH_MP_TAC(REWRITE_RULE[CONNECTED_CLOPEN] CONNECTED_UNIV) THEN
3430  ASM_REWRITE_TAC[SUBTOPOLOGY_UNIV, GSYM OPEN_IN, GSYM CLOSED_IN]);
3431
3432val CONNECTED_BIGUNION = store_thm ("CONNECTED_BIGUNION",
3433 ``!P:(real->bool)->bool.
3434        (!s. s IN P ==> connected s) /\ ~(BIGINTER P = {})
3435        ==> connected(BIGUNION P)``,
3436  GEN_TAC THEN REWRITE_TAC[connected] THEN STRIP_TAC THEN
3437  CCONTR_TAC THEN POP_ASSUM (MP_TAC o REWRITE_RULE [REAL_NEG_NEG]) THEN
3438  STRIP_TAC THEN UNDISCH_TAC ``~(BIGINTER P :real->bool = {})`` THEN
3439  PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_BIGINTER] THEN
3440  DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN
3441  SUBGOAL_THEN ``(a:real) IN e1 \/ a IN e2`` STRIP_ASSUME_TAC THENL
3442   [ASM_SET_TAC[],
3443    UNDISCH_TAC ``~(e2 INTER BIGUNION P:real->bool = {})``,
3444    UNDISCH_TAC ``~(e1 INTER BIGUNION P:real->bool = {})``] THEN
3445  PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_INTER, IN_BIGUNION] THEN
3446  DISCH_THEN(X_CHOOSE_THEN ``b:real``
3447   (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
3448  DISCH_THEN(X_CHOOSE_THEN ``s:real->bool`` STRIP_ASSUME_TAC) THEN
3449  UNDISCH_TAC ``!t:real->bool. t IN P ==> a IN t`` THEN
3450  DISCH_THEN(MP_TAC o SPEC ``s:real->bool``) THEN
3451  ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
3452  FIRST_X_ASSUM(MP_TAC o SPEC ``s:real->bool``) THEN
3453  ASM_REWRITE_TAC[] THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
3454  POP_ASSUM (MP_TAC o SPECL [``e1:real->bool``, ``e2:real->bool``]) THEN
3455  ASM_SET_TAC[]);
3456
3457val CONNECTED_UNION = store_thm ("CONNECTED_UNION",
3458 ``!s t:real->bool.
3459        connected s /\ connected t /\ ~(s INTER t = {})
3460        ==> connected (s UNION t)``,
3461  REWRITE_TAC[GSYM BIGUNION_2, GSYM BIGINTER_2] THEN
3462  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_BIGUNION THEN
3463  ASM_SET_TAC[]);
3464
3465val CONNECTED_DIFF_OPEN_FROM_CLOSED = store_thm ("CONNECTED_DIFF_OPEN_FROM_CLOSED",
3466 ``!s t u:real->bool.
3467        s SUBSET t /\ t SUBSET u /\
3468        open s /\ closed t /\ connected u /\ connected(t DIFF s)
3469        ==> connected(u DIFF s)``,
3470  REPEAT STRIP_TAC THEN SIMP_TAC std_ss [connected, NOT_EXISTS_THM] THEN
3471  MAP_EVERY X_GEN_TAC [``v:real->bool``, ``w:real->bool``] THEN
3472  CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
3473  UNDISCH_TAC ``connected(t DIFF s:real->bool)`` THEN SIMP_TAC std_ss [connected] THEN
3474  MAP_EVERY EXISTS_TAC [``v:real->bool``, ``w:real->bool``] THEN
3475  ASM_REWRITE_TAC[] THEN CONJ_TAC  THENL [ASM_SET_TAC [], ALL_TAC] THEN
3476  CONJ_TAC THENL [ASM_SET_TAC [], ALL_TAC] THEN
3477  POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
3478  MAP_EVERY (fn t => SPEC_TAC(t,t)) [``v:real->bool``, ``w:real->bool``] THEN
3479  KNOW_TAC ``(!v:real->bool w:real->bool.
3480      ~(w INTER (u DIFF s) = {}) /\ ~(v INTER (u DIFF s) = {}) /\
3481      (v INTER w INTER (u DIFF s) = {}) /\ u DIFF s SUBSET v UNION w /\
3482      open w /\ open v /\ connected u /\ closed t /\ open s /\
3483      t SUBSET u /\ s SUBSET t
3484      ==> ~(v INTER (u DIFF s) = {}) /\ ~(w INTER (u DIFF s) = {}) /\
3485          (w INTER v INTER (u DIFF s) = {}) /\ u DIFF s SUBSET w UNION v /\
3486          open v /\ open w /\ connected u /\ closed t /\ open s /\
3487          t SUBSET u /\ s SUBSET t) /\
3488 (!w v. (~(w INTER (u DIFF s) = {}) /\ ~(v INTER (u DIFF s) = {}) /\
3489       (v INTER w INTER (u DIFF s) = {}) /\ u DIFF s SUBSET v UNION w /\
3490       open w /\ open v /\ connected u /\ closed t /\ open s /\
3491       t SUBSET u /\ s SUBSET t) /\ (w INTER (t DIFF s) = {})
3492      ==> F)`` THENL
3493  [CONJ_TAC THENL [SIMP_TAC std_ss [CONJ_ACI, INTER_ACI, UNION_ACI], ALL_TAC] THEN
3494  REPEAT STRIP_TAC THEN UNDISCH_TAC ``connected u`` THEN
3495  GEN_REWR_TAC LAND_CONV [connected] THEN SIMP_TAC std_ss [] THEN
3496  MAP_EVERY EXISTS_TAC [``v UNION s:real->bool``, ``w DIFF t:real->bool``] THEN
3497  ASM_SIMP_TAC std_ss [OPEN_UNION, OPEN_DIFF] THEN ASM_SET_TAC[], METIS_TAC []]);
3498
3499val CONNECTED_DISJOINT_BIGUNION_OPEN_UNIQUE = store_thm
3500  ("CONNECTED_DISJOINT_BIGUNION_OPEN_UNIQUE",
3501 ``!f:(real->bool)->bool f'.
3502         pairwise DISJOINT f /\ pairwise DISJOINT f' /\
3503        (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\
3504        (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\
3505        (BIGUNION f = BIGUNION f')
3506        ==> (f = f')``,
3507  GEN_REWR_TAC (funpow 2 BINDER_CONV o RAND_CONV) [EXTENSION] THEN
3508  KNOW_TAC ``(!f f'.
3509      pairwise DISJOINT f /\ pairwise DISJOINT f' /\
3510      (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\
3511      (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\
3512      (BIGUNION f = BIGUNION f')
3513      ==> pairwise DISJOINT f' /\ pairwise DISJOINT f /\
3514          (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\
3515          (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\
3516          (BIGUNION f' = BIGUNION f)) /\
3517 (!f f' x. (pairwise DISJOINT f /\ pairwise DISJOINT f' /\
3518       (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\
3519       (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\
3520       (BIGUNION f = BIGUNION f')) /\ x IN f ==> x IN f')`` THENL
3521  [ALL_TAC, METIS_TAC []] THEN
3522  CONJ_TAC THENL [MESON_TAC[], ALL_TAC] THEN
3523  GEN_TAC THEN GEN_TAC THEN X_GEN_TAC ``s:real->bool`` THEN STRIP_TAC THEN
3524  SUBGOAL_THEN
3525   ``?t a:real. t IN f' /\ a IN s /\ a IN t`` STRIP_ASSUME_TAC
3526  THENL [ASM_SET_TAC[], ALL_TAC] THEN
3527  SUBGOAL_THEN ``s:real->bool = t`` (fn th => ASM_REWRITE_TAC[th]) THEN
3528  REWRITE_TAC[EXTENSION] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
3529  MAP_EVERY (fn t => SPEC_TAC(t,t))
3530   [``s:real->bool``, ``t:real->bool``,
3531    ``f:(real->bool)->bool``, ``f':(real->bool)->bool``] THEN
3532  KNOW_TAC ``(!f f' s t.
3533      a IN t /\ a IN s /\ t IN f' /\ s IN f /\
3534      (BIGUNION f = BIGUNION f') /\
3535      (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\
3536      (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\
3537      pairwise DISJOINT f' /\ pairwise DISJOINT f
3538      ==> a IN s /\ a IN t /\ s IN f /\ t IN f' /\
3539          (BIGUNION f' = BIGUNION f) /\
3540          (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\
3541          (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\
3542          pairwise DISJOINT f /\ pairwise DISJOINT f') /\
3543 (!f f' s t x.
3544      (a IN t /\ a IN s /\ t IN f' /\ s IN f /\
3545       (BIGUNION f = BIGUNION f') /\
3546       (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\
3547       (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\
3548       pairwise DISJOINT f' /\ pairwise DISJOINT f) /\
3549      x IN s ==> x IN t)`` THENL
3550  [ALL_TAC, METIS_TAC []] THEN
3551  CONJ_TAC THENL [MESON_TAC[], ALL_TAC] THEN
3552  GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN
3553  X_GEN_TAC ``b:real`` THEN STRIP_TAC THEN
3554  UNDISCH_TAC
3555   ``!s:real->bool. s IN f ==> open s /\ connected s /\ ~(s = {})`` THEN
3556  DISCH_THEN(MP_TAC o SPEC ``s:real->bool``) THEN ASM_REWRITE_TAC[] THEN
3557  STRIP_TAC THEN ASM_CASES_TAC ``(b:real) IN t`` THEN
3558  ASM_REWRITE_TAC[] THEN
3559  UNDISCH_TAC ``connected(s:real->bool)`` THEN
3560  REWRITE_TAC[connected] THEN
3561  MAP_EVERY EXISTS_TAC
3562   [``t:real->bool``, ``BIGUNION(f' DELETE (t:real->bool))``] THEN
3563  REPEAT STRIP_TAC THENL
3564   [ASM_SIMP_TAC std_ss [],
3565    MATCH_MP_TAC OPEN_BIGUNION THEN ASM_SIMP_TAC std_ss [IN_DELETE],
3566    REWRITE_TAC[GSYM BIGUNION_INSERT] THEN ASM_SET_TAC[],
3567    MATCH_MP_TAC(SET_RULE ``(t INTER u = {}) ==> (t INTER u INTER s = {})``) THEN
3568    SIMP_TAC std_ss [INTER_BIGUNION, EMPTY_BIGUNION, FORALL_IN_GSPEC] THEN
3569    REWRITE_TAC [IN_DELETE, GSYM DISJOINT_DEF] THEN ASM_MESON_TAC[pairwise],
3570    ASM_SET_TAC[], ASM_SET_TAC[]]);
3571
3572val CONNECTED_FROM_CLOSED_UNION_AND_INTER = store_thm ("CONNECTED_FROM_CLOSED_UNION_AND_INTER",
3573 ``!s t:real->bool.
3574        closed s /\ closed t /\ connected(s UNION t) /\ connected(s INTER t)
3575        ==> connected s /\ connected t``,
3576  KNOW_TAC ``(!s t. closed s /\ closed t /\
3577       connected (s UNION t) /\ connected (s INTER t)
3578      ==> closed t /\ closed s /\ connected (t UNION s) /\
3579          connected (t INTER s)) /\
3580 (!s t. closed s /\ closed t /\ connected (s UNION t) /\
3581        connected (s INTER t) ==> connected s)`` THENL
3582  [ALL_TAC, MESON_TAC []] THEN
3583  CONJ_TAC THENL [SIMP_TAC std_ss [UNION_COMM, INTER_COMM], REPEAT STRIP_TAC] THEN
3584  ASM_SIMP_TAC std_ss [CONNECTED_CLOSED_SET] THEN
3585  MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
3586  CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
3587  ASM_CASES_TAC
3588   ``~(s INTER t SUBSET (u:real->bool)) /\ ~(s INTER t SUBSET v)``
3589  THENL
3590   [UNDISCH_TAC ``connected(s INTER t:real->bool)`` THEN
3591    ASM_SIMP_TAC std_ss [CONNECTED_CLOSED] THEN
3592    MAP_EVERY EXISTS_TAC [``u:real->bool``, ``v:real->bool``] THEN
3593    ASM_REWRITE_TAC[] THEN ASM_SET_TAC [],
3594    POP_ASSUM (MP_TAC o REWRITE_RULE [DE_MORGAN_THM]) THEN
3595    STRIP_TAC THEN UNDISCH_TAC ``connected(s UNION t:real->bool)`` THEN
3596    ASM_SIMP_TAC std_ss [CONNECTED_CLOSED] THENL
3597     [MAP_EVERY EXISTS_TAC [``t UNION u:real->bool``, ``v:real->bool``] THEN
3598      ASM_SIMP_TAC std_ss [CLOSED_UNION] THEN ASM_SET_TAC[],
3599      MAP_EVERY EXISTS_TAC [``t UNION v:real->bool``, ``u:real->bool``] THEN
3600      ASM_SIMP_TAC std_ss [CLOSED_UNION] THEN ASM_SET_TAC[]]]);
3601
3602val CONNECTED_FROM_OPEN_UNION_AND_INTER = store_thm ("CONNECTED_FROM_OPEN_UNION_AND_INTER",
3603 ``!s t:real->bool.
3604        open s /\ open t /\ connected(s UNION t) /\ connected(s INTER t)
3605        ==> connected s /\ connected t``,
3606
3607  KNOW_TAC ``(!s t.
3608      open s /\ open t /\ connected (s UNION t) /\ connected (s INTER t)
3609      ==> open t /\ open s /\ connected (t UNION s) /\ connected (t INTER s)) /\
3610 (!s t.
3611      open s /\ open t /\ connected (s UNION t) /\ connected (s INTER t)
3612      ==> connected s)`` THENL
3613  [ALL_TAC, MESON_TAC []] THEN
3614  CONJ_TAC THENL [SIMP_TAC std_ss [UNION_COMM, INTER_COMM], REPEAT STRIP_TAC] THEN
3615  ASM_SIMP_TAC std_ss [CONNECTED_OPEN_SET] THEN
3616  MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
3617  CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN ASM_CASES_TAC
3618   ``~(s INTER t SUBSET (u:real->bool)) /\ ~(s INTER t SUBSET v)``
3619  THENL
3620   [UNDISCH_TAC ``connected(s INTER t:real->bool)`` THEN
3621    ASM_SIMP_TAC std_ss [connected] THEN
3622    MAP_EVERY EXISTS_TAC [``u:real->bool``, ``v:real->bool``] THEN
3623    ASM_REWRITE_TAC[] THEN ASM_SET_TAC[],
3624    POP_ASSUM (MP_TAC o REWRITE_RULE [DE_MORGAN_THM]) THEN
3625    STRIP_TAC THEN UNDISCH_TAC ``connected(s UNION t:real->bool)`` THEN
3626    ASM_SIMP_TAC std_ss [connected] THENL
3627     [MAP_EVERY EXISTS_TAC [``t UNION u:real->bool``, ``v:real->bool``] THEN
3628      ASM_SIMP_TAC std_ss [OPEN_UNION] THEN ASM_SET_TAC[],
3629      MAP_EVERY EXISTS_TAC [``t UNION v:real->bool``, ``u:real->bool``] THEN
3630      ASM_SIMP_TAC std_ss [OPEN_UNION] THEN ASM_SET_TAC[]]]);
3631
3632(* ------------------------------------------------------------------------- *)
3633(* Sort of induction principle for connected sets.                           *)
3634(* ------------------------------------------------------------------------- *)
3635
3636val CONNECTED_INDUCTION = store_thm ("CONNECTED_INDUCTION",
3637 ``!P Q s:real->bool. connected s /\
3638     (!t a. open_in (subtopology euclidean s) t /\ a IN t
3639     ==> ?z. z IN t /\ P z) /\ (!a. a IN s
3640       ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
3641       !x y. x IN t /\ y IN t /\ P x /\ P y /\ Q x ==> Q y)
3642          ==> !a b. a IN s /\ b IN s /\ P a /\ P b /\ Q a ==> Q b``,
3643  REPEAT STRIP_TAC THEN
3644  GEN_REWR_TAC I [TAUT `p <=> ~ ~p`] THEN DISCH_TAC THEN
3645  UNDISCH_TAC ``connected s`` THEN GEN_REWR_TAC LAND_CONV [CONNECTED_OPEN_IN] THEN
3646  REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC
3647  [``{b:real | ?t. open_in (subtopology euclidean s) t /\
3648                   b IN t /\ !x. x IN t /\ P x ==> Q x}``,
3649   ``{b:real | ?t. open_in (subtopology euclidean s) t /\
3650                 b IN t /\ !x. x IN t /\ P x ==> ~(Q x)}``]   THEN
3651  REPEAT CONJ_TAC THENL
3652  [ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN
3653   X_GEN_TAC ``c:real`` THEN SIMP_TAC std_ss [GSPECIFICATION] THEN
3654   ASM_SET_TAC[],
3655   ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN
3656   X_GEN_TAC ``c:real`` THEN SIMP_TAC std_ss [GSPECIFICATION] THEN
3657   ASM_SET_TAC[],
3658   SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_UNION] THEN
3659   X_GEN_TAC ``c:real`` THEN DISCH_TAC THEN
3660   FIRST_X_ASSUM(MP_TAC o SPEC ``c:real``) THEN ASM_SET_TAC[],
3661   KNOW_TAC ``!x. ~((?t. open_in (subtopology euclidean s) t /\
3662            x IN t /\ (!x. x IN t /\ P x ==> Q x)) /\
3663       (?t. open_in (subtopology euclidean s) t /\ x IN t /\
3664            (!x. x IN t /\ P x ==> ~Q x)))`` THENL
3665   [ALL_TAC, SIMP_TAC std_ss [EXTENSION, IN_INTER, NOT_IN_EMPTY, GSPECIFICATION]] THEN
3666   X_GEN_TAC ``c:real`` THEN DISCH_THEN(CONJUNCTS_THEN2
3667   (X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC)
3668   (X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC)) THEN
3669   FIRST_X_ASSUM(MP_TAC o SPECL [``t INTER u:real->bool``, ``c:real``]) THEN
3670   ASM_SIMP_TAC std_ss [OPEN_IN_INTER] THEN ASM_SET_TAC[],
3671   ASM_SET_TAC[], ASM_SET_TAC[]]);
3672
3673val CONNECTED_EQUIVALENCE_RELATION_GEN = store_thm ("CONNECTED_EQUIVALENCE_RELATION_GEN",
3674 ``!P R s:real->bool. connected s /\ (!x y. R x y ==> R y x) /\
3675     (!x y z. R x y /\ R y z ==> R x z) /\
3676     (!t a. open_in (subtopology euclidean s) t /\ a IN t
3677    ==> ?z. z IN t /\ P z) /\ (!a. a IN s
3678      ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
3679      !x y. x IN t /\ y IN t /\ P x /\ P y ==> R x y)
3680        ==> !a b. a IN s /\ b IN s /\ P a /\ P b ==> R a b``,
3681  REPEAT GEN_TAC THEN STRIP_TAC THEN
3682  SUBGOAL_THEN
3683  ``!a:real. a IN s /\ P a
3684  ==> !b c. b IN s /\ c IN s /\ P b /\ P c /\ R a b ==> R a c``
3685  MP_TAC THENL [ALL_TAC, ASM_MESON_TAC[]] THEN
3686  GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONNECTED_INDUCTION THEN
3687  ASM_REWRITE_TAC [] THEN
3688  X_GEN_TAC ``b:real`` THEN POP_ASSUM MP_TAC THEN
3689  POP_ASSUM (MP_TAC o Q.SPEC `b:real`) THEN
3690  METIS_TAC[]);
3691
3692val CONNECTED_INDUCTION_SIMPLE = store_thm ("CONNECTED_INDUCTION_SIMPLE",
3693 ``!P s:real->bool. connected s /\
3694    (!a. a IN s
3695    ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
3696      !x y. x IN t /\ y IN t /\ P x ==> P y)
3697      ==> !a b. a IN s /\ b IN s /\ P a ==> P b``,
3698  MP_TAC(ISPEC ``\x:real. T`` CONNECTED_INDUCTION) THEN
3699  REWRITE_TAC[] THEN STRIP_TAC THEN
3700  MAP_EVERY X_GEN_TAC [``Q:real->bool``, ``s:real->bool``] THEN
3701  POP_ASSUM (MP_TAC o Q.SPECL [`Q:real->bool`, `s:real->bool`]) THEN
3702  METIS_TAC[]);
3703
3704val CONNECTED_EQUIVALENCE_RELATION = store_thm ("CONNECTED_EQUIVALENCE_RELATION",
3705 ``!R s:real->bool. connected s /\
3706     (!x y. R x y ==> R y x) /\
3707     (!x y z. R x y /\ R y z ==> R x z) /\
3708     (!a. a IN s
3709     ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
3710      !x. x IN t ==> R a x)
3711      ==> !a b. a IN s /\ b IN s ==> R a b``,
3712  REPEAT GEN_TAC THEN STRIP_TAC THEN
3713  SUBGOAL_THEN
3714  ``!a:real. a IN s ==> !b c. b IN s /\ c IN s /\ R a b ==> R a c``
3715  MP_TAC THENL [ALL_TAC, ASM_MESON_TAC[]] THEN
3716  GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONNECTED_INDUCTION_SIMPLE THEN
3717  ASM_MESON_TAC[]);
3718
3719(* ------------------------------------------------------------------------- *)
3720(* Limit points.                                                             *)
3721(* ------------------------------------------------------------------------- *)
3722
3723val _ = set_fixity "limit_point_of" (Infix(NONASSOC, 450));
3724
3725val limit_point_of = new_definition ("limit_point_of",
3726 ``x limit_point_of s <=>
3727        !t. x IN t /\ open t ==> ?y. ~(y = x) /\ y IN s /\ y IN t``);
3728
3729val LIMPT_SUBSET = store_thm ("LIMPT_SUBSET",
3730 ``!x s t. x limit_point_of s /\ s SUBSET t ==> x limit_point_of t``,
3731  REWRITE_TAC[limit_point_of, SUBSET_DEF] THEN MESON_TAC[]);
3732
3733val LIMPT_APPROACHABLE = store_thm ("LIMPT_APPROACHABLE",
3734 ``!x s. x limit_point_of s <=>
3735                !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ dist(x',x) < e``,
3736  REPEAT GEN_TAC THEN REWRITE_TAC[limit_point_of] THEN
3737  MESON_TAC[open_def, DIST_SYM, OPEN_BALL, CENTRE_IN_BALL, IN_BALL]);
3738
3739val lemma = prove (
3740 ``&0 < d:real ==> x <= d / &2 ==> x < d``,
3741 SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_LT] THEN REAL_ARITH_TAC);
3742
3743val APPROACHABLE_LT_LE = store_thm ("APPROACHABLE_LT_LE",
3744 ``!P f. (?d:real. &0 < d /\ !x. f(x) < d ==> P x) =
3745         (?d:real. &0 < d /\ !x. f(x) <= d ==> P x)``,
3746  MESON_TAC[REAL_LT_IMP_LE, lemma, REAL_LT_HALF1]);
3747
3748val LIMPT_APPROACHABLE_LE = store_thm ("LIMPT_APPROACHABLE_LE",
3749 ``!x s. x limit_point_of s <=>
3750                !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ dist(x',x) <= e``,
3751  REPEAT GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
3752  MATCH_MP_TAC(TAUT `(~a <=> ~b) ==> (a <=> b)`) THEN
3753  KNOW_TAC ``!e. (0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) < e) <=>
3754            (\e. (0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) < e)) e`` THENL
3755  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
3756  KNOW_TAC ``!e. (0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) <= e) <=>
3757            (\e. (0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) <= e)) e `` THENL
3758  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
3759  REWRITE_TAC [NOT_FORALL_THM] THEN BETA_TAC THEN REWRITE_TAC [NOT_IMP] THEN
3760  KNOW_TAC ``!x'' x'. ( x'' IN s /\ x'' <> x /\ dist (x'',x) < x') <=>
3761            (\x''. x'' IN s /\ x'' <> x /\ dist (x'',x) < x') x''`` THENL
3762  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
3763  KNOW_TAC ``!x'' x'. ( x'' IN s /\ x'' <> x /\ dist (x'',x) <= x') <=>
3764            (\x''. x'' IN s /\ x'' <> x /\ dist (x'',x) <= x') x''`` THENL
3765  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
3766  REWRITE_TAC [NOT_EXISTS_THM] THEN BETA_TAC THEN
3767  SIMP_TAC std_ss [TAUT `~(a /\ b /\ c) <=> c ==> ~(a /\ b)`, APPROACHABLE_LT_LE]);
3768
3769val REAL_CHOOSE_SIZE = store_thm ("REAL_CHOOSE_SIZE",
3770 ``!c. &0 <= c ==> (?x. abs x = c:real)``,
3771  METIS_TAC [ABS_REFL]);
3772
3773val LIMPT_UNIV = store_thm ("LIMPT_UNIV",
3774 ``!x:real. x limit_point_of UNIV``,
3775  GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE, IN_UNIV] THEN
3776  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
3777  SUBGOAL_THEN ``?c:real. abs(c) = e / &2`` CHOOSE_TAC THENL
3778   [ASM_SIMP_TAC std_ss [REAL_CHOOSE_SIZE, REAL_LT_HALF1, REAL_LT_IMP_LE],
3779    ALL_TAC] THEN
3780  EXISTS_TAC ``x + c:real`` THEN
3781  REWRITE_TAC[dist, REAL_ADD_RID_UNIQ] THEN ASM_REWRITE_TAC[REAL_ADD_SUB] THEN
3782  ASM_REWRITE_TAC [REAL_LT_HALF2] THEN KNOW_TAC ``0 < abs c:real`` THENL
3783  [ASM_SIMP_TAC std_ss [REAL_LT_HALF1], METIS_TAC [ABS_NZ]]);
3784
3785val CLOSED_LIMPT = store_thm ("CLOSED_LIMPT",
3786 ``!s. closed s <=> !x. x limit_point_of s ==> x IN s``,
3787  REWRITE_TAC[closed_def] THEN ONCE_REWRITE_TAC[OPEN_SUB_OPEN] THEN
3788  REWRITE_TAC[limit_point_of, IN_DIFF, IN_UNIV, SUBSET_DEF] THEN MESON_TAC[]);
3789
3790val LIMPT_EMPTY = store_thm ("LIMPT_EMPTY",
3791 ``!x. ~(x limit_point_of {})``,
3792  REWRITE_TAC[LIMPT_APPROACHABLE, NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]);
3793
3794val NO_LIMIT_POINT_IMP_CLOSED = store_thm ("NO_LIMIT_POINT_IMP_CLOSED",
3795 ``!s. ~(?x. x limit_point_of s) ==> closed s``,
3796  MESON_TAC[CLOSED_LIMPT]);
3797
3798val CLOSED_POSITIVE_ORTHANT = store_thm ("CLOSED_POSITIVE_ORTHANT",
3799 ``closed {x:real | &0 <= x}``,
3800  REWRITE_TAC[CLOSED_LIMPT, LIMPT_APPROACHABLE] THEN
3801  SIMP_TAC std_ss [GSPECIFICATION] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
3802  REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
3803  FIRST_X_ASSUM(MP_TAC o SPEC ``-(x:real)``) THEN
3804  ASM_SIMP_TAC std_ss [REAL_LT_RNEG, REAL_ADD_LID, NOT_EXISTS_THM] THEN
3805  X_GEN_TAC ``y:real`` THEN ONCE_REWRITE_TAC [METIS []``(a = b) <=> ~(a <> b:real)``] THEN
3806  REWRITE_TAC [GSYM DE_MORGAN_THM] THEN
3807  MATCH_MP_TAC(TAUT `(a ==> ~c) ==> ~(a /\ b /\ c)`) THEN DISCH_TAC THEN
3808  MATCH_MP_TAC(REAL_ARITH ``!b. abs x <= b /\ b <= a ==> ~(a + x < &0:real)``) THEN
3809  EXISTS_TAC ``abs(y - x :real)`` THEN ASM_SIMP_TAC std_ss [dist, REAL_LE_REFL] THEN
3810  ASM_SIMP_TAC std_ss [REAL_ARITH ``x < &0 /\ &0 <= y:real ==> abs(x) <= abs(y - x)``]);
3811
3812val FINITE_SET_AVOID = store_thm ("FINITE_SET_AVOID",
3813 ``!a:real s. FINITE s
3814   ==> ?d. &0 < d /\ !x. x IN s /\ ~(x = a) ==> d <= dist(a,x)``,
3815  GEN_TAC THEN
3816  KNOW_TAC ``!s. (?d. 0 < d /\ !x:real. x IN s /\ x <> a ==> d <= dist (a,x)) <=>
3817             (\s. ?d. 0 < d /\ !x:real. x IN s /\ x <> a ==> d <= dist (a,x)) s `` THENL
3818  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
3819  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
3820  REWRITE_TAC[NOT_IN_EMPTY] THEN
3821  CONJ_TAC THENL [MESON_TAC[REAL_LT_01], ALL_TAC] THEN
3822  SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN
3823  MAP_EVERY X_GEN_TAC [``s:real->bool``, ``x:real``] THEN
3824  DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN DISCH_TAC THEN
3825  FIRST_X_ASSUM(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
3826  ASM_CASES_TAC ``x:real = a`` THEN REWRITE_TAC[IN_INSERT] THENL
3827  [ASM_MESON_TAC[], ALL_TAC] THEN
3828  EXISTS_TAC ``min d (dist(a:real,x))`` THEN
3829  ASM_REWRITE_TAC[REAL_LT_MIN, GSYM DIST_NZ, REAL_MIN_LE] THEN
3830  ASM_MESON_TAC[REAL_LE_REFL]);
3831
3832val LIMIT_POINT_FINITE = store_thm ("LIMIT_POINT_FINITE",
3833 ``!s a. FINITE s ==> ~(a limit_point_of s)``,
3834  REWRITE_TAC[LIMPT_APPROACHABLE, GSYM REAL_NOT_LE] THEN
3835  SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM, REAL_NOT_LE,
3836   REAL_NOT_LT, TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN
3837  MESON_TAC[FINITE_SET_AVOID, DIST_SYM]);
3838
3839val LIMPT_SING = store_thm ("LIMPT_SING",
3840 ``!x y:real. ~(x limit_point_of {y})``,
3841  SIMP_TAC std_ss [LIMIT_POINT_FINITE, FINITE_SING]);
3842
3843val LIMIT_POINT_UNION = store_thm ("LIMIT_POINT_UNION",
3844 ``!s t x:real. x limit_point_of (s UNION t) <=>
3845                x limit_point_of s \/ x limit_point_of t``,
3846  REPEAT GEN_TAC THEN EQ_TAC THENL
3847  [ALL_TAC, MESON_TAC[LIMPT_SUBSET, SUBSET_UNION]] THEN
3848  REWRITE_TAC[LIMPT_APPROACHABLE, IN_UNION] THEN DISCH_TAC THEN
3849  MATCH_MP_TAC(TAUT `(~a ==> b) ==> a \/ b`) THEN
3850  KNOW_TAC ``!e. &0 < e /\ ~(?x'. x' IN s /\ ~(x' = x) /\ dist (x',x) < e)
3851     ==> (!e. &0 < e ==> (?x'. x' IN t /\ ~(x' = x) /\ dist (x',x) < e))`` THENL
3852  [ALL_TAC, SIMP_TAC std_ss [NOT_FORALL_THM, LEFT_IMP_EXISTS_THM, NOT_IMP]] THEN
3853  X_GEN_TAC ``e:real`` THEN STRIP_TAC THEN X_GEN_TAC ``d:real`` THEN DISCH_TAC THEN
3854  FIRST_X_ASSUM(MP_TAC o SPEC ``min d e:real``) THEN ASM_MESON_TAC[REAL_LT_MIN]);
3855
3856val LIMPT_INSERT = store_thm ("LIMPT_INSERT",
3857 ``!s x y:real. x limit_point_of (y INSERT s) <=> x limit_point_of s``,
3858  ONCE_REWRITE_TAC[SET_RULE ``y:real INSERT s = {y} UNION s``] THEN
3859  REWRITE_TAC[LIMIT_POINT_UNION] THEN
3860  SIMP_TAC std_ss [FINITE_SING, LIMIT_POINT_FINITE]);
3861
3862val LIMPT_OF_LIMPTS = store_thm ("LIMPT_OF_LIMPTS",
3863 ``!x:real s. x limit_point_of {y | y limit_point_of s}
3864          ==> x limit_point_of s``,
3865  SIMP_TAC std_ss [LIMPT_APPROACHABLE, GSPECIFICATION] THEN REPEAT GEN_TAC THEN
3866  DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
3867  FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN
3868  DISCH_THEN (X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN
3869  FIRST_X_ASSUM(MP_TAC o SPEC ``dist(y:real,x)``) THEN
3870  ASM_SIMP_TAC std_ss [DIST_POS_LT] THEN
3871  DISCH_THEN (X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC) THEN
3872  EXISTS_TAC ``z:real`` THEN
3873  ASM_REWRITE_TAC[] THEN
3874  CONJ_TAC THENL
3875  [FIRST_ASSUM MP_TAC THEN GEN_REWR_TAC (LAND_CONV o LAND_CONV) [DIST_SYM] THEN
3876   REWRITE_TAC [dist] THEN REAL_ARITH_TAC, ALL_TAC] THEN
3877  FULL_SIMP_TAC std_ss [dist, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
3878  ASM_REAL_ARITH_TAC);
3879
3880val CLOSED_LIMPTS = store_thm ("CLOSED_LIMPTS",
3881 ``!s. closed {x:real | x limit_point_of s}``,
3882  SIMP_TAC std_ss [CLOSED_LIMPT, GSPECIFICATION, LIMPT_OF_LIMPTS]);
3883
3884val DISCRETE_IMP_CLOSED = store_thm ("DISCRETE_IMP_CLOSED",
3885 ``!s:real->bool e. &0 < e /\
3886    (!x y. x IN s /\ y IN s /\ abs(y - x) < e ==> (y = x))
3887    ==> closed s``,
3888  REPEAT STRIP_TAC THEN
3889  SUBGOAL_THEN ``!x:real. ~(x limit_point_of s)``
3890  (fn th => MESON_TAC[th, CLOSED_LIMPT]) THEN
3891  GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN DISCH_TAC THEN
3892  FIRST_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN
3893  REWRITE_TAC[REAL_LT_HALF1, ASSUME ``&0 < e:real``] THEN
3894  DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN
3895  FIRST_X_ASSUM(MP_TAC o SPEC ``min (e / &2) (dist(x:real,y))``) THEN
3896  ASM_REWRITE_TAC [REAL_LT_MIN, REAL_LT_HALF1] THEN
3897  KNOW_TAC ``0 < dist(x,y:real)`` THENL
3898  [ASM_SIMP_TAC std_ss [DIST_POS_LT], ALL_TAC] THEN
3899  DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
3900  DISCH_THEN(X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC) THEN
3901  FIRST_X_ASSUM(MP_TAC o SPECL [``y:real``, ``z:real``]) THEN
3902  ASM_SIMP_TAC arith_ss [GSYM dist] THEN CONJ_TAC THENL
3903  [MATCH_MP_TAC REAL_LET_TRANS THEN
3904   EXISTS_TAC ``dist(z,x) + dist(x,y:real)`` THEN
3905   METIS_TAC [DIST_TRIANGLE, GSYM REAL_HALF_DOUBLE, REAL_LT_ADD2, DIST_SYM],
3906   REPEAT (POP_ASSUM MP_TAC) THEN REWRITE_TAC [dist, DIST_NZ] THEN
3907   REAL_ARITH_TAC]);
3908
3909val LIMPT_OF_UNIV = store_thm ("LIMPT_OF_UNIV",
3910 ``!x. x limit_point_of univ(:real)``,
3911  GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE, IN_UNIV] THEN
3912  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
3913  MP_TAC(ISPECL [``x:real``, ``e / &2:real``] REAL_CHOOSE_DIST) THEN
3914  KNOW_TAC ``0 <= e / 2:real`` THENL
3915  [METIS_TAC [REAL_LT_HALF1, REAL_LE_LT], ALL_TAC] THEN DISCH_TAC THEN
3916  ASM_REWRITE_TAC [] THEN STRIP_TAC THEN EXISTS_TAC ``y:real`` THEN
3917  CONJ_TAC THENL [ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN
3918  ASM_REWRITE_TAC [DIST_NZ, REAL_LT_HALF1], MATCH_MP_TAC REAL_LET_TRANS THEN
3919  EXISTS_TAC ``e / 2:real`` THEN METIS_TAC [REAL_LT_HALF2, REAL_LE_LT, DIST_SYM]]);
3920
3921val LIMPT_OF_OPEN_IN = store_thm ("LIMPT_OF_OPEN_IN",
3922 ``!s t x:real. open_in (subtopology euclidean s) t /\
3923                x limit_point_of s /\ x IN t
3924                ==> x limit_point_of t``,
3925  REWRITE_TAC[open_in, SUBSET_DEF, LIMPT_APPROACHABLE] THEN
3926  REPEAT GEN_TAC THEN STRIP_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
3927  UNDISCH_TAC ``!x. x IN t ==>
3928    ?e. 0 < e /\ !x'. x' IN s /\ dist (x',x) < e ==> x' IN t`` THEN DISCH_TAC THEN
3929  FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
3930  DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
3931  UNDISCH_TAC ``!e. 0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) < e`` THEN
3932  DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``min d e / &2:real``) THEN
3933  KNOW_TAC ``0 < min d e / 2:real`` THENL [REWRITE_TAC [min_def] THEN
3934  METIS_TAC [REAL_LT_HALF1], ALL_TAC] THEN DISCH_TAC THEN
3935  ASM_REWRITE_TAC [] THEN STRIP_TAC THEN EXISTS_TAC ``x':real`` THEN
3936  ASM_REWRITE_TAC[] THEN CONJ_TAC THEN TRY (FIRST_X_ASSUM MATCH_MP_TAC) THEN
3937  ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_TRANS THEN
3938  EXISTS_TAC ``min d e / 2:real`` THEN ASM_REWRITE_TAC [] THEN
3939  MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``min d e:real`` THEN
3940  METIS_TAC [REAL_MIN_LE1, min_def, REAL_LT_HALF2]);
3941
3942val LIMPT_OF_OPEN = store_thm ("LIMPT_OF_OPEN",
3943 ``!s x:real. open s /\ x IN s ==> x limit_point_of s``,
3944  REWRITE_TAC[OPEN_IN] THEN ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN
3945  MESON_TAC[LIMPT_OF_OPEN_IN, LIMPT_OF_UNIV]);
3946
3947val OPEN_IN_SING = store_thm ("OPEN_IN_SING",
3948 ``!s a. open_in (subtopology euclidean s) {a} <=>
3949   a IN s /\ ~(a limit_point_of s)``,
3950  REWRITE_TAC[open_in, LIMPT_APPROACHABLE, SING_SUBSET, IN_SING] THEN
3951  METIS_TAC[]);
3952
3953(* ------------------------------------------------------------------------- *)
3954(* Interior of a set.                                                        *)
3955(* ------------------------------------------------------------------------- *)
3956
3957val interior = new_definition ("interior",
3958  ``interior s = {x | ?t. open t /\ x IN t /\ t SUBSET s}``);
3959
3960val INTERIOR_EQ = store_thm ("INTERIOR_EQ",
3961 ``!s. (interior s = s) <=> open s``,
3962  GEN_TAC THEN REWRITE_TAC[EXTENSION, interior] THEN
3963  SIMP_TAC std_ss [GSPECIFICATION] THEN GEN_REWR_TAC RAND_CONV [OPEN_SUB_OPEN]
3964  THEN MESON_TAC[SUBSET_DEF]);
3965
3966val INTERIOR_OPEN = store_thm ("INTERIOR_OPEN",
3967 ``!s. open s ==> (interior s = s)``,
3968  MESON_TAC[INTERIOR_EQ]);
3969
3970val INTERIOR_EMPTY = store_thm ("INTERIOR_EMPTY",
3971 ``interior {} = {}``,
3972  SIMP_TAC std_ss [INTERIOR_OPEN, OPEN_EMPTY]);
3973
3974val INTERIOR_UNIV = store_thm ("INTERIOR_UNIV",
3975 ``interior univ(:real) = univ(:real)``,
3976  SIMP_TAC std_ss [INTERIOR_OPEN, OPEN_UNIV]);
3977
3978val OPEN_INTERIOR = store_thm ("OPEN_INTERIOR",
3979 ``!s. open(interior s)``,
3980  GEN_TAC THEN REWRITE_TAC[interior] THEN GEN_REWR_TAC I [OPEN_SUB_OPEN] THEN
3981  SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN MESON_TAC[]);
3982
3983val INTERIOR_INTERIOR = store_thm ("INTERIOR_INTERIOR",
3984 ``!s. interior(interior s) = interior s``,
3985  MESON_TAC[INTERIOR_EQ, OPEN_INTERIOR]);
3986
3987val INTERIOR_SUBSET = store_thm ("INTERIOR_SUBSET",
3988 ``!s. (interior s) SUBSET s``,
3989  SIMP_TAC std_ss [SUBSET_DEF, interior, GSPECIFICATION] THEN MESON_TAC[]);
3990
3991val SUBSET_INTERIOR_EQ = store_thm ("SUBSET_INTERIOR_EQ",
3992 ``!s:real->bool. s SUBSET interior s <=> open s``,
3993  REWRITE_TAC[GSYM INTERIOR_EQ,
3994  SET_RULE ``!(s:real->bool) t. (s = t) <=> s SUBSET t /\ t SUBSET s``,
3995  INTERIOR_SUBSET]);
3996
3997val SUBSET_INTERIOR = store_thm ("SUBSET_INTERIOR",
3998 ``!s t. s SUBSET t ==> (interior s) SUBSET (interior t)``,
3999  SIMP_TAC std_ss [interior, SUBSET_DEF, GSPECIFICATION] THEN MESON_TAC[]);
4000
4001val INTERIOR_MAXIMAL = store_thm ("INTERIOR_MAXIMAL",
4002 ``!s t. t SUBSET s /\ open t ==> t SUBSET (interior s)``,
4003  SIMP_TAC std_ss[interior, SUBSET_DEF, GSPECIFICATION] THEN MESON_TAC[]);
4004
4005val INTERIOR_MAXIMAL_EQ = store_thm ("INTERIOR_MAXIMAL_EQ",
4006 ``!s t:real->bool. open s ==> (s SUBSET interior t <=> s SUBSET t)``,
4007  MESON_TAC[INTERIOR_MAXIMAL, SUBSET_TRANS, INTERIOR_SUBSET]);
4008
4009val INTERIOR_UNIQUE = store_thm ("INTERIOR_UNIQUE",
4010 ``!s t. t SUBSET s /\ open t /\ (!t'. t' SUBSET s /\ open t' ==> t' SUBSET t)
4011         ==> (interior s = t)``,
4012  MESON_TAC[SUBSET_ANTISYM, INTERIOR_MAXIMAL, INTERIOR_SUBSET, OPEN_INTERIOR]);
4013
4014val IN_INTERIOR = store_thm ("IN_INTERIOR",
4015 ``!x s. x IN interior s <=> ?e. &0 < e /\ ball(x,e) SUBSET s``,
4016  SIMP_TAC std_ss [interior, GSPECIFICATION] THEN
4017  MESON_TAC[OPEN_CONTAINS_BALL, SUBSET_TRANS, CENTRE_IN_BALL, OPEN_BALL]);
4018
4019val OPEN_SUBSET_INTERIOR = store_thm ("OPEN_SUBSET_INTERIOR",
4020 ``!s t. open s ==> (s SUBSET interior t <=> s SUBSET t)``,
4021  MESON_TAC[INTERIOR_MAXIMAL, INTERIOR_SUBSET, SUBSET_TRANS]);
4022
4023val INTERIOR_INTER = store_thm ("INTERIOR_INTER",
4024 ``!s t:real->bool. interior(s INTER t) = interior s INTER interior t``,
4025  REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
4026   [REWRITE_TAC[SUBSET_INTER] THEN CONJ_TAC THEN
4027    MATCH_MP_TAC SUBSET_INTERIOR THEN REWRITE_TAC[INTER_SUBSET],
4028    MATCH_MP_TAC INTERIOR_MAXIMAL THEN SIMP_TAC std_ss [OPEN_INTER, OPEN_INTERIOR] THEN
4029    MATCH_MP_TAC(SET_RULE
4030      ``s SUBSET s' /\ t SUBSET t' ==> s INTER t SUBSET s' INTER t'``) THEN
4031    REWRITE_TAC[INTERIOR_SUBSET]]);
4032
4033val INTERIOR_FINITE_BIGINTER = store_thm ("INTERIOR_FINITE_BIGINTER",
4034 ``!s:(real->bool)->bool.
4035        FINITE s ==> (interior(BIGINTER s) = BIGINTER(IMAGE interior s))``,
4036  GEN_TAC THEN KNOW_TAC ``(interior (BIGINTER s) = BIGINTER (IMAGE interior s)) =
4037  (\s:(real->bool)->bool. (interior (BIGINTER s) = BIGINTER (IMAGE interior s))) s`` THENL
4038  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
4039  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
4040  REWRITE_TAC[BIGINTER_EMPTY, BIGINTER_INSERT, INTERIOR_UNIV, IMAGE_EMPTY,
4041  IMAGE_INSERT] THEN SIMP_TAC std_ss [INTERIOR_INTER]);
4042
4043val INTERIOR_BIGINTER_SUBSET = store_thm ("INTERIOR_BIGINTER_SUBSET",
4044 ``!f. interior(BIGINTER f) SUBSET BIGINTER (IMAGE interior f)``,
4045  REWRITE_TAC[SUBSET_DEF, IN_INTERIOR, IN_BIGINTER, FORALL_IN_IMAGE] THEN
4046  MESON_TAC[]);
4047
4048val UNION_INTERIOR_SUBSET = store_thm ("UNION_INTERIOR_SUBSET",
4049 ``!s t:real->bool.
4050        interior s UNION interior t SUBSET interior(s UNION t)``,
4051  SIMP_TAC std_ss [INTERIOR_MAXIMAL_EQ, OPEN_UNION, OPEN_INTERIOR] THEN
4052  REPEAT GEN_TAC THEN MATCH_MP_TAC(SET_RULE
4053   ``s SUBSET s' /\ t SUBSET t' ==> (s UNION t) SUBSET (s' UNION t')``) THEN
4054  REWRITE_TAC[INTERIOR_SUBSET]);
4055
4056val INTERIOR_EQ_EMPTY = store_thm ("INTERIOR_EQ_EMPTY",
4057 ``!s:real->bool. (interior s = {}) <=> !t. open t /\ t SUBSET s ==> (t = {})``,
4058  MESON_TAC[INTERIOR_MAXIMAL_EQ, SUBSET_EMPTY,
4059            OPEN_INTERIOR, INTERIOR_SUBSET]);
4060
4061val INTERIOR_EQ_EMPTY_ALT = store_thm ("INTERIOR_EQ_EMPTY_ALT",
4062 ``!s:real->bool. (interior s = {}) <=>
4063  !t. open t /\ ~(t = {}) ==> ~(t DIFF s = {})``,
4064  GEN_TAC THEN REWRITE_TAC[INTERIOR_EQ_EMPTY] THEN SET_TAC[]);
4065
4066val INTERIOR_LIMIT_POINT = store_thm ("INTERIOR_LIMIT_POINT",
4067 ``!s x:real. x IN interior s ==> x limit_point_of s``,
4068  REPEAT GEN_TAC THEN
4069  SIMP_TAC std_ss [IN_INTERIOR, GSPECIFICATION, SUBSET_DEF, IN_BALL] THEN
4070  DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
4071  REWRITE_TAC[LIMPT_APPROACHABLE] THEN X_GEN_TAC ``d:real`` THEN
4072  DISCH_TAC THEN
4073  MP_TAC(ISPECL [``x:real``, ``min d e / &2:real``] REAL_CHOOSE_DIST) THEN
4074  KNOW_TAC ``0 <= min d e / 2:real`` THENL
4075  [METIS_TAC [min_def, REAL_LE_LT, REAL_LT_HALF1], ALL_TAC] THEN
4076  DISCH_TAC THEN ASM_REWRITE_TAC [] THEN STRIP_TAC THEN
4077  EXISTS_TAC ``y:real`` THEN REPEAT CONJ_TAC THENL
4078  [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC [] THEN
4079   MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``min d e:real`` THEN
4080   METIS_TAC [REAL_MIN_LE1, min_def, REAL_LT_HALF2],
4081   CONV_TAC (RAND_CONV SYM_CONV) THEN REWRITE_TAC[DIST_NZ] THEN
4082   ASM_REWRITE_TAC [] THEN METIS_TAC [min_def, REAL_LE_LT, REAL_LT_HALF1],
4083   ONCE_REWRITE_TAC[DIST_SYM] THEN ASM_REWRITE_TAC [] THEN
4084   MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``min d e:real`` THEN
4085   METIS_TAC [REAL_MIN_LE1, min_def, REAL_LT_HALF2]]);
4086
4087val INTERIOR_SING = store_thm ("INTERIOR_SING",
4088  ``!a:real. interior {a} = {}``,
4089  REWRITE_TAC[EXTENSION, NOT_IN_EMPTY] THEN
4090  MESON_TAC[INTERIOR_LIMIT_POINT, LIMPT_SING]);
4091
4092val INTERIOR_CLOSED_UNION_EMPTY_INTERIOR = store_thm ("INTERIOR_CLOSED_UNION_EMPTY_INTERIOR",
4093 ``!s t:real->bool. closed(s) /\ (interior(t) = {})
4094                ==> (interior(s UNION t) = interior(s))``,
4095  REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
4096  SIMP_TAC std_ss [SUBSET_INTERIOR, SUBSET_UNION] THEN
4097  REWRITE_TAC[SUBSET_DEF, IN_INTERIOR, IN_INTER, IN_UNION] THEN
4098  X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN
4099  ASM_REWRITE_TAC[] THEN X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN
4100  SUBGOAL_THEN ``(y:real) limit_point_of s``
4101   (fn th => ASM_MESON_TAC[CLOSED_LIMPT, th]) THEN
4102  REWRITE_TAC[IN_INTERIOR, NOT_IN_EMPTY, LIMPT_APPROACHABLE] THEN
4103  X_GEN_TAC ``d:real`` THEN DISCH_TAC THEN
4104  SUBGOAL_THEN
4105  ``?z:real. ~(z IN t) /\ ~(z = y) /\ dist(z,y) < d /\ dist(x,z) < e``
4106   (fn th => ASM_MESON_TAC[th, IN_BALL]) THEN
4107  UNDISCH_TAC ``y IN ball (x,e)`` THEN REWRITE_TAC [IN_BALL] THEN
4108  DISCH_TAC THEN UNDISCH_TAC ``interior t = {}`` THEN
4109  GEN_REWR_TAC LAND_CONV [EXTENSION] THEN
4110  KNOW_TAC ``(!x e. ~(&0 < e /\ ball (x,e) SUBSET t))
4111   ==> (?z. ~(z IN t) /\ ~(z = y) /\ dist (z,y) < d /\ dist (x,z) < e)`` THENL
4112  [ALL_TAC, SIMP_TAC std_ss [IN_INTERIOR, NOT_IN_EMPTY, NOT_EXISTS_THM]] THEN
4113  ABBREV_TAC ``k = min d (e - dist(x:real,y))`` THEN
4114  SUBGOAL_THEN ``&0 < k:real`` ASSUME_TAC THENL
4115  [METIS_TAC [min_def, REAL_SUB_LT], ALL_TAC] THEN
4116  SUBGOAL_THEN ``?w:real. dist(y,w) = k / &2`` CHOOSE_TAC THENL
4117  [ASM_SIMP_TAC std_ss [REAL_CHOOSE_DIST, REAL_HALF, REAL_LT_IMP_LE], ALL_TAC] THEN
4118  DISCH_THEN(MP_TAC o SPECL [``w:real``, ``k / &4:real``]) THEN
4119  ASM_SIMP_TAC arith_ss [SUBSET_DEF, NOT_FORALL_THM, REAL_LT_DIV, REAL_LT,
4120  NOT_IMP, IN_BALL] THEN DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN
4121  EXISTS_TAC ``z:real`` THEN POP_ASSUM MP_TAC THEN
4122  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN ASM_REWRITE_TAC[] THEN
4123  DISCH_TAC THEN REPEAT CONJ_TAC THENL
4124  [CCONTR_TAC THEN FULL_SIMP_TAC std_ss [DIST_SYM] THEN
4125   UNDISCH_TAC `` dist (w,y) < k / 4`` THEN ASM_REWRITE_TAC [REAL_NOT_LT, REAL_LE_LT] THEN
4126   DISJ1_TAC THEN KNOW_TAC ``k < k / 2 * 4:real`` THENL
4127   [ALL_TAC, SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``0 < 4:real``]] THEN
4128   REWRITE_TAC [REAL_ARITH ``4 = 2 * 2:real``, REAL_MUL_ASSOC] THEN
4129   SIMP_TAC arith_ss [REAL_DIV_RMUL, REAL_ARITH ``2 <> 0:real``] THEN
4130   ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM REAL_DOUBLE] THEN
4131   ONCE_REWRITE_TAC [REAL_ARITH``a = a + 0:real``] THEN
4132   GEN_REWR_TAC RAND_CONV [REAL_ADD_RID] THEN ASM_REWRITE_TAC [REAL_LT_LADD],
4133   MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``dist (z, w) + dist (w, y:real)`` THEN
4134   REWRITE_TAC [DIST_TRIANGLE] THEN ONCE_REWRITE_TAC [DIST_SYM] THEN
4135   MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``min d (e - dist (x,y))`` THEN
4136   ASM_REWRITE_TAC [REAL_MIN_LE1] THEN
4137   GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN REWRITE_TAC [REAL_LT_RADD] THEN
4138   MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC ``k / 4:real`` THEN
4139   ASM_REWRITE_TAC [] THEN KNOW_TAC ``k < k / 2 * 4:real`` THENL
4140   [ALL_TAC, SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``0 < 4:real``]] THEN
4141   REWRITE_TAC [REAL_ARITH ``4 = 2 * 2:real``, REAL_MUL_ASSOC] THEN
4142   SIMP_TAC arith_ss [REAL_DIV_RMUL, REAL_ARITH ``2 <> 0:real``] THEN
4143   ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM REAL_DOUBLE] THEN
4144   ONCE_REWRITE_TAC [REAL_ARITH``a = a + 0:real``] THEN
4145   GEN_REWR_TAC RAND_CONV [REAL_ADD_RID] THEN ASM_REWRITE_TAC [REAL_LT_LADD],
4146   Cases_on `d <= (e - dist (x,y))` THENL
4147   [ALL_TAC, FULL_SIMP_TAC std_ss [min_def] THEN
4148    FULL_SIMP_TAC std_ss [REAL_ARITH ``(a - b = c) = (a = c + b:real)``] THEN
4149    ONCE_REWRITE_TAC [REAL_ADD_SYM] THEN MATCH_MP_TAC REAL_LET_TRANS THEN
4150    EXISTS_TAC ``dist (x, y) + dist (y, z:real)`` THEN
4151    REWRITE_TAC [DIST_TRIANGLE, REAL_LT_LADD] THEN MATCH_MP_TAC REAL_LET_TRANS THEN
4152    EXISTS_TAC ``dist (y,w) + dist (w, z:real)`` THEN ASM_REWRITE_TAC [DIST_TRIANGLE] THEN
4153    GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN REWRITE_TAC [REAL_LT_LADD] THEN
4154    MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC ``k / 4:real`` THEN
4155    ASM_REWRITE_TAC [] THEN KNOW_TAC ``k < k / 2 * 4:real`` THENL
4156    [ALL_TAC, SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``0 < 4:real``]] THEN
4157    REWRITE_TAC [REAL_ARITH ``4 = 2 * 2:real``, REAL_MUL_ASSOC] THEN
4158    SIMP_TAC arith_ss [REAL_DIV_RMUL, REAL_ARITH ``2 <> 0:real``] THEN
4159    ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM REAL_DOUBLE] THEN
4160    ONCE_REWRITE_TAC [REAL_ARITH``a = a + 0:real``] THEN
4161    GEN_REWR_TAC RAND_CONV [REAL_ADD_RID] THEN ASM_REWRITE_TAC [REAL_LT_LADD]] THEN
4162   FULL_SIMP_TAC std_ss [min_def, REAL_LE_SUB_LADD] THEN
4163   MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``d + dist (x,y)`` THEN
4164   ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC [REAL_ADD_SYM] THEN
4165   MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``dist (x, y) + dist (y, z:real)`` THEN
4166   REWRITE_TAC [DIST_TRIANGLE, REAL_LT_LADD] THEN MATCH_MP_TAC REAL_LET_TRANS THEN
4167   EXISTS_TAC ``dist (y,w) + dist (w, z:real)`` THEN REWRITE_TAC [DIST_TRIANGLE] THEN
4168   ASM_REWRITE_TAC [] THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN
4169   ASM_REWRITE_TAC [REAL_LT_LADD] THEN MATCH_MP_TAC REAL_LT_TRANS THEN
4170   EXISTS_TAC ``k / 4:real`` THEN ASM_REWRITE_TAC [] THEN
4171   KNOW_TAC ``k < k / 2 * 4:real`` THENL
4172   [ALL_TAC, SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``0 < 4:real``]] THEN
4173   REWRITE_TAC [REAL_ARITH ``4 = 2 * 2:real``, REAL_MUL_ASSOC] THEN
4174   SIMP_TAC arith_ss [REAL_DIV_RMUL, REAL_ARITH ``2 <> 0:real``] THEN
4175   ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM REAL_DOUBLE] THEN
4176   ONCE_REWRITE_TAC [REAL_ARITH``a = a + 0:real``] THEN
4177   GEN_REWR_TAC RAND_CONV [REAL_ADD_RID] THEN ASM_REWRITE_TAC [REAL_LT_LADD]]);
4178
4179val INTERIOR_UNION_EQ_EMPTY = store_thm ("INTERIOR_UNION_EQ_EMPTY",
4180 ``!s t:real->bool. closed s \/ closed t
4181        ==> ((interior(s UNION t) = {}) <=>
4182             (interior s = {}) /\ (interior t = {}))``,
4183REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THENL
4184[ASM_MESON_TAC[SUBSET_UNION, SUBSET_INTERIOR, SUBSET_EMPTY],
4185 ASM_MESON_TAC[UNION_COMM, INTERIOR_CLOSED_UNION_EMPTY_INTERIOR]]);
4186
4187val INTERIOR_UNIONS_OPEN_SUBSETS = store_thm ("INTERIOR_UNIONS_OPEN_SUBSETS",
4188 ``!s:real->bool. BIGUNION {t | open t /\ t SUBSET s} = interior s``,
4189  GEN_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN
4190  SIMP_TAC std_ss [OPEN_BIGUNION, GSPECIFICATION] THEN SET_TAC[]);
4191
4192(* ------------------------------------------------------------------------- *)
4193(* More variants of the Archimedian property and useful consequences.        *)
4194(* ------------------------------------------------------------------------- *)
4195
4196val REAL_ARCH_INV = store_thm ("REAL_ARCH_INV",
4197 ``!e. &0 < e <=> ?n. ~(n = 0) /\ &0:real < inv(&n) /\ inv(&n) < e:real``,
4198  GEN_TAC THEN EQ_TAC THENL [ALL_TAC, MESON_TAC[REAL_LT_TRANS]] THEN
4199  DISCH_TAC THEN MP_TAC(SPEC ``inv(e:real)`` REAL_BIGNUM) THEN
4200  STRIP_TAC THEN EXISTS_TAC ``n:num`` THEN
4201  ASM_MESON_TAC[REAL_LT_INV, REAL_INV_INV, REAL_LT_INV_EQ, REAL_LT_TRANS,
4202                REAL_LT_ANTISYM]);
4203
4204val REAL_POW_LBOUND = store_thm ("REAL_POW_LBOUND",
4205 ``!x:real n. &0 <= x ==> &1 + &n * x <= (&1 + x) pow n``,
4206  GEN_TAC THEN SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN DISCH_TAC THEN
4207  INDUCT_TAC THEN
4208  REWRITE_TAC[pow, REAL_MUL_LZERO, REAL_ADD_RID, REAL_LE_REFL] THEN
4209  REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN
4210  MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``(&1 + x) * (&1 + &n * x:real)`` THEN
4211  ASM_SIMP_TAC std_ss [REAL_LE_LMUL, REAL_ARITH ``&0 <= x:real ==> &0 <= &1 + x``,
4212                       REAL_LE_MUL, REAL_LE_LMUL_IMP, REAL_POS, pow, REAL_ARITH
4213   ``&1 + (n + &1) * x:real <= (&1 + x) * (&1 + n * x) <=> &0 <= n * x * x``]);
4214
4215val REAL_ARCH_POW = store_thm ("REAL_ARCH_POW",
4216 ``!x:real y. &1 < x ==> ?n. y < x pow n``,
4217  REPEAT STRIP_TAC THEN
4218  MP_TAC(SPEC ``x:real - &1`` REAL_ARCH) THEN ASM_REWRITE_TAC[REAL_SUB_LT] THEN
4219  DISCH_THEN(MP_TAC o SPEC ``y:real``) THEN STRIP_TAC THEN
4220  EXISTS_TAC ``n:num`` THEN MATCH_MP_TAC REAL_LTE_TRANS THEN
4221  EXISTS_TAC ``&1 + &n * (x:real - &1)`` THEN
4222  ASM_SIMP_TAC std_ss [REAL_ARITH ``x:real < y ==> x < &1 + y``] THEN
4223  ASM_MESON_TAC[REAL_POW_LBOUND, REAL_SUB_ADD2, REAL_ARITH
4224    ``&1 < x:real ==> &0 <= x - &1``]);
4225
4226val REAL_ARCH_POW2 = store_thm ("REAL_ARCH_POW2",
4227 ``!x:real. ?n. x < &2:real pow n``,
4228  SIMP_TAC std_ss [REAL_ARCH_POW, REAL_ARITH ``1 < 2:real``]);
4229
4230val REAL_ARCH_POW_INV = store_thm ("REAL_ARCH_POW_INV",
4231 ``!x:real y. &0 < y /\ x < &1 ==> ?n. x pow n < y``,
4232  REPEAT STRIP_TAC THEN ASM_CASES_TAC ``&0 < x:real`` THENL
4233   [ALL_TAC, ASM_MESON_TAC[POW_1, REAL_LET_TRANS, REAL_NOT_LT]] THEN
4234  SUBGOAL_THEN ``inv(&1) < inv(x:real)`` MP_TAC THENL
4235   [ASM_SIMP_TAC std_ss [REAL_LT_INV], REWRITE_TAC[REAL_INV1]] THEN
4236  DISCH_THEN(MP_TAC o SPEC ``inv(y:real)`` o MATCH_MP REAL_ARCH_POW) THEN
4237  STRIP_TAC THEN EXISTS_TAC ``n:num`` THEN
4238  GEN_REWR_TAC BINOP_CONV [GSYM REAL_INV_INV] THEN
4239  ASM_SIMP_TAC std_ss [GSYM REAL_POW_INV, REAL_LT_INV_EQ, REAL_LT_INV]);
4240
4241val FORALL_POS_MONO = store_thm ("FORALL_POS_MONO",
4242 ``!P. (!d e:real. d < e /\ P d ==> P e) /\ (!n. ~(n = 0) ==> P(inv(&n)))
4243       ==> !e. &0 < e ==> P e``,
4244  MESON_TAC[REAL_ARCH_INV, REAL_LT_TRANS]);
4245
4246val FORALL_SUC = store_thm ("FORALL_SUC",
4247 ``(!n. n <> 0 ==> P n) <=> !n. P (SUC n)``,
4248  EQ_TAC THENL [RW_TAC arith_ss [SUC_NOT, REAL_OF_NUM_EQ],
4249  METIS_TAC [REAL_NZ_IMP_LT, SUC_PRE, REAL_LT, REAL_OF_NUM_EQ]]);
4250
4251val LT_NZ = store_thm ("LT_NZ",
4252 ``!n:num. 0 < n <=> ~(n = 0)``,
4253  INDUCT_TAC THEN ASM_SIMP_TAC std_ss [NOT_SUC, LT, EQ_SYM_EQ] THEN
4254  TAUT_TAC);
4255
4256val REAL_ARCH_RDIV_EQ_0 = store_thm ("REAL_ARCH_RDIV_EQ_0",
4257 ``!x c:real. &0 <= x /\ &0 <= c /\ (!m. 0 < m ==> &m * x <= c) ==> (x = &0)``,
4258  SIMP_TAC std_ss [GSYM REAL_LE_ANTISYM, GSYM REAL_NOT_LT] THEN REPEAT STRIP_TAC THEN
4259  POP_ASSUM (STRIP_ASSUME_TAC o SPEC ``c:real`` o MATCH_MP REAL_ARCH) THEN
4260  ASM_CASES_TAC ``n=0:num`` THENL
4261   [POP_ASSUM SUBST_ALL_TAC THEN
4262    RULE_ASSUM_TAC (REWRITE_RULE [REAL_MUL_LZERO]) THEN
4263    ASM_MESON_TAC [REAL_LET_ANTISYM],
4264    ASM_MESON_TAC [REAL_LET_ANTISYM, REAL_MUL_SYM, LT_NZ]]);
4265
4266(* ------------------------------------------------------------------------- *)
4267(* Closure of a set.                                                         *)
4268(* ------------------------------------------------------------------------- *)
4269
4270val closure = new_definition ("closure",
4271  ``closure s = s UNION {x | x limit_point_of s}``);
4272
4273val CLOSURE_APPROACHABLE = store_thm ("CLOSURE_APPROACHABLE",
4274 ``!x s. x IN closure(s) <=> !e. &0 < e ==> ?y. y IN s /\ dist(y,x) < e``,
4275  SIMP_TAC std_ss [closure, LIMPT_APPROACHABLE, IN_UNION, GSPECIFICATION] THEN
4276  MESON_TAC[DIST_REFL]);
4277
4278val CLOSURE_NONEMPTY_OPEN_INTER = store_thm ("CLOSURE_NONEMPTY_OPEN_INTER",
4279 ``!s x:real. x IN closure s <=> !t. x IN t /\ open t ==> ~(s INTER t = {})``,
4280  REPEAT GEN_TAC THEN SIMP_TAC std_ss [closure, IN_UNION, GSPECIFICATION] THEN
4281  REWRITE_TAC[limit_point_of] THEN SET_TAC[]);
4282
4283val CLOSURE_INTERIOR = store_thm ("CLOSURE_INTERIOR",
4284 ``!s:real->bool. closure s = UNIV DIFF (interior (UNIV DIFF s))``,
4285  SIMP_TAC std_ss [EXTENSION, closure, IN_UNION, IN_DIFF, IN_UNIV, interior,
4286              GSPECIFICATION, limit_point_of, SUBSET_DEF] THEN
4287  MESON_TAC[]);
4288
4289val INTERIOR_CLOSURE = store_thm ("INTERIOR_CLOSURE",
4290 ``!s:real->bool. interior s = UNIV DIFF (closure (UNIV DIFF s))``,
4291  REWRITE_TAC[CLOSURE_INTERIOR, SET_RULE ``!s t. UNIV DIFF (UNIV DIFF t) = t``]);
4292
4293val CLOSED_CLOSURE = store_thm ("CLOSED_CLOSURE",
4294 ``!s. closed(closure s)``,
4295  REWRITE_TAC[closed_def, CLOSURE_INTERIOR, SET_RULE ``UNIV DIFF (UNIV DIFF s) = s``,
4296              OPEN_INTERIOR]);
4297
4298val CLOSURE_HULL = store_thm ("CLOSURE_HULL",
4299 ``!s. closure s = closed hull s``,
4300  GEN_TAC THEN MATCH_MP_TAC(GSYM HULL_UNIQUE) THEN
4301  REWRITE_TAC[CLOSED_CLOSURE, SUBSET_DEF] THEN
4302  SIMP_TAC std_ss [closure, IN_UNION, GSPECIFICATION, CLOSED_LIMPT] THEN
4303  MESON_TAC[limit_point_of]);
4304
4305val CLOSURE_EQ = store_thm ("CLOSURE_EQ",
4306 ``!s. (closure s = s) <=> closed s``,
4307  SIMP_TAC std_ss [CLOSURE_HULL, HULL_EQ, CLOSED_BIGINTER]);
4308
4309val CLOSURE_CLOSED = store_thm ("CLOSURE_CLOSED",
4310 ``!s. closed s ==> (closure s = s)``,
4311  MESON_TAC[CLOSURE_EQ]);
4312
4313val CLOSURE_CLOSURE = store_thm ("CLOSURE_CLOSURE",
4314 ``!s. closure(closure s) = closure s``,
4315  REWRITE_TAC[CLOSURE_HULL, HULL_HULL]);
4316
4317val CLOSURE_SUBSET = store_thm ("CLOSURE_SUBSET",
4318 ``!s. s SUBSET (closure s)``,
4319  REWRITE_TAC[CLOSURE_HULL, HULL_SUBSET]);
4320
4321val SUBSET_CLOSURE = store_thm ("SUBSET_CLOSURE",
4322 ``!s t. s SUBSET t ==> (closure s) SUBSET (closure t)``,
4323  REWRITE_TAC[CLOSURE_HULL, HULL_MONO]);
4324
4325val CLOSURE_UNION = store_thm ("CLOSURE_UNION",
4326 ``!s t:real->bool. closure(s UNION t) = closure s UNION closure t``,
4327  REWRITE_TAC[LIMIT_POINT_UNION, closure] THEN SET_TAC[]);
4328
4329val CLOSURE_INTER_SUBSET = store_thm ("CLOSURE_INTER_SUBSET",
4330 ``!s t. closure(s INTER t) SUBSET closure(s) INTER closure(t)``,
4331  REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET_INTER] THEN
4332  CONJ_TAC THEN MATCH_MP_TAC SUBSET_CLOSURE THEN SET_TAC[]);
4333
4334val CLOSURE_BIGINTER_SUBSET = store_thm ("CLOSURE_BIGINTER_SUBSET",
4335 ``!f. closure(BIGINTER f) SUBSET BIGINTER (IMAGE closure f)``,
4336  REWRITE_TAC[SET_RULE ``s SUBSET BIGINTER f <=> !t. t IN f ==> s SUBSET t``] THEN
4337  REWRITE_TAC[FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN
4338  MATCH_MP_TAC SUBSET_CLOSURE THEN ASM_SET_TAC[]);
4339
4340val CLOSURE_MINIMAL = store_thm ("CLOSURE_MINIMAL",
4341 ``!s t. s SUBSET t /\ closed t ==> (closure s) SUBSET t``,
4342  REWRITE_TAC[HULL_MINIMAL, CLOSURE_HULL]);
4343
4344val CLOSURE_MINIMAL_EQ = store_thm ("CLOSURE_MINIMAL_EQ",
4345 ``!s t:real->bool. closed t ==> (closure s SUBSET t <=> s SUBSET t)``,
4346  MESON_TAC[SUBSET_TRANS, CLOSURE_SUBSET, CLOSURE_MINIMAL]);
4347
4348val CLOSURE_UNIQUE = store_thm ("CLOSURE_UNIQUE",
4349 ``!s t. s SUBSET t /\ closed t /\
4350  (!t'. s SUBSET t' /\ closed t' ==> t SUBSET t')
4351   ==> (closure s = t)``,
4352  REWRITE_TAC[CLOSURE_HULL, HULL_UNIQUE]);
4353
4354val CLOSURE_EMPTY = store_thm ("CLOSURE_EMPTY",
4355 ``closure {} = {}``,
4356  SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_EMPTY]);
4357
4358val CLOSURE_UNIV = store_thm ("CLOSURE_UNIV",
4359 ``closure univ(:real) = univ(:real)``,
4360  SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_UNIV]);
4361
4362val CLOSURE_BIGUNION = store_thm ("CLOSURE_BIGUNION",
4363 ``!f. FINITE f ==> (closure(BIGUNION f) = BIGUNION {closure s | s IN f})``,
4364  KNOW_TAC ``!f. (closure(BIGUNION f) = BIGUNION {closure s | s IN f}) =
4365             (\f. closure(BIGUNION f) = BIGUNION {closure s | s IN f}) f`` THENL
4366  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
4367  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
4368  SIMP_TAC std_ss [BIGUNION_EMPTY, BIGUNION_INSERT, SET_RULE ``{f x | x IN {}} = {}``,
4369  SET_RULE ``{f x | x IN a INSERT s} = (f a) INSERT {f x | x IN s}``] THEN
4370  SIMP_TAC std_ss [CLOSURE_EMPTY, CLOSURE_UNION]);
4371
4372val CLOSURE_EQ_EMPTY = store_thm ("CLOSURE_EQ_EMPTY",
4373 ``!s. (closure s = {}) <=> (s = {})``,
4374  GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [CLOSURE_EMPTY] THEN
4375  MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> (t = {}) ==> (s = {})``) THEN
4376  REWRITE_TAC[CLOSURE_SUBSET]);
4377
4378val CLOSURE_SUBSET_EQ = store_thm ("CLOSURE_SUBSET_EQ",
4379 ``!s:real->bool. closure s SUBSET s <=> closed s``,
4380  GEN_TAC THEN REWRITE_TAC[GSYM CLOSURE_EQ] THEN
4381  MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN SET_TAC[]);
4382
4383val OPEN_INTER_CLOSURE_EQ_EMPTY = store_thm ("OPEN_INTER_CLOSURE_EQ_EMPTY",
4384 ``!s t:real->bool.
4385        open s ==> ((s INTER (closure t) = {}) <=> (s INTER t = {}))``,
4386  REPEAT STRIP_TAC THEN EQ_TAC THENL
4387   [MP_TAC(ISPEC ``t:real->bool`` CLOSURE_SUBSET) THEN SET_TAC[], ALL_TAC] THEN
4388  DISCH_TAC THEN REWRITE_TAC[CLOSURE_INTERIOR] THEN
4389  MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> (s INTER (UNIV DIFF t) = {})``) THEN
4390  ASM_SIMP_TAC std_ss [OPEN_SUBSET_INTERIOR] THEN
4391  REPEAT (POP_ASSUM MP_TAC) THEN SET_TAC[]);
4392
4393val CLOSURE_OPEN_IN_INTER_CLOSURE = store_thm ("CLOSURE_OPEN_IN_INTER_CLOSURE",
4394 ``!s t u:real->bool.
4395     open_in (subtopology euclidean u) s /\ t SUBSET u
4396     ==> (closure(s INTER closure t) = closure(s INTER t))``,
4397  REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
4398  SIMP_TAC std_ss [CLOSURE_SUBSET, SUBSET_CLOSURE, SET_RULE
4399  ``t SUBSET u ==> s INTER t SUBSET s INTER u``] THEN
4400  REWRITE_TAC[SUBSET_DEF, CLOSURE_APPROACHABLE] THEN
4401  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
4402  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
4403  FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN
4404  ASM_REWRITE_TAC[REAL_LT_HALF1, IN_INTER, CLOSURE_APPROACHABLE] THEN
4405  DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN
4406  UNDISCH_TAC ``open_in (subtopology euclidean u) s`` THEN
4407  REWRITE_TAC [open_in] THEN REWRITE_TAC[SUBSET_DEF] THEN
4408  DISCH_THEN(CONJUNCTS_THEN(MP_TAC o SPEC ``y:real``)) THEN
4409  ASM_REWRITE_TAC[] THEN
4410  DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN DISCH_TAC THEN
4411  UNDISCH_TAC ``!e. 0 < e ==> ?y'. y' IN t /\ dist (y',y) < e`` THEN
4412  DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``min d (e / &2:real)``) THEN
4413  ASM_REWRITE_TAC[REAL_LT_HALF1, REAL_LT_MIN] THEN
4414  DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN
4415  POP_ASSUM MP_TAC THEN
4416  RULE_ASSUM_TAC(REWRITE_RULE[SUBSET_DEF]) THEN ASM_SIMP_TAC std_ss [] THEN
4417  STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
4418  EXISTS_TAC ``dist(z,y) + dist(y,x)`` THEN REWRITE_TAC [DIST_TRIANGLE] THEN
4419  GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN
4420  MATCH_MP_TAC REAL_LT_ADD2 THEN ASM_REWRITE_TAC []);
4421
4422val CLOSURE_OPEN_INTER_CLOSURE = store_thm ("CLOSURE_OPEN_INTER_CLOSURE",
4423 ``!s t:real->bool.
4424   open s ==> (closure(s INTER closure t) = closure(s INTER t))``,
4425  REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_OPEN_IN_INTER_CLOSURE THEN
4426  EXISTS_TAC ``univ(:real)`` THEN
4427  ASM_REWRITE_TAC[SUBSET_UNIV, GSYM OPEN_IN, SUBTOPOLOGY_UNIV]);
4428
4429val OPEN_INTER_CLOSURE_SUBSET = store_thm ("OPEN_INTER_CLOSURE_SUBSET",
4430 ``!s t:real->bool.
4431        open s ==> (s INTER (closure t)) SUBSET closure(s INTER t)``,
4432  REPEAT STRIP_TAC THEN
4433  SIMP_TAC std_ss [SUBSET_DEF, IN_INTER, closure, IN_UNION, GSPECIFICATION] THEN
4434  X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4435  DISJ2_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
4436  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
4437  UNDISCH_TAC ``open s`` THEN REWRITE_TAC [open_def] THEN
4438  DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
4439  DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
4440  UNDISCH_TAC ``x limit_point_of t`` THEN REWRITE_TAC [LIMPT_APPROACHABLE] THEN
4441  DISCH_THEN(MP_TAC o SPEC ``min d e:real``) THEN
4442  ASM_REWRITE_TAC[REAL_LT_MIN, IN_INTER] THEN STRIP_TAC THEN
4443  EXISTS_TAC ``x':real`` THEN ASM_MESON_TAC[]);
4444
4445val CLOSURE_OPEN_INTER_SUPERSET = store_thm ("CLOSURE_OPEN_INTER_SUPERSET",
4446 ``!s t:real->bool.
4447        open s /\ s SUBSET closure t ==> (closure(s INTER t) = closure s)``,
4448  REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
4449  SIMP_TAC std_ss [SUBSET_CLOSURE, INTER_SUBSET] THEN
4450  MATCH_MP_TAC CLOSURE_MINIMAL THEN REWRITE_TAC[CLOSED_CLOSURE] THEN
4451  W(MP_TAC o PART_MATCH (rand o rand) OPEN_INTER_CLOSURE_SUBSET o rand o snd) THEN
4452  ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] SUBSET_TRANS) THEN
4453  ASM_SET_TAC[]);
4454
4455val CLOSURE_COMPLEMENT = store_thm ("CLOSURE_COMPLEMENT",
4456 ``!s:real->bool. closure(UNIV DIFF s) = UNIV DIFF interior(s)``,
4457  REWRITE_TAC[SET_RULE ``(s = UNIV DIFF t) <=> (UNIV DIFF s = t)``] THEN
4458  REWRITE_TAC[GSYM INTERIOR_CLOSURE]);
4459
4460val INTERIOR_COMPLEMENT = store_thm ("INTERIOR_COMPLEMENT",
4461 ``!s:real->bool. interior(UNIV DIFF s) = UNIV DIFF closure(s)``,
4462  REWRITE_TAC[SET_RULE ``(s = UNIV DIFF t) <=> (UNIV DIFF s = t)``] THEN
4463  REWRITE_TAC[GSYM CLOSURE_INTERIOR]);
4464
4465val CONNECTED_INTERMEDIATE_CLOSURE = store_thm ("CONNECTED_INTERMEDIATE_CLOSURE",
4466 ``!s t:real->bool.
4467   connected s /\ s SUBSET t /\ t SUBSET closure s ==> connected t``,
4468  REPEAT GEN_TAC THEN
4469  KNOW_TAC ``(!e1 e2.
4470      ~(open e1 /\ open e2 /\
4471        s SUBSET e1 UNION e2 /\ (e1 INTER e2 INTER s = {}) /\
4472        ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))) /\
4473        s SUBSET t /\ t SUBSET closure s
4474 ==> (!e1 e2.
4475          ~(open e1 /\ open e2 /\
4476            t SUBSET e1 UNION e2 /\ (e1 INTER e2 INTER t = {}) /\
4477            ~(e1 INTER t = {}) /\ ~(e2 INTER t = {})))`` THENL
4478  [ALL_TAC, SIMP_TAC std_ss [connected, NOT_EXISTS_THM]] THEN
4479  STRIP_TAC THEN MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
4480  STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL [``u:real->bool``, ``v:real->bool``]) THEN
4481  ASM_REWRITE_TAC[] THEN ASSUME_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN
4482  CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
4483  REWRITE_TAC[GSYM DE_MORGAN_THM] THEN STRIP_TAC THENL
4484  [SUBGOAL_THEN ``(closure s) SUBSET (univ(:real) DIFF u)`` MP_TAC THENL
4485  [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_REWRITE_TAC[GSYM OPEN_CLOSED], ALL_TAC],
4486  SUBGOAL_THEN ``(closure s) SUBSET (univ(:real) DIFF v)`` MP_TAC THENL
4487  [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_REWRITE_TAC[GSYM OPEN_CLOSED],
4488   ALL_TAC]] THEN ASM_SET_TAC[]);
4489
4490val CONNECTED_CLOSURE = store_thm ("CONNECTED_CLOSURE",
4491 ``!s:real->bool. connected s ==> connected(closure s)``,
4492  MESON_TAC[CONNECTED_INTERMEDIATE_CLOSURE, CLOSURE_SUBSET, SUBSET_REFL]);
4493
4494val CONNECTED_UNION_STRONG = store_thm ("CONNECTED_UNION_STRONG",
4495 ``!s t:real->bool.
4496    connected s /\ connected t /\ ~(closure s INTER t = {})
4497    ==> connected(s UNION t)``,
4498  REPEAT STRIP_TAC THEN
4499  POP_ASSUM (MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
4500  DISCH_THEN(X_CHOOSE_TAC ``p:real``) THEN
4501  SUBGOAL_THEN ``s UNION t = ((p:real) INSERT s) UNION t`` SUBST1_TAC THENL
4502  [ASM_SET_TAC[], ALL_TAC] THEN
4503  MATCH_MP_TAC CONNECTED_UNION THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
4504  [MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN
4505   EXISTS_TAC ``s:real->bool`` THEN ASM_REWRITE_TAC[] THEN
4506   MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[],
4507   ASM_SET_TAC[]]);
4508
4509val INTERIOR_DIFF = store_thm ("INTERIOR_DIFF",
4510 ``!s t. interior(s DIFF t) = interior(s) DIFF closure(t)``,
4511  ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s INTER (UNIV DIFF t)``] THEN
4512  REWRITE_TAC[INTERIOR_INTER, CLOSURE_INTERIOR] THEN SET_TAC[]);
4513
4514val LIMPT_OF_CLOSURE = store_thm ("LIMPT_OF_CLOSURE",
4515 ``!x:real s. x limit_point_of closure s <=> x limit_point_of s``,
4516  SIMP_TAC std_ss [closure, IN_UNION, GSPECIFICATION, LIMIT_POINT_UNION] THEN
4517  REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT `(q ==> p) ==> (p \/ q <=> p)`) THEN
4518  REWRITE_TAC[LIMPT_OF_LIMPTS]);
4519
4520val CLOSED_IN_LIMPT = store_thm ("CLOSED_IN_LIMPT",
4521 ``!s t. closed_in (subtopology euclidean t) s <=>
4522    s SUBSET t /\ !x:real. x limit_point_of s /\ x IN t ==> x IN s``,
4523  REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN EQ_TAC THENL
4524  [DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN
4525  ASM_SIMP_TAC std_ss [IN_INTER] THEN
4526  ASM_MESON_TAC[CLOSED_LIMPT, LIMPT_SUBSET, INTER_SUBSET],
4527  STRIP_TAC THEN EXISTS_TAC ``closure s :real->bool`` THEN
4528  REWRITE_TAC[CLOSED_CLOSURE] THEN REWRITE_TAC[closure] THEN
4529  ASM_SET_TAC[]]);
4530
4531val CLOSED_IN_INTER_CLOSURE = store_thm ("CLOSED_IN_INTER_CLOSURE",
4532 ``!s t:real->bool.
4533    closed_in (subtopology euclidean s) t <=> (s INTER closure t = t)``,
4534  REWRITE_TAC[closure, CLOSED_IN_LIMPT] THEN SET_TAC[]);
4535
4536val INTERIOR_CLOSURE_IDEMP = store_thm ("INTERIOR_CLOSURE_IDEMP",
4537 ``!s:real->bool.
4538    interior(closure(interior(closure s))) = interior(closure s)``,
4539  GEN_TAC THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN
4540  ASM_MESON_TAC[OPEN_INTERIOR, CLOSURE_SUBSET, CLOSURE_CLOSURE, SUBSET_TRANS,
4541                OPEN_SUBSET_INTERIOR, SUBSET_CLOSURE, INTERIOR_SUBSET]);
4542
4543val CLOSURE_INTERIOR_IDEMP = store_thm ("CLOSURE_INTERIOR_IDEMP",
4544 ``!s:real->bool.
4545    closure(interior(closure(interior s))) = closure(interior s)``,
4546  GEN_TAC THEN
4547  ONCE_REWRITE_TAC[SET_RULE ``(s = t) <=> (UNIV DIFF s = UNIV DIFF t)``] THEN
4548  REWRITE_TAC[GSYM INTERIOR_COMPLEMENT, GSYM CLOSURE_COMPLEMENT] THEN
4549  REWRITE_TAC[INTERIOR_CLOSURE_IDEMP]);
4550
4551val NOWHERE_DENSE_UNION = store_thm ("NOWHERE_DENSE_UNION",
4552 ``!s t:real->bool.
4553   (interior(closure(s UNION t)) = {}) <=>
4554   (interior(closure s) = {}) /\ (interior(closure t) = {})``,
4555  SIMP_TAC std_ss [CLOSURE_UNION, INTERIOR_UNION_EQ_EMPTY, CLOSED_CLOSURE]);
4556
4557val NOWHERE_DENSE = store_thm ("NOWHERE_DENSE",
4558 ``!s:real->bool. (interior(closure s) = {}) <=>
4559              !t. open t /\ ~(t = {})
4560          ==> ?u. open u /\ ~(u = {}) /\ u SUBSET t /\ (u INTER s = {})``,
4561  GEN_TAC THEN REWRITE_TAC[INTERIOR_EQ_EMPTY_ALT] THEN EQ_TAC THEN
4562  DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN STRIP_TAC THENL
4563  [EXISTS_TAC ``t DIFF closure s:real->bool`` THEN
4564  ASM_SIMP_TAC std_ss [OPEN_DIFF, CLOSED_CLOSURE] THEN
4565  MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN SET_TAC[],
4566  FIRST_X_ASSUM(MP_TAC o SPEC ``t:real->bool``) THEN ASM_REWRITE_TAC[] THEN
4567  DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN
4568  MP_TAC(ISPECL [``u:real->bool``, ``s:real->bool``]
4569  OPEN_INTER_CLOSURE_EQ_EMPTY) THEN ASM_SET_TAC[]]);
4570
4571val INTERIOR_CLOSURE_INTER_OPEN = store_thm ("INTERIOR_CLOSURE_INTER_OPEN",
4572 ``!s t:real->bool. open s /\ open t
4573        ==> (interior(closure(s INTER t)) =
4574             interior(closure s) INTER interior(closure t))``,
4575  REPEAT STRIP_TAC THEN REWRITE_TAC[SET_RULE
4576  ``(u = s INTER t) <=> s INTER t SUBSET u /\ u SUBSET s /\ u SUBSET t``] THEN
4577  SIMP_TAC std_ss [SUBSET_INTERIOR, SUBSET_CLOSURE, INTER_SUBSET] THEN
4578  MATCH_MP_TAC INTERIOR_MAXIMAL THEN SIMP_TAC std_ss [OPEN_INTER, OPEN_INTERIOR] THEN
4579  REWRITE_TAC[SET_RULE ``s SUBSET t <=> (s INTER (UNIV DIFF t) = {})``,
4580   GSYM INTERIOR_COMPLEMENT] THEN
4581  REWRITE_TAC[GSYM INTERIOR_INTER] THEN
4582  REWRITE_TAC[INTERIOR_EQ_EMPTY] THEN
4583  X_GEN_TAC ``u:real->bool`` THEN STRIP_TAC THEN
4584  MP_TAC(ISPECL [``u INTER s:real->bool``, ``t:real->bool``]
4585   OPEN_INTER_CLOSURE_EQ_EMPTY) THEN
4586  MP_TAC(ISPECL [``u:real->bool``, ``s:real->bool``]
4587   OPEN_INTER_CLOSURE_EQ_EMPTY) THEN
4588  ASM_SIMP_TAC std_ss [OPEN_INTER] THEN ASM_SET_TAC[]);
4589
4590val CLOSURE_INTERIOR_UNION_CLOSED = store_thm ("CLOSURE_INTERIOR_UNION_CLOSED",
4591 ``!s t:real->bool. closed s /\ closed t
4592        ==> (closure (interior (s UNION t)) =
4593             closure (interior s) UNION closure(interior t))``,
4594  REPEAT GEN_TAC THEN REWRITE_TAC[closed_def] THEN
4595  DISCH_THEN(MP_TAC o MATCH_MP INTERIOR_CLOSURE_INTER_OPEN) THEN
4596  REWRITE_TAC[CLOSURE_COMPLEMENT, INTERIOR_COMPLEMENT,
4597  SET_RULE ``(UNIV DIFF s) INTER (UNIV DIFF t) = UNIV DIFF (s UNION t)``] THEN
4598  SET_TAC[]);
4599
4600val REGULAR_OPEN_INTER = store_thm ("REGULAR_OPEN_INTER",
4601 ``!s t:real->bool.
4602    (interior(closure s) = s) /\ (interior(closure t) = t)
4603     ==> (interior(closure(s INTER t)) = s INTER t)``,
4604  MESON_TAC[INTERIOR_CLOSURE_INTER_OPEN, OPEN_INTERIOR]);
4605
4606val REGULAR_CLOSED_UNION = store_thm ("REGULAR_CLOSED_UNION",
4607 ``!s t:real->bool.
4608  (closure(interior s) = s) /\ (closure(interior t) = t)
4609   ==> (closure(interior(s UNION t)) = s UNION t)``,
4610  MESON_TAC[CLOSURE_INTERIOR_UNION_CLOSED, CLOSED_CLOSURE]);
4611
4612val REGULAR_CLOSED_BIGUNION = store_thm ("REGULAR_CLOSED_BIGUNION",
4613 ``!f:(real->bool)->bool.
4614    FINITE f /\ (!t. t IN f ==> (closure(interior t) = t))
4615    ==> (closure(interior(BIGUNION f)) = BIGUNION f)``,
4616  REWRITE_TAC[GSYM AND_IMP_INTRO] THEN
4617  KNOW_TAC ``!f. ((!t. t IN f ==> (closure(interior t) = t))
4618         ==> (closure(interior(BIGUNION f)) = BIGUNION f)) =
4619           (\f. (!t. t IN f ==> (closure(interior t) = t))
4620         ==> (closure(interior(BIGUNION f)) = BIGUNION f)) f`` THENL
4621  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
4622  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
4623  REWRITE_TAC[BIGUNION_INSERT, BIGUNION_EMPTY, INTERIOR_EMPTY, CLOSURE_EMPTY] THEN
4624  SIMP_TAC std_ss [FORALL_IN_INSERT, REGULAR_CLOSED_UNION]);
4625
4626val DIFF_CLOSURE_SUBSET = store_thm ("DIFF_CLOSURE_SUBSET",
4627 ``!s t:real->bool. closure(s) DIFF closure t SUBSET closure(s DIFF t)``,
4628  REPEAT GEN_TAC THEN
4629  MP_TAC(ISPECL [``univ(:real) DIFF closure t``, ``s:real->bool``]
4630   OPEN_INTER_CLOSURE_SUBSET) THEN
4631  REWRITE_TAC[SET_RULE ``(UNIV DIFF t) INTER s = s DIFF t``] THEN
4632  REWRITE_TAC[GSYM closed_def, CLOSED_CLOSURE] THEN
4633  MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUBSET_TRANS) THEN
4634  MATCH_MP_TAC SUBSET_CLOSURE THEN
4635  MATCH_MP_TAC(SET_RULE ``t SUBSET u ==> s DIFF u SUBSET s DIFF t``) THEN
4636  REWRITE_TAC[CLOSURE_SUBSET]);
4637
4638val DENSE_OPEN_INTER = store_thm ("DENSE_OPEN_INTER",
4639 ``!s t u:real->bool.
4640  (open_in (subtopology euclidean u) s /\ t SUBSET u \/
4641   open_in (subtopology euclidean u) t /\ s SUBSET u)
4642   ==> (u SUBSET closure (s INTER t) <=>
4643        u SUBSET closure s /\ u SUBSET closure t)``,
4644  KNOW_TAC ``((!s t u.
4645      (u SUBSET closure (s INTER t) <=>
4646       u SUBSET closure s /\ u SUBSET closure t)
4647      ==> (u SUBSET closure (t INTER s) <=>
4648           u SUBSET closure t /\ u SUBSET closure s)) /\
4649 (!s t u.
4650      open_in (subtopology euclidean u) s /\ t SUBSET u
4651      ==> (u SUBSET closure (s INTER t) <=>
4652           u SUBSET closure s /\ u SUBSET closure t)))`` THENL
4653  [ALL_TAC, METIS_TAC []] THEN CONJ_TAC THENL
4654  [SIMP_TAC std_ss [INTER_COMM, CONJ_ACI], ALL_TAC] THEN
4655  REPEAT GEN_TAC THEN STRIP_TAC THEN EQ_TAC THENL
4656  [ASM_MESON_TAC[SUBSET_TRANS, SUBSET_CLOSURE, INTER_SUBSET], ALL_TAC] THEN
4657  REWRITE_TAC[SUBSET_DEF, CLOSURE_APPROACHABLE] THEN DISCH_TAC THEN
4658  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
4659  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
4660  FIRST_X_ASSUM(CONJUNCTS_THEN2 (MP_TAC o SPEC ``x:real``) ASSUME_TAC) THEN
4661  ASM_REWRITE_TAC[] THEN
4662  DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN
4663  DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN
4664  FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN
4665  UNDISCH_TAC ``open_in (subtopology euclidean u) s`` THEN REWRITE_TAC [open_in] THEN
4666  REWRITE_TAC[SUBSET_DEF, IN_INTER] THEN
4667  DISCH_THEN(CONJUNCTS_THEN (MP_TAC o SPEC ``y:real``)) THEN
4668  ASM_REWRITE_TAC[] THEN
4669  DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN DISCH_TAC THEN
4670  ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``min d (e / &2):real``) THEN
4671  ASM_REWRITE_TAC[REAL_HALF, REAL_LT_MIN] THEN
4672  DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN
4673  RULE_ASSUM_TAC(REWRITE_RULE[SUBSET_DEF]) THEN ASM_SIMP_TAC std_ss [] THEN
4674  POP_ASSUM MP_TAC THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
4675  EXISTS_TAC ``dist(z,y) + dist(y,x)`` THEN REWRITE_TAC [DIST_TRIANGLE] THEN
4676  GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN
4677  MATCH_MP_TAC REAL_LT_ADD2 THEN ASM_REWRITE_TAC []);
4678
4679(* ------------------------------------------------------------------------- *)
4680(* Frontier (aka boundary).                                                  *)
4681(* ------------------------------------------------------------------------- *)
4682
4683val frontier = new_definition ("frontier",
4684  ``frontier s = (closure s) DIFF (interior s)``);
4685
4686val FRONTIER_CLOSED = store_thm ("FRONTIER_CLOSED",
4687 ``!s. closed(frontier s)``,
4688  SIMP_TAC std_ss [frontier, CLOSED_DIFF, CLOSED_CLOSURE, OPEN_INTERIOR]);
4689
4690val FRONTIER_CLOSURES = store_thm ("FRONTIER_CLOSURES",
4691 ``!s:real->bool. frontier s = (closure s) INTER (closure(UNIV DIFF s))``,
4692  REWRITE_TAC[frontier, INTERIOR_CLOSURE,
4693   SET_RULE ``s DIFF (UNIV DIFF t) = s INTER t``]);
4694
4695val FRONTIER_STRADDLE = store_thm ("FRONTIER_STRADDLE",
4696 ``!a:real s.
4697    a IN frontier s <=> !e. &0 < e ==> (?x. x IN s /\ dist(a,x) < e) /\
4698    (?x. ~(x IN s) /\ dist(a,x) < e)``,
4699  REPEAT GEN_TAC THEN REWRITE_TAC[FRONTIER_CLOSURES, IN_INTER] THEN
4700  SIMP_TAC std_ss [closure, IN_UNION, GSPECIFICATION, limit_point_of,
4701  IN_UNIV, IN_DIFF] THEN
4702  ASM_MESON_TAC[IN_BALL, SUBSET_DEF, OPEN_CONTAINS_BALL,
4703  CENTRE_IN_BALL, OPEN_BALL, DIST_REFL]);
4704
4705val FRONTIER_SUBSET_CLOSED = store_thm ("FRONTIER_SUBSET_CLOSED",
4706 ``!s. closed s ==> (frontier s) SUBSET s``,
4707  METIS_TAC[frontier, CLOSURE_CLOSED, DIFF_SUBSET]);
4708
4709val FRONTIER_EMPTY = store_thm ("FRONTIER_EMPTY",
4710 ``frontier {} = {}``,
4711  REWRITE_TAC[frontier, CLOSURE_EMPTY, EMPTY_DIFF]);
4712
4713val FRONTIER_UNIV = store_thm ("FRONTIER_UNIV",
4714 ``frontier univ(:real) = {}``,
4715  REWRITE_TAC[frontier, CLOSURE_UNIV, INTERIOR_UNIV] THEN SET_TAC[]);
4716
4717val FRONTIER_SUBSET_EQ = store_thm ("FRONTIER_SUBSET_EQ",
4718 ``!s:real->bool. (frontier s) SUBSET s <=> closed s``,
4719  GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [FRONTIER_SUBSET_CLOSED] THEN
4720  REWRITE_TAC[frontier] THEN
4721  DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
4722  ``s DIFF t SUBSET u ==> t SUBSET u ==> s SUBSET u``)) THEN
4723  REWRITE_TAC[INTERIOR_SUBSET, CLOSURE_SUBSET_EQ]);
4724
4725val FRONTIER_COMPLEMENT = store_thm ("FRONTIER_COMPLEMENT",
4726 ``!s:real->bool. frontier(UNIV DIFF s) = frontier s``,
4727  REWRITE_TAC[frontier, CLOSURE_COMPLEMENT, INTERIOR_COMPLEMENT] THEN
4728  SET_TAC[]);
4729
4730val FRONTIER_DISJOINT_EQ = store_thm ("FRONTIER_DISJOINT_EQ",
4731 ``!s. ((frontier s) INTER s = {}) <=> open s``,
4732  ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT, OPEN_CLOSED] THEN
4733  REWRITE_TAC[GSYM FRONTIER_SUBSET_EQ] THEN SET_TAC[]);
4734
4735val FRONTIER_INTER_SUBSET = store_thm ("FRONTIER_INTER_SUBSET",
4736 ``!s t. frontier(s INTER t) SUBSET frontier(s) UNION frontier(t)``,
4737  REPEAT GEN_TAC THEN REWRITE_TAC[frontier, INTERIOR_INTER] THEN
4738  MATCH_MP_TAC(SET_RULE ``cst SUBSET cs INTER ct
4739  ==> cst DIFF (s INTER t) SUBSET (cs DIFF s) UNION (ct DIFF t)``) THEN
4740  REWRITE_TAC[CLOSURE_INTER_SUBSET]);
4741
4742val FRONTIER_UNION_SUBSET = store_thm ("FRONTIER_UNION_SUBSET",
4743 ``!s t:real->bool. frontier(s UNION t) SUBSET frontier s UNION frontier t``,
4744  ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT] THEN
4745  REWRITE_TAC[SET_RULE ``u DIFF (s UNION t) = (u DIFF s) INTER (u DIFF t)``] THEN
4746  REWRITE_TAC[FRONTIER_INTER_SUBSET]);
4747
4748val FRONTIER_INTERIORS = store_thm ("FRONTIER_INTERIORS",
4749 ``!s. frontier s = univ(:real) DIFF interior(s) DIFF interior(univ(:real) DIFF s)``,
4750  REWRITE_TAC[frontier, CLOSURE_INTERIOR] THEN SET_TAC[]);
4751
4752val FRONTIER_FRONTIER_SUBSET = store_thm ("FRONTIER_FRONTIER_SUBSET",
4753 ``!s:real->bool. frontier(frontier s) SUBSET frontier s``,
4754  GEN_TAC THEN GEN_REWR_TAC LAND_CONV [frontier] THEN
4755  SIMP_TAC std_ss [CLOSURE_CLOSED, FRONTIER_CLOSED] THEN SET_TAC[]);
4756
4757val INTERIOR_FRONTIER = store_thm ("INTERIOR_FRONTIER",
4758 ``!s:real->bool.
4759    interior(frontier s) = interior(closure s) DIFF closure(interior s)``,
4760  ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s INTER (UNIV DIFF t)``] THEN
4761  REWRITE_TAC[GSYM INTERIOR_COMPLEMENT, GSYM INTERIOR_INTER, frontier] THEN
4762  GEN_TAC THEN AP_TERM_TAC THEN SET_TAC[]);
4763
4764val INTERIOR_FRONTIER_EMPTY = store_thm ("INTERIOR_FRONTIER_EMPTY",
4765 ``!s:real->bool. open s \/ closed s ==> (interior(frontier s) = {})``,
4766  REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[INTERIOR_FRONTIER] THEN
4767  ASM_SIMP_TAC std_ss [CLOSURE_CLOSED, INTERIOR_OPEN] THEN
4768  REWRITE_TAC[SET_RULE ``(s DIFF t = {}) <=> s SUBSET t``] THEN
4769  REWRITE_TAC[INTERIOR_SUBSET, CLOSURE_SUBSET]);
4770
4771val FRONTIER_FRONTIER = store_thm ("FRONTIER_FRONTIER",
4772 ``!s:real->bool. open s \/ closed s ==> (frontier(frontier s) = frontier s)``,
4773  GEN_TAC THEN GEN_REWR_TAC (RAND_CONV o LAND_CONV) [frontier] THEN STRIP_TAC THEN
4774  ASM_SIMP_TAC std_ss [INTERIOR_FRONTIER_EMPTY, CLOSURE_CLOSED, FRONTIER_CLOSED] THEN
4775  REWRITE_TAC[DIFF_EMPTY]);
4776
4777val FRONTIER_FRONTIER_FRONTIER = store_thm ("FRONTIER_FRONTIER_FRONTIER",
4778 ``!s:real->bool. frontier(frontier(frontier s)) = frontier(frontier s)``,
4779  SIMP_TAC std_ss [FRONTIER_FRONTIER, FRONTIER_CLOSED]);
4780
4781val lemma = prove (
4782 ``!s t x. x IN frontier s /\ x IN interior t ==> x IN frontier(s INTER t)``,
4783  REWRITE_TAC[FRONTIER_STRADDLE, IN_INTER, IN_INTERIOR, SUBSET_DEF, IN_BALL] THEN
4784  REPEAT GEN_TAC THEN
4785  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_TAC ``d:real``)) THEN
4786  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
4787  FIRST_X_ASSUM(MP_TAC o SPEC ``min d e:real``) THEN
4788  ASM_REWRITE_TAC[REAL_LT_MIN] THEN ASM_MESON_TAC[]);
4789
4790val UNION_FRONTIER = store_thm ("UNION_FRONTIER",
4791 ``!s t:real->bool. frontier(s) UNION frontier(t) =
4792   frontier(s UNION t) UNION frontier(s INTER t) UNION
4793   frontier(s) INTER frontier(t)``,
4794  REWRITE_TAC[SET_EQ_SUBSET, UNION_SUBSET,
4795   FRONTIER_UNION_SUBSET, FRONTIER_INTER_SUBSET,
4796   SET_RULE ``s INTER t SUBSET s UNION t``] THEN
4797  REWRITE_TAC[GSYM UNION_SUBSET] THEN REWRITE_TAC[SUBSET_DEF, IN_UNION] THEN
4798  KNOW_TAC ``((!s t x. x IN frontier s
4799      ==> x IN frontier (s UNION t) \/
4800          x IN frontier (s INTER t) \/
4801          x IN frontier s INTER frontier t) /\
4802 (!s t x.
4803      x IN frontier (s UNION t) \/
4804      x IN frontier (s INTER t) \/
4805      x IN frontier s INTER frontier t <=>
4806      x IN frontier (t UNION s) \/
4807      x IN frontier (t INTER s) \/
4808      x IN frontier t INTER frontier s))`` THENL
4809  [ALL_TAC, METIS_TAC []] THEN CONJ_TAC THENL
4810  [REPEAT STRIP_TAC, SIMP_TAC std_ss [UNION_COMM, INTER_COMM]] THEN
4811  ASM_CASES_TAC ``(x:real) IN frontier t`` THEN ASM_REWRITE_TAC[IN_INTER] THEN
4812  POP_ASSUM MP_TAC THEN GEN_REWR_TAC (LAND_CONV o RAND_CONV o RAND_CONV)
4813   [FRONTIER_INTERIORS] THEN
4814  REWRITE_TAC[DE_MORGAN_THM, IN_DIFF, IN_UNIV] THEN
4815  GEN_REWR_TAC RAND_CONV [DISJ_SYM] THEN MATCH_MP_TAC MONO_OR THEN
4816  ASM_SIMP_TAC std_ss [lemma] THEN
4817  POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT] THEN
4818  SIMP_TAC std_ss [lemma, SET_RULE
4819  ``UNIV DIFF (s UNION t) = (UNIV DIFF s) INTER (UNIV DIFF t)``]);
4820
4821val CONNECTED_INTER_FRONTIER = store_thm ("CONNECTED_INTER_FRONTIER",
4822 ``!s t:real->bool.
4823    connected s /\ ~(s INTER t = {}) /\ ~(s DIFF t = {})
4824    ==> ~(s INTER frontier t = {})``,
4825  REWRITE_TAC[FRONTIER_INTERIORS] THEN REPEAT STRIP_TAC THEN
4826  UNDISCH_TAC ``connected s`` THEN REWRITE_TAC [CONNECTED_OPEN_IN] THEN
4827  MAP_EVERY EXISTS_TAC
4828   [``s INTER interior t:real->bool``,
4829    ``s INTER (interior(univ(:real) DIFF t))``] THEN
4830  SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_INTERIOR] THEN
4831  MAP_EVERY (MP_TAC o C ISPEC INTERIOR_SUBSET)
4832   [``t:real->bool``, ``univ(:real) DIFF t``] THEN
4833  ASM_SET_TAC[]);
4834
4835val INTERIOR_CLOSED_EQ_EMPTY_AS_FRONTIER = store_thm ("INTERIOR_CLOSED_EQ_EMPTY_AS_FRONTIER",
4836 ``!s:real->bool. closed s /\ (interior s = {}) <=>
4837                ?t. open t /\ (s = frontier t)``,
4838  GEN_TAC THEN EQ_TAC THEN STRIP_TAC THENL
4839  [EXISTS_TAC ``univ(:real) DIFF s`` THEN
4840  ASM_SIMP_TAC std_ss [OPEN_DIFF, OPEN_UNIV, FRONTIER_COMPLEMENT] THEN
4841  ASM_SIMP_TAC std_ss [frontier, CLOSURE_CLOSED, DIFF_EMPTY],
4842  ASM_SIMP_TAC std_ss [FRONTIER_CLOSED, INTERIOR_FRONTIER_EMPTY]]);
4843
4844val FRONTIER_UNION = store_thm ("FRONTIER_UNION",
4845 ``!s t:real->bool. (closure s INTER closure t = {})
4846    ==> (frontier(s UNION t) = frontier(s) UNION frontier(t))``,
4847  REPEAT STRIP_TAC THEN
4848  MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[FRONTIER_UNION_SUBSET] THEN
4849  GEN_REWR_TAC RAND_CONV [frontier] THEN
4850  REWRITE_TAC[CLOSURE_UNION] THEN MATCH_MP_TAC(SET_RULE
4851  ``(fs SUBSET cs /\ ft SUBSET ct) /\ (k INTER fs = {}) /\ (k INTER ft = {})
4852    ==> (fs UNION ft) SUBSET (cs UNION ct) DIFF k``) THEN
4853  CONJ_TAC THENL [REWRITE_TAC[frontier] THEN SET_TAC[], ALL_TAC] THEN
4854  CONJ_TAC THENL [ALL_TAC,
4855   ONCE_REWRITE_TAC[UNION_COMM] THEN
4856   RULE_ASSUM_TAC(ONCE_REWRITE_RULE[INTER_COMM])] THEN
4857   FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
4858   ``(s INTER t = {}) ==> s' SUBSET s /\ (s' INTER u INTER (UNIV DIFF t) = {})
4859     ==> (u INTER s' = {})``)) THEN
4860  REWRITE_TAC[frontier, DIFF_SUBSET, GSYM INTERIOR_COMPLEMENT] THENL
4861  [KNOW_TAC ``(closure s DIFF interior s) INTER
4862                     interior (s UNION t) INTER
4863            interior (univ(:real) DIFF t) =
4864              (closure s DIFF interior s) INTER
4865           interior ((s UNION t) INTER (univ(:real) DIFF t))`` THENL
4866   [METIS_TAC [INTERIOR_INTER, INTER_ASSOC], ALL_TAC] THEN DISC_RW_KILL,
4867   KNOW_TAC ``(closure t DIFF interior t) INTER
4868                    interior (t UNION s) INTER
4869           interior (univ(:real) DIFF s) =
4870             (closure t DIFF interior t) INTER
4871           interior ((t UNION s) INTER (univ(:real) DIFF s))`` THENL
4872   [METIS_TAC [INTERIOR_INTER, INTER_ASSOC], ALL_TAC] THEN DISC_RW_KILL] THEN
4873  REWRITE_TAC[SET_RULE ``(s UNION t) INTER (UNIV DIFF t) = s DIFF t``] THEN
4874  MATCH_MP_TAC(SET_RULE
4875  ``ti SUBSET si ==> ((c DIFF si) INTER ti = {})``) THEN
4876  SIMP_TAC std_ss [SUBSET_INTERIOR, DIFF_SUBSET]);
4877
4878val CLOSURE_UNION_FRONTIER = store_thm ("CLOSURE_UNION_FRONTIER",
4879 ``!s:real->bool. closure s = s UNION frontier s``,
4880  GEN_TAC THEN REWRITE_TAC[frontier] THEN
4881  MP_TAC(ISPEC ``s:real->bool`` INTERIOR_SUBSET) THEN
4882  MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN
4883  SET_TAC[]);
4884
4885val FRONTIER_INTERIOR_SUBSET = store_thm ("FRONTIER_INTERIOR_SUBSET",
4886 ``!s:real->bool. frontier(interior s) SUBSET frontier s``,
4887  GEN_TAC THEN REWRITE_TAC[frontier, INTERIOR_INTERIOR] THEN
4888  MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> s DIFF u SUBSET t DIFF u``) THEN
4889  SIMP_TAC std_ss [SUBSET_CLOSURE, INTERIOR_SUBSET]);
4890
4891val FRONTIER_CLOSURE_SUBSET = store_thm ("FRONTIER_CLOSURE_SUBSET",
4892 ``!s:real->bool. frontier(closure s) SUBSET frontier s``,
4893  GEN_TAC THEN REWRITE_TAC[frontier, CLOSURE_CLOSURE] THEN
4894  MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> u DIFF t SUBSET u DIFF s``) THEN
4895  SIMP_TAC std_ss [SUBSET_INTERIOR, CLOSURE_SUBSET]);
4896
4897val SET_DIFF_FRONTIER = store_thm ("SET_DIFF_FRONTIER",
4898 ``!s:real->bool. s DIFF frontier s = interior s``,
4899  GEN_TAC THEN REWRITE_TAC[frontier] THEN
4900  MP_TAC(ISPEC ``s:real->bool`` INTERIOR_SUBSET) THEN
4901  MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN
4902  SET_TAC[]);
4903
4904val FRONTIER_INTER_SUBSET_INTER = store_thm ("FRONTIER_INTER_SUBSET_INTER",
4905 ``!s t:real->bool.
4906   frontier(s INTER t) SUBSET closure s INTER frontier t UNION
4907   frontier s INTER closure t``,
4908  REPEAT GEN_TAC THEN REWRITE_TAC[frontier, INTERIOR_INTER] THEN
4909  MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``]
4910   CLOSURE_INTER_SUBSET) THEN SET_TAC[]);
4911
4912(* ------------------------------------------------------------------------- *)
4913(* A variant of nets (slightly non-standard but good for our purposes).      *)
4914(* ------------------------------------------------------------------------- *)
4915
4916val isnet = new_definition("isnet",
4917 ``!g. isnet g = !x y. (!z. g z x ==> g z y) \/
4918                       (!z. g z y ==> g z x)``);
4919
4920val net_tydef = new_type_definition
4921 ("net",
4922  prove (``?(g:'a->'a->bool). isnet g``,
4923        EXISTS_TAC ``\x:'a y:'a. F`` THEN REWRITE_TAC[isnet]));
4924
4925val net_ty_bij = define_new_type_bijections
4926    {name="net_tybij",
4927     ABS="mk_net", REP="netord",tyax=net_tydef};
4928
4929val net_tybij = store_thm ("net_tybij",
4930  ``(!a. mk_net (netord a) = a) /\
4931    (!r. (!x y. (!z. r z x ==> r z y) \/ (!z. r z y ==> r z x)) <=>
4932          (netord (mk_net r) = r))``,
4933  SIMP_TAC std_ss [net_ty_bij, GSYM isnet]);
4934
4935val NET = store_thm ("NET",
4936 ``!n x y. (!z. netord n z x ==> netord n z y) \/
4937           (!z. netord n z y ==> netord n z x)``,
4938   REWRITE_TAC[net_tybij, ETA_AX]);
4939
4940val OLDNET = store_thm ("OLDNET",
4941 ``!n x y. netord n x x /\ netord n y y
4942           ==> ?z. netord n z z /\
4943                   !w. netord n w z ==> netord n w x /\ netord n w y``,
4944  MESON_TAC[NET]);
4945
4946val NET_DILEMMA = store_thm ("NET_DILEMMA",
4947 ``!net. (?a. (?x. netord net x a) /\ (!x. netord net x a ==> P x)) /\
4948         (?b. (?x. netord net x b) /\ (!x. netord net x b ==> Q x))
4949         ==> ?c. (?x. netord net x c) /\ (!x. netord net x c ==> P x /\ Q x)``,
4950  MESON_TAC[NET]);
4951
4952(* ------------------------------------------------------------------------- *)
4953(* Common nets and the "within" modifier for nets.                           *)
4954(* ------------------------------------------------------------------------- *)
4955
4956val _ = set_fixity "within" (Infix(NONASSOC, 450));
4957val _ = set_fixity "in_direction" (Infix(NONASSOC, 450));
4958
4959val at = new_definition ("at",
4960  ``at a = mk_net(\x y. &0 < dist(x,a) /\ dist(x,a) <= dist(y,a))``);
4961
4962val at_infinity = new_definition ("at_infinity",
4963  ``at_infinity = mk_net(\x y. abs(x) >= abs(y))``);
4964
4965val at_posinfinity = new_definition ("at_posinfinity",
4966  ``at_posinfinity = mk_net(\x y:real. x >= y)``);
4967
4968val at_neginfinity = new_definition ("at_neginfinity",
4969  ``at_neginfinity = mk_net(\x y:real. x <= y)``);
4970
4971val sequentially = new_definition ("sequentially",
4972  ``sequentially = mk_net(\m:num n. m >= n)``);
4973
4974val within = new_definition ("within",
4975  ``(net within s) = mk_net(\x y. netord net x y /\ x IN s)``);
4976
4977val in_direction = new_definition ("in_direction",
4978  ``(a in_direction v) = ((at a) within {b | ?c. &0 <= c /\ (b - a = c * v)})``);
4979
4980(* ------------------------------------------------------------------------- *)
4981(* Prove that they are all nets.                                             *)
4982(* ------------------------------------------------------------------------- *)
4983
4984fun NET_PROVE_TAC [def] =
4985  SIMP_TAC std_ss [GSYM FUN_EQ_THM, def] THEN
4986  REWRITE_TAC [ETA_AX] THEN
4987  ASM_SIMP_TAC std_ss [GSYM(CONJUNCT2 net_tybij)];
4988
4989val AT = store_thm ("AT",
4990 ``!a:real x y.
4991        netord(at a) x y <=> &0 < dist(x,a) /\ dist(x,a) <= dist(y,a)``,
4992  GEN_TAC THEN NET_PROVE_TAC[at] THEN
4993  METIS_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS, REAL_LET_TRANS]);
4994
4995val AT_INFINITY = store_thm ("AT_INFINITY",
4996 ``!x y. netord at_infinity x y <=> abs(x) >= abs(y)``,
4997  NET_PROVE_TAC[at_infinity] THEN
4998  REWRITE_TAC[real_ge, REAL_LE_REFL] THEN
4999  MESON_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS]);
5000
5001val AT_POSINFINITY = store_thm ("AT_POSINFINITY",
5002 ``!x y. netord at_posinfinity x y <=> x >= y``,
5003  NET_PROVE_TAC[at_posinfinity] THEN
5004  REWRITE_TAC[real_ge, REAL_LE_REFL] THEN
5005  MESON_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS]);
5006
5007val AT_NEGINFINITY = store_thm ("AT_NEGINFINITY",
5008 ``!x y. netord at_neginfinity x y <=> x <= y``,
5009  NET_PROVE_TAC[at_neginfinity] THEN
5010  REWRITE_TAC[real_ge, REAL_LE_REFL] THEN
5011  MESON_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS]);
5012
5013val SEQUENTIALLY = store_thm ("SEQUENTIALLY",
5014 ``!m n. netord sequentially m n <=> m >= n``,
5015  NET_PROVE_TAC[sequentially] THEN REWRITE_TAC[GREATER_EQ, LESS_EQ_REFL] THEN
5016  MESON_TAC[LESS_EQ_CASES, LESS_EQ_REFL, LESS_EQ_TRANS]);
5017
5018val WITHIN = store_thm ("WITHIN",
5019 ``!n s x y. netord(n within s) x y <=> netord n x y /\ x IN s``,
5020  GEN_TAC THEN GEN_TAC THEN SIMP_TAC std_ss [within, GSYM FUN_EQ_THM] THEN
5021  REWRITE_TAC[GSYM(CONJUNCT2 net_tybij), ETA_AX] THEN
5022  METIS_TAC[NET]);
5023
5024val IN_DIRECTION = store_thm ("IN_DIRECTION",
5025 ``!a v x y. netord(a in_direction v) x y <=>
5026                &0 < dist(x,a) /\ dist(x,a) <= dist(y,a) /\
5027                 ?c. &0 <= c /\ (x - a = c * v)``,
5028  SIMP_TAC std_ss [WITHIN, AT, in_direction, GSPECIFICATION] THEN METIS_TAC []);
5029
5030val WITHIN_UNIV = store_thm ("WITHIN_UNIV",
5031 ``!x:real. (at x within UNIV) = at x``,
5032  REWRITE_TAC[within, at, IN_UNIV] THEN REWRITE_TAC[ETA_AX, net_tybij]);
5033
5034val WITHIN_WITHIN = store_thm ("WITHIN_WITHIN",
5035 ``!net s t. ((net within s) within t) = (net within (s INTER t))``,
5036  ONCE_REWRITE_TAC[within] THEN
5037  REWRITE_TAC[WITHIN, IN_INTER, GSYM CONJ_ASSOC]);
5038
5039(* ------------------------------------------------------------------------- *)
5040(* Identify trivial limits, where we can't approach arbitrarily closely.     *)
5041(* ------------------------------------------------------------------------- *)
5042
5043val trivial_limit = new_definition ("trivial_limit",
5044  ``trivial_limit net <=>
5045     (!a:'a b. a = b) \/
5046     ?a:'a b. ~(a = b) /\ !x. ~(netord(net) x a) /\ ~(netord(net) x b)``);
5047
5048val TRIVIAL_LIMIT_WITHIN = store_thm ("TRIVIAL_LIMIT_WITHIN",
5049 ``!a:real. trivial_limit (at a within s) <=> ~(a limit_point_of s)``,
5050  REWRITE_TAC[trivial_limit, LIMPT_APPROACHABLE_LE, WITHIN, AT, DIST_NZ] THEN
5051  REPEAT GEN_TAC THEN EQ_TAC THENL
5052   [DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL
5053     [MESON_TAC[REAL_LT_01, REAL_LT_REFL, REAL_CHOOSE_DIST,
5054                DIST_REFL, REAL_LT_IMP_LE],
5055      DISCH_THEN(X_CHOOSE_THEN ``b:real`` (X_CHOOSE_THEN ``c:real``
5056        STRIP_ASSUME_TAC)) THEN
5057      SUBGOAL_THEN ``&0 < dist(a,b:real) \/ &0 < dist(a,c:real)`` MP_TAC THEN
5058      ASM_MESON_TAC[DIST_TRIANGLE, DIST_SYM, GSYM DIST_NZ, GSYM DIST_EQ_0,
5059                    REAL_ARITH ``x:real <= &0 + &0 ==> ~(&0 < x)``]],
5060    KNOW_TAC ``!e. (0 < e ==> ?x'. x' IN s /\ 0 < dist (x',a) /\ dist (x',a) <= e) =
5061           (\e. 0 < e ==> ?x'. x' IN s /\ 0 < dist (x',a) /\ dist (x',a) <= e) e`` THENL
5062    [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
5063    REWRITE_TAC[NOT_FORALL_THM] THEN BETA_TAC THEN REWRITE_TAC [NOT_IMP] THEN
5064    SIMP_TAC std_ss [GSYM LEFT_EXISTS_IMP_THM] THEN
5065    STRIP_TAC THEN DISJ2_TAC THEN
5066    EXISTS_TAC ``a:real`` THEN
5067    SUBGOAL_THEN ``?b:real. dist(a,b) = x`` MP_TAC THENL
5068     [ASM_SIMP_TAC std_ss [REAL_CHOOSE_DIST, REAL_LT_IMP_LE], ALL_TAC] THEN
5069    STRIP_TAC THEN EXISTS_TAC ``b:real`` THEN POP_ASSUM MP_TAC THEN
5070    DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
5071    ASM_MESON_TAC[REAL_NOT_LE, DIST_REFL, DIST_NZ, DIST_SYM]]);
5072
5073val TRIVIAL_LIMIT_AT = store_thm ("TRIVIAL_LIMIT_AT",
5074 ``!a. ~(trivial_limit (at a))``,
5075  ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
5076  REWRITE_TAC[TRIVIAL_LIMIT_WITHIN, LIMPT_UNIV]);
5077
5078val TRIVIAL_LIMIT_AT_INFINITY = store_thm ("TRIVIAL_LIMIT_AT_INFINITY",
5079 ``~(trivial_limit at_infinity)``,
5080  REWRITE_TAC[trivial_limit, AT_INFINITY, real_ge] THEN
5081  MESON_TAC[REAL_LE_REFL, REAL_CHOOSE_SIZE, REAL_LT_01, REAL_LT_LE]);
5082
5083val TRIVIAL_LIMIT_AT_POSINFINITY = store_thm ("TRIVIAL_LIMIT_AT_POSINFINITY",
5084 ``~(trivial_limit at_posinfinity)``,
5085  REWRITE_TAC[trivial_limit, AT_POSINFINITY, DE_MORGAN_THM] THEN
5086  CONJ_TAC THENL
5087   [DISCH_THEN(MP_TAC o SPECL [``&0:real``, ``&1:real``]) THEN REAL_ARITH_TAC, ALL_TAC] THEN
5088  REWRITE_TAC[DE_MORGAN_THM, NOT_EXISTS_THM, real_ge, REAL_NOT_LE] THEN
5089  MESON_TAC[REAL_LT_TOTAL, REAL_LT_ANTISYM]);
5090
5091val TRIVIAL_LIMIT_AT_NEGINFINITY = store_thm ("TRIVIAL_LIMIT_AT_NEGINFINITY",
5092 ``~(trivial_limit at_neginfinity)``,
5093  REWRITE_TAC[trivial_limit, AT_NEGINFINITY, DE_MORGAN_THM] THEN
5094  CONJ_TAC THENL
5095   [DISCH_THEN(MP_TAC o SPECL [``&0:real``, ``&1:real``]) THEN REAL_ARITH_TAC, ALL_TAC] THEN
5096  REWRITE_TAC[DE_MORGAN_THM, NOT_EXISTS_THM, real_ge, REAL_NOT_LE] THEN
5097  MESON_TAC[REAL_LT_TOTAL, REAL_LT_ANTISYM]);
5098
5099val TRIVIAL_LIMIT_SEQUENTIALLY = store_thm ("TRIVIAL_LIMIT_SEQUENTIALLY",
5100 ``~(trivial_limit sequentially)``,
5101  REWRITE_TAC[trivial_limit, SEQUENTIALLY] THEN
5102  MESON_TAC[GREATER_EQ, LESS_EQ_REFL, SUC_NOT]);
5103
5104val LIM_WITHIN_CLOSED_TRIVIAL = store_thm ("LIM_WITHIN_CLOSED_TRIVIAL",
5105 ``!a s. closed s /\ ~(a IN s) ==> trivial_limit (at a within s)``,
5106  REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN MESON_TAC[CLOSED_LIMPT]);
5107
5108val NONTRIVIAL_LIMIT_WITHIN = store_thm ("NONTRIVIAL_LIMIT_WITHIN",
5109 ``!net s. trivial_limit net ==> trivial_limit(net within s)``,
5110  REWRITE_TAC[trivial_limit, WITHIN] THEN MESON_TAC[]);
5111
5112(* ------------------------------------------------------------------------- *)
5113(* Some property holds "sufficiently close" to the limit point.              *)
5114(* ------------------------------------------------------------------------- *)
5115
5116val eventually = new_definition ("eventually",
5117 ``eventually p net <=>
5118        trivial_limit net \/
5119        ?y. (?x. netord net x y) /\ (!x. netord net x y ==> p x)``);
5120
5121val EVENTUALLY_HAPPENS = store_thm ("EVENTUALLY_HAPPENS",
5122 ``!net p. eventually p net ==> trivial_limit net \/ ?x. p x``,
5123  REWRITE_TAC[eventually] THEN MESON_TAC[]);
5124
5125val EVENTUALLY_WITHIN_LE = store_thm ("EVENTUALLY_WITHIN_LE",
5126 ``!s a:real p.
5127     eventually p (at a within s) <=>
5128        ?d. &0 < d /\ !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d ==> p(x)``,
5129  REWRITE_TAC[eventually, AT, WITHIN, TRIVIAL_LIMIT_WITHIN] THEN
5130  REWRITE_TAC[LIMPT_APPROACHABLE_LE, DIST_NZ] THEN
5131  REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[REAL_LTE_TRANS], ALL_TAC] THEN
5132  DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
5133  MATCH_MP_TAC(TAUT `(a ==> b) ==> ~a \/ b`) THEN DISCH_TAC THEN
5134  SUBGOAL_THEN ``?b:real. dist(a,b) = d`` MP_TAC THENL
5135   [ASM_SIMP_TAC std_ss [REAL_CHOOSE_DIST, REAL_LT_IMP_LE], ALL_TAC] THEN
5136  STRIP_TAC THEN EXISTS_TAC ``b:real`` THEN POP_ASSUM MP_TAC THEN
5137  DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
5138  ASM_MESON_TAC[REAL_NOT_LE, DIST_REFL, DIST_NZ, DIST_SYM]);
5139
5140val EVENTUALLY_WITHIN = store_thm ("EVENTUALLY_WITHIN",
5141 ``!s a:real p.
5142     eventually p (at a within s) <=>
5143        ?d. &0 < d /\ !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d ==> p(x)``,
5144  REWRITE_TAC[EVENTUALLY_WITHIN_LE] THEN
5145  ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] THEN
5146  SIMP_TAC std_ss [APPROACHABLE_LT_LE]);
5147
5148val EVENTUALLY_AT = store_thm ("EVENTUALLY_AT",
5149 ``!a p. eventually p (at a) <=>
5150         ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d ==> p(x)``,
5151  ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
5152  REWRITE_TAC[EVENTUALLY_WITHIN, IN_UNIV]);
5153
5154val EVENTUALLY_SEQUENTIALLY = store_thm ("EVENTUALLY_SEQUENTIALLY",
5155 ``!p. eventually p sequentially <=> ?N. !n. N <= n ==> p n``,
5156  REWRITE_TAC[eventually, SEQUENTIALLY, GREATER_EQ, LESS_EQ_REFL,
5157    TRIVIAL_LIMIT_SEQUENTIALLY] THEN  MESON_TAC[LESS_EQ_REFL]);
5158
5159val EVENTUALLY_AT_INFINITY = store_thm ("EVENTUALLY_AT_INFINITY",
5160 ``!p. eventually p at_infinity <=> ?b. !x. abs(x) >= b ==> p x``,
5161  SIMP_TAC std_ss [eventually, AT_INFINITY, TRIVIAL_LIMIT_AT_INFINITY] THEN
5162  REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[REAL_LE_REFL], ALL_TAC] THEN
5163  MESON_TAC[real_ge, REAL_LE_REFL, REAL_CHOOSE_SIZE,
5164    REAL_ARITH ``&0 <= b:real \/ (!x. x >= &0 ==> x >= b)``]);
5165
5166val EVENTUALLY_AT_POSINFINITY = store_thm ("EVENTUALLY_AT_POSINFINITY",
5167 ``!p. eventually p at_posinfinity <=> ?b. !x. x >= b ==> p x``,
5168  REWRITE_TAC[eventually, TRIVIAL_LIMIT_AT_POSINFINITY, AT_POSINFINITY] THEN
5169  MESON_TAC[REAL_ARITH ``x >= x``]);
5170
5171val EVENTUALLY_AT_NEGINFINITY = store_thm ("EVENTUALLY_AT_NEGINFINITY",
5172 ``!p. eventually p at_neginfinity <=> ?b. !x. x <= b ==> p x``,
5173  REWRITE_TAC[eventually, TRIVIAL_LIMIT_AT_NEGINFINITY, AT_NEGINFINITY] THEN
5174  MESON_TAC[REAL_LE_REFL]);
5175
5176val EVENTUALLY_AT_INFINITY_POS = store_thm ("EVENTUALLY_AT_INFINITY_POS",
5177 ``!p:real->bool.
5178        eventually p at_infinity <=> ?b. &0 < b /\ !x. abs x >= b ==> p x``,
5179  GEN_TAC THEN REWRITE_TAC[EVENTUALLY_AT_INFINITY, real_ge] THEN
5180  MESON_TAC[REAL_ARITH ``&0 < abs b + &1 /\ (abs b + &1 <= x ==> b <= x:real)``]);
5181
5182val ALWAYS_EVENTUALLY = store_thm ("ALWAYS_EVENTUALLY",
5183 ``(!x. p x) ==> eventually p net``,
5184  REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[eventually, trivial_limit] THEN
5185  MESON_TAC[]);
5186
5187(* ------------------------------------------------------------------------- *)
5188(* Combining theorems for "eventually". *)
5189(* ------------------------------------------------------------------------- *)
5190
5191val EVENTUALLY_AND = store_thm ("EVENTUALLY_AND",
5192 ``!net:('a net) p q.
5193   eventually (\x. p x /\ q x) net <=>
5194   eventually p net /\ eventually q net``,
5195  REPEAT GEN_TAC THEN REWRITE_TAC[eventually] THEN
5196  ASM_CASES_TAC ``trivial_limit(net:('a net))`` THEN ASM_REWRITE_TAC[] THEN
5197  EQ_TAC THEN SIMP_TAC std_ss [NET_DILEMMA] THENL [MESON_TAC [], ALL_TAC] THEN
5198  DISCH_TAC THEN MATCH_MP_TAC NET_DILEMMA THEN METIS_TAC []);
5199
5200val EVENTUALLY_MONO = store_thm ("EVENTUALLY_MONO",
5201 ``!net:('a net) p q.
5202  (!x. p x ==> q x) /\ eventually p net
5203    ==> eventually q net``,
5204  REWRITE_TAC[eventually] THEN MESON_TAC[]);
5205
5206val EVENTUALLY_MP = store_thm ("EVENTUALLY_MP",
5207 ``!net:('a net) p q.
5208  eventually (\x. p x ==> q x) net /\ eventually p net
5209  ==> eventually q net``,
5210  REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
5211  REWRITE_TAC[eventually] THEN MESON_TAC[]);
5212
5213val EVENTUALLY_FALSE = store_thm ("EVENTUALLY_FALSE",
5214 ``!net. eventually (\x. F) net <=> trivial_limit net``,
5215  REWRITE_TAC[eventually] THEN MESON_TAC[]);
5216
5217val EVENTUALLY_TRUE = store_thm ("EVENTUALLY_TRUE",
5218 ``!net. eventually (\x. T) net <=> T``,
5219  REWRITE_TAC[eventually, trivial_limit] THEN MESON_TAC[]);
5220
5221val NOT_EVENTUALLY = store_thm ("NOT_EVENTUALLY",
5222 ``!net p. (!x. ~(p x)) /\ ~(trivial_limit net) ==> ~(eventually p net)``,
5223  REWRITE_TAC[eventually] THEN MESON_TAC[]);
5224
5225val EVENTUALLY_FORALL = store_thm ("EVENTUALLY_FORALL",
5226 ``!net:('a net) p s:'b->bool.
5227  FINITE s /\ ~(s = {})
5228  ==> (eventually (\x. !a. a IN s ==> p a x) net <=>
5229   !a. a IN s ==> eventually (p a) net)``,
5230  GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN
5231  KNOW_TAC ``!s:'b->bool. (s <> ({} :'b -> bool) ==>
5232   (eventually (\(x :'a). !(a :'b). a IN s ==> (p :'b -> 'a -> bool) a x)
5233   (net :'a net) <=> !(a :'b). a IN s ==> eventually (p a) net)) =
5234             (\s. s <> ({} :'b -> bool) ==>
5235   (eventually (\(x :'a). !(a :'b). a IN s ==> (p :'b -> 'a -> bool) a x)
5236   (net :'a net) <=> !(a :'b). a IN s ==> eventually (p a) net)) s`` THENL
5237  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
5238  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
5239  SIMP_TAC std_ss [FORALL_IN_INSERT, EVENTUALLY_AND, ETA_AX] THEN
5240  SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN
5241  MAP_EVERY X_GEN_TAC [``t:'b->bool``, ``b:'b``] THEN
5242  ASM_CASES_TAC ``t:'b->bool = {}`` THEN
5243  ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, EVENTUALLY_TRUE] THEN METIS_TAC []);
5244
5245val FORALL_EVENTUALLY = store_thm ("FORALL_EVENTUALLY",
5246 ``!net:('a net) p s:'b->bool.
5247   FINITE s /\ ~(s = {})
5248   ==> ((!a. a IN s ==> eventually (p a) net) <=>
5249   eventually (\x. !a. a IN s ==> p a x) net)``,
5250  SIMP_TAC std_ss [EVENTUALLY_FORALL]);
5251
5252(* ------------------------------------------------------------------------- *)
5253(* Limits, defined as vacuously true when the limit is trivial.              *)
5254(* ------------------------------------------------------------------------- *)
5255
5256val _ = hide "-->";
5257
5258val tendsto = new_infixr_definition("tendsto",
5259  ``$--> f l net = !e. &0 < e ==> eventually (\x. dist(f(x),l) < e) net``,750);
5260
5261(* LONG RIGHTWARDS ARROW *)
5262val _ = Unicode.unicode_version {u = UTF8.chr 0x27F6, tmnm = "-->"};
5263val _ = TeX_notation {hol = UTF8.chr 0x27F6, TeX = ("\\HOLTokenLongmap{}", 1)};
5264val _ = TeX_notation {hol = "-->",           TeX = ("\\HOLTokenLongmap{}", 1)};
5265
5266val lim_def = new_definition ("lim_def",
5267 ``lim_def net f = @l. (f --> l) net``);
5268
5269val _ = overload_on ("lim",``lim_def``);
5270
5271val LIM = store_thm ("LIM",
5272 ``(f --> l) net <=>
5273        trivial_limit net \/
5274        !e. &0 < e ==> ?y. (?x. netord(net) x y) /\
5275                           !x. netord(net) x y ==> dist(f(x),l) < e``,
5276  REWRITE_TAC[tendsto, eventually] THEN MESON_TAC[]);
5277
5278(* ------------------------------------------------------------------------- *)
5279(* Show that they yield usual definitions in the various cases.              *)
5280(* ------------------------------------------------------------------------- *)
5281
5282val LIM_WITHIN_LE = store_thm ("LIM_WITHIN_LE",
5283 ``!f:real->real l a s.
5284        (f --> l)(at a within s) <=>
5285           !e. &0 < e ==> ?d. &0 < d /\
5286                              !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d
5287                                   ==> dist(f(x),l) < e``,
5288  SIMP_TAC std_ss [tendsto, EVENTUALLY_WITHIN_LE]);
5289
5290val LIM_WITHIN = store_thm ("LIM_WITHIN",
5291 ``!f:real->real l a s.
5292      (f --> l) (at a within s) <=>
5293        !e. &0 < e
5294            ==> ?d. &0 < d /\
5295                    !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d
5296                    ==> dist(f(x),l) < e``,
5297  SIMP_TAC std_ss [tendsto, EVENTUALLY_WITHIN] THEN MESON_TAC[]);
5298
5299val LIM_AT_LE = store_thm ("LIM_AT_LE",
5300 ``!f l a. (f --> l) (at a) <=>
5301           !e. &0 < e
5302               ==> ?d. &0 < d /\
5303                       !x. &0 < dist(x,a) /\ dist(x,a) <= d
5304                           ==> dist (f x,l) < e``,
5305  ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
5306  REWRITE_TAC[LIM_WITHIN_LE, IN_UNIV]);
5307
5308val LIM_AT = store_thm ("LIM_AT",
5309 ``!f l:real a:real.
5310      (f --> l) (at a) <=>
5311              !e. &0 < e
5312                  ==> ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d
5313                          ==> dist(f(x),l) < e``,
5314  REWRITE_TAC[tendsto, EVENTUALLY_AT] THEN MESON_TAC[]);
5315
5316val LIM_AT_INFINITY = store_thm ("LIM_AT_INFINITY",
5317 ``!f l. (f --> l) at_infinity <=>
5318               !e. &0 < e ==> ?b. !x. abs(x) >= b ==> dist(f(x),l) < e``,
5319  SIMP_TAC std_ss [tendsto, EVENTUALLY_AT_INFINITY] THEN MESON_TAC[]);
5320
5321val LIM_AT_INFINITY_POS = store_thm ("LIM_AT_INFINITY_POS",
5322 ``!f l. (f --> l) at_infinity <=>
5323         !e. &0 < e ==> ?b. &0 < b /\ !x. abs x >= b ==> dist(f x,l) < e``,
5324  REPEAT GEN_TAC THEN SIMP_TAC std_ss [LIM_AT_INFINITY] THEN
5325  METIS_TAC[REAL_ARITH ``&0 < abs b + &1 /\ (x >= abs b + &1 ==> x >= b)``]);
5326
5327val LIM_AT_POSINFINITY = store_thm ("LIM_AT_POSINFINITY",
5328 ``!f l. (f --> l) at_posinfinity <=>
5329               !e. &0 < e ==> ?b. !x. x >= b ==> dist(f(x),l) < e``,
5330  REWRITE_TAC[tendsto, EVENTUALLY_AT_POSINFINITY] THEN MESON_TAC[]);
5331
5332val LIM_AT_NEGINFINITY = store_thm ("LIM_AT_NEGINFINITY",
5333 ``!f l. (f --> l) at_neginfinity <=>
5334               !e. &0 < e ==> ?b. !x. x <= b ==> dist(f(x),l) < e``,
5335  REWRITE_TAC[tendsto, EVENTUALLY_AT_NEGINFINITY] THEN MESON_TAC[]);
5336
5337val LIM_SEQUENTIALLY = store_thm ("LIM_SEQUENTIALLY",
5338 ``!s l. (s --> l) sequentially <=>
5339          !e. &0 < e ==> ?N. !n. N <= n ==> dist(s(n),l) < e``,
5340  REWRITE_TAC[tendsto, EVENTUALLY_SEQUENTIALLY] THEN MESON_TAC[]);
5341
5342val LIM_EVENTUALLY = store_thm ("LIM_EVENTUALLY",
5343 ``!net f l. eventually (\x. f x = l) net ==> (f --> l) net``,
5344  REWRITE_TAC[eventually, LIM] THEN MESON_TAC[DIST_REFL]);
5345
5346val LIM_POSINFINITY_SEQUENTIALLY = store_thm ("LIM_POSINFINITY_SEQUENTIALLY",
5347 ``!f l. (f --> l) at_posinfinity ==> ((\n. f(&n)) --> l) sequentially``,
5348  REPEAT GEN_TAC THEN
5349  REWRITE_TAC[LIM_AT_POSINFINITY, LIM_SEQUENTIALLY] THEN
5350  DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
5351  FIRST_X_ASSUM(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN
5352  DISCH_THEN(X_CHOOSE_TAC ``B:real``) THEN
5353  MP_TAC(ISPEC ``B:real`` SIMP_REAL_ARCH) THEN
5354  DISCH_THEN(X_CHOOSE_THEN ``N:num`` STRIP_ASSUME_TAC) THEN
5355  EXISTS_TAC ``N:num`` THEN POP_ASSUM MP_TAC THEN
5356  REPEAT STRIP_TAC THEN BETA_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
5357  RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN
5358  METIS_TAC [real_ge, REAL_LE_TRANS]);
5359
5360val LIM_INFINITY_POSINFINITY = store_thm ("LIM_INFINITY_POSINFINITY",
5361 ``!f l:real. (f --> l) at_infinity ==> (f --> l) at_posinfinity``,
5362  SIMP_TAC std_ss [LIM_AT_INFINITY, LIM_AT_POSINFINITY, o_THM] THEN
5363  METIS_TAC[dist, REAL_ARITH ``x >= b ==> abs(x) >= b:real``]);
5364
5365(* ------------------------------------------------------------------------- *)
5366(* The expected monotonicity property.                                       *)
5367(* ------------------------------------------------------------------------- *)
5368
5369val LIM_WITHIN_EMPTY = store_thm ("LIM_WITHIN_EMPTY",
5370 ``!f l x. (f --> l) (at x within {})``,
5371  REWRITE_TAC[LIM_WITHIN, NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]);
5372
5373val LIM_WITHIN_SUBSET = store_thm ("LIM_WITHIN_SUBSET",
5374 ``!f l a s.
5375    (f --> l) (at a within s) /\ t SUBSET s ==> (f --> l) (at a within t)``,
5376  REWRITE_TAC[LIM_WITHIN, SUBSET_DEF] THEN MESON_TAC[]);
5377
5378val LIM_UNION = store_thm ("LIM_UNION",
5379 ``!f x l s t.
5380        (f --> l) (at x within s) /\ (f --> l) (at x within t)
5381        ==> (f --> l) (at x within (s UNION t))``,
5382  REPEAT GEN_TAC THEN REWRITE_TAC[LIM_WITHIN, IN_UNION] THEN
5383  SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN STRIP_TAC THEN
5384  X_GEN_TAC ``e:real`` THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN
5385  ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [] THEN
5386  DISCH_THEN(CONJUNCTS_THEN2
5387   (X_CHOOSE_TAC ``d1:real``) (X_CHOOSE_TAC ``d2:real``)) THEN
5388  EXISTS_TAC ``min d1 d2:real`` THEN ASM_MESON_TAC[REAL_LT_MIN]);
5389
5390val LIM_UNION_UNIV = store_thm ("LIM_UNION_UNIV",
5391 ``!f x l s t.
5392        (f --> l) (at x within s) /\ (f --> l) (at x within t) /\
5393        (s UNION t = univ(:real)) ==> (f --> l) (at x)``,
5394  MESON_TAC[LIM_UNION, WITHIN_UNIV]);
5395
5396(* ------------------------------------------------------------------------- *)
5397(* Composition of limits.                                                    *)
5398(* ------------------------------------------------------------------------- *)
5399
5400val LIM_COMPOSE_WITHIN = store_thm ("LIM_COMPOSE_WITHIN",
5401 ``!net f:'a->real g:real->real s y z.
5402    (f --> y) net /\
5403    eventually (\w. f w IN s /\ ((f w = y) ==> (g y = z))) net /\
5404    (g --> z) (at y within s)
5405    ==> ((g o f) --> z) net``,
5406  REPEAT GEN_TAC THEN REWRITE_TAC[tendsto, CONJ_ASSOC] THEN
5407  KNOW_TAC ``(!e. (&0 < e ==> eventually (\x. dist ((f:'a->real) x,y) < e) net) /\
5408             eventually (\w. f w IN s /\ ((f w = y) ==> ((g:real->real) y = z))) net) /\
5409   (!e. &0 < e ==> eventually (\x. dist (g x,z) < e) (at y within s))
5410   ==> (!e. &0 < e ==> eventually (\x. dist ((g o f) x,z) < e) net)`` THENL
5411  [ALL_TAC, SIMP_TAC std_ss [LEFT_AND_FORALL_THM]] THEN
5412  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5413  STRIP_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN
5414  ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[] THEN
5415  REWRITE_TAC[EVENTUALLY_WITHIN, GSYM DIST_NZ, o_DEF] THEN
5416  DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
5417  UNDISCH_TAC ``!e. (0 < e ==> eventually (\x. dist (f x,y) < e) net) /\
5418        eventually (\w. f w IN s /\ ((f:'a->real w = y) ==> (g:real->real y = z))) net`` THEN
5419  DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``d:real``) THEN
5420  ASM_REWRITE_TAC[GSYM EVENTUALLY_AND] THEN BETA_TAC THEN
5421  MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN
5422  ASM_MESON_TAC[DIST_REFL]);
5423
5424val LIM_COMPOSE_AT = store_thm ("LIM_COMPOSE_AT",
5425 ``!net f:'a->real g:real->real y z.
5426    (f --> y) net /\
5427    eventually (\w. (f w = y) ==> (g y = z)) net /\
5428    (g --> z) (at y)
5429    ==> ((g o f) --> z) net``,
5430  REPEAT STRIP_TAC THEN
5431  MP_TAC(ISPECL [``net:('a)net``, ``f:'a->real``, ``g:real->real``,
5432                 ``univ(:real)``, ``y:real``, ``z:real``]
5433        LIM_COMPOSE_WITHIN) THEN
5434  ASM_REWRITE_TAC[IN_UNIV, WITHIN_UNIV]);
5435
5436(* ------------------------------------------------------------------------- *)
5437(* Interrelations between restricted and unrestricted limits.                *)
5438(* ------------------------------------------------------------------------- *)
5439
5440val LIM_AT_WITHIN = store_thm ("LIM_AT_WITHIN",
5441 ``!f l a s. (f --> l)(at a) ==> (f --> l)(at a within s)``,
5442  REWRITE_TAC[LIM_AT, LIM_WITHIN] THEN MESON_TAC[]);
5443
5444val LIM_WITHIN_OPEN = store_thm ("LIM_WITHIN_OPEN",
5445 ``!f l a:real s.
5446     a IN s /\ open s ==> ((f --> l)(at a within s) <=> (f --> l)(at a))``,
5447  REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [LIM_AT_WITHIN] THEN
5448  REWRITE_TAC[LIM_AT, LIM_WITHIN] THEN
5449  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN
5450  ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[] THEN
5451   DISCH_THEN(X_CHOOSE_THEN ``d1:real`` STRIP_ASSUME_TAC) THEN
5452  UNDISCH_TAC ``open s`` THEN GEN_REWR_TAC LAND_CONV [open_def] THEN
5453  DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``a:real``) THEN
5454  ASM_REWRITE_TAC[] THEN
5455  DISCH_THEN(X_CHOOSE_THEN ``d2:real`` STRIP_ASSUME_TAC) THEN
5456  MP_TAC(SPECL [``d1:real``, ``d2:real``] REAL_DOWN2) THEN ASM_REWRITE_TAC[] THEN
5457  ASM_MESON_TAC[REAL_LT_TRANS]);
5458
5459(* ------------------------------------------------------------------------- *)
5460(* Segment of natural numbers starting at a specific number.                 *)
5461(* ------------------------------------------------------------------------- *)
5462
5463val from_def = Define
5464   `from n = {m:num | n <= m}`;
5465
5466val FROM_0 = store_thm ("FROM_0",
5467  ``from 0 = univ(:num)``,
5468    REWRITE_TAC [from_def, ZERO_LESS_EQ, GSPEC_T]);
5469
5470val IN_FROM = store_thm ("IN_FROM",
5471  ``!m n. m IN from n <=> n <= m``,
5472    SIMP_TAC std_ss [from_def, GSPECIFICATION]);
5473
5474val DISJOINT_COUNT_FROM = store_thm
5475  ("DISJOINT_COUNT_FROM", ``!n. DISJOINT (count n) (from n)``,
5476    RW_TAC arith_ss [from_def, count_def, DISJOINT_DEF, Once EXTENSION, NOT_IN_EMPTY,
5477                     GSPECIFICATION, IN_INTER]);
5478
5479val DISJOINT_FROM_COUNT = store_thm
5480  ("DISJOINT_FROM_COUNT", ``!n. DISJOINT (from n) (count n)``,
5481    RW_TAC std_ss [Once DISJOINT_SYM, DISJOINT_COUNT_FROM]);
5482
5483val UNION_COUNT_FROM = store_thm
5484  ("UNION_COUNT_FROM", ``!n. (count n) UNION (from n) = UNIV``,
5485    RW_TAC arith_ss [from_def, count_def, Once EXTENSION, NOT_IN_EMPTY,
5486                     GSPECIFICATION, IN_UNION, IN_UNIV]);
5487
5488val UNION_FROM_COUNT = store_thm
5489  ("UNION_FROM_COUNT", ``!n. (from n) UNION (count n) = UNIV``,
5490    RW_TAC std_ss [Once UNION_COMM, UNION_COUNT_FROM]);
5491
5492Theorem FROM_NOT_EMPTY :
5493    !n. from n <> {}
5494Proof
5495    RW_TAC std_ss [GSYM MEMBER_NOT_EMPTY, from_def, GSPECIFICATION]
5496 >> Q.EXISTS_TAC `n` >> REWRITE_TAC [LESS_EQ_REFL]
5497QED
5498
5499Theorem COUNTABLE_FROM :
5500    !n. COUNTABLE (from n)
5501Proof
5502    PROVE_TAC [COUNTABLE_NUM]
5503QED
5504
5505val FROM_INTER_NUMSEG_GEN = store_thm ("FROM_INTER_NUMSEG_GEN",
5506 ``!k m n. (from k) INTER (m..n) = (if m < k then k..n else m..n)``,
5507  REPEAT GEN_TAC THEN COND_CASES_TAC THEN POP_ASSUM MP_TAC THEN
5508  SIMP_TAC std_ss [from_def, GSPECIFICATION, IN_INTER, IN_NUMSEG, EXTENSION] THEN
5509  ARITH_TAC);
5510
5511val FROM_INTER_NUMSEG_MAX = store_thm ("FROM_INTER_NUMSEG_MAX",
5512 ``!m n p. from p INTER (m..n) = (MAX p m..n)``,
5513  SIMP_TAC arith_ss [EXTENSION, IN_INTER, IN_NUMSEG, IN_FROM] THEN ARITH_TAC);
5514
5515val FROM_INTER_NUMSEG = store_thm ("FROM_INTER_NUMSEG",
5516 ``!k n. (from k) INTER (0:num..n) = k..n``,
5517  SIMP_TAC std_ss [from_def, GSPECIFICATION, IN_INTER, IN_NUMSEG, EXTENSION] THEN
5518  ARITH_TAC);
5519
5520val INFINITE_FROM = store_thm ("INFINITE_FROM",
5521  ``!n. INFINITE(from n)``,
5522   GEN_TAC THEN KNOW_TAC ``from n = univ(:num) DIFF {i | i < n}`` THENL
5523  [SIMP_TAC std_ss [EXTENSION, from_def, IN_DIFF, IN_UNIV, GSPECIFICATION] THEN
5524   ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
5525   MATCH_MP_TAC INFINITE_DIFF_FINITE THEN
5526   REWRITE_TAC [FINITE_NUMSEG_LT, num_INFINITE]]);
5527
5528(* ------------------------------------------------------------------------- *)
5529(* More limit point characterizations.                                       *)
5530(* ------------------------------------------------------------------------- *)
5531
5532val WLOG_LT = store_thm ("WLOG_LT",
5533 ``(!m:num. P m m) /\ (!m n. P m n <=> P n m) /\ (!m n. m < n ==> P m n)
5534   ==> !m y. P m y``,
5535  METIS_TAC[LESS_LESS_CASES]);
5536
5537val LT_EXISTS = store_thm ("LT_EXISTS",
5538 ``!m n. (m < n) <=> (?d. n = m + SUC d)``,
5539  GEN_TAC THEN INDUCT_TAC THEN SIMP_TAC std_ss [LESS_THM, ADD_CLAUSES, SUC_NOT] THEN
5540  ASM_REWRITE_TAC[INV_SUC_EQ] THEN EQ_TAC THENL
5541   [DISCH_THEN(DISJ_CASES_THEN2 SUBST1_TAC MP_TAC) THENL
5542     [EXISTS_TAC ``0:num`` THEN REWRITE_TAC[ADD_CLAUSES],
5543      DISCH_THEN(X_CHOOSE_THEN ``d:num`` SUBST1_TAC) THEN
5544      EXISTS_TAC ``SUC d`` THEN REWRITE_TAC[ADD_CLAUSES]],
5545  SIMP_TAC std_ss [LEFT_EXISTS_IMP_THM] THEN
5546  KNOW_TAC ``((?d. n = m + d) ==> (m = n) \/ ?d. n = m + SUC d) =
5547             (!d. (n = m + d) ==> (m = n) \/ ?d. n = m + SUC d)`` THENL
5548  [EQ_TAC THENL [SIMP_TAC std_ss [LEFT_EXISTS_IMP_THM],
5549   STRIP_TAC THEN STRIP_TAC THEN POP_ASSUM MP_TAC THEN
5550   POP_ASSUM (MP_TAC o Q.SPEC `d:num`) THEN FULL_SIMP_TAC std_ss []],
5551   ALL_TAC] THEN DISC_RW_KILL THEN
5552    INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES, INV_SUC_EQ] THEN
5553    DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[] THEN DISJ2_TAC THEN
5554    EXISTS_TAC ``d:num`` THEN METIS_TAC[INV_SUC_EQ, ADD_COMM]]);
5555
5556val TRANSITIVE_STEPWISE_LT_EQ = store_thm ("TRANSITIVE_STEPWISE_LT_EQ",
5557 ``!R. (!x y z. R x y /\ R y z ==> R x z)
5558         ==> ((!m n. m < n ==> R m n) <=> (!n. R n (SUC n)))``,
5559  REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC std_ss [LESS_THM] THEN
5560  DISCH_TAC THEN SIMP_TAC std_ss [LT_EXISTS] THEN
5561  KNOW_TAC ``(!m n. (?d. n = m + SUC d) ==> R m n) =
5562              (!m d n. (n = m + SUC d) ==> R m (m + SUC d))`` THENL
5563  [METIS_TAC [LEFT_EXISTS_IMP_THM, SWAP_FORALL_THM], ALL_TAC] THEN
5564  DISC_RW_KILL THEN GEN_TAC THEN
5565  SIMP_TAC std_ss [LEFT_FORALL_IMP_THM, EXISTS_REFL, ADD_CLAUSES] THEN
5566  INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES] THEN ASM_MESON_TAC[]);
5567
5568val TRANSITIVE_STEPWISE_LT = store_thm ("TRANSITIVE_STEPWISE_LT",
5569 ``!R. (!x y z. R x y /\ R y z ==> R x z) /\ (!n. R n (SUC n))
5570       ==> !m n. m < n ==> R m n``,
5571  REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
5572   `(a ==> (c <=> b)) ==> a /\ b ==> c`) THEN
5573  MATCH_ACCEPT_TAC TRANSITIVE_STEPWISE_LT_EQ);
5574
5575val LIMPT_SEQUENTIAL_INJ = store_thm ("LIMPT_SEQUENTIAL_INJ",
5576 ``!x:real s.
5577      x limit_point_of s <=>
5578             ?f. (!n. f(n) IN (s DELETE x)) /\
5579                 (!m n. (f m = f n) <=> (m = n)) /\
5580                 (f --> x) sequentially``,
5581  REPEAT GEN_TAC THEN
5582  REWRITE_TAC[LIMPT_APPROACHABLE, LIM_SEQUENTIALLY, IN_DELETE] THEN
5583  EQ_TAC THENL [ALL_TAC, MESON_TAC[GREATER_EQ, LESS_EQ_REFL]] THEN
5584  KNOW_TAC ``(!e. 0 < e ==> ?x'. x' IN s /\ x' <> x /\ dist (x',x) < e) =
5585             (!e. ?x'. &0 < e ==> x' IN s /\ ~(x' = x) /\ dist (x',x) < e)`` THENL
5586  [SIMP_TAC std_ss [GSYM RIGHT_EXISTS_IMP_THM], ALL_TAC] THEN DISC_RW_KILL THEN
5587  SIMP_TAC std_ss [SKOLEM_THM] THEN STRIP_TAC THEN
5588  KNOW_TAC ``?z. (z 0 = f (&1)) /\
5589    (!n. z (SUC n):real = f (min (inv(&2 pow (SUC n))) (dist(z n,x))))`` THENL
5590  [RW_TAC real_ss [num_Axiom], ALL_TAC] THEN STRIP_TAC THEN
5591  EXISTS_TAC ``z:num->real`` THEN
5592  SUBGOAL_THEN
5593   ``!n. z(n) IN s /\ ~(z n:real = x) /\ dist(z n,x) < inv(&2 pow n)``
5594  ASSUME_TAC THENL
5595   [INDUCT_TAC THEN ASM_REWRITE_TAC[] THENL [REWRITE_TAC [pow, REAL_INV1] THEN
5596    ASM_SIMP_TAC std_ss [REAL_LT_01], FIRST_X_ASSUM(MP_TAC o SPEC
5597     ``min (inv(&2 pow (SUC n))) (dist(z n:real,x))``) THEN
5598    ASM_SIMP_TAC std_ss [REAL_LT_MIN, REAL_LT_INV_EQ, REAL_POW_LT, DIST_POS_LT,
5599                         REAL_ARITH ``0:real < 2``]],
5600    ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
5601     [KNOW_TAC ``!m:num n. (((z:num->real) m = z n) <=> (m = n)) =
5602                    (\m n. ((z m = z n) <=> (m = n))) m n`` THENL
5603     [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
5604     MATCH_MP_TAC WLOG_LT THEN BETA_TAC THEN SIMP_TAC std_ss [EQ_SYM_EQ] THEN
5605      SUBGOAL_THEN ``!m n:num. m < n ==> dist(z n:real,x) < dist(z m,x)``
5606       (fn th => MESON_TAC[th, REAL_LT_REFL, LESS_REFL]) THEN
5607      KNOW_TAC ``!m n:num.  (dist (z n,x) < dist (z m,x)) =
5608                     (\m n.  dist (z n,x) < dist (z m,x)) m n`` THENL
5609      [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
5610      MATCH_MP_TAC TRANSITIVE_STEPWISE_LT THEN BETA_TAC THEN
5611      CONJ_TAC THENL [REAL_ARITH_TAC, GEN_TAC THEN ASM_REWRITE_TAC[]] THEN
5612      FIRST_X_ASSUM(MP_TAC o SPEC
5613       ``min (inv(&2 pow (SUC n))) (dist(z n:real,x))``) THEN
5614      ASM_SIMP_TAC std_ss [REAL_LT_MIN, REAL_LT_INV_EQ, REAL_POW_LT,
5615      REAL_ARITH ``0:real < 2``, DIST_POS_LT],
5616      X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
5617      MP_TAC(ISPECL [``inv(&2:real)``, ``e:real``] REAL_ARCH_POW_INV) THEN
5618      ASM_SIMP_TAC std_ss [REAL_INV_1OVER, REAL_HALF_BETWEEN] THEN
5619      DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN
5620      FULL_SIMP_TAC std_ss [GSYM REAL_INV_1OVER, REAL_POW_INV] THEN
5621      X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN MATCH_MP_TAC REAL_LT_TRANS THEN
5622      EXISTS_TAC ``inv (2:real pow N)`` THEN ASM_REWRITE_TAC [] THEN
5623      MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``inv(&2:real pow n)`` THEN
5624      ASM_REWRITE_TAC [] THEN REWRITE_TAC [REAL_INV_1OVER] THEN
5625      SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_POW_LT, REAL_ARITH ``0 < 2:real``] THEN
5626      ONCE_REWRITE_TAC [REAL_MUL_COMM] THEN
5627      REWRITE_TAC [GSYM REAL_INV_1OVER, GSYM real_div] THEN SIMP_TAC std_ss [REAL_LE_RDIV_EQ,
5628      REAL_POW_LT, REAL_MUL_LID, REAL_ARITH ``0 < 2:real``] THEN
5629      FULL_SIMP_TAC std_ss [REAL_LE_LT, LESS_OR_EQ] THEN DISJ1_TAC THEN
5630      MATCH_MP_TAC REAL_POW_MONO_LT THEN ASM_REWRITE_TAC [] THEN REAL_ARITH_TAC]]);
5631
5632val LIMPT_SEQUENTIAL = store_thm ("LIMPT_SEQUENTIAL",
5633 ``!x:real s.
5634      x limit_point_of s <=>
5635             ?f. (!n. f(n) IN (s DELETE x)) /\ (f --> x) sequentially``,
5636  REPEAT GEN_TAC THEN EQ_TAC THENL
5637   [REWRITE_TAC[LIMPT_SEQUENTIAL_INJ] THEN MESON_TAC[],
5638    REWRITE_TAC[LIMPT_APPROACHABLE, LIM_SEQUENTIALLY, IN_DELETE] THEN
5639    MESON_TAC[GREATER_EQ, LESS_EQ_REFL]]);
5640
5641val INFINITE_SUPERSET = store_thm ("INFINITE_SUPERSET",
5642 ``!s t. INFINITE s /\ s SUBSET t ==> INFINITE t``,
5643  REWRITE_TAC[] THEN MESON_TAC[SUBSET_FINITE_I]);
5644
5645val LIMPT_INFINITE_OPEN_BALL_CBALL = store_thm ("LIMPT_INFINITE_OPEN_BALL_CBALL",
5646 ``(!s x:real.
5647        x limit_point_of s <=> !t. x IN t /\ open t ==> INFINITE(s INTER t)) /\
5648   (!s x:real.
5649        x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER ball(x,e))) /\
5650   (!s x:real.
5651        x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER cball(x,e)))``,
5652  SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
5653   `(q ==> p) /\ (r ==> s) /\ (s ==> q) /\ (p ==> r)
5654    ==> (p <=> q) /\ (p <=> r) /\ (p <=> s)`) THEN
5655  REPEAT CONJ_TAC THENL
5656   [REWRITE_TAC[limit_point_of, SET_RULE
5657     ``(?y. ~(y = x) /\ y IN s /\ y IN t) <=> ~(s INTER t SUBSET {x})``] THEN
5658    MESON_TAC[SUBSET_FINITE_I, FINITE_SING],
5659    MESON_TAC[INFINITE_SUPERSET, BALL_SUBSET_CBALL,
5660              SET_RULE ``t SUBSET u ==> s INTER t SUBSET s INTER u``],
5661    MESON_TAC[INFINITE_SUPERSET, OPEN_CONTAINS_CBALL,
5662              SET_RULE ``t SUBSET u ==> s INTER t SUBSET s INTER u``],
5663    REWRITE_TAC[LIMPT_SEQUENTIAL_INJ, IN_DELETE, FORALL_AND_THM] THEN
5664    DISCH_THEN(X_CHOOSE_THEN ``f:num->real`` STRIP_ASSUME_TAC) THEN
5665    X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
5666    UNDISCH_TAC ``(f --> x) sequentially`` THEN
5667    GEN_REWR_TAC LAND_CONV [LIM_SEQUENTIALLY] THEN
5668    DISCH_THEN(MP_TAC o SPEC ``e:real``) THEN
5669    ASM_REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[DIST_SYM] IN_BALL)] THEN
5670    DISCH_THEN(X_CHOOSE_TAC ``N:num``) THEN
5671    MATCH_MP_TAC INFINITE_SUPERSET THEN
5672    EXISTS_TAC ``IMAGE (f:num->real) (from N)`` THEN
5673    ASM_SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE, IN_FROM, IN_INTER] THEN
5674    ASM_MESON_TAC[IMAGE_11_INFINITE, INFINITE_FROM]]);
5675
5676val LIMPT_INFINITE_OPEN = store_thm ("LIMPT_INFINITE_OPEN",
5677 ``(!s x:real.
5678        x limit_point_of s <=> !t. x IN t /\ open t ==> INFINITE(s INTER t))``,
5679  SIMP_TAC std_ss [LIMPT_INFINITE_OPEN_BALL_CBALL]);
5680
5681val LIMPT_INFINITE_BALL = store_thm ("LIMPT_INFINITE_BALL",
5682 ``(!s x:real.
5683        x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER ball(x,e)))``,
5684  METIS_TAC [LIMPT_INFINITE_OPEN_BALL_CBALL]);
5685
5686val LIMPT_INFINITE_CBALL = store_thm ("LIMPT_INFINITE_CBALL",
5687 ``(!s x:real.
5688        x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER cball(x,e)))``,
5689  METIS_TAC [LIMPT_INFINITE_OPEN_BALL_CBALL]);
5690
5691val INFINITE_OPEN_IN = store_thm ("INFINITE_OPEN_IN",
5692 ``!u s:real->bool.
5693      open_in (subtopology euclidean u) s /\ (?x. x IN s /\ x limit_point_of u)
5694      ==> INFINITE s``,
5695  REPEAT STRIP_TAC THEN
5696  UNDISCH_TAC ``open_in (subtopology euclidean u) s`` THEN
5697  REWRITE_TAC [OPEN_IN_OPEN] THEN
5698  DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN
5699  UNDISCH_TAC ``x limit_point_of u`` THEN REWRITE_TAC [LIMPT_INFINITE_OPEN] THEN
5700  FIRST_X_ASSUM SUBST_ALL_TAC THEN ASM_SET_TAC[]);
5701
5702(* ------------------------------------------------------------------------- *)
5703(* Condensation points.                                                      *)
5704(* ------------------------------------------------------------------------- *)
5705
5706val _ = set_fixity "condensation_point_of" (Infix(NONASSOC, 450));
5707
5708val condensation_point_of = new_definition ("condensation_point_of",
5709 ``x condensation_point_of s <=>
5710        !t. x IN t /\ open t ==> ~COUNTABLE(s INTER t)``);
5711
5712val CONDENSATION_POINT_OF_SUBSET = store_thm ("CONDENSATION_POINT_OF_SUBSET",
5713 ``!x:real s t.
5714        x condensation_point_of s /\ s SUBSET t ==> x condensation_point_of t``,
5715  REPEAT GEN_TAC THEN
5716  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
5717  REWRITE_TAC[condensation_point_of] THEN
5718  DISCH_TAC THEN X_GEN_TAC ``t':real->bool`` THEN
5719  POP_ASSUM (MP_TAC o Q.SPEC `t':real->bool`) THEN
5720  MATCH_MP_TAC MONO_IMP THEN
5721  REWRITE_TAC[GSYM MONO_NOT_EQ] THEN
5722  MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] COUNTABLE_SUBSET) THEN
5723  ASM_SET_TAC[]);
5724
5725val CONDENSATION_POINT_IMP_LIMPT = store_thm ("CONDENSATION_POINT_IMP_LIMPT",
5726 ``!x s. x condensation_point_of s ==> x limit_point_of s``,
5727  REWRITE_TAC[condensation_point_of, LIMPT_INFINITE_OPEN] THEN
5728  MESON_TAC[FINITE_IMP_COUNTABLE]);
5729
5730val CONDENSATION_POINT_INFINITE_BALL_CBALL = store_thm ("CONDENSATION_POINT_INFINITE_BALL_CBALL",
5731 ``(!s x:real.
5732        x condensation_point_of s <=>
5733        !e. &0 < e ==> ~COUNTABLE(s INTER ball(x,e))) /\
5734   (!s x:real.
5735        x condensation_point_of s <=>
5736        !e. &0 < e ==> ~COUNTABLE(s INTER cball(x,e)))``,
5737  SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
5738   `(p ==> q) /\ (q ==> r) /\ (r ==> p)
5739    ==> (p <=> q) /\ (p <=> r)`) THEN
5740  REWRITE_TAC[condensation_point_of] THEN REPEAT CONJ_TAC THENL
5741   [MESON_TAC[OPEN_BALL, CENTRE_IN_BALL],
5742    MESON_TAC[BALL_SUBSET_CBALL, COUNTABLE_SUBSET,
5743              SET_RULE ``t SUBSET u ==> s INTER t SUBSET s INTER u``],
5744    MESON_TAC[COUNTABLE_SUBSET, OPEN_CONTAINS_CBALL,
5745              SET_RULE ``t SUBSET u ==> s INTER t SUBSET s INTER u``]]);
5746
5747val CONDENSATION_POINT_INFINITE_BALL = store_thm ("CONDENSATION_POINT_INFINITE_BALL",
5748 ``(!s x:real.
5749        x condensation_point_of s <=>
5750        !e. &0 < e ==> ~COUNTABLE(s INTER ball(x,e)))``,
5751  METIS_TAC [CONDENSATION_POINT_INFINITE_BALL_CBALL]);
5752
5753val CONDENSATION_POINT_INFINITE_CBALL = store_thm ("CONDENSATION_POINT_INFINITE_CBALL",
5754 ``(!s x:real.
5755        x condensation_point_of s <=>
5756        !e. &0 < e ==> ~COUNTABLE(s INTER cball(x,e)))``,
5757  METIS_TAC [CONDENSATION_POINT_INFINITE_BALL_CBALL]);
5758
5759(* ------------------------------------------------------------------------- *)
5760(* Basic arithmetical combining theorems for limits.                         *)
5761(* ------------------------------------------------------------------------- *)
5762
5763val LIM_LINEAR = store_thm ("LIM_LINEAR",
5764 ``!net:('a)net h f l.
5765        (f --> l) net /\ linear h ==> ((\x. h(f x)) --> h l) net``,
5766  REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
5767  ASM_CASES_TAC ``trivial_limit (net:('a)net)`` THEN ASM_REWRITE_TAC[] THEN
5768  STRIP_TAC THEN FIRST_ASSUM(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC o
5769    MATCH_MP LINEAR_BOUNDED_POS) THEN
5770  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
5771  UNDISCH_TAC ``!e. 0 < e ==> ?y. (?x. netord net x y) /\
5772          !x. netord net x y ==> dist (f x,l) < e`` THEN DISCH_TAC THEN
5773  FIRST_X_ASSUM(MP_TAC o SPEC ``e / B:real``) THEN
5774  ASM_SIMP_TAC std_ss [REAL_LT_DIV, dist, GSYM LINEAR_SUB, REAL_LT_RDIV_EQ] THEN
5775  ASM_MESON_TAC[REAL_LET_TRANS, REAL_MUL_SYM]);
5776
5777val LIM_CONST = store_thm ("LIM_CONST",
5778 ``!net a:real. ((\x. a) --> a) net``,
5779  SIMP_TAC std_ss [LIM, DIST_REFL, trivial_limit] THEN MESON_TAC[]);
5780
5781val LIM_CMUL = store_thm ("LIM_CMUL",
5782 ``!f l c. (f --> l) net ==> ((\x. c * f x) --> (c * l)) net``,
5783  REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_LINEAR THEN
5784  ASM_SIMP_TAC std_ss [REWRITE_RULE[ETA_AX]
5785    (MATCH_MP LINEAR_COMPOSE_CMUL LINEAR_ID)] THEN
5786  REWRITE_TAC [linear] THEN REAL_ARITH_TAC);
5787
5788val LIM_CMUL_EQ = store_thm ("LIM_CMUL_EQ",
5789 ``!net f l c.
5790        ~(c = &0) ==> (((\x. c * f x) --> (c * l)) net <=> (f --> l) net)``,
5791  REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [LIM_CMUL] THEN
5792  DISCH_THEN(MP_TAC o SPEC ``inv c:real`` o MATCH_MP LIM_CMUL) THEN
5793  ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID, ETA_AX]);
5794
5795val LIM_NEG = store_thm ("LIM_NEG",
5796 ``!net f l:real. (f --> l) net ==> ((\x. -(f x)) --> -l) net``,
5797  REPEAT GEN_TAC THEN REWRITE_TAC[LIM, dist] THEN
5798  SIMP_TAC std_ss [REAL_ARITH ``-x - -y = -(x - y:real)``, ABS_NEG]);
5799
5800val LIM_NEG_EQ = store_thm ("LIM_NEG_EQ",
5801 ``!net f l:real. ((\x. -(f x)) --> -l) net <=> (f --> l) net``,
5802  REPEAT GEN_TAC THEN EQ_TAC THEN
5803  DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG) THEN
5804  SIMP_TAC std_ss [REAL_NEG_NEG, ETA_AX]);
5805
5806val LIM_ADD = store_thm ("LIM_ADD",
5807 ``!net:('a)net f g l m.
5808    (f --> l) net /\ (g --> m) net ==> ((\x. f(x) + g(x)) --> (l + m)) net``,
5809  REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
5810  ASM_CASES_TAC ``trivial_limit (net:('a)net)`` THEN
5811  ASM_SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN
5812  DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
5813  FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN
5814  KNOW_TAC ``!x y. (dist(f x, l) < e / 2:real) =
5815              (\x. (dist(f x, l) < e / 2:real)) x`` THENL
5816  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
5817  KNOW_TAC ``!x y. (dist(g x, m) < e / 2:real) =
5818              (\x. (dist(g x, m) < e / 2:real)) x`` THENL
5819  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
5820  DISCH_THEN(MP_TAC o MATCH_MP NET_DILEMMA) THEN BETA_TAC THEN
5821  STRIP_TAC THEN EXISTS_TAC ``c:'a`` THEN CONJ_TAC THENL [METIS_TAC [], ALL_TAC] THEN
5822  GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x'`) THEN REPEAT STRIP_TAC THEN
5823  FULL_SIMP_TAC std_ss [] THEN MATCH_MP_TAC REAL_LET_TRANS THEN
5824  EXISTS_TAC ``dist (f x', l) + dist (g x', m)`` THEN
5825  METIS_TAC[REAL_LT_HALF1, REAL_LT_ADD2, DIST_TRIANGLE_ADD, GSYM REAL_HALF_DOUBLE]);
5826
5827val lemma = prove (
5828 ``abs(x - y) <= abs(a - b) ==> dist(a,b) < e ==> dist(x,y) < e``,
5829  REWRITE_TAC [dist] THEN REAL_ARITH_TAC);
5830
5831val LIM_ABS = store_thm ("LIM_ABS",
5832 ``!net:('a)net f:'a->real l.
5833     (f --> l) net
5834     ==> ((\x. abs(f(x))) --> (abs(l)):real) net``,
5835  REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
5836  ASM_CASES_TAC ``trivial_limit (net:('a)net)`` THEN ASM_REWRITE_TAC[] THEN
5837  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN
5838  MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
5839  STRIP_TAC THEN EXISTS_TAC ``y:'a`` THEN POP_ASSUM MP_TAC THEN
5840  POP_ASSUM MP_TAC THEN REWRITE_TAC [AND_IMP_INTRO] THEN
5841  MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
5842  STRIP_TAC THENL [DISCH_TAC THEN EXISTS_TAC ``x:'a`` THEN ASM_REWRITE_TAC [],
5843   ALL_TAC] THEN DISCH_TAC THEN GEN_TAC THEN
5844  POP_ASSUM (MP_TAC o Q.SPEC `x:'a`) THEN
5845  MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
5846  MATCH_MP_TAC lemma THEN BETA_TAC THEN
5847  REAL_ARITH_TAC);
5848
5849val LIM_SUB = store_thm ("LIM_SUB",
5850 ``!net:('a)net f g l m.
5851    (f --> l) net /\ (g --> m) net ==> ((\x. f(x) - g(x)) --> (l - m)) net``,
5852  REWRITE_TAC[real_sub] THEN ASM_SIMP_TAC std_ss [LIM_ADD, LIM_NEG]);
5853
5854val LIM_MAX = store_thm ("LIM_MAX",
5855 ``!net:('a)net f g l:real m:real.
5856    (f --> l) net /\ (g --> m) net
5857    ==> ((\x. max (f(x)) (g(x)))
5858         --> (max (l) (m)):real) net``,
5859  REPEAT GEN_TAC THEN DISCH_TAC THEN
5860  FIRST_ASSUM(MP_TAC o MATCH_MP LIM_ADD) THEN
5861  FIRST_ASSUM(MP_TAC o MATCH_MP LIM_SUB) THEN
5862  DISCH_THEN(MP_TAC o MATCH_MP LIM_ABS) THEN
5863  REWRITE_TAC[AND_IMP_INTRO] THEN
5864  DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN
5865  DISCH_THEN(MP_TAC o SPEC ``inv(&2:real)`` o MATCH_MP LIM_CMUL) THEN
5866  MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN BINOP_TAC THEN
5867  SIMP_TAC std_ss [FUN_EQ_THM, max_def, abs] THEN
5868  ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN ONCE_REWRITE_TAC [GSYM real_div] THEN
5869  SIMP_TAC arith_ss [REAL_EQ_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
5870  ONCE_REWRITE_TAC [REAL_MUL_COMM] THEN (RW_TAC arith_ss [REAL_SUB_LE] THENL
5871  [REPEAT (POP_ASSUM MP_TAC) THEN RW_TAC std_ss [AND_IMP_INTRO, REAL_LE_ANTISYM, REAL_SUB_REFL,
5872    REAL_ADD_LID] THEN  REWRITE_TAC [GSYM REAL_DOUBLE],
5873   REWRITE_TAC [REAL_ARITH ``a - b + (a + b) = a + a - b + b:real``, REAL_SUB_ADD, REAL_DOUBLE],
5874   REWRITE_TAC [REAL_ARITH ``-(a - b) + (a + b) = b + b - a + a:real``,
5875    REAL_SUB_ADD, REAL_DOUBLE],
5876   FULL_SIMP_TAC real_ss [REAL_NOT_LE] THEN METIS_TAC [REAL_LT_ANTISYM]]));
5877
5878val LIM_MIN = store_thm ("LIM_MIN",
5879 ``!net:('a)net f g l:real m:real.
5880    (f --> l) net /\ (g --> m) net
5881    ==> ((\x. min (f(x)) (g(x)))
5882         --> (min (l) (m)):real) net``,
5883  REPEAT GEN_TAC THEN
5884  DISCH_THEN(CONJUNCTS_THEN(MP_TAC o MATCH_MP LIM_NEG)) THEN
5885  REWRITE_TAC[AND_IMP_INTRO] THEN
5886  DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG o MATCH_MP LIM_MAX) THEN
5887  MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN
5888  reverse BINOP_TAC >- PROVE_TAC [GSYM REAL_MIN_MAX, REAL_MIN_ACI] THEN
5889  SIMP_TAC std_ss [FUN_EQ_THM] THEN
5890  GEN_TAC >> PROVE_TAC [GSYM REAL_MIN_MAX, REAL_MIN_ACI]);
5891
5892val LIM_NULL = store_thm ("LIM_NULL",
5893 ``!net f l. (f --> l) net <=> ((\x. f(x) - l) --> 0) net``,
5894  SIMP_TAC arith_ss [LIM, dist, REAL_SUB_RZERO]);
5895
5896val LIM_NULL_ABS = store_thm ("LIM_NULL_ABS",
5897 ``!net f. (f --> 0) net <=> ((\x. (abs(f x))) --> 0) net``,
5898  SIMP_TAC std_ss [LIM, dist, REAL_SUB_RZERO, ABS_ABS]);
5899
5900val LIM_NULL_CMUL_EQ = store_thm ("LIM_NULL_CMUL_EQ",
5901 ``!net f c.
5902        ~(c = &0) ==> (((\x. c * f x) --> 0) net <=> (f --> 0) net)``,
5903  METIS_TAC[LIM_CMUL_EQ, REAL_MUL_RZERO]);
5904
5905val LIM_NULL_CMUL = store_thm ("LIM_NULL_CMUL",
5906 ``!net f c. (f --> 0) net ==> ((\x. c * f x) --> 0) net``,
5907  REPEAT GEN_TAC THEN ASM_CASES_TAC ``c = &0:real`` THEN
5908  ASM_SIMP_TAC std_ss [LIM_NULL_CMUL_EQ, REAL_MUL_LZERO, LIM_CONST]);
5909
5910val LIM_NULL_ADD = store_thm ("LIM_NULL_ADD",
5911 ``!net f g:'a->real.
5912        (f --> 0) net /\ (g --> 0) net
5913        ==> ((\x. f x + g x) --> 0) net``,
5914  REPEAT GEN_TAC THEN
5915  DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN
5916  REWRITE_TAC[REAL_ADD_LID]);
5917
5918val LIM_NULL_SUB = store_thm ("LIM_NULL_SUB",
5919 ``!net f g:'a->real.
5920        (f --> 0) net /\ (g --> 0) net
5921        ==> ((\x. f x - g x) --> 0) net``,
5922  REPEAT GEN_TAC THEN
5923  DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN
5924  REWRITE_TAC[REAL_SUB_RZERO]);
5925
5926val LIM_NULL_COMPARISON = store_thm ("LIM_NULL_COMPARISON",
5927 ``!net f g. eventually (\x. abs(f x) <= g x) net /\
5928             ((\x. (g x)) --> 0) net
5929             ==> (f --> 0) net``,
5930  REPEAT GEN_TAC THEN SIMP_TAC std_ss [tendsto, RIGHT_AND_FORALL_THM] THEN
5931  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN
5932  ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [GSYM EVENTUALLY_AND] THEN
5933  MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN
5934  SIMP_TAC arith_ss [dist, REAL_SUB_RZERO] THEN REAL_ARITH_TAC);
5935
5936val LIM_COMPONENT = store_thm ("LIM_COMPONENT",
5937 ``!net f i l:real. (f --> l) net
5938       ==> ((\a. f(a)) --> l) net``,
5939  REWRITE_TAC[LIM, dist] THEN
5940  METIS_TAC[REAL_LET_TRANS]);
5941
5942val LIM_TRANSFORM_BOUND = store_thm ("LIM_TRANSFORM_BOUND",
5943 ``!f g. eventually (\n. abs(f n) <= abs(g n)) net /\ (g --> 0) net
5944         ==> (f --> 0) net``,
5945  REPEAT GEN_TAC THEN
5946  SIMP_TAC std_ss [tendsto, RIGHT_AND_FORALL_THM] THEN
5947  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN
5948  ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [GSYM EVENTUALLY_AND] THEN
5949  MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN
5950  SIMP_TAC arith_ss [dist, REAL_SUB_RZERO] THEN REAL_ARITH_TAC);
5951
5952val LIM_NULL_CMUL_BOUNDED = store_thm ("LIM_NULL_CMUL_BOUNDED",
5953 ``!f g:'a->real B.
5954        eventually (\a. (g a = 0) \/ abs(f a) <= B) net /\
5955        (g --> 0) net
5956        ==> ((\n. f n * g n) --> 0) net``,
5957  REPEAT GEN_TAC THEN REWRITE_TAC[tendsto] THEN STRIP_TAC THEN
5958  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
5959  FIRST_X_ASSUM(MP_TAC o SPEC ``e / (abs B + &1:real)``) THEN
5960  ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_ARITH ``&0 < abs x + &1:real``] THEN
5961  UNDISCH_TAC ``eventually
5962        (\(a :'a). ((g :'a -> real) a = (0 :real)) \/
5963           abs ((f :'a -> real) a) <= (B :real)) (net :'a net)`` THEN
5964  REWRITE_TAC[AND_IMP_INTRO, GSYM EVENTUALLY_AND] THEN
5965  MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MP) THEN
5966  SIMP_TAC std_ss [dist, REAL_SUB_RZERO, o_THM, ABS_MUL] THEN
5967  MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC ``x:'a`` THEN BETA_TAC THEN
5968  ASM_CASES_TAC ``(g:'a->real) x = 0`` THEN
5969  ASM_SIMP_TAC std_ss [ABS_0, REAL_MUL_RZERO] THEN
5970  STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
5971  EXISTS_TAC ``B * e / (abs B + &1:real)`` THEN CONJ_TAC THENL
5972  [ONCE_REWRITE_TAC [real_div] THEN ONCE_REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN
5973  MATCH_MP_TAC REAL_LE_MUL2 THEN ONCE_REWRITE_TAC [GSYM real_div] THEN
5974  ASM_SIMP_TAC std_ss [REAL_ABS_POS, REAL_LT_IMP_LE], ALL_TAC] THEN
5975  SIMP_TAC std_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``&0 < abs x + &1:real``] THEN
5976  MATCH_MP_TAC(REAL_ARITH
5977   ``e * B <= e * abs B /\ &0 < e ==> B * e < e * (abs B + &1:real)``) THEN
5978  ASM_SIMP_TAC std_ss [REAL_LE_LMUL] THEN REAL_ARITH_TAC);
5979
5980val LIM_SUM = store_thm ("LIM_SUM",
5981 ``!net f:'a->'b->real l s.
5982        FINITE s /\ (!i. i IN s ==> ((f i) --> (l i)) net)
5983        ==> ((\x. sum s (\i. f i x)) --> sum s l) net``,
5984  GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN
5985  KNOW_TAC ``!s:'a->bool. ( (!(i :'a). i IN s ==>
5986     ((f :'a -> 'b -> real) i --> (l :'a -> real) i) (net :'b net)) ==>
5987  ((\(x :'b). sum s (\(i :'a). f i x)) --> sum s l) net) =
5988                       (\s. (!(i :'a). i IN s ==>
5989     ((f :'a -> 'b -> real) i --> (l :'a -> real) i) (net :'b net)) ==>
5990  ((\(x :'b). sum s (\(i :'a). f i x)) --> sum s l) net)  s`` THENL
5991  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
5992  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
5993  SIMP_TAC std_ss [SUM_CLAUSES, LIM_CONST, LIM_ADD, IN_INSERT, ETA_AX] THEN
5994  METIS_TAC [SUM_CLAUSES, LIM_CONST, LIM_ADD, IN_INSERT, ETA_AX]);
5995
5996val LIM_NULL_SUM = store_thm ("LIM_NULL_SUM",
5997 ``!net f:'a->'b->real s.
5998  FINITE s /\ (!a. a IN s ==> ((\x. f x a) --> 0) net)
5999  ==> ((\x. sum s (f x)) --> 0) net``,
6000  REPEAT GEN_TAC THEN
6001  ONCE_REWRITE_TAC [METIS [] ``!a. (\x. f x a) = (\a. (\x. f x a)) a``] THEN
6002  ONCE_REWRITE_TAC [METIS [] ``0:real = (\a. 0) (a:'b)``] THEN
6003  DISCH_THEN(MP_TAC o MATCH_MP LIM_SUM) THEN BETA_TAC THEN
6004   ONCE_REWRITE_TAC [METIS [] ``!i. (\i. f x i) = (\i. f x) i``] THEN
6005  METIS_TAC [SUM_0, ETA_AX]);
6006
6007(* ------------------------------------------------------------------------- *)
6008(* Deducing things about the limit from the elements.                        *)
6009(* ------------------------------------------------------------------------- *)
6010
6011val LIM_IN_CLOSED_SET = store_thm ("LIM_IN_CLOSED_SET",
6012 ``!net f:'a->real s l.
6013    closed s /\ eventually (\x. f(x) IN s) net /\
6014    ~(trivial_limit net) /\ (f --> l) net
6015    ==> l IN s``,
6016  REWRITE_TAC[closed_def] THEN REPEAT STRIP_TAC THEN
6017  MATCH_MP_TAC(SET_RULE ``~(x IN (UNIV DIFF s)) ==> x IN s``) THEN
6018  DISCH_TAC THEN UNDISCH_TAC ``open (univ(:real) DIFF s)`` THEN
6019  GEN_REWR_TAC LAND_CONV [OPEN_CONTAINS_BALL] THEN DISCH_TAC THEN
6020  POP_ASSUM (MP_TAC o Q.SPEC `l:real`) THEN
6021  KNOW_TAC ``~(?e. &0 < e /\ (!x. dist (l,x) < e ==>
6022                x IN univ(:real) /\ ~(x IN s)))`` THENL
6023  [ALL_TAC, ASM_SIMP_TAC std_ss [SUBSET_DEF, IN_BALL, IN_DIFF, IN_UNION]] THEN
6024  DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
6025  UNDISCH_TAC ``((f:'a->real) --> l) net`` THEN GEN_REWR_TAC LAND_CONV [tendsto] THEN
6026  DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN
6027  UNDISCH_TAC ``eventually (\x. (f:'a->real) x IN s) net`` THEN
6028  ASM_REWRITE_TAC[GSYM EVENTUALLY_AND, TAUT `a ==> ~b <=> ~(a /\ b)`] THEN
6029  MATCH_MP_TAC NOT_EVENTUALLY THEN ASM_MESON_TAC[DIST_SYM]);
6030
6031(* ------------------------------------------------------------------------- *)
6032(* Need to prove closed(cball(x,e)) before deducing this as a corollary.     *)
6033(* ------------------------------------------------------------------------- *)
6034
6035val LIM_ABS_UBOUND = store_thm ("LIM_ABS_UBOUND",
6036 ``!net:('a)net f (l:real) b.
6037   ~(trivial_limit net) /\ (f --> l) net /\
6038   eventually (\x. abs(f x) <= b) net
6039   ==> abs(l) <= b``,
6040  REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6041  ASM_REWRITE_TAC[LIM] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6042  ASM_REWRITE_TAC[eventually] THEN
6043  STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
6044  ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN
6045  SUBGOAL_THEN
6046  ``?x:'a. dist(f(x):real,l) < abs(l:real) - b /\ abs(f x) <= b``
6047   (CHOOSE_THEN MP_TAC) THENL [ASM_MESON_TAC[NET], ALL_TAC] THEN
6048  REWRITE_TAC[REAL_NOT_LT, REAL_LE_SUB_RADD, DE_MORGAN_THM, dist] THEN
6049  REAL_ARITH_TAC);
6050
6051val LIM_ABS_LBOUND = store_thm ("LIM_ABS_LBOUND",
6052 ``!net:('a)net f (l:real) b.
6053   ~(trivial_limit net) /\ (f --> l) net /\
6054   eventually (\x. b <= abs(f x)) net
6055   ==> b <= abs(l)``,
6056  REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6057  ASM_REWRITE_TAC[LIM] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6058  ASM_REWRITE_TAC[eventually] THEN
6059  STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
6060  ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN
6061  SUBGOAL_THEN
6062  ``?x:'a. dist(f(x):real,l) < b - abs(l:real) /\ b <= abs(f x)``
6063   (CHOOSE_THEN MP_TAC) THENL [ASM_MESON_TAC[NET], ALL_TAC] THEN
6064  REWRITE_TAC[REAL_NOT_LT, REAL_LE_SUB_RADD, DE_MORGAN_THM, dist] THEN
6065  REAL_ARITH_TAC);
6066
6067(* ------------------------------------------------------------------------- *)
6068(* Uniqueness of the limit, when nontrivial. *)
6069(* ------------------------------------------------------------------------- *)
6070
6071val LIM_UNIQUE = store_thm ("LIM_UNIQUE",
6072 ``!net:('a)net f l:real l'.
6073  ~(trivial_limit net) /\ (f --> l) net /\ (f --> l') net ==> (l = l')``,
6074  REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6075  DISCH_THEN(ASSUME_TAC o REWRITE_RULE[REAL_SUB_REFL] o MATCH_MP LIM_SUB) THEN
6076  SUBGOAL_THEN ``!e. &0 < e ==> abs(l:real - l') <= e`` MP_TAC THENL
6077  [GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC LIM_ABS_UBOUND THEN
6078   MAP_EVERY EXISTS_TAC [``net:('a)net``, ``\x:'a. 0:real``] THEN
6079   ASM_SIMP_TAC std_ss [ABS_0, REAL_LT_IMP_LE, eventually] THEN
6080   ASM_MESON_TAC[trivial_limit],
6081  ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN REWRITE_TAC[DIST_NZ, dist] THEN
6082  DISCH_TAC THEN DISCH_THEN(MP_TAC o SPEC ``abs(l - l':real) / &2``) THEN
6083  ASM_SIMP_TAC arith_ss [REAL_LT_RDIV_EQ, REAL_LE_RDIV_EQ, REAL_LT] THEN
6084  UNDISCH_TAC ``&0 < abs(l - l':real)`` THEN REAL_ARITH_TAC]);
6085
6086val TENDSTO_LIM = store_thm ("TENDSTO_LIM",
6087 ``!net f l. ~(trivial_limit net) /\ (f --> l) net ==> (lim net f = l)``,
6088  REWRITE_TAC[lim_def] THEN METIS_TAC[LIM_UNIQUE]);
6089
6090val LIM_CONST_EQ = store_thm ("LIM_CONST_EQ",
6091 ``!net:('a net) c d:real.
6092  ((\x. c) --> d) net <=> trivial_limit net \/ (c = d)``,
6093  REPEAT GEN_TAC THEN
6094  ASM_CASES_TAC ``trivial_limit (net:'a net)`` THEN ASM_REWRITE_TAC[] THENL
6095  [ASM_REWRITE_TAC[LIM], ALL_TAC] THEN
6096  EQ_TAC THEN SIMP_TAC std_ss [LIM_CONST] THEN DISCH_TAC THEN
6097  MATCH_MP_TAC(SPEC ``net:'a net`` LIM_UNIQUE) THEN
6098  EXISTS_TAC ``(\x. c):'a->real`` THEN ASM_REWRITE_TAC[LIM_CONST]);
6099
6100(* ------------------------------------------------------------------------- *)
6101(* Some unwieldy but occasionally useful theorems about uniform limits.      *)
6102(* ------------------------------------------------------------------------- *)
6103
6104val UNIFORM_LIM_ADD = store_thm ("UNIFORM_LIM_ADD",
6105 ``!net:('a)net P f g l m.
6106  (!e:real. &0 < e
6107   ==> eventually (\x. !n:'b. P n ==> abs(f n x - l n) < e) net) /\
6108  (!e:real. &0 < e
6109   ==> eventually (\x. !n. P n ==> abs(g n x - m n) < e) net)
6110    ==> !e. &0 < e ==> eventually (\x. !n. P n
6111     ==> abs((f n x + g n x) - (l n + m n)) < e) net``,
6112  REPEAT GEN_TAC THEN SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN DISCH_TAC THEN
6113  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
6114  FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN
6115  ASM_REWRITE_TAC[REAL_LT_HALF1, GSYM EVENTUALLY_AND] THEN
6116  MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN
6117  GEN_TAC THEN REWRITE_TAC[GSYM FORALL_AND_THM] THEN
6118  BETA_TAC THEN STRIP_TAC THEN X_GEN_TAC ``n:'b`` THEN
6119  POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN
6120  ASM_CASES_TAC ``(P:'b->bool) n`` THEN ASM_REWRITE_TAC[] THEN
6121  REPEAT STRIP_TAC THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN
6122  REWRITE_TAC [REAL_ADD2_SUB2] THEN MATCH_MP_TAC REAL_LET_TRANS THEN
6123  EXISTS_TAC ``abs ((f:'b->'a->real) n x - l n) + abs (-g n x - -m n):real`` THEN
6124  ASM_REAL_ARITH_TAC);
6125
6126val UNIFORM_LIM_SUB = store_thm ("UNIFORM_LIM_SUB",
6127 ``!net:('a)net P f g l m.
6128  (!e:real. &0 < e
6129   ==> eventually (\x. !n:'b. P n ==> abs(f n x - l n) < e) net) /\
6130  (!e:real. &0 < e
6131   ==> eventually (\x. !n. P n ==> abs(g n x - m n) < e) net)
6132    ==> !e. &0 < e ==> eventually (\x. !n. P n
6133     ==> abs((f n x - g n x) - (l n - m n)) < e) net``,
6134  REPEAT GEN_TAC THEN SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN DISCH_TAC THEN
6135  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
6136  FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN
6137  ASM_REWRITE_TAC[REAL_LT_HALF1, GSYM EVENTUALLY_AND] THEN
6138  MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN
6139  GEN_TAC THEN REWRITE_TAC[GSYM FORALL_AND_THM] THEN
6140  BETA_TAC THEN STRIP_TAC THEN X_GEN_TAC ``n:'b`` THEN
6141  POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN
6142  ASM_CASES_TAC ``(P:'b->bool) n`` THEN ASM_REWRITE_TAC[] THEN
6143  REPEAT STRIP_TAC THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN
6144  REWRITE_TAC [REAL_ARITH ``abs (f n x - g n x - (l n - m n)):real =
6145                            abs (f n x + -g n x - (l n + -m n))``] THEN
6146  REWRITE_TAC [REAL_ADD2_SUB2] THEN
6147  MATCH_MP_TAC REAL_LET_TRANS THEN
6148  EXISTS_TAC ``abs ((f:'b->'a->real) n x - l n) + abs (-g n x - -m n):real`` THEN
6149  REWRITE_TAC [ABS_TRIANGLE] THEN MATCH_MP_TAC REAL_LT_ADD2 THEN
6150  ASM_REWRITE_TAC [REAL_ARITH ``-a - -b = - (a - b):real``, ABS_NEG]);
6151
6152(* ------------------------------------------------------------------------- *)
6153(* Limit under bilinear function, uniform version first.                     *)
6154(* ------------------------------------------------------------------------- *)
6155
6156val UNIFORM_LIM_BILINEAR = store_thm ("UNIFORM_LIM_BILINEAR",
6157 ``!net:('a)net P (h:real->real->real) f g l m b1 b2.
6158        bilinear h /\
6159        eventually (\x. !n. P n ==> abs(l n) <= b1) net /\
6160        eventually (\x. !n. P n ==> abs(m n) <= b2) net /\
6161        (!e. &0 < e
6162             ==> eventually (\x. !n:'b. P n ==> abs(f n x - l n) < e) net) /\
6163        (!e. &0 < e
6164             ==> eventually (\x. !n. P n ==> abs(g n x - m n) < e) net)
6165        ==> !e. &0 < e
6166             ==> eventually (\x. !n. P n
6167                 ==> abs(h (f n x) (g n x) - h (l n) (m n)) < e) net``,
6168  REPEAT GEN_TAC THEN
6169  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6170  FIRST_ASSUM(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC o  MATCH_MP
6171   BILINEAR_BOUNDED_POS) THEN
6172  SIMP_TAC std_ss [GSYM FORALL_AND_THM, RIGHT_AND_FORALL_THM] THEN DISCH_TAC THEN
6173  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
6174  FIRST_X_ASSUM(MP_TAC o SPEC
6175   ``min (abs b2 + &1:real) (e / &2 / (B * (abs b1 + abs b2 + &2)))``) THEN
6176  ASM_SIMP_TAC std_ss [REAL_LT_HALF1, REAL_LT_DIV, REAL_LT_MUL, REAL_LT_MIN,
6177               REAL_ARITH ``&0 < abs x + &1:real``,
6178               REAL_ARITH ``&0 < abs x + abs y + &2:real``] THEN
6179  REWRITE_TAC[GSYM EVENTUALLY_AND] THEN BETA_TAC THEN
6180  MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] EVENTUALLY_MONO) THEN
6181  X_GEN_TAC ``x:'a`` THEN SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN
6182  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `n:'b`) THEN
6183  ASM_CASES_TAC ``(P:'b->bool) n`` THEN ASM_REWRITE_TAC[] THEN
6184  STRIP_TAC THEN
6185  ONCE_REWRITE_TAC[REAL_ARITH
6186    ``h a b - h c d :real = (h a b - h a d) + (h a d - h c d)``] THEN
6187  ASM_SIMP_TAC std_ss [GSYM BILINEAR_LSUB, GSYM BILINEAR_RSUB] THEN
6188  MATCH_MP_TAC ABS_TRIANGLE_LT THEN
6189  FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
6190   (MESON[REAL_LE_ADD2, REAL_LET_TRANS]
6191     ``(!x y. abs(h x y:real) <= B * abs x * abs y)
6192       ==> B * abs a * abs b + B * abs c * abs d < e
6193           ==> abs(h a b) + abs(h c d) < e``)) THEN
6194  REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN
6195  MATCH_MP_TAC(METIS [REAL_LT_ADD2, REAL_HALF_DOUBLE, REAL_MUL_SYM]
6196   ``x * B < e / &2:real /\ y * B < e / &2:real ==> B * x + B * y < e``) THEN
6197  CONJ_TAC THEN ASM_SIMP_TAC std_ss [GSYM REAL_LT_RDIV_EQ] THENL
6198   [ONCE_REWRITE_TAC[REAL_MUL_SYM], ALL_TAC] THEN
6199  MATCH_MP_TAC REAL_LET_TRANS THEN
6200  EXISTS_TAC ``e / &2 / (B * (abs b1 + abs b2 + &2)) *
6201             (abs b1 + abs b2 + &1:real)`` THEN
6202  (CONJ_TAC THENL
6203    [MATCH_MP_TAC REAL_LE_MUL2 THEN
6204     ASM_SIMP_TAC std_ss [ABS_POS, REAL_LT_IMP_LE] THEN
6205     ASM_SIMP_TAC std_ss [REAL_ARITH ``a <= b2 ==> a <= abs b1 + abs b2 + &1:real``] THEN
6206     ASM_MESON_TAC[REAL_ARITH
6207       ``abs(f - l:real) < abs b2 + &1 /\ abs(l) <= b1
6208        ==> abs(f) <= abs b1 + abs b2 + &1``],
6209     ONCE_REWRITE_TAC[real_div] THEN
6210     KNOW_TAC ``(abs b1 + abs b2 + 2) <> 0:real`` THENL
6211     [ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN MATCH_MP_TAC REAL_LT_IMP_NE THEN
6212      MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``2:real`` THEN
6213      REWRITE_TAC [REAL_LE_ADDL] THEN CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN
6214      ONCE_REWRITE_TAC [REAL_ARITH ``0 = 0 + 0:real``] THEN MATCH_MP_TAC REAL_LE_ADD2 THEN
6215      REWRITE_TAC [ABS_POS], ALL_TAC] THEN DISCH_TAC THEN
6216     ASM_SIMP_TAC arith_ss [REAL_LT_LMUL, REAL_LT_HALF1, GSYM REAL_MUL_ASSOC,
6217                  REAL_INV_MUL, REAL_LT_IMP_NE] THEN REWRITE_TAC [REAL_MUL_ASSOC] THEN
6218     REWRITE_TAC[METIS [real_div, REAL_MUL_RID, REAL_ARITH ``a * b * c = a * c * b:real``]
6219                 ``B * inv x * y < B <=> B * y / x < B * &1:real``] THEN
6220     ASM_SIMP_TAC arith_ss [REAL_LT_INV_EQ, REAL_LT_LMUL, REAL_LT_LDIV_EQ, REAL_MUL_RID,
6221                  REAL_ARITH ``&0 < abs x + abs y + &2:real``] THEN
6222     REAL_ARITH_TAC]));
6223
6224val LIM_BILINEAR = store_thm ("LIM_BILINEAR",
6225 ``!net:('a)net (h:real->real->real) f g l m.
6226        (f --> l) net /\ (g --> m) net /\ bilinear h
6227        ==> ((\x. h (f x) (g x)) --> (h l m)) net``,
6228  REPEAT STRIP_TAC THEN
6229  MP_TAC(ISPECL
6230   [``net:('a)net``, ``\x:one. T``, ``h:real->real->real``,
6231    ``\n:one. (f:'a->real)``, ``\n:one. (g:'a->real)``,
6232    ``\n:one. (l:real)``, ``\n:one. (m:real)``,
6233    ``abs(l:real)``, ``abs(m:real)``]
6234   UNIFORM_LIM_BILINEAR) THEN
6235  ASM_REWRITE_TAC[REAL_LE_REFL, EVENTUALLY_TRUE] THEN
6236  ASM_SIMP_TAC std_ss [GSYM dist, GSYM tendsto]);
6237
6238(* ------------------------------------------------------------------------- *)
6239(* These are special for limits out of the same vector space. *)
6240(* ------------------------------------------------------------------------- *)
6241
6242val LIM_WITHIN_ID = store_thm ("LIM_WITHIN_ID",
6243 ``!a s. ((\x. x) --> a) (at a within s)``,
6244  REWRITE_TAC[LIM_WITHIN] THEN MESON_TAC[]);
6245
6246val LIM_AT_ID = store_thm ("LIM_AT_ID",
6247 ``!a. ((\x. x) --> a) (at a)``,
6248  ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN REWRITE_TAC[LIM_WITHIN_ID]);
6249
6250val LIM_AT_ZERO = store_thm ("LIM_AT_ZERO",
6251 ``!f:real->real l a.
6252    (f --> l) (at a) <=> ((\x. f(a + x)) --> l) (at(0))``,
6253  REPEAT GEN_TAC THEN REWRITE_TAC[LIM_AT] THEN
6254  AP_TERM_TAC THEN ABS_TAC THEN
6255  ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[] THEN
6256  AP_TERM_TAC THEN ABS_TAC THEN
6257  ASM_CASES_TAC ``&0 < d:real`` THEN ASM_REWRITE_TAC[] THEN
6258  EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``x:real`` THENL
6259  [FIRST_X_ASSUM(MP_TAC o SPEC ``a + x:real``) THEN
6260   SIMP_TAC std_ss [dist, REAL_ADD_SUB, REAL_SUB_RZERO],
6261  FIRST_X_ASSUM(MP_TAC o SPEC ``x - a:real``) THEN
6262  SIMP_TAC std_ss [dist, REAL_SUB_RZERO, REAL_SUB_ADD2]]);
6263
6264(* ------------------------------------------------------------------------- *)
6265(* It's also sometimes useful to extract the limit point from the net. *)
6266(* ------------------------------------------------------------------------- *)
6267
6268val netlimit = new_definition ("netlimit",
6269 ``netlimit net = @a. !x. ~(netord net x a)``);
6270
6271val NETLIMIT_WITHIN = store_thm ("NETLIMIT_WITHIN",
6272 ``!a:real s. ~(trivial_limit (at a within s))
6273    ==> (netlimit (at a within s) = a)``,
6274  REWRITE_TAC[trivial_limit, netlimit, AT, WITHIN, DE_MORGAN_THM] THEN
6275  REPEAT STRIP_TAC THEN MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN
6276  SUBGOAL_THEN
6277   ``!x:real. ~(&0 < dist(x,a) /\ dist(x,a) <= dist(a,a) /\ x IN s)``
6278    ASSUME_TAC THENL
6279    [ASM_MESON_TAC[DIST_REFL, REAL_NOT_LT], ASM_MESON_TAC[]]);
6280
6281val NETLIMIT_AT = store_thm ("NETLIMIT_AT",
6282 ``!a. netlimit(at a) = a``,
6283  GEN_TAC THEN ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
6284  MATCH_MP_TAC NETLIMIT_WITHIN THEN
6285  SIMP_TAC std_ss [TRIVIAL_LIMIT_AT, WITHIN_UNIV]);
6286
6287(* ------------------------------------------------------------------------- *)
6288(* Transformation of limit. *)
6289(* ------------------------------------------------------------------------- *)
6290
6291val LIM_TRANSFORM = store_thm ("LIM_TRANSFORM",
6292 ``!net f g l.
6293  ((\x. f x - g x) --> 0) net /\ (f --> l) net ==> (g --> l) net``,
6294  REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN
6295  DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG) THEN MATCH_MP_TAC EQ_IMPLIES THEN
6296  AP_THM_TAC THEN BINOP_TAC THEN SIMP_TAC std_ss [FUN_EQ_THM] THEN
6297  REAL_ARITH_TAC);
6298
6299val LIM_TRANSFORM_EVENTUALLY = store_thm ("LIM_TRANSFORM_EVENTUALLY",
6300 ``!net f g l.
6301   eventually (\x. f x = g x) net /\ (f --> l) net ==> (g --> l) net``,
6302  REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN STRIP_TAC THEN
6303  KNOW_TAC ``((\ (x:'a). f x - g x) --> (0:real)) net`` THENL
6304  [METIS_TAC [LIM_EVENTUALLY], ALL_TAC] THEN
6305  METIS_TAC[LIM_TRANSFORM]);
6306
6307val LIM_TRANSFORM_WITHIN = store_thm ("LIM_TRANSFORM_WITHIN",
6308  ``!f g x s d. &0 < d /\
6309  (!x'. x' IN s /\ &0 < dist(x',x) /\ dist(x',x) < d ==> (f(x') = g(x'))) /\
6310  (f --> l) (at x within s) ==> (g --> l) (at x within s)``,
6311  REPEAT GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN
6312  DISCH_TAC THEN DISCH_TAC THEN
6313  MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] LIM_TRANSFORM) THEN
6314  REWRITE_TAC[LIM_WITHIN] THEN REPEAT STRIP_TAC THEN EXISTS_TAC ``d:real`` THEN
6315  ASM_SIMP_TAC std_ss [REAL_SUB_REFL, DIST_REFL]);
6316
6317val LIM_TRANSFORM_AT = store_thm ("LIM_TRANSFORM_AT",
6318 ``!f g x d. &0 < d /\
6319  (!x'. &0 < dist(x',x) /\ dist(x',x) < d ==> (f(x') = g(x'))) /\
6320  (f --> l) (at x) ==> (g --> l) (at x)``,
6321  ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN MESON_TAC[LIM_TRANSFORM_WITHIN]);
6322
6323val LIM_TRANSFORM_EQ = store_thm ("LIM_TRANSFORM_EQ",
6324 ``!net f:'a->real g l.
6325  ((\x. f x - g x) --> 0) net ==> ((f --> l) net <=> (g --> l) net)``,
6326  REPEAT STRIP_TAC THEN EQ_TAC THEN
6327  DISCH_TAC THEN MATCH_MP_TAC LIM_TRANSFORM THENL
6328  [EXISTS_TAC ``f:'a->real`` THEN ASM_REWRITE_TAC[],
6329  EXISTS_TAC ``g:'a->real`` THEN ASM_REWRITE_TAC[] THEN
6330  ONCE_REWRITE_TAC[GSYM LIM_NEG_EQ] THEN BETA_TAC THEN
6331  ASM_REWRITE_TAC[REAL_NEG_SUB, REAL_NEG_0]]);
6332
6333val LIM_TRANSFORM_WITHIN_SET = store_thm ("LIM_TRANSFORM_WITHIN_SET",
6334 ``!f a s t.
6335  eventually (\x. x IN s <=> x IN t) (at a)
6336  ==> ((f --> l) (at a within s) <=> (f --> l) (at a within t))``,
6337  REPEAT GEN_TAC THEN REWRITE_TAC[EVENTUALLY_AT, LIM_WITHIN] THEN
6338  DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
6339  EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
6340  FIRST_X_ASSUM(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN
6341  DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN
6342  EXISTS_TAC ``min d k:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
6343  ASM_MESON_TAC[]);
6344
6345val LIM_TRANSFORM_WITHIN_SET_IMP = store_thm ("LIM_TRANSFORM_WITHIN_SET_IMP",
6346 ``!f l a s t.
6347  eventually (\x. x IN t ==> x IN s) (at a) /\ (f --> l) (at a within s)
6348  ==> (f --> l) (at a within t)``,
6349  REPEAT GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO, EVENTUALLY_AT, LIM_WITHIN] THEN
6350  DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
6351  DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
6352  FIRST_X_ASSUM(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN
6353  DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN
6354  EXISTS_TAC ``min d k:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
6355  ASM_MESON_TAC[]);
6356
6357(* ------------------------------------------------------------------------- *)
6358(* Common case assuming being away from some crucial point like 0.           *)
6359(* ------------------------------------------------------------------------- *)
6360
6361val LIM_TRANSFORM_AWAY_WITHIN = store_thm ("LIM_TRANSFORM_AWAY_WITHIN",
6362 ``!f:real->real g a b s. ~(a = b) /\
6363  (!x. x IN s /\ ~(x = a) /\ ~(x = b) ==> (f(x) = g(x))) /\
6364  (f --> l) (at a within s) ==> (g --> l) (at a within s)``,
6365  REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN
6366  MAP_EVERY EXISTS_TAC [``f:real->real``, ``dist(a:real,b)``] THEN
6367  ASM_REWRITE_TAC[GSYM DIST_NZ] THEN X_GEN_TAC ``y:real`` THEN
6368  REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
6369  ASM_MESON_TAC[DIST_SYM, REAL_LT_REFL]);
6370
6371val LIM_TRANSFORM_AWAY_AT = store_thm ("LIM_TRANSFORM_AWAY_AT",
6372 ``!f:real->real g a b. ~(a = b) /\
6373  (!x. ~(x = a) /\ ~(x = b) ==> (f(x) = g(x))) /\
6374  (f --> l) (at a) ==> (g --> l) (at a)``,
6375  ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
6376  MESON_TAC[LIM_TRANSFORM_AWAY_WITHIN]);
6377
6378(* ------------------------------------------------------------------------- *)
6379(* Alternatively, within an open set. *)
6380(* ------------------------------------------------------------------------- *)
6381
6382val LIM_TRANSFORM_WITHIN_OPEN = store_thm ("LIM_TRANSFORM_WITHIN_OPEN",
6383 ``!f g:real->real s a l. open s /\ a IN s /\
6384  (!x. x IN s /\ ~(x = a) ==> (f x = g x)) /\
6385  (f --> l) (at a) ==> (g --> l) (at a)``,
6386  REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_AT THEN
6387  EXISTS_TAC ``f:real->real`` THEN ASM_REWRITE_TAC[] THEN
6388  UNDISCH_TAC ``open s`` THEN GEN_REWR_TAC LAND_CONV [OPEN_CONTAINS_BALL] THEN
6389  DISCH_THEN(MP_TAC o SPEC ``a:real``) THEN ASM_REWRITE_TAC[] THEN
6390  STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN POP_ASSUM MP_TAC THEN
6391  REWRITE_TAC[SUBSET_DEF, IN_BALL] THEN ASM_MESON_TAC[DIST_NZ, DIST_SYM]);
6392
6393val LIM_TRANSFORM_WITHIN_OPEN_IN = store_thm ("LIM_TRANSFORM_WITHIN_OPEN_IN",
6394 ``!f g:real->real s t a l.
6395  open_in (subtopology euclidean t) s /\ a IN s /\
6396  (!x. x IN s /\ ~(x = a) ==> (f x = g x)) /\
6397  (f --> l) (at a within t) ==> (g --> l) (at a within t)``,
6398  REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN
6399  EXISTS_TAC ``f:real->real`` THEN ASM_REWRITE_TAC[] THEN
6400  UNDISCH_TAC ``open_in (subtopology euclidean t) s`` THEN
6401  GEN_REWR_TAC LAND_CONV [OPEN_IN_CONTAINS_BALL] THEN
6402  DISCH_THEN(MP_TAC o SPEC ``a:real`` o CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN
6403  STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN POP_ASSUM MP_TAC THEN
6404  REWRITE_TAC[SUBSET_DEF, IN_INTER, IN_BALL] THEN ASM_MESON_TAC[DIST_NZ, DIST_SYM]);
6405
6406(* ------------------------------------------------------------------------- *)
6407(* Another quite common idiom of an explicit conditional in a sequence. *)
6408(* ------------------------------------------------------------------------- *)
6409
6410val LIM_CASES_FINITE_SEQUENTIALLY = store_thm ("LIM_CASES_FINITE_SEQUENTIALLY",
6411 ``!f g l. FINITE {n | P n}
6412  ==> (((\n. if P n then f n else g n) --> l) sequentially <=>
6413  (g --> l) sequentially)``,
6414  REPEAT STRIP_TAC THEN EQ_TAC THEN
6415  MATCH_MP_TAC(REWRITE_RULE[GSYM AND_IMP_INTRO] LIM_TRANSFORM_EVENTUALLY) THEN
6416  FIRST_ASSUM(MP_TAC o SPEC ``\n:num. n`` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN
6417  SIMP_TAC std_ss [GSPECIFICATION, LEFT_IMP_EXISTS_THM] THEN
6418  X_GEN_TAC ``N:num`` THEN DISCH_TAC THEN SIMP_TAC std_ss [EVENTUALLY_SEQUENTIALLY] THEN
6419  EXISTS_TAC ``N + 1:num`` THEN
6420  METIS_TAC[ARITH_PROVE ``~(x <= n:num /\ n + 1 <= x)``]);
6421
6422val lemma = prove (
6423 ``(if p then x else y) = (if ~p then y else x)``,
6424 RW_TAC std_ss []);
6425
6426val LIM_CASES_COFINITE_SEQUENTIALLY = store_thm ("LIM_CASES_COFINITE_SEQUENTIALLY",
6427 ``!f g l. FINITE {n | ~P n}
6428  ==> (((\n. if P n then f n else g n) --> l) sequentially <=>
6429  (f --> l) sequentially)``,
6430  ONCE_REWRITE_TAC[lemma] THEN
6431  SIMP_TAC std_ss [LIM_CASES_FINITE_SEQUENTIALLY]);
6432
6433val LIM_CASES_SEQUENTIALLY = store_thm ("LIM_CASES_SEQUENTIALLY",
6434 ``!f g l m. (((\n. if m <= n then f n else g n) --> l) sequentially <=>
6435  (f --> l) sequentially) /\
6436   (((\n. if m < n then f n else g n) --> l) sequentially <=>
6437  (f --> l) sequentially) /\
6438   (((\n. if n <= m then f n else g n) --> l) sequentially <=>
6439  (g --> l) sequentially) /\
6440   (((\n. if n < m then f n else g n) --> l) sequentially <=>
6441  (g --> l) sequentially)``,
6442  SIMP_TAC std_ss [LIM_CASES_FINITE_SEQUENTIALLY, LIM_CASES_COFINITE_SEQUENTIALLY,
6443  NOT_LESS, NOT_LESS_EQUAL, FINITE_NUMSEG_LT, FINITE_NUMSEG_LE]);
6444
6445(* ------------------------------------------------------------------------- *)
6446(* A congruence rule allowing us to transform limits assuming not at point.  *)
6447(* ------------------------------------------------------------------------- *)
6448
6449val LIM_CONG_WITHIN = store_thm ("LIM_CONG_WITHIN",
6450 ``(!x. ~(x = a) ==> (f x = g x))
6451  ==> (((\x. f x) --> l) (at a within s) <=> ((g --> l) (at a within s)))``,
6452 REWRITE_TAC[LIM_WITHIN, GSYM DIST_NZ] THEN SIMP_TAC std_ss []);
6453
6454val LIM_CONG_AT = store_thm ("LIM_CONG_AT",
6455 ``(!x. ~(x = a) ==> (f x = g x))
6456  ==> (((\x. f x) --> l) (at a) <=> ((g --> l) (at a)))``,
6457 REWRITE_TAC[LIM_AT, GSYM DIST_NZ] THEN SIMP_TAC std_ss []);
6458
6459(* ------------------------------------------------------------------------- *)
6460(* Useful lemmas on closure and set of possible sequential limits.           *)
6461(* ------------------------------------------------------------------------- *)
6462
6463val CLOSURE_SEQUENTIAL = store_thm ("CLOSURE_SEQUENTIAL",
6464 ``!s l:real.
6465  l IN closure(s) <=> ?x. (!n. x(n) IN s) /\ (x --> l) sequentially``,
6466  SIMP_TAC std_ss [closure, IN_UNION, LIMPT_SEQUENTIAL, GSPECIFICATION, IN_DELETE] THEN
6467  REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
6468   `((b ==> c) /\ (~a /\ c ==> b)) /\ (a ==> c) ==> (a \/ b <=> c)`) THEN
6469  CONJ_TAC THENL [MESON_TAC[], ALL_TAC] THEN DISCH_TAC THEN
6470  EXISTS_TAC ``\n:num. l:real`` THEN ASM_REWRITE_TAC[LIM_CONST]);
6471
6472val CLOSED_CONTAINS_SEQUENTIAL_LIMIT = store_thm ("CLOSED_CONTAINS_SEQUENTIAL_LIMIT",
6473 ``!s x l:real.
6474  closed s /\ (!n. x n IN s) /\ (x --> l) sequentially ==> l IN s``,
6475  MESON_TAC[CLOSURE_SEQUENTIAL, CLOSURE_CLOSED]);
6476
6477val CLOSED_SEQUENTIAL_LIMITS = store_thm ("CLOSED_SEQUENTIAL_LIMITS",
6478 ``!s. closed s <=>
6479   !x l. (!n. x(n) IN s) /\ (x --> l) sequentially ==> l IN s``,
6480  MESON_TAC[CLOSURE_SEQUENTIAL, CLOSURE_CLOSED,
6481  CLOSED_LIMPT, LIMPT_SEQUENTIAL, IN_DELETE]);
6482
6483val CLOSED_APPROACHABLE = store_thm ("CLOSED_APPROACHABLE",
6484 ``!x s. closed s
6485  ==> ((!e. &0 < e ==> ?y. y IN s /\ dist(y,x) < e) <=> x IN s)``,
6486  MESON_TAC[CLOSURE_CLOSED, CLOSURE_APPROACHABLE]);
6487
6488val IN_CLOSURE_DELETE = store_thm ("IN_CLOSURE_DELETE",
6489 ``!s x:real. x IN closure(s DELETE x) <=> x limit_point_of s``,
6490  SIMP_TAC std_ss [CLOSURE_APPROACHABLE, LIMPT_APPROACHABLE, IN_DELETE, CONJ_ASSOC]);
6491
6492val DENSE_IMP_PERFECT = store_thm ("DENSE_IMP_PERFECT",
6493 ``!s. (closure s = univ(:real)) ==> !x. x IN s ==> x limit_point_of s``,
6494  REPEAT STRIP_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
6495  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
6496  KNOW_TAC ``~(!x'. ~(x' = x) /\ dist (x',x) < e ==> ~(x' IN s))`` THENL
6497  [ALL_TAC, METIS_TAC []] THEN DISCH_TAC THEN
6498  MP_TAC(ISPECL [``x:real``, ``e / &2:real``] REAL_CHOOSE_DIST) THEN
6499  KNOW_TAC ``~(?y. dist (x,y) = e / &2)`` THENL
6500  [ALL_TAC, ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE, REAL_LT_HALF1]] THEN
6501  DISCH_THEN(X_CHOOSE_TAC ``y:real``) THEN
6502  FIRST_ASSUM(MP_TAC o SPEC ``y:real`` o MATCH_MP (SET_RULE
6503   ``(s = UNIV) ==> !x. x IN s``)) THEN
6504  REWRITE_TAC[CLOSURE_APPROACHABLE] THEN
6505  DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN
6506  ASM_SIMP_TAC std_ss [REAL_HALF, NOT_EXISTS_THM] THEN
6507  X_GEN_TAC ``z:real`` THEN FIRST_X_ASSUM(MP_TAC o SPEC ``z:real``) THEN
6508  ASM_CASES_TAC ``(z:real) IN s`` THEN ASM_REWRITE_TAC[] THEN
6509  SIMP_TAC std_ss [] THEN STRIP_TAC THENL
6510  [METIS_TAC [REAL_LE_LT, REAL_NOT_LT], ALL_TAC] THEN
6511  DISCH_TAC THEN UNDISCH_TAC ``~(dist (z,x) < e)`` THEN REWRITE_TAC [] THEN
6512  GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF_DOUBLE] THEN
6513  MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``dist (z,y) + dist (y,x)`` THEN
6514  REWRITE_TAC [DIST_TRIANGLE] THEN ONCE_REWRITE_TAC [DIST_SYM] THEN
6515  ASM_REWRITE_TAC [] THEN METIS_TAC [REAL_LT_RADD, DIST_SYM]);
6516
6517val DENSE_LIMIT_POINTS = store_thm ("DENSE_LIMIT_POINTS",
6518 ``!x. ({x | x limit_point_of s} = univ(:real)) <=> (closure s = univ(:real))``,
6519  GEN_TAC THEN EQ_TAC THENL [SIMP_TAC std_ss [closure] THEN SET_TAC[], DISCH_TAC] THEN
6520  FIRST_ASSUM(MP_TAC o MATCH_MP DENSE_IMP_PERFECT) THEN
6521  RULE_ASSUM_TAC(REWRITE_RULE[closure]) THEN ASM_SET_TAC[]);
6522
6523(* ------------------------------------------------------------------------- *)
6524(* Some other lemmas about sequences.                                        *)
6525(* ------------------------------------------------------------------------- *)
6526
6527val SEQ_OFFSET = store_thm ("SEQ_OFFSET",
6528 ``!f l k. (f --> l) sequentially ==> ((\i. f(i + k)) --> l) sequentially``,
6529  REWRITE_TAC[LIM_SEQUENTIALLY] THEN
6530  MESON_TAC[ARITH_PROVE ``N <= n ==> N <= n + k:num``]);
6531
6532val SEQ_OFFSET_NEG = store_thm ("SEQ_OFFSET_NEG",
6533 ``!f l k. (f --> l) sequentially ==> ((\i. f(i - k)) --> l) sequentially``,
6534  REWRITE_TAC[LIM_SEQUENTIALLY] THEN
6535  MESON_TAC[ARITH_PROVE ``N + k <= n ==> N <= n - k:num``]);
6536
6537val SEQ_OFFSET_REV = store_thm ("SEQ_OFFSET_REV",
6538 ``!f l k. ((\i. f(i + k)) --> l) sequentially ==> (f --> l) sequentially``,
6539  REWRITE_TAC[LIM_SEQUENTIALLY] THEN
6540  MESON_TAC[ARITH_PROVE ``N + k <= n ==> N <= n - k /\ ((n - k) + k = n:num)``]);
6541
6542val SEQ_HARMONIC_OFFSET = store_thm ("SEQ_HARMONIC_OFFSET",
6543 ``!a. ((\n. inv(&n + a)) --> 0) sequentially``,
6544  GEN_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY] THEN
6545  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
6546  ASSUME_TAC REAL_ARCH_INV THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN
6547  ASM_REWRITE_TAC [] THEN DISCH_THEN (X_CHOOSE_THEN ``N:num`` STRIP_ASSUME_TAC) THEN
6548  X_CHOOSE_THEN ``M:num`` STRIP_ASSUME_TAC
6549  (SPEC ``-a:real`` SIMP_REAL_ARCH) THEN
6550  EXISTS_TAC ``M + N:num`` THEN REWRITE_TAC[DIST_0] THEN
6551  X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN
6552  MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``inv (&N:real)`` THEN
6553  KNOW_TAC ``(&n + a:real) <> 0`` THENL
6554  [ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN MATCH_MP_TAC REAL_LT_IMP_NE THEN
6555   UNDISCH_TAC ``-a <= &M:real`` THEN
6556   GEN_REWR_TAC LAND_CONV [GSYM REAL_LE_NEG] THEN REWRITE_TAC [REAL_NEG_NEG] THEN
6557   DISCH_TAC THEN FULL_SIMP_TAC arith_ss [GSYM REAL_LE, GSYM REAL_ADD] THEN
6558   KNOW_TAC ``&M + &N + (-&M) <= &n + a:real`` THENL
6559   [FULL_SIMP_TAC arith_ss [REAL_LE_ADD2], ALL_TAC] THEN
6560   REWRITE_TAC [GSYM real_sub] THEN ONCE_REWRITE_TAC [REAL_ADD_COMM] THEN
6561   REWRITE_TAC [REAL_ADD_SUB_ALT] THEN DISCH_TAC THEN
6562   MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``&N:real`` THEN
6563   FULL_SIMP_TAC std_ss [REAL_LT_INV_EQ], ALL_TAC] THEN DISCH_TAC THEN
6564  BETA_TAC THEN ASM_SIMP_TAC arith_ss [ABS_INV] THEN
6565  MATCH_MP_TAC REAL_LE_INV2 THEN FULL_SIMP_TAC std_ss [REAL_LT_INV_EQ] THEN
6566  RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE, GSYM REAL_OF_NUM_ADD]) THEN
6567  ASM_REAL_ARITH_TAC);
6568
6569val SEQ_HARMONIC = store_thm ("SEQ_HARMONIC",
6570 ``((\n. inv(&n)) --> 0) sequentially``,
6571  MP_TAC(SPEC ``&0:real`` SEQ_HARMONIC_OFFSET) THEN REWRITE_TAC[REAL_ADD_RID]);
6572
6573(* ------------------------------------------------------------------------- *)
6574(* More properties of closed balls.                                          *)
6575(* ------------------------------------------------------------------------- *)
6576
6577val CLOSED_CBALL = store_thm ("CLOSED_CBALL",
6578 ``!x:real e. closed(cball(x,e))``,
6579  REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS, IN_CBALL, dist] THEN
6580  GEN_TAC THEN GEN_TAC THEN X_GEN_TAC ``s:num->real`` THEN
6581  X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN
6582  MATCH_MP_TAC(ISPEC ``sequentially`` LIM_ABS_UBOUND) THEN
6583  EXISTS_TAC ``\n. x - (s:num->real) n`` THEN
6584  REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY, EVENTUALLY_SEQUENTIALLY] THEN
6585  ASM_SIMP_TAC std_ss [LIM_SUB, LIM_CONST, SEQUENTIALLY]);
6586
6587val IN_INTERIOR_CBALL = store_thm ("IN_INTERIOR_CBALL",
6588 ``!x s. x IN interior s <=> ?e. &0 < e /\ cball(x,e) SUBSET s``,
6589  SIMP_TAC std_ss [interior, GSPECIFICATION] THEN
6590  MESON_TAC[OPEN_CONTAINS_CBALL, SUBSET_TRANS,
6591  BALL_SUBSET_CBALL, CENTRE_IN_BALL, OPEN_BALL]);
6592
6593val LIMPT_BALL = store_thm ("LIMPT_BALL",
6594 ``!x:real y e. y limit_point_of ball(x,e) <=> &0 < e /\ y IN cball(x,e)``,
6595  REPEAT GEN_TAC THEN ASM_CASES_TAC ``&0 < e:real`` THENL
6596  [ALL_TAC, ASM_MESON_TAC[LIMPT_EMPTY, REAL_NOT_LT, BALL_EQ_EMPTY]] THEN
6597  ASM_REWRITE_TAC[] THEN EQ_TAC THENL
6598  [MESON_TAC[CLOSED_CBALL, CLOSED_LIMPT, LIMPT_SUBSET, BALL_SUBSET_CBALL],
6599   REWRITE_TAC[IN_CBALL, LIMPT_APPROACHABLE, IN_BALL]] THEN
6600  DISCH_TAC THEN X_GEN_TAC ``d:real`` THEN DISCH_TAC THEN
6601  ASM_CASES_TAC ``y:real = x`` THEN ASM_REWRITE_TAC[DIST_NZ] THENL
6602  [MP_TAC(SPECL [``d:real``, ``e:real``] REAL_DOWN2) THEN
6603   ASM_REWRITE_TAC[] THEN
6604   GEN_MESON_TAC 0 40 1 [REAL_CHOOSE_DIST, DIST_SYM, REAL_LT_IMP_LE],
6605   ALL_TAC] THEN
6606  MP_TAC(SPECL [``abs(y:real - x)``, ``d:real``] REAL_DOWN2) THEN
6607  RULE_ASSUM_TAC(REWRITE_RULE[DIST_NZ, dist]) THEN ASM_REWRITE_TAC[] THEN
6608  DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN
6609  EXISTS_TAC ``(y:real) - (k / dist(y,x)) * (y - x)`` THEN
6610  REWRITE_TAC[dist, REAL_ARITH ``(y - c * z) - y = -c * z:real``] THEN
6611  ASM_SIMP_TAC std_ss [ABS_MUL, ABS_DIV, ABS_ABS, ABS_NEG, REAL_POS_NZ] THEN
6612  ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_POS_NZ] THEN
6613  REWRITE_TAC[REAL_ARITH ``x - (y - k * (y - x)) = (&1 - k) * (x - y:real)``] THEN
6614  ASM_SIMP_TAC std_ss [REAL_ARITH ``&0 < k ==> &0 < abs k:real``, ABS_MUL] THEN
6615  ASM_SIMP_TAC std_ss [REAL_ARITH ``&0 < k /\ k < d ==> abs k < d:real``] THEN
6616  MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``abs(x:real - y)`` THEN
6617  ASM_REWRITE_TAC[] THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN
6618  KNOW_TAC ``0:real < abs (x - y)`` THENL [ASM_MESON_TAC[ABS_SUB], ALL_TAC] THEN
6619  DISCH_TAC THEN ASM_SIMP_TAC std_ss [REAL_LT_RMUL] THEN
6620  MATCH_MP_TAC(REAL_ARITH ``&0 < k /\ k < &1 ==> abs(&1 - k) < &1:real``) THEN
6621  ASM_SIMP_TAC std_ss [REAL_LT_LDIV_EQ, REAL_LT_RDIV_EQ, REAL_MUL_LZERO,
6622   REAL_MUL_LID]);
6623
6624val CLOSURE_BALL = store_thm ("CLOSURE_BALL",
6625 ``!x:real e. &0 < e ==> (closure(ball(x,e)) = cball(x,e))``,
6626  SIMP_TAC std_ss [EXTENSION, closure, GSPECIFICATION, IN_UNION, LIMPT_BALL] THEN
6627  REWRITE_TAC[IN_BALL, IN_CBALL] THEN REAL_ARITH_TAC);
6628
6629val INTERIOR_BALL = store_thm ("INTERIOR_BALL",
6630 ``!a r. interior(ball(a,r)) = ball(a,r)``,
6631  SIMP_TAC std_ss [INTERIOR_OPEN, OPEN_BALL]);
6632
6633val INTERIOR_CBALL = store_thm ("INTERIOR_CBALL",
6634 ``!x:real e. interior(cball(x,e)) = ball(x,e)``,
6635  REPEAT GEN_TAC THEN ASM_CASES_TAC ``&0 <= e:real`` THENL
6636  [ALL_TAC,
6637   SUBGOAL_THEN ``(cball(x:real,e) = {}) /\ (ball(x:real,e) = {})``
6638    (fn th => REWRITE_TAC[th, INTERIOR_EMPTY]) THEN
6639   REWRITE_TAC[IN_BALL, IN_CBALL, EXTENSION, NOT_IN_EMPTY] THEN
6640   CONJ_TAC THEN X_GEN_TAC ``y:real`` THEN
6641   MP_TAC(ISPECL [``x:real``, ``y:real``] DIST_POS_LE) THEN
6642   POP_ASSUM MP_TAC THEN REAL_ARITH_TAC] THEN
6643  MATCH_MP_TAC INTERIOR_UNIQUE THEN
6644  REWRITE_TAC[BALL_SUBSET_CBALL, OPEN_BALL] THEN
6645  X_GEN_TAC ``t:real->bool`` THEN
6646  SIMP_TAC std_ss [SUBSET_DEF, IN_CBALL, IN_BALL, REAL_LT_LE] THEN STRIP_TAC THEN
6647  X_GEN_TAC ``z:real`` THEN DISCH_TAC THEN DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
6648  UNDISCH_TAC ``open t`` THEN REWRITE_TAC [open_def] THEN
6649  DISCH_THEN(MP_TAC o SPEC ``z:real``) THEN
6650  ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN ``d:real`` MP_TAC) THEN
6651  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6652  ASM_CASES_TAC ``z:real = x`` THENL
6653  [FIRST_X_ASSUM SUBST_ALL_TAC THEN
6654  FIRST_X_ASSUM(X_CHOOSE_TAC ``k:real`` o MATCH_MP REAL_DOWN) THEN
6655  SUBGOAL_THEN ``?w:real. dist(w,x) = k`` STRIP_ASSUME_TAC THENL
6656  [ASM_MESON_TAC[REAL_CHOOSE_DIST, DIST_SYM, REAL_LT_IMP_LE],
6657   ASM_MESON_TAC[REAL_NOT_LE, DIST_REFL, DIST_SYM]],
6658  RULE_ASSUM_TAC(REWRITE_RULE[DIST_NZ]) THEN
6659  DISCH_THEN(MP_TAC o SPEC ``z + ((d / &2) / dist(z,x)) * (z - x:real)``) THEN
6660  FULL_SIMP_TAC arith_ss [dist, REAL_ADD_SUB, ABS_MUL, ABS_DIV,
6661  ABS_ABS, ABS_N, REAL_POS_NZ, REAL_ARITH ``0 < 2:real``] THEN
6662  ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, GSYM dist, REAL_POS_NZ] THEN
6663  ASM_SIMP_TAC arith_ss [REAL_LT_LDIV_EQ, REAL_LT] THEN
6664  ASM_REWRITE_TAC [REAL_ARITH ``abs d < d * &2 <=> &0 < d:real``] THEN
6665  DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN REWRITE_TAC[dist] THEN
6666  REWRITE_TAC[REAL_ARITH ``x - (z + k * (z - x)) = (&1 + k) * (x - z:real)``] THEN
6667  REWRITE_TAC[REAL_NOT_LE, ABS_MUL] THEN
6668  GEN_REWR_TAC LAND_CONV [GSYM REAL_MUL_LID] THEN
6669  ONCE_REWRITE_TAC[ABS_SUB] THEN
6670  ASM_SIMP_TAC std_ss [REAL_LT_RMUL, GSYM dist] THEN
6671  MATCH_MP_TAC(REAL_ARITH ``&0 < x ==> &1:real < abs(&1 + x)``) THEN
6672  ONCE_REWRITE_TAC[DIST_SYM] THEN
6673  ASM_SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT, dist]]);
6674
6675val FRONTIER_BALL = store_thm ("FRONTIER_BALL",
6676 ``!a e. &0 < e ==> (frontier(ball(a,e)) = sphere(a,e))``,
6677  SIMP_TAC std_ss [frontier, sphere, CLOSURE_BALL, INTERIOR_OPEN, OPEN_BALL,
6678   REAL_LT_IMP_LE] THEN
6679  SIMP_TAC std_ss [EXTENSION, IN_DIFF, GSPECIFICATION, IN_BALL, IN_CBALL] THEN
6680  REAL_ARITH_TAC);
6681
6682val FRONTIER_CBALL = store_thm ("FRONTIER_CBALL",
6683 ``!a e. (frontier(cball(a,e)) = sphere(a,e))``,
6684  SIMP_TAC std_ss [frontier, sphere, INTERIOR_CBALL, CLOSED_CBALL, CLOSURE_CLOSED,
6685   REAL_LT_IMP_LE] THEN
6686  SIMP_TAC std_ss [EXTENSION, IN_DIFF, SPECIFICATION, IN_BALL, IN_CBALL, dist] THEN
6687  GEN_REWR_TAC (QUANT_CONV o QUANT_CONV o QUANT_CONV o RAND_CONV) [GSYM SPECIFICATION] THEN
6688  SIMP_TAC std_ss [GSPECIFICATION] THEN REAL_ARITH_TAC);
6689
6690val CBALL_EQ_EMPTY = store_thm ("CBALL_EQ_EMPTY",
6691 ``!x e. (cball(x,e) = {}) <=> e < &0``,
6692  REWRITE_TAC[EXTENSION, IN_CBALL, NOT_IN_EMPTY, REAL_NOT_LE] THEN
6693  MESON_TAC[DIST_POS_LE, DIST_REFL, REAL_LTE_TRANS]);
6694
6695val CBALL_EMPTY = store_thm ("CBALL_EMPTY",
6696 ``!x e. e < &0 ==> (cball(x,e) = {})``,
6697 REWRITE_TAC[CBALL_EQ_EMPTY]);
6698
6699val CBALL_EQ_SING = store_thm ("CBALL_EQ_SING",
6700 ``!x:real e. (cball(x,e) = {x}) <=> (e = &0)``,
6701  REPEAT GEN_TAC THEN REWRITE_TAC[EXTENSION, IN_CBALL, IN_SING] THEN
6702  EQ_TAC THENL [ALL_TAC, MESON_TAC[DIST_LE_0]] THEN
6703  DISCH_THEN(fn th => MP_TAC(SPEC ``x + (e / &2) * 1:real`` th) THEN
6704  MP_TAC(SPEC ``x:real`` th)) THEN
6705  REWRITE_TAC[dist, REAL_ARITH ``x - (x + e):real = -e``,
6706   REAL_ARITH ``(x + e = x) <=> (e:real = 0)``] THEN
6707  REWRITE_TAC[ABS_NEG, ABS_MUL, REAL_ENTIRE, ABS_0, REAL_SUB_REFL] THEN
6708  SIMP_TAC std_ss [ABS_1, REAL_ARITH ``~(1 = 0:real)``] THEN
6709  SIMP_TAC arith_ss [REAL_MUL_RID, REAL_EQ_LDIV_EQ,
6710   REAL_ARITH ``0 < 2:real``, REAL_MUL_LZERO] THEN
6711  GEN_REWR_TAC LAND_CONV [REAL_LE_LT] THEN RW_TAC arith_ss [] THEN
6712  RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN ASM_REWRITE_TAC [abs] THEN
6713  COND_CASES_TAC THENL
6714  [FULL_SIMP_TAC std_ss [REAL_LE_LT] THEN DISJ1_TAC THEN
6715   ASM_SIMP_TAC std_ss [REAL_LT_HALF2], ALL_TAC] THEN
6716  UNDISCH_TAC ``0 < e:real`` THEN GEN_REWR_TAC LAND_CONV [GSYM REAL_LT_HALF1] THEN
6717  DISCH_TAC THEN FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN METIS_TAC [REAL_LT_ANTISYM]);
6718
6719val CBALL_SING = store_thm ("CBALL_SING",
6720 ``!x e. (e = &0) ==> (cball(x,e) = {x})``,
6721 REWRITE_TAC[CBALL_EQ_SING]);
6722
6723val SPHERE_SING = store_thm ("SPHERE_SING",
6724 ``!x e. (e = &0) ==> (sphere(x,e) = {x})``,
6725  SIMP_TAC std_ss [sphere, DIST_EQ_0, GSPEC_EQ, GSPEC_EQ2]);
6726
6727val SPHERE_EQ_SING = store_thm ("SPHERE_EQ_SING",
6728 ``!a:real r x. (sphere(a,r) = {x}) <=> (x = a) /\ (r = &0)``,
6729  REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [SPHERE_SING] THEN
6730  ASM_CASES_TAC ``r < &0:real`` THEN ASM_SIMP_TAC std_ss [SPHERE_EMPTY, NOT_INSERT_EMPTY] THEN
6731  ASM_CASES_TAC ``r = &0:real`` THEN ASM_SIMP_TAC std_ss [SPHERE_SING] THENL
6732  [ASM_SET_TAC[], ALL_TAC] THEN
6733  MATCH_MP_TAC(SET_RULE
6734   ``!y. (x IN s ==> y IN s /\ ~(y = x)) ==> ~(s = {x})``) THEN
6735  EXISTS_TAC ``a - (x - a):real`` THEN REWRITE_TAC[IN_SPHERE] THEN
6736  REWRITE_TAC [dist] THEN REPEAT(POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC);
6737
6738(* ------------------------------------------------------------------------- *)
6739(* For points in the interior, localization of limits makes no difference.   *)
6740(* ------------------------------------------------------------------------- *)
6741
6742val EVENTUALLY_WITHIN_INTERIOR = store_thm ("EVENTUALLY_WITHIN_INTERIOR",
6743 ``!p s x.
6744  x IN interior s
6745  ==> (eventually p (at x within s) <=> eventually p (at x))``,
6746  REWRITE_TAC[EVENTUALLY_WITHIN, EVENTUALLY_AT, IN_INTERIOR] THEN
6747  REPEAT GEN_TAC THEN SIMP_TAC std_ss [SUBSET_DEF, IN_BALL] THEN
6748  DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
6749  EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
6750  EXISTS_TAC ``min (d:real) e`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
6751  ASM_MESON_TAC[DIST_SYM]);
6752
6753val LIM_WITHIN_INTERIOR = store_thm ("LIM_WITHIN_INTERIOR",
6754 ``!f l s x. x IN interior s
6755   ==> ((f --> l) (at x within s) <=> (f --> l) (at x))``,
6756  SIMP_TAC std_ss [tendsto, EVENTUALLY_WITHIN_INTERIOR]);
6757
6758val NETLIMIT_WITHIN_INTERIOR = store_thm ("NETLIMIT_WITHIN_INTERIOR",
6759 ``!s x:real. x IN interior s ==> (netlimit(at x within s) = x)``,
6760  REPEAT STRIP_TAC THEN MATCH_MP_TAC NETLIMIT_WITHIN THEN
6761  REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN
6762  FIRST_ASSUM(MP_TAC o MATCH_MP(REWRITE_RULE[OPEN_CONTAINS_BALL]
6763   (SPEC_ALL OPEN_INTERIOR))) THEN
6764  ASM_MESON_TAC[LIMPT_SUBSET, LIMPT_BALL, CENTRE_IN_CBALL, REAL_LT_IMP_LE,
6765   SUBSET_TRANS, INTERIOR_SUBSET]);
6766
6767(* ------------------------------------------------------------------------- *)
6768(* A non-singleton connected set is perfect (i.e. has no isolated points). *)
6769(* ------------------------------------------------------------------------- *)
6770
6771val CONNECTED_IMP_PERFECT = store_thm ("CONNECTED_IMP_PERFECT",
6772 ``!s x:real.
6773   connected s /\ ~(?a. s = {a}) /\ x IN s ==> x limit_point_of s``,
6774  REPEAT STRIP_TAC THEN REWRITE_TAC[limit_point_of] THEN
6775  X_GEN_TAC ``t:real->bool`` THEN STRIP_TAC THEN
6776  MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN
6777  KNOW_TAC ``open t`` THENL [ASM_REWRITE_TAC [], ALL_TAC] THEN
6778  GEN_REWR_TAC LAND_CONV [OPEN_CONTAINS_CBALL] THEN
6779  DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x:real`) THEN
6780  ASM_REWRITE_TAC[] THEN
6781  DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
6782  UNDISCH_TAC ``connected s`` THEN GEN_REWR_TAC LAND_CONV [CONNECTED_CLOPEN] THEN
6783  DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `{x:real}`) THEN
6784  REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL
6785  [REWRITE_TAC[OPEN_IN_OPEN] THEN EXISTS_TAC ``t:real->bool`` THEN
6786   ASM_SET_TAC[],
6787   REWRITE_TAC[CLOSED_IN_CLOSED] THEN
6788   EXISTS_TAC ``cball(x:real,e)`` THEN REWRITE_TAC[CLOSED_CBALL] THEN
6789   REWRITE_TAC[EXTENSION, IN_INTER, IN_SING] THEN
6790   ASM_MESON_TAC[CENTRE_IN_CBALL, SUBSET_DEF, REAL_LT_IMP_LE],
6791  ASM_SET_TAC[]]);
6792
6793val CONNECTED_IMP_PERFECT_CLOSED = store_thm ("CONNECTED_IMP_PERFECT_CLOSED",
6794 ``!s x. connected s /\ closed s /\ ~(?a. s = {a})
6795   ==> (x limit_point_of s <=> x IN s)``,
6796  MESON_TAC[CONNECTED_IMP_PERFECT, CLOSED_LIMPT]);
6797
6798(* ------------------------------------------------------------------------- *)
6799(* Boundedness.                                                              *)
6800(* ------------------------------------------------------------------------- *)
6801
6802val bounded_def = new_definition ("bounded_def",
6803  ``bounded_def s <=> ?a. !x:real. x IN s ==> abs(x) <= a``);
6804
6805val _ = overload_on ("bounded",``bounded_def``);
6806
6807val BOUNDED_EMPTY = store_thm ("BOUNDED_EMPTY",
6808 ``bounded {}``,
6809  REWRITE_TAC[bounded_def, NOT_IN_EMPTY]);
6810
6811val BOUNDED_SUBSET = store_thm ("BOUNDED_SUBSET",
6812 ``!s t. bounded t /\ s SUBSET t ==> bounded s``,
6813  MESON_TAC[bounded_def, SUBSET_DEF]);
6814
6815val BOUNDED_INTERIOR = store_thm ("BOUNDED_INTERIOR",
6816 ``!s:real->bool. bounded s ==> bounded(interior s)``,
6817  MESON_TAC[BOUNDED_SUBSET, INTERIOR_SUBSET]);
6818
6819val BOUNDED_CLOSURE = store_thm ("BOUNDED_CLOSURE",
6820 ``!s:real->bool. bounded s ==> bounded(closure s)``,
6821  REWRITE_TAC[bounded_def, CLOSURE_SEQUENTIAL] THEN
6822  GEN_TAC THEN STRIP_TAC THEN EXISTS_TAC ``a:real`` THEN
6823  GEN_TAC THEN
6824  METIS_TAC[REWRITE_RULE[eventually] LIM_ABS_UBOUND,
6825   TRIVIAL_LIMIT_SEQUENTIALLY, trivial_limit]);
6826
6827val BOUNDED_CLOSURE_EQ = store_thm ("BOUNDED_CLOSURE_EQ",
6828 ``!s:real->bool. bounded(closure s) <=> bounded s``,
6829  GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_CLOSURE] THEN
6830  MESON_TAC[BOUNDED_SUBSET, CLOSURE_SUBSET]);
6831
6832val BOUNDED_CBALL = store_thm ("BOUNDED_CBALL",
6833 ``!x:real e. bounded(cball(x,e))``,
6834  REPEAT GEN_TAC THEN REWRITE_TAC[bounded_def] THEN
6835  EXISTS_TAC ``abs(x:real) + e`` THEN REWRITE_TAC[IN_CBALL, dist] THEN
6836  REAL_ARITH_TAC);
6837
6838val BOUNDED_BALL = store_thm ("BOUNDED_BALL",
6839 ``!x e. bounded(ball(x,e))``,
6840  MESON_TAC[BALL_SUBSET_CBALL, BOUNDED_CBALL, BOUNDED_SUBSET]);
6841
6842val FINITE_IMP_BOUNDED = store_thm ("FINITE_IMP_BOUNDED",
6843 ``!s:real->bool. FINITE s ==> bounded s``,
6844  KNOW_TAC ``!s:real->bool. (bounded s) = (\s. bounded s) s`` THENL
6845  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
6846  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN REWRITE_TAC[BOUNDED_EMPTY] THEN
6847  SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN
6848  REWRITE_TAC[bounded_def, IN_INSERT] THEN GEN_TAC THEN X_GEN_TAC ``x:real`` THEN
6849  REWRITE_TAC [AND_IMP_INTRO] THEN STRIP_TAC THEN
6850  EXISTS_TAC ``abs(x:real) + abs a`` THEN REPEAT STRIP_TAC THEN
6851  ASM_MESON_TAC[ABS_POS, REAL_ARITH
6852   ``(y <= b /\ &0 <= x ==> y <= x + abs b) /\ x <= x + abs b:real``]);
6853
6854val BOUNDED_UNION = store_thm ("BOUNDED_UNION",
6855 ``!s t. bounded (s UNION t) <=> bounded s /\ bounded t``,
6856  REWRITE_TAC[bounded_def, IN_UNION] THEN MESON_TAC[REAL_LE_MAX]);
6857
6858val BOUNDED_BIGUNION = store_thm ("BOUNDED_BIGUNION",
6859 ``!f. FINITE f /\ (!s. s IN f ==> bounded s) ==> bounded(BIGUNION f)``,
6860  REWRITE_TAC[GSYM AND_IMP_INTRO] THEN
6861  KNOW_TAC ``!f. ((!s. s IN f ==> bounded s) ==> bounded(BIGUNION f)) =
6862             (\f. (!s. s IN f ==> bounded s) ==> bounded(BIGUNION f)) f`` THENL
6863  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
6864  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
6865  REWRITE_TAC[BIGUNION_EMPTY, BOUNDED_EMPTY, IN_INSERT, BIGUNION_INSERT] THEN
6866  MESON_TAC[BOUNDED_UNION]);
6867
6868val BOUNDED_POS = store_thm ("BOUNDED_POS",
6869 ``!s. bounded s <=> ?b. &0 < b /\ !x. x IN s ==> abs(x) <= b``,
6870  REWRITE_TAC[bounded_def] THEN
6871  METIS_TAC[REAL_ARITH ``&0 < &1 + abs(y) /\ (x <= y ==> x:real <= &1 + abs(y))``]);
6872
6873val BOUNDED_POS_LT = store_thm ("BOUNDED_POS_LT",
6874 ``!s. bounded s <=> ?b. &0 < b /\ !x. x IN s ==> abs(x) < b``,
6875  REWRITE_TAC[bounded_def] THEN
6876  MESON_TAC[REAL_LT_IMP_LE,
6877   REAL_ARITH ``&0 < &1 + abs(y) /\ (x <= y ==> x < &1 + abs(y:real))``]);
6878
6879val BOUNDED_INTER = store_thm ("BOUNDED_INTER",
6880 ``!s t. bounded s \/ bounded t ==> bounded (s INTER t)``,
6881  MESON_TAC[BOUNDED_SUBSET, INTER_SUBSET]);
6882
6883val BOUNDED_DIFF = store_thm ("BOUNDED_DIFF",
6884 ``!s t. bounded s ==> bounded (s DIFF t)``,
6885  METIS_TAC[BOUNDED_SUBSET, DIFF_SUBSET]);
6886
6887val BOUNDED_INSERT = store_thm ("BOUNDED_INSERT",
6888 ``!x s. bounded(x INSERT s) <=> bounded s``,
6889  ONCE_REWRITE_TAC[SET_RULE ``x INSERT s = {x} UNION s``] THEN
6890  SIMP_TAC std_ss [BOUNDED_UNION, FINITE_IMP_BOUNDED, FINITE_EMPTY, FINITE_INSERT]);
6891
6892val BOUNDED_SING = store_thm ("BOUNDED_SING",
6893 ``!a. bounded {a}``,
6894  REWRITE_TAC[BOUNDED_INSERT, BOUNDED_EMPTY]);
6895
6896val BOUNDED_BIGINTER = store_thm ("BOUNDED_BIGINTER",
6897 ``!f:(real->bool)->bool.
6898    (?s:real->bool. s IN f /\ bounded s) ==> bounded(BIGINTER f)``,
6899  SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, CONJ_EQ_IMP] THEN REPEAT GEN_TAC THEN
6900  DISCH_TAC THEN MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN
6901  ASM_SET_TAC[]);
6902
6903val NOT_BOUNDED_UNIV = store_thm ("NOT_BOUNDED_UNIV",
6904 ``~(bounded univ(:real))``,
6905  SIMP_TAC std_ss [BOUNDED_POS, NOT_FORALL_THM, NOT_EXISTS_THM, IN_UNIV,
6906                   DE_MORGAN_THM, REAL_NOT_LE] THEN
6907  X_GEN_TAC ``B:real`` THEN ASM_CASES_TAC ``&0 < B:real`` THEN ASM_REWRITE_TAC[] THEN
6908  EXISTS_TAC ``(B + &1):real`` THEN REAL_ARITH_TAC);
6909
6910val COBOUNDED_IMP_UNBOUNDED = store_thm ("COBOUNDED_IMP_UNBOUNDED",
6911 ``!s. bounded(univ(:real) DIFF s) ==> ~bounded s``,
6912  GEN_TAC THEN REWRITE_TAC[TAUT `a ==> ~b <=> ~(a /\ b)`] THEN
6913  REWRITE_TAC[GSYM BOUNDED_UNION, SET_RULE ``UNIV DIFF s UNION s = UNIV``] THEN
6914  REWRITE_TAC[NOT_BOUNDED_UNIV]);
6915
6916val BOUNDED_LINEAR_IMAGE = store_thm ("BOUNDED_LINEAR_IMAGE",
6917 ``!f:real->real s. bounded s /\ linear f ==> bounded(IMAGE f s)``,
6918  REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN
6919  DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC ``B1:real``) MP_TAC) THEN
6920  DISCH_THEN(X_CHOOSE_TAC ``B2:real`` o MATCH_MP LINEAR_BOUNDED_POS) THEN
6921  EXISTS_TAC ``B2 * B1:real`` THEN ASM_SIMP_TAC std_ss [REAL_LT_MUL, FORALL_IN_IMAGE] THEN
6922  X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN
6923  MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``B2 * abs(x:real)`` THEN
6924  ASM_SIMP_TAC std_ss [REAL_LE_LMUL]);
6925
6926val BOUNDED_SCALING = store_thm ("BOUNDED_SCALING",
6927 ``!c s. bounded s ==> bounded (IMAGE (\x. c * x) s)``,
6928  REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_LINEAR_IMAGE THEN
6929  ASM_SIMP_TAC std_ss [LINEAR_COMPOSE_CMUL, LINEAR_ID]);
6930
6931val BOUNDED_NEGATIONS = store_thm ("BOUNDED_NEGATIONS",
6932 ``!s. bounded s ==> bounded (IMAGE (\x. -x) s)``,
6933  GEN_TAC THEN
6934  DISCH_THEN(MP_TAC o SPEC ``-&1:real`` o MATCH_MP BOUNDED_SCALING) THEN
6935  REWRITE_TAC[bounded_def, IN_IMAGE, REAL_MUL_LNEG, REAL_MUL_LID]);
6936
6937val BOUNDED_TRANSLATION = store_thm ("BOUNDED_TRANSLATION",
6938 ``!a:real s. bounded s ==> bounded (IMAGE (\x. a + x) s)``,
6939  REPEAT GEN_TAC THEN SIMP_TAC std_ss [BOUNDED_POS, FORALL_IN_IMAGE] THEN
6940  DISCH_THEN(X_CHOOSE_TAC ``B:real``) THEN
6941  EXISTS_TAC ``B + abs(a:real)`` THEN POP_ASSUM MP_TAC THEN
6942  MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN
6943  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x:real`) THEN
6944  MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN REAL_ARITH_TAC);
6945
6946val BOUNDED_TRANSLATION_EQ = store_thm ("BOUNDED_TRANSLATION_EQ",
6947 ``!a s. bounded (IMAGE (\x:real. a + x) s) <=> bounded s``,
6948  REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_TRANSLATION] THEN
6949  DISCH_THEN(MP_TAC o SPEC ``-a:real`` o MATCH_MP BOUNDED_TRANSLATION) THEN
6950  SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, o_DEF, IMAGE_ID,
6951   REAL_ARITH ``-a + (a + x:real) = x``]);
6952
6953val BOUNDED_DIFFS = store_thm ("BOUNDED_DIFFS",
6954 ``!s t:real->bool.
6955  bounded s /\ bounded t ==> bounded {x - y | x IN s /\ y IN t}``,
6956  REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN
6957  DISCH_THEN(CONJUNCTS_THEN2
6958   (X_CHOOSE_TAC ``B:real``) (X_CHOOSE_TAC ``C:real``)) THEN
6959  EXISTS_TAC ``B + C:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN
6960  CONJ_TAC THENL [MATCH_MP_TAC REAL_LT_ADD THEN ASM_REWRITE_TAC [], REPEAT STRIP_TAC] THEN
6961  ASM_REWRITE_TAC[] THEN KNOW_TAC ``abs p_1 <= B:real /\ abs p_2 <= C:real`` THENL
6962  [ASM_SET_TAC [], ALL_TAC] THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
6963  EXISTS_TAC ``abs p_1 + abs p_2:real`` THEN REWRITE_TAC [real_sub, ABS_TRIANGLE] THEN
6964  CONJ_TAC THENL [REAL_ARITH_TAC, ALL_TAC] THEN
6965  MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC [ABS_NEG]);
6966
6967val BOUNDED_SUMS = store_thm ("BOUNDED_SUMS",
6968 ``!s t:real->bool.
6969   bounded s /\ bounded t ==> bounded {x + y | x IN s /\ y IN t}``,
6970  REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN
6971  DISCH_THEN(CONJUNCTS_THEN2
6972   (X_CHOOSE_TAC ``B:real``) (X_CHOOSE_TAC ``C:real``)) THEN
6973  EXISTS_TAC ``B + C:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN
6974  CONJ_TAC THENL [MATCH_MP_TAC REAL_LT_ADD THEN ASM_REWRITE_TAC [], REPEAT STRIP_TAC] THEN
6975  ASM_REWRITE_TAC[] THEN KNOW_TAC ``abs p_1 <= B:real /\ abs p_2 <= C:real`` THENL
6976  [ASM_SET_TAC [], ALL_TAC] THEN STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
6977  EXISTS_TAC ``abs p_1 + abs p_2:real`` THEN REWRITE_TAC [ABS_TRIANGLE] THEN
6978  MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC []);
6979
6980val BOUNDED_SUMS_IMAGE = store_thm ("BOUNDED_SUMS_IMAGE",
6981 ``!f g t. bounded {f x | x IN t} /\ bounded {g x | x IN t}
6982    ==> bounded {f x + g x | x IN t}``,
6983  REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUMS) THEN
6984  MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN
6985  REWRITE_TAC [SUBSET_DEF] THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN
6986  METIS_TAC []);
6987
6988val BOUNDED_SUMS_IMAGES = store_thm ("BOUNDED_SUMS_IMAGES",
6989 ``!f:'a->'b->real t s. FINITE s /\
6990     (!a. a IN s ==> bounded {f x a | x IN t})
6991     ==> bounded { sum s (f x) | x IN t}``,
6992  GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[GSYM AND_IMP_INTRO] THEN
6993  KNOW_TAC ``!s. ((!a. a IN s ==> bounded {(f:'a->'b->real) x a | x IN t}) ==>
6994                                  bounded {sum s (f x) | x IN t}) =
6995             (\s. (!a. a IN s ==> bounded {f x a | x IN t}) ==>
6996                                  bounded {sum s (f x) | x IN t}) s`` THENL
6997  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
6998  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
6999  SIMP_TAC std_ss [SUM_CLAUSES] THEN CONJ_TAC THENL
7000  [DISCH_THEN(K ALL_TAC) THEN MATCH_MP_TAC BOUNDED_SUBSET THEN
7001   EXISTS_TAC ``{0:real}`` THEN
7002   SIMP_TAC std_ss [FINITE_IMP_BOUNDED, FINITE_EMPTY, FINITE_INSERT] THEN SET_TAC[],
7003   ALL_TAC] THEN REPEAT STRIP_TAC THEN
7004  KNOW_TAC ``bounded {(f:'a->'b->real) x e | x IN t} /\
7005             bounded {sum s ((f:'a->'b->real) x) | x IN t}`` THENL
7006  [ALL_TAC, METIS_TAC [BOUNDED_SUMS_IMAGE]] THEN ASM_SIMP_TAC std_ss [IN_INSERT]);
7007
7008val BOUNDED_SUBSET_BALL = store_thm ("BOUNDED_SUBSET_BALL",
7009 ``!s x:real. bounded(s) ==> ?r. &0 < r /\ s SUBSET ball(x,r)``,
7010  REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN
7011  DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN
7012  EXISTS_TAC ``&2 * B + abs(x:real)`` THEN
7013  ASM_SIMP_TAC std_ss [ABS_POS, REAL_ARITH
7014   ``&0 < B /\ &0 <= x ==> &0 < &2 * B + x:real``] THEN
7015  REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN
7016  FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN ASM_REWRITE_TAC[IN_BALL, dist] THEN
7017  UNDISCH_TAC ``&0 < B:real`` THEN REAL_ARITH_TAC);
7018
7019val BOUNDED_SUBSET_CBALL = store_thm ("BOUNDED_SUBSET_CBALL",
7020 ``!s x:real. bounded(s) ==> ?r. &0 < r /\ s SUBSET cball(x,r)``,
7021  MESON_TAC[BOUNDED_SUBSET_BALL, SUBSET_TRANS, BALL_SUBSET_CBALL]);
7022
7023val UNBOUNDED_INTER_COBOUNDED = store_thm ("UNBOUNDED_INTER_COBOUNDED",
7024 ``!s t. ~bounded s /\ bounded(univ(:real) DIFF t) ==> ~(s INTER t = {})``,
7025  REWRITE_TAC[SET_RULE ``(s INTER t = {}) <=> s SUBSET univ(:real) DIFF t``] THEN
7026  MESON_TAC[BOUNDED_SUBSET]);
7027
7028val COBOUNDED_INTER_UNBOUNDED = store_thm ("COBOUNDED_INTER_UNBOUNDED",
7029 ``!s t. bounded(univ(:real) DIFF s) /\ ~bounded t ==> ~(s INTER t = {})``,
7030  REWRITE_TAC[SET_RULE ``(s INTER t = {}) <=> t SUBSET univ(:real) DIFF s``] THEN
7031  MESON_TAC[BOUNDED_SUBSET]);
7032
7033val SUBSPACE_BOUNDED_EQ_TRIVIAL = store_thm ("SUBSPACE_BOUNDED_EQ_TRIVIAL",
7034 ``!s:real->bool. subspace s ==> (bounded s <=> (s = {0}))``,
7035  REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [BOUNDED_SING] THEN
7036  ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN
7037  DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
7038  ``~(s = {a}) ==> a IN s ==> ?b. b IN s /\ ~(b = a)``)) THEN
7039  ASM_SIMP_TAC std_ss [SUBSPACE_0] THEN
7040  DISCH_THEN(X_CHOOSE_THEN ``v:real`` STRIP_ASSUME_TAC) THEN
7041  SIMP_TAC std_ss [bounded_def, NOT_EXISTS_THM] THEN X_GEN_TAC ``B:real`` THEN
7042  EXISTS_TAC ``(B + &1) / abs v * v:real`` THEN
7043  RULE_ASSUM_TAC (ONCE_REWRITE_RULE [GSYM ABS_ZERO]) THEN
7044  ASM_SIMP_TAC std_ss [SUBSPACE_MUL, ABS_MUL, ABS_DIV, ABS_ABS] THEN
7045  ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, ABS_ZERO] THEN REAL_ARITH_TAC);
7046
7047val BOUNDED_COMPONENTWISE = store_thm ("BOUNDED_COMPONENTWISE",
7048 ``!s:real->bool.
7049   bounded s <=> bounded (IMAGE (\x. x) s)``,
7050 METIS_TAC [IMAGE_ID]);
7051
7052(* ------------------------------------------------------------------------- *)
7053(* Some theorems on sups and infs using the notion "bounded".                *)
7054(* ------------------------------------------------------------------------- *)
7055
7056val BOUNDED_HAS_SUP = store_thm ("BOUNDED_HAS_SUP",
7057 ``!s. bounded s /\ ~(s = {})
7058    ==> (!x. x IN s ==> x <= sup s) /\
7059    (!b. (!x. x IN s ==> x <= b) ==> sup s <= b)``,
7060  REWRITE_TAC[bounded_def, IMAGE_EQ_EMPTY] THEN
7061  MESON_TAC[SUP, REAL_ARITH ``abs(x) <= a ==> x <= a:real``]);
7062
7063val SUP_INSERT = store_thm ("SUP_INSERT",
7064 ``!x s:real->bool. bounded s
7065   ==> (sup(x INSERT s) = if s = {} then x else (max x (sup s)))``,
7066  REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_UNIQUE THEN
7067  COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THENL
7068  [MESON_TAC[REAL_LE_REFL], ALL_TAC] THEN
7069   REWRITE_TAC[REAL_LE_MAX, REAL_LT_MAX, IN_INSERT] THEN
7070   MP_TAC(ISPEC ``s:real->bool`` BOUNDED_HAS_SUP) THEN ASM_REWRITE_TAC[] THEN
7071   REPEAT STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_REFL, REAL_NOT_LT]);
7072
7073val BOUNDED_HAS_INF = store_thm ("BOUNDED_HAS_INF",
7074 ``!s. bounded s /\ ~(s = {})
7075   ==> (!x. x IN s ==> inf s <= x) /\
7076   (!b. (!x. x IN s ==> b <= x) ==> b <= inf s)``,
7077  REWRITE_TAC[bounded_def, IMAGE_EQ_EMPTY] THEN
7078  MESON_TAC[INF, REAL_ARITH ``abs(x) <= a ==> -a <= x:real``]);
7079
7080val INF_INSERT = store_thm ("INF_INSERT",
7081 ``!x s. bounded s
7082   ==> (inf(x INSERT s) = if s = {} then x else (min x (inf s)))``,
7083  REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INF_UNIQUE THEN
7084  COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THENL
7085  [MESON_TAC[REAL_LE_REFL], ALL_TAC] THEN
7086   REWRITE_TAC[REAL_MIN_LE, REAL_MIN_LT, IN_INSERT] THEN
7087   MP_TAC(ISPEC ``s:real->bool`` BOUNDED_HAS_INF) THEN ASM_REWRITE_TAC[] THEN
7088   REPEAT STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_REFL, REAL_NOT_LT]);
7089
7090(* ------------------------------------------------------------------------- *)
7091(* Subset and overlapping relations on balls.                                *)
7092(* ------------------------------------------------------------------------- *)
7093
7094val lemma = prove (
7095   ``(!a':real r r'.
7096       cball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r < &0) /\
7097     (!a':real r r'.
7098       cball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r < r' \/ r < &0)``,
7099    CONJ_TAC THENL
7100    [KNOW_TAC ``(!a' r r'.
7101  cball (a,r) SUBSET cball (a',r') <=> dist (a,a') + r <= r' \/ r < 0) =
7102               (!r r' a.
7103  cball (a,r) SUBSET cball (0,r') <=> dist (a,0) + r <= r' \/ r < 0)`` THENL
7104  [EQ_TAC THENL
7105   [DISCH_TAC THEN REPEAT GEN_TAC THEN
7106    FULL_SIMP_TAC std_ss [cball, ball, SUBSET_DEF, GSPECIFICATION, dist,
7107     REAL_SUB_LZERO, REAL_SUB_RZERO, ABS_NEG] THEN
7108    POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN
7109    FULL_SIMP_TAC std_ss [REAL_ARITH ``a - (a - b) = b:real``] THEN
7110    POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN
7111    POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN DISCH_TAC THEN
7112    RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN
7113    ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN EQ_TAC THENL
7114    [DISCH_TAC THEN GEN_TAC THEN
7115     POP_ASSUM (MP_TAC o Q.SPEC `-(a - a' - x:real)`) THEN
7116     REWRITE_TAC [ABS_NEG] THEN REAL_ARITH_TAC, ALL_TAC] THEN
7117    DISCH_TAC THEN GEN_TAC THEN
7118    POP_ASSUM (MP_TAC o Q.SPEC `-(-a + a' - x:real)`) THEN
7119    REAL_ARITH_TAC, ALL_TAC] THEN
7120  DISCH_TAC THEN REPEAT GEN_TAC THEN
7121  FULL_SIMP_TAC std_ss [cball, ball, SUBSET_DEF, GSPECIFICATION, dist,
7122   REAL_SUB_LZERO, REAL_SUB_RZERO, ABS_NEG] THEN
7123  POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN
7124  POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN DISCH_TAC THEN
7125  POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN
7126  RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN
7127  ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN EQ_TAC THENL
7128  [DISCH_TAC THEN GEN_TAC THEN
7129   POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN
7130   REAL_ARITH_TAC, ALL_TAC] THEN
7131  DISCH_TAC THEN GEN_TAC THEN
7132  POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN
7133  REAL_ARITH_TAC,
7134  DISCH_TAC THEN ASM_REWRITE_TAC[] THEN POP_ASSUM K_TAC],
7135    KNOW_TAC ``(!a' r r'.
7136  cball (a,r) SUBSET ball (a',r') <=> dist (a,a') + r < r' \/ r < 0) =
7137               (!r r' a.
7138  cball (a,r) SUBSET ball (0,r') <=> dist (a,0) + r < r' \/ r < 0)`` THENL
7139  [EQ_TAC THENL
7140   [DISCH_TAC THEN REPEAT GEN_TAC THEN
7141    FULL_SIMP_TAC std_ss [cball, ball, SUBSET_DEF, GSPECIFICATION, dist,
7142     REAL_SUB_LZERO, REAL_SUB_RZERO, ABS_NEG] THEN
7143    POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN
7144    FULL_SIMP_TAC std_ss [REAL_ARITH ``a - (a - b) = b:real``] THEN
7145    POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN
7146    POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN DISCH_TAC THEN
7147    RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN
7148    ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN EQ_TAC THENL
7149    [DISCH_TAC THEN GEN_TAC THEN
7150     POP_ASSUM (MP_TAC o Q.SPEC `-(a - a' - x:real)`) THEN
7151     REWRITE_TAC [ABS_NEG] THEN REAL_ARITH_TAC, ALL_TAC] THEN
7152    DISCH_TAC THEN GEN_TAC THEN
7153    POP_ASSUM (MP_TAC o Q.SPEC `-(-a + a' - x:real)`) THEN
7154    REAL_ARITH_TAC, ALL_TAC] THEN
7155  DISCH_TAC THEN REPEAT GEN_TAC THEN
7156  FULL_SIMP_TAC std_ss [cball, ball, SUBSET_DEF, GSPECIFICATION, dist,
7157   REAL_SUB_LZERO, REAL_SUB_RZERO, ABS_NEG] THEN
7158  POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN
7159  POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN DISCH_TAC THEN
7160  POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN
7161  RULE_ASSUM_TAC (ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN
7162  ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN EQ_TAC THENL
7163  [DISCH_TAC THEN GEN_TAC THEN
7164   POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN
7165   REAL_ARITH_TAC, ALL_TAC] THEN
7166  DISCH_TAC THEN GEN_TAC THEN
7167  POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN
7168  REAL_ARITH_TAC,
7169  DISCH_TAC THEN ASM_REWRITE_TAC[] THEN POP_ASSUM K_TAC]] THEN
7170   (REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET_DEF, IN_CBALL, IN_BALL] THEN
7171    EQ_TAC THENL
7172    [REWRITE_TAC[DIST_0],
7173     REWRITE_TAC [dist] THEN REAL_ARITH_TAC] THEN
7174    DISJ_CASES_TAC(REAL_ARITH ``r < &0 \/ &0 <= r:real``) THEN
7175    ASM_REWRITE_TAC[] THEN DISCH_TAC THEN DISJ1_TAC THEN
7176    ASM_CASES_TAC ``a:real = 0`` THENL
7177     [FIRST_X_ASSUM(MP_TAC o SPEC ``r:real``) THEN
7178      ASM_SIMP_TAC std_ss [DIST_0, ABS_MUL, LESS_EQ_REFL] THEN
7179      ASM_REAL_ARITH_TAC,
7180      FIRST_X_ASSUM(MP_TAC o SPEC ``(&1 + r / abs(a)) * a:real``) THEN
7181      SIMP_TAC std_ss [dist, REAL_ARITH ``a - (&1 + x) * a:real = -(x * a)``] THEN
7182      ASM_SIMP_TAC std_ss [ABS_MUL, ABS_DIV, ABS_ABS, ABS_NEG, REAL_POS,
7183                   REAL_LE_DIV, ABS_POS, REAL_ADD_RDISTRIB, REAL_DIV_RMUL,
7184               ABS_ZERO, REAL_ARITH ``&0 <= x ==> (abs(&1 + x) = &1 + x:real)``] THEN
7185      ASM_REAL_ARITH_TAC]));
7186
7187val tac = DISCH_THEN(MP_TAC o MATCH_MP SUBSET_CLOSURE) THEN
7188          ASM_SIMP_TAC std_ss [CLOSED_CBALL, CLOSURE_CLOSED, CLOSURE_BALL];
7189
7190val SUBSET_BALLS = store_thm ("SUBSET_BALLS",
7191 ``(!a a':real r r'.
7192      ball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r <= r' \/ r <= &0) /\
7193   (!a a':real r r'.
7194      ball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r <= &0) /\
7195   (!a a':real r r'.
7196      cball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r < r' \/ r < &0) /\
7197   (!a a':real r r'.
7198      cball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r < &0)``,
7199  SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN
7200  KNOW_TAC ``(!a a':real r r'.
7201  (ball (a,r) SUBSET ball (a',r') <=>
7202   dist (a,a') + r <= r' \/ r <= 0) /\
7203  (ball (a,r) SUBSET cball (a',r') <=>
7204   dist (a,a') + r <= r' \/ r <= 0) /\
7205  (cball (a,r) SUBSET ball (a',r') <=>
7206     dist (a,a') + r < r' \/ r < 0) /\
7207  (cball (a,r) SUBSET cball (a',r') <=>
7208    dist (a,a') + r <= r' \/ r < 0)) =
7209   (!a:real r r'.
7210  (ball (a,r) SUBSET ball (0,r') <=>
7211   dist (a,0) + r <= r' \/ r <= 0) /\
7212  (ball (a,r) SUBSET cball (0,r') <=>
7213   dist (a,0) + r <= r' \/ r <= 0) /\
7214  (cball (a,r) SUBSET ball (0,r') <=>
7215     dist (a,0) + r < r' \/ r < 0) /\
7216  (cball (a,r) SUBSET cball (0,r') <=>
7217    dist (a,0) + r <= r' \/ r < 0))`` THENL
7218 [EQ_TAC THENL
7219  [DISCH_TAC THEN REPEAT GEN_TAC THEN METIS_TAC [], ALL_TAC] THEN
7220  DISCH_TAC THEN REPEAT GEN_TAC THEN FULL_SIMP_TAC std_ss [DIST_0] THEN
7221  FULL_SIMP_TAC std_ss [cball, ball, dist, SUBSET_DEF, GSPECIFICATION] THEN
7222  FULL_SIMP_TAC std_ss [REAL_SUB_LZERO, ABS_NEG] THEN
7223  POP_ASSUM (MP_TAC o Q.SPEC `a - a':real`) THEN DISCH_TAC THEN
7224  POP_ASSUM (MP_TAC o Q.SPEC `r:real`) THEN DISCH_TAC THEN
7225  POP_ASSUM (MP_TAC o Q.SPEC `r':real`) THEN
7226  GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN
7227  REPEAT STRIP_TAC THENL
7228  [UNDISCH_TAC ``abs (a - a') + r <= r' \/ r <= 0 <=>
7229        !x:real. abs (a - a' - x) < r ==> abs x < r'`` THEN
7230   REPEAT (POP_ASSUM K_TAC) THEN DISCH_TAC THEN
7231   ASM_REWRITE_TAC [] THEN EQ_TAC THENL
7232   [DISCH_TAC THEN GEN_TAC THEN
7233    POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN
7234    REAL_ARITH_TAC,
7235    DISCH_TAC THEN GEN_TAC THEN
7236    POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN
7237    REAL_ARITH_TAC],
7238   UNDISCH_TAC ``abs (a - a') + r <= r' \/ r <= 0 <=>
7239        !x:real. abs (a - a' - x) < r ==> abs x <= r'`` THEN
7240   REPEAT (POP_ASSUM K_TAC) THEN DISCH_TAC THEN
7241   ASM_REWRITE_TAC [] THEN EQ_TAC THENL
7242   [DISCH_TAC THEN GEN_TAC THEN
7243    POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN
7244    REAL_ARITH_TAC,
7245    DISCH_TAC THEN GEN_TAC THEN
7246    POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN
7247    REAL_ARITH_TAC],
7248   UNDISCH_TAC ``abs (a - a') + r < r' \/ r < 0 <=>
7249        !x:real. abs (a - a' - x) <= r ==> abs x < r'`` THEN
7250   REPEAT (POP_ASSUM K_TAC) THEN DISCH_TAC THEN
7251   ASM_REWRITE_TAC [] THEN EQ_TAC THENL
7252   [DISCH_TAC THEN GEN_TAC THEN
7253    POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN
7254    REAL_ARITH_TAC,
7255    DISCH_TAC THEN GEN_TAC THEN
7256    POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN
7257    REAL_ARITH_TAC],
7258   UNDISCH_TAC ``abs (a - a') + r <= r' \/ r < 0 <=>
7259        !x:real. abs (a - a' - x) <= r ==> abs x <= r'`` THEN
7260   REPEAT (POP_ASSUM K_TAC) THEN DISCH_TAC THEN
7261   ASM_REWRITE_TAC [] THEN EQ_TAC THENL
7262   [DISCH_TAC THEN GEN_TAC THEN
7263    POP_ASSUM (MP_TAC o Q.SPEC `-(-a' - x:real)`) THEN
7264    REAL_ARITH_TAC,
7265    DISCH_TAC THEN GEN_TAC THEN
7266    POP_ASSUM (MP_TAC o Q.SPEC `-(a' - x:real)`) THEN
7267    REAL_ARITH_TAC]],
7268 DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
7269  REPEAT STRIP_TAC THEN
7270  (EQ_TAC THENL
7271    [ALL_TAC, REWRITE_TAC[SUBSET_DEF, IN_BALL, IN_CBALL, dist] THEN REAL_ARITH_TAC]) THEN
7272  MATCH_MP_TAC(SET_RULE
7273   ``((s = {}) <=> q) /\ (s SUBSET t /\ ~(s = {}) /\ ~(t = {}) ==> p)
7274    ==> s SUBSET t ==> p \/ q``) THEN
7275  SIMP_TAC std_ss [BALL_EQ_EMPTY, CBALL_EQ_EMPTY, REAL_NOT_LE, REAL_NOT_LT] THEN
7276  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THENL
7277   [tac, tac, ALL_TAC, ALL_TAC] THEN REWRITE_TAC[lemma] THEN
7278  REPEAT(POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC);
7279
7280(* NOTE: this proof needs 10s to finish *)
7281Theorem INTER_BALLS_EQ_EMPTY :
7282   (!a b:real r s. (ball(a,r) INTER ball(b,s) = {}) <=>
7283                     r <= &0 \/ s <= &0 \/ r + s <= dist(a,b)) /\
7284   (!a b:real r s. (ball(a,r) INTER cball(b,s) = {}) <=>
7285                     r <= &0 \/ s < &0 \/ r + s <= dist(a,b)) /\
7286   (!a b:real r s. (cball(a,r) INTER ball(b,s) = {}) <=>
7287                     r < &0 \/ s <= &0 \/ r + s <= dist(a,b)) /\
7288   (!a b:real r s. (cball(a,r) INTER cball(b,s) = {}) <=>
7289                     r < &0 \/ s < &0 \/ r + s < dist(a,b))
7290Proof
7291  rpt STRIP_TAC >| (* 4 subgoals *)
7292  [(* goal 1 (of 4) *)
7293   Suff `!b:real. 0 <= b ==>
7294               !r s:real. ((ball (0,r) INTER ball (b,s) = {}) <=>
7295                r <= 0 \/ s <= 0 \/ r + s <= dist (0,b))` >-
7296   (SIMP_TAC std_ss [ball, dist, REAL_ARITH ``abs (0 - x:real) = abs x``,
7297                    EXTENSION, GSPECIFICATION, INTER_DEF, NOT_IN_EMPTY, REAL_NOT_LT] THEN
7298    DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC ``abs (a - b:real)``) THEN
7299    REWRITE_TAC [ABS_POS, ABS_ABS] THEN DISCH_TAC THEN
7300    POP_ASSUM (MP_TAC o SPECL [``r:real``,``s:real``]) THEN
7301    GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
7302    POP_ASSUM K_TAC THEN REWRITE_TAC [abs] THEN COND_CASES_TAC THEN
7303    REWRITE_TAC [GSYM abs] THENL [EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN
7304    POP_ASSUM (MP_TAC o SPEC ``a - x:real``) THEN REAL_ARITH_TAC, ALL_TAC] THEN
7305    EQ_TAC THENL [DISCH_TAC THEN GEN_TAC THEN
7306    POP_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN REAL_ARITH_TAC,
7307    DISCH_TAC THEN GEN_TAC THEN
7308    POP_ASSUM (MP_TAC o SPEC ``-(a - x):real``) THEN REAL_ARITH_TAC]),
7309   (* goal 2 (of 4) *)
7310   Suff `!b:real. 0 <= b ==>
7311               !r s:real. ((ball (0,r) INTER cball (b,s) = {}) <=>
7312                r <= 0 \/ s < 0 \/ r + s <= dist (0,b))` >-
7313   (SIMP_TAC std_ss [ball, cball, dist, REAL_ARITH ``abs (0 - x:real) = abs x``,
7314                    EXTENSION, GSPECIFICATION, INTER_DEF, NOT_IN_EMPTY, REAL_NOT_LT] THEN
7315    DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC ``abs (a - b:real)``) THEN
7316    REWRITE_TAC [ABS_POS, ABS_ABS] THEN DISCH_TAC THEN
7317    POP_ASSUM (MP_TAC o SPECL [``r:real``,``s:real``]) THEN
7318    GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
7319    POP_ASSUM K_TAC THEN REWRITE_TAC [abs] THEN COND_CASES_TAC THEN
7320    REWRITE_TAC [GSYM abs] THENL [EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN
7321    POP_ASSUM (MP_TAC o SPEC ``a - x:real``) THEN REAL_ARITH_TAC, ALL_TAC] THEN
7322    EQ_TAC THENL [DISCH_TAC THEN GEN_TAC THEN
7323    POP_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN REAL_ARITH_TAC,
7324    DISCH_TAC THEN GEN_TAC THEN
7325    POP_ASSUM (MP_TAC o SPEC ``-(a - x):real``) THEN REAL_ARITH_TAC]),
7326   (* goal 3 (of 4) *)
7327   Suff `!b:real. 0 <= b ==>
7328               !r s:real. ((cball (0,r) INTER ball (b,s) = {}) <=>
7329                r < 0 \/ s <= 0 \/ r + s <= dist (0,b))` >-
7330   (SIMP_TAC std_ss [ball, cball, dist, REAL_ARITH ``abs (0 - x:real) = abs x``,
7331                    EXTENSION, GSPECIFICATION, INTER_DEF, NOT_IN_EMPTY, REAL_NOT_LT] THEN
7332    DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC ``abs (a - b:real)``) THEN
7333    REWRITE_TAC [ABS_POS, ABS_ABS] THEN DISCH_TAC THEN
7334    POP_ASSUM (MP_TAC o SPECL [``r:real``,``s:real``]) THEN
7335    GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
7336    POP_ASSUM K_TAC THEN REWRITE_TAC [abs] THEN COND_CASES_TAC THEN
7337    REWRITE_TAC [GSYM abs] THENL [EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN
7338    POP_ASSUM (MP_TAC o SPEC ``a - x:real``) THEN REAL_ARITH_TAC, ALL_TAC] THEN
7339    EQ_TAC THENL [DISCH_TAC THEN GEN_TAC THEN
7340    POP_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN REAL_ARITH_TAC,
7341    DISCH_TAC THEN GEN_TAC THEN
7342    POP_ASSUM (MP_TAC o SPEC ``-(a - x):real``) THEN REAL_ARITH_TAC]),
7343   (* goal 4 (of 4) *)
7344   Suff `!b:real. 0 <= b ==>
7345               !r s:real. ((cball (0,r) INTER cball (b,s) = {}) <=>
7346                r < 0 \/ s < 0 \/ r + s < dist (0,b))` >-
7347   (SIMP_TAC std_ss [ball, cball, dist, REAL_ARITH ``abs (0 - x:real) = abs x``,
7348                    EXTENSION, GSPECIFICATION, INTER_DEF, NOT_IN_EMPTY, REAL_NOT_LT] THEN
7349    DISCH_TAC THEN POP_ASSUM (MP_TAC o SPEC ``abs (a - b:real)``) THEN
7350    REWRITE_TAC [ABS_POS, ABS_ABS] THEN DISCH_TAC THEN
7351    POP_ASSUM (MP_TAC o SPECL [``r:real``,``s:real``]) THEN
7352    GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
7353    POP_ASSUM K_TAC THEN REWRITE_TAC [abs] THEN COND_CASES_TAC THEN
7354    REWRITE_TAC [GSYM abs] THENL [EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN
7355    POP_ASSUM (MP_TAC o SPEC ``a - x:real``) THEN REAL_ARITH_TAC, ALL_TAC] THEN
7356    EQ_TAC THENL [DISCH_TAC THEN GEN_TAC THEN
7357    POP_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN REAL_ARITH_TAC,
7358    DISCH_TAC THEN GEN_TAC THEN
7359    POP_ASSUM (MP_TAC o SPEC ``-(a - x):real``) THEN REAL_ARITH_TAC])] THEN
7360  (* still 4 subgoals *)
7361  rpt STRIP_TAC THEN
7362  REWRITE_TAC[EXTENSION, NOT_IN_EMPTY, IN_INTER, IN_CBALL, IN_BALL] THEN
7363  (reverse EQ_TAC
7364   >- (Q.SPEC_TAC (`b`, `v`) THEN REWRITE_TAC [dist] THEN REAL_ARITH_TAC)) THEN
7365  DISCH_THEN(MP_TAC o GEN ``c:real`` o SPEC ``c:real``) THEN
7366  SIMP_TAC std_ss [ABS_MUL, LESS_EQ_REFL, dist, ABS_NEG,
7367           REAL_SUB_LZERO, GSYM REAL_SUB_RDISTRIB, REAL_MUL_RID] THEN
7368  ASM_REWRITE_TAC[abs] THEN REWRITE_TAC[GSYM abs] THEN
7369  DISCH_THEN(fn th =>
7370    MP_TAC(SPEC ``min b r:real`` th) THEN
7371    MP_TAC(SPEC ``max (&0) (b - s:real)`` th) THEN
7372    MP_TAC(SPEC ``(r + (b - s)) / &2:real`` th)) THEN
7373  REWRITE_TAC [real_div] THEN
7374  ONCE_REWRITE_TAC [REAL_ARITH ``a - b * c = a * 1 - b * c:real``] THEN
7375  REWRITE_TAC [METIS [REAL_DIV_REFL, REAL_ARITH ``2 <> 0:real``, real_div]
7376   ``1 = 2 * inv 2:real``, REAL_ARITH ``a * (b * c) = (a * b) * c:real``] THEN
7377  REWRITE_TAC [GSYM REAL_SUB_RDISTRIB] THEN
7378  SIMP_TAC std_ss [real_div, ABS_MUL, REAL_ARITH ``2 <> 0:real``, ABS_INV, ABS_N] THEN
7379  SIMP_TAC std_ss [GSYM real_div] THEN
7380  FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_LE_RDIV_EQ,
7381                        REAL_LT_LDIV_EQ, REAL_LE_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
7382  RW_TAC real_ss [abs, max_def, min_def] THEN (* 1024 subgoals (for each goals) *)
7383  ASM_REAL_ARITH_TAC
7384QED
7385
7386(* ------------------------------------------------------------------------- *)
7387(* Every closed set is a G_Delta.                                            *)
7388(* ------------------------------------------------------------------------- *)
7389
7390val CLOSED_AS_GDELTA = store_thm ("CLOSED_AS_GDELTA",
7391 ``!s:real->bool. closed s ==> ?g. COUNTABLE g /\
7392   (!u. u IN g ==> open u) /\ (BIGINTER g = s)``,
7393  REPEAT STRIP_TAC THEN EXISTS_TAC
7394   ``{ BIGUNION { ball(x:real,inv(&n + &1)) | x IN s} | n IN univ(:num)}`` THEN
7395  SIMP_TAC std_ss [GSYM IMAGE_DEF, COUNTABLE_IMAGE, NUM_COUNTABLE] THEN
7396  SIMP_TAC std_ss [FORALL_IN_IMAGE, OPEN_BIGUNION, OPEN_BALL] THEN
7397  MATCH_MP_TAC(SET_RULE
7398   ``(closure s = s) /\ s SUBSET t /\ t SUBSET closure s ==> (t = s)``) THEN
7399  ASM_REWRITE_TAC[CLOSURE_EQ] THEN CONJ_TAC THENL
7400  [SIMP_TAC std_ss [SUBSET_BIGINTER, FORALL_IN_IMAGE, IN_UNIV] THEN
7401   X_GEN_TAC ``n:num`` THEN SIMP_TAC std_ss [BIGUNION_IMAGE, SUBSET_DEF, GSPECIFICATION] THEN
7402   X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN EXISTS_TAC ``x:real`` THEN
7403   ASM_REWRITE_TAC[CENTRE_IN_BALL, REAL_LT_INV_EQ] THEN
7404   MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC ``1:real`` THEN CONJ_TAC THENL
7405   [REAL_ARITH_TAC, ALL_TAC] THEN REWRITE_TAC [REAL_LE_ADDL, REAL_POS],
7406   SIMP_TAC std_ss [SUBSET_DEF, CLOSURE_APPROACHABLE, BIGINTER_IMAGE, IN_UNIV] THEN
7407   X_GEN_TAC ``x:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, BIGUNION_IMAGE] THEN
7408   DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
7409   POP_ASSUM MP_TAC THEN GEN_REWR_TAC LAND_CONV [REAL_ARCH_INV] THEN
7410   DISCH_THEN(X_CHOOSE_THEN ``n:num`` STRIP_ASSUME_TAC) THEN
7411   FIRST_X_ASSUM(MP_TAC o SPEC ``n:num``) THEN REWRITE_TAC[IN_BALL] THEN
7412   DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN
7413   POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
7414   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LT_TRANS) THEN
7415   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] REAL_LT_TRANS)) THEN
7416   MATCH_MP_TAC REAL_LT_INV2 THEN
7417   REWRITE_TAC[REAL_OF_NUM_ADD, REAL_LT] THEN CONJ_TAC THENL
7418   [FULL_SIMP_TAC std_ss [REAL_LT_INV_EQ, GSYM REAL_LT],
7419    FULL_SIMP_TAC arith_ss [REAL_LT_ADDR]]]);
7420
7421(* ------------------------------------------------------------------------- *)
7422(* Compactness (the definition is the one based on convegent subsequences).  *)
7423(* ------------------------------------------------------------------------- *)
7424
7425val compact = new_definition ("compact",
7426 ``compact s <=> !f:num->real. (!n. f(n) IN s)
7427   ==> ?l r. l IN s /\ (!m n:num. m < n ==> r(m) < r(n)) /\
7428       ((f o r) --> l) sequentially``);
7429
7430val MONOTONE_BIGGER = store_thm ("MONOTONE_BIGGER",
7431 ``!r. (!m n. m < n ==> r(m) < r(n)) ==> !n:num. n <= r(n)``,
7432  GEN_TAC THEN DISCH_TAC THEN INDUCT_TAC THEN
7433  METIS_TAC[ZERO_LESS_EQ, ARITH_PROVE ``n <= m /\ m < p ==> SUC n <= p``, LT]);
7434
7435val LIM_SUBSEQUENCE = store_thm ("LIM_SUBSEQUENCE",
7436 ``!s r l. (!m n. m < n ==> r(m) < r(n)) /\ (s --> l) sequentially
7437  ==> (s o r --> l) sequentially``,
7438  SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN
7439  MESON_TAC[MONOTONE_BIGGER, LESS_EQ_TRANS]);
7440
7441val MONOTONE_SUBSEQUENCE = store_thm ("MONOTONE_SUBSEQUENCE",
7442 ``!s:num->real. ?r:num->num.
7443   (!m n. m < n ==> r(m) < r(n)) /\
7444  ((!m n. m <= n ==> s(r(m)) <= s(r(n))) \/
7445   (!m n. m <= n ==> s(r(n)) <= s(r(m))))``,
7446  GEN_TAC THEN
7447  ASM_CASES_TAC ``!n:num. ?p. n < p /\ !m. p <= m ==> s(m):real <= s(p)`` THEN
7448  POP_ASSUM MP_TAC THEN
7449  SIMP_TAC std_ss [NOT_FORALL_THM, NOT_EXISTS_THM, NOT_IMP, DE_MORGAN_THM] THEN
7450  SIMP_TAC std_ss [RIGHT_OR_EXISTS_THM, SKOLEM_THM, REAL_NOT_LE, REAL_NOT_LT] THENL
7451  [ABBREV_TAC ``N = 0:num``, DISCH_THEN(X_CHOOSE_THEN ``N:num`` MP_TAC)] THEN
7452  DISCH_THEN(X_CHOOSE_THEN ``next:num->num`` STRIP_ASSUME_TAC) THEN
7453  (KNOW_TAC ``(?r. (r 0 = (next:num->num) (SUC N)) /\
7454             (!n. r (SUC n) = (next:num->num) (r n)))`` THENL
7455  [RW_TAC std_ss [num_Axiom], ALL_TAC]) THEN
7456  STRIP_TAC THEN EXISTS_TAC ``r:num->num`` THENL
7457  [SUBGOAL_THEN ``!m:num n:num. r n <= m ==> s(m) <= s(r n):real``
7458   ASSUME_TAC THEN TRY CONJ_TAC THEN TRY DISJ2_TAC THEN
7459   GEN_TAC THEN INDUCT_TAC THEN ASM_SIMP_TAC std_ss [LT, LE] THEN
7460   ASM_MESON_TAC[REAL_LE_TRANS, REAL_LE_REFL, LESS_IMP_LESS_OR_EQ, LESS_TRANS],
7461   SUBGOAL_THEN ``!n. N < (r:num->num) n`` ASSUME_TAC THEN
7462   TRY(CONJ_TAC THENL [GEN_TAC, DISJ1_TAC THEN GEN_TAC]) THEN
7463   INDUCT_TAC THEN ASM_SIMP_TAC std_ss [LT, LE] THEN
7464   TRY STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
7465   ASM_MESON_TAC[REAL_LT_REFL, LT_LE, LESS_LESS_EQ_TRANS, REAL_LE_REFL,
7466    REAL_LT_LE, REAL_LE_TRANS, LT]]);
7467
7468val CONVERGENT_BOUNDED_INCREASING = store_thm ("CONVERGENT_BOUNDED_INCREASING",
7469 ``!s:num->real b. (!m n. m <= n ==> s m <= s n) /\ (!n. abs(s n) <= b)
7470   ==> ?l. !e. &0 < e ==> ?N. !n. N <= n ==> abs(s n - l) < e``,
7471  REPEAT STRIP_TAC THEN
7472  MP_TAC(SPEC ``\x. ?n. (s:num->real) n = x`` REAL_COMPLETE) THEN BETA_TAC THEN
7473  KNOW_TAC ``(?x:real n:num. s n = x) /\ (?M. !x. (?n. s n = x) ==> x <= M)`` THENL
7474  [ASM_MESON_TAC[REAL_ARITH ``abs(x:real) <= b ==> x <= b``],
7475   DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
7476  DISCH_THEN (X_CHOOSE_TAC ``l:real``) THEN EXISTS_TAC ``l:real`` THEN
7477  POP_ASSUM MP_TAC THEN STRIP_TAC THEN
7478  X_GEN_TAC ``e:real`` THEN STRIP_TAC THEN
7479  FIRST_X_ASSUM(MP_TAC o SPEC ``l - e:real``) THEN
7480  METIS_TAC[REAL_ARITH ``&0:real < e ==> ~(l <= l - e)``,
7481  REAL_ARITH ``x <= y /\ y <= l /\ ~(x <= l - e) ==> abs(y - l) < e:real``]);
7482
7483val CONVERGENT_BOUNDED_MONOTONE = store_thm ("CONVERGENT_BOUNDED_MONOTONE",
7484 ``!s:num->real b. (!n. abs(s n) <= b) /\
7485   ((!m n. m <= n ==> s m <= s n) \/
7486    (!m n. m <= n ==> s n <= s m))
7487   ==> ?l. !e. &0 < e ==> ?N. !n. N <= n ==> abs(s n - l) < e``,
7488  REPEAT STRIP_TAC THENL
7489  [ASM_MESON_TAC[CONVERGENT_BOUNDED_INCREASING], ALL_TAC] THEN
7490  MP_TAC(SPEC ``\n. -((s:num->real) n)`` CONVERGENT_BOUNDED_INCREASING) THEN
7491  ASM_SIMP_TAC std_ss [REAL_LE_NEG2, ABS_NEG] THEN
7492  ASM_MESON_TAC[REAL_ARITH ``abs(x - -l) = abs(-x - l:real)``]);
7493
7494val COMPACT_REAL_LEMMA = store_thm ("COMPACT_REAL_LEMMA",
7495 ``!s b. (!n:num. abs(s n) <= b)
7496   ==> ?l r. (!m n:num. m < n ==> r(m) < r(n)) /\
7497   !e. &0:real < e ==> ?N. !n. N <= n ==> abs(s(r n) - l) < e``,
7498  REPEAT GEN_TAC THEN DISCH_TAC THEN
7499  KNOW_TAC ``?(r :num -> num) (l :real).
7500  (!(m :num) (n :num). m < n ==> r m < r n) /\
7501  !(e :real).
7502    (0 :real) < e ==>
7503    ?(N :num).
7504      !(n :num). N <= n ==> abs ((s :num -> real) (r n) - l) < e`` THENL
7505  [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN
7506  MP_TAC(SPEC ``s:num->real`` MONOTONE_SUBSEQUENCE) THEN
7507  DISCH_THEN (X_CHOOSE_TAC ``r:num->num``) THEN EXISTS_TAC ``r:num->num`` THEN
7508  ASM_SIMP_TAC std_ss [] THEN POP_ASSUM MP_TAC THEN STRIP_TAC THENL
7509  [MP_TAC(SPEC ``\n. ((s:num->real) ((r:num->num) n))`` CONVERGENT_BOUNDED_INCREASING),
7510   MP_TAC(SPEC ``\n. -((s:num->real) ((r:num->num) n))`` CONVERGENT_BOUNDED_INCREASING)] THEN
7511  ASM_SIMP_TAC std_ss [REAL_LE_NEG2, ABS_NEG] THEN
7512  ASM_MESON_TAC[REAL_ARITH ``abs(x - -l) = abs(-x - l:real)``]);
7513
7514val COMPACT_LEMMA = store_thm ("COMPACT_LEMMA",
7515``!s. bounded s /\ (!n. (x:num->real) n IN s)
7516      ==> ?l:real r. (!m n. m < n ==> r m < (r:num->num) n) /\
7517      !e. &0 < e ==> ?N. !n i. N <= n ==> abs(x(r n) - l) < e``,
7518  METIS_TAC [COMPACT_REAL_LEMMA, bounded_def]);
7519
7520val BOUNDED_CLOSED_IMP_COMPACT = store_thm ("BOUNDED_CLOSED_IMP_COMPACT",
7521 ``!s:real->bool. bounded s /\ closed s ==> compact s``,
7522  REPEAT STRIP_TAC THEN REWRITE_TAC[compact] THEN
7523  X_GEN_TAC ``x:num->real`` THEN DISCH_TAC THEN
7524  MP_TAC(ISPEC ``s:real->bool`` COMPACT_LEMMA) THEN
7525  ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
7526  MAP_EVERY EXISTS_TAC [``l:real``, ``r:num->num``] THEN
7527  ASM_SIMP_TAC std_ss [] THEN
7528  MATCH_MP_TAC(TAUT `(b ==> a) /\ b ==> a /\ b`) THEN
7529  REPEAT STRIP_TAC THENL
7530  [FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CLOSED_SEQUENTIAL_LIMITS]) THEN
7531   EXISTS_TAC ``(x:num->real) o (r:num->num)`` THEN
7532   ASM_SIMP_TAC std_ss [o_THM], ALL_TAC] THEN
7533  REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
7534  FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN
7535  ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT, REAL_HALF,
7536   ARITH_PROVE ``0:num < n <=> ~(n = 0)``] THEN
7537  STRIP_TAC THEN EXISTS_TAC ``N:num`` THEN
7538  POP_ASSUM MP_TAC THEN
7539  REWRITE_TAC[dist] THEN REPEAT STRIP_TAC THEN
7540  GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN
7541  GEN_REWR_TAC LAND_CONV [GSYM REAL_ADD_RID] THEN MATCH_MP_TAC REAL_LT_ADD2 THEN
7542  UNDISCH_TAC `` !n:num. N <= n ==> abs (x ((r:num->num) n) - l) < e / 2:real`` THEN
7543  DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `n:num`) THEN
7544  ASM_REWRITE_TAC [] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
7545  METIS_TAC [REAL_LT_HALF1]);
7546
7547(* ------------------------------------------------------------------------- *)
7548(* Completeness.                                                             *)
7549(* ------------------------------------------------------------------------- *)
7550
7551val cauchy = new_definition ("cauchy",
7552  ``cauchy (s:num->real) <=>
7553     !e. &0 < e ==> ?N. !m n. m >= N /\ n >= N ==> dist(s m,s n) < e``);
7554
7555val complete = new_definition ("complete",
7556  ``complete s <=>
7557     !f:num->real. (!n. f n IN s) /\ cauchy f
7558                      ==> ?l. l IN s /\ (f --> l) sequentially``);
7559
7560val CAUCHY = store_thm ("CAUCHY",
7561 ``!s:num->real.
7562      cauchy s <=> !e. &0 < e ==> ?N. !n. n >= N ==> dist(s n,s N) < e``,
7563  REPEAT GEN_TAC THEN REWRITE_TAC[cauchy, GREATER_EQ] THEN EQ_TAC THENL
7564   [MESON_TAC[LESS_EQ_REFL], DISCH_TAC] THEN
7565  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
7566  FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_LT_HALF1] THEN
7567  MESON_TAC[DIST_TRIANGLE_HALF_L]);
7568
7569val CONVERGENT_IMP_CAUCHY = store_thm ("CONVERGENT_IMP_CAUCHY",
7570 ``!s l. (s --> l) sequentially ==> cauchy s``,
7571  REWRITE_TAC[LIM_SEQUENTIALLY, cauchy] THEN
7572  REPEAT GEN_TAC THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
7573  FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN
7574  ASM_SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT] THEN
7575  ASM_MESON_TAC[GREATER_EQ, LESS_EQ_REFL, DIST_TRIANGLE_HALF_L]);
7576
7577val GREATER_EQ_REFL = store_thm ("GREATER_EQ_REFL",
7578  ``!m:num. m >= m``,
7579  REWRITE_TAC [GREATER_EQ, LESS_EQ_REFL]);
7580
7581val UPPER_BOUND_FINITE_SET_REAL = store_thm ("UPPER_BOUND_FINITE_SET_REAL",
7582 ``!f:('a->real) s. FINITE(s) ==> ?a. !x. x IN s ==> f(x) <= a``,
7583  REPEAT GEN_TAC THEN
7584  KNOW_TAC `` (?a. !x. x IN s ==> (f:'a->real) x <= a) =
7585          (\s. ?a. !x. x IN s ==> (f:'a->real) x <= a) s`` THENL
7586  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
7587  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
7588  REWRITE_TAC[IN_INSERT, NOT_IN_EMPTY] THEN
7589  MESON_TAC[REAL_LE_TOTAL, REAL_LE_REFL, REAL_LE_TRANS]);
7590
7591val CAUCHY_IMP_BOUNDED = store_thm ("CAUCHY_IMP_BOUNDED",
7592 ``!s:num->real. cauchy s ==> bounded {y | ?n. y = s n}``,
7593  REWRITE_TAC[cauchy, bounded_def, GSPECIFICATION] THEN GEN_TAC THEN
7594  DISCH_THEN(MP_TAC o SPEC ``&1:real``) THEN REWRITE_TAC[REAL_LT_01] THEN
7595  DISCH_THEN(X_CHOOSE_THEN ``N:num`` (MP_TAC o SPEC ``N:num``)) THEN
7596  REWRITE_TAC[GREATER_EQ_REFL] THEN DISCH_TAC THEN
7597  SUBGOAL_THEN ``!n:num. N <= n ==> abs(s n :real) <= abs(s N) + &1:real``
7598  ASSUME_TAC THENL
7599   [ASM_MESON_TAC[GREATER_EQ, dist, DIST_SYM, ABS_TRIANGLE_SUB,
7600                  REAL_ARITH ``a <= b + c /\ c < &1 ==> a <= b + &1:real``],
7601    MP_TAC(ISPECL [``\n:num. abs(s n :real)``, ``0..N``]
7602                  UPPER_BOUND_FINITE_SET_REAL) THEN
7603    SIMP_TAC std_ss [FINITE_NUMSEG, IN_NUMSEG, LESS_EQ_0, GSYM LEFT_EXISTS_IMP_THM] THEN
7604    ASM_MESON_TAC[LESS_EQ_CASES,
7605                  REAL_ARITH ``x <= a \/ x <= b ==> x <= abs a + abs b:real``]]);
7606
7607val COMPACT_IMP_COMPLETE = store_thm ("COMPACT_IMP_COMPLETE",
7608 ``!s:real->bool. compact s ==> complete s``,
7609  GEN_TAC THEN REWRITE_TAC[complete, compact] THEN
7610  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `f:num->real`) THEN
7611  DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN
7612  ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC ``l:real`` THEN
7613  FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] LIM_ADD)) THEN
7614  DISCH_THEN(MP_TAC o SPEC ``\n. (f:num->real)(n) - f(r n)``) THEN
7615  DISCH_THEN(MP_TAC o SPEC ``0:real``) THEN ASM_SIMP_TAC std_ss [o_THM] THEN
7616  SIMP_TAC std_ss [REAL_ADD_RID, REAL_SUB_ADD2, ETA_AX] THEN
7617  DISCH_THEN MATCH_MP_TAC THEN
7618  UNDISCH_TAC ``cauchy f`` THEN GEN_REWR_TAC LAND_CONV [cauchy] THEN
7619  SIMP_TAC std_ss [GE, LIM, SEQUENTIALLY, dist, REAL_SUB_RZERO] THEN
7620  SUBGOAL_THEN ``!n:num. n <= r(n)`` MP_TAC THENL [INDUCT_TAC, ALL_TAC] THEN
7621  ASM_MESON_TAC[LESS_EQ_TRANS, LESS_EQ_REFL, LT, LESS_EQ_LESS_TRANS, ZERO_LESS_EQ, LE_SUC_LT]);
7622
7623val COMPLETE_UNIV = store_thm ("COMPLETE_UNIV",
7624 ``complete univ(:real)``,
7625  REWRITE_TAC[complete, IN_UNIV] THEN X_GEN_TAC ``x:num->real`` THEN
7626  DISCH_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_IMP_BOUNDED) THEN
7627  DISCH_THEN(ASSUME_TAC o MATCH_MP BOUNDED_CLOSURE) THEN
7628  MP_TAC(ISPEC ``closure {y:real | ?n:num. y = x n}``
7629   COMPACT_IMP_COMPLETE) THEN
7630  ASM_SIMP_TAC std_ss [BOUNDED_CLOSED_IMP_COMPACT, CLOSED_CLOSURE, complete] THEN
7631  DISCH_THEN(MP_TAC o SPEC ``x:num->real``) THEN
7632  KNOW_TAC ``(!n. x n IN closure {y | ?n. y = x n}) /\ cauchy x`` THENL
7633  [ALL_TAC, MESON_TAC[]] THEN
7634  ASM_SIMP_TAC std_ss [closure, GSPECIFICATION, IN_UNION] THEN MESON_TAC[]);
7635
7636val COMPLETE_EQ_CLOSED = store_thm ("COMPLETE_EQ_CLOSED",
7637 ``!s:real->bool. complete s <=> closed s``,
7638  GEN_TAC THEN EQ_TAC THENL
7639  [REWRITE_TAC[complete, CLOSED_LIMPT, LIMPT_SEQUENTIAL] THEN
7640   SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN GEN_TAC THEN
7641   SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN DISCH_TAC THEN
7642   GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `f:num->real`) THEN
7643   MESON_TAC[CONVERGENT_IMP_CAUCHY, IN_DELETE, LIM_UNIQUE,
7644    TRIVIAL_LIMIT_SEQUENTIALLY],
7645   REWRITE_TAC[complete, CLOSED_SEQUENTIAL_LIMITS] THEN DISCH_TAC THEN
7646   X_GEN_TAC ``f:num->real`` THEN STRIP_TAC THEN
7647   MP_TAC(REWRITE_RULE[complete] COMPLETE_UNIV) THEN
7648   DISCH_THEN(MP_TAC o SPEC ``f:num->real``) THEN
7649   ASM_REWRITE_TAC[IN_UNIV] THEN ASM_MESON_TAC[]]);
7650
7651val CONVERGENT_EQ_CAUCHY = store_thm ("CONVERGENT_EQ_CAUCHY",
7652 ``!s. (?l. (s --> l) sequentially) <=> cauchy s``,
7653  GEN_TAC THEN EQ_TAC THENL
7654  [METIS_TAC [LEFT_IMP_EXISTS_THM, CONVERGENT_IMP_CAUCHY],
7655   REWRITE_TAC[REWRITE_RULE[complete, IN_UNIV] COMPLETE_UNIV]]);
7656
7657val CONVERGENT_IMP_BOUNDED = store_thm ("CONVERGENT_IMP_BOUNDED",
7658 ``!s l. (s --> l) sequentially ==> bounded (IMAGE s univ(:num))``,
7659  SIMP_TAC std_ss [LEFT_FORALL_IMP_THM, CONVERGENT_EQ_CAUCHY] THEN
7660  REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CAUCHY_IMP_BOUNDED) THEN
7661  REWRITE_TAC [bounded_def] THEN SET_TAC []);
7662
7663(* ------------------------------------------------------------------------- *)
7664(* Total boundedness.                                                        *)
7665(* ------------------------------------------------------------------------- *)
7666
7667val COMPACT_IMP_TOTALLY_BOUNDED = store_thm
7668  ("COMPACT_IMP_TOTALLY_BOUNDED",
7669 ``!s:real->bool. compact s
7670   ==> !e. &0 < e ==> ?k. FINITE k /\ k SUBSET s /\
7671       s SUBSET (BIGUNION (IMAGE (\x. ball(x,e)) k))``,
7672  GEN_TAC THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN
7673  SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM] THEN
7674  REWRITE_TAC[TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`, SUBSET_DEF] THEN
7675  DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
7676  SUBGOAL_THEN
7677   ``?x:num->real. !n. x(n) IN s /\ !m. m < n ==> ~(dist(x(m),x(n)) < e)``
7678   MP_TAC THENL
7679  [SUBGOAL_THEN
7680   ``?x:num->real.
7681     !n. x(n) = @y. y IN s /\ !m. m < n ==> ~(dist(x(m),y) < e)``
7682     MP_TAC THENL
7683   [KNOW_TAC ``?(x :num -> real). !(n :num). x n =
7684    (\x n. @(y :real). y IN (s :real -> bool) /\
7685      !(m :num). m < n ==> ~((dist (x m,y) :real) < (e :real))) x n`` THENL
7686    [ALL_TAC, METIS_TAC []] THEN
7687    MATCH_MP_TAC(MATCH_MP WF_REC WF_num) THEN SIMP_TAC std_ss [], ALL_TAC] THEN
7688    DISCH_THEN (X_CHOOSE_TAC ``x:num->real``) THEN EXISTS_TAC ``x:num->real`` THEN
7689    KNOW_TAC ``!(n :num). (\n. (x :num -> real) n IN (s :real -> bool) /\
7690     !(m :num). m < n ==> ~((dist (x m,x n) :real) < (e :real))) n`` THENL
7691    [ALL_TAC, METIS_TAC []] THEN
7692    MATCH_MP_TAC COMPLETE_INDUCTION THEN X_GEN_TAC ``n:num`` THEN
7693    BETA_TAC THEN FIRST_X_ASSUM(SUBST1_TAC o SPEC ``n:num``) THEN STRIP_TAC THEN
7694    CONV_TAC SELECT_CONV THEN
7695    FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (x:num->real) {m | m < n}``) THEN
7696    SIMP_TAC std_ss [IMAGE_FINITE, FINITE_NUMSEG_LT, NOT_FORALL_THM, NOT_IMP] THEN
7697    SIMP_TAC std_ss [IN_BIGUNION, IN_IMAGE, GSPECIFICATION] THEN METIS_TAC[IN_BALL],
7698    ALL_TAC] THEN
7699   SIMP_TAC std_ss [compact, NOT_FORALL_THM] THEN
7700   DISCH_THEN (X_CHOOSE_TAC ``x:num->real``) THEN EXISTS_TAC ``x:num->real`` THEN
7701   POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [NOT_IMP, FORALL_AND_THM] THEN
7702   STRIP_TAC THEN ASM_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN REPEAT STRIP_TAC THEN
7703   CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
7704   FIRST_X_ASSUM(MP_TAC o MATCH_MP CONVERGENT_IMP_CAUCHY) THEN
7705   REWRITE_TAC[cauchy] THEN DISCH_THEN(MP_TAC o SPEC ``e:real``) THEN
7706   ASM_SIMP_TAC std_ss [o_THM, NOT_EXISTS_THM, NOT_IMP, NOT_FORALL_THM, NOT_IMP] THEN
7707   X_GEN_TAC ``N:num`` THEN MAP_EVERY EXISTS_TAC [``N:num``, ``SUC N``] THEN
7708   CONJ_TAC THENL [ARITH_TAC, ASM_MESON_TAC[LT]]);
7709
7710(* ------------------------------------------------------------------------- *)
7711(* Heine-Borel theorem (following Burkill & Burkill vol. 2) *)
7712(* ------------------------------------------------------------------------- *)
7713
7714val HEINE_BOREL_LEMMA = store_thm ("HEINE_BOREL_LEMMA",
7715 ``!s:real->bool. compact s
7716    ==> !t. s SUBSET (BIGUNION t) /\ (!b. b IN t ==> open b)
7717       ==> ?e. &0 < e /\
7718           !x. x IN s ==> ?b. b IN t /\ ball(x,e) SUBSET b``,
7719  GEN_TAC THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN
7720  SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM] THEN
7721  DISCH_THEN(CHOOSE_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
7722  DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC ``&1 / (&n + &1:real)``) THEN
7723  SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT_01, REAL_ARITH ``x <= y ==> x < y + &1:real``,
7724   FORALL_AND_THM, REAL_POS, NOT_FORALL_THM, NOT_IMP, SKOLEM_THM, compact] THEN
7725  DISCH_THEN (X_CHOOSE_TAC ``f:num->real``) THEN
7726  EXISTS_TAC ``f:num->real`` THEN POP_ASSUM MP_TAC THEN
7727  SIMP_TAC std_ss [NOT_EXISTS_THM] THEN
7728  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
7729  DISCH_TAC THEN MAP_EVERY X_GEN_TAC [``l:real``, ``r:num->num``] THEN
7730  CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
7731  SUBGOAL_THEN ``?b:real->bool. l IN b /\ b IN t`` STRIP_ASSUME_TAC THENL
7732  [ASM_MESON_TAC[SUBSET_DEF, IN_BIGUNION], ALL_TAC] THEN
7733  SUBGOAL_THEN ``?e. &0 < e /\ !z:real. dist(z,l) < e ==> z IN b``
7734   STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[open_def], ALL_TAC] THEN
7735  UNDISCH_TAC ``(f o r:num->num --> l:real) sequentially`` THEN DISCH_TAC THEN
7736  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LIM_SEQUENTIALLY]) THEN
7737  DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN
7738  SUBGOAL_THEN ``&0 < e / &2:real`` (fn th =>
7739   REWRITE_TAC [th, o_THM] THEN MP_TAC(ONCE_REWRITE_RULE [REAL_ARCH_INV] th))
7740   THENL [ASM_REWRITE_TAC[REAL_HALF], ALL_TAC] THEN
7741  DISCH_THEN(X_CHOOSE_THEN ``N1:num`` STRIP_ASSUME_TAC) THEN
7742  DISCH_THEN(X_CHOOSE_THEN ``N2:num`` STRIP_ASSUME_TAC) THEN
7743  FIRST_X_ASSUM(MP_TAC o SPECL
7744   [``(r:num->num)(N1 + N2)``, ``b:real->bool``]) THEN
7745  ASM_REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
7746  FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC DIST_TRIANGLE_HALF_R THEN
7747  EXISTS_TAC ``(f:num->real)(r(N1 + N2:num))`` THEN CONJ_TAC THENL
7748  [ALL_TAC, FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC] THEN
7749  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [IN_BALL]) THEN
7750  MATCH_MP_TAC(REAL_ARITH ``a <= b ==> x < a ==> x < b:real``) THEN
7751  MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``inv(&N1:real)`` THEN
7752  ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE] THEN REWRITE_TAC[real_div, REAL_MUL_LID] THEN
7753  MATCH_MP_TAC REAL_LE_INV2 THEN
7754  REWRITE_TAC[REAL_OF_NUM_ADD, REAL_OF_NUM_LE, REAL_LT] THEN
7755  ASM_MESON_TAC[ARITH_PROVE ``(~(n = 0) ==> 0 < n:num)``, LESS_EQ_ADD, MONOTONE_BIGGER,
7756   LESS_IMP_LESS_OR_EQ, LESS_EQ_TRANS]);
7757
7758val COMPACT_IMP_HEINE_BOREL = store_thm
7759  ("COMPACT_IMP_HEINE_BOREL",
7760 ``!s. compact (s:real->bool)
7761  ==> !f. (!t. t IN f ==> open t) /\ s SUBSET (BIGUNION f)
7762  ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (BIGUNION f')``,
7763  REPEAT STRIP_TAC THEN
7764  FIRST_ASSUM(MP_TAC o SPEC ``f:(real->bool)->bool`` o
7765   MATCH_MP HEINE_BOREL_LEMMA) THEN ASM_REWRITE_TAC[] THEN
7766  DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
7767  DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN
7768  SIMP_TAC std_ss [SKOLEM_THM, SUBSET_DEF, IN_BALL] THEN
7769  DISCH_THEN(X_CHOOSE_TAC ``B:real->real->bool``) THEN
7770  FIRST_ASSUM(MP_TAC o SPEC ``e:real`` o
7771   MATCH_MP COMPACT_IMP_TOTALLY_BOUNDED) THEN
7772  ASM_SIMP_TAC std_ss [BIGUNION_IMAGE, SUBSET_DEF, GSPECIFICATION] THEN
7773  REWRITE_TAC[IN_BIGUNION, IN_BALL] THEN
7774  DISCH_THEN(X_CHOOSE_THEN ``k:real->bool`` STRIP_ASSUME_TAC) THEN
7775  EXISTS_TAC ``IMAGE (B:real->real->bool) k`` THEN
7776  ASM_SIMP_TAC std_ss [IMAGE_FINITE, SUBSET_DEF, IN_IMAGE, LEFT_IMP_EXISTS_THM] THEN
7777  ASM_MESON_TAC[IN_BALL]);
7778
7779(* ------------------------------------------------------------------------- *)
7780(* Bolzano-Weierstrass property.                                             *)
7781(* ------------------------------------------------------------------------- *)
7782
7783val HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS = store_thm
7784  ("HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS",
7785 ``!s:real->bool.
7786  (!f. (!t. t IN f ==> open t) /\ s SUBSET (BIGUNION f)
7787   ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (BIGUNION f'))
7788   ==> !t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t``,
7789  SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM, limit_point_of] THEN REPEAT GEN_TAC THEN
7790  ONCE_REWRITE_TAC[TAUT `a ==> b /\ c ==> d <=> c ==> ~d ==> a ==> ~b`] THEN
7791  KNOW_TAC ``t SUBSET s
7792       ==> (!x. ?t'. ~(x IN s:real->bool /\
7793                 (x IN t' /\ open t' ==> (?y. ~(y = x) /\ y IN t /\ y IN t'))))
7794       ==> (!f. (!t. t IN f ==> open t) /\ s SUBSET BIGUNION f
7795              ==> (?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET BIGUNION f'))
7796        ==> ~INFINITE t`` THENL
7797  [ALL_TAC, SIMP_TAC std_ss [NOT_FORALL_THM, NOT_EXISTS_THM, RIGHT_AND_FORALL_THM] THEN
7798   METIS_TAC []] THEN
7799  DISCH_TAC THEN SIMP_TAC std_ss [SKOLEM_THM] THEN
7800  DISCH_THEN(X_CHOOSE_TAC ``f:real->real->bool``) THEN
7801  DISCH_THEN(MP_TAC o SPEC
7802   ``{t:real->bool | ?x:real. x IN s /\ (t = f x)}``) THEN
7803  SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_BIGUNION, NOT_IMP] THEN
7804  KNOW_TAC ``(!t. (?x. x IN s:real->bool /\ (t = f x)) ==> open t) /\
7805     (!x. x IN s ==> ?s'. x IN s' /\ ?x. x IN s /\ (s' = f x))`` THENL
7806  [METIS_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
7807  DISCH_THEN(X_CHOOSE_THEN ``g:(real->bool)->bool`` STRIP_ASSUME_TAC) THEN
7808  MATCH_MP_TAC SUBSET_FINITE_I THEN
7809  EXISTS_TAC ``{x:real | x IN t /\ (f(x):real->bool) IN g}`` THEN
7810  CONJ_TAC THENL
7811  [MATCH_MP_TAC FINITE_IMAGE_INJ_GENERAL THEN ASM_MESON_TAC[SUBSET_DEF],
7812   SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN X_GEN_TAC ``u:real`` THEN
7813   DISCH_TAC THEN SUBGOAL_THEN ``(u:real) IN s`` ASSUME_TAC THEN
7814   ASM_MESON_TAC[SUBSET_DEF]]);
7815
7816(* ------------------------------------------------------------------------- *)
7817(* Complete the chain of compactness variants.                               *)
7818(* ------------------------------------------------------------------------- *)
7819
7820val BOLZANO_WEIERSTRASS_IMP_BOUNDED = store_thm ("BOLZANO_WEIERSTRASS_IMP_BOUNDED",
7821 ``!s:real->bool.
7822   (!t. INFINITE t /\ t SUBSET s ==> ?x. x limit_point_of t)
7823   ==> bounded s``,
7824  GEN_TAC THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN
7825  SIMP_TAC std_ss [compact, bounded_def] THEN
7826  SIMP_TAC std_ss [NOT_FORALL_THM, NOT_EXISTS_THM, SKOLEM_THM, NOT_IMP] THEN
7827  REWRITE_TAC[REAL_NOT_LE] THEN
7828  DISCH_THEN(X_CHOOSE_TAC ``beyond:real->real``) THEN
7829  KNOW_TAC ``?f. (f(0) = beyond(&0)) /\
7830   (!n. f(SUC n) = beyond(abs(f n) + &1):real)`` THENL
7831  [RW_TAC std_ss [num_Axiom], ALL_TAC] THEN
7832  DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` STRIP_ASSUME_TAC) THEN
7833  EXISTS_TAC ``IMAGE (x:num->real) UNIV`` THEN
7834  SUBGOAL_THEN
7835  ``!m n. m < n ==> abs((x:num->real) m) + &1 < abs(x n)``
7836   ASSUME_TAC THENL
7837  [GEN_TAC THEN INDUCT_TAC THEN ASM_REWRITE_TAC[LT] THEN
7838   ASM_MESON_TAC[REAL_LT_TRANS, REAL_ARITH ``b < b + &1:real``],
7839   ALL_TAC] THEN
7840  SUBGOAL_THEN ``!m n. ~(m = n) ==> &1 < dist((x:num->real) m,x n)``
7841  ASSUME_TAC THENL
7842  [REPEAT GEN_TAC THEN REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC
7843   (SPECL [``m:num``, ``n:num``] LT_CASES) THEN
7844   ASM_MESON_TAC[dist, LT_CASES, ABS_TRIANGLE_SUB, ABS_SUB,
7845    REAL_ARITH ``x + &1 < y /\ y <= x + d ==> &1 < d:real``],
7846   ALL_TAC] THEN
7847  REPEAT CONJ_TAC THENL
7848  [ASM_MESON_TAC[IMAGE_11_INFINITE, num_INFINITE, DIST_REFL,
7849   REAL_ARITH ``~(&1 < &0:real)``],
7850  SIMP_TAC std_ss [SUBSET_DEF, IN_IMAGE, IN_UNIV, LEFT_IMP_EXISTS_THM] THEN
7851  INDUCT_TAC THEN METIS_TAC[], ALL_TAC] THEN
7852  X_GEN_TAC ``l:real`` THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
7853  SIMP_TAC std_ss [IN_IMAGE, IN_UNIV, GSYM LEFT_EXISTS_AND_THM] THEN
7854  KNOW_TAC ``~(!(e :real). (0 :real) < e ==>
7855      (?(x'' :num) (x' :real). (x' = (x :num -> real) x'') /\ (x' <> (l :real)) /\
7856        ((dist (x',l) :real) < e)))`` THENL
7857  [ALL_TAC, METIS_TAC []] THEN SIMP_TAC std_ss [UNWIND_THM2] THEN
7858  CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
7859  FIRST_ASSUM(MP_TAC o SPEC ``&1 / &2:real``) THEN
7860  REWRITE_TAC [METIS [REAL_HALF_BETWEEN] ``0 < 1 / 2:real``] THEN
7861  DISCH_THEN(X_CHOOSE_THEN ``k:num`` STRIP_ASSUME_TAC) THEN
7862  FIRST_X_ASSUM(MP_TAC o SPEC ``dist((x:num->real) k,l)``) THEN
7863  ASM_SIMP_TAC std_ss [DIST_POS_LT] THEN
7864  X_GEN_TAC ``m:num`` THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
7865  ASM_CASES_TAC ``m:num = k`` THEN
7866  ASM_MESON_TAC[DIST_TRIANGLE_HALF_L, REAL_LT_TRANS, REAL_LT_REFL]);
7867
7868val INF_FINITE_LEMMA = store_thm ("INF_FINITE_LEMMA",
7869 ``!s. FINITE s /\ ~(s = {}) ==> ?b:real. b IN s /\ !x. x IN s ==> b <= x``,
7870  REWRITE_TAC[CONJ_EQ_IMP] THEN
7871  ONCE_REWRITE_TAC [METIS [] ``!s. ( s <> {} ==> ?b. b IN s /\ !x. x IN s ==> b <= x) =                        (\s.  s <> {} ==> ?b:real. b IN s /\ !x. x IN s ==> b <= x) s``] THEN
7872  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
7873  REWRITE_TAC[NOT_INSERT_EMPTY, IN_INSERT] THEN
7874  REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
7875  MESON_TAC[REAL_LE_TOTAL, REAL_LE_TRANS]);
7876
7877val INF_FINITE = store_thm ("INF_FINITE",
7878 ``!s:real->bool. FINITE s /\ ~(s = {}) ==> (inf s) IN s /\ !x. x IN s ==> inf s <= x``,
7879  GEN_TAC THEN DISCH_TAC THEN
7880  FIRST_ASSUM(MP_TAC o MATCH_MP INF_FINITE_LEMMA) THEN
7881  ASM_MESON_TAC[REAL_LE_ANTISYM, REAL_LE_TOTAL, INF]);
7882
7883val REAL_LE_INF_FINITE = store_thm ("REAL_LE_INF_FINITE",
7884 ``!s:real->bool a. FINITE s /\ ~(s = {}) ==> (a <= inf s <=> !x. x IN s ==> a <= x)``,
7885  METIS_TAC[INF_FINITE, REAL_LE_TRANS]);
7886
7887val REAL_INF_LE_FINITE = store_thm ("REAL_INF_LE_FINITE",
7888 ``!s:real->bool a. FINITE s /\ ~(s = {}) ==> (inf s <= a <=> ?x. x IN s /\ x <= a)``,
7889  MESON_TAC[INF_FINITE, REAL_LE_TRANS]);
7890
7891val REAL_LT_INF_FINITE = store_thm ("REAL_LT_INF_FINITE",
7892 ``!s:real->bool a. FINITE s /\ ~(s = {}) ==> (a < inf s <=> !x. x IN s ==> a < x)``,
7893  MESON_TAC[INF_FINITE, REAL_LTE_TRANS]);
7894
7895val REAL_INF_LT_FINITE = store_thm ("REAL_INF_LT_FINITE",
7896 ``!s:real->bool a. FINITE s /\ ~(s = {}) ==> (inf s < a <=> ?x. x IN s /\ x < a)``,
7897  MESON_TAC[INF_FINITE, REAL_LET_TRANS]);
7898
7899val SEQUENCE_INFINITE_LEMMA = store_thm ("SEQUENCE_INFINITE_LEMMA",
7900 ``!f l. (!n. ~(f(n) = l)) /\ (f --> l) sequentially
7901    ==> INFINITE {y:real | ?n. y = f n}``,
7902  REPEAT STRIP_TAC THEN MP_TAC(ISPEC
7903    ``IMAGE (\y:real. dist(y,l)) {y | ?n:num. y = f n}`` INF_FINITE) THEN
7904  ASM_SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, IN_IMAGE, IMAGE_FINITE, GSPECIFICATION] THEN
7905  ASM_MESON_TAC[LIM_SEQUENTIALLY, LESS_EQ_REFL, REAL_NOT_LE, DIST_POS_LT]);
7906
7907val LE_1 = store_thm ("LE_1",
7908 ``(!n:num. ~(n = 0) ==> 0 < n) /\
7909   (!n:num. ~(n = 0) ==> 1 <= n) /\
7910   (!n:num. 0 < n ==> ~(n = 0)) /\
7911   (!n:num. 0 < n ==> 1 <= n) /\
7912   (!n:num. 1 <= n ==> 0 < n) /\
7913   (!n:num. 1 <= n ==> ~(n = 0))``,
7914  REWRITE_TAC[LT_NZ, GSYM NOT_LESS, ONE, LT]);
7915
7916val LIMPT_OF_SEQUENCE_SUBSEQUENCE = store_thm ("LIMPT_OF_SEQUENCE_SUBSEQUENCE",
7917  ``!f:num->real l.
7918     l limit_point_of (IMAGE f univ(:num))
7919     ==> ?r. (!m n. m < n ==> r(m) < r(n)) /\ ((f o r) --> l) sequentially``,
7920  REPEAT STRIP_TAC THEN
7921  FIRST_ASSUM(MP_TAC o REWRITE_RULE [LIMPT_APPROACHABLE]) THEN
7922  DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC
7923   ``inf((inv(&n + &1:real)) INSERT IMAGE (\k. dist((f:num->real) k,l))
7924         {k | k IN (0:num)..n /\ ~(f k = l)})``) THEN
7925  SIMP_TAC std_ss [REAL_LT_INF_FINITE, FINITE_INSERT, NOT_INSERT_EMPTY,
7926   FINITE_RESTRICT, FINITE_NUMSEG, IMAGE_FINITE] THEN
7927  SIMP_TAC std_ss [FORALL_IN_INSERT, EXISTS_IN_IMAGE, FORALL_IN_IMAGE, IN_UNIV] THEN
7928  SIMP_TAC std_ss [REAL_LT_INV_EQ, METIS [REAL_LT, REAL_OF_NUM_ADD, GSYM ADD1, LESS_0]
7929                            ``&0 < &n + &1:real``] THEN
7930  SIMP_TAC std_ss [FORALL_AND_THM, FORALL_IN_GSPEC, GSYM DIST_NZ, SKOLEM_THM] THEN
7931  DISCH_THEN(X_CHOOSE_THEN ``nn:num->num`` STRIP_ASSUME_TAC) THEN
7932  KNOW_TAC ``?r:num->num. (r 0 = nn 0) /\ (!n. r (SUC n) = nn(r n))`` THENL
7933  [RW_TAC std_ss [num_Axiom], ALL_TAC] THEN
7934  STRIP_TAC THEN EXISTS_TAC ``r:num->num`` THEN
7935  MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
7936  [ONCE_REWRITE_TAC [METIS []
7937    `` (r:num->num) m < r n <=> (\m n. r m < r n) m n``] THEN
7938  MATCH_MP_TAC TRANSITIVE_STEPWISE_LT THEN CONJ_TAC THENL
7939  [METIS_TAC [LESS_TRANS], ALL_TAC] THEN
7940   X_GEN_TAC ``n:num`` THEN ASM_REWRITE_TAC[] THEN
7941   FIRST_X_ASSUM(MP_TAC o SPECL
7942    [``(r:num->num) n``, ``(nn:num->num)(r(n:num))``]) THEN
7943   ASM_SIMP_TAC arith_ss [IN_NUMSEG, ZERO_LESS_EQ, REAL_LT_REFL],
7944   DISCH_THEN(ASSUME_TAC o MATCH_MP MONOTONE_BIGGER)] THEN
7945  REWRITE_TAC[LIM_SEQUENTIALLY] THEN
7946  X_GEN_TAC ``e:real`` THEN GEN_REWR_TAC LAND_CONV [REAL_ARCH_INV] THEN
7947  DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN
7948  POP_ASSUM MP_TAC THEN STRIP_TAC THEN
7949  ONCE_REWRITE_TAC [METIS [] ``!n:num. (N <= n ==> dist ((f o r) n,l) < e) <=>
7950                          (\n. N <= n ==> dist ((f o r) n,l) < e) n``] THEN
7951  MATCH_MP_TAC INDUCTION THEN ASM_SIMP_TAC std_ss [CONJUNCT1 LE] THEN
7952  X_GEN_TAC ``n:num`` THEN DISCH_THEN(K ALL_TAC) THEN DISCH_TAC THEN
7953  ASM_SIMP_TAC std_ss [o_THM] THEN MATCH_MP_TAC REAL_LT_TRANS THEN
7954  EXISTS_TAC ``inv(&((r:num->num) n) + &1:real)`` THEN ASM_REWRITE_TAC[] THEN
7955  MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``inv(&N:real)`` THEN
7956  ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
7957  ASM_SIMP_TAC std_ss [REAL_OF_NUM_LE, REAL_LT, LE_1, REAL_OF_NUM_ADD] THEN
7958  MATCH_MP_TAC(ARITH_PROVE ``N <= SUC n /\ n <= r n ==> N <= r n + 1``) THEN
7959  ASM_REWRITE_TAC[]);
7960
7961val SEQUENCE_UNIQUE_LIMPT = store_thm ("SEQUENCE_UNIQUE_LIMPT",
7962 ``!f l l':real.
7963   (f --> l) sequentially /\ l' limit_point_of {y | ?n. y = f n}
7964   ==> (l' = l)``,
7965  REWRITE_TAC[SET_RULE ``{y | ?n. y = f n} = IMAGE f univ(:num)``] THEN
7966  REPEAT STRIP_TAC THEN
7967  FIRST_X_ASSUM(MP_TAC o MATCH_MP LIMPT_OF_SEQUENCE_SUBSEQUENCE) THEN
7968  DISCH_THEN(X_CHOOSE_THEN ``r:num->num`` STRIP_ASSUME_TAC) THEN
7969  MATCH_MP_TAC(ISPEC ``sequentially`` LIM_UNIQUE) THEN
7970  EXISTS_TAC ``(f:num->real) o (r:num->num)`` THEN
7971  ASM_SIMP_TAC std_ss [TRIVIAL_LIMIT_SEQUENTIALLY, LIM_SUBSEQUENCE]);
7972
7973val BOLZANO_WEIERSTRASS_IMP_CLOSED = store_thm ("BOLZANO_WEIERSTRASS_IMP_CLOSED",
7974 ``!s:real->bool.
7975  (!t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t)
7976   ==> closed s``,
7977  REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS] THEN
7978  MAP_EVERY X_GEN_TAC [``f:num->real``, ``l:real``] THEN
7979  DISCH_TAC THEN
7980  MAP_EVERY (MP_TAC o ISPECL [``f:num->real``, ``l:real``])
7981   [SEQUENCE_UNIQUE_LIMPT, SEQUENCE_INFINITE_LEMMA] THEN
7982  MATCH_MP_TAC(TAUT
7983   `(~d ==> a /\ ~(b /\ c)) ==> (a ==> b) ==> c ==> d`) THEN
7984  DISCH_TAC THEN CONJ_TAC THENL [ASM_MESON_TAC[], STRIP_TAC] THEN
7985  FIRST_X_ASSUM(MP_TAC o SPEC ``{y:real | ?n:num. y = f n}``) THEN
7986  ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL
7987  [SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION],
7988   ABBREV_TAC ``t = {y:real | ?n:num. y = f n}``] THEN
7989  ASM_MESON_TAC[]);
7990
7991(* ------------------------------------------------------------------------- *)
7992(* Hence express everything as an equivalence.                               *)
7993(* ------------------------------------------------------------------------- *)
7994
7995val COMPACT_EQ_HEINE_BOREL = store_thm ("COMPACT_EQ_HEINE_BOREL",
7996 ``!s:real->bool. compact s <=>
7997   !f. (!t. t IN f ==> open t) /\ s SUBSET (BIGUNION f)
7998   ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (BIGUNION f')``,
7999  GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [COMPACT_IMP_HEINE_BOREL] THEN
8000  DISCH_THEN(MP_TAC o MATCH_MP HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS) THEN
8001  DISCH_TAC THEN MATCH_MP_TAC BOUNDED_CLOSED_IMP_COMPACT THEN
8002  ASM_MESON_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED,
8003   BOLZANO_WEIERSTRASS_IMP_CLOSED]);
8004
8005val COMPACT_EQ_BOLZANO_WEIERSTRASS = store_thm ("COMPACT_EQ_BOLZANO_WEIERSTRASS",
8006 ``!s:real->bool. compact s <=>
8007   !t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t``,
8008  GEN_TAC THEN EQ_TAC THENL
8009  [SIMP_TAC std_ss [COMPACT_EQ_HEINE_BOREL, HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS],
8010   MESON_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED, BOLZANO_WEIERSTRASS_IMP_CLOSED,
8011    BOUNDED_CLOSED_IMP_COMPACT]]);
8012
8013val COMPACT_EQ_BOUNDED_CLOSED = store_thm ("COMPACT_EQ_BOUNDED_CLOSED",
8014``!s:real->bool. compact s <=> bounded s /\ closed s``,
8015  GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_CLOSED_IMP_COMPACT] THEN
8016  MESON_TAC[COMPACT_EQ_BOLZANO_WEIERSTRASS, BOLZANO_WEIERSTRASS_IMP_BOUNDED,
8017  BOLZANO_WEIERSTRASS_IMP_CLOSED]);
8018
8019val COMPACT_IMP_BOUNDED = store_thm ("COMPACT_IMP_BOUNDED",
8020 ``!s. compact s ==> bounded s``,
8021  SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED]);
8022
8023val COMPACT_IMP_CLOSED = store_thm ("COMPACT_IMP_CLOSED",
8024 ``!s. compact s ==> closed s``,
8025  SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED]);
8026
8027val COMPACT_SEQUENCE_WITH_LIMIT = store_thm ("COMPACT_SEQUENCE_WITH_LIMIT",
8028 ``!f l:real.
8029  (f --> l) sequentially ==> compact (l INSERT IMAGE f univ(:num))``,
8030  REPEAT STRIP_TAC THEN REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
8031  REWRITE_TAC[BOUNDED_INSERT] THEN CONJ_TAC THENL
8032  [ASM_MESON_TAC[CONVERGENT_IMP_BOUNDED],
8033   SIMP_TAC std_ss [CLOSED_LIMPT, LIMPT_INSERT, IN_INSERT] THEN
8034  SIMP_TAC std_ss [IMAGE_DEF, IN_UNIV, SET_RULE ``{f x | x IN s} =
8035    {y | ?x. x IN s /\ (y = f x)}``] THEN REPEAT STRIP_TAC THEN DISJ1_TAC THEN
8036  MATCH_MP_TAC SEQUENCE_UNIQUE_LIMPT THEN METIS_TAC[]]);
8037
8038val CLOSED_IN_COMPACT = store_thm ("CLOSED_IN_COMPACT",
8039 ``!s t:real->bool.
8040  compact s /\ closed_in (subtopology euclidean s) t
8041   ==> compact t``,
8042  SIMP_TAC std_ss [CONJ_EQ_IMP, COMPACT_EQ_BOUNDED_CLOSED, CLOSED_IN_CLOSED_EQ] THEN
8043  MESON_TAC[BOUNDED_SUBSET]);
8044
8045val CLOSED_IN_COMPACT_EQ = store_thm ("CLOSED_IN_COMPACT_EQ",
8046 ``!s t. compact s
8047  ==> (closed_in (subtopology euclidean s) t <=>
8048   compact t /\ t SUBSET s)``,
8049  MESON_TAC[CLOSED_IN_CLOSED_EQ, COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_SUBSET]);
8050
8051(* ------------------------------------------------------------------------- *)
8052(* A version of Heine-Borel for subtopology.                                 *)
8053(* ------------------------------------------------------------------------- *)
8054
8055val COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY = store_thm ("COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY",
8056 ``!s:real->bool. compact s <=>
8057   (!f. (!t. t IN f ==> open_in(subtopology euclidean s) t) /\
8058                        s SUBSET BIGUNION f
8059     ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET BIGUNION f')``,
8060  GEN_TAC THEN REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN EQ_TAC THEN
8061  DISCH_TAC THEN X_GEN_TAC ``f:(real->bool)->bool`` THENL
8062  [REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_TAC THEN
8063   POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN
8064   SIMP_TAC std_ss [SKOLEM_THM] THEN
8065   DISCH_THEN(CONJUNCTS_THEN2
8066   (X_CHOOSE_TAC ``m:(real->bool)->(real->bool)``) ASSUME_TAC) THEN
8067   FIRST_X_ASSUM(MP_TAC o SPEC
8068   ``IMAGE (m:(real->bool)->(real->bool)) f``) THEN
8069   ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN
8070   KNOW_TAC ``(s :real -> bool) SUBSET
8071     BIGUNION
8072       (IMAGE (m :(real -> bool) -> real -> bool)
8073          (f :(real -> bool) -> bool))`` THENL
8074   [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
8075  DISCH_THEN(X_CHOOSE_THEN ``f':(real->bool)->bool`` STRIP_ASSUME_TAC) THEN
8076  EXISTS_TAC ``IMAGE (\t:real->bool. s INTER t) f'`` THEN
8077  ASM_SIMP_TAC std_ss [IMAGE_FINITE, BIGUNION_IMAGE, SUBSET_DEF, FORALL_IN_IMAGE] THEN
8078  CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
8079  UNDISCH_TAC ``f' SUBSET IMAGE (m :(real -> bool) -> real -> bool) f`` THEN
8080  DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_IMAGE]) THEN
8081  STRIP_TAC THEN ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN ASM_MESON_TAC[SUBSET_DEF],
8082  DISCH_TAC THEN
8083  FIRST_X_ASSUM(MP_TAC o SPEC ``{s INTER t:real->bool | t IN f}``) THEN
8084  SIMP_TAC std_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, OPEN_IN_OPEN, BIGUNION_IMAGE] THEN
8085  KNOW_TAC ``(!(t :real -> bool).
8086        t IN (f :(real -> bool) -> bool) ==>
8087        ?(t' :real -> bool).
8088          (open t' :bool) /\ ((s :real -> bool) INTER t = s INTER t')) /\
8089     s SUBSET {y | ?(t :real -> bool). t IN f /\ y IN s INTER t}`` THENL
8090  [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
8091  ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN
8092  SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE, BIGUNION_IMAGE] THEN
8093  STRIP_TAC THEN EXISTS_TAC ``f' :(real -> bool) -> bool`` THEN
8094  ASM_SET_TAC []]);
8095
8096(* ------------------------------------------------------------------------- *)
8097(* More easy lemmas.                                                         *)
8098(* ------------------------------------------------------------------------- *)
8099
8100val COMPACT_CLOSURE = store_thm ("COMPACT_CLOSURE",
8101 ``!s. compact(closure s) <=> bounded s``,
8102  REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_CLOSURE, BOUNDED_CLOSURE_EQ]);
8103
8104val BOLZANO_WEIERSTRASS_CONTRAPOS = store_thm ("BOLZANO_WEIERSTRASS_CONTRAPOS",
8105 ``!s t:real->bool.
8106  compact s /\ t SUBSET s /\
8107  (!x. x IN s ==> ~(x limit_point_of t))
8108  ==> FINITE t``,
8109  REWRITE_TAC[COMPACT_EQ_BOLZANO_WEIERSTRASS] THEN MESON_TAC[]);
8110
8111val DISCRETE_BOUNDED_IMP_FINITE = store_thm ("DISCRETE_BOUNDED_IMP_FINITE",
8112 ``!s:real->bool e. &0 < e /\
8113  (!x y. x IN s /\ y IN s /\ abs(y - x) < e ==> (y = x)) /\
8114   bounded s ==> FINITE s``,
8115  REPEAT STRIP_TAC THEN
8116  SUBGOAL_THEN ``compact(s:real->bool)`` MP_TAC THENL
8117  [ASM_REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
8118   ASM_MESON_TAC[DISCRETE_IMP_CLOSED],
8119  DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_HEINE_BOREL)] THEN
8120  DISCH_THEN(MP_TAC o SPEC ``IMAGE (\x:real. ball(x,e)) s``) THEN
8121  SIMP_TAC std_ss [FORALL_IN_IMAGE, OPEN_BALL, BIGUNION_IMAGE, GSPECIFICATION] THEN
8122  KNOW_TAC ``(s :real -> bool) SUBSET
8123     {y | ?(x :real). x IN s /\ y IN ball (x,(e :real))}`` THENL
8124  [SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN ASM_MESON_TAC[CENTRE_IN_BALL],
8125   DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
8126   ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`]] THEN
8127  SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE] THEN
8128  DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN
8129  SUBGOAL_THEN ``s:real->bool = t`` (fn th => ASM_REWRITE_TAC[th]) THEN
8130  MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN
8131  REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
8132  UNDISCH_TAC ``s SUBSET BIGUNION (IMAGE (\x. ball (x,e)) t)`` THEN
8133  GEN_REWR_TAC (LAND_CONV o RAND_CONV) [BIGUNION_IMAGE] THEN
8134  DISCH_THEN(MP_TAC o SPEC ``x:real`` o REWRITE_RULE [SUBSET_DEF]) THEN
8135  ASM_SIMP_TAC std_ss [GSPECIFICATION, IN_BALL, dist] THEN ASM_MESON_TAC[SUBSET_DEF]);
8136
8137val BOLZANO_WEIERSTRASS = store_thm ("BOLZANO_WEIERSTRASS",
8138 ``!s:real->bool. bounded s /\ INFINITE s ==> ?x. x limit_point_of s``,
8139  GEN_TAC THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN
8140  FIRST_ASSUM(ASSUME_TAC o MATCH_MP NO_LIMIT_POINT_IMP_CLOSED) THEN
8141  STRIP_TAC THEN
8142  MP_TAC(ISPEC ``s:real->bool`` COMPACT_EQ_BOLZANO_WEIERSTRASS) THEN
8143  ASM_SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED] THEN
8144  EXISTS_TAC ``s:real->bool`` THEN
8145  ASM_REWRITE_TAC[SUBSET_REFL] THEN ASM_MESON_TAC[]);
8146
8147val BOUNDED_EQ_BOLZANO_WEIERSTRASS = store_thm ("BOUNDED_EQ_BOLZANO_WEIERSTRASS",
8148 ``!s:real->bool.
8149  bounded s <=> !t. t SUBSET s /\ INFINITE t ==> ?x. x limit_point_of t``,
8150  MESON_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED, BOLZANO_WEIERSTRASS,
8151   BOUNDED_SUBSET]);
8152
8153(* ------------------------------------------------------------------------- *)
8154(* In particular, some common special cases.                                 *)
8155(* ------------------------------------------------------------------------- *)
8156
8157val COMPACT_EMPTY = store_thm ("COMPACT_EMPTY",
8158 ``compact {}``,
8159  REWRITE_TAC[compact, NOT_IN_EMPTY]);
8160
8161val COMPACT_UNION = store_thm ("COMPACT_UNION",
8162 ``!s t. compact s /\ compact t ==> compact (s UNION t)``,
8163  SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_UNION, CLOSED_UNION]);
8164
8165val COMPACT_INTER = store_thm ("COMPACT_INTER",
8166 ``!s t. compact s /\ compact t ==> compact (s INTER t)``,
8167  SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_INTER, CLOSED_INTER]);
8168
8169val COMPACT_INTER_CLOSED = store_thm ("COMPACT_INTER_CLOSED",
8170 ``!s t. compact s /\ closed t ==> compact (s INTER t)``,
8171  SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_INTER] THEN
8172  MESON_TAC[BOUNDED_SUBSET, INTER_SUBSET]);
8173
8174val CLOSED_INTER_COMPACT = store_thm ("CLOSED_INTER_COMPACT",
8175 ``!s t. closed s /\ compact t ==> compact (s INTER t)``,
8176  MESON_TAC[COMPACT_INTER_CLOSED, INTER_COMM]);
8177
8178val COMPACT_BIGINTER = store_thm ("COMPACT_BIGINTER",
8179 ``!f:(real->bool)->bool.
8180  (!s. s IN f ==> compact s) /\ ~(f = {})
8181  ==> compact(BIGINTER f)``,
8182  SIMP_TAC std_ss[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_BIGINTER] THEN
8183  REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_BIGINTER THEN ASM_SET_TAC[]);
8184
8185val FINITE_IMP_CLOSED = store_thm ("FINITE_IMP_CLOSED",
8186 ``!s. FINITE s ==> closed s``,
8187  MESON_TAC[BOLZANO_WEIERSTRASS_IMP_CLOSED, SUBSET_FINITE_I]);
8188
8189val FINITE_IMP_CLOSED_IN = store_thm ("FINITE_IMP_CLOSED_IN",
8190 ``!s t. FINITE s /\ s SUBSET t ==> closed_in (subtopology euclidean t) s``,
8191  SIMP_TAC std_ss [CLOSED_SUBSET_EQ, FINITE_IMP_CLOSED]);
8192
8193val FINITE_IMP_COMPACT = store_thm ("FINITE_IMP_COMPACT",
8194 ``!s. FINITE s ==> compact s``,
8195  SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, FINITE_IMP_CLOSED, FINITE_IMP_BOUNDED]);
8196
8197val COMPACT_SING = store_thm ("COMPACT_SING",
8198 ``!a. compact {a}``,
8199  SIMP_TAC std_ss [FINITE_IMP_COMPACT, FINITE_EMPTY, FINITE_INSERT]);
8200
8201val COMPACT_INSERT = store_thm ("COMPACT_INSERT",
8202 ``!a s. compact s ==> compact(a INSERT s)``,
8203  ONCE_REWRITE_TAC[SET_RULE ``a INSERT s = {a} UNION s``] THEN
8204  SIMP_TAC std_ss [COMPACT_UNION, COMPACT_SING]);
8205
8206val CLOSED_SING = store_thm ("CLOSED_SING",
8207 ``!a. closed {a}``,
8208 MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, COMPACT_SING]);
8209
8210val CLOSED_IN_SING = store_thm ("CLOSED_IN_SING",
8211 ``!u x:real. closed_in (subtopology euclidean u) {x} <=> x IN u``,
8212  SIMP_TAC std_ss [CLOSED_SUBSET_EQ, CLOSED_SING] THEN SET_TAC[]);
8213
8214val CLOSURE_SING = store_thm ("CLOSURE_SING",
8215 ``!x:real. closure {x} = {x}``,
8216   SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_SING]);
8217
8218val CLOSED_INSERT = store_thm ("CLOSED_INSERT",
8219 ``!a s. closed s ==> closed(a INSERT s)``,
8220  ONCE_REWRITE_TAC[SET_RULE ``a INSERT s = {a} UNION s``] THEN
8221  SIMP_TAC std_ss [CLOSED_UNION, CLOSED_SING]);
8222
8223val COMPACT_CBALL = store_thm ("COMPACT_CBALL",
8224 ``!x e. compact(cball(x,e))``,
8225  REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_CBALL, CLOSED_CBALL]);
8226
8227val COMPACT_FRONTIER_BOUNDED = store_thm ("COMPACT_FRONTIER_BOUNDED",
8228 ``!s. bounded s ==> compact(frontier s)``,
8229  SIMP_TAC std_ss [frontier, COMPACT_EQ_BOUNDED_CLOSED,
8230   CLOSED_DIFF, OPEN_INTERIOR, CLOSED_CLOSURE] THEN
8231  MESON_TAC[DIFF_SUBSET, BOUNDED_SUBSET, BOUNDED_CLOSURE]);
8232
8233val COMPACT_FRONTIER = store_thm ("COMPACT_FRONTIER",
8234 ``!s. compact s ==> compact (frontier s)``,
8235  MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, COMPACT_FRONTIER_BOUNDED]);
8236
8237val BOUNDED_FRONTIER = store_thm ("BOUNDED_FRONTIER",
8238 ``!s:real->bool. bounded s ==> bounded(frontier s)``,
8239  MESON_TAC[COMPACT_FRONTIER_BOUNDED, COMPACT_IMP_BOUNDED]);
8240
8241val FRONTIER_SUBSET_COMPACT = store_thm ("FRONTIER_SUBSET_COMPACT",
8242 ``!s. compact s ==> frontier s SUBSET s``,
8243  MESON_TAC[FRONTIER_SUBSET_CLOSED, COMPACT_EQ_BOUNDED_CLOSED]);
8244
8245val OPEN_DELETE = store_thm ("OPEN_DELETE",
8246 ``!s x. open s ==> open(s DELETE x)``,
8247SIMP_TAC std_ss [SET_RULE ``s DELETE x = s DIFF {x}``,
8248                 OPEN_DIFF, CLOSED_SING]);
8249
8250val OPEN_IN_DELETE = store_thm ("OPEN_IN_DELETE",
8251 ``!u s a:real.
8252  open_in (subtopology euclidean u) s
8253  ==> open_in (subtopology euclidean u) (s DELETE a)``,
8254  REPEAT STRIP_TAC THEN ASM_CASES_TAC ``(a:real) IN s`` THENL
8255  [ONCE_REWRITE_TAC[SET_RULE ``s DELETE a = s DIFF {a}``] THEN
8256   MATCH_MP_TAC OPEN_IN_DIFF THEN ASM_REWRITE_TAC[CLOSED_IN_SING] THEN
8257   FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN ASM_SET_TAC[],
8258   ASM_SIMP_TAC std_ss [SET_RULE ``~(a IN s) ==> (s DELETE a = s)``]]);
8259
8260val CLOSED_BIGINTER_COMPACT = store_thm ("CLOSED_BIGINTER_COMPACT",
8261 ``!s:real->bool.
8262  closed s <=> !e. compact(cball(0,e) INTER s)``,
8263  GEN_TAC THEN EQ_TAC THENL
8264  [SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_INTER, CLOSED_CBALL,
8265   BOUNDED_INTER, BOUNDED_CBALL], ALL_TAC] THEN
8266  STRIP_TAC THEN REWRITE_TAC[CLOSED_LIMPT] THEN
8267  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
8268  FIRST_X_ASSUM(MP_TAC o SPEC ``abs(x:real) + &1:real``) THEN
8269  DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_CLOSED) THEN
8270  REWRITE_TAC[CLOSED_LIMPT] THEN DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN
8271  REWRITE_TAC[IN_INTER] THEN
8272  KNOW_TAC ``(x :real) limit_point_of
8273     cball ((0 :real),abs x + (1 :real)) INTER (s :real -> bool)`` THENL
8274  [ALL_TAC, MESON_TAC[]] THEN
8275  POP_ASSUM MP_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
8276  DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
8277  FIRST_X_ASSUM(MP_TAC o SPEC ``min e (&1 / &2:real)``) THEN
8278  KNOW_TAC ``0 < min e (1 / 2:real)`` THENL
8279  [REWRITE_TAC [min_def] THEN COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [REAL_HALF_BETWEEN],
8280   DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
8281  DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN
8282  POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [IN_INTER, IN_CBALL] THEN
8283  REWRITE_TAC [REAL_LT_MIN, DIST_0, dist] THEN STRIP_TAC THEN
8284  FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
8285  ASM_REAL_ARITH_TAC);
8286
8287val COMPACT_BIGUNION = store_thm ("COMPACT_BIGUNION",
8288 ``!s. FINITE s /\ (!t. t IN s ==> compact t) ==> compact(BIGUNION s)``,
8289  SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_BIGUNION, BOUNDED_BIGUNION]);
8290
8291val COMPACT_DIFF = store_thm ("COMPACT_DIFF",
8292 ``!s t. compact s /\ open t ==> compact(s DIFF t)``,
8293  ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s INTER (UNIV DIFF t)``] THEN
8294  SIMP_TAC std_ss [COMPACT_INTER_CLOSED, GSYM OPEN_CLOSED]);
8295
8296val COMPACT_SPHERE = store_thm ("COMPACT_SPHERE",
8297 ``!a:real r. compact(sphere(a,r))``,
8298  REPEAT GEN_TAC THEN
8299 REWRITE_TAC[GSYM FRONTIER_CBALL] THEN MATCH_MP_TAC COMPACT_FRONTIER THEN
8300  REWRITE_TAC[COMPACT_CBALL]);
8301
8302val BOUNDED_SPHERE = store_thm ("BOUNDED_SPHERE",
8303 ``!a:real r. bounded(sphere(a,r))``,
8304  SIMP_TAC std_ss [COMPACT_SPHERE, COMPACT_IMP_BOUNDED]);
8305
8306val CLOSED_SPHERE = store_thm ("CLOSED_SPHERE",
8307 ``!a r. closed(sphere(a,r))``,
8308  SIMP_TAC std_ss [COMPACT_SPHERE, COMPACT_IMP_CLOSED]);
8309
8310val FRONTIER_SING = store_thm ("FRONTIER_SING",
8311 ``!a:real. frontier {a} = {a}``,
8312  REWRITE_TAC[frontier, CLOSURE_SING, INTERIOR_SING, DIFF_EMPTY]);
8313
8314(* ------------------------------------------------------------------------- *)
8315(* Finite intersection property. I could make it an equivalence in fact.     *)
8316(* ------------------------------------------------------------------------- *)
8317
8318val lemma = prove (
8319 ``(s = UNIV DIFF t) <=> (UNIV DIFF s = t)``,
8320  SET_TAC[]);
8321
8322val COMPACT_IMP_FIP = store_thm ("COMPACT_IMP_FIP",
8323 ``!s:real->bool f.
8324        compact s /\
8325        (!t. t IN f ==> closed t) /\
8326        (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (BIGINTER f') = {}))
8327        ==> ~(s INTER (BIGINTER f) = {})``,
8328  REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
8329  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [COMPACT_EQ_HEINE_BOREL]) THEN
8330  DISCH_THEN(MP_TAC o SPEC ``IMAGE (\t:real->bool. UNIV DIFF t) f``) THEN
8331  ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN
8332  DISCH_THEN(fn th => REPEAT STRIP_TAC THEN MP_TAC th) THEN
8333  ASM_SIMP_TAC std_ss [OPEN_DIFF, CLOSED_DIFF, OPEN_UNIV, CLOSED_UNIV, NOT_IMP] THEN
8334  CONJ_TAC THENL
8335   [UNDISCH_TAC ``(s:real->bool) INTER BIGINTER f = {}`` THEN
8336    ONCE_REWRITE_TAC[SUBSET_DEF, EXTENSION] THEN
8337    REWRITE_TAC [IN_BIGUNION] THEN ONCE_REWRITE_TAC [CONJ_SYM] THEN
8338        REWRITE_TAC [EXISTS_IN_IMAGE] THEN BETA_TAC THEN SET_TAC[],
8339    X_GEN_TAC ``g:(real->bool)->bool`` THEN
8340    FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (\t:real->bool. UNIV DIFF t) g``) THEN
8341    ASM_CASES_TAC ``FINITE(g:(real->bool)->bool)`` THEN
8342    ASM_SIMP_TAC std_ss [IMAGE_FINITE] THEN ONCE_REWRITE_TAC[SUBSET_DEF, EXTENSION] THEN
8343    SIMP_TAC std_ss [FORALL_IN_IMAGE, IN_INTER, IN_BIGINTER, IN_IMAGE, IN_DIFF,
8344                IN_UNIV, NOT_IN_EMPTY, lemma, UNWIND_THM1, IN_BIGUNION] THEN
8345    SET_TAC[]]);
8346
8347val CLOSED_IMP_FIP = store_thm ("CLOSED_IMP_FIP",
8348 ``!s:real->bool f.
8349        closed s /\
8350        (!t. t IN f ==> closed t) /\ (?t. t IN f /\ bounded t) /\
8351        (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (BIGINTER f') = {}))
8352        ==> ~(s INTER (BIGINTER f) = {})``,
8353  REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC(SET_RULE
8354   ``~((s INTER t) INTER u = {}) ==> ~(s INTER u = {})``) THEN
8355  MATCH_MP_TAC COMPACT_IMP_FIP THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
8356   [ASM_MESON_TAC[CLOSED_INTER_COMPACT, COMPACT_EQ_BOUNDED_CLOSED],
8357    REWRITE_TAC [METIS [INTER_ASSOC, GSYM BIGINTER_INSERT]
8358          ``!f.  s INTER t INTER BIGINTER f =  s INTER BIGINTER (t INSERT f)``] THEN
8359  GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
8360  ASM_SIMP_TAC std_ss [FINITE_INSERT, INSERT_SUBSET]]);
8361
8362val CLOSED_IMP_FIP_COMPACT = store_thm ("CLOSED_IMP_FIP_COMPACT",
8363 ``!s:real->bool f.
8364        closed s /\ (!t. t IN f ==> compact t) /\
8365        (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (BIGINTER f') = {}))
8366        ==> ~(s INTER (BIGINTER f) = {})``,
8367  REPEAT GEN_TAC THEN
8368  ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THEN
8369  ASM_SIMP_TAC std_ss [SUBSET_EMPTY, BIGINTER_EMPTY, INTER_UNIV] THENL
8370   [MESON_TAC[FINITE_EMPTY], ALL_TAC] THEN
8371  STRIP_TAC THEN MATCH_MP_TAC CLOSED_IMP_FIP THEN
8372  ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, MEMBER_NOT_EMPTY]);
8373
8374val CLOSED_FIP = store_thm ("CLOSED_FIP",
8375 ``!f. (!t:real->bool. t IN f ==> closed t) /\ (?t. t IN f /\ bounded t) /\
8376       (!f'. FINITE f' /\ f' SUBSET f ==> ~(BIGINTER f' = {}))
8377       ==> ~(BIGINTER f = {})``,
8378  GEN_TAC THEN DISCH_TAC THEN
8379  ONCE_REWRITE_TAC[SET_RULE ``(s = {}) <=> (UNIV INTER s = {})``] THEN
8380  MATCH_MP_TAC CLOSED_IMP_FIP THEN ASM_REWRITE_TAC[CLOSED_UNIV, INTER_UNIV]);
8381
8382val COMPACT_FIP = store_thm ("COMPACT_FIP",
8383 ``!f. (!t:real->bool. t IN f ==> compact t) /\
8384       (!f'. FINITE f' /\ f' SUBSET f ==> ~(BIGINTER f' = {}))
8385       ==> ~(BIGINTER f = {})``,
8386  GEN_TAC THEN DISCH_TAC THEN
8387  ONCE_REWRITE_TAC[SET_RULE ``(s = {}) <=> (UNIV INTER s = {})``] THEN
8388  MATCH_MP_TAC CLOSED_IMP_FIP_COMPACT THEN
8389  ASM_REWRITE_TAC[CLOSED_UNIV, INTER_UNIV]);
8390
8391(* ------------------------------------------------------------------------- *)
8392(* Bounded closed nest property (proof does not use Heine-Borel).            *)
8393(* ------------------------------------------------------------------------- *)
8394
8395val BOUNDED_CLOSED_NEST = store_thm ("BOUNDED_CLOSED_NEST",
8396 ``!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\
8397       (!m n. m <= n ==> s(n) SUBSET s(m)) /\
8398       bounded(s 0)
8399       ==> ?a:real. !n:num. a IN s(n)``,
8400  GEN_TAC THEN SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, SKOLEM_THM] THEN
8401  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
8402  DISCH_THEN(CONJUNCTS_THEN2
8403     (X_CHOOSE_TAC ``a:num->real``) STRIP_ASSUME_TAC) THEN
8404  SUBGOAL_THEN ``compact(s (0:num):real->bool)`` MP_TAC THENL
8405   [METIS_TAC[BOUNDED_CLOSED_IMP_COMPACT], ALL_TAC] THEN
8406  REWRITE_TAC[compact] THEN
8407  DISCH_THEN(MP_TAC o SPEC ``a:num->real``) THEN
8408  KNOW_TAC ``(!n:num. a n IN s (0:num):real->bool)`` THENL
8409  [ASM_MESON_TAC[SUBSET_DEF, ZERO_LESS_EQ],
8410   DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
8411  DISCH_THEN (X_CHOOSE_TAC ``l:real``) THEN
8412  EXISTS_TAC ``l:real`` THEN POP_ASSUM MP_TAC THEN
8413  SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN
8414  DISCH_THEN(X_CHOOSE_THEN ``r:num->num`` STRIP_ASSUME_TAC) THEN
8415  GEN_REWR_TAC I [TAUT `p <=> ~(~p)`] THEN
8416  REWRITE_TAC [NOT_FORALL_THM] THEN X_GEN_TAC ``N:num`` THEN
8417  MP_TAC(ISPECL [``l:real``, ``(s:num->real->bool) N``]
8418                CLOSED_APPROACHABLE) THEN
8419  ASM_MESON_TAC[SUBSET_DEF, LESS_EQ_REFL, LESS_EQ_TRANS, LE_CASES, MONOTONE_BIGGER]);
8420
8421(* ------------------------------------------------------------------------- *)
8422(* Decreasing case does not even need compactness, just completeness.        *)
8423(* ------------------------------------------------------------------------- *)
8424
8425val DECREASING_CLOSED_NEST = store_thm ("DECREASING_CLOSED_NEST",
8426 ``!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\
8427       (!m n. m <= n ==> s(n) SUBSET s(m)) /\
8428       (!e. &0 < e ==> ?n. !x y. x IN s(n) /\ y IN s(n) ==> dist(x,y) < e)
8429       ==> ?a:real. !n:num. a IN s(n)``,
8430  GEN_TAC THEN SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, SKOLEM_THM] THEN
8431  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
8432  DISCH_THEN(CONJUNCTS_THEN2
8433     (X_CHOOSE_TAC ``a:num->real``) STRIP_ASSUME_TAC) THEN
8434  SUBGOAL_THEN ``?l:real. (a --> l) sequentially`` MP_TAC THENL
8435   [ASM_MESON_TAC[cauchy, GE, SUBSET_DEF, LESS_EQ_TRANS, LESS_EQ_REFL,
8436                  complete, COMPLETE_UNIV, IN_UNIV],
8437    ASM_MESON_TAC[LIM_SEQUENTIALLY, CLOSED_APPROACHABLE,
8438                  SUBSET_DEF, LESS_EQ_REFL, LESS_EQ_TRANS, LE_CASES]]);
8439
8440(* ------------------------------------------------------------------------- *)
8441(* Strengthen it to the intersection actually being a singleton.             *)
8442(* ------------------------------------------------------------------------- *)
8443
8444val DECREASING_CLOSED_NEST_SING = store_thm ("DECREASING_CLOSED_NEST_SING",
8445 ``!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\
8446       (!m n. m <= n ==> s(n) SUBSET s(m)) /\
8447       (!e. &0 < e ==> ?n. !x y. x IN s(n) /\ y IN s(n) ==> dist(x,y) < e)
8448       ==> ?a:real. BIGINTER {t | ?n:num. t = s n} = {a}``,
8449  GEN_TAC THEN DISCH_TAC THEN
8450  FIRST_ASSUM(MP_TAC o MATCH_MP DECREASING_CLOSED_NEST) THEN
8451  STRIP_TAC THEN EXISTS_TAC ``a:real`` THEN
8452  SIMP_TAC std_ss [EXTENSION, IN_BIGINTER, IN_SING, GSPECIFICATION] THEN
8453  METIS_TAC[DIST_POS_LT, REAL_LT_REFL, SUBSET_DEF, LE_CASES]);
8454
8455(* ------------------------------------------------------------------------- *)
8456(* A version for a more general chain, not indexed by N.                     *)
8457(* ------------------------------------------------------------------------- *)
8458
8459val BOUNDED_CLOSED_CHAIN = store_thm ("BOUNDED_CLOSED_CHAIN",
8460 ``!f b:real->bool.
8461        (!s. s IN f ==> closed s /\ ~(s = {})) /\
8462        (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) /\
8463         b IN f /\ bounded b
8464         ==> ~(BIGINTER f = {})``,
8465  REPEAT GEN_TAC THEN STRIP_TAC THEN
8466  SUBGOAL_THEN ``~(b INTER (BIGINTER f):real->bool = {})`` MP_TAC THENL
8467   [ALL_TAC, SET_TAC[]] THEN
8468  MATCH_MP_TAC COMPACT_IMP_FIP THEN
8469  ASM_SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED] THEN
8470  X_GEN_TAC ``u:(real->bool)->bool`` THEN STRIP_TAC THEN
8471  SUBGOAL_THEN ``?s:real->bool. s IN f /\ !t. t IN u ==> s SUBSET t``
8472   MP_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
8473  UNDISCH_TAC ``(u:(real->bool)->bool) SUBSET f`` THEN
8474  UNDISCH_TAC ``FINITE(u:(real->bool)->bool)`` THEN
8475  SPEC_TAC(``u:(real->bool)->bool``,``u:(real->bool)->bool``) THEN
8476  ONCE_REWRITE_TAC [METIS [] ``!u. (u SUBSET f ==> ?s. s IN f /\ !t. t IN u ==> s SUBSET t) =
8477                          (\u. u SUBSET f ==> ?s. s IN f /\ !t. t IN u ==> s SUBSET t) u``] THEN
8478  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
8479  CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
8480  SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN
8481  MAP_EVERY X_GEN_TAC [``u:(real->bool)->bool``, ``t:real->bool``] THEN
8482  REWRITE_TAC[INSERT_SUBSET] THEN
8483  ONCE_REWRITE_TAC [AND_IMP_INTRO] THEN
8484  DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN
8485  ASM_REWRITE_TAC[] THEN
8486  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
8487  DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
8488  DISCH_THEN(X_CHOOSE_THEN ``s:real->bool`` STRIP_ASSUME_TAC) THEN
8489  FIRST_X_ASSUM(MP_TAC o SPECL [``s:real->bool``, ``t:real->bool``]) THEN
8490  ASM_SET_TAC[]);
8491
8492(* ------------------------------------------------------------------------- *)
8493(* Analogous things directly for compactness.                                *)
8494(* ------------------------------------------------------------------------- *)
8495
8496val COMPACT_CHAIN = store_thm ("COMPACT_CHAIN",
8497 ``!f:(real->bool)->bool.
8498        (!s. s IN f ==> compact s /\ ~(s = {})) /\
8499        (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s)
8500        ==> ~(BIGINTER f = {})``,
8501  GEN_TAC THEN REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN STRIP_TAC THEN
8502  ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THENL
8503   [ASM_REWRITE_TAC[BIGINTER_EMPTY] THEN SET_TAC[],
8504    MATCH_MP_TAC BOUNDED_CLOSED_CHAIN THEN ASM_SET_TAC[]]);
8505
8506val COMPACT_NEST = store_thm ("COMPACT_NEST",
8507 ``!s. (!n. compact(s n) /\ ~(s n = {})) /\
8508       (!m n. m <= n ==> s n SUBSET s m)
8509       ==> ~(BIGINTER {s n | n IN univ(:num)} = {})``,
8510  GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC COMPACT_CHAIN THEN
8511  ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN
8512  ONCE_REWRITE_TAC [METIS [] ``!n n'. (s n SUBSET s n' \/ s n' SUBSET s n) =
8513                          (\n n'. s n SUBSET s n' \/ s n' SUBSET s n) n n'``] THEN
8514  MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]);
8515
8516(* ------------------------------------------------------------------------- *)
8517(* Cauchy-type criteria for *uniform* convergence.                           *)
8518(* ------------------------------------------------------------------------- *)
8519
8520val UNIFORMLY_CONVERGENT_EQ_CAUCHY = store_thm ("UNIFORMLY_CONVERGENT_EQ_CAUCHY",
8521 ``!P s:num->'a->real.
8522         (?l. !e. &0 < e
8523                  ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e) <=>
8524         (!e. &0 < e
8525              ==> ?N. !m n x. N <= m /\ N <= n /\ P x
8526                              ==> dist(s m x,s n x) < e)``,
8527  REPEAT GEN_TAC THEN EQ_TAC THENL
8528   [DISCH_THEN(X_CHOOSE_TAC ``l:'a->real``) THEN X_GEN_TAC ``e:real`` THEN
8529    DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN
8530    ASM_REWRITE_TAC[REAL_HALF] THEN MESON_TAC[DIST_TRIANGLE_HALF_L],
8531    ALL_TAC] THEN
8532  DISCH_TAC THEN
8533  SUBGOAL_THEN ``!x:'a. P x ==> cauchy (\n. s n x :real)`` MP_TAC THENL
8534   [REWRITE_TAC[cauchy, GE] THEN ASM_MESON_TAC[], ALL_TAC] THEN
8535  REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY, LIM_SEQUENTIALLY] THEN
8536  DISCH_TAC THEN KNOW_TAC ``(!(x :'a). ?(l :real). (P :'a -> bool) x ==>
8537        (!(e :real). (0 :real) < e ==>
8538           (?(N :num). !(n :num). N <= n ==>
8539               (dist ((\(n :num). (s :num -> 'a -> real) n x) n,l) :real) < e)))`` THENL
8540  [METIS_TAC [], POP_ASSUM K_TAC] THEN SIMP_TAC std_ss [SKOLEM_THM] THEN
8541  DISCH_THEN (X_CHOOSE_TAC ``l:'a->real``) THEN
8542  EXISTS_TAC ``l:'a->real`` THEN POP_ASSUM MP_TAC THEN
8543  DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN
8544  DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN
8545  ASM_REWRITE_TAC[REAL_HALF] THEN
8546  DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN
8547  POP_ASSUM MP_TAC THEN STRIP_TAC THEN
8548  MAP_EVERY X_GEN_TAC [``n:num``, ``x:'a``] THEN STRIP_TAC THEN
8549  FIRST_X_ASSUM(MP_TAC o SPEC ``x:'a``) THEN ASM_REWRITE_TAC[] THEN
8550  DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
8551  DISCH_THEN(X_CHOOSE_TAC ``M:num``) THEN
8552  UNDISCH_TAC ``!m n x. N:num <= m /\ N <= n /\ P x
8553                 ==> dist (s m x,s n x) < e / 2:real`` THEN DISCH_TAC THEN
8554  POP_ASSUM (MP_TAC o Q.SPECL [`n:num`, `N + M:num`, `x:'a`]) THEN
8555  ASM_REWRITE_TAC[LE_ADD] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN
8556  FIRST_X_ASSUM(MP_TAC o SPEC ``M + N:num``) THEN REWRITE_TAC[LE_ADD] THEN
8557  ASM_MESON_TAC[DIST_TRIANGLE_HALF_L, DIST_SYM]);
8558
8559Theorem UNIFORMLY_CONVERGENT_EQ_CAUCHY_ALT:
8560   !P s:num->'a->real.
8561      (?l. !e. &0 < e ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e) <=>
8562      (!e. &0 < e ==>
8563           ?N. !m n x. N <= m /\ N <= n /\ m < n /\ P x ==>
8564                       dist(s m x,s n x) < e)
8565Proof
8566  REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONVERGENT_EQ_CAUCHY] THEN
8567  EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
8568  FIRST_X_ASSUM(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN
8569  DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN
8570  ASM_SIMP_TAC std_ss [] THEN
8571  HO_MATCH_MP_TAC WLOG_LT THEN
8572  ASM_SIMP_TAC std_ss [DIST_REFL] THEN MESON_TAC[DIST_SYM]
8573QED
8574
8575val UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT = store_thm ("UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT",
8576 ``!P (s:num->'a->real) l.
8577    (!e. &0 < e
8578         ==> ?N. !m n x. N <= m /\ N <= n /\ P x ==> dist(s m x,s n x) < e) /\
8579    (!x. P x ==> !e. &0 < e ==> ?N. !n. N <= n ==> dist(s n x,l x) < e)
8580    ==> (!e. &0 < e ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e)``,
8581  REPEAT GEN_TAC THEN REWRITE_TAC[GSYM UNIFORMLY_CONVERGENT_EQ_CAUCHY] THEN
8582  DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC ``l':'a->real``) ASSUME_TAC) THEN
8583  SUBGOAL_THEN ``!x. P x ==> ((l:'a->real) x = l' x)`` MP_TAC THENL
8584   [ALL_TAC, METIS_TAC[]] THEN
8585  REPEAT STRIP_TAC THEN MATCH_MP_TAC(ISPEC ``sequentially`` LIM_UNIQUE) THEN
8586  EXISTS_TAC ``\n. (s:num->'a->real) n x`` THEN
8587  REWRITE_TAC[LIM_SEQUENTIALLY, TRIVIAL_LIMIT_SEQUENTIALLY] THEN
8588  ASM_MESON_TAC[]);
8589
8590(* ------------------------------------------------------------------------- *)
8591(* Define continuity over a net to take in restrictions of the set.          *)
8592(* ------------------------------------------------------------------------- *)
8593
8594val _ = set_fixity "continuous" (Infix(NONASSOC, 450));
8595
8596val continuous = new_definition ("continuous",
8597 ``f continuous net <=> (f --> f(netlimit net)) net``);
8598
8599val CONTINUOUS_TRIVIAL_LIMIT = store_thm ("CONTINUOUS_TRIVIAL_LIMIT",
8600 ``!f net. trivial_limit net ==> f continuous net``,
8601  SIMP_TAC std_ss [continuous, LIM]);
8602
8603val CONTINUOUS_WITHIN = store_thm ("CONTINUOUS_WITHIN",
8604 ``!f x:real. f continuous (at x within s) <=> (f --> f(x)) (at x within s)``,
8605  REPEAT GEN_TAC THEN REWRITE_TAC[continuous] THEN
8606  ASM_CASES_TAC ``trivial_limit(at (x:real) within s)`` THENL
8607  [ASM_REWRITE_TAC[LIM], ASM_SIMP_TAC std_ss [NETLIMIT_WITHIN]]);
8608
8609val CONTINUOUS_AT = store_thm ("CONTINUOUS_AT",
8610 ``!f (x:real). f continuous (at x) <=> (f --> f(x)) (at x)``,
8611  ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
8612  REWRITE_TAC[CONTINUOUS_WITHIN, IN_UNIV]);
8613
8614val CONTINUOUS_AT_WITHIN = store_thm ("CONTINUOUS_AT_WITHIN",
8615 ``!f:real->real x s.
8616  f continuous (at x) ==> f continuous (at x within s)``,
8617  SIMP_TAC std_ss [LIM_AT_WITHIN, CONTINUOUS_AT, CONTINUOUS_WITHIN]);
8618
8619val CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL = store_thm ("CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL",
8620 ``!a s. closed s /\ ~(a IN s) ==> f continuous (at a within s)``,
8621  ASM_SIMP_TAC std_ss [continuous, LIM, LIM_WITHIN_CLOSED_TRIVIAL]);
8622
8623val CONTINUOUS_TRANSFORM_WITHIN = store_thm ("CONTINUOUS_TRANSFORM_WITHIN",
8624 ``!f g:real->real s x d. &0 < d /\ x IN s /\
8625   (!x'. x' IN s /\ dist(x',x) < d ==> (f(x') = g(x'))) /\
8626    f continuous (at x within s) ==> g continuous (at x within s)``,
8627  SIMP_TAC std_ss [CONTINUOUS_WITHIN] THEN
8628  METIS_TAC[LIM_TRANSFORM_WITHIN, DIST_REFL]);
8629
8630val CONTINUOUS_TRANSFORM_AT = store_thm ("CONTINUOUS_TRANSFORM_AT",
8631 ``!f g:real->real x d.
8632   &0 < d /\ (!x'. dist(x',x) < d ==> (f(x') = g(x'))) /\
8633   f continuous (at x) ==> g continuous (at x)``,
8634  REWRITE_TAC[CONTINUOUS_AT] THEN
8635  METIS_TAC[LIM_TRANSFORM_AT, DIST_REFL]);
8636
8637val CONTINUOUS_TRANSFORM_WITHIN_OPEN = store_thm ("CONTINUOUS_TRANSFORM_WITHIN_OPEN",
8638 ``!f g:real->real s a. open s /\ a IN s /\
8639   (!x. x IN s ==> (f x = g x)) /\
8640    f continuous at a ==> g continuous at a``,
8641  METIS_TAC[CONTINUOUS_AT, LIM_TRANSFORM_WITHIN_OPEN]);
8642
8643val CONTINUOUS_TRANSFORM_WITHIN_OPEN_IN = store_thm ("CONTINUOUS_TRANSFORM_WITHIN_OPEN_IN",
8644 ``!f g:real->real s t a.
8645   open_in (subtopology euclidean t) s /\ a IN s /\
8646   (!x. x IN s ==> (f x = g x)) /\
8647    f continuous (at a within t) ==> g continuous (at a within t)``,
8648  METIS_TAC[CONTINUOUS_WITHIN, LIM_TRANSFORM_WITHIN_OPEN_IN]);
8649
8650val CONTINUOUS_TRANSFORM_WITHIN_SET_IMP = store_thm ("CONTINUOUS_TRANSFORM_WITHIN_SET_IMP",
8651 ``!f a s t. eventually (\x. x IN t ==> x IN s) (at a) /\
8652   f continuous (at a within s) ==> f continuous (at a within t)``,
8653  REWRITE_TAC[CONTINUOUS_WITHIN, LIM_TRANSFORM_WITHIN_SET_IMP]);
8654
8655(* ------------------------------------------------------------------------- *)
8656(* Derive the epsilon-delta forms, which we often use as "definitions" *)
8657(* ------------------------------------------------------------------------- *)
8658
8659val continuous_within = store_thm ("continuous_within",
8660 ``f continuous (at x within s) <=> !e. &0 < e
8661   ==> ?d. &0 < d /\ !x'. x' IN s /\ dist(x',x) < d
8662     ==> dist(f(x'),f(x)) < e``,
8663  SIMP_TAC std_ss [CONTINUOUS_WITHIN, LIM_WITHIN] THEN
8664  SIMP_TAC std_ss [GSYM DIST_NZ] THEN MESON_TAC[DIST_REFL]);
8665
8666val continuous_at = store_thm ("continuous_at",
8667 ``f continuous (at x) <=>
8668  !e. &0 < e ==> ?d. &0 < d /\
8669  !x'. dist(x',x) < d ==> dist(f(x'),f(x)) < e``,
8670  ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
8671  SIMP_TAC std_ss [continuous_within, IN_UNIV]);
8672
8673(* ------------------------------------------------------------------------- *)
8674(* Versions in terms of open balls.                                          *)
8675(* ------------------------------------------------------------------------- *)
8676
8677val CONTINUOUS_WITHIN_BALL = store_thm ("CONTINUOUS_WITHIN_BALL",
8678 ``!f s x. f continuous (at x within s) <=>
8679   !e. &0 < e ==> ?d. &0 < d /\
8680   IMAGE f (ball(x,d) INTER s) SUBSET ball(f x,e)``,
8681  SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE, IN_BALL, continuous_within, IN_INTER] THEN
8682  MESON_TAC[DIST_SYM]);
8683
8684val CONTINUOUS_AT_BALL = store_thm ("CONTINUOUS_AT_BALL",
8685 ``!f x. f continuous (at x) <=>
8686   !e. &0 < e ==> ?d. &0 < d /\
8687   IMAGE f (ball(x,d)) SUBSET ball(f x,e)``,
8688  SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE, IN_BALL, continuous_at] THEN
8689  MESON_TAC[DIST_SYM]);
8690
8691(* ------------------------------------------------------------------------- *)
8692(*                                                                           *)
8693(* ------------------------------------------------------------------------- *)
8694
8695val CONTINUOUS_WITHIN_COMPARISON = store_thm ("CONTINUOUS_WITHIN_COMPARISON",
8696 ``!f:real->real g:real->real s a.
8697        g continuous (at a within s) /\
8698        (!x. x IN s ==> dist(f a,f x) <= dist(g a,g x))
8699        ==> f continuous (at a within s)``,
8700  ONCE_REWRITE_TAC[DIST_SYM] THEN
8701  REWRITE_TAC[continuous_within] THEN MESON_TAC[REAL_LET_TRANS]);
8702
8703(* ------------------------------------------------------------------------- *)
8704(* For setwise continuity, just start from the epsilon-delta definitions.    *)
8705(* ------------------------------------------------------------------------- *)
8706
8707val _ = set_fixity "continuous_on" (Infix(NONASSOC, 450));
8708val _ = set_fixity "uniformly_continuous_on" (Infix(NONASSOC, 450));
8709
8710val continuous_on = new_definition ("continuous_on",
8711 ``f continuous_on s <=>
8712   !x. x IN s ==> !e. &0 < e
8713   ==> ?d. &0 < d /\ !x'. x' IN s /\ dist(x',x) < d
8714     ==> dist(f(x'),f(x)) < e``);
8715
8716val uniformly_continuous_on = new_definition ("uniformly_continuous_on",
8717 ``f uniformly_continuous_on s <=>
8718   !e. &0 < e
8719   ==> ?d. &0 < d /\ !x x'. x IN s /\ x' IN s /\ dist(x',x) < d
8720     ==> dist(f(x'),f(x)) < e``);
8721
8722(* ------------------------------------------------------------------------- *)
8723(* Some simple consequential lemmas.                                         *)
8724(* ------------------------------------------------------------------------- *)
8725
8726val UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS = store_thm ("UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS",
8727 ``!f s. f uniformly_continuous_on s ==> f continuous_on s``,
8728  REWRITE_TAC[uniformly_continuous_on, continuous_on] THEN MESON_TAC[]);
8729
8730val CONTINUOUS_AT_IMP_CONTINUOUS_ON = store_thm ("CONTINUOUS_AT_IMP_CONTINUOUS_ON",
8731 ``!f s. (!x. x IN s ==> f continuous (at x)) ==> f continuous_on s``,
8732  REWRITE_TAC[continuous_at, continuous_on] THEN MESON_TAC[]);
8733
8734val CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN = store_thm ("CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN",
8735 ``!f s. f continuous_on s <=> !x. x IN s ==> f continuous (at x within s)``,
8736 REWRITE_TAC[continuous_on, continuous_within]);
8737
8738val CONTINUOUS_ON = store_thm ("CONTINUOUS_ON",
8739 ``!f (s:real->bool).
8740  f continuous_on s <=> !x. x IN s ==> (f --> f(x)) (at x within s)``,
8741  REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_WITHIN]);
8742
8743val CONTINUOUS_ON_EQ_CONTINUOUS_AT = store_thm ("CONTINUOUS_ON_EQ_CONTINUOUS_AT",
8744 ``!f:real->real s.
8745  open s ==> (f continuous_on s <=> (!x. x IN s ==> f continuous (at x)))``,
8746  SIMP_TAC std_ss [CONTINUOUS_ON, CONTINUOUS_AT, LIM_WITHIN_OPEN]);
8747
8748val CONTINUOUS_WITHIN_SUBSET = store_thm ("CONTINUOUS_WITHIN_SUBSET",
8749 ``!f s t x. f continuous (at x within s) /\ t SUBSET s
8750  ==> f continuous (at x within t)``,
8751 REWRITE_TAC[CONTINUOUS_WITHIN] THEN MESON_TAC[LIM_WITHIN_SUBSET]);
8752
8753val CONTINUOUS_ON_SUBSET = store_thm ("CONTINUOUS_ON_SUBSET",
8754 ``!f s t. f continuous_on s /\ t SUBSET s ==> f continuous_on t``,
8755  REWRITE_TAC[CONTINUOUS_ON] THEN MESON_TAC[SUBSET_DEF, LIM_WITHIN_SUBSET]);
8756
8757val UNIFORMLY_CONTINUOUS_ON_SUBSET = store_thm ("UNIFORMLY_CONTINUOUS_ON_SUBSET",
8758 ``!f s t. f uniformly_continuous_on s /\ t SUBSET s
8759  ==> f uniformly_continuous_on t``,
8760  REWRITE_TAC[uniformly_continuous_on] THEN
8761  MESON_TAC[SUBSET_DEF, LIM_WITHIN_SUBSET]);
8762
8763val CONTINUOUS_ON_INTERIOR = store_thm ("CONTINUOUS_ON_INTERIOR",
8764 ``!f:real->real s x.
8765  f continuous_on s /\ x IN interior(s) ==> f continuous at x``,
8766  SIMP_TAC std_ss [interior, GSPECIFICATION] THEN
8767  MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT, CONTINUOUS_ON_SUBSET]);
8768
8769val CONTINUOUS_ON_EQ = store_thm ("CONTINUOUS_ON_EQ",
8770 ``!f g s. (!x. x IN s ==> (f(x) = g(x))) /\ f continuous_on s
8771  ==> g continuous_on s``,
8772  SIMP_TAC std_ss [continuous_on, CONJ_EQ_IMP]);
8773
8774val UNIFORMLY_CONTINUOUS_ON_EQ = store_thm ("UNIFORMLY_CONTINUOUS_ON_EQ",
8775 ``!f g s. (!x. x IN s ==> (f x = g x)) /\ f uniformly_continuous_on s
8776   ==> g uniformly_continuous_on s``,
8777  SIMP_TAC std_ss [uniformly_continuous_on, CONJ_EQ_IMP]);
8778
8779val CONTINUOUS_ON_SING = store_thm ("CONTINUOUS_ON_SING",
8780 ``!f:real->real a. f continuous_on {a}``,
8781  SIMP_TAC std_ss [continuous_on, IN_SING, DIST_REFL] THEN
8782  METIS_TAC[]);
8783
8784val CONTINUOUS_ON_EMPTY = store_thm ("CONTINUOUS_ON_EMPTY",
8785 ``!f:real->real. f continuous_on {}``,
8786  MESON_TAC[CONTINUOUS_ON_SING, EMPTY_SUBSET, CONTINUOUS_ON_SUBSET]);
8787
8788val CONTINUOUS_ON_NO_LIMPT = store_thm ("CONTINUOUS_ON_NO_LIMPT",
8789 ``!f:real->real s.
8790  ~(?x. x limit_point_of s) ==> f continuous_on s``,
8791  REWRITE_TAC[continuous_on, LIMPT_APPROACHABLE] THEN MESON_TAC[DIST_REFL]);
8792
8793val CONTINUOUS_ON_FINITE = store_thm ("CONTINUOUS_ON_FINITE",
8794 ``!f:real->real s. FINITE s ==> f continuous_on s``,
8795  MESON_TAC[CONTINUOUS_ON_NO_LIMPT, LIMIT_POINT_FINITE]);
8796
8797val CONTRACTION_IMP_CONTINUOUS_ON = store_thm ("CONTRACTION_IMP_CONTINUOUS_ON",
8798 ``!f:real->real.
8799   (!x y. x IN s /\ y IN s ==> dist(f x,f y) <= dist(x,y))
8800   ==> f continuous_on s``,
8801  SIMP_TAC std_ss [continuous_on] THEN MESON_TAC[REAL_LET_TRANS]);
8802
8803val ISOMETRY_ON_IMP_CONTINUOUS_ON = store_thm ("ISOMETRY_ON_IMP_CONTINUOUS_ON",
8804 ``!f:real->real.
8805   (!x y. x IN s /\ y IN s ==> (dist(f x,f y) = dist(x,y)))
8806   ==> f continuous_on s``,
8807  SIMP_TAC std_ss [CONTRACTION_IMP_CONTINUOUS_ON, REAL_LE_REFL]);
8808
8809(* ------------------------------------------------------------------------- *)
8810(* Characterization of various kinds of continuity in terms of sequences.    *)
8811(* ------------------------------------------------------------------------- *)
8812
8813val FORALL_POS_MONO_1 = store_thm ("FORALL_POS_MONO_1",
8814 ``!P. (!d e. d < e /\ P d ==> P e) /\ (!n. P(inv(&n + &1)))
8815       ==> !e. (&0:real) < e ==> P e``,
8816  SIMP_TAC std_ss [REAL_OF_NUM_SUC] THEN SIMP_TAC std_ss [GSYM FORALL_SUC] THEN
8817  REWRITE_TAC [FORALL_POS_MONO]);
8818
8819val CONTINUOUS_WITHIN_SEQUENTIALLY = store_thm ("CONTINUOUS_WITHIN_SEQUENTIALLY",
8820 ``!f s a:real.
8821    f continuous (at a within s) <=>
8822    !x. (!n. x(n) IN s) /\ (x --> a) sequentially
8823    ==> ((f o x) --> f(a)) sequentially``,
8824  REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within] THEN EQ_TAC THENL
8825  [SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN MESON_TAC[], ALL_TAC] THEN
8826  ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN
8827  SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM] THEN
8828  DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
8829  DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC ``&1 / (&n + &1:real)``) THEN
8830  SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT, REAL_OF_NUM_LE, REAL_POS,
8831   REAL_ARITH ``&0 <= n ==> &0 < n + &1:real``, NOT_FORALL_THM, SKOLEM_THM] THEN
8832  DISCH_THEN (X_CHOOSE_TAC ``y:num->real``) THEN EXISTS_TAC ``y:num->real`` THEN
8833  POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [NOT_IMP, FORALL_AND_THM] THEN
8834  SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN
8835  STRIP_TAC THEN CONJ_TAC THENL [ALL_TAC, ASM_MESON_TAC[LESS_EQ_REFL]] THEN
8836  KNOW_TAC ``!e. (?N:num. !n. N <= n ==> dist (y n,a) < e) =
8837             (\e. ?N:num. !n. N <= n ==> dist (y n,a) < e) e`` THENL
8838  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
8839  MATCH_MP_TAC FORALL_POS_MONO_1 THEN BETA_TAC THEN
8840  CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_TRANS], ALL_TAC] THEN
8841  X_GEN_TAC ``n:num`` THEN EXISTS_TAC ``n:num`` THEN X_GEN_TAC ``m:num`` THEN
8842  DISCH_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN
8843  EXISTS_TAC ``&1 / (&m + &1:real)`` THEN ASM_REWRITE_TAC[] THEN
8844  ASM_SIMP_TAC std_ss [REAL_LE_INV2, real_div, REAL_ARITH ``&0 <= x ==> &0 < x + &1:real``,
8845   REAL_POS, REAL_MUL_LID, REAL_LE_RADD, REAL_OF_NUM_LE]);
8846
8847val CONTINUOUS_AT_SEQUENTIALLY = store_thm ("CONTINUOUS_AT_SEQUENTIALLY",
8848 ``!f a:real. f continuous (at a) <=>
8849   !x. (x --> a) sequentially ==> ((f o x) --> f(a)) sequentially``,
8850  ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
8851  REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY, IN_UNIV]);
8852
8853val CONTINUOUS_ON_SEQUENTIALLY = store_thm ("CONTINUOUS_ON_SEQUENTIALLY",
8854 ``!f s:real->bool. f continuous_on s <=>
8855   !x a. a IN s /\ (!n. x(n) IN s) /\ (x --> a) sequentially
8856   ==> ((f o x) --> f(a)) sequentially``,
8857  REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN,
8858  CONTINUOUS_WITHIN_SEQUENTIALLY] THEN MESON_TAC[]);
8859
8860val UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY = store_thm ("UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY",
8861 ``!f s:real->bool. f uniformly_continuous_on s <=>
8862   !x y. (!n. x(n) IN s) /\ (!n. y(n) IN s) /\
8863   ((\n. x(n) - y(n)) --> 0) sequentially
8864   ==> ((\n. f(x(n)) - f(y(n))) --> 0) sequentially``,
8865  REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on] THEN
8866  REWRITE_TAC[LIM_SEQUENTIALLY, dist, REAL_SUB_RZERO] THEN
8867  EQ_TAC THENL [MESON_TAC[], ALL_TAC] THEN
8868  ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN
8869  SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, NOT_EXISTS_THM] THEN
8870  DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
8871  DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC ``&1 / (&n + &1:real)``) THEN
8872  SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT, REAL_OF_NUM_LE, REAL_POS,
8873   REAL_ARITH ``&0 <= n ==> &0 < n + &1:real``, NOT_FORALL_THM, SKOLEM_THM] THEN
8874  DISCH_THEN (X_CHOOSE_TAC ``x:num->real``) THEN POP_ASSUM MP_TAC THEN
8875  DISCH_THEN (X_CHOOSE_TAC ``y:num->real``) THEN
8876  EXISTS_TAC ``x:num->real`` THEN EXISTS_TAC ``y:num->real`` THEN
8877  POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [NOT_IMP, FORALL_AND_THM] THEN STRIP_TAC THEN
8878  ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[ABS_SUB] THEN CONJ_TAC THENL
8879  [KNOW_TAC ``!e:real. (?N:num. !n. N <= n ==> abs (y n - x n) < e) =
8880                   (\e. ?N:num. !n. N <= n ==> abs (y n - x n) < e) e`` THENL
8881   [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
8882   MATCH_MP_TAC FORALL_POS_MONO_1 THEN BETA_TAC THEN
8883   CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_TRANS], ALL_TAC] THEN
8884   X_GEN_TAC ``n:num`` THEN EXISTS_TAC ``n:num`` THEN X_GEN_TAC ``m:num`` THEN
8885   DISCH_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN
8886   EXISTS_TAC ``&1 / (&m + &1:real)`` THEN ASM_REWRITE_TAC[] THEN
8887   ASM_SIMP_TAC std_ss [REAL_LE_INV2, real_div, REAL_ARITH ``&0 <= x ==> &0 < x + &1:real``,
8888    REAL_POS, REAL_MUL_LID, REAL_LE_RADD, REAL_OF_NUM_LE],
8889  EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[] THEN
8890  EXISTS_TAC ``\x:num. x`` THEN ASM_SIMP_TAC std_ss [LESS_EQ_REFL]]);
8891
8892val LIM_CONTINUOUS_FUNCTION = store_thm ("LIM_CONTINUOUS_FUNCTION",
8893 ``!f net g l.
8894  f continuous (at l) /\ (g --> l) net ==> ((\x. f(g x)) --> f l) net``,
8895  REWRITE_TAC[tendsto, continuous_at, eventually] THEN MESON_TAC[]);
8896
8897(* ------------------------------------------------------------------------- *)
8898(* Combination results for pointwise continuity.                             *)
8899(* ------------------------------------------------------------------------- *)
8900
8901val CONTINUOUS_CONST = store_thm ("CONTINUOUS_CONST",
8902 ``!net c. (\x. c) continuous net``,
8903  REWRITE_TAC[continuous, LIM_CONST]);
8904
8905val CONTINUOUS_CMUL = store_thm ("CONTINUOUS_CMUL",
8906 ``!f c net. f continuous net ==> (\x. c * f(x)) continuous net``,
8907  SIMP_TAC std_ss [continuous, LIM_CMUL]);
8908
8909val CONTINUOUS_NEG = store_thm ("CONTINUOUS_NEG",
8910 ``!f net. f continuous net ==> (\x. -(f x)) continuous net``,
8911  SIMP_TAC std_ss [continuous, LIM_NEG]);
8912
8913val CONTINUOUS_ADD = store_thm ("CONTINUOUS_ADD",
8914 ``!f g net. f continuous net /\ g continuous net
8915  ==> (\x. f(x) + g(x)) continuous net``,
8916  SIMP_TAC std_ss [continuous, LIM_ADD]);
8917
8918val CONTINUOUS_SUB = store_thm ("CONTINUOUS_SUB",
8919 ``!f g net. f continuous net /\ g continuous net
8920  ==> (\x. f(x) - g(x)) continuous net``,
8921  SIMP_TAC std_ss [continuous, LIM_SUB]);
8922
8923val CONTINUOUS_ABS = store_thm ("CONTINUOUS_ABS",
8924 ``!(f:'a->real) net. f continuous net
8925  ==> (\x. abs(f(x)):real) continuous net``,
8926  SIMP_TAC std_ss [continuous, LIM_ABS]);
8927
8928val CONTINUOUS_MAX = store_thm ("CONTINUOUS_MAX",
8929 ``!(f:'a->real) (g:'a->real) net.
8930   f continuous net /\ g continuous net
8931   ==> (\x. (max (f(x)) (g(x))):real) continuous net``,
8932  SIMP_TAC std_ss [continuous, LIM_MAX]);
8933
8934val CONTINUOUS_MIN = store_thm ("CONTINUOUS_MIN",
8935 ``!(f:'a->real) (g:'a->real) net.
8936   f continuous net /\ g continuous net
8937   ==> (\x. (min (f(x)) (g(x))):real) continuous net``,
8938  SIMP_TAC std_ss [continuous, LIM_MIN]);
8939
8940val CONTINUOUS_SUM = store_thm ("CONTINUOUS_SUM",
8941 ``!net f s. FINITE s /\ (!a. a IN s ==> (f a) continuous net)
8942  ==> (\x. sum s (\a. f a x)) continuous net``,
8943  GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[CONJ_EQ_IMP] THEN
8944  KNOW_TAC ``!s. ((!a:'b. a IN s ==> f a continuous net) ==>
8945              (\x:'a. sum s (\a. f a x)) continuous net) =
8946             (\s. (!a. a IN s ==> f a continuous net) ==>
8947              (\x. sum s (\a. f a x)) continuous net) s`` THENL
8948  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
8949  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
8950  SIMP_TAC std_ss [FORALL_IN_INSERT, NOT_IN_EMPTY, SUM_CLAUSES,
8951   CONTINUOUS_CONST, CONTINUOUS_ADD, ETA_AX] THEN
8952  METIS_TAC [FORALL_IN_INSERT, NOT_IN_EMPTY, SUM_CLAUSES,
8953   CONTINUOUS_CONST, CONTINUOUS_ADD, ETA_AX]);
8954
8955(* ------------------------------------------------------------------------- *)
8956(* Same thing for setwise continuity.                                        *)
8957(* ------------------------------------------------------------------------- *)
8958
8959val CONTINUOUS_ON_CONST = store_thm ("CONTINUOUS_ON_CONST",
8960 ``!s c. (\x. c) continuous_on s``,
8961  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_CONST]);
8962
8963val CONTINUOUS_ON_CMUL = store_thm ("CONTINUOUS_ON_CMUL",
8964 ``!f c s. f continuous_on s ==> (\x. c * f(x)) continuous_on s``,
8965  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_CMUL]);
8966
8967val CONTINUOUS_ON_NEG = store_thm ("CONTINUOUS_ON_NEG",
8968 ``!f s. f continuous_on s
8969  ==> (\x. -(f x)) continuous_on s``,
8970  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_NEG]);
8971
8972val CONTINUOUS_ON_ADD = store_thm ("CONTINUOUS_ON_ADD",
8973 ``!f g s. f continuous_on s /\ g continuous_on s
8974  ==> (\x. f(x) + g(x)) continuous_on s``,
8975  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_ADD]);
8976
8977val CONTINUOUS_ON_SUB = store_thm ("CONTINUOUS_ON_SUB",
8978 ``!f g s. f continuous_on s /\ g continuous_on s
8979  ==> (\x. f(x) - g(x)) continuous_on s``,
8980  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_SUB]);
8981
8982val CONTINUOUS_ON_ABS = store_thm ("CONTINUOUS_ON_ABS",
8983 ``!f:real->real s. f continuous_on s
8984  ==> (\x. (abs(f(x))):real) continuous_on s``,
8985  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_ABS]);
8986
8987val CONTINUOUS_ON_MAX = store_thm ("CONTINUOUS_ON_MAX",
8988 ``!f:real->real g:real->real s.
8989  f continuous_on s /\ g continuous_on s
8990  ==> (\x. (max (f(x)) (g(x))):real)
8991   continuous_on s``,
8992  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_MAX]);
8993
8994val CONTINUOUS_ON_MIN = store_thm ("CONTINUOUS_ON_MIN",
8995 ``!f:real->real g:real->real s.
8996  f continuous_on s /\ g continuous_on s
8997  ==> (\x. (min (f(x)) (g(x))):real)
8998   continuous_on s``,
8999  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_MIN]);
9000
9001val CONTINUOUS_ON_SUM = store_thm ("CONTINUOUS_ON_SUM",
9002 ``!t f s. FINITE s /\ (!a. a IN s ==> (f a) continuous_on t)
9003  ==> (\x. sum s (\a. f a x)) continuous_on t``,
9004  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_SUM]);
9005
9006(* ------------------------------------------------------------------------- *)
9007(* Same thing for uniform continuity, using sequential formulations.         *)
9008(* ------------------------------------------------------------------------- *)
9009
9010val UNIFORMLY_CONTINUOUS_ON_CONST = store_thm ("UNIFORMLY_CONTINUOUS_ON_CONST",
9011 ``!s c. (\x. c) uniformly_continuous_on s``,
9012  SIMP_TAC std_ss [UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY, o_DEF,
9013   REAL_SUB_REFL, LIM_CONST]);
9014
9015val LINEAR_UNIFORMLY_CONTINUOUS_ON = store_thm ("LINEAR_UNIFORMLY_CONTINUOUS_ON",
9016 ``!f:real->real s. linear f ==> f uniformly_continuous_on s``,
9017  REPEAT STRIP_TAC THEN
9018  ASM_SIMP_TAC std_ss [uniformly_continuous_on, dist, GSYM LINEAR_SUB] THEN
9019  FIRST_ASSUM(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC o
9020   MATCH_MP LINEAR_BOUNDED_POS) THEN
9021  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN EXISTS_TAC ``e / B:real`` THEN
9022  ASM_SIMP_TAC std_ss [REAL_LT_DIV] THEN
9023  MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN
9024  MATCH_MP_TAC REAL_LET_TRANS THEN
9025  EXISTS_TAC ``B * abs(y - x:real)`` THEN ASM_REWRITE_TAC[] THEN
9026  ASM_MESON_TAC[REAL_LT_RDIV_EQ, REAL_MUL_SYM]);
9027
9028val lemma = prove (
9029 ``(!y. ((?x. (y = f x) /\ P x) /\ Q y ==> R y)) <=>
9030   (!x. P x /\ Q (f x) ==> R (f x))``,
9031  MESON_TAC[]);
9032
9033val UNIFORMLY_CONTINUOUS_ON_COMPOSE = store_thm ("UNIFORMLY_CONTINUOUS_ON_COMPOSE",
9034 ``!f g s. f uniformly_continuous_on s /\
9035           g uniformly_continuous_on (IMAGE f s)
9036 ==> (g o f) uniformly_continuous_on s``,
9037  REPEAT GEN_TAC THEN
9038  SIMP_TAC std_ss [uniformly_continuous_on, o_THM, IN_IMAGE] THEN
9039  KNOW_TAC ``((!e:real. 0 < e ==> ?d. 0 < d /\
9040     !x x'. x IN s /\ x' IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\
9041              (!e:real. 0 < e ==> ?d. 0 < d /\
9042     !x x'. (?x'. (x = f x') /\ x' IN s) /\ (?x. (x' = f x) /\ x IN s) /\
9043       dist (x',x) < d ==> dist (g x',g x) < e) ==>
9044               !e:real. 0 < e ==> ?d. 0 < d /\
9045    !x x'. x IN s /\ x' IN s /\ dist (x',x) < d ==>
9046      dist (g (f x'),g (f x)) < e) =
9047             ((!e:real. 0 < e ==> ?d. 0 < d /\
9048     !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\
9049              (!e:real. 0 < e ==> ?d. 0 < d /\
9050     !x' x. (?x'. (x = f x') /\ x' IN s) /\ (?x. (x' = f x) /\ x IN s) /\
9051       dist (x',x) < d ==> dist (g x',g x) < e) ==>
9052               !e:real. 0 < e ==> ?d. 0 < d /\
9053    !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==>
9054      dist (g (f x'),g (f x)) < e)`` THENL
9055  [METIS_TAC [SWAP_FORALL_THM], ALL_TAC] THEN DISC_RW_KILL THEN
9056  KNOW_TAC `` ((!e:real. 0 < e ==> ?d. 0 < d /\
9057     !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\
9058              (!e:real. 0 < e ==> ?d. 0 < d /\
9059     !x' x. (?x'. (x = f x') /\ x' IN s) /\ (?x. (x' = f x) /\ x IN s) /\
9060       dist (x',x) < d ==> dist (g x',g x) < e) ==>
9061               !e:real. 0 < e ==> ?d. 0 < d /\
9062     !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==>
9063      dist (g (f x'),g (f x)) < e) =
9064              ((!e:real. 0 < e ==> ?d. 0 < d /\
9065     !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\
9066              (!e:real. 0 < e ==> ?d. 0 < d /\
9067     !x' x. x IN s /\ (?x. (x' = f x) /\ x IN s) /\ dist (x',f x) < d
9068                    ==> dist (g x',g (f x)) < e) ==>
9069               !e:real. 0 < e ==> ?d. 0 < d /\
9070     !x' x. x IN s /\ x' IN s /\ dist (x',x) < d ==>
9071      dist (g (f x'),g (f x)) < e)`` THENL
9072  [METIS_TAC [], ALL_TAC] THEN DISC_RW_KILL THEN
9073  ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN
9074  KNOW_TAC ``((!e. 0 < e ==> ?d. 0 < d /\
9075     !x' x. x' IN s /\ x IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\
9076              (!e. 0 < e ==> ?d. 0 < d /\
9077     !x' x. (?x. (x' = f x) /\ x IN s) /\ x IN s /\ dist (x',f x) < d ==>
9078       dist (g x',g (f x)) < e) ==>
9079               !e. 0 < e ==> ?d. 0 < d /\
9080    !x' x. x' IN s /\ x IN s /\ dist (x',x) < d ==>
9081      dist (g (f x'),g (f x)) < e) =
9082              ((!e. 0 < e ==> ?d. 0 < d /\
9083     !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\
9084              (!e. 0 < e ==> ?d. 0 < d /\
9085     !x x'. (?x. (x' = f x) /\ x IN s) /\ x IN s /\ dist (x',f x) < d ==>
9086       dist (g x',g (f x)) < e) ==>
9087               !e. 0 < e ==> ?d. 0 < d /\
9088    !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==>
9089      dist (g (f x'),g (f x)) < e)`` THENL
9090  [METIS_TAC [SWAP_FORALL_THM], ALL_TAC] THEN DISC_RW_KILL THEN
9091  KNOW_TAC ``((!e. 0 < e ==> ?d. 0 < d /\
9092     !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\
9093              (!e. 0 < e ==> ?d. 0 < d /\
9094     !x x'. (?x. (x' = f x) /\ x IN s) /\ x IN s /\ dist (x',f x) < d ==>
9095       dist (g x',g (f x)) < e) ==>
9096               !e. 0 < e ==> ?d. 0 < d /\
9097    !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==>
9098      dist (g (f x'),g (f x)) < e) =
9099            ((!e. 0 < e ==> ?d. 0 < d /\
9100     !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==> dist (f x',f x) < e) /\
9101              (!e. 0 < e ==> ?d. 0 < d /\
9102     !x x'. x' IN s /\ x IN s /\ dist (f x',f x) < d ==>
9103       dist (g (f x'),g (f x)) < e) ==>
9104               !e. 0 < e ==> ?d. 0 < d /\
9105    !x x'. x' IN s /\ x IN s /\ dist (x',x) < d ==>
9106      dist (g (f x'),g (f x)) < e)`` THENL
9107  [METIS_TAC [], ALL_TAC] THEN DISC_RW_KILL THEN
9108  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
9109  DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN
9110  POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN
9111  ASM_CASES_TAC ``&0 < e`` THEN ASM_REWRITE_TAC[] THEN
9112  ASM_MESON_TAC[]);
9113
9114val BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE = store_thm ("BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE",
9115 ``!f:real->real g (h:real->real->real) s.
9116    f uniformly_continuous_on s /\ g uniformly_continuous_on s /\
9117    bilinear h /\ bounded(IMAGE f s) /\ bounded(IMAGE g s)
9118    ==> (\x. h (f x) (g x)) uniformly_continuous_on s``,
9119  REPEAT STRIP_TAC THEN REWRITE_TAC[uniformly_continuous_on, dist] THEN
9120  BETA_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
9121  SUBGOAL_THEN
9122   ``!a b c d. (h:real->real->real) a b - h c d =
9123     h (a - c) b + h c (b - d)`` (fn th => ONCE_REWRITE_TAC[th]) THENL
9124  [FIRST_ASSUM(fn th => REWRITE_TAC[MATCH_MP BILINEAR_LSUB th]) THEN
9125   FIRST_ASSUM(fn th => REWRITE_TAC[MATCH_MP BILINEAR_RSUB th]) THEN
9126   REAL_ARITH_TAC, ALL_TAC] THEN
9127  FIRST_X_ASSUM(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC o
9128   MATCH_MP BILINEAR_BOUNDED_POS) THEN
9129  UNDISCH_TAC ``bounded(IMAGE (g:real->real) s)`` THEN
9130  UNDISCH_TAC ``bounded(IMAGE (f:real->real) s)`` THEN
9131  SIMP_TAC std_ss [BOUNDED_POS, FORALL_IN_IMAGE] THEN
9132  DISCH_THEN(X_CHOOSE_THEN ``B1:real`` STRIP_ASSUME_TAC) THEN
9133  DISCH_THEN(X_CHOOSE_THEN ``B2:real`` STRIP_ASSUME_TAC) THEN
9134  UNDISCH_TAC ``(g:real->real) uniformly_continuous_on s`` THEN
9135  UNDISCH_TAC ``(f:real->real) uniformly_continuous_on s`` THEN
9136  REWRITE_TAC[uniformly_continuous_on] THEN
9137  DISCH_THEN(MP_TAC o SPEC ``e:real / &2 / &2 / B / B2``) THEN
9138  ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_HALF, dist] THEN
9139  DISCH_THEN(X_CHOOSE_THEN ``d1:real`` STRIP_ASSUME_TAC) THEN
9140  DISCH_THEN(MP_TAC o SPEC ``e:real / &2 / &2 / B / B1``) THEN
9141  ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_HALF, dist] THEN
9142  DISCH_THEN(X_CHOOSE_THEN ``d2:real`` STRIP_ASSUME_TAC) THEN
9143  EXISTS_TAC ``min d1 d2:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
9144  MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN
9145  FIRST_X_ASSUM(MP_TAC o SPECL [``x:real``, ``y:real``]) THEN
9146  FIRST_X_ASSUM(MP_TAC o SPECL [``x:real``, ``y:real``]) THEN
9147  ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
9148  MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC
9149   ``B * e / &2 / &2 / B / B2 * B2 + B * B1 * e / &2 / &2 / B / B1:real`` THEN
9150  CONJ_TAC THENL
9151  [MATCH_MP_TAC(REAL_ARITH
9152   ``abs(x) <= a /\ abs(y) <= b ==> abs(x + y:real) <= a + b``) THEN
9153  CONJ_TAC THEN
9154  FIRST_X_ASSUM(fn th => W(MP_TAC o PART_MATCH lhand th o lhand o snd)) THEN
9155  MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
9156  REWRITE_TAC [real_div] THEN REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN
9157  MATCH_MP_TAC REAL_LE_LMUL1 THEN ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE] THENL
9158  [REWRITE_TAC [GSYM real_div, REAL_MUL_ASSOC],ALL_TAC] THEN
9159  MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC [GSYM real_div, REAL_MUL_ASSOC] THEN
9160  ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE, ABS_POS],
9161  ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_POS_NZ] THEN
9162  REWRITE_TAC [real_div, GSYM REAL_MUL_ASSOC] THEN
9163  ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN
9164  REWRITE_TAC [GSYM real_div, REAL_MUL_ASSOC] THEN
9165  ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_POS_NZ] THEN
9166  REWRITE_TAC [real_div] THEN
9167  REWRITE_TAC [REAL_ARITH `` B1 * e * inv 2 * inv 2 * inv B * inv B1 * B =
9168                             e * inv 2 * inv 2 * inv B * inv B1 * B1 * B:real``] THEN
9169  REWRITE_TAC [GSYM real_div] THEN
9170  ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_POS_NZ] THEN
9171  REWRITE_TAC [REAL_HALF_DOUBLE] THEN ASM_SIMP_TAC std_ss [REAL_LT_HALF2]]);
9172
9173val UNIFORMLY_CONTINUOUS_ON_MUL = store_thm ("UNIFORMLY_CONTINUOUS_ON_MUL",
9174 ``!f g:real->real s.
9175    f uniformly_continuous_on s /\ g uniformly_continuous_on s /\
9176    bounded(IMAGE f s) /\ bounded(IMAGE g s)
9177    ==> (\x. f x * g x) uniformly_continuous_on s``,
9178  REPEAT STRIP_TAC THEN
9179  MP_TAC(ISPECL [``(f:real->real)``, ``g:real->real``,
9180   ``\c (v:real). c * v``, ``s:real->bool``]
9181  BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE) THEN
9182  ASM_SIMP_TAC std_ss [o_THM] THEN DISCH_THEN MATCH_MP_TAC THEN
9183  REWRITE_TAC[bilinear, linear] THEN BETA_TAC THEN REAL_ARITH_TAC);
9184
9185val UNIFORMLY_CONTINUOUS_ON_CMUL = store_thm ("UNIFORMLY_CONTINUOUS_ON_CMUL",
9186 ``!f c s. f uniformly_continuous_on s
9187   ==> (\x. c * f(x)) uniformly_continuous_on s``,
9188  REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY] THEN
9189  DISCH_TAC THEN GEN_TAC THEN GEN_TAC THEN
9190  POP_ASSUM (MP_TAC o Q.SPECL [`x:num->real`, `y:num->real`]) THEN
9191  DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN
9192  ASM_REWRITE_TAC[] THEN
9193  DISCH_THEN(MP_TAC o MATCH_MP LIM_CMUL) THEN
9194  ASM_SIMP_TAC std_ss [REAL_SUB_LDISTRIB, REAL_MUL_RZERO]);
9195
9196val UNIFORMLY_CONTINUOUS_ON_VMUL = store_thm ("UNIFORMLY_CONTINUOUS_ON_VMUL",
9197 ``!s:real->bool c v:real.
9198    c uniformly_continuous_on s
9199    ==> (\x. c x * v) uniformly_continuous_on s``,
9200  REPEAT GEN_TAC THEN
9201  DISCH_THEN(MP_TAC o ISPEC ``\x. (x * v:real)`` o MATCH_MP
9202   (REWRITE_RULE[CONJ_EQ_IMP] UNIFORMLY_CONTINUOUS_ON_COMPOSE)) THEN
9203  SIMP_TAC std_ss [o_DEF] THEN DISCH_THEN MATCH_MP_TAC THEN
9204  MATCH_MP_TAC LINEAR_UNIFORMLY_CONTINUOUS_ON THEN
9205  REWRITE_TAC [linear] THEN BETA_TAC THEN REAL_ARITH_TAC);
9206
9207val UNIFORMLY_CONTINUOUS_ON_NEG = store_thm ("UNIFORMLY_CONTINUOUS_ON_NEG",
9208 ``!f s. f uniformly_continuous_on s
9209   ==> (\x. -(f x)) uniformly_continuous_on s``,
9210  ONCE_REWRITE_TAC[REAL_NEG_MINUS1] THEN
9211  REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_CMUL]);
9212
9213val UNIFORMLY_CONTINUOUS_ON_ADD = store_thm ("UNIFORMLY_CONTINUOUS_ON_ADD",
9214 ``!f g s. f uniformly_continuous_on s /\ g uniformly_continuous_on s
9215  ==> (\x. f(x) + g(x)) uniformly_continuous_on s``,
9216  REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY] THEN
9217  SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN
9218  DISCH_TAC THEN GEN_TAC THEN GEN_TAC THEN
9219  POP_ASSUM (MP_TAC o Q.SPECL [`x:num->real`, `y:num->real`]) THEN
9220  DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN
9221  ASM_SIMP_TAC std_ss [o_DEF] THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN
9222  MATCH_MP_TAC EQ_IMPLIES THEN BETA_TAC THEN
9223  REWRITE_TAC[REAL_ADD_LID] THEN AP_THM_TAC THEN BINOP_TAC THEN
9224  REWRITE_TAC[FUN_EQ_THM] THEN BETA_TAC THEN REAL_ARITH_TAC);
9225
9226val UNIFORMLY_CONTINUOUS_ON_SUB = store_thm ("UNIFORMLY_CONTINUOUS_ON_SUB",
9227 ``!f g s. f uniformly_continuous_on s /\ g uniformly_continuous_on s
9228   ==> (\x. f(x) - g(x)) uniformly_continuous_on s``,
9229  REWRITE_TAC[real_sub] THEN
9230  SIMP_TAC std_ss [UNIFORMLY_CONTINUOUS_ON_NEG, UNIFORMLY_CONTINUOUS_ON_ADD]);
9231
9232val UNIFORMLY_CONTINUOUS_ON_SUM = store_thm ("UNIFORMLY_CONTINUOUS_ON_SUM",
9233 ``!t f s. FINITE s /\ (!a. a IN s ==> (f a) uniformly_continuous_on t)
9234    ==> (\x. sum s (\a. f a x)) uniformly_continuous_on t``,
9235  GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[CONJ_EQ_IMP] THEN
9236  KNOW_TAC ``!s. ((!a. a IN s ==> f a uniformly_continuous_on t) ==>
9237              (\x. sum s (\a. f a x)) uniformly_continuous_on t) =
9238             (\s. (!a. a IN s ==> f a uniformly_continuous_on t) ==>
9239              (\x. sum s (\a. f a x)) uniformly_continuous_on t) s`` THENL
9240  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
9241  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN
9242  SIMP_TAC std_ss [FORALL_IN_INSERT, NOT_IN_EMPTY, SUM_CLAUSES,
9243   UNIFORMLY_CONTINUOUS_ON_CONST, ETA_AX] THEN REPEAT STRIP_TAC THEN
9244  METIS_TAC [UNIFORMLY_CONTINUOUS_ON_ADD]);
9245
9246(* ------------------------------------------------------------------------- *)
9247(* Identity function is continuous in every sense.                           *)
9248(* ------------------------------------------------------------------------- *)
9249
9250val CONTINUOUS_WITHIN_ID = store_thm ("CONTINUOUS_WITHIN_ID",
9251 ``!a s. (\x. x) continuous (at a within s)``,
9252  REWRITE_TAC[continuous_within] THEN MESON_TAC[]);
9253
9254val CONTINUOUS_AT_ID = store_thm ("CONTINUOUS_AT_ID",
9255 ``!a. (\x. x) continuous (at a)``,
9256  REWRITE_TAC[continuous_at] THEN MESON_TAC[]);
9257
9258val CONTINUOUS_ON_ID = store_thm ("CONTINUOUS_ON_ID",
9259 ``!s. (\x. x) continuous_on s``,
9260  REWRITE_TAC[continuous_on] THEN MESON_TAC[]);
9261
9262val UNIFORMLY_CONTINUOUS_ON_ID = store_thm ("UNIFORMLY_CONTINUOUS_ON_ID",
9263 ``!s. (\x. x) uniformly_continuous_on s``,
9264  REWRITE_TAC[uniformly_continuous_on] THEN MESON_TAC[]);
9265
9266(* ------------------------------------------------------------------------- *)
9267(* Continuity of all kinds is preserved under composition. *)
9268(* ------------------------------------------------------------------------- *)
9269
9270val CONTINUOUS_WITHIN_COMPOSE = store_thm ("CONTINUOUS_WITHIN_COMPOSE",
9271 ``!f g x s. f continuous (at x within s) /\
9272      g continuous (at (f x) within IMAGE f s)
9273    ==> (g o f) continuous (at x within s)``,
9274  REPEAT GEN_TAC THEN SIMP_TAC std_ss [continuous_within, o_THM, IN_IMAGE] THEN
9275  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
9276  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN
9277  ASM_MESON_TAC[]);
9278
9279val CONTINUOUS_AT_COMPOSE = store_thm ("CONTINUOUS_AT_COMPOSE",
9280 ``!f g x. f continuous (at x) /\ g continuous (at (f x))
9281   ==> (g o f) continuous (at x)``,
9282  ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
9283  MESON_TAC[CONTINUOUS_WITHIN_COMPOSE, IN_IMAGE, CONTINUOUS_WITHIN_SUBSET,
9284   SUBSET_UNIV, IN_UNIV]);
9285
9286val CONTINUOUS_ON_COMPOSE = store_thm ("CONTINUOUS_ON_COMPOSE",
9287 ``!f g s. f continuous_on s /\ g continuous_on (IMAGE f s)
9288  ==> (g o f) continuous_on s``,
9289  REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
9290  MESON_TAC[IN_IMAGE, CONTINUOUS_WITHIN_COMPOSE]);
9291
9292(* ------------------------------------------------------------------------- *)
9293(* Continuity in terms of open preimages. *)
9294(* ------------------------------------------------------------------------- *)
9295
9296val CONTINUOUS_WITHIN_OPEN = store_thm ("CONTINUOUS_WITHIN_OPEN",
9297 ``!f:real->real x u.
9298    f continuous (at x within u) <=>
9299   !t. open t /\ f(x) IN t
9300   ==> ?s. open s /\ x IN s /\
9301    !x'. x' IN s /\ x' IN u ==> f(x') IN t``,
9302  REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within] THEN EQ_TAC THENL
9303  [DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN
9304   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
9305   GEN_REWR_TAC LAND_CONV [open_def] THEN
9306   DISCH_THEN(MP_TAC o SPEC ``(f:real->real) x``) THEN
9307   ASM_MESON_TAC[IN_BALL, DIST_SYM, OPEN_BALL, CENTRE_IN_BALL, DIST_SYM],
9308   DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
9309   FIRST_X_ASSUM(MP_TAC o SPEC ``ball((f:real->real) x,e)``) THEN
9310   ASM_SIMP_TAC std_ss [OPEN_BALL, CENTRE_IN_BALL] THEN
9311   MESON_TAC[open_def, IN_BALL, REAL_LT_TRANS, DIST_SYM]]);
9312
9313val CONTINUOUS_AT_OPEN = store_thm ("CONTINUOUS_AT_OPEN",
9314 ``!f:real->real x.
9315   f continuous (at x) <=>
9316   !t. open t /\ f(x) IN t
9317   ==> ?s. open s /\ x IN s /\
9318    !x'. x' IN s ==> f(x') IN t``,
9319  REPEAT GEN_TAC THEN REWRITE_TAC[continuous_at] THEN EQ_TAC THENL
9320  [DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN
9321   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
9322   GEN_REWR_TAC LAND_CONV [open_def] THEN
9323   DISCH_THEN(MP_TAC o SPEC ``(f:real->real) x``) THEN
9324   ASM_MESON_TAC[IN_BALL, DIST_SYM, OPEN_BALL, CENTRE_IN_BALL],
9325   DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
9326   FIRST_X_ASSUM(MP_TAC o SPEC ``ball((f:real->real) x,e)``) THEN
9327   ASM_SIMP_TAC std_ss [OPEN_BALL, CENTRE_IN_BALL] THEN
9328   MESON_TAC[open_def, IN_BALL, REAL_LT_TRANS, DIST_SYM]]);
9329
9330val CONTINUOUS_ON_OPEN_GEN = store_thm ("CONTINUOUS_ON_OPEN_GEN",
9331 ``!f:real->real s t.
9332   IMAGE f s SUBSET t
9333   ==> (f continuous_on s <=>
9334    !u. open_in (subtopology euclidean t) u
9335    ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN u})``,
9336  REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_on] THEN EQ_TAC THENL
9337  [SIMP_TAC std_ss [open_in, SUBSET_DEF, GSPECIFICATION] THEN
9338   DISCH_TAC THEN X_GEN_TAC ``u:real->bool`` THEN STRIP_TAC THEN
9339   X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN
9340   FIRST_X_ASSUM(MP_TAC o SPEC ``(f:real->real) x``) THEN ASM_SET_TAC[],
9341  DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN
9342  DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
9343  FIRST_X_ASSUM(MP_TAC o
9344   SPEC ``ball((f:real->real) x,e) INTER t``) THEN
9345  KNOW_TAC ``open_in (subtopology euclidean t) (ball ((f:real->real) x,e) INTER t)`` THENL
9346  [ASM_MESON_TAC[OPEN_IN_OPEN, INTER_COMM, OPEN_BALL], ALL_TAC] THEN
9347  DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
9348  SIMP_TAC std_ss [open_in, SUBSET_DEF, IN_INTER, GSPECIFICATION, IN_BALL, IN_IMAGE] THEN
9349  DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN
9350  RULE_ASSUM_TAC(REWRITE_RULE[SUBSET_DEF, FORALL_IN_IMAGE]) THEN
9351  FULL_SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN
9352  ASM_MESON_TAC[DIST_REFL, DIST_SYM]]);
9353
9354val CONTINUOUS_ON_OPEN = store_thm ("CONTINUOUS_ON_OPEN",
9355 ``!f:real->real s.
9356   f continuous_on s <=>
9357   !t. open_in (subtopology euclidean (IMAGE f s)) t
9358    ==> open_in (subtopology euclidean s) {x | x IN s /\ f(x) IN t}``,
9359  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_OPEN_GEN THEN
9360  REWRITE_TAC[SUBSET_REFL]);
9361
9362val CONTINUOUS_OPEN_IN_PREIMAGE_GEN = store_thm ("CONTINUOUS_OPEN_IN_PREIMAGE_GEN",
9363 ``!f:real->real s t u.
9364    f continuous_on s /\ IMAGE f s SUBSET t /\
9365    open_in (subtopology euclidean t) u
9366    ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN u}``,
9367  METIS_TAC[CONTINUOUS_ON_OPEN_GEN]);
9368
9369val CONTINUOUS_ON_IMP_OPEN_IN = store_thm ("CONTINUOUS_ON_IMP_OPEN_IN",
9370 ``!f:real->real s t. f continuous_on s /\
9371   open_in (subtopology euclidean (IMAGE f s)) t
9372   ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``,
9373 METIS_TAC[CONTINUOUS_ON_OPEN]);
9374
9375(* ------------------------------------------------------------------------- *)
9376(* Similarly in terms of closed sets. *)
9377(* ------------------------------------------------------------------------- *)
9378
9379val CONTINUOUS_ON_CLOSED_GEN = store_thm ("CONTINUOUS_ON_CLOSED_GEN",
9380 ``!f:real->real s t.
9381   IMAGE f s SUBSET t
9382   ==> (f continuous_on s <=>
9383    !u. closed_in (subtopology euclidean t) u
9384    ==> closed_in (subtopology euclidean s)
9385    {x | x IN s /\ f x IN u})``,
9386  REPEAT STRIP_TAC THEN FIRST_ASSUM(fn th =>
9387  ONCE_REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THEN
9388  EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``u:real->bool`` THEN
9389  FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THENL
9390  [REWRITE_TAC[closed_in], REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ]] THEN
9391  REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
9392  DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN
9393  ASM_SIMP_TAC std_ss [SUBSET_RESTRICT] THEN
9394  MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]);
9395
9396val CONTINUOUS_ON_CLOSED = store_thm ("CONTINUOUS_ON_CLOSED",
9397 ``!f:real->real s.
9398    f continuous_on s <=>
9399   !t. closed_in (subtopology euclidean (IMAGE f s)) t
9400    ==> closed_in (subtopology euclidean s) {x | x IN s /\ f(x) IN t}``,
9401  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CLOSED_GEN THEN
9402  REWRITE_TAC[SUBSET_REFL]);
9403
9404val CONTINUOUS_CLOSED_IN_PREIMAGE_GEN = store_thm ("CONTINUOUS_CLOSED_IN_PREIMAGE_GEN",
9405 ``!f:real->real s t u.
9406   f continuous_on s /\ IMAGE f s SUBSET t /\
9407   closed_in (subtopology euclidean t) u
9408   ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN u}``,
9409  METIS_TAC[CONTINUOUS_ON_CLOSED_GEN]);
9410
9411val CONTINUOUS_ON_IMP_CLOSED_IN = store_thm ("CONTINUOUS_ON_IMP_CLOSED_IN",
9412 ``!f:real->real s t. f continuous_on s /\
9413    closed_in (subtopology euclidean (IMAGE f s)) t
9414    ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``,
9415  METIS_TAC[CONTINUOUS_ON_CLOSED]);
9416
9417(* ------------------------------------------------------------------------- *)
9418(* Half-global and completely global cases. *)
9419(* ------------------------------------------------------------------------- *)
9420
9421val CONTINUOUS_OPEN_IN_PREIMAGE = store_thm ("CONTINUOUS_OPEN_IN_PREIMAGE",
9422 ``!f s t.
9423  f continuous_on s /\ open t
9424  ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``,
9425  REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE
9426  ``x IN s /\ f x IN t <=> x IN s /\ f x IN (t INTER IMAGE f s)``] THEN
9427  FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CONTINUOUS_ON_OPEN]) THEN
9428  ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN
9429  ASM_REWRITE_TAC[]);
9430
9431val CONTINUOUS_CLOSED_IN_PREIMAGE = store_thm ("CONTINUOUS_CLOSED_IN_PREIMAGE",
9432 ``!f s t.
9433   f continuous_on s /\ closed t
9434   ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``,
9435  REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE
9436   ``x IN s /\ f x IN t <=> x IN s /\ f x IN (t INTER IMAGE f s)``] THEN
9437  FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CONTINUOUS_ON_CLOSED]) THEN
9438  ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC CLOSED_IN_CLOSED_INTER THEN
9439  ASM_REWRITE_TAC[]);
9440
9441val CONTINUOUS_OPEN_PREIMAGE = store_thm ("CONTINUOUS_OPEN_PREIMAGE",
9442 ``!f:real->real s t.
9443   f continuous_on s /\ open s /\ open t
9444   ==> open {x | x IN s /\ f(x) IN t}``,
9445  REPEAT STRIP_TAC THEN
9446  UNDISCH_TAC ``f continuous_on s`` THEN GEN_REWR_TAC LAND_CONV [CONTINUOUS_ON_OPEN] THEN
9447  REWRITE_TAC [OPEN_IN_OPEN] THEN
9448  DISCH_THEN(MP_TAC o SPEC ``IMAGE (f:real->real) s INTER t``) THEN
9449  KNOW_TAC ``(?t'. open t' /\ (IMAGE (f:real->real) s INTER t = IMAGE f s INTER t'))`` THENL
9450  [EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC [],
9451  DISCH_TAC THEN ASM_REWRITE_TAC [] THEN STRIP_TAC THEN
9452  SUBGOAL_THEN ``{x | x IN s /\ (f:real->real) x IN t} =
9453                                            s INTER t'`` SUBST1_TAC THENL
9454  [ASM_SET_TAC [], ASM_MESON_TAC [OPEN_INTER]]]);
9455
9456val CONTINUOUS_CLOSED_PREIMAGE = store_thm ("CONTINUOUS_CLOSED_PREIMAGE",
9457 ``!f:real->real s t.
9458    f continuous_on s /\ closed s /\ closed t
9459    ==> closed {x | x IN s /\ f(x) IN t}``,
9460  REPEAT STRIP_TAC THEN UNDISCH_TAC ``f continuous_on s`` THEN
9461  GEN_REWR_TAC LAND_CONV [CONTINUOUS_ON_CLOSED] THEN
9462  REWRITE_TAC [CLOSED_IN_CLOSED] THEN
9463  DISCH_THEN(MP_TAC o SPEC ``IMAGE (f:real->real) s INTER t``) THEN
9464  KNOW_TAC ``(?t'. closed t' /\ (IMAGE (f:real->real) s INTER t = IMAGE f s INTER t'))`` THENL
9465  [EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC [],
9466  DISCH_TAC THEN ASM_REWRITE_TAC [] THEN STRIP_TAC THEN
9467  SUBGOAL_THEN ``{x | x IN s /\ (f:real->real) x IN t} =
9468                                            s INTER t'`` SUBST1_TAC THENL
9469  [ASM_SET_TAC [], ASM_MESON_TAC [CLOSED_INTER]]]);
9470
9471val CONTINUOUS_OPEN_PREIMAGE_UNIV = store_thm ("CONTINUOUS_OPEN_PREIMAGE_UNIV",
9472 ``!f:real->real s.
9473  (!x. f continuous (at x)) /\ open s ==> open {x | f(x) IN s}``,
9474  REPEAT STRIP_TAC THEN
9475  MP_TAC(SPECL [``f:real->real``, ``univ(:real)``, ``s:real->bool``]
9476   CONTINUOUS_OPEN_PREIMAGE) THEN
9477  ASM_SIMP_TAC std_ss [OPEN_UNIV, IN_UNIV, CONTINUOUS_AT_IMP_CONTINUOUS_ON]);
9478
9479val CONTINUOUS_CLOSED_PREIMAGE_UNIV = store_thm ("CONTINUOUS_CLOSED_PREIMAGE_UNIV",
9480 ``!f:real->real s.
9481  (!x. f continuous (at x)) /\ closed s ==> closed {x | f(x) IN s}``,
9482  REPEAT STRIP_TAC THEN
9483  MP_TAC(SPECL [``f:real->real``, ``univ(:real)``, ``s:real->bool``]
9484   CONTINUOUS_CLOSED_PREIMAGE) THEN
9485  ASM_SIMP_TAC std_ss [CLOSED_UNIV, IN_UNIV, CONTINUOUS_AT_IMP_CONTINUOUS_ON]);
9486
9487val CONTINUOUS_OPEN_IN_PREIMAGE_EQ = store_thm ("CONTINUOUS_OPEN_IN_PREIMAGE_EQ",
9488 ``!f:real->real s. f continuous_on s <=>
9489   !t. open t ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``,
9490  REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [CONTINUOUS_OPEN_IN_PREIMAGE] THEN
9491  REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN DISCH_TAC THEN
9492  X_GEN_TAC ``t:real->bool`` THEN GEN_REWR_TAC LAND_CONV [OPEN_IN_OPEN] THEN
9493  DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN
9494  FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN
9495  ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN SET_TAC[]);
9496
9497val CONTINUOUS_CLOSED_IN_PREIMAGE_EQ = store_thm ("CONTINUOUS_CLOSED_IN_PREIMAGE_EQ",
9498 ``!f:real->real s. f continuous_on s <=> !t. closed t
9499     ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}``,
9500  REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [CONTINUOUS_CLOSED_IN_PREIMAGE] THEN
9501  REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN DISCH_TAC THEN
9502  X_GEN_TAC ``t:real->bool`` THEN
9503  GEN_REWR_TAC LAND_CONV [CLOSED_IN_CLOSED] THEN
9504  DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN
9505  FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN
9506  ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN SET_TAC[]);
9507
9508(* ------------------------------------------------------------------------- *)
9509(* Linear functions are (uniformly) continuous on any set. *)
9510(* ------------------------------------------------------------------------- *)
9511
9512val LINEAR_LIM_0 = store_thm ("LINEAR_LIM_0",
9513 ``!f. linear f ==> (f --> 0) (at (0))``,
9514  REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_AT] THEN
9515  FIRST_X_ASSUM(MP_TAC o MATCH_MP LINEAR_BOUNDED_POS) THEN
9516  DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN
9517  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN EXISTS_TAC ``e / B:real`` THEN
9518  ASM_SIMP_TAC std_ss [REAL_LT_DIV] THEN REWRITE_TAC[dist, REAL_SUB_RZERO] THEN
9519  ASM_MESON_TAC[REAL_MUL_SYM, REAL_LET_TRANS, REAL_LT_RDIV_EQ]);
9520
9521val LINEAR_CONTINUOUS_AT = store_thm ("LINEAR_CONTINUOUS_AT",
9522 ``!f:real->real a. linear f ==> f continuous (at a)``,
9523  REPEAT STRIP_TAC THEN
9524  MP_TAC(ISPEC ``\x. (f:real->real) (a + x) - f(a)`` LINEAR_LIM_0) THEN
9525  KNOW_TAC ``linear (\x. f (a + x) - f a)`` THENL
9526  [POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [linear] THEN
9527   REPEAT STRIP_TAC THEN REAL_ARITH_TAC, ALL_TAC] THEN
9528  DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
9529  SIMP_TAC std_ss [GSYM LIM_NULL, CONTINUOUS_AT] THEN
9530  GEN_REWR_TAC RAND_CONV [LIM_AT_ZERO] THEN SIMP_TAC std_ss []);
9531
9532val LINEAR_CONTINUOUS_WITHIN = store_thm ("LINEAR_CONTINUOUS_WITHIN",
9533 ``!f:real->real s x. linear f ==> f continuous (at x within s)``,
9534  SIMP_TAC std_ss [CONTINUOUS_AT_WITHIN, LINEAR_CONTINUOUS_AT]);
9535
9536val LINEAR_CONTINUOUS_ON = store_thm ("LINEAR_CONTINUOUS_ON",
9537 ``!f:real->real s. linear f ==> f continuous_on s``,
9538  MESON_TAC[LINEAR_CONTINUOUS_AT, CONTINUOUS_AT_IMP_CONTINUOUS_ON]);
9539
9540val LINEAR_CONTINUOUS_COMPOSE = store_thm ("LINEAR_CONTINUOUS_COMPOSE",
9541 ``!net f:'a->real g:real->real.
9542   f continuous net /\ linear g ==> (\x. g(f x)) continuous net``,
9543  SIMP_TAC std_ss [continuous, LIM_LINEAR]);
9544
9545val LINEAR_CONTINUOUS_ON_COMPOSE = store_thm ("LINEAR_CONTINUOUS_ON_COMPOSE",
9546 ``!f:real->real g:real->real s.
9547    f continuous_on s /\ linear g ==> (\x. g(f x)) continuous_on s``,
9548  SIMP_TAC std_ss[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN,
9549   LINEAR_CONTINUOUS_COMPOSE]);
9550
9551val CONTINUOUS_COMPONENT_COMPOSE = store_thm ("CONTINUOUS_COMPONENT_COMPOSE",
9552 ``!net f:'a->real i. f continuous net ==> (\x. f x) continuous net``,
9553  REPEAT GEN_TAC THEN
9554  SUBGOAL_THEN ``linear(\x:real. x)`` MP_TAC THENL
9555  [REWRITE_TAC[LINEAR_ID], REWRITE_TAC[GSYM IMP_CONJ_ALT]] THEN
9556  METIS_TAC [LINEAR_CONTINUOUS_COMPOSE]);
9557
9558val CONTINUOUS_ON_COMPONENT_COMPOSE = store_thm ("CONTINUOUS_ON_COMPONENT_COMPOSE",
9559 ``!f:real->real s. f continuous_on s
9560    ==> (\x. f x) continuous_on s``,
9561  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN,
9562                   CONTINUOUS_COMPONENT_COMPOSE]);
9563
9564(* ------------------------------------------------------------------------- *)
9565(* Also bilinear functions, in composition form. *)
9566(* ------------------------------------------------------------------------- *)
9567
9568val BILINEAR_CONTINUOUS_COMPOSE = store_thm ("BILINEAR_CONTINUOUS_COMPOSE",
9569 ``!net f:'a->real g:'a->real h:real->real->real.
9570   f continuous net /\ g continuous net /\ bilinear h
9571   ==> (\x. h (f x) (g x)) continuous net``,
9572  SIMP_TAC std_ss [continuous, LIM_BILINEAR]);
9573
9574val BILINEAR_CONTINUOUS_ON_COMPOSE = store_thm ("BILINEAR_CONTINUOUS_ON_COMPOSE",
9575 ``!f g h s. f continuous_on s /\ g continuous_on s /\ bilinear h
9576   ==> (\x. h (f x) (g x)) continuous_on s``,
9577  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN,
9578                   BILINEAR_CONTINUOUS_COMPOSE]);
9579
9580val BILINEAR_DOT = store_thm ("BILINEAR_DOT",
9581 ``bilinear (\x y:real. (x * y))``,
9582SIMP_TAC std_ss [bilinear, linear] THEN REAL_ARITH_TAC);
9583
9584val CONTINUOUS_DOT2 = store_thm ("CONTINUOUS_DOT2",
9585 ``!net f g:'a->real.
9586   f continuous net /\ g continuous net
9587   ==> (\x. f x * g x) continuous net``,
9588  REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE
9589   [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`]
9590  BILINEAR_CONTINUOUS_COMPOSE) BILINEAR_DOT)) THEN BETA_TAC THEN REWRITE_TAC[]);
9591
9592val CONTINUOUS_ON_DOT2 = store_thm ("CONTINUOUS_ON_DOT2",
9593 ``!f:real->real g s.
9594    f continuous_on s /\ g continuous_on s
9595    ==> (\x. f x * g x) continuous_on s``,
9596  REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE
9597  [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`]
9598  BILINEAR_CONTINUOUS_ON_COMPOSE) BILINEAR_DOT)) THEN BETA_TAC THEN REWRITE_TAC[]);
9599
9600(* ------------------------------------------------------------------------- *)
9601(* Preservation of compactness and connectedness under continuous function. *)
9602(* ------------------------------------------------------------------------- *)
9603
9604val COMPACT_CONTINUOUS_IMAGE = store_thm ("COMPACT_CONTINUOUS_IMAGE",
9605 ``!f:real->real s.
9606    f continuous_on s /\ compact s ==> compact(IMAGE f s)``,
9607  REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on, compact] THEN
9608  STRIP_TAC THEN X_GEN_TAC ``y:num->real`` THEN
9609  SIMP_TAC std_ss [IN_IMAGE, SKOLEM_THM, FORALL_AND_THM] THEN
9610  DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` STRIP_ASSUME_TAC) THEN
9611  FIRST_X_ASSUM(MP_TAC o SPEC ``x:num->real``) THEN ASM_REWRITE_TAC[] THEN
9612  KNOW_TAC ``((?(l :real) (r :num -> num).
9613              l IN s /\ (!(m :num) (n :num). m < n ==> r m < r n) /\
9614                         ((x :num -> real) o r --> l) sequentially) ==>
9615               ?(l :real) (r :num -> num).
9616              (?(x :real). (l = f x) /\ x IN s) /\
9617                        (!(m :num) (n :num). m < n ==> r m < r n) /\
9618                         ((y :num -> real) o r --> l) sequentially) =
9619             ((?(r :num -> num) (l :real).
9620              l IN s /\ (!(m :num) (n :num). m < n ==> r m < r n) /\
9621                         ((x :num -> real) o r --> l) sequentially) ==>
9622               ?(r :num -> num) (l :real).
9623              (?(x :real). (l = f x) /\ x IN s) /\
9624                        (!(m :num) (n :num). m < n ==> r m < r n) /\
9625                         ((y :num -> real) o r --> l) sequentially)`` THENL
9626  [METIS_TAC [SWAP_EXISTS_THM], DISC_RW_KILL] THEN
9627  STRIP_TAC THEN EXISTS_TAC ``r:num->num`` THEN
9628  EXISTS_TAC ``(f:real->real) l`` THEN ASM_REWRITE_TAC[] THEN
9629  CONJ_TAC THENL [ASM_MESON_TAC[], ALL_TAC] THEN
9630  REWRITE_TAC[LIM_SEQUENTIALLY] THEN
9631  FIRST_X_ASSUM(MP_TAC o SPEC ``l:real``) THEN
9632  ASM_REWRITE_TAC[] THEN DISCH_TAC THEN GEN_TAC THEN
9633  POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN
9634  DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
9635  DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
9636  UNDISCH_TAC `` ((x :num -> real) o (r :num -> num) --> l) sequentially`` THEN
9637  GEN_REWR_TAC LAND_CONV [LIM_SEQUENTIALLY] THEN
9638  DISCH_THEN(MP_TAC o SPEC ``d:real``) THEN ASM_SIMP_TAC std_ss [o_THM] THEN
9639  ASM_MESON_TAC[]);
9640
9641val COMPACT_TRANSLATION = store_thm ("COMPACT_TRANSLATION",
9642 ``!s a:real. compact s ==> compact (IMAGE (\x. a + x) s)``,
9643  SIMP_TAC std_ss [COMPACT_CONTINUOUS_IMAGE, CONTINUOUS_ON_ADD,
9644   CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID]);
9645
9646val COMPACT_TRANSLATION_EQ = store_thm ("COMPACT_TRANSLATION_EQ",
9647 ``!a s. compact (IMAGE (\x:real. a + x) s) <=> compact s``,
9648  REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[COMPACT_TRANSLATION] THEN
9649  DISCH_THEN(MP_TAC o ISPEC ``-a:real`` o MATCH_MP COMPACT_TRANSLATION) THEN
9650  SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, o_DEF, IMAGE_ID,
9651   REAL_ARITH ``-a + (a + x:real) = x``]);
9652
9653val COMPACT_LINEAR_IMAGE = store_thm ("COMPACT_LINEAR_IMAGE",
9654 ``!f:real->real s. compact s /\ linear f ==> compact(IMAGE f s)``,
9655  SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON, COMPACT_CONTINUOUS_IMAGE]);
9656
9657val CONNECTED_CONTINUOUS_IMAGE = store_thm ("CONNECTED_CONTINUOUS_IMAGE",
9658 ``!f:real->real s.
9659   f continuous_on s /\ connected s ==> connected(IMAGE f s)``,
9660  REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN
9661  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
9662  ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN
9663  SIMP_TAC std_ss [CONNECTED_CLOPEN, NOT_FORALL_THM, NOT_IMP, DE_MORGAN_THM] THEN
9664  SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
9665  DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN
9666  FIRST_X_ASSUM(fn th => MP_TAC(SPEC ``t:real->bool`` th) THEN
9667   MP_TAC(SPEC ``IMAGE (f:real->real) s DIFF t`` th)) THEN
9668  ASM_REWRITE_TAC[] THEN
9669  SUBGOAL_THEN ``{x | x IN s /\ (f:real->real) x IN IMAGE f s DIFF t} =
9670   s DIFF {x | x IN s /\ f x IN t}`` SUBST1_TAC THENL
9671  [UNDISCH_TAC ``t SUBSET IMAGE (f:real->real) s`` THEN
9672   SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_DIFF, GSPECIFICATION, SUBSET_DEF] THEN
9673   MESON_TAC[],
9674   REPEAT STRIP_TAC THEN
9675   EXISTS_TAC ``{x | x IN s /\ (f:real->real) x IN t}`` THEN
9676   ASM_REWRITE_TAC[] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
9677   SIMP_TAC std_ss [IN_IMAGE, SUBSET_DEF, GSPECIFICATION, NOT_IN_EMPTY, EXTENSION] THEN
9678   MESON_TAC[]]);
9679
9680val CONNECTED_TRANSLATION = store_thm ("CONNECTED_TRANSLATION",
9681 ``!a s. connected s ==> connected (IMAGE (\x:real. a + x) s)``,
9682  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN
9683  ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ADD, CONTINUOUS_ON_ID, CONTINUOUS_ON_CONST]);
9684
9685val CONNECTED_TRANSLATION_EQ = store_thm ("CONNECTED_TRANSLATION_EQ",
9686 ``!a s. connected (IMAGE (\x:real. a + x) s) <=> connected s``,
9687  REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[CONNECTED_TRANSLATION] THEN
9688  DISCH_THEN(MP_TAC o ISPEC ``-a:real`` o MATCH_MP CONNECTED_TRANSLATION) THEN
9689  SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, o_DEF, IMAGE_ID,
9690   REAL_ARITH ``-a + (a + x:real) = x``]);
9691
9692val CONNECTED_LINEAR_IMAGE = store_thm ("CONNECTED_LINEAR_IMAGE",
9693 ``!f:real->real s. connected s /\ linear f ==> connected(IMAGE f s)``,
9694  SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON, CONNECTED_CONTINUOUS_IMAGE]);
9695
9696(* ------------------------------------------------------------------------- *)
9697(* Quotient maps are occasionally useful.                                    *)
9698(* ------------------------------------------------------------------------- *)
9699
9700val QUASICOMPACT_OPEN_CLOSED = store_thm ("QUASICOMPACT_OPEN_CLOSED",
9701 ``!f:real->real s t.
9702   IMAGE f s SUBSET t
9703   ==> ((!u. u SUBSET t
9704    ==> (open_in (subtopology euclidean s)
9705        {x | x IN s /\ f x IN u}
9706      ==> open_in (subtopology euclidean t) u)) <=>
9707          (!u. u SUBSET t
9708        ==> (closed_in (subtopology euclidean s)
9709            {x | x IN s /\ f x IN u}
9710           ==> closed_in (subtopology euclidean t) u)))``,
9711  SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
9712  REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
9713  X_GEN_TAC ``u:real->bool`` THEN
9714  DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THEN
9715  ASM_SIMP_TAC std_ss [SET_RULE ``u SUBSET t ==> (t DIFF (t DIFF u) = u)``] THEN
9716  REWRITE_TAC [DIFF_SUBSET] THEN REPEAT STRIP_TAC THEN
9717  FIRST_X_ASSUM MATCH_MP_TAC THEN SIMP_TAC std_ss [SUBSET_RESTRICT] THEN
9718  FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[]
9719   ``open_in top x ==> (x = y) ==> open_in top y``)) THEN
9720  ASM_SET_TAC[]);
9721
9722val QUOTIENT_MAP_IMP_CONTINUOUS_OPEN = store_thm ("QUOTIENT_MAP_IMP_CONTINUOUS_OPEN",
9723 ``!f:real->real s t.
9724    IMAGE f s SUBSET t /\
9725    (!u. u SUBSET t
9726    ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
9727     open_in (subtopology euclidean t) u))
9728     ==> f continuous_on s``,
9729  METIS_TAC[OPEN_IN_IMP_SUBSET, CONTINUOUS_ON_OPEN_GEN]);
9730
9731val QUOTIENT_MAP_IMP_CONTINUOUS_CLOSED = store_thm ("QUOTIENT_MAP_IMP_CONTINUOUS_CLOSED",
9732 ``!f:real->real s t.
9733   IMAGE f s SUBSET t /\
9734   (!u. u SUBSET t
9735   ==> (closed_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
9736     closed_in (subtopology euclidean t) u))
9737     ==> f continuous_on s``,
9738  METIS_TAC[CLOSED_IN_IMP_SUBSET, CONTINUOUS_ON_CLOSED_GEN]);
9739
9740val OPEN_MAP_IMP_QUOTIENT_MAP = store_thm ("OPEN_MAP_IMP_QUOTIENT_MAP",
9741 ``!f:real->real s. f continuous_on s /\
9742  (!t. open_in (subtopology euclidean s) t
9743  ==> open_in (subtopology euclidean (IMAGE f s)) (IMAGE f t))
9744    ==> !t. t SUBSET IMAGE f s
9745      ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=>
9746           open_in (subtopology euclidean (IMAGE f s)) t)``,
9747  REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
9748  [SUBGOAL_THEN
9749   ``(t = IMAGE f {x | x IN s /\ (f:real->real) x IN t})``
9750    SUBST1_TAC THENL [ASM_SET_TAC[], ASM_SIMP_TAC std_ss []],
9751  UNDISCH_TAC ``f continuous_on s`` THEN GEN_REWR_TAC LAND_CONV [CONTINUOUS_ON_OPEN] THEN
9752  ASM_SIMP_TAC std_ss []]);
9753
9754val CLOSED_MAP_IMP_QUOTIENT_MAP = store_thm ("CLOSED_MAP_IMP_QUOTIENT_MAP",
9755 ``!f:real->real s. f continuous_on s /\
9756  (!t. closed_in (subtopology euclidean s) t
9757  ==> closed_in (subtopology euclidean (IMAGE f s)) (IMAGE f t))
9758   ==> !t. t SUBSET IMAGE f s
9759     ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=>
9760          open_in (subtopology euclidean (IMAGE f s)) t)``,
9761  REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
9762  [FIRST_X_ASSUM(MP_TAC o SPEC
9763    ``s DIFF {x | x IN s /\ (f:real->real) x IN t}``) THEN
9764   KNOW_TAC ``closed_in (subtopology euclidean (s :real -> bool))
9765   (s DIFF {x | x IN s /\ (f :real -> real) x IN (t :real -> bool)})`` THENL
9766  [MATCH_MP_TAC CLOSED_IN_DIFF THEN
9767   ASM_SIMP_TAC std_ss [CLOSED_IN_SUBTOPOLOGY_REFL,
9768    TOPSPACE_EUCLIDEAN, SUBSET_UNIV],
9769   DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
9770   SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
9771   DISCH_THEN(MP_TAC o CONJUNCT2) THEN MATCH_MP_TAC EQ_IMPLIES THEN
9772   AP_TERM_TAC THEN ASM_SET_TAC[]],
9773  UNDISCH_TAC ``f continuous_on s`` THEN GEN_REWR_TAC LAND_CONV [CONTINUOUS_ON_OPEN] THEN
9774  ASM_SIMP_TAC std_ss []]);
9775
9776val CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP = store_thm ("CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP",
9777 ``!f:real->real g s t.
9778    f continuous_on s /\ IMAGE f s SUBSET t /\
9779    g continuous_on t /\ IMAGE g t SUBSET s /\
9780  (!y. y IN t ==> (f(g y) = y))
9781   ==> (!u. u SUBSET t
9782    ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
9783         open_in (subtopology euclidean t) u))``,
9784  REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN REPEAT STRIP_TAC THEN EQ_TAC THENL
9785  [DISCH_TAC THEN FIRST_ASSUM(MP_TAC o SPEC ``(IMAGE (g:real->real) t) INTER
9786                              {x | x IN s /\ (f:real->real) x IN u}``) THEN
9787   SUBGOAL_THEN ``open_in (subtopology euclidean (IMAGE (g:real->real) t))
9788               (IMAGE g t INTER {x | x IN s /\ (f:real->real) x IN u})``
9789               (fn th => REWRITE_TAC[th]) THENL
9790   [POP_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_OPEN]) THEN
9791    SIMP_TAC std_ss [OPEN_IN_OPEN] THEN ASM_SET_TAC[],
9792    MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]],
9793   DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
9794   SUBGOAL_THEN ``IMAGE (f:real->real) s = t``
9795    (fn th => ASM_REWRITE_TAC[th]) THEN
9796   ASM_SET_TAC[]]);
9797
9798val CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP = store_thm ("CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP",
9799 ``!f:real->real g s.
9800    f continuous_on s /\ g continuous_on (IMAGE f s) /\
9801    (!x. x IN s ==> (g(f x) = x))
9802    ==> (!u. u SUBSET (IMAGE f s)
9803      ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
9804           open_in (subtopology euclidean (IMAGE f s)) u))``,
9805  REPEAT GEN_TAC THEN STRIP_TAC THEN
9806  MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN
9807  EXISTS_TAC ``g:real->real`` THEN
9808  ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]);
9809
9810val QUOTIENT_MAP_OPEN_CLOSED = store_thm ("QUOTIENT_MAP_OPEN_CLOSED",
9811 ``!f:real->real s t.
9812    IMAGE f s SUBSET t
9813    ==> ((!u. u SUBSET t
9814      ==> (open_in (subtopology euclidean s)
9815          {x | x IN s /\ f x IN u} <=>
9816          open_in (subtopology euclidean t) u)) <=>
9817          (!u. u SUBSET t
9818          ==> (closed_in (subtopology euclidean s)
9819              {x | x IN s /\ f x IN u} <=>
9820              closed_in (subtopology euclidean t) u)))``,
9821  SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
9822  REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
9823  X_GEN_TAC ``u:real->bool`` THEN
9824  DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THEN
9825  ASM_SIMP_TAC std_ss [SET_RULE ``u SUBSET t ==> (t DIFF (t DIFF u) = u)``] THEN
9826  REWRITE_TAC [DIFF_SUBSET] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
9827  SIMP_TAC std_ss [SUBSET_RESTRICT] THEN AP_TERM_TAC THEN ASM_SET_TAC[]);
9828
9829val CONTINUOUS_ON_COMPOSE_QUOTIENT = store_thm ("CONTINUOUS_ON_COMPOSE_QUOTIENT",
9830 ``!f:real->real g:real->real s t u.
9831   IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\
9832   (!v. v SUBSET t
9833   ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN v} <=>
9834        open_in (subtopology euclidean t) v)) /\
9835       (g o f) continuous_on s
9836         ==> g continuous_on t``,
9837  REPEAT GEN_TAC THEN
9838  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
9839  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
9840  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
9841  FIRST_ASSUM(fn th => REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THEN
9842  SUBGOAL_THEN
9843   ``IMAGE ((g:real->real) o (f:real->real)) s SUBSET u``
9844   (fn th => REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THENL
9845  [REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[], DISCH_TAC] THEN
9846  X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN
9847  FIRST_X_ASSUM(MP_TAC o SPEC ``v:real->bool``) THEN
9848  ASM_REWRITE_TAC[o_THM] THEN DISCH_TAC THEN
9849  FIRST_X_ASSUM(MP_TAC o SPEC ``{x | x IN t /\ (g:real->real) x IN v}``) THEN
9850  ASM_SIMP_TAC std_ss [SUBSET_RESTRICT] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
9851  FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[]
9852   ``open_in top s ==> (s = t) ==> open_in top t``)) THEN
9853  ASM_SET_TAC[]);
9854
9855val FUNCTION_FACTORS_LEFT_GEN = store_thm ("FUNCTION_FACTORS_LEFT_GEN",
9856 ``!P f g. (!x y. P x /\ P y /\ (g x = g y) ==> (f x = f y)) <=>
9857           (?h. !x. P x ==> (f(x) = h(g x)))``,
9858  ONCE_REWRITE_TAC[MESON[]
9859   ``(!x. P x ==> (f(x) = g(k x))) <=> (!y x. P x /\ (y = k x) ==> (f x = g y))``] THEN
9860  SIMP_TAC std_ss [GSYM SKOLEM_THM] THEN MESON_TAC[]);
9861
9862val LIFT_TO_QUOTIENT_SPACE = store_thm ("LIFT_TO_QUOTIENT_SPACE",
9863 ``!f:real->real h:real->real s t u.
9864  (IMAGE f s = t) /\ (!v. v SUBSET t
9865  ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN v} <=>
9866       open_in (subtopology euclidean t) v)) /\
9867       h continuous_on s /\ (IMAGE h s = u) /\
9868      (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (h x = h y))
9869     ==> ?g. g continuous_on t /\ (IMAGE g t = u) /\
9870         !x. x IN s ==> (h(x) = g(f x))``,
9871  REPEAT GEN_TAC THEN
9872  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
9873  SIMP_TAC std_ss [FUNCTION_FACTORS_LEFT_GEN] THEN
9874  DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN
9875  EXISTS_TAC ``g:real->real`` THEN
9876  CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
9877  MATCH_MP_TAC CONTINUOUS_ON_COMPOSE_QUOTIENT THEN MAP_EVERY EXISTS_TAC
9878   [``f:real->real``, ``s:real->bool``, ``u:real->bool``] THEN
9879  ASM_SIMP_TAC std_ss [SUBSET_REFL] THEN CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
9880  FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
9881   CONTINUOUS_ON_EQ)) THEN ASM_SIMP_TAC std_ss [o_THM]);
9882
9883val QUOTIENT_MAP_COMPOSE = store_thm ("QUOTIENT_MAP_COMPOSE",
9884 ``!f:real->real g:real->real s t u.
9885  IMAGE f s SUBSET t /\
9886  (!v. v SUBSET t
9887  ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN v} <=>
9888      open_in (subtopology euclidean t) v)) /\
9889      (!v. v SUBSET u
9890      ==> (open_in (subtopology euclidean t) {x | x IN t /\ g x IN v} <=>
9891           open_in (subtopology euclidean u) v))
9892          ==> !v. v SUBSET u
9893            ==> (open_in (subtopology euclidean s)
9894                {x | x IN s /\ (g o f) x IN v} <=>
9895                 open_in (subtopology euclidean u) v)``,
9896  REPEAT STRIP_TAC THEN SIMP_TAC std_ss [o_THM] THEN
9897  SUBGOAL_THEN
9898   ``{x | x IN s /\ (g:real->real) ((f:real->real) x) IN v} =
9899     {x | x IN s /\ f x IN {x | x IN t /\ g x IN v}}``
9900   SUBST1_TAC THENL [ASM_SET_TAC[], ASM_SIMP_TAC std_ss [SUBSET_RESTRICT]]);
9901
9902val QUOTIENT_MAP_FROM_COMPOSITION = store_thm ("QUOTIENT_MAP_FROM_COMPOSITION",
9903 ``!f:real->real g:real->real s t u.
9904    f continuous_on s /\ IMAGE f s SUBSET t /\
9905    g continuous_on t /\ IMAGE g t SUBSET u /\
9906    (!v. v SUBSET u
9907    ==> (open_in (subtopology euclidean s)
9908         {x | x IN s /\ (g o f) x IN v} <=>
9909         open_in (subtopology euclidean u) v))
9910         ==> !v. v SUBSET u
9911           ==> (open_in (subtopology euclidean t)
9912                {x | x IN t /\ g x IN v} <=>
9913                open_in (subtopology euclidean u) v)``,
9914  REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL
9915  [FIRST_X_ASSUM(MP_TAC o SPEC ``v:real->bool``) THEN
9916   ASM_SIMP_TAC std_ss [o_THM] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
9917   SUBGOAL_THEN
9918    ``{x | x IN s /\ (g:real->real) ((f:real->real) x) IN v} =
9919      {x | x IN s /\ f x IN {x | x IN t /\ g x IN v}}``
9920     SUBST1_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
9921   MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN
9922   EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[],
9923   MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN
9924   EXISTS_TAC ``u:real->bool`` THEN ASM_REWRITE_TAC[]]);
9925
9926val QUOTIENT_MAP_FROM_SUBSET = store_thm ("QUOTIENT_MAP_FROM_SUBSET",
9927 ``!f:real->real s t u.
9928    f continuous_on t /\ IMAGE f t SUBSET u /\
9929    s SUBSET t /\ (IMAGE f s = u) /\
9930    (!v. v SUBSET u
9931    ==> (open_in (subtopology euclidean s)
9932         {x | x IN s /\ f x IN v} <=>
9933         open_in (subtopology euclidean u) v))
9934         ==> !v. v SUBSET u
9935           ==> (open_in (subtopology euclidean t)
9936               {x | x IN t /\ f x IN v} <=>
9937                open_in (subtopology euclidean u) v)``,
9938  REPEAT GEN_TAC THEN STRIP_TAC THEN
9939  MATCH_MP_TAC QUOTIENT_MAP_FROM_COMPOSITION THEN
9940  MAP_EVERY EXISTS_TAC [``\x:real. x``, ``s:real->bool``] THEN
9941  ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ID, IMAGE_ID, o_THM]);
9942
9943val QUOTIENT_MAP_RESTRICT = store_thm ("QUOTIENT_MAP_RESTRICT",
9944 ``!f:real->real s t c.
9945    IMAGE f s SUBSET t /\
9946   (!u. u SUBSET t
9947   ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
9948        open_in (subtopology euclidean t) u)) /\
9949       (open_in (subtopology euclidean t) c \/
9950      closed_in (subtopology euclidean t) c)
9951      ==> !u. u SUBSET c
9952        ==> (open_in (subtopology euclidean {x | x IN s /\ f x IN c})
9953             {x | x IN {x | x IN s /\ f x IN c} /\ f x IN u} <=>
9954             open_in (subtopology euclidean c) u)``,
9955  REPEAT GEN_TAC THEN
9956  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
9957  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
9958  DISCH_THEN(fn th => MP_TAC th THEN MP_TAC (MATCH_MP
9959   (REWRITE_RULE[IMP_CONJ_ALT] QUOTIENT_MAP_IMP_CONTINUOUS_OPEN) th)) THEN
9960  ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
9961  SUBGOAL_THEN ``IMAGE (f:real->real) {x | x IN s /\ f x IN c} SUBSET c``
9962   ASSUME_TAC THENL [SET_TAC[], ALL_TAC] THEN
9963  FIRST_X_ASSUM DISJ_CASES_TAC THENL
9964  [FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET),
9965   ASM_SIMP_TAC std_ss [QUOTIENT_MAP_OPEN_CLOSED] THEN
9966   FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET)] THEN
9967  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `u:real->bool`) THEN
9968  DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN
9969  (KNOW_TAC ``(u:real->bool) SUBSET t`` THENL
9970   [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []]) THEN
9971  (MATCH_MP_TAC EQ_IMPLIES THEN BINOP_TAC THENL
9972  [MATCH_MP_TAC(MESON[] ``(t = s) /\ (P s <=> Q s) ==> (P s <=> Q t)``) THEN
9973   CONJ_TAC THENL [ASM_SET_TAC[], SIMP_TAC std_ss [GSPECIFICATION]], ALL_TAC]) THEN
9974  (EQ_TAC THENL
9975  [MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] OPEN_IN_SUBSET_TRANS) ORELSE
9976   MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] CLOSED_IN_SUBSET_TRANS),
9977   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] OPEN_IN_TRANS) ORELSE
9978   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CLOSED_IN_TRANS)]) THEN
9979  (MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN ORELSE
9980   MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN ORELSE ASM_SIMP_TAC std_ss []) THEN
9981  ASM_SET_TAC[]);
9982
9983val CONNECTED_MONOTONE_QUOTIENT_PREIMAGE = store_thm ("CONNECTED_MONOTONE_QUOTIENT_PREIMAGE",
9984 ``!f:real->real s t.
9985    f continuous_on s /\ (IMAGE f s = t) /\
9986   (!u. u SUBSET t
9987   ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
9988        open_in (subtopology euclidean t) u)) /\
9989       (!y. y IN t ==> connected {x | x IN s /\ (f x = y)}) /\
9990        connected t ==> connected s``,
9991  REPEAT STRIP_TAC THEN SIMP_TAC std_ss [connected, NOT_EXISTS_THM] THEN
9992  MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN CCONTR_TAC THEN
9993  FULL_SIMP_TAC std_ss [] THEN UNDISCH_TAC ``connected(t:real->bool)`` THEN
9994  SIMP_TAC std_ss [CONNECTED_OPEN_IN] THEN
9995  MAP_EVERY EXISTS_TAC
9996  [``IMAGE (f:real->real) (s INTER u)``,
9997   ``IMAGE (f:real->real) (s INTER v)``] THEN
9998  ASM_REWRITE_TAC[IMAGE_EQ_EMPTY] THEN
9999  SUBGOAL_THEN
10000   ``IMAGE (f:real->real) (s INTER u) INTER IMAGE f (s INTER v) = {}``
10001   ASSUME_TAC THENL
10002  [REWRITE_TAC[EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN
10003   X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN
10004   FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN
10005   KNOW_TAC ``y IN t:real->bool`` THENL
10006   [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN REWRITE_TAC[connected]] THEN
10007  MAP_EVERY EXISTS_TAC [``u:real->bool``, ``v:real->bool``] THEN
10008  ASM_SET_TAC[], ALL_TAC] THEN
10009  ONCE_REWRITE_TAC[CONJ_ASSOC] THEN
10010  CONJ_TAC THENL [CONJ_TAC, ASM_SET_TAC[]] THEN
10011  FIRST_X_ASSUM(fn th =>
10012   W(MP_TAC o PART_MATCH (rand o rand) th o snd)) THENL
10013  [KNOW_TAC ``IMAGE (f:real->real) (s INTER u) SUBSET t:real->bool`` THENL
10014   [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_THEN(SUBST1_TAC o SYM)],
10015   KNOW_TAC ``IMAGE (f:real->real) (s INTER v) SUBSET t:real->bool`` THENL
10016   [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_THEN(SUBST1_TAC o SYM)]] THEN
10017  MATCH_MP_TAC(MESON[]
10018   ``({x | x IN s /\ f x IN IMAGE f u} = u) /\ open_in top u
10019       ==> open_in top {x | x IN s /\ f x IN IMAGE f u}``) THEN
10020  ASM_SIMP_TAC std_ss [OPEN_IN_OPEN_INTER] THEN ASM_SET_TAC[]);
10021
10022val CONNECTED_MONOTONE_QUOTIENT_PREIMAGE_GEN = store_thm ("CONNECTED_MONOTONE_QUOTIENT_PREIMAGE_GEN",
10023 ``!f:real->real s t c.
10024   (IMAGE f s = t) /\ (!u. u SUBSET t
10025   ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
10026        open_in (subtopology euclidean t) u)) /\
10027       (!y. y IN t ==> connected {x | x IN s /\ (f x = y)}) /\
10028       (open_in (subtopology euclidean t) c \/
10029      closed_in (subtopology euclidean t) c) /\
10030      connected c ==> connected {x | x IN s /\ f x IN c}``,
10031  REPEAT GEN_TAC THEN
10032  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
10033  MATCH_MP_TAC(ONCE_REWRITE_RULE[CONJ_EQ_IMP]
10034   (REWRITE_RULE[CONJ_ASSOC] CONNECTED_MONOTONE_QUOTIENT_PREIMAGE)) THEN
10035  SUBGOAL_THEN ``(c:real->bool) SUBSET t`` ASSUME_TAC THENL
10036  [ASM_MESON_TAC[OPEN_IN_IMP_SUBSET, CLOSED_IN_IMP_SUBSET], ALL_TAC] THEN
10037  EXISTS_TAC ``f:real->real`` THEN REPEAT CONJ_TAC THENL
10038  [FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
10039    QUOTIENT_MAP_IMP_CONTINUOUS_OPEN)) THEN
10040   ASM_REWRITE_TAC[SUBSET_REFL] THEN
10041  MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET) THEN
10042  SIMP_TAC std_ss [SUBSET_RESTRICT],
10043  ASM_SET_TAC[],
10044  MATCH_MP_TAC QUOTIENT_MAP_RESTRICT THEN
10045  METIS_TAC[SUBSET_REFL],
10046  X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN
10047  FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN
10048  KNOW_TAC ``y IN t:real->bool`` THENL
10049  [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN MATCH_MP_TAC EQ_IMPLIES] THEN
10050  AP_TERM_TAC THEN ASM_SET_TAC[]]);
10051
10052(* ------------------------------------------------------------------------- *)
10053(* More properties of open and closed maps.                                  *)
10054(* ------------------------------------------------------------------------- *)
10055
10056val CLOSED_MAP_CLOSURES = store_thm ("CLOSED_MAP_CLOSURES",
10057 ``!f:real->real.
10058  (!s. closed s ==> closed(IMAGE f s)) <=>
10059  (!s. closure(IMAGE f s) SUBSET IMAGE f (closure s))``,
10060  GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
10061  [MATCH_MP_TAC CLOSURE_MINIMAL THEN
10062   ASM_SIMP_TAC std_ss [CLOSED_CLOSURE, CLOSURE_SUBSET, IMAGE_SUBSET],
10063   REWRITE_TAC[GSYM CLOSURE_SUBSET_EQ] THEN ASM_MESON_TAC[CLOSURE_CLOSED]]);
10064
10065val OPEN_MAP_INTERIORS = store_thm ("OPEN_MAP_INTERIORS",
10066 ``!f:real->real.
10067  (!s. open s ==> open(IMAGE f s)) <=>
10068  (!s. IMAGE f (interior s) SUBSET interior(IMAGE f s))``,
10069  GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
10070  [MATCH_MP_TAC INTERIOR_MAXIMAL THEN
10071  ASM_SIMP_TAC std_ss [OPEN_INTERIOR, INTERIOR_SUBSET, IMAGE_SUBSET],
10072  REWRITE_TAC[GSYM SUBSET_INTERIOR_EQ] THEN ASM_MESON_TAC[INTERIOR_OPEN]]);
10073
10074val OPEN_MAP_RESTRICT = store_thm ("OPEN_MAP_RESTRICT",
10075 ``!f:real->real s t t'.
10076  (!u. open_in (subtopology euclidean s) u
10077  ==> open_in (subtopology euclidean t) (IMAGE f u)) /\
10078      t' SUBSET t
10079     ==> !u. open_in (subtopology euclidean {x | x IN s /\ f x IN t'}) u
10080         ==> open_in (subtopology euclidean t') (IMAGE f u)``,
10081  REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN
10082  SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, CONJ_EQ_IMP] THEN
10083  REPEAT DISCH_TAC THEN X_GEN_TAC ``c:real->bool`` THEN
10084  DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``c:real->bool``) THEN
10085ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]);
10086
10087val CLOSED_MAP_RESTRICT = store_thm ("CLOSED_MAP_RESTRICT",
10088 ``!f:real->real s t t'.
10089  (!u. closed_in (subtopology euclidean s) u
10090  ==> closed_in (subtopology euclidean t) (IMAGE f u)) /\
10091      t' SUBSET t
10092     ==> !u. closed_in (subtopology euclidean {x | x IN s /\ f x IN t'}) u
10093     ==> closed_in (subtopology euclidean t') (IMAGE f u)``,
10094  REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN
10095  SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, CONJ_EQ_IMP] THEN
10096  REPEAT DISCH_TAC THEN X_GEN_TAC ``c:real->bool`` THEN
10097  DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``c:real->bool``) THEN
10098  ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]);
10099
10100val QUOTIENT_MAP_OPEN_MAP_EQ = store_thm ("QUOTIENT_MAP_OPEN_MAP_EQ",
10101 ``!f:real->real s t.
10102  IMAGE f s SUBSET t /\
10103  (!u. u SUBSET t
10104  ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
10105       open_in (subtopology euclidean t) u))
10106      ==> ((!k. open_in (subtopology euclidean s) k
10107            ==> open_in (subtopology euclidean t) (IMAGE f k)) <=>
10108               (!k. open_in (subtopology euclidean s) k
10109                ==> open_in (subtopology euclidean s)
10110                    {x | x IN s /\ f x IN IMAGE f k}))``,
10111  REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
10112  X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN
10113  FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
10114  UNDISCH_TAC ``!u. u SUBSET t ==>
10115        (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
10116         open_in (subtopology euclidean t) u)`` THEN
10117  DISCH_TAC THEN
10118  FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (f:real->real) k``) THEN
10119  ASM_SIMP_TAC std_ss [IMAGE_SUBSET] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_SET_TAC[]);
10120
10121val QUOTIENT_MAP_CLOSED_MAP_EQ = store_thm ("QUOTIENT_MAP_CLOSED_MAP_EQ",
10122 ``!f:real->real s t.
10123   IMAGE f s SUBSET t /\
10124   (!u. u SUBSET t
10125   ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
10126        open_in (subtopology euclidean t) u))
10127       ==> ((!k. closed_in (subtopology euclidean s) k
10128         ==> closed_in (subtopology euclidean t) (IMAGE f k)) <=>
10129            (!k. closed_in (subtopology euclidean s) k
10130           ==> closed_in (subtopology euclidean s)
10131               {x | x IN s /\ f x IN IMAGE f k}))``,
10132  REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
10133  ASM_SIMP_TAC std_ss [QUOTIENT_MAP_OPEN_CLOSED] THEN
10134  REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
10135  X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN
10136  FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
10137  UNDISCH_TAC ``!u. u SUBSET t ==>
10138        (closed_in (subtopology euclidean s)
10139           {x | x IN s /\ f x IN u} <=>
10140         closed_in (subtopology euclidean t) u)`` THEN
10141  DISCH_TAC THEN
10142  FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (f:real->real) k``) THEN
10143  ASM_SIMP_TAC std_ss [IMAGE_SUBSET] THEN DISCH_THEN MATCH_MP_TAC THEN ASM_SET_TAC[]);
10144
10145val CLOSED_MAP_IMP_OPEN_MAP = store_thm ("CLOSED_MAP_IMP_OPEN_MAP",
10146 ``!f:real->real s t.
10147  (IMAGE f s = t) /\
10148  (!u. closed_in (subtopology euclidean s) u
10149  ==> closed_in (subtopology euclidean t) (IMAGE f u)) /\
10150      (!u. open_in (subtopology euclidean s) u
10151      ==> open_in (subtopology euclidean s)
10152          {x | x IN s /\ f x IN IMAGE f u})
10153          ==> (!u. open_in (subtopology euclidean s) u
10154            ==> open_in (subtopology euclidean t) (IMAGE f u))``,
10155  REPEAT STRIP_TAC THEN
10156  SUBGOAL_THEN
10157   ``IMAGE (f:real->real) u =
10158   t DIFF IMAGE f (s DIFF {x | x IN s /\ f x IN IMAGE f u})``
10159   SUBST1_TAC THENL
10160  [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN ASM_SET_TAC[],
10161  MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN
10162  FIRST_X_ASSUM MATCH_MP_TAC THEN
10163  MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN
10164  ASM_SIMP_TAC std_ss [CLOSED_IN_REFL]]);
10165
10166val OPEN_MAP_IMP_CLOSED_MAP = store_thm ("OPEN_MAP_IMP_CLOSED_MAP",
10167 ``!f:real->real s t.
10168   (IMAGE f s = t) /\
10169   (!u. open_in (subtopology euclidean s) u
10170   ==> open_in (subtopology euclidean t) (IMAGE f u)) /\
10171      (!u. closed_in (subtopology euclidean s) u
10172      ==> closed_in (subtopology euclidean s)
10173          {x | x IN s /\ f x IN IMAGE f u})
10174          ==> (!u. closed_in (subtopology euclidean s) u
10175            ==> closed_in (subtopology euclidean t) (IMAGE f u))``,
10176  REPEAT STRIP_TAC THEN
10177  SUBGOAL_THEN
10178  ``IMAGE (f:real->real) u =
10179    t DIFF IMAGE f (s DIFF {x | x IN s /\ f x IN IMAGE f u})``
10180   SUBST1_TAC THENL
10181  [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN ASM_SET_TAC[],
10182  MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN
10183  FIRST_X_ASSUM MATCH_MP_TAC THEN
10184  MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN
10185  ASM_SIMP_TAC std_ss [OPEN_IN_REFL]]);
10186
10187val OPEN_MAP_FROM_COMPOSITION_SURJECTIVE = store_thm ("OPEN_MAP_FROM_COMPOSITION_SURJECTIVE",
10188 ``!f:real->real g:real->real s t u.
10189   f continuous_on s /\ (IMAGE f s = t) /\ IMAGE g t SUBSET u /\
10190  (!k. open_in (subtopology euclidean s) k
10191  ==> open_in (subtopology euclidean u) (IMAGE (g o f) k))
10192    ==> (!k. open_in (subtopology euclidean t) k
10193      ==> open_in (subtopology euclidean u) (IMAGE g k))``,
10194  REPEAT STRIP_TAC THEN SUBGOAL_THEN
10195   ``IMAGE g k = IMAGE ((g:real->real) o (f:real->real))
10196     {x | x IN s /\ f(x) IN k}`` SUBST1_TAC THENL
10197  [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
10198   REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[],
10199  FIRST_X_ASSUM MATCH_MP_TAC THEN
10200  MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN
10201  EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[SUBSET_REFL]]);
10202
10203val CLOSED_MAP_FROM_COMPOSITION_SURJECTIVE = store_thm ("CLOSED_MAP_FROM_COMPOSITION_SURJECTIVE",
10204 ``!f:real->real g:real->real s t u.
10205    f continuous_on s /\ (IMAGE f s = t) /\ IMAGE g t SUBSET u /\
10206  (!k. closed_in (subtopology euclidean s) k
10207   ==> closed_in (subtopology euclidean u) (IMAGE (g o f) k))
10208     ==> (!k. closed_in (subtopology euclidean t) k
10209       ==> closed_in (subtopology euclidean u) (IMAGE g k))``,
10210  REPEAT STRIP_TAC THEN SUBGOAL_THEN
10211   ``IMAGE g k = IMAGE ((g:real->real) o (f:real->real))
10212    {x | x IN s /\ f(x) IN k}`` SUBST1_TAC THENL
10213  [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
10214  REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[],
10215  FIRST_X_ASSUM MATCH_MP_TAC THEN
10216  MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN
10217  EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[SUBSET_REFL]]);
10218
10219val OPEN_MAP_FROM_COMPOSITION_INJECTIVE = store_thm ("OPEN_MAP_FROM_COMPOSITION_INJECTIVE",
10220 ``!f:real->real g:real->real s t u.
10221  IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\
10222  g continuous_on t /\ (!x y. x IN t /\ y IN t /\ (g x = g y) ==> (x = y)) /\
10223  (!k. open_in (subtopology euclidean s) k
10224   ==> open_in (subtopology euclidean u) (IMAGE (g o f) k))
10225     ==> (!k. open_in (subtopology euclidean s) k
10226       ==> open_in (subtopology euclidean t) (IMAGE f k))``,
10227  REPEAT STRIP_TAC THEN SUBGOAL_THEN
10228  ``IMAGE f k = {x | x IN t /\
10229     g(x) IN IMAGE ((g:real->real) o (f:real->real)) k}``
10230   SUBST1_TAC THENL
10231  [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
10232  REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[],
10233  MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN
10234  EXISTS_TAC ``u:real->bool`` THEN ASM_SIMP_TAC std_ss []]);
10235
10236val CLOSED_MAP_FROM_COMPOSITION_INJECTIVE = store_thm ("CLOSED_MAP_FROM_COMPOSITION_INJECTIVE",
10237 ``!f:real->real g:real->real s t u.
10238  IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\
10239  g continuous_on t /\ (!x y. x IN t /\ y IN t /\ (g x = g y) ==> (x = y)) /\
10240  (!k. closed_in (subtopology euclidean s) k
10241  ==> closed_in (subtopology euclidean u) (IMAGE (g o f) k))
10242    ==> (!k. closed_in (subtopology euclidean s) k
10243      ==> closed_in (subtopology euclidean t) (IMAGE f k))``,
10244  REPEAT STRIP_TAC THEN SUBGOAL_THEN
10245   ``IMAGE f k = {x | x IN t /\
10246     g(x) IN IMAGE ((g:real->real) o (f:real->real)) k}``
10247   SUBST1_TAC THENL
10248  [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
10249  REWRITE_TAC[IMAGE_COMPOSE] THEN ASM_SET_TAC[],
10250  MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN
10251  EXISTS_TAC ``u:real->bool`` THEN ASM_SIMP_TAC std_ss []]);
10252
10253val OPEN_MAP_CLOSED_SUPERSET_PREIMAGE = store_thm ("OPEN_MAP_CLOSED_SUPERSET_PREIMAGE",
10254 ``!f:real->real s t u w.
10255  (!k. open_in (subtopology euclidean s) k
10256   ==> open_in (subtopology euclidean t) (IMAGE f k)) /\
10257     closed_in (subtopology euclidean s) u /\
10258     w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u
10259     ==> ?v. closed_in (subtopology euclidean t) v /\
10260          w SUBSET v /\
10261         {x | x IN s /\ f(x) IN v} SUBSET u``,
10262  REPEAT STRIP_TAC THEN
10263  EXISTS_TAC ``t DIFF IMAGE (f:real->real) (s DIFF u)`` THEN
10264  CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
10265  MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN
10266  FIRST_X_ASSUM MATCH_MP_TAC THEN
10267  ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL]);
10268
10269val OPEN_MAP_CLOSED_SUPERSET_PREIMAGE_EQ = store_thm ("OPEN_MAP_CLOSED_SUPERSET_PREIMAGE_EQ",
10270 ``!f:real->real s t.
10271  IMAGE f s SUBSET t
10272    ==> ((!k. open_in (subtopology euclidean s) k
10273      ==> open_in (subtopology euclidean t) (IMAGE f k)) <=>
10274        (!u w. closed_in (subtopology euclidean s) u /\
10275        w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u
10276        ==> ?v. closed_in (subtopology euclidean t) v /\
10277            w SUBSET v /\ {x | x IN s /\ f(x) IN v} SUBSET u))``,
10278  REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN
10279  ASM_SIMP_TAC std_ss [OPEN_MAP_CLOSED_SUPERSET_PREIMAGE] THEN
10280  FIRST_X_ASSUM(MP_TAC o SPECL
10281  [``s DIFF k:real->bool``, ``t DIFF IMAGE (f:real->real) k``]) THEN
10282  FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
10283  ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL] THEN
10284  KNOW_TAC ``t DIFF IMAGE (f:real->real) k SUBSET t /\
10285     {x | x IN s /\ f x IN t DIFF IMAGE (f:real->real) k} SUBSET s DIFF k`` THENL
10286  [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
10287  DISCH_THEN(X_CHOOSE_THEN ``v:real->bool`` STRIP_ASSUME_TAC) THEN
10288  SUBGOAL_THEN ``IMAGE (f:real->real) k = t DIFF v`` SUBST1_TAC THENL
10289  [ASM_SET_TAC[], ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL]]);
10290
10291val CLOSED_MAP_OPEN_SUPERSET_PREIMAGE = store_thm ("CLOSED_MAP_OPEN_SUPERSET_PREIMAGE",
10292 ``!f:real->real s t u w.
10293  (!k. closed_in (subtopology euclidean s) k
10294   ==> closed_in (subtopology euclidean t) (IMAGE f k)) /\
10295         open_in (subtopology euclidean s) u /\
10296        w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u
10297       ==> ?v. open_in (subtopology euclidean t) v /\
10298          w SUBSET v /\
10299         {x | x IN s /\ f(x) IN v} SUBSET u``,
10300  REPEAT STRIP_TAC THEN
10301  EXISTS_TAC ``t DIFF IMAGE (f:real->real) (s DIFF u)`` THEN
10302  CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
10303  MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN
10304  FIRST_X_ASSUM MATCH_MP_TAC THEN
10305  ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL]);
10306
10307val CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_EQ = store_thm ("CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_EQ",
10308 ``!f:real->real s t.
10309  IMAGE f s SUBSET t
10310  ==> ((!k. closed_in (subtopology euclidean s) k
10311    ==> closed_in (subtopology euclidean t) (IMAGE f k)) <=>
10312       (!u w. open_in (subtopology euclidean s) u /\
10313       w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u
10314       ==> ?v. open_in (subtopology euclidean t) v /\
10315           w SUBSET v /\ {x | x IN s /\ f(x) IN v} SUBSET u))``,
10316  REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN
10317  ASM_SIMP_TAC std_ss [CLOSED_MAP_OPEN_SUPERSET_PREIMAGE] THEN
10318  FIRST_X_ASSUM(MP_TAC o SPECL
10319  [``s DIFF k:real->bool``, ``t DIFF IMAGE (f:real->real) k``]) THEN
10320  FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
10321  ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL] THEN
10322  KNOW_TAC ``t DIFF IMAGE (f:real->real) k SUBSET t /\
10323     {x | x IN s /\ f x IN t DIFF IMAGE (f:real->real) k} SUBSET s DIFF k`` THENL
10324  [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
10325  DISCH_THEN(X_CHOOSE_THEN ``v:real->bool`` STRIP_ASSUME_TAC) THEN
10326  SUBGOAL_THEN ``IMAGE (f:real->real) k = t DIFF v`` SUBST1_TAC THENL
10327  [ASM_SET_TAC[], ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL]]);
10328
10329val BIGUNION_GSPEC = store_thm ("BIGUNION_GSPEC",
10330 ``(!P f. BIGUNION {f x | P x} = {a | ?x. P x /\ a IN (f x)}) /\
10331   (!P f. BIGUNION {f x y | P x y} = {a | ?x y. P x y /\ a IN (f x y)}) /\
10332   (!P f. BIGUNION {f x y z | P x y z} =
10333            {a | ?x y z. P x y z /\ a IN (f x y z)})``,
10334  REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN
10335  SIMP_TAC std_ss [IN_BIGUNION, GSPECIFICATION, EXISTS_PROD] THEN MESON_TAC[]);
10336
10337val CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_POINT = store_thm ("CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_POINT",
10338 ``!f:real->real s t.
10339  IMAGE f s SUBSET t
10340  ==> ((!k. closed_in (subtopology euclidean s) k
10341    ==> closed_in (subtopology euclidean t) (IMAGE f k)) <=>
10342   (!u y. open_in (subtopology euclidean s) u /\
10343     y IN t /\ {x | x IN s /\ (f(x) = y)} SUBSET u
10344  ==> ?v. open_in (subtopology euclidean t) v /\
10345     y IN v /\ {x | x IN s /\ f(x) IN v} SUBSET u))``,
10346  REPEAT STRIP_TAC THEN ASM_SIMP_TAC std_ss [CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_EQ] THEN
10347  EQ_TAC THEN DISCH_TAC THENL
10348  [MAP_EVERY X_GEN_TAC [``u:real->bool``, ``y:real``] THEN
10349  STRIP_TAC THEN
10350  FIRST_X_ASSUM(MP_TAC o SPECL [``u:real->bool``, ``{y:real}``]) THEN
10351  ASM_REWRITE_TAC[SING_SUBSET, IN_SING],
10352  MAP_EVERY X_GEN_TAC [``u:real->bool``, ``w:real->bool``] THEN
10353  STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN
10354  KNOW_TAC ``(!y. ?v. open_in (subtopology euclidean s) u /\
10355          y IN t /\ {x | x IN s /\ (f x = y)} SUBSET u
10356          ==> open_in (subtopology euclidean t) v /\
10357              y IN v /\ {x | x IN s /\ f x IN v} SUBSET u)
10358     ==> (?v. open_in (subtopology euclidean t) v /\
10359          w SUBSET v /\ {x | x IN s /\ f x IN v} SUBSET u)`` THENL
10360  [ALL_TAC, METIS_TAC [GSYM RIGHT_EXISTS_IMP_THM]] THEN
10361  SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN
10362  X_GEN_TAC ``vv:real->real->bool`` THEN DISCH_TAC THEN
10363  EXISTS_TAC ``BIGUNION {(vv:real->real->bool) y | y IN w}`` THEN
10364  CONJ_TAC THENL
10365  [MATCH_MP_TAC OPEN_IN_BIGUNION THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN
10366   ASM_SET_TAC[],
10367   SIMP_TAC std_ss [BIGUNION_GSPEC] THEN
10368   CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
10369   SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, GSYM RIGHT_EXISTS_AND_THM,
10370    LEFT_IMP_EXISTS_THM] THEN
10371   MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN
10372   FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN ASM_SET_TAC[]]]);
10373
10374val CONNECTED_OPEN_MONOTONE_PREIMAGE = store_thm ("CONNECTED_OPEN_MONOTONE_PREIMAGE",
10375 ``!f:real->real s t.
10376    f continuous_on s /\ (IMAGE f s = t) /\
10377  (!c. open_in (subtopology euclidean s) c
10378   ==> open_in (subtopology euclidean t) (IMAGE f c)) /\
10379      (!y. y IN t ==> connected {x | x IN s /\ (f x = y)})
10380       ==> !c. connected c /\ c SUBSET t
10381         ==> connected {x | x IN s /\ f x IN c}``,
10382  REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC ``c:real->bool`` o MATCH_MP
10383   (ONCE_REWRITE_RULE[CONJ_EQ_IMP] OPEN_MAP_RESTRICT)) THEN
10384  ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC(ISPECL
10385   [``f:real->real``, ``{x | x IN s /\ (f:real->real) x IN c}``]
10386   OPEN_MAP_IMP_QUOTIENT_MAP) THEN
10387  SUBGOAL_THEN ``IMAGE f {x | x IN s /\ (f:real->real) x IN c} = c``
10388   ASSUME_TAC THENL [ASM_SET_TAC[], ASM_REWRITE_TAC[]] THEN
10389  KNOW_TAC ``(f:real->real) continuous_on {x | x IN s /\ f x IN c}`` THENL
10390  [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP]
10391   CONTINUOUS_ON_SUBSET)) THEN SET_TAC[],
10392   DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN
10393  MATCH_MP_TAC CONNECTED_MONOTONE_QUOTIENT_PREIMAGE THEN
10394  MAP_EVERY EXISTS_TAC [``f:real->real``, ``c:real->bool``] THEN
10395  ASM_REWRITE_TAC[] THEN
10396  SIMP_TAC std_ss [SET_RULE
10397   ``y IN c ==> ({x | x IN {x | x IN s /\ f x IN c} /\ (f x = y)} =
10398                 {x | x IN s /\ (f x = y)})``] THEN
10399  ASM_SET_TAC[]);
10400
10401val CONNECTED_CLOSED_MONOTONE_PREIMAGE = store_thm ("CONNECTED_CLOSED_MONOTONE_PREIMAGE",
10402 ``!f:real->real s t.
10403    f continuous_on s /\ (IMAGE f s = t) /\
10404   (!c. closed_in (subtopology euclidean s) c
10405   ==> closed_in (subtopology euclidean t) (IMAGE f c)) /\
10406      (!y. y IN t ==> connected {x | x IN s /\ (f x = y)})
10407      ==> !c. connected c /\ c SUBSET t
10408        ==> connected {x | x IN s /\ f x IN c}``,
10409  REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC ``c:real->bool`` o MATCH_MP
10410   (ONCE_REWRITE_RULE[CONJ_EQ_IMP] CLOSED_MAP_RESTRICT)) THEN
10411  ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC(ISPECL
10412   [``f:real->real``, ``{x | x IN s /\ (f:real->real) x IN c}``]
10413    CLOSED_MAP_IMP_QUOTIENT_MAP) THEN
10414  SUBGOAL_THEN ``IMAGE f {x | x IN s /\ (f:real->real) x IN c} = c``
10415   ASSUME_TAC THENL [ASM_SET_TAC[], ASM_REWRITE_TAC[]] THEN
10416  KNOW_TAC ``(f:real->real) continuous_on {x | x IN s /\ f x IN c}`` THENL
10417  [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP]
10418   CONTINUOUS_ON_SUBSET)) THEN SET_TAC[],
10419   DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN
10420  MATCH_MP_TAC CONNECTED_MONOTONE_QUOTIENT_PREIMAGE THEN
10421  MAP_EVERY EXISTS_TAC [``f:real->real``, ``c:real->bool``] THEN
10422  ASM_REWRITE_TAC[] THEN
10423  SIMP_TAC std_ss [SET_RULE
10424   ``y IN c ==> ({x | x IN {x | x IN s /\ f x IN c} /\ (f x = y)} =
10425                 {x | x IN s /\ (f x = y)})``] THEN
10426  ASM_SET_TAC[]);
10427
10428(* ------------------------------------------------------------------------- *)
10429(* Proper maps, including projections out of compact sets.                   *)
10430(* ------------------------------------------------------------------------- *)
10431
10432val PROPER_MAP = store_thm ("PROPER_MAP",
10433 ``!f:real->real s t.
10434  IMAGE f s SUBSET t
10435  ==> ((!k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}) <=>
10436       (!k. closed_in (subtopology euclidean s) k
10437        ==> closed_in (subtopology euclidean t) (IMAGE f k)) /\
10438            (!a. a IN t ==> compact {x | x IN s /\ (f x = a)}))``,
10439  REPEAT STRIP_TAC THEN EQ_TAC THENL
10440  [REPEAT STRIP_TAC THENL
10441   [ALL_TAC,
10442    ONCE_REWRITE_TAC[SET_RULE ``(x = a) <=> x IN {a}``] THEN
10443    FIRST_X_ASSUM MATCH_MP_TAC THEN
10444    ASM_REWRITE_TAC[SING_SUBSET, COMPACT_SING]] THEN
10445   FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
10446   REWRITE_TAC[CLOSED_IN_LIMPT] THEN
10447   CONJ_TAC THENL [ASM_SET_TAC[], X_GEN_TAC ``y:real``] THEN
10448   REWRITE_TAC[LIMPT_SEQUENTIAL_INJ, IN_DELETE] THEN
10449   SIMP_TAC std_ss [IN_IMAGE, GSYM LEFT_EXISTS_AND_THM, SKOLEM_THM] THEN
10450   KNOW_TAC ``(?(x :num -> real) (f' :num -> real).
10451   ((!(n :num).
10452       ((f' n = (f :real -> real) (x n)) /\
10453        x n IN (k :real -> bool)) /\ f' n <> (y :real)) /\
10454    (!(m :num) (n :num). (f' m = f' n) <=> (m = n)) /\
10455    ((f' --> y) sequentially :bool)) /\ y IN (t :real -> bool)) ==>
10456     ?(x :real). (y = f x) /\ x IN k`` THENL
10457   [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN
10458   SIMP_TAC std_ss [GSYM CONJ_ASSOC, FORALL_AND_THM] THEN
10459   SIMP_TAC std_ss [GSYM FUN_EQ_THM] THEN
10460   SIMP_TAC std_ss [UNWIND_THM2, FUN_EQ_THM] THEN
10461   DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` STRIP_ASSUME_TAC) THEN
10462   SUBGOAL_THEN
10463   ``~(BIGINTER {{a | a IN k /\ (f:real->real) a IN
10464      (y INSERT IMAGE (\i. f(x(n + i))) univ(:num))} | n IN univ(:num)} = {})``
10465   MP_TAC THENL
10466   [MATCH_MP_TAC COMPACT_FIP THEN CONJ_TAC THENL
10467    [SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV] THEN X_GEN_TAC ``n:num`` THEN
10468     UNDISCH_TAC ``closed_in (subtopology euclidean s) k`` THEN DISCH_TAC THEN
10469     FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [CLOSED_IN_CLOSED]) THEN
10470     DISCH_THEN(X_CHOOSE_THEN ``c:real->bool`` STRIP_ASSUME_TAC) THEN
10471     ONCE_REWRITE_TAC [METIS [] ``f a IN s <=> (\a. f a IN s) a``] THEN
10472     ASM_REWRITE_TAC[SET_RULE
10473     ``{x | x IN s INTER k /\ P x} = k INTER {x | x IN s /\ P x}``] THEN
10474     MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN
10475     BETA_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
10476     CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
10477     MATCH_MP_TAC COMPACT_SEQUENCE_WITH_LIMIT THEN
10478     UNDISCH_TAC ``((\n. f ((x:num->real) n)) --> y) sequentially`` THEN DISCH_TAC THEN
10479     FIRST_ASSUM(MP_TAC o SPEC ``n:num`` o MATCH_MP SEQ_OFFSET) THEN
10480     BETA_TAC THEN GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [ADD_SYM] THEN
10481     SIMP_TAC std_ss [],
10482     SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_FINITE_SUBSET_IMAGE] THEN
10483     X_GEN_TAC ``i:num->bool`` THEN STRIP_TAC THEN
10484     UNDISCH_TAC ``FINITE (i:num->bool)`` THEN DISCH_TAC THEN
10485     FIRST_ASSUM(MP_TAC o ISPEC ``\n:num. n`` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN
10486     SIMP_TAC std_ss [] THEN DISCH_THEN(X_CHOOSE_TAC ``m:num``) THEN
10487     SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, BIGINTER_IMAGE, GSPECIFICATION] THEN
10488     EXISTS_TAC ``(x:num->real) m`` THEN
10489     X_GEN_TAC ``p:num`` THEN DISCH_TAC THEN
10490     CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
10491     REWRITE_TAC[IN_INSERT, IN_IMAGE, IN_UNIV] THEN DISJ2_TAC THEN
10492     EXISTS_TAC ``m - p:num`` THEN BETA_TAC THEN
10493     UNDISCH_TAC ``!x:num. x IN i ==> x <= m`` THEN DISCH_THEN (MP_TAC o SPEC ``p:num``) THEN
10494     ASM_REWRITE_TAC [] THEN ARITH_TAC],
10495     REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
10496     DISCH_THEN (X_CHOOSE_TAC ``x:real``) THEN EXISTS_TAC ``x:real`` THEN
10497     POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [BIGINTER_GSPEC, GSPECIFICATION, IN_UNIV] THEN
10498     DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC ``0:num``) THEN
10499     SIMP_TAC std_ss [ADD_CLAUSES, IN_INSERT, IN_IMAGE, IN_UNIV] THEN
10500     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (DISJ_CASES_THEN MP_TAC)) THEN
10501     ASM_SIMP_TAC std_ss [] THEN DISCH_THEN(X_CHOOSE_TAC ``i:num``) THEN
10502     FIRST_X_ASSUM (MP_TAC o SPEC ``i + 1:num``) THEN
10503     ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN
10504     ASM_SIMP_TAC std_ss [IN_INSERT, IN_IMAGE, IN_UNIV] THEN ARITH_TAC],
10505   STRIP_TAC THEN X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN
10506   REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN
10507   X_GEN_TAC ``c:(real->bool)->bool`` THEN STRIP_TAC THEN
10508   SUBGOAL_THEN
10509   ``!a. a IN k
10510   ==> ?g. g SUBSET c /\ FINITE g /\
10511    {x | x IN s /\ ((f:real->real) x = a)} SUBSET BIGUNION g``
10512   MP_TAC THENL
10513   [X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN UNDISCH_THEN
10514    ``!a. a IN t ==> compact {x | x IN s /\ ((f:real->real) x = a)}``
10515    (MP_TAC o SPEC ``a:real``) THEN
10516    KNOW_TAC ``(a :real) IN (t :real -> bool)`` THENL
10517    [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
10518     POP_ASSUM K_TAC THEN REWRITE_TAC[COMPACT_EQ_HEINE_BOREL]] THEN
10519     DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_SET_TAC[],
10520   DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN
10521   SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN
10522   X_GEN_TAC ``uu:real->(real->bool)->bool`` THEN DISCH_TAC] THEN
10523  SUBGOAL_THEN
10524  ``!a. a IN k ==> ?v. open v /\ a IN v /\
10525   {x | x IN s /\ (f:real->real) x IN v} SUBSET BIGUNION(uu a)``
10526   MP_TAC THENL
10527  [REPEAT STRIP_TAC THEN
10528   UNDISCH_THEN
10529   ``!k. closed_in (subtopology euclidean s) k
10530     ==> closed_in (subtopology euclidean t) (IMAGE (f:real->real) k)``
10531    (MP_TAC o SPEC ``(s:real->bool) DIFF BIGUNION(uu(a:real))``) THEN
10532   SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
10533   KNOW_TAC ``(s :real -> bool) DIFF
10534    BIGUNION ((uu :real -> (real -> bool) -> bool) (a :real)) SUBSET s /\
10535     open_in (subtopology euclidean s) (s DIFF (s DIFF BIGUNION (uu a)))`` THENL
10536   [CONJ_TAC THENL [SET_TAC[], ALL_TAC] THEN
10537    REWRITE_TAC[SET_RULE ``s DIFF (s DIFF t) = s INTER t``] THEN
10538    MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN
10539    MATCH_MP_TAC OPEN_BIGUNION THEN ASM_SET_TAC[],
10540    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
10541    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
10542    REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_THEN (X_CHOOSE_TAC ``v:real->bool``) THEN
10543    EXISTS_TAC ``v:real->bool`` THEN POP_ASSUM MP_TAC THEN
10544    STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
10545    REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC ``a:real``)) THEN
10546    ASM_REWRITE_TAC[] THEN
10547    KNOW_TAC ``a IN t:real->bool`` THENL [ASM_SET_TAC[],
10548     DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN DISCH_TAC] THEN
10549    STRIP_TAC THEN ASM_SET_TAC[]],
10550   DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN
10551   SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN
10552   X_GEN_TAC ``vv:real->(real->bool)`` THEN DISCH_TAC] THEN
10553  UNDISCH_TAC ``compact k`` THEN DISCH_TAC THEN
10554  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [COMPACT_EQ_HEINE_BOREL]) THEN
10555  DISCH_THEN(MP_TAC o SPEC ``IMAGE (vv:real->(real->bool)) k``) THEN
10556  KNOW_TAC ``(!(t :real -> bool).
10557    t IN IMAGE (vv :real -> real -> bool) (k :real -> bool) ==>
10558    (open t :bool)) /\ k SUBSET BIGUNION (IMAGE vv k)`` THENL
10559  [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
10560   POP_ASSUM K_TAC THEN SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM]] THEN
10561  ONCE_REWRITE_TAC[TAUT `p /\ q /\ r ==> s <=> q /\ p ==> r ==> s`] THEN
10562  SIMP_TAC real_ss [FORALL_FINITE_SUBSET_IMAGE] THEN
10563  X_GEN_TAC ``j:real->bool`` THEN REPEAT STRIP_TAC THEN
10564  EXISTS_TAC ``BIGUNION (IMAGE (uu:real->(real->bool)->bool) j)`` THEN
10565  REPEAT CONJ_TAC THENL
10566  [ASM_SET_TAC[],
10567   ASM_SIMP_TAC std_ss [FINITE_BIGUNION_EQ, FORALL_IN_IMAGE, IMAGE_FINITE] THEN
10568   ASM_SET_TAC[],
10569   SIMP_TAC std_ss [BIGUNION_IMAGE, SUBSET_DEF, IN_BIGUNION, GSPECIFICATION] THEN
10570   ASM_SET_TAC[]]]);
10571
10572val COMPACT_CONTINUOUS_IMAGE_EQ = store_thm ("COMPACT_CONTINUOUS_IMAGE_EQ",
10573 ``!f:real->real s.
10574   (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y))
10575   ==> (f continuous_on s <=>
10576   !t. compact t /\ t SUBSET s ==> compact(IMAGE f t))``,
10577  REPEAT STRIP_TAC THEN EQ_TAC THENL
10578  [MESON_TAC[COMPACT_CONTINUOUS_IMAGE, CONTINUOUS_ON_SUBSET], DISCH_TAC] THEN
10579   FIRST_X_ASSUM(X_CHOOSE_TAC ``g:real->real`` o
10580   SIMP_RULE std_ss [INJECTIVE_ON_LEFT_INVERSE]) THEN
10581   REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN
10582   X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN
10583   MP_TAC(ISPECL [``g:real->real``, ``IMAGE (f:real->real) s``,
10584    ``s:real->bool``] PROPER_MAP) THEN
10585  KNOW_TAC ``IMAGE (g :real -> real)
10586   (IMAGE (f :real -> real) (s :real -> bool)) SUBSET s`` THENL
10587  [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
10588   POP_ASSUM K_TAC] THEN
10589  MATCH_MP_TAC(TAUT `(q ==> s) /\ p ==> (p <=> q /\ r) ==> s`) THEN
10590  REPEAT STRIP_TAC THENL
10591  [SUBGOAL_THEN
10592   ``{x | x IN s /\ (f:real->real) x IN u} = IMAGE g u``
10593   (fn th => ASM_MESON_TAC[th]),
10594   SUBGOAL_THEN
10595   ``{x | x IN IMAGE f s /\ (g:real->real) x IN k} = IMAGE f k``
10596   (fn th => ASM_SIMP_TAC std_ss [th])] THEN
10597  UNDISCH_TAC `` closed_in
10598        (subtopology euclidean
10599           (IMAGE (f :real -> real) (s :real -> bool)))
10600        (u :real -> bool)`` THEN DISCH_TAC THEN
10601  FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN ASM_SET_TAC[]);
10602
10603val PROPER_MAP_FROM_COMPACT = store_thm ("PROPER_MAP_FROM_COMPACT",
10604 ``!f:real->real s k.
10605   f continuous_on s /\ IMAGE f s SUBSET t /\ compact s /\
10606   closed_in (subtopology euclidean t) k
10607   ==> compact {x | x IN s /\ f x IN k}``,
10608   REPEAT STRIP_TAC THEN
10609   MATCH_MP_TAC CLOSED_IN_COMPACT THEN EXISTS_TAC ``s:real->bool`` THEN
10610   METIS_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_GEN]);
10611
10612val PROPER_MAP_COMPOSE = store_thm ("PROPER_MAP_COMPOSE",
10613 ``!f:real->real g:real->real s t u.
10614   IMAGE f s SUBSET t /\
10615   (!k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}) /\
10616   (!k. k SUBSET u /\ compact k ==> compact {x | x IN t /\ g x IN k})
10617   ==> !k. k SUBSET u /\ compact k
10618   ==> compact {x | x IN s /\ (g o f) x IN k}``,
10619  REPEAT STRIP_TAC THEN REWRITE_TAC[o_THM] THEN
10620  FIRST_X_ASSUM(MP_TAC o SPEC ``k:real->bool``) THEN
10621  ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
10622  FIRST_X_ASSUM(MP_TAC o SPEC ``{x | x IN t /\ (g:real->real) x IN k}``) THEN
10623  KNOW_TAC ``{x | x IN (t :real -> bool) /\
10624   (g :real -> real) x IN (k :real -> bool)} SUBSET t /\
10625    compact {x | x IN t /\ g x IN k}`` THENL
10626  [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
10627   POP_ASSUM K_TAC THEN MATCH_MP_TAC EQ_IMPLIES] THEN
10628  AP_TERM_TAC THEN ASM_SET_TAC[]);
10629
10630val PROPER_MAP_FROM_COMPOSITION_LEFT = store_thm ("PROPER_MAP_FROM_COMPOSITION_LEFT",
10631 ``!f:real->real g:real->real s t u.
10632    f continuous_on s /\ (IMAGE f s = t) /\
10633    g continuous_on t /\ IMAGE g t SUBSET u /\
10634    (!k. k SUBSET u /\ compact k
10635   ==> compact {x | x IN s /\ (g o f) x IN k})
10636   ==> !k. k SUBSET u /\ compact k ==> compact {x | x IN t /\ g x IN k}``,
10637  REWRITE_TAC[o_THM] THEN REPEAT STRIP_TAC THEN
10638  FIRST_X_ASSUM(MP_TAC o SPEC ``k:real->bool``) THEN ASM_REWRITE_TAC[] THEN
10639  DISCH_THEN(MP_TAC o ISPEC ``f:real->real`` o MATCH_MP
10640  (REWRITE_RULE[IMP_CONJ_ALT] COMPACT_CONTINUOUS_IMAGE)) THEN
10641  KNOW_TAC ``(f :real -> real) continuous_on
10642   {x | x IN (s :real -> bool) /\
10643   (g :real -> real) (f x) IN (k :real -> bool)} `` THENL
10644  [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP]
10645  CONTINUOUS_ON_SUBSET)) THEN SET_TAC[],
10646  DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
10647  MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]]);
10648
10649val lemma = prove (
10650 ``!s t. closed_in (subtopology euclidean s) t ==> compact s ==> compact t``,
10651  MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_SUBSET, CLOSED_IN_CLOSED_EQ]);
10652
10653val PROPER_MAP_FROM_COMPOSITION_RIGHT = store_thm ("PROPER_MAP_FROM_COMPOSITION_RIGHT",
10654 ``!f:real->real g:real->real s t u.
10655    f continuous_on s /\ IMAGE f s SUBSET t /\
10656    g continuous_on t /\ IMAGE g t SUBSET u /\
10657   (!k. k SUBSET u /\ compact k
10658   ==> compact {x | x IN s /\ (g o f) x IN k})
10659   ==> !k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}``,
10660  REWRITE_TAC[o_THM] THEN REPEAT STRIP_TAC THEN
10661  FIRST_X_ASSUM(MP_TAC o SPEC ``IMAGE (g:real->real) k``) THEN
10662  KNOW_TAC ``IMAGE (g :real -> real) (k :real -> bool) SUBSET (u :real -> bool) /\
10663   compact (IMAGE g k)`` THENL
10664  [CONJ_TAC THENL [ASM_SET_TAC[], MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE] THEN
10665   ASM_MESON_TAC[CONTINUOUS_ON_SUBSET],
10666   DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
10667   MATCH_MP_TAC lemma THEN
10668   MATCH_MP_TAC CLOSED_IN_SUBSET_TRANS THEN
10669   EXISTS_TAC ``s:real->bool`` THEN
10670   CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
10671  MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN
10672  EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[] THEN
10673  MATCH_MP_TAC CLOSED_SUBSET THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED]]);
10674
10675(* ------------------------------------------------------------------------- *)
10676(* Pasting functions together on open sets.                                  *)
10677(* ------------------------------------------------------------------------- *)
10678
10679val PASTING_LEMMA = store_thm ("PASTING_LEMMA",
10680 ``!f:'a->real->real g t s k.
10681        (!i. i IN k
10682             ==> open_in (subtopology euclidean s) (t i) /\
10683                 (f i) continuous_on (t i)) /\
10684        (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j
10685                 ==> (f i x = f j x)) /\
10686        (!x. x IN s ==> ?j. j IN k /\ x IN t j /\ (g x = f j x))
10687        ==> g continuous_on s``,
10688  REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_OPEN_IN_PREIMAGE_EQ] THEN
10689  STRIP_TAC THEN X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN
10690  SUBGOAL_THEN
10691   ``{x | x IN s /\ g x IN u} =
10692     BIGUNION {{x | x IN (t i) /\ ((f:'a->real->real) i x) IN u} |
10693            i IN k}``
10694  SUBST1_TAC THENL
10695   [SUBGOAL_THEN ``!i. i IN k ==> ((t:'a->real->bool) i) SUBSET s``
10696    ASSUME_TAC THENL
10697     [ASM_MESON_TAC[OPEN_IN_SUBSET, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY],
10698      SIMP_TAC std_ss [BIGUNION_GSPEC] THEN ASM_SET_TAC[]],
10699    MATCH_MP_TAC OPEN_IN_BIGUNION THEN SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN
10700    METIS_TAC[OPEN_IN_TRANS]]);
10701
10702val PASTING_LEMMA_EXISTS = store_thm ("PASTING_LEMMA_EXISTS",
10703 ``!f:'a->real->real t s k.
10704        s SUBSET BIGUNION {t i | i IN k} /\
10705        (!i. i IN k
10706             ==> open_in (subtopology euclidean s) (t i) /\
10707                 (f i) continuous_on (t i)) /\
10708        (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j
10709                 ==> (f i x = f j x))
10710        ==> ?g. g continuous_on s /\
10711                (!x i. i IN k /\ x IN s INTER t i ==> (g x = f i x))``,
10712  REPEAT STRIP_TAC THEN
10713  EXISTS_TAC ``\x. (f:'a->real->real)(@i. i IN k /\ x IN t i) x`` THEN
10714  CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN MATCH_MP_TAC PASTING_LEMMA THEN
10715  MAP_EVERY EXISTS_TAC
10716   [``f:'a->real->real``, ``t:'a->real->bool``, ``k:'a->bool``] THEN
10717  ASM_SET_TAC[]);
10718
10719val CONTINUOUS_ON_UNION_LOCAL_OPEN = store_thm ("CONTINUOUS_ON_UNION_LOCAL_OPEN",
10720 ``!f:real->real s.
10721        open_in (subtopology euclidean (s UNION t)) s /\
10722        open_in (subtopology euclidean (s UNION t)) t /\
10723        f continuous_on s /\ f continuous_on t
10724        ==> f continuous_on (s UNION t)``,
10725  REPEAT STRIP_TAC THEN MP_TAC(ISPECL
10726   [``(\i:(real->bool). (f:real->real))``, ``f:real->real``,
10727    ``(\i:(real->bool). i)``, ``s UNION (t:real->bool)``, ``{s:real->bool;t}``]
10728   PASTING_LEMMA) THEN DISCH_THEN MATCH_MP_TAC THEN
10729  ASM_SIMP_TAC std_ss [FORALL_IN_INSERT, EXISTS_IN_INSERT, NOT_IN_EMPTY] THEN
10730  REWRITE_TAC[IN_UNION]);
10731
10732val CONTINUOUS_ON_UNION_OPEN = store_thm ("CONTINUOUS_ON_UNION_OPEN",
10733 ``!f s t. open s /\ open t /\ f continuous_on s /\ f continuous_on t
10734           ==> f continuous_on (s UNION t)``,
10735  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL_OPEN THEN
10736  ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN
10737  ASM_SIMP_TAC std_ss [OPEN_UNION] THEN SET_TAC[]);
10738
10739val CONTINUOUS_ON_CASES_LOCAL_OPEN = store_thm ("CONTINUOUS_ON_CASES_LOCAL_OPEN",
10740 ``!P f g:real->real s t.
10741        open_in (subtopology euclidean (s UNION t)) s /\
10742        open_in (subtopology euclidean (s UNION t)) t /\
10743        f continuous_on s /\ g continuous_on t /\
10744        (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> (f x = g x))
10745        ==> (\x. if P x then f x else g x) continuous_on (s UNION t)``,
10746  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL_OPEN THEN
10747  ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL
10748   [EXISTS_TAC ``f:real->real``, EXISTS_TAC ``g:real->real``] THEN
10749  ASM_SIMP_TAC std_ss [] THEN METIS_TAC[]);
10750
10751val CONTINUOUS_ON_CASES_OPEN = store_thm ("CONTINUOUS_ON_CASES_OPEN",
10752 ``!P f g s t.
10753           open s /\
10754           open t /\
10755           f continuous_on s /\
10756           g continuous_on t /\
10757           (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> (f x = g x))
10758           ==> (\x. if P x then f x else g x) continuous_on s UNION t``,
10759  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL_OPEN THEN
10760  ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN
10761  ASM_SIMP_TAC std_ss [OPEN_UNION] THEN SET_TAC[]);
10762
10763(* ------------------------------------------------------------------------- *)
10764(* Likewise on closed sets, with a finiteness assumption.                    *)
10765(* ------------------------------------------------------------------------- *)
10766
10767val PASTING_LEMMA_CLOSED = store_thm ("PASTING_LEMMA_CLOSED",
10768 ``!f:'a->real->real g t s k.
10769        FINITE k /\
10770        (!i. i IN k
10771             ==> closed_in (subtopology euclidean s) (t i) /\
10772                 (f i) continuous_on (t i)) /\
10773        (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j
10774                 ==> (f i x = f j x)) /\
10775        (!x. x IN s ==> ?j. j IN k /\ x IN t j /\ (g x = f j x))
10776        ==> g continuous_on s``,
10777  REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN
10778  STRIP_TAC THEN X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN
10779  SUBGOAL_THEN
10780   ``{x | x IN s /\ g x IN u} =
10781     BIGUNION {{x | x IN (t i) /\ ((f:'a->real->real) i x) IN u} |
10782            i IN k}``
10783  SUBST1_TAC THENL
10784   [SUBGOAL_THEN ``!i. i IN k ==> ((t:'a->real->bool) i) SUBSET s``
10785    ASSUME_TAC THENL
10786     [ASM_MESON_TAC[CLOSED_IN_SUBSET, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY],
10787      SIMP_TAC std_ss [BIGUNION_GSPEC] THEN ASM_SET_TAC[]],
10788    MATCH_MP_TAC CLOSED_IN_BIGUNION THEN
10789    ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, IMAGE_FINITE, FORALL_IN_IMAGE] THEN
10790    METIS_TAC[CLOSED_IN_TRANS]]);
10791
10792val PASTING_LEMMA_EXISTS_CLOSED = store_thm ("PASTING_LEMMA_EXISTS_CLOSED",
10793 ``!f:'a->real->real t s k.
10794        FINITE k /\
10795        s SUBSET BIGUNION {t i | i IN k} /\
10796        (!i. i IN k
10797             ==> closed_in (subtopology euclidean s) (t i) /\
10798                 (f i) continuous_on (t i)) /\
10799        (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j
10800                 ==> (f i x = f j x))
10801        ==> ?g. g continuous_on s /\
10802                (!x i. i IN k /\ x IN s INTER t i ==> (g x = f i x))``,
10803  REPEAT STRIP_TAC THEN
10804  EXISTS_TAC ``\x. (f:'a->real->real)(@i. i IN k /\ x IN t i) x`` THEN
10805  CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
10806  MATCH_MP_TAC PASTING_LEMMA_CLOSED THEN
10807  MAP_EVERY EXISTS_TAC
10808   [``f:'a->real->real``, ``t:'a->real->bool``, ``k:'a->bool``] THEN
10809  ASM_SET_TAC[]);
10810
10811(* ------------------------------------------------------------------------- *)
10812(* Closure of halflines, halfspaces and hyperplanes.                         *)
10813(* ------------------------------------------------------------------------- *)
10814
10815val LIM_LIFT_DOT = store_thm ("LIM_LIFT_DOT",
10816 ``!f:real->real a.
10817        (f --> l) net ==> ((\y. a * f(y)) --> (a * l)) net``,
10818  METIS_TAC [LIM_CMUL]);
10819
10820val CONTINUOUS_AT_LIFT_DOT = store_thm ("CONTINUOUS_AT_LIFT_DOT",
10821 ``!a:real x. (\y. a * y) continuous at x``,
10822  REPEAT GEN_TAC THEN SIMP_TAC std_ss [CONTINUOUS_AT, o_THM] THEN
10823  KNOW_TAC ``((\y. a * (\y. y) y:real) --> (a * x)) (at x)`` THENL
10824  [ALL_TAC, SIMP_TAC std_ss []] THEN
10825  MATCH_MP_TAC LIM_LIFT_DOT THEN REWRITE_TAC[LIM_AT] THEN METIS_TAC[]);
10826
10827val CONTINUOUS_ON_LIFT_DOT = store_thm ("CONTINUOUS_ON_LIFT_DOT",
10828 ``!s. (\y. a * y) continuous_on s``,
10829  SIMP_TAC std_ss [CONTINUOUS_AT_IMP_CONTINUOUS_ON, CONTINUOUS_AT_LIFT_DOT]);
10830
10831val CLOSED_INTERVAL_LEFT = store_thm ("CLOSED_INTERVAL_LEFT",
10832 ``!b:real.
10833     closed {x:real | x <= b}``,
10834  SIMP_TAC std_ss [CLOSED_LIMPT, LIMPT_APPROACHABLE, GSPECIFICATION] THEN
10835  REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
10836  FIRST_X_ASSUM(MP_TAC o SPEC ``(x:real) - (b:real)``) THEN
10837  ASM_REWRITE_TAC[REAL_SUB_LT] THEN
10838  DISCH_THEN(X_CHOOSE_THEN ``z:real`` MP_TAC) THEN
10839  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
10840  REWRITE_TAC[dist] THEN ASM_REAL_ARITH_TAC);
10841
10842val CLOSED_INTERVAL_RIGHT = store_thm ("CLOSED_INTERVAL_RIGHT",
10843 ``!a:real.
10844     closed {x:real | a <= x}``,
10845  SIMP_TAC std_ss [CLOSED_LIMPT, LIMPT_APPROACHABLE, GSPECIFICATION] THEN
10846  REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
10847  FIRST_X_ASSUM(MP_TAC o SPEC ``(a:real) - (x:real)``) THEN
10848  ASM_REWRITE_TAC[REAL_SUB_LT] THEN
10849  DISCH_THEN(X_CHOOSE_THEN ``z:real`` MP_TAC) THEN
10850  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
10851  REWRITE_TAC[dist] THEN ASM_REAL_ARITH_TAC);
10852
10853val CLOSED_HALFSPACE_LE = store_thm ("CLOSED_HALFSPACE_LE",
10854 ``!a:real b. closed {x | a * x <= b}``,
10855  REPEAT GEN_TAC THEN
10856  MP_TAC(ISPEC ``univ(:real)`` CONTINUOUS_ON_LIFT_DOT) THEN
10857  SIMP_TAC std_ss [CONTINUOUS_ON_CLOSED, GSYM CLOSED_IN, SUBTOPOLOGY_UNIV] THEN
10858  DISCH_THEN(MP_TAC o SPEC
10859   ``IMAGE (\x. x) {r | ?x:real. (a * x = r) /\ r <= b}``) THEN
10860   KNOW_TAC ``closed_in (subtopology euclidean (IMAGE (\y. a * y) univ(:real)))
10861             (IMAGE (\x. x) {r | ?x. (a * x = r) /\ r <= b})`` THENL
10862   [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
10863    MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN
10864    SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE, IN_UNIV] THEN
10865    METIS_TAC []] THEN
10866  REWRITE_TAC[CLOSED_IN_CLOSED] THEN
10867  EXISTS_TAC ``{x | (x:real) <= (b)}`` THEN
10868  SIMP_TAC std_ss [CLOSED_INTERVAL_LEFT] THEN
10869  SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_UNIV, GSPECIFICATION, IN_INTER] THEN
10870  METIS_TAC []);
10871
10872val CLOSED_HALFSPACE_GE = store_thm ("CLOSED_HALFSPACE_GE",
10873 ``!a:real b. closed {x | a * x >= b}``,
10874  REWRITE_TAC[REAL_ARITH ``a >= b <=> -a <= -b:real``] THEN
10875  REWRITE_TAC[GSYM REAL_MUL_LNEG, CLOSED_HALFSPACE_LE]);
10876
10877val CLOSED_HYPERPLANE = store_thm ("CLOSED_HYPERPLANE",
10878 ``!a b. closed {x | a * x = b}``,
10879  REPEAT GEN_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
10880  REWRITE_TAC[REAL_ARITH ``b <= a * x <=> a * x >= b:real``] THEN
10881  REWRITE_TAC[SET_RULE `` {x | a * x <= b /\ a * x >= b} =
10882                          {x | a * x <= b} INTER  {x | a * x >= b}``] THEN
10883  SIMP_TAC std_ss [CLOSED_INTER, CLOSED_HALFSPACE_LE, CLOSED_HALFSPACE_GE]);
10884
10885val CLOSURE_HYPERPLANE = store_thm ("CLOSURE_HYPERPLANE",
10886 ``!a b. closure {x | a * x = b} = {x | a * x = b}``,
10887  SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_HYPERPLANE]);
10888
10889val CLOSED_STANDARD_HYPERPLANE = store_thm ("CLOSED_STANDARD_HYPERPLANE",
10890 ``!a. closed {x:real | x = a}``,
10891  REPEAT GEN_TAC THEN
10892  MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSED_HYPERPLANE) THEN
10893  REAL_ARITH_TAC);
10894
10895val CLOSED_HALFSPACE_COMPONENT_LE = store_thm ("CLOSED_HALFSPACE_COMPONENT_LE",
10896 ``!a. closed {x:real | x <= a}``,
10897  REPEAT GEN_TAC THEN
10898  MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSED_HALFSPACE_LE) THEN
10899  REAL_ARITH_TAC);
10900
10901val CLOSED_HALFSPACE_COMPONENT_GE = store_thm ("CLOSED_HALFSPACE_COMPONENT_GE",
10902 ``!a. closed {x:real | x >= a}``,
10903  REPEAT GEN_TAC THEN
10904  MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSED_HALFSPACE_GE) THEN
10905  REAL_ARITH_TAC);
10906
10907(* ------------------------------------------------------------------------- *)
10908(* Openness of halfspaces.                                                   *)
10909(* ------------------------------------------------------------------------- *)
10910
10911val OPEN_HALFSPACE_LT = store_thm ("OPEN_HALFSPACE_LT",
10912 ``!a b. open {x | a * x < b}``,
10913  REWRITE_TAC[GSYM REAL_NOT_LE] THEN
10914  SIMP_TAC std_ss [SET_RULE ``{x | ~p x} = UNIV DIFF {x | p x}``] THEN
10915  REWRITE_TAC[GSYM closed_def, GSYM real_ge, CLOSED_HALFSPACE_GE]);
10916
10917val OPEN_HALFSPACE_COMPONENT_LT = store_thm ("OPEN_HALFSPACE_COMPONENT_LT",
10918 ``!a. open {x:real | x < a}``,
10919  REPEAT GEN_TAC THEN
10920  MP_TAC(ISPECL [``1:real``, ``a:real``] OPEN_HALFSPACE_LT) THEN
10921  ASM_SIMP_TAC std_ss [REAL_MUL_LID]);
10922
10923val OPEN_HALFSPACE_GT = store_thm ("OPEN_HALFSPACE_GT",
10924 ``!a b. open {x | a * x > b}``,
10925  REWRITE_TAC[REAL_ARITH ``x > y <=> ~(x <= y:real)``] THEN
10926  SIMP_TAC std_ss [SET_RULE ``{x | ~p x} = UNIV DIFF {x | p x}``] THEN
10927  REWRITE_TAC[GSYM closed_def, CLOSED_HALFSPACE_LE]);
10928
10929val OPEN_HALFSPACE_COMPONENT_GT = store_thm ("OPEN_HALFSPACE_COMPONENT_GT",
10930 ``!a. open {x:real | x > a}``,
10931  REPEAT GEN_TAC THEN
10932  MP_TAC(ISPECL [``1:real``, ``a:real``] OPEN_HALFSPACE_GT) THEN
10933  ASM_SIMP_TAC std_ss [REAL_MUL_LID]);
10934
10935val OPEN_POSITIVE_MULTIPLES = store_thm ("OPEN_POSITIVE_MULTIPLES",
10936 ``!s:real->bool. open s ==> open {c * x | &0 < c /\ x IN s}``,
10937  SIMP_TAC std_ss [open_def, FORALL_IN_GSPEC] THEN GEN_TAC THEN DISCH_TAC THEN
10938  MAP_EVERY X_GEN_TAC [``c:real``, ``x:real``] THEN STRIP_TAC THEN
10939  FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_SIMP_TAC std_ss [] THEN
10940  DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
10941  EXISTS_TAC ``c * e:real`` THEN ASM_SIMP_TAC std_ss [REAL_LT_MUL] THEN
10942  X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN
10943  FIRST_X_ASSUM(MP_TAC o SPEC ``inv(c) * y:real``) THEN
10944  KNOW_TAC ``(dist (inv (c :real) * (y :real),(x :real)) :real) < (e :real)`` THENL
10945   [SUBGOAL_THEN ``x:real = inv c * c * x`` SUBST1_TAC THENL
10946     [ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID,
10947                   REAL_LT_IMP_NE],
10948          ONCE_REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN
10949      ASM_SIMP_TAC std_ss [DIST_MUL, abs, REAL_LT_INV_EQ, REAL_LT_IMP_LE] THEN
10950      ONCE_REWRITE_TAC[METIS [REAL_MUL_SYM, GSYM real_div] ``inv c * x:real = x / c:real``] THEN
10951      METIS_TAC[REAL_LT_LDIV_EQ, REAL_MUL_SYM]],
10952        DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
10953    DISCH_TAC THEN SRW_TAC [][] THEN
10954    EXISTS_TAC ``c:real`` THEN EXISTS_TAC ``inv(c) * y:real`` THEN
10955    ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_RINV, REAL_LT_IMP_NE] THEN
10956    REAL_ARITH_TAC]);
10957
10958val OPEN_INTERVAL_LEFT = store_thm ("OPEN_INTERVAL_LEFT",
10959 ``!b:real. open {x:real | x < b}``,
10960    REWRITE_TAC[OPEN_HALFSPACE_COMPONENT_LT]);
10961
10962val OPEN_INTERVAL_RIGHT = store_thm ("OPEN_INTERVAL_RIGHT",
10963 ``!a:real. open {x:real | a < x}``,
10964    REWRITE_TAC[GSYM real_gt, OPEN_HALFSPACE_COMPONENT_GT]);
10965
10966val OPEN_POSITIVE_ORTHANT = store_thm ("OPEN_POSITIVE_ORTHANT",
10967 ``open {x:real | &0 < x}``,
10968  MP_TAC(ISPEC ``0:real`` OPEN_INTERVAL_RIGHT) THEN
10969  REWRITE_TAC[]);
10970
10971(* ------------------------------------------------------------------------- *)
10972(* Closures and interiors of halfspaces.                                     *)
10973(* ------------------------------------------------------------------------- *)
10974
10975val INTERIOR_HALFSPACE_LE = store_thm ("INTERIOR_HALFSPACE_LE",
10976 ``!a:real b.
10977        ~(a = 0) ==> (interior {x | a * x <= b} = {x | a * x < b})``,
10978  REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN
10979  SIMP_TAC std_ss [OPEN_HALFSPACE_LT, SUBSET_DEF, GSPECIFICATION, REAL_LT_IMP_LE] THEN
10980  X_GEN_TAC ``s:real->bool`` THEN STRIP_TAC THEN
10981  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN ASM_SIMP_TAC std_ss [REAL_LT_LE] THEN
10982  DISCH_TAC THEN UNDISCH_TAC ``open s`` THEN DISCH_TAC THEN
10983  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_CONTAINS_CBALL]) THEN
10984  DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
10985  DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
10986  REWRITE_TAC[SUBSET_DEF, IN_CBALL] THEN
10987  DISCH_THEN(MP_TAC o SPEC ``x + e / abs(a) * a:real``) THEN
10988  REWRITE_TAC[METIS [dist, REAL_ADD_SUB2, ABS_NEG] ``dist(x:real,x + y) = abs y``] THEN
10989  ASM_SIMP_TAC std_ss [ABS_MUL, ABS_DIV, ABS_ABS, REAL_DIV_RMUL,
10990               ABS_ZERO, REAL_ARITH ``&0 < x ==> abs x <= x:real``] THEN
10991  DISCH_TAC THEN
10992  FIRST_X_ASSUM(MP_TAC o SPEC ``x + e / abs(a) * a:real``) THEN
10993  ASM_REWRITE_TAC [REAL_LDISTRIB] THEN
10994  REWRITE_TAC [REAL_ARITH ``a * (b * a) = b * (a * a:real)``] THEN
10995  MATCH_MP_TAC(REAL_ARITH ``&0 < e ==> ~(b + e <= b:real)``) THEN
10996  ASM_SIMP_TAC std_ss [REAL_LT_MUL, REAL_LT_DIV, GSYM ABS_NZ, REAL_POSSQ]);
10997
10998val INTERIOR_HALFSPACE_GE = store_thm ("INTERIOR_HALFSPACE_GE",
10999 ``!a:real b.
11000        ~(a = 0) ==> (interior {x | a * x >= b} = {x | a * x > b})``,
11001  REPEAT STRIP_TAC THEN
11002  ONCE_REWRITE_TAC[REAL_ARITH ``a >= b <=> -a <= -b:real``,
11003                   REAL_ARITH ``a > b <=> -a < -b:real``] THEN
11004  ASM_SIMP_TAC std_ss [REAL_NEG_LMUL, INTERIOR_HALFSPACE_LE, REAL_NEG_EQ0]);
11005
11006val INTERIOR_HALFSPACE_COMPONENT_LE = store_thm ("INTERIOR_HALFSPACE_COMPONENT_LE",
11007 ``!a. interior {x:real | x <= a} = {x | x < a}``,
11008  REPEAT GEN_TAC THEN
11009  MP_TAC(ISPECL [``1:real``, ``a:real``] INTERIOR_HALFSPACE_LE) THEN
11010  ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]);
11011
11012val INTERIOR_HALFSPACE_COMPONENT_GE = store_thm ("INTERIOR_HALFSPACE_COMPONENT_GE",
11013 ``!a. interior {x:real | x >= a} = {x | x > a}``,
11014  REPEAT GEN_TAC THEN
11015  MP_TAC(ISPECL [``1:real``, ``a:real``] INTERIOR_HALFSPACE_GE) THEN
11016  ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]);
11017
11018val CLOSURE_HALFSPACE_LT = store_thm ("CLOSURE_HALFSPACE_LT",
11019 ``!a:real b.
11020        ~(a = 0) ==> (closure {x | a * x < b} = {x | a * x <= b})``,
11021  REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSURE_INTERIOR] THEN
11022  SIMP_TAC std_ss [SET_RULE ``UNIV DIFF {x | P x} = {x | ~P x}``] THEN
11023  ASM_SIMP_TAC std_ss [REAL_ARITH ``~(x < b) <=> x >= b:real``, INTERIOR_HALFSPACE_GE] THEN
11024  SIMP_TAC std_ss [EXTENSION, IN_DIFF, IN_UNIV, GSPECIFICATION] THEN REAL_ARITH_TAC);
11025
11026val CLOSURE_HALFSPACE_GT = store_thm ("CLOSURE_HALFSPACE_GT",
11027 ``!a:real b.
11028        ~(a = 0) ==> (closure {x | a * x > b} = {x | a * x >= b})``,
11029  REPEAT STRIP_TAC THEN
11030  ONCE_REWRITE_TAC[REAL_ARITH ``a >= b <=> -a <= -b:real``,
11031                   REAL_ARITH ``a > b <=> -a < -b:real``] THEN
11032  ASM_SIMP_TAC std_ss [REAL_NEG_LMUL, CLOSURE_HALFSPACE_LT, REAL_NEG_EQ0]);
11033
11034val CLOSURE_HALFSPACE_COMPONENT_LT = store_thm ("CLOSURE_HALFSPACE_COMPONENT_LT",
11035 ``!a. closure {x:real | x < a} = {x | x <= a}``,
11036  REPEAT GEN_TAC THEN
11037  MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSURE_HALFSPACE_LT) THEN
11038  ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]);
11039
11040val CLOSURE_HALFSPACE_COMPONENT_GT = store_thm ("CLOSURE_HALFSPACE_COMPONENT_GT",
11041 ``!a. closure {x:real | x > a} = {x | x >= a}``,
11042  REPEAT GEN_TAC THEN
11043  MP_TAC(ISPECL [``1:real``, ``a:real``] CLOSURE_HALFSPACE_GT) THEN
11044  ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]);
11045
11046val INTERIOR_HYPERPLANE = store_thm ("INTERIOR_HYPERPLANE",
11047 ``!a b. ~(a = 0) ==> (interior {x | a * x = b} = {})``,
11048  REWRITE_TAC[REAL_ARITH ``(x = y) <=> x <= y /\ x >= y:real``] THEN
11049  SIMP_TAC std_ss [SET_RULE ``{x | p x /\ q x} = {x | p x} INTER {x | q x}``] THEN
11050  REWRITE_TAC[INTERIOR_INTER] THEN
11051  REWRITE_TAC [GSYM DE_MORGAN_THM, REAL_ARITH ``x <= y /\ x >= y:real <=> (x = y)``] THEN
11052  ASM_SIMP_TAC std_ss [INTERIOR_HALFSPACE_LE, INTERIOR_HALFSPACE_GE] THEN
11053  SIMP_TAC std_ss [EXTENSION, IN_INTER, GSPECIFICATION, NOT_IN_EMPTY] THEN
11054  REAL_ARITH_TAC);
11055
11056val FRONTIER_HALFSPACE_LE = store_thm ("FRONTIER_HALFSPACE_LE",
11057 ``!a:real b. ~((a = 0) /\ (b = &0))
11058                ==> (frontier {x | a * x <= b} = {x | a * x = b})``,
11059  REPEAT GEN_TAC THEN ASM_CASES_TAC ``a:real = 0`` THEN
11060  ASM_SIMP_TAC std_ss [REAL_MUL_LZERO] THENL
11061   [ASM_CASES_TAC ``&0 <= b:real`` THEN
11062    ASM_SIMP_TAC std_ss [GSPEC_T, FRONTIER_UNIV, GSPEC_F, FRONTIER_EMPTY],
11063    ASM_SIMP_TAC std_ss [frontier, INTERIOR_HALFSPACE_LE, CLOSURE_CLOSED,
11064                 CLOSED_HALFSPACE_LE] THEN
11065    SIMP_TAC std_ss [EXTENSION, IN_DIFF, GSPECIFICATION] THEN REAL_ARITH_TAC]);
11066
11067val FRONTIER_HALFSPACE_GE = store_thm ("FRONTIER_HALFSPACE_GE",
11068 ``!a:real b. ~((a = 0) /\ (b = &0))
11069                ==> (frontier {x | a * x >= b} = {x | a * x = b})``,
11070  REPEAT STRIP_TAC THEN
11071  MP_TAC(ISPECL [``-a:real``, ``-b:real``] FRONTIER_HALFSPACE_LE) THEN
11072  ASM_REWRITE_TAC [REAL_NEG_EQ0, REAL_NEG_LMUL] THEN
11073  REWRITE_TAC [GSYM REAL_NEG_LMUL] THEN REWRITE_TAC [REAL_EQ_NEG] THEN
11074  SIMP_TAC std_ss [REAL_LE_NEG2, real_ge]);
11075
11076val FRONTIER_HALFSPACE_LT = store_thm ("FRONTIER_HALFSPACE_LT",
11077 ``!a:real b. ~((a = 0) /\ (b = &0))
11078                ==> (frontier {x | a * x < b} = {x | a * x = b})``,
11079  REPEAT GEN_TAC THEN ASM_CASES_TAC ``a:real = 0`` THEN
11080  ASM_SIMP_TAC std_ss [REAL_NEG_LMUL] THENL
11081   [ASM_CASES_TAC ``&0 < b:real`` THEN REWRITE_TAC [REAL_MUL_LZERO] THEN
11082    ASM_SIMP_TAC std_ss [GSPEC_T, FRONTIER_UNIV, GSPEC_F, FRONTIER_EMPTY],
11083    ASM_SIMP_TAC std_ss [frontier, CLOSURE_HALFSPACE_LT, INTERIOR_OPEN,
11084                 OPEN_HALFSPACE_LT] THEN
11085    SIMP_TAC std_ss [EXTENSION, IN_DIFF, GSPECIFICATION] THEN REAL_ARITH_TAC]);
11086
11087val FRONTIER_HALFSPACE_GT = store_thm ("FRONTIER_HALFSPACE_GT",
11088 ``!a:real b. ~((a = 0) /\ (b = &0))
11089                ==> (frontier {x | a * x > b} = {x | a * x = b})``,
11090  REPEAT STRIP_TAC THEN
11091  MP_TAC(ISPECL [``-a:real``, ``-b:real``] FRONTIER_HALFSPACE_LT) THEN
11092  ASM_REWRITE_TAC[REAL_NEG_EQ0, REAL_MUL_LNEG] THEN
11093  SIMP_TAC std_ss [REAL_LT_NEG, REAL_EQ_NEG, real_gt]);
11094
11095val INTERIOR_STANDARD_HYPERPLANE = store_thm ("INTERIOR_STANDARD_HYPERPLANE",
11096 ``!a. interior {x:real | x = a} = {}``,
11097  REPEAT GEN_TAC THEN
11098  MP_TAC(ISPECL [``1:real``, ``a:real``] INTERIOR_HYPERPLANE) THEN
11099  ONCE_REWRITE_TAC [REAL_ARITH ``1 <> 0:real``] THEN SIMP_TAC std_ss [REAL_MUL_LID]);
11100
11101(* ------------------------------------------------------------------------- *)
11102(* Unboundedness of halfspaces.                                              *)
11103(* ------------------------------------------------------------------------- *)
11104
11105val UNBOUNDED_HALFSPACE_COMPONENT_LE = store_thm
11106  ("UNBOUNDED_HALFSPACE_COMPONENT_LE",
11107  ``!a. ~bounded {x:real | x <= a}``,
11108    REPEAT GEN_TAC
11109 >> ASM_SIMP_TAC std_ss [bounded_def, FORALL_IN_GSPEC]
11110 >> X_GEN_TAC ``B:real``
11111 >> EXISTS_TAC ``-((&1:real) + max (abs B) (abs a))``
11112 >> REWRITE_TAC [ABS_NEG, REAL_NOT_LE, REAL_NEG_ADD]
11113 >> RW_TAC bool_ss [abs, max_def]
11114 >> FULL_SIMP_TAC real_ss [REAL_NOT_LE]
11115 >| (* 12 goals *)
11116  [ ASM_REAL_ARITH_TAC, (* 1 *)
11117    ASM_REAL_ARITH_TAC, (* 2 *)
11118    Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [] >> ASM_REAL_ARITH_TAC, (* 3 *)
11119    Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC, (* 4 *)
11120    Cases_on `0 <= B` >> FULL_SIMP_TAC real_ss [] >> ASM_REAL_ARITH_TAC, (* 5 *)
11121    Cases_on `0 <= B` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC, (* 6 *)
11122    Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [] >> ASM_REAL_ARITH_TAC, (* 7 *)
11123    ASM_REAL_ARITH_TAC, (* 8 *)
11124    Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [] >> ASM_REAL_ARITH_TAC, (* 9 *)
11125    Cases_on `0 <= B` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC, (* 10 *)
11126    Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC, (* 11 *)
11127    Cases_on `0 <= a` >> FULL_SIMP_TAC real_ss [GSYM REAL_NOT_LE] >> ASM_REAL_ARITH_TAC ]);
11128
11129val UNBOUNDED_HALFSPACE_COMPONENT_GE = store_thm
11130  ("UNBOUNDED_HALFSPACE_COMPONENT_GE",
11131 ``!a. ~bounded {x:real | x >= a}``,
11132  REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_NEGATIONS) THEN
11133  MP_TAC(SPECL [``-a:real``] UNBOUNDED_HALFSPACE_COMPONENT_LE) THEN
11134  REWRITE_TAC[GSYM MONO_NOT_EQ] THEN MATCH_MP_TAC EQ_IMPLIES THEN
11135  AP_TERM_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN CONJ_TAC THENL
11136   [MESON_TAC[REAL_NEG_NEG],
11137    SIMP_TAC std_ss [GSPECIFICATION] THEN REAL_ARITH_TAC]);
11138
11139val UNBOUNDED_HALFSPACE_COMPONENT_LT = store_thm ("UNBOUNDED_HALFSPACE_COMPONENT_LT",
11140 ``!a. ~bounded {x:real | x < a}``,
11141  ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN
11142  REWRITE_TAC[CLOSURE_HALFSPACE_COMPONENT_LT,
11143              UNBOUNDED_HALFSPACE_COMPONENT_LE]);
11144
11145val UNBOUNDED_HALFSPACE_COMPONENT_GT = store_thm ("UNBOUNDED_HALFSPACE_COMPONENT_GT",
11146 ``!a. ~bounded {x:real | x > a}``,
11147  ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN
11148  REWRITE_TAC[CLOSURE_HALFSPACE_COMPONENT_GT,
11149              UNBOUNDED_HALFSPACE_COMPONENT_GE]);
11150
11151(* ------------------------------------------------------------------------- *)
11152(* Equality of continuous functions on closure and related results.          *)
11153(* ------------------------------------------------------------------------- *)
11154
11155val FORALL_IN_CLOSURE = store_thm ("FORALL_IN_CLOSURE",
11156 ``!f:real->real s t.
11157        closed t /\ f continuous_on (closure s) /\
11158        (!x. x IN s ==> f x IN t)
11159        ==> (!x. x IN closure s ==> f x IN t)``,
11160  REWRITE_TAC[SET_RULE ``(!x. x IN s ==> f x IN t) <=>
11161                        s SUBSET {x | x IN s /\ f x IN t}``] THEN
11162  REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN
11163  ASM_REWRITE_TAC[CLOSED_CLOSURE] THEN CONJ_TAC THENL
11164   [MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[],
11165    MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN
11166    ASM_REWRITE_TAC[CLOSED_CLOSURE]]);
11167
11168val FORALL_IN_CLOSURE_EQ = store_thm ("FORALL_IN_CLOSURE_EQ",
11169 ``!f s t.
11170         closed t /\ f continuous_on closure s
11171         ==> ((!x. x IN closure s ==> f x IN t) <=>
11172              (!x. x IN s ==> f x IN t))``,
11173  METIS_TAC[FORALL_IN_CLOSURE, CLOSURE_SUBSET, SUBSET_DEF]);
11174
11175val CONTINUOUS_LE_ON_CLOSURE = store_thm ("CONTINUOUS_LE_ON_CLOSURE",
11176 ``!f:real->real s a.
11177        f continuous_on closure(s) /\ (!x. x IN s ==> f(x) <= a)
11178        ==> !x. x IN closure(s) ==> f(x) <= a``,
11179  REPEAT GEN_TAC THEN STRIP_TAC THEN
11180  KNOW_TAC `` !(x :real). x IN closure (s :real -> bool)
11181           ==> (f :real -> real) x IN {y | y <= (a :real)}`` THENL
11182  [ALL_TAC, SET_TAC []] THEN
11183  MATCH_MP_TAC FORALL_IN_CLOSURE THEN
11184  ASM_SIMP_TAC std_ss [ETA_AX, CLOSED_HALFSPACE_COMPONENT_LE] THEN ASM_SET_TAC []);
11185
11186val CONTINUOUS_GE_ON_CLOSURE = store_thm ("CONTINUOUS_GE_ON_CLOSURE",
11187 ``!f:real->real s a.
11188        f continuous_on closure(s) /\ (!x. x IN s ==> a <= f(x))
11189        ==> !x. x IN closure(s) ==> a <= f(x)``,
11190  REPEAT GEN_TAC THEN STRIP_TAC THEN
11191  KNOW_TAC `` !(x :real). x IN closure (s :real -> bool)
11192           ==> (f :real -> real) x IN {y | y >= (a :real)}`` THENL
11193  [ALL_TAC, SET_TAC [real_ge]] THEN
11194  MATCH_MP_TAC FORALL_IN_CLOSURE THEN
11195  ASM_SIMP_TAC std_ss [ETA_AX, CLOSED_HALFSPACE_COMPONENT_GE] THEN ASM_SET_TAC [real_ge]);
11196
11197val CONTINUOUS_CONSTANT_ON_CLOSURE = store_thm ("CONTINUOUS_CONSTANT_ON_CLOSURE",
11198 ``!f:real->real s a.
11199        f continuous_on closure(s) /\ (!x. x IN s ==> (f(x) = a))
11200        ==> !x. x IN closure(s) ==> (f(x) = a)``,
11201  REWRITE_TAC[SET_RULE
11202   ``x IN s ==> (f x = a) <=> x IN s ==> f x IN {a}``] THEN
11203  REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC FORALL_IN_CLOSURE THEN
11204  ASM_REWRITE_TAC[CLOSED_SING]);
11205
11206val CONTINUOUS_AGREE_ON_CLOSURE = store_thm ("CONTINUOUS_AGREE_ON_CLOSURE",
11207 ``!g h:real->real.
11208        g continuous_on closure s /\ h continuous_on closure s /\
11209        (!x. x IN s ==> (g x = h x))
11210        ==> !x. x IN closure s ==> (g x = h x)``,
11211  REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN STRIP_TAC THEN
11212  ONCE_REWRITE_TAC [METIS [] ``(g x - h x = 0) =  ((\x. g x - h x) x = 0:real)``] THEN
11213  MATCH_MP_TAC CONTINUOUS_CONSTANT_ON_CLOSURE THEN
11214  ASM_SIMP_TAC std_ss [CONTINUOUS_ON_SUB]);
11215
11216val CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT = store_thm ("CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT",
11217 ``!f:real->real s a.
11218        f continuous_on s
11219        ==> closed_in (subtopology euclidean s) {x | x IN s /\ (f x = a)}``,
11220  REPEAT STRIP_TAC THEN
11221  ONCE_REWRITE_TAC[SET_RULE
11222   ``{x | x IN s /\ (f(x) = a)} = {x | x IN s /\ f(x) IN {a}}``] THEN
11223  MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN
11224  ASM_REWRITE_TAC[CLOSED_SING]);
11225
11226val CONTINUOUS_CLOSED_PREIMAGE_CONSTANT = store_thm ("CONTINUOUS_CLOSED_PREIMAGE_CONSTANT",
11227 ``!f:real->real s.
11228      f continuous_on s /\ closed s ==> closed {x | x IN s /\ (f(x) = a)}``,
11229  REPEAT STRIP_TAC THEN
11230  ASM_CASES_TAC ``{x | x IN s /\ ((f:real->real)(x) = a)} = {}`` THEN
11231  ASM_REWRITE_TAC[CLOSED_EMPTY] THEN ONCE_REWRITE_TAC[SET_RULE
11232   ``{x | x IN s /\ (f(x) = a)} = {x | x IN s /\ f(x) IN {a}}``] THEN
11233  MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN
11234  ASM_REWRITE_TAC[CLOSED_SING] THEN ASM_SET_TAC[]);
11235
11236(* ------------------------------------------------------------------------- *)
11237(* Theorems relating continuity and uniform continuity to closures.          *)
11238(* ------------------------------------------------------------------------- *)
11239
11240val CONTINUOUS_ON_CLOSURE = store_thm ("CONTINUOUS_ON_CLOSURE",
11241 ``!f:real->real s.
11242        f continuous_on closure s <=>
11243        !x e. x IN closure s /\ &0 < e
11244              ==> ?d. &0 < d /\
11245                      !y. y IN s /\ dist(y,x) < d ==> dist(f y,f x) < e``,
11246  REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on] THEN
11247  EQ_TAC THENL [METIS_TAC[REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET], ALL_TAC] THEN
11248  DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
11249  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
11250  FIRST_ASSUM(MP_TAC o SPECL [``x:real``, ``e / &2:real``]) THEN
11251  KNOW_TAC ``x IN closure s:real->bool /\ 0 < e / 2:real`` THENL
11252  [ASM_REWRITE_TAC[REAL_HALF], DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [])] THEN
11253  DISCH_TAC THEN FIRST_ASSUM (fn th => REWRITE_TAC [th]) THEN
11254  DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
11255  EXISTS_TAC ``d / &2:real`` THEN ASM_REWRITE_TAC[REAL_HALF] THEN
11256  X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN
11257  FIRST_X_ASSUM(MP_TAC o SPECL [``y:real``, ``e / &2:real``]) THEN
11258  ASM_REWRITE_TAC[REAL_HALF] THEN
11259  DISCH_THEN(X_CHOOSE_THEN ``k:real`` STRIP_ASSUME_TAC) THEN
11260  MP_TAC(ISPECL [``y:real``, ``s:real->bool``] CLOSURE_APPROACHABLE) THEN
11261  ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``min k (d / &2:real)``) THEN
11262  ASM_REWRITE_TAC[REAL_HALF, REAL_LT_MIN] THEN
11263  KNOW_TAC ``!a b c e. abs(a - b) < e / &2 /\ abs(b - c) < e / &2:real ==>
11264                                    abs(a - c) < e / 2 + e / 2:real`` THENL
11265  [REAL_ARITH_TAC, DISCH_TAC] THEN STRIP_TAC THEN
11266  GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN REWRITE_TAC [dist] THEN
11267  FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC ``(f:real->real) y'`` THEN CONJ_TAC THENL
11268  [REWRITE_TAC [GSYM dist] THEN ONCE_REWRITE_TAC [DIST_SYM] THEN
11269   FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC [],
11270   REWRITE_TAC [GSYM dist] THEN FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC [] THEN
11271   MATCH_MP_TAC DIST_TRIANGLE_LT THEN EXISTS_TAC ``y:real`` THEN
11272   GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN MATCH_MP_TAC REAL_LT_ADD2 THEN
11273   METIS_TAC [DIST_SYM]]);
11274
11275val CONTINUOUS_ON_CLOSURE_SEQUENTIALLY = store_thm ("CONTINUOUS_ON_CLOSURE_SEQUENTIALLY",
11276 ``!f:real->real s.
11277        f continuous_on closure s <=>
11278        !x a. a IN closure s /\ (!n. x n IN s) /\ (x --> a) sequentially
11279              ==> ((f o x) --> f a) sequentially``,
11280  REWRITE_TAC[CONTINUOUS_ON_CLOSURE] THEN
11281  SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN
11282  REWRITE_TAC[AND_IMP_INTRO, GSYM continuous_within] THEN
11283  REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY] THEN MESON_TAC[]);
11284
11285val UNIFORMLY_CONTINUOUS_ON_CLOSURE = store_thm ("UNIFORMLY_CONTINUOUS_ON_CLOSURE",
11286 ``!f:real->real s.
11287        f uniformly_continuous_on s /\ f continuous_on closure s
11288        ==> f uniformly_continuous_on closure s``,
11289  REPEAT GEN_TAC THEN
11290  REWRITE_TAC[uniformly_continuous_on] THEN STRIP_TAC THEN
11291  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
11292  FIRST_X_ASSUM(MP_TAC o SPEC ``e / &3:real``) THEN
11293  KNOW_TAC ``0 < e / 3:real`` THENL
11294  [FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN
11295   ASM_REAL_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
11296  DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
11297  EXISTS_TAC ``d / &3:real`` THEN CONJ_TAC THENL
11298  [FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN
11299   REWRITE_TAC [REAL_MUL_LZERO] THEN ASM_REWRITE_TAC [], ALL_TAC] THEN
11300  MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN
11301  UNDISCH_TAC ``f continuous_on closure s`` THEN DISCH_TAC THEN
11302  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [continuous_on]) THEN
11303  DISCH_THEN(fn th =>
11304    MP_TAC(SPEC ``y:real`` th) THEN MP_TAC(SPEC ``x:real`` th)) THEN
11305  ASM_REWRITE_TAC[] THEN
11306  DISCH_THEN(MP_TAC o SPEC ``e / &3:real``) THEN ASM_REWRITE_TAC [] THEN
11307  DISCH_THEN(X_CHOOSE_THEN ``d1:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
11308  MP_TAC(ISPECL [``x:real``, ``s:real->bool``] CLOSURE_APPROACHABLE) THEN
11309  ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``min d1 (d / &3:real)``) THEN
11310  KNOW_TAC ``0 < min d1 (d / 3:real)`` THENL
11311  [REWRITE_TAC [min_def] THEN COND_CASES_TAC THEN
11312   FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN
11313   REWRITE_TAC [REAL_MUL_LZERO] THEN ASM_REWRITE_TAC [],
11314   DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
11315  REWRITE_TAC[REAL_LT_MIN] THEN
11316  DISCH_THEN(X_CHOOSE_THEN ``x':real`` STRIP_ASSUME_TAC) THEN
11317  DISCH_THEN(MP_TAC o SPEC ``x':real``) THEN
11318  ASM_SIMP_TAC std_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET] THEN DISCH_TAC THEN
11319  DISCH_THEN(MP_TAC o SPEC ``e / &3:real``) THEN ASM_REWRITE_TAC [] THEN
11320  DISCH_THEN(X_CHOOSE_THEN ``d2:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
11321  MP_TAC(ISPECL [``y:real``, ``s:real->bool``] CLOSURE_APPROACHABLE) THEN
11322  ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``min d2 (d / &3:real)``) THEN
11323  KNOW_TAC ``0 < min d2 (d / 3:real)`` THENL
11324  [REWRITE_TAC [min_def] THEN COND_CASES_TAC THEN
11325   FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN
11326   REWRITE_TAC [REAL_MUL_LZERO] THEN ASM_REWRITE_TAC [],
11327   DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
11328  REWRITE_TAC[REAL_LT_MIN] THEN
11329  DISCH_THEN(X_CHOOSE_THEN ``y':real`` STRIP_ASSUME_TAC) THEN
11330  DISCH_THEN(MP_TAC o SPEC ``y':real``) THEN
11331  ASM_SIMP_TAC std_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET] THEN DISCH_TAC THEN
11332  FIRST_X_ASSUM(MP_TAC o SPECL [``x':real``, ``y':real``]) THEN
11333  FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN
11334  METIS_TAC[dist, ABS_SUB, REAL_ARITH
11335   ``abs(y - x) * 3 < d /\ abs(x' - x) * 3 < d /\ abs(y' - y) * 3 < d
11336    ==> abs(y' - x') < d:real``]);
11337
11338(* ------------------------------------------------------------------------- *)
11339(* Cauchy continuity, and the extension of functions to closures.            *)
11340(* ------------------------------------------------------------------------- *)
11341
11342val UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS = store_thm
11343  ("UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS",
11344 ``!f:real->real s.
11345        f uniformly_continuous_on s
11346        ==> (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))``,
11347  REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on, cauchy, o_DEF] THEN
11348  MESON_TAC[]);
11349
11350val CONTINUOUS_CLOSED_IMP_CAUCHY_CONTINUOUS = store_thm
11351  ("CONTINUOUS_CLOSED_IMP_CAUCHY_CONTINUOUS",
11352 ``!f:real->real s.
11353        f continuous_on s /\ closed s
11354        ==> (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))``,
11355  REWRITE_TAC[GSYM COMPLETE_EQ_CLOSED, CONTINUOUS_ON_SEQUENTIALLY] THEN
11356  REWRITE_TAC[complete] THEN MESON_TAC[CONVERGENT_IMP_CAUCHY]);
11357
11358val CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA = store_thm
11359  ("CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA",
11360 ``!f:real->real s.
11361        (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))
11362        ==> !a x. (!n. (x n) IN s) /\ (x --> a) sequentially
11363                  ==> ?l. ((f o x) --> l) sequentially /\
11364                          !y. (!n. (y n) IN s) /\ (y --> a) sequentially
11365                              ==> ((f o y) --> l) sequentially``,
11366  REPEAT STRIP_TAC THEN
11367  FIRST_ASSUM(MP_TAC o SPEC ``x:num->real``) THEN
11368  KNOW_TAC ``cauchy x /\ (!n. x n IN s)`` THENL
11369  [ASM_MESON_TAC[CONVERGENT_IMP_CAUCHY],
11370    DISCH_THEN (fn th => REWRITE_TAC [th])] THEN
11371  REWRITE_TAC [GSYM CONVERGENT_EQ_CAUCHY] THEN
11372  DISCH_THEN (X_CHOOSE_TAC ``l:real``) THEN EXISTS_TAC ``l:real`` THEN
11373  ASM_REWRITE_TAC [] THEN
11374  X_GEN_TAC ``y:num->real`` THEN STRIP_TAC THEN
11375  FIRST_ASSUM(MP_TAC o SPEC ``y:num->real``) THEN
11376  KNOW_TAC ``cauchy y /\ (!n. y n IN s)`` THENL
11377  [ASM_MESON_TAC[CONVERGENT_IMP_CAUCHY],
11378    DISCH_THEN (fn th => REWRITE_TAC [th])] THEN
11379  REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN
11380  DISCH_THEN(X_CHOOSE_THEN ``l':real`` STRIP_ASSUME_TAC) THEN
11381  SUBGOAL_THEN ``l:real = l'`` (fn th => ASM_REWRITE_TAC[th]) THEN
11382  ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN
11383  MATCH_MP_TAC(ISPEC ``sequentially`` LIM_UNIQUE) THEN
11384  EXISTS_TAC ``\n:num. (f:real->real)(x n) - f(y n)`` THEN
11385  RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN
11386  ASM_SIMP_TAC std_ss [LIM_SUB, TRIVIAL_LIMIT_SEQUENTIALLY] THEN
11387  FIRST_X_ASSUM(MP_TAC o SPEC
11388   ``\n. if EVEN n then x(n DIV 2):real else y(n DIV 2)``) THEN
11389  REWRITE_TAC[cauchy, o_THM, LIM_SEQUENTIALLY] THEN
11390  KNOW_TAC ``(!(e :real).
11391    (0 :real) < e ==>
11392    ?(N :num).
11393      !(m :num) (n :num).
11394        m >= N /\ n >= N ==>
11395        (dist
11396           ((\(n :num).
11397               if EVEN n then (x :num -> real) (n DIV (2 :num))
11398               else (y :num -> real) (n DIV (2 :num))) m,
11399            (\(n :num).
11400               if EVEN n then x (n DIV (2 :num))
11401               else y (n DIV (2 :num))) n) :real) < e) /\
11402      (!(n :num). (\(n :num).
11403       if EVEN n then x (n DIV (2 :num)) else y (n DIV (2 :num))) n IN
11404    (s :real -> bool))`` THENL
11405  [ (* goal 1 (of 2) *)
11406    CONJ_TAC THENL [ALL_TAC, METIS_TAC[]] THEN
11407    X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN MAP_EVERY UNDISCH_TAC
11408     [``((y:num->real) --> a) sequentially``,
11409      ``((x:num->real) --> a) sequentially``] THEN
11410    REWRITE_TAC[LIM_SEQUENTIALLY] THEN
11411    DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
11412    DISCH_THEN(X_CHOOSE_TAC ``N1:num``) THEN
11413    DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
11414    DISCH_THEN(X_CHOOSE_TAC ``N2:num``) THEN
11415    EXISTS_TAC ``2 * (N1 + N2:num)`` THEN
11416    MAP_EVERY X_GEN_TAC [``m:num``, ``n:num``] THEN STRIP_TAC THEN
11417    UNDISCH_TAC ``!n. (y:num->real) n IN s`` THEN DISCH_TAC THEN
11418    UNDISCH_TAC ``!n. (x:num->real) n IN s`` THEN DISCH_TAC THEN
11419    POP_ASSUM K_TAC THEN POP_ASSUM K_TAC THEN
11420    REPEAT(FIRST_X_ASSUM(fn th =>
11421      MP_TAC(SPEC ``m DIV 2`` th) THEN MP_TAC(SPEC ``n DIV 2`` th))) THEN
11422    KNOW_TAC ``N1 <= n DIV 2`` THENL
11423    [SIMP_TAC std_ss [X_LE_DIV, ARITH_PROVE ``0 < 2:num``] THEN
11424     ASM_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
11425     POP_ASSUM K_TAC THEN DISCH_TAC] THEN
11426    KNOW_TAC ``N1 <= m DIV 2`` THENL
11427    [SIMP_TAC std_ss [X_LE_DIV, ARITH_PROVE ``0 < 2:num``] THEN
11428     ASM_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
11429     POP_ASSUM K_TAC THEN DISCH_TAC] THEN
11430    KNOW_TAC ``N2 <= n DIV 2`` THENL
11431    [SIMP_TAC std_ss [X_LE_DIV, ARITH_PROVE ``0 < 2:num``] THEN
11432     ASM_SIMP_TAC arith_ss [], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
11433     POP_ASSUM K_TAC THEN DISCH_TAC] THEN
11434    KNOW_TAC ``N2 <= m DIV 2`` THENL
11435    [SIMP_TAC std_ss [X_LE_DIV, ARITH_PROVE ``0 < 2:num``] THEN
11436     ASM_SIMP_TAC arith_ss [], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
11437     POP_ASSUM K_TAC THEN DISCH_TAC] THEN
11438    REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN
11439    FULL_SIMP_TAC std_ss [dist, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
11440    Cases_on `EVEN m` >> Cases_on `EVEN n` >> fs [] >| (* 4 subgoals *)
11441    [ MP_TAC (Q.SPECL [`x (m DIV 2) - a`, `x (n DIV 2) - a`] ABS_TRIANGLE_NEG),
11442      MP_TAC (Q.SPECL [`x (m DIV 2) - a`, `y (n DIV 2) - a`] ABS_TRIANGLE_NEG),
11443      MP_TAC (Q.SPECL [`y (m DIV 2) - a`, `x (n DIV 2) - a`] ABS_TRIANGLE_NEG),
11444      MP_TAC (Q.SPECL [`y (m DIV 2) - a`, `y (n DIV 2) - a`] ABS_TRIANGLE_NEG) ]
11445    >> ASM_REAL_ARITH_TAC,
11446    (* goal 2 (of 2) *)
11447    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
11448    DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN
11449    ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[] THEN
11450    DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN
11451    X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN
11452    FIRST_X_ASSUM(MP_TAC o SPECL [``2 * n:num``, ``2 * n + 1:num``]) THEN
11453    KNOW_TAC ``2 * n >= N /\ 2 * n + 1 >= N:num`` THENL
11454    [ASM_SIMP_TAC arith_ss [], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
11455    SIMP_TAC arith_ss [EVEN_ADD, EVEN_MULT] THEN
11456    KNOW_TAC ``((2 * n) DIV 2 = n) /\ ((2 * n + 1) DIV 2 = n)`` THENL
11457    [SIMP_TAC arith_ss [DIV_EQ_X, ARITH_PROVE ``0 < 2:num``], ALL_TAC] THEN
11458    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
11459    REWRITE_TAC[dist, REAL_SUB_RZERO] ]);
11460
11461val CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE = store_thm ("CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE",
11462 ``!f:real->real s.
11463        (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))
11464        ==> ?g. g continuous_on closure s /\ (!x. x IN s ==> (g x = f x))``,
11465  REPEAT STRIP_TAC THEN
11466  SUBGOAL_THEN
11467   ``!a:real. ?x.
11468       a IN closure s ==> (!n. x n IN s) /\ (x --> a) sequentially``
11469  MP_TAC THENL [MESON_TAC[CLOSURE_SEQUENTIAL], ALL_TAC] THEN
11470  SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN
11471  X_GEN_TAC ``X:real->num->real`` THEN DISCH_TAC THEN
11472  FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA) THEN
11473  DISCH_THEN(MP_TAC o GEN ``a:real`` o
11474   SPECL [``a:real``, ``(X:real->num->real) a``]) THEN
11475  KNOW_TAC ``(!(a :real). a IN closure (s :real -> bool) ==>
11476   ?(l :real).
11477     (((f :real -> real) o X a --> l) sequentially :bool) /\
11478     !(y :num -> real).
11479       (!(n :num). y n IN s) /\ ((y --> a) sequentially :bool) ==>
11480       ((f o y --> l) sequentially :bool)) ==>
11481  ?(g :real -> real).
11482  g continuous_on closure s /\ !(x :real). x IN s ==> (g x = f x)`` THENL
11483  [ALL_TAC, METIS_TAC []] THEN DISCH_TAC THEN
11484  POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN
11485  SIMP_TAC std_ss [SKOLEM_THM] THEN
11486  DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN EXISTS_TAC ``g:real->real`` THEN
11487  POP_ASSUM MP_TAC THEN STRIP_TAC THEN
11488  MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
11489   [X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN
11490    FIRST_X_ASSUM(MP_TAC o SPEC ``a:real``) THEN
11491    ASM_SIMP_TAC std_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET] THEN
11492    DISCH_THEN(MP_TAC o SPEC ``(\n. a):num->real`` o CONJUNCT2) THEN
11493    ASM_SIMP_TAC std_ss [LIM_CONST_EQ, o_DEF, TRIVIAL_LIMIT_SEQUENTIALLY],
11494    STRIP_TAC] THEN
11495  ASM_SIMP_TAC std_ss [CONTINUOUS_ON_CLOSURE_SEQUENTIALLY] THEN
11496  MAP_EVERY X_GEN_TAC [``x:num->real``, ``a:real``] THEN STRIP_TAC THEN
11497  MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
11498  EXISTS_TAC ``(f:real->real) o (x:num->real)`` THEN ASM_SIMP_TAC std_ss [] THEN
11499  MATCH_MP_TAC ALWAYS_EVENTUALLY THEN ASM_SIMP_TAC std_ss [o_THM]);
11500
11501val UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE = store_thm ("UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE",
11502 ``!f:real->real s.
11503   f uniformly_continuous_on s
11504   ==> ?g. g uniformly_continuous_on closure s /\ (!x. x IN s ==> (g x = f x)) /\
11505           !h. h continuous_on closure s /\ (!x. x IN s ==> (h x = f x))
11506               ==> !x. x IN closure s ==> (h x = g x)``,
11507  REPEAT STRIP_TAC THEN
11508  FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE o
11509   MATCH_MP UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS) THEN
11510  STRIP_TAC THEN EXISTS_TAC ``g:real->real`` THEN
11511  ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THENL
11512   [METIS_TAC[UNIFORMLY_CONTINUOUS_ON_CLOSURE, UNIFORMLY_CONTINUOUS_ON_EQ],
11513    METIS_TAC[CONTINUOUS_AGREE_ON_CLOSURE]]);
11514
11515val CAUCHY_CONTINUOUS_IMP_CONTINUOUS = store_thm ("CAUCHY_CONTINUOUS_IMP_CONTINUOUS",
11516 ``!f:real->real s.
11517        (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))
11518        ==> f continuous_on s``,
11519  REPEAT STRIP_TAC THEN
11520  FIRST_ASSUM(CHOOSE_TAC o MATCH_MP CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE) THEN
11521  ASM_MESON_TAC[CONTINUOUS_ON_SUBSET, CLOSURE_SUBSET, CONTINUOUS_ON_EQ]);
11522
11523val BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE = store_thm ("BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE",
11524 ``!f:real->real s.
11525        f uniformly_continuous_on s /\ bounded s ==> bounded(IMAGE f s)``,
11526  REPEAT STRIP_TAC THEN FIRST_ASSUM
11527   (MP_TAC o MATCH_MP UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE) THEN
11528  DISCH_THEN(X_CHOOSE_THEN ``g:real->real`` STRIP_ASSUME_TAC) THEN
11529  MATCH_MP_TAC BOUNDED_SUBSET THEN
11530  EXISTS_TAC ``IMAGE (g:real->real) (closure s)`` THEN CONJ_TAC THENL
11531   [ASM_MESON_TAC[COMPACT_CLOSURE, UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS,
11532                  COMPACT_IMP_BOUNDED, COMPACT_CONTINUOUS_IMAGE],
11533    MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[]]);
11534
11535(* ------------------------------------------------------------------------- *)
11536(* Occasionally useful invariance properties.                                *)
11537(* ------------------------------------------------------------------------- *)
11538
11539val CONTINUOUS_AT_COMPOSE_EQ = store_thm ("CONTINUOUS_AT_COMPOSE_EQ",
11540 ``!f:real->real g:real->real h:real->real.
11541        g continuous at x /\ h continuous at (g x) /\
11542        (!y. g(h y) = y) /\ (h(g x) = x)
11543        ==> ((f continuous at (g x) <=> (\x. f(g x)) continuous at x))``,
11544  REPEAT STRIP_TAC THEN EQ_TAC THEN
11545  ASM_SIMP_TAC std_ss [REWRITE_RULE[o_DEF] CONTINUOUS_AT_COMPOSE] THEN
11546  DISCH_TAC THEN
11547  SUBGOAL_THEN
11548   ``((f:real->real) o (g:real->real) o (h:real->real))
11549     continuous at (g(x:real))``
11550  MP_TAC THENL
11551   [REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN
11552    ASM_REWRITE_TAC[o_DEF],
11553    ASM_SIMP_TAC std_ss [o_DEF, ETA_AX]]);
11554
11555val CONTINUOUS_AT_TRANSLATION = store_thm ("CONTINUOUS_AT_TRANSLATION",
11556 ``!a z f:real->real.
11557      f continuous at (a + z) <=> (\x. f(a + x)) continuous at z``,
11558  REPEAT GEN_TAC THEN
11559  ONCE_REWRITE_TAC [METIS [] ``a + z = (\z. a + z) z:real``] THEN
11560  MATCH_MP_TAC CONTINUOUS_AT_COMPOSE_EQ THEN
11561  EXISTS_TAC ``\x:real. x - a`` THEN
11562  SIMP_TAC std_ss [CONTINUOUS_ADD, CONTINUOUS_SUB,
11563           CONTINUOUS_AT_ID, CONTINUOUS_CONST] THEN
11564  REAL_ARITH_TAC);
11565
11566(* ------------------------------------------------------------------------- *)
11567(* Interior of an injective image.                                           *)
11568(* ------------------------------------------------------------------------- *)
11569
11570val INTERIOR_IMAGE_SUBSET = store_thm ("INTERIOR_IMAGE_SUBSET",
11571 ``!f:real->real s.
11572       (!x. f continuous at x) /\ (!x y. (f x = f y) ==> (x = y))
11573       ==> interior(IMAGE f s) SUBSET IMAGE f (interior s)``,
11574  REPEAT STRIP_TAC THEN REWRITE_TAC[SUBSET_DEF] THEN
11575  SIMP_TAC std_ss [interior, GSPECIFICATION] THEN
11576  X_GEN_TAC ``y:real`` THEN
11577  DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN
11578  SIMP_TAC std_ss [IN_IMAGE, GSPECIFICATION] THEN
11579  SUBGOAL_THEN ``y IN IMAGE (f:real->real) s`` MP_TAC THENL
11580   [ASM_SET_TAC[], ALL_TAC] THEN
11581  REWRITE_TAC[IN_IMAGE] THEN
11582  STRIP_TAC THEN EXISTS_TAC ``x:real`` THEN
11583  ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN
11584  EXISTS_TAC ``{x | (f:real->real)(x) IN t}`` THEN
11585  SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN CONJ_TAC THENL
11586   [MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE_UNIV THEN ASM_MESON_TAC[],
11587    ASM_SET_TAC[]]);
11588
11589(* ------------------------------------------------------------------------- *)
11590(* Making a continuous function avoid some value in a neighbourhood.         *)
11591(* ------------------------------------------------------------------------- *)
11592
11593val CONTINUOUS_WITHIN_AVOID = store_thm ("CONTINUOUS_WITHIN_AVOID",
11594 ``!f:real->real x s a.
11595        f continuous (at x within s) /\ x IN s /\  ~(f x = a)
11596        ==> ?e. &0 < e /\ !y. y IN s /\ dist(x,y) < e ==> ~(f y = a)``,
11597  REPEAT STRIP_TAC THEN
11598  UNDISCH_TAC ``f continuous (at x within s)`` THEN DISCH_TAC THEN
11599  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [continuous_within]) THEN
11600  DISCH_THEN(MP_TAC o SPEC ``abs((f:real->real) x - a)``) THEN
11601  ASM_REWRITE_TAC[GSYM ABS_NZ, REAL_SUB_0] THEN
11602  DISCH_THEN (X_CHOOSE_TAC ``d:real``) THEN EXISTS_TAC ``d:real`` THEN
11603  POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_AND THEN
11604  REWRITE_TAC[] THEN DISCH_TAC THEN X_GEN_TAC ``y:real`` THEN
11605  POP_ASSUM (MP_TAC o SPEC ``y:real``) THEN
11606  MATCH_MP_TAC MONO_IMP THEN SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
11607
11608val CONTINUOUS_AT_AVOID = store_thm ("CONTINUOUS_AT_AVOID",
11609 ``!f:real->real x a.
11610        f continuous (at x) /\ ~(f x = a)
11611        ==> ?e. &0 < e /\ !y. dist(x,y) < e ==> ~(f y = a)``,
11612  MP_TAC CONTINUOUS_WITHIN_AVOID THEN
11613  DISCH_TAC THEN GEN_TAC THEN GEN_TAC THEN
11614  POP_ASSUM (MP_TAC o SPECL [``f:real->real``,``x:real``]) THEN
11615  DISCH_THEN(MP_TAC o SPEC ``univ(:real)``) THEN
11616  DISCH_TAC THEN X_GEN_TAC ``a:real`` THEN POP_ASSUM (MP_TAC o SPEC ``a:real``) THEN
11617  REWRITE_TAC[WITHIN_UNIV, IN_UNIV]);
11618
11619val CONTINUOUS_ON_AVOID = store_thm ("CONTINUOUS_ON_AVOID",
11620 ``!f:real->real x s a.
11621        f continuous_on s /\ x IN s /\ ~(f x = a)
11622        ==> ?e. &0 < e /\ !y. y IN s /\ dist(x,y) < e ==> ~(f y = a)``,
11623  REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
11624  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_WITHIN_AVOID THEN
11625  ASM_SIMP_TAC std_ss []);
11626
11627val CONTINUOUS_ON_OPEN_AVOID = store_thm ("CONTINUOUS_ON_OPEN_AVOID",
11628 ``!f:real->real x s a.
11629        f continuous_on s /\ open s /\ x IN s /\ ~(f x = a)
11630        ==> ?e. &0 < e /\ !y. dist(x,y) < e ==> ~(f y = a)``,
11631  REPEAT GEN_TAC THEN ASM_CASES_TAC ``open(s:real->bool)`` THEN
11632  ASM_SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_AT] THEN
11633  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_AVOID THEN
11634  ASM_SIMP_TAC std_ss []);
11635
11636(* ------------------------------------------------------------------------- *)
11637(* Proving a function is constant by proving open-ness of level set.         *)
11638(* ------------------------------------------------------------------------- *)
11639
11640val CONTINUOUS_LEVELSET_OPEN_IN_CASES = store_thm ("CONTINUOUS_LEVELSET_OPEN_IN_CASES",
11641 ``!f:real->real s a.
11642        connected s /\
11643        f continuous_on s /\
11644        open_in (subtopology euclidean s) {x | x IN s /\ (f x = a)}
11645        ==> (!x. x IN s ==> ~(f x = a)) \/ (!x. x IN s ==> (f x = a))``,
11646  REWRITE_TAC[SET_RULE ``(!x. x IN s ==> ~(f x = a)) <=>
11647                        ({x | x IN s /\ (f x = a)} = {})``,
11648              SET_RULE ``(!x. x IN s ==> (f x = a)) <=>
11649                        ({x | x IN s /\ (f x = a)} = s)``] THEN
11650  REWRITE_TAC[CONNECTED_CLOPEN] THEN REPEAT STRIP_TAC THEN
11651  FIRST_X_ASSUM MATCH_MP_TAC THEN
11652  ASM_SIMP_TAC std_ss [CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT]);
11653
11654val CONTINUOUS_LEVELSET_OPEN_IN = store_thm ("CONTINUOUS_LEVELSET_OPEN_IN",
11655 ``!f:real->real s a.
11656        connected s /\
11657        f continuous_on s /\
11658        open_in (subtopology euclidean s) {x | x IN s /\ (f x = a)} /\
11659        (?x. x IN s /\ (f x = a))
11660        ==> (!x. x IN s ==> (f x = a))``,
11661  METIS_TAC[CONTINUOUS_LEVELSET_OPEN_IN_CASES]);
11662
11663val CONTINUOUS_LEVELSET_OPEN = store_thm ("CONTINUOUS_LEVELSET_OPEN",
11664 ``!f:real->real s a.
11665        connected s /\
11666        f continuous_on s /\
11667        open {x | x IN s /\ (f x = a)} /\
11668        (?x. x IN s /\ (f x = a))
11669        ==> (!x. x IN s ==> (f x = a))``,
11670  REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
11671  MATCH_MP_TAC CONTINUOUS_LEVELSET_OPEN_IN THEN
11672  ASM_REWRITE_TAC[OPEN_IN_OPEN] THEN
11673  EXISTS_TAC ``{x | x IN s /\ ((f:real->real) x = a)}`` THEN
11674  ASM_REWRITE_TAC[] THEN SET_TAC[]);
11675
11676(* ------------------------------------------------------------------------- *)
11677(* Some arithmetical combinations (more to prove).                           *)
11678(* ------------------------------------------------------------------------- *)
11679
11680val OPEN_SCALING = store_thm ("OPEN_SCALING",
11681 ``!s:real->bool c. ~(c = &0) /\ open s ==> open(IMAGE (\x. c * x) s)``,
11682  REPEAT GEN_TAC THEN SIMP_TAC std_ss [open_def, FORALL_IN_IMAGE] THEN
11683  STRIP_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
11684  FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
11685  DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
11686  EXISTS_TAC ``e * abs(c:real)`` THEN ASM_SIMP_TAC std_ss [REAL_LT_MUL, GSYM ABS_NZ] THEN
11687  X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN REWRITE_TAC[IN_IMAGE] THEN
11688  EXISTS_TAC ``inv(c) * y:real`` THEN
11689  ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_RINV, REAL_MUL_LID] THEN
11690  FIRST_X_ASSUM MATCH_MP_TAC THEN
11691  SUBGOAL_THEN ``x = inv(c) * c * x:real`` SUBST1_TAC THENL
11692   [ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID],
11693    REWRITE_TAC[dist, GSYM REAL_MUL_ASSOC, GSYM REAL_SUB_LDISTRIB, ABS_MUL] THEN
11694    ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_SIMP_TAC std_ss [ABS_INV] THEN
11695    ASM_SIMP_TAC std_ss [GSYM real_div, REAL_LT_LDIV_EQ, GSYM ABS_NZ] THEN
11696    ASM_REWRITE_TAC[GSYM dist]]);
11697
11698val OPEN_NEGATIONS = store_thm ("OPEN_NEGATIONS",
11699 ``!s:real->bool. open s ==> open (IMAGE (\x. -x) s)``,
11700  SUBGOAL_THEN ``(\x. -x) = \x:real. -(&1) * x``
11701   (fn th => SIMP_TAC std_ss [th, OPEN_SCALING, REAL_ARITH ``~(-(&1) = &0:real)``]) THEN
11702  REWRITE_TAC[FUN_EQ_THM] THEN REAL_ARITH_TAC);
11703
11704val OPEN_TRANSLATION = store_thm ("OPEN_TRANSLATION",
11705 ``!s a:real. open s ==> open(IMAGE (\x. a + x) s)``,
11706  REPEAT STRIP_TAC THEN
11707  MP_TAC(ISPECL [``\x:real. x - a``, ``s:real->bool``]
11708         CONTINUOUS_OPEN_PREIMAGE_UNIV) THEN
11709  ASM_SIMP_TAC std_ss [CONTINUOUS_SUB, CONTINUOUS_AT_ID, CONTINUOUS_CONST] THEN
11710  MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN
11711  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE, IN_UNIV] THEN
11712  ASM_MESON_TAC[REAL_ARITH ``(a + x) - a = x:real``,
11713                REAL_ARITH ``a + (x - a) = x:real``]);
11714
11715val OPEN_TRANSLATION_EQ = store_thm ("OPEN_TRANSLATION_EQ",
11716 ``!a s. open (IMAGE (\x:real. a + x) s) <=> open s``,
11717  REPEAT GEN_TAC THEN EQ_TAC THENL
11718  [ALL_TAC, REWRITE_TAC [OPEN_TRANSLATION]] THEN
11719  REWRITE_TAC [open_def] THEN DISCH_TAC THEN GEN_TAC THEN
11720  DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC ``a + x:real``) THEN
11721  KNOW_TAC ``a + x IN IMAGE (\x:real. a + x) s`` THENL
11722  [SIMP_TAC std_ss [IN_IMAGE, REAL_EQ_LADD] THEN METIS_TAC [],
11723   DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
11724  STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC [] THEN
11725  GEN_TAC THEN DISCH_TAC THEN FULL_SIMP_TAC std_ss [dist, IN_IMAGE] THEN
11726  FIRST_X_ASSUM (MP_TAC o SPEC ``a + x':real``) THEN
11727  ASM_SIMP_TAC real_ss [REAL_ARITH ``a + b - (a + c) = b - c:real``] THEN
11728  REWRITE_TAC [REAL_EQ_LADD] THEN METIS_TAC []);
11729
11730val OPEN_AFFINITY = store_thm ("OPEN_AFFINITY",
11731 ``!s a:real c.
11732        open s /\ ~(c = &0) ==> open (IMAGE (\x. a + c * x) s)``,
11733  REPEAT STRIP_TAC THEN
11734  SUBGOAL_THEN ``(\x:real. a + c * x) = (\x. a + x) o (\x. c * x)``
11735  SUBST1_TAC THENL [REWRITE_TAC[o_DEF], ALL_TAC] THEN
11736  ASM_SIMP_TAC std_ss [IMAGE_COMPOSE, OPEN_TRANSLATION, OPEN_SCALING]);
11737
11738val INTERIOR_TRANSLATION = store_thm ("INTERIOR_TRANSLATION",
11739 ``!a:real s.
11740    interior (IMAGE (\x. a + x) s) = IMAGE (\x. a + x) (interior s)``,
11741  REPEAT STRIP_TAC THEN
11742  KNOW_TAC ``(!t. ?s. IMAGE ((\x. a + x):real->real) s = t)`` THENL
11743  [REWRITE_TAC [SURJECTIVE_IMAGE] THEN GEN_TAC THEN EXISTS_TAC ``-a + y:real`` THEN
11744   SIMP_TAC std_ss [] THEN REAL_ARITH_TAC, DISCH_TAC] THEN
11745  REWRITE_TAC [interior] THEN
11746  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE] THEN
11747  GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
11748  [FIRST_ASSUM (MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN
11749   DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC [IN_IMAGE] THEN
11750   SIMP_TAC std_ss [] THEN STRIP_TAC THEN EXISTS_TAC ``x':real`` THEN
11751   ASM_REWRITE_TAC [] THEN
11752   FIRST_ASSUM (MP_TAC o SPEC ``t:real->bool``) THEN STRIP_TAC THEN
11753   EXISTS_TAC ``s':real->bool`` THEN REPEAT CONJ_TAC THENL
11754   [METIS_TAC [OPEN_TRANSLATION_EQ],
11755    UNDISCH_TAC ``IMAGE ((\x. a + x):real->real) s' = t`` THEN REWRITE_TAC [EXTENSION] THEN
11756    DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN ASM_SIMP_TAC std_ss [IN_IMAGE] THEN
11757    REWRITE_TAC [REAL_EQ_LADD] THEN METIS_TAC [],
11758    REWRITE_TAC [SUBSET_DEF] THEN X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN
11759    UNDISCH_TAC ``IMAGE ((\x. a + x):real->real) s' = t`` THEN REWRITE_TAC [EXTENSION] THEN
11760    DISCH_THEN (MP_TAC o SPEC ``a + y:real``) THEN SIMP_TAC std_ss [IN_IMAGE] THEN
11761    KNOW_TAC ``(?x:real. (a + y = a + x) /\ x IN s')`` THENL
11762    [METIS_TAC [], ALL_TAC] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
11763    DISCH_TAC THEN UNDISCH_TAC ``t SUBSET IMAGE ((\x. a + x):real->real) s`` THEN
11764    REWRITE_TAC [SUBSET_DEF] THEN DISCH_THEN (MP_TAC o SPEC ``a + y:real``) THEN
11765    ASM_REWRITE_TAC [] THEN SIMP_TAC std_ss [IN_IMAGE, REAL_EQ_LADD]], ALL_TAC] THEN
11766  FIRST_ASSUM (MP_TAC o SPEC ``t:real->bool``) THEN
11767  STRIP_TAC THEN EXISTS_TAC ``IMAGE (\x:real. a + x) t`` THEN
11768  REPEAT CONJ_TAC THENL
11769  [METIS_TAC [OPEN_TRANSLATION_EQ],
11770   SIMP_TAC std_ss [IN_IMAGE] THEN EXISTS_TAC ``x':real`` THEN
11771   ASM_REWRITE_TAC [],
11772   MATCH_MP_TAC IMAGE_SUBSET THEN ASM_REWRITE_TAC []]);
11773
11774val OPEN_SUMS = store_thm ("OPEN_SUMS",
11775 ``!s t:real->bool.
11776        open s \/ open t ==> open {x + y | x IN s /\ y IN t}``,
11777  REPEAT GEN_TAC THEN REWRITE_TAC[open_def] THEN STRIP_TAC THEN
11778  SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN
11779  MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THENL
11780   [FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``),
11781    FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``)] THEN
11782  ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
11783  EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[] THEN
11784  X_GEN_TAC ``z:real`` THEN DISCH_TAC THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN
11785  METIS_TAC[REAL_ADD_SYM, REAL_ARITH ``(z - y) + y:real = z``, dist,
11786                REAL_ARITH ``abs(z:real - (x + y)) < e ==> abs(z - y - x) < e``]);
11787
11788(* ------------------------------------------------------------------------- *)
11789(* Upper and lower hemicontinuous functions, relation in the case of         *)
11790(* preimage map to open and closed maps, and fact that upper and lower       *)
11791(* hemicontinuity together imply continuity in the sense of the Hausdorff    *)
11792(* metric (at points where the function gives a bounded and nonempty set).   *)
11793(* ------------------------------------------------------------------------- *)
11794
11795val UPPER_HEMICONTINUOUS = store_thm ("UPPER_HEMICONTINUOUS",
11796 ``!f:real->real->bool t s.
11797        (!x. x IN s ==> f(x) SUBSET t)
11798        ==> ((!u. open_in (subtopology euclidean t) u
11799                  ==> open_in (subtopology euclidean s)
11800                              {x | x IN s /\ f(x) SUBSET u}) <=>
11801             (!u. closed_in (subtopology euclidean t) u
11802                  ==> closed_in (subtopology euclidean s)
11803                                {x | x IN s /\ ~(f(x) INTER u = {})}))``,
11804  REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN
11805  FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THEN
11806  MATCH_MP_TAC MONO_IMP THEN
11807  SIMP_TAC std_ss [OPEN_IN_DIFF, CLOSED_IN_DIFF, OPEN_IN_REFL, CLOSED_IN_REFL] THENL
11808   [REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ], REWRITE_TAC[closed_in]] THEN
11809  SIMP_TAC std_ss [TOPSPACE_EUCLIDEAN_SUBTOPOLOGY, SUBSET_RESTRICT] THEN
11810  MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]);
11811
11812val LOWER_HEMICONTINUOUS = store_thm ("LOWER_HEMICONTINUOUS",
11813 ``!f:real->real->bool t s.
11814        (!x. x IN s ==> f(x) SUBSET t)
11815        ==> ((!u. closed_in (subtopology euclidean t) u
11816                  ==> closed_in (subtopology euclidean s)
11817                                {x | x IN s /\ f(x) SUBSET u}) <=>
11818             (!u. open_in (subtopology euclidean t) u
11819                  ==> open_in (subtopology euclidean s)
11820                              {x | x IN s /\ ~(f(x) INTER u = {})}))``,
11821  REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN
11822  FIRST_X_ASSUM(MP_TAC o SPEC ``t DIFF u:real->bool``) THEN
11823  MATCH_MP_TAC MONO_IMP THEN
11824  SIMP_TAC std_ss [OPEN_IN_DIFF, CLOSED_IN_DIFF, OPEN_IN_REFL, CLOSED_IN_REFL] THENL
11825   [REWRITE_TAC[closed_in], REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ]] THEN
11826  SIMP_TAC std_ss [TOPSPACE_EUCLIDEAN_SUBTOPOLOGY, SUBSET_RESTRICT] THEN
11827  MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]);
11828
11829val OPEN_MAP_IFF_LOWER_HEMICONTINUOUS_PREIMAGE = store_thm ("OPEN_MAP_IFF_LOWER_HEMICONTINUOUS_PREIMAGE",
11830 ``!f:real->real s t.
11831        IMAGE f s SUBSET t
11832        ==> ((!u. open_in (subtopology euclidean s) u
11833                  ==> open_in (subtopology euclidean t) (IMAGE f u)) <=>
11834             (!u. closed_in (subtopology euclidean s) u
11835                      ==> closed_in (subtopology euclidean t)
11836                                    {y | y IN t /\
11837                                         {x | x IN s /\ (f x = y)} SUBSET u}))``,
11838  REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
11839   [X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN
11840    FIRST_X_ASSUM(MP_TAC o SPEC ``s DIFF v:real->bool``) THEN
11841    ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL] THEN
11842    SIMP_TAC std_ss [OPEN_IN_CLOSED_IN_EQ, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
11843    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
11844    FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
11845    MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[],
11846    X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN
11847    FIRST_X_ASSUM(MP_TAC o SPEC ``s DIFF v:real->bool``) THEN
11848    ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL] THEN
11849    FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
11850    REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
11851    DISCH_THEN(fn th => CONJ_TAC THENL [ASM_SET_TAC[], MP_TAC th]) THEN
11852    MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]]);
11853
11854val CLOSED_MAP_IFF_UPPER_HEMICONTINUOUS_PREIMAGE = store_thm ("CLOSED_MAP_IFF_UPPER_HEMICONTINUOUS_PREIMAGE",
11855 ``!f:real->real s t.
11856        IMAGE f s SUBSET t
11857        ==> ((!u. closed_in (subtopology euclidean s) u
11858                  ==> closed_in (subtopology euclidean t) (IMAGE f u)) <=>
11859             (!u. open_in (subtopology euclidean s) u
11860                  ==> open_in (subtopology euclidean t)
11861                              {y | y IN t /\
11862                                   {x | x IN s /\ (f x = y)} SUBSET u}))``,
11863  REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
11864   [X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN
11865    FIRST_X_ASSUM(MP_TAC o SPEC ``s DIFF v:real->bool``) THEN
11866    ASM_SIMP_TAC std_ss [CLOSED_IN_DIFF, CLOSED_IN_REFL] THEN
11867    SIMP_TAC std_ss [closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
11868    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
11869    FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
11870    MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[],
11871    X_GEN_TAC ``v:real->bool`` THEN DISCH_TAC THEN
11872    FIRST_X_ASSUM(MP_TAC o SPEC ``s DIFF v:real->bool``) THEN
11873    ASM_SIMP_TAC std_ss [OPEN_IN_DIFF, OPEN_IN_REFL] THEN
11874    FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
11875    REWRITE_TAC[closed_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
11876    DISCH_THEN(fn th => CONJ_TAC THENL [ASM_SET_TAC[], MP_TAC th]) THEN
11877    MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN ASM_SET_TAC[]]);
11878
11879val UPPER_LOWER_HEMICONTINUOUS_EXPLICIT = store_thm ("UPPER_LOWER_HEMICONTINUOUS_EXPLICIT",
11880 ``!f:real->real->bool t s.
11881      (!x. x IN s ==> f(x) SUBSET t) /\
11882      (!u. open_in (subtopology euclidean t) u
11883           ==> open_in (subtopology euclidean s)
11884                       {x | x IN s /\ f(x) SUBSET u}) /\
11885      (!u. closed_in (subtopology euclidean t) u
11886           ==> closed_in (subtopology euclidean s)
11887                         {x | x IN s /\ f(x) SUBSET u})
11888      ==> !x e. x IN s /\ &0 < e /\ bounded(f x) /\ ~(f x = {})
11889                ==> ?d. &0 < d /\
11890                        !x'. x' IN s /\ dist(x,x') < d
11891                             ==> (!y. y IN f x
11892                                      ==> ?y'. y' IN f x' /\ dist(y,y') < e) /\
11893                                 (!y'. y' IN f x'
11894                                       ==> ?y. y IN f x /\ dist(y',y) < e)``,
11895  REPEAT STRIP_TAC THEN
11896  UNDISCH_TAC
11897   ``!u. open_in (subtopology euclidean t) u
11898        ==> open_in (subtopology euclidean s)
11899                    {x | x IN s /\ (f:real->real->bool)(x) SUBSET u}`` THEN
11900  DISCH_THEN(MP_TAC o SPEC
11901   ``t INTER
11902    {a + b | a IN (f:real->real->bool) x /\ b IN ball(0,e)}``) THEN
11903  SIMP_TAC std_ss [OPEN_SUMS, OPEN_BALL, OPEN_IN_OPEN_INTER] THEN
11904  SIMP_TAC std_ss [open_in, SUBSET_RESTRICT] THEN
11905  DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN
11906  ASM_SIMP_TAC std_ss [GSPECIFICATION, SUBSET_INTER] THEN
11907  KNOW_TAC ``(f :real -> real -> bool) (x :real) SUBSET
11908    {a + b | a IN f x /\ b IN ball ((0 :real),(e :real))}`` THENL
11909   [SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN
11910    METIS_TAC[CENTRE_IN_BALL, REAL_ADD_RID],
11911    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
11912    DISCH_THEN(X_CHOOSE_THEN ``d1:real``
11913     (CONJUNCTS_THEN2 ASSUME_TAC ASSUME_TAC))] THEN
11914  UNDISCH_TAC
11915   ``!u. closed_in (subtopology euclidean t) u
11916        ==> closed_in (subtopology euclidean s)
11917                    {x | x IN s /\ (f:real->real->bool)(x) SUBSET u}`` THEN
11918  ASM_SIMP_TAC std_ss [LOWER_HEMICONTINUOUS] THEN DISCH_THEN(MP_TAC o
11919    GEN ``a:real`` o SPEC ``t INTER ball(a:real,e / &2)``) THEN
11920  SIMP_TAC std_ss [OPEN_BALL, OPEN_IN_OPEN_INTER] THEN
11921  MP_TAC(SPEC ``closure((f:real->real->bool) x)``
11922    COMPACT_EQ_HEINE_BOREL) THEN
11923  ASM_REWRITE_TAC[COMPACT_CLOSURE] THEN DISCH_THEN(MP_TAC o SPEC
11924   ``{ball(a:real,e / &2) | a IN (f:real->real->bool) x}``) THEN
11925  SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, OPEN_BALL] THEN
11926  ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
11927  SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE] THEN
11928  KNOW_TAC ``closure ((f :real -> real -> bool) (x :real)) SUBSET
11929   BIGUNION (IMAGE (\(a :real). ball (a,(e :real) / (2 :real))) (f x))`` THENL
11930   [SIMP_TAC std_ss [CLOSURE_APPROACHABLE, SUBSET_DEF, BIGUNION_IMAGE, GSPECIFICATION] THEN
11931    REWRITE_TAC[IN_BALL] THEN ASM_SIMP_TAC std_ss [REAL_HALF],
11932    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
11933  DISCH_THEN(X_CHOOSE_THEN ``c:real->bool`` STRIP_ASSUME_TAC) THEN
11934  DISCH_TAC THEN FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP
11935   (METIS[CLOSURE_SUBSET, SUBSET_TRANS]
11936        ``closure s SUBSET t ==> s SUBSET t``)) THEN
11937  SUBGOAL_THEN
11938   ``open_in (subtopology euclidean s)
11939      (BIGINTER {{x | x IN s /\
11940          ~((f:real->real->bool) x INTER t INTER ball(a,e / &2) = {})} |
11941     a IN c})``
11942  MP_TAC THENL
11943   [MATCH_MP_TAC OPEN_IN_BIGINTER THEN
11944    ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, IMAGE_FINITE,
11945     GSYM INTER_ASSOC] THEN ASM_SIMP_TAC std_ss [IMAGE_EQ_EMPTY] THEN
11946    ASM_SET_TAC[], ALL_TAC] THEN
11947  REWRITE_TAC[open_in] THEN
11948  DISCH_THEN(MP_TAC o SPEC ``x:real`` o CONJUNCT2) THEN
11949  KNOW_TAC ``(x :real) IN
11950   BIGINTER {{x |
11951     x IN (s :real -> bool) /\
11952     (f :real -> real -> bool) x INTER (t :real -> bool) INTER
11953     ball (a,(e :real) / (2 :real)) <> ({} :real -> bool)} |
11954    a IN (c :real -> bool)}`` THENL
11955   [SIMP_TAC std_ss [BIGINTER_GSPEC, GSPECIFICATION] THEN
11956    X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN
11957    ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
11958    EXISTS_TAC ``a:real`` THEN
11959    ASM_REWRITE_TAC[IN_INTER, CENTRE_IN_BALL, REAL_HALF] THEN
11960    ASM_SET_TAC[],
11961    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
11962    DISCH_THEN(X_CHOOSE_THEN ``d2:real``
11963     (CONJUNCTS_THEN2 ASSUME_TAC ASSUME_TAC))] THEN
11964  EXISTS_TAC ``min d1 d2:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
11965  X_GEN_TAC ``x':real`` THEN STRIP_TAC THEN CONJ_TAC THENL
11966   [ALL_TAC,
11967    UNDISCH_TAC ``!x'':real.
11968        x'' IN s /\ dist (x'',x) < d1 ==>
11969        f x'' SUBSET {a + b | a IN f x /\ b IN ball (0,e)}`` THEN
11970    DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC ``x':real``) THEN
11971    ASM_REWRITE_TAC[] THEN
11972    KNOW_TAC ``dist (x',x) < d1:real`` THENL
11973    [ASM_MESON_TAC[DIST_SYM], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
11974    SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD, IN_BALL] THEN
11975    SIMP_TAC std_ss [REAL_ARITH ``(x:real = a + b) <=> (x - a = b)``,
11976                DIST_0, ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN
11977    REWRITE_TAC[dist]] THEN
11978  UNDISCH_TAC ``!x':real.
11979         x' IN s /\ dist (x',x) < d2 ==>
11980         x' IN
11981         BIGINTER
11982           {{x | x IN s /\ f x INTER t INTER ball (a,e / 2) <> {}} |
11983            a IN c}`` THEN DISCH_TAC THEN
11984  FIRST_X_ASSUM (MP_TAC o SPEC ``x':real``) THEN
11985  ASM_SIMP_TAC std_ss [BIGINTER_GSPEC, GSPECIFICATION] THEN
11986  KNOW_TAC ``dist (x',x) < d2:real`` THENL
11987  [ASM_MESON_TAC[DIST_SYM], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
11988  DISCH_TAC THEN
11989  X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN
11990  UNDISCH_TAC ``(f:real->real->bool) x SUBSET
11991               BIGUNION (IMAGE (\a. ball (a,e / &2)) c)`` THEN
11992  REWRITE_TAC[SUBSET_DEF] THEN DISCH_THEN(MP_TAC o SPEC ``y:real``) THEN
11993  ASM_SIMP_TAC std_ss [BIGUNION_IMAGE, GSPECIFICATION, IN_BALL] THEN
11994  DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN
11995  UNDISCH_TAC ``!(a' :real).
11996         a' IN (c :real -> bool) ==>
11997         (f :real -> real -> bool) (x' :real) INTER
11998         (t :real -> bool) INTER ball (a',(e :real) / (2 :real)) <>
11999         ({} :real -> bool)`` THEN DISCH_TAC THEN
12000  FIRST_X_ASSUM (MP_TAC o SPEC ``a:real``) THEN
12001  ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_INTER, IN_BALL] THEN
12002  DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN
12003  POP_ASSUM MP_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
12004  METIS_TAC[DIST_TRIANGLE_HALF_L, DIST_SYM]);
12005
12006(* ------------------------------------------------------------------------- *)
12007(* Connected components, considered as a "connectedness" relation or a set.  *)
12008(* ------------------------------------------------------------------------- *)
12009
12010val connected_component = new_definition ("connected_component",
12011 ``connected_component s x y <=>
12012        ?t. connected t /\ t SUBSET s /\ x IN t /\ y IN t``);
12013
12014val CONNECTED_COMPONENT_IN = store_thm ("CONNECTED_COMPONENT_IN",
12015 ``!s x y. connected_component s x y ==> x IN s /\ y IN s``,
12016  REWRITE_TAC[connected_component] THEN SET_TAC[]);
12017
12018val CONNECTED_COMPONENT_REFL = store_thm ("CONNECTED_COMPONENT_REFL",
12019 ``!s x:real. x IN s ==> connected_component s x x``,
12020  REWRITE_TAC[connected_component] THEN REPEAT STRIP_TAC THEN
12021  EXISTS_TAC ``{x:real}`` THEN REWRITE_TAC[CONNECTED_SING] THEN
12022  ASM_SET_TAC[]);
12023
12024val CONNECTED_COMPONENT_REFL_EQ = store_thm ("CONNECTED_COMPONENT_REFL_EQ",
12025 ``!s x:real. connected_component s x x <=> x IN s``,
12026  REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[CONNECTED_COMPONENT_REFL] THEN
12027  REWRITE_TAC[connected_component] THEN SET_TAC[]);
12028
12029val CONNECTED_COMPONENT_SYM = store_thm ("CONNECTED_COMPONENT_SYM",
12030 ``!s x y:real. connected_component s x y ==> connected_component s y x``,
12031  REWRITE_TAC[connected_component] THEN MESON_TAC[]);
12032
12033val CONNECTED_COMPONENT_TRANS = store_thm ("CONNECTED_COMPONENT_TRANS",
12034 ``!s x y:real.
12035    connected_component s x y /\ connected_component s y z
12036    ==> connected_component s x z``,
12037  REPEAT GEN_TAC THEN REWRITE_TAC[connected_component] THEN
12038  DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC ``t:real->bool``)
12039                             (X_CHOOSE_TAC ``u:real->bool``)) THEN
12040  EXISTS_TAC ``t UNION u:real->bool`` THEN
12041  ASM_REWRITE_TAC[IN_UNION, UNION_SUBSET] THEN
12042  MATCH_MP_TAC CONNECTED_UNION THEN ASM_SET_TAC[]);
12043
12044val CONNECTED_COMPONENT_OF_SUBSET = store_thm ("CONNECTED_COMPONENT_OF_SUBSET",
12045 ``!s t x. s SUBSET t /\ connected_component s x y
12046           ==> connected_component t x y``,
12047  REWRITE_TAC[connected_component] THEN SET_TAC[]);
12048
12049val CONNECTED_COMPONENT_SET = store_thm ("CONNECTED_COMPONENT_SET",
12050 ``!s x. connected_component s x =
12051            { y | ?t. connected t /\ t SUBSET s /\ x IN t /\ y IN t}``,
12052  SIMP_TAC std_ss [GSPECIFICATION, EXTENSION] THEN
12053  SIMP_TAC std_ss [IN_DEF, connected_component]);
12054
12055val CONNECTED_COMPONENT_BIGUNION = store_thm ("CONNECTED_COMPONENT_BIGUNION",
12056 ``!s x. connected_component s x =
12057                BIGUNION {t | connected t /\ x IN t /\ t SUBSET s}``,
12058  REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);
12059
12060val CONNECTED_COMPONENT_SUBSET = store_thm ("CONNECTED_COMPONENT_SUBSET",
12061 ``!s x. (connected_component s x) SUBSET s``,
12062  REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);
12063
12064val CONNECTED_CONNECTED_COMPONENT_SET = store_thm ("CONNECTED_CONNECTED_COMPONENT_SET",
12065 ``!s. connected s <=> !x:real. x IN s ==> (connected_component s x = s)``,
12066  GEN_TAC THEN REWRITE_TAC[CONNECTED_COMPONENT_BIGUNION] THEN EQ_TAC THENL
12067   [SET_TAC[], ALL_TAC] THEN
12068  ASM_CASES_TAC ``s:real->bool = {}`` THEN
12069  ASM_REWRITE_TAC[CONNECTED_EMPTY] THEN
12070  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
12071  DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN
12072  DISCH_THEN(MP_TAC o SPEC ``a:real``) THEN ASM_REWRITE_TAC[] THEN
12073  DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC CONNECTED_BIGUNION THEN
12074  ASM_SET_TAC[]);
12075
12076val CONNECTED_COMPONENT_UNIV = store_thm ("CONNECTED_COMPONENT_UNIV",
12077 ``!x. connected_component univ(:real) x = univ(:real)``,
12078  MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET, CONNECTED_UNIV, IN_UNIV]);
12079
12080val CONNECTED_COMPONENT_EQ_UNIV = store_thm ("CONNECTED_COMPONENT_EQ_UNIV",
12081 ``!s x. (connected_component s x = univ(:real)) <=> (s = univ(:real))``,
12082  REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC std_ss [CONNECTED_COMPONENT_UNIV] THEN
12083  MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> (s = UNIV) ==> (t = UNIV)``) THEN
12084  REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]);
12085
12086val CONNECTED_COMPONENT_EQ_SELF = store_thm ("CONNECTED_COMPONENT_EQ_SELF",
12087 ``!s x. connected s /\ x IN s ==> (connected_component s x = s)``,
12088  MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET]);
12089
12090val CONNECTED_IFF_CONNECTED_COMPONENT = store_thm ("CONNECTED_IFF_CONNECTED_COMPONENT",
12091 ``!s. connected s <=>
12092          !x y. x IN s /\ y IN s ==> connected_component s x y``,
12093  REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT_SET] THEN
12094  REWRITE_TAC[EXTENSION] THEN MESON_TAC[IN_DEF, CONNECTED_COMPONENT_IN]);
12095
12096val CONNECTED_COMPONENT_MAXIMAL = store_thm ("CONNECTED_COMPONENT_MAXIMAL",
12097 ``!s t x:real.
12098        x IN t /\ connected t /\ t SUBSET s
12099        ==> t SUBSET (connected_component s x)``,
12100  REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);
12101
12102val CONNECTED_COMPONENT_MONO = store_thm ("CONNECTED_COMPONENT_MONO",
12103 ``!s t x. s SUBSET t
12104           ==> (connected_component s x) SUBSET (connected_component t x)``,
12105  REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);
12106
12107val CONNECTED_CONNECTED_COMPONENT = store_thm ("CONNECTED_CONNECTED_COMPONENT",
12108 ``!s x. connected(connected_component s x)``,
12109  REWRITE_TAC[CONNECTED_COMPONENT_BIGUNION] THEN
12110  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_BIGUNION THEN SET_TAC[]);
12111
12112val CONNECTED_COMPONENT_EQ_EMPTY = store_thm ("CONNECTED_COMPONENT_EQ_EMPTY",
12113 ``!s x:real. (connected_component s x = {}) <=> ~(x IN s)``,
12114  REPEAT GEN_TAC THEN EQ_TAC THENL
12115   [REWRITE_TAC[EXTENSION, NOT_IN_EMPTY] THEN
12116    DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN
12117    SIMP_TAC std_ss [IN_DEF, CONNECTED_COMPONENT_REFL_EQ],
12118    REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]]);
12119
12120val CONNECTED_COMPONENT_EMPTY = store_thm ("CONNECTED_COMPONENT_EMPTY",
12121 ``!x. connected_component {} x = {}``,
12122  REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY, NOT_IN_EMPTY]);
12123
12124val CONNECTED_COMPONENT_EQ = store_thm ("CONNECTED_COMPONENT_EQ",
12125 ``!s x y. y IN connected_component s x
12126           ==> ((connected_component s y = connected_component s x))``,
12127  REWRITE_TAC[EXTENSION, IN_DEF] THEN
12128  MESON_TAC[CONNECTED_COMPONENT_SYM, CONNECTED_COMPONENT_TRANS]);
12129
12130val CLOSED_CONNECTED_COMPONENT = store_thm ("CLOSED_CONNECTED_COMPONENT",
12131 ``!s x:real. closed s ==> closed(connected_component s x)``,
12132  REPEAT STRIP_TAC THEN
12133  ASM_CASES_TAC ``(x:real) IN s`` THENL
12134   [ALL_TAC, ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY, CLOSED_EMPTY]] THEN
12135  REWRITE_TAC[GSYM CLOSURE_EQ] THEN
12136  MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[CLOSURE_SUBSET] THEN
12137  MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
12138  SIMP_TAC std_ss [CONNECTED_CLOSURE, CONNECTED_CONNECTED_COMPONENT] THEN
12139  CONJ_TAC THENL
12140   [MATCH_MP_TAC(REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET) THEN
12141    ASM_SIMP_TAC std_ss [IN_DEF, CONNECTED_COMPONENT_REFL_EQ],
12142    MATCH_MP_TAC CLOSURE_MINIMAL THEN
12143    ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_SUBSET]]);
12144
12145val CONNECTED_COMPONENT_DISJOINT = store_thm ("CONNECTED_COMPONENT_DISJOINT",
12146 ``!s a b. DISJOINT (connected_component s a) (connected_component s b) <=>
12147             ~(a IN connected_component s b)``,
12148  REWRITE_TAC[DISJOINT_DEF, EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN
12149  REWRITE_TAC[IN_DEF] THEN
12150  MESON_TAC[CONNECTED_COMPONENT_SYM, CONNECTED_COMPONENT_TRANS]);
12151
12152val CONNECTED_COMPONENT_NONOVERLAP = store_thm ("CONNECTED_COMPONENT_NONOVERLAP",
12153 ``!s a b:real.
12154        ((connected_component s a) INTER (connected_component s b) = {}) <=>
12155        ~(a IN s) \/ ~(b IN s) \/
12156        ~(connected_component s a = connected_component s b)``,
12157  REPEAT GEN_TAC THEN
12158  ASM_CASES_TAC ``(a:real) IN s`` THEN ASM_REWRITE_TAC[] THEN
12159  RULE_ASSUM_TAC(SIMP_RULE std_ss [GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN
12160  ASM_SIMP_TAC std_ss [INTER_EMPTY] THEN
12161  ASM_CASES_TAC ``(b:real) IN s`` THEN ASM_REWRITE_TAC[] THEN
12162  RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN
12163  ASM_REWRITE_TAC[INTER_EMPTY] THEN ASM_CASES_TAC
12164   ``connected_component s (a:real) = connected_component s b`` THEN
12165  ASM_REWRITE_TAC[INTER_IDEMPOT, CONNECTED_COMPONENT_EQ_EMPTY] THEN
12166  POP_ASSUM MP_TAC THEN
12167  ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN
12168  REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN
12169  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM DISJOINT_DEF]) THEN
12170  REWRITE_TAC[CONNECTED_COMPONENT_DISJOINT]);
12171
12172val CONNECTED_COMPONENT_OVERLAP = store_thm ("CONNECTED_COMPONENT_OVERLAP",
12173 ``!s a b:real.
12174        ~((connected_component s a) INTER (connected_component s b) = {}) <=>
12175        a IN s /\ b IN s /\
12176        (connected_component s a = connected_component s b)``,
12177  REWRITE_TAC[CONNECTED_COMPONENT_NONOVERLAP, DE_MORGAN_THM]);
12178
12179val CONNECTED_COMPONENT_SYM_EQ = store_thm ("CONNECTED_COMPONENT_SYM_EQ",
12180 ``!s x y. connected_component s x y <=> connected_component s y x``,
12181  MESON_TAC[CONNECTED_COMPONENT_SYM]);
12182
12183val CONNECTED_COMPONENT_EQ_EQ = store_thm ("CONNECTED_COMPONENT_EQ_EQ",
12184 ``!s x y:real.
12185        (connected_component s x = connected_component s y) <=>
12186           ~(x IN s) /\ ~(y IN s) \/
12187           x IN s /\ y IN s /\ connected_component s x y``,
12188  REPEAT GEN_TAC THEN ASM_CASES_TAC ``(y:real) IN s`` THENL
12189   [ASM_CASES_TAC ``(x:real) IN s`` THEN ASM_REWRITE_TAC[] THENL
12190     [REWRITE_TAC[FUN_EQ_THM] THEN
12191      ASM_MESON_TAC[CONNECTED_COMPONENT_TRANS, CONNECTED_COMPONENT_REFL,
12192                    CONNECTED_COMPONENT_SYM],
12193      ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]],
12194    RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN
12195    ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY] THEN
12196    ONCE_REWRITE_TAC[CONNECTED_COMPONENT_SYM_EQ] THEN
12197    ASM_REWRITE_TAC[EMPTY_DEF] THEN ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]]);
12198
12199val CONNECTED_EQ_CONNECTED_COMPONENT_EQ = store_thm ("CONNECTED_EQ_CONNECTED_COMPONENT_EQ",
12200 ``!s. connected s <=>
12201       !x y. x IN s /\ y IN s
12202             ==> (connected_component s x = connected_component s y)``,
12203  SIMP_TAC std_ss [CONNECTED_COMPONENT_EQ_EQ] THEN
12204  REWRITE_TAC[CONNECTED_IFF_CONNECTED_COMPONENT]);
12205
12206val CONNECTED_COMPONENT_IDEMP = store_thm ("CONNECTED_COMPONENT_IDEMP",
12207 ``!s x:real. connected_component (connected_component s x) x =
12208                connected_component s x``,
12209  REWRITE_TAC[FUN_EQ_THM, connected_component] THEN
12210  REPEAT GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN EQ_TAC THEN
12211  STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
12212  ASM_MESON_TAC[CONNECTED_COMPONENT_MAXIMAL, SUBSET_TRANS,
12213                CONNECTED_COMPONENT_SUBSET]);
12214
12215val CONNECTED_COMPONENT_UNIQUE = store_thm ("CONNECTED_COMPONENT_UNIQUE",
12216 ``!s c x:real.
12217        x IN c /\ c SUBSET s /\ connected c /\
12218        (!c'. x IN c' /\ c' SUBSET s /\ connected c'
12219              ==> c' SUBSET c)
12220        ==> (connected_component s x = c)``,
12221  REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
12222   [FIRST_X_ASSUM MATCH_MP_TAC THEN
12223    REWRITE_TAC[CONNECTED_COMPONENT_SUBSET, CONNECTED_CONNECTED_COMPONENT] THEN
12224    REWRITE_TAC[IN_DEF] THEN ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_REFL_EQ] THEN
12225    ASM_SET_TAC[],
12226    MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN ASM_REWRITE_TAC[]]);
12227
12228val JOINABLE_CONNECTED_COMPONENT_EQ = store_thm ("JOINABLE_CONNECTED_COMPONENT_EQ",
12229 ``!s t x y:real.
12230        connected t /\ t SUBSET s /\
12231        ~(connected_component s x INTER t = {}) /\
12232        ~(connected_component s y INTER t = {})
12233        ==> (connected_component s x = connected_component s y)``,
12234  REPEAT GEN_TAC THEN
12235  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
12236  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
12237  REWRITE_TAC[GSYM MEMBER_NOT_EMPTY, IN_INTER] THEN DISCH_THEN(CONJUNCTS_THEN2
12238   (X_CHOOSE_THEN ``w:real`` STRIP_ASSUME_TAC)
12239   (X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC)) THEN
12240  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN
12241  SIMP_TAC std_ss [IN_DEF] THEN
12242  MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN
12243  EXISTS_TAC ``z:real`` THEN CONJ_TAC THENL [ASM_MESON_TAC[IN_DEF], ALL_TAC] THEN
12244  MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN
12245  EXISTS_TAC ``w:real`` THEN CONJ_TAC THENL
12246   [REWRITE_TAC[connected_component] THEN
12247    EXISTS_TAC ``t:real->bool`` THEN ASM_REWRITE_TAC[],
12248    ASM_MESON_TAC[IN_DEF, CONNECTED_COMPONENT_SYM]]);
12249
12250val BIGUNION_CONNECTED_COMPONENT = store_thm ("BIGUNION_CONNECTED_COMPONENT",
12251 ``!s:real->bool. BIGUNION {connected_component s x |x| x IN s} = s``,
12252  GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
12253  SIMP_TAC std_ss [BIGUNION_SUBSET, FORALL_IN_GSPEC, CONNECTED_COMPONENT_SUBSET] THEN
12254  SIMP_TAC std_ss [SUBSET_DEF, BIGUNION_GSPEC, GSPECIFICATION] THEN
12255  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN EXISTS_TAC ``x:real`` THEN
12256  ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN_DEF] THEN
12257  ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_REFL_EQ]);
12258
12259val COMPLEMENT_CONNECTED_COMPONENT_BIGUNION = store_thm ("COMPLEMENT_CONNECTED_COMPONENT_BIGUNION",
12260 ``!s x:real.
12261     s DIFF connected_component s x =
12262     BIGUNION({connected_component s y | y | y IN s} DELETE
12263            (connected_component s x))``,
12264  REPEAT GEN_TAC THEN
12265  GEN_REWR_TAC (LAND_CONV o LAND_CONV)
12266    [GSYM BIGUNION_CONNECTED_COMPONENT] THEN
12267  MATCH_MP_TAC(SET_RULE
12268   ``(!x. x IN s DELETE a ==> DISJOINT a x)
12269     ==> (BIGUNION s DIFF a = BIGUNION (s DELETE a))``) THEN
12270  SIMP_TAC std_ss [CONJ_EQ_IMP, FORALL_IN_GSPEC, IN_DELETE] THEN
12271  SIMP_TAC std_ss [CONNECTED_COMPONENT_DISJOINT, CONNECTED_COMPONENT_EQ_EQ] THEN
12272  MESON_TAC[IN_DEF, SUBSET_DEF, CONNECTED_COMPONENT_SUBSET]);
12273
12274val CLOSED_IN_CONNECTED_COMPONENT = store_thm ("CLOSED_IN_CONNECTED_COMPONENT",
12275 ``!s x:real. closed_in (subtopology euclidean s) (connected_component s x)``,
12276  REPEAT GEN_TAC THEN
12277  ASM_CASES_TAC ``connected_component s (x:real) = {}`` THEN
12278  ASM_REWRITE_TAC[CLOSED_IN_EMPTY] THEN
12279  RULE_ASSUM_TAC(REWRITE_RULE[CONNECTED_COMPONENT_EQ_EMPTY]) THEN
12280  REWRITE_TAC[CLOSED_IN_CLOSED] THEN
12281  EXISTS_TAC ``closure(connected_component s x):real->bool`` THEN
12282  REWRITE_TAC[CLOSED_CLOSURE] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
12283  REWRITE_TAC[SUBSET_INTER, CONNECTED_COMPONENT_SUBSET, CLOSURE_SUBSET] THEN
12284  MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN REWRITE_TAC[INTER_SUBSET] THEN
12285  CONJ_TAC THENL
12286   [ASM_REWRITE_TAC[IN_INTER] THEN
12287    MATCH_MP_TAC(REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET) THEN
12288    ASM_SIMP_TAC std_ss [IN_DEF, CONNECTED_COMPONENT_REFL_EQ],
12289    MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN
12290    EXISTS_TAC ``connected_component s (x:real)`` THEN
12291    SIMP_TAC std_ss [INTER_SUBSET, CONNECTED_CONNECTED_COMPONENT,
12292                SUBSET_INTER, CONNECTED_COMPONENT_SUBSET, CLOSURE_SUBSET]]);
12293
12294val BIGUNION_DIFF = store_thm ("BIGUNION_DIFF",
12295 ``!s t. BIGUNION s DIFF t = BIGUNION {x DIFF t | x IN s}``,
12296  SIMP_TAC std_ss [BIGUNION_GSPEC] THEN SET_TAC[]);
12297
12298val OPEN_IN_CONNECTED_COMPONENT = store_thm ("OPEN_IN_CONNECTED_COMPONENT",
12299 ``!s x:real.
12300        FINITE {connected_component s x |x| x IN s}
12301        ==> open_in (subtopology euclidean s) (connected_component s x)``,
12302  REPEAT STRIP_TAC THEN
12303  SUBGOAL_THEN
12304   ``connected_component s (x:real) =
12305        s DIFF (BIGUNION {connected_component s y |y| y IN s} DIFF
12306                connected_component s x)``
12307  SUBST1_TAC THENL
12308   [REWRITE_TAC[BIGUNION_CONNECTED_COMPONENT] THEN
12309    MATCH_MP_TAC(SET_RULE ``t SUBSET s ==> (t = s DIFF (s DIFF t))``) THEN
12310    SIMP_TAC std_ss [CONNECTED_COMPONENT_SUBSET],
12311    MATCH_MP_TAC OPEN_IN_DIFF THEN
12312    SIMP_TAC std_ss [OPEN_IN_SUBTOPOLOGY_REFL, TOPSPACE_EUCLIDEAN, SUBSET_UNIV] THEN
12313    SIMP_TAC std_ss [BIGUNION_DIFF] THEN
12314    MATCH_MP_TAC CLOSED_IN_BIGUNION THEN SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN
12315        CONJ_TAC THENL [METIS_TAC [GSYM IMAGE_DEF, IMAGE_FINITE], ALL_TAC] THEN
12316    X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN
12317    SUBGOAL_THEN
12318    ``(connected_component s y DIFF connected_component s x =
12319       connected_component s y) \/
12320      (connected_component s (y:real) DIFF connected_component s x = {})``
12321     (DISJ_CASES_THEN SUBST1_TAC)
12322    THENL
12323     [MATCH_MP_TAC(SET_RULE
12324       ``(~(s INTER t = {}) ==> (s = t)) ==> (s DIFF t = s) \/ (s DIFF t = {})``) THEN
12325      SIMP_TAC std_ss [CONNECTED_COMPONENT_OVERLAP],
12326      REWRITE_TAC[CLOSED_IN_CONNECTED_COMPONENT],
12327      REWRITE_TAC[CLOSED_IN_EMPTY]]]);
12328
12329val CONNECTED_COMPONENT_EQUIVALENCE_RELATION = store_thm ("CONNECTED_COMPONENT_EQUIVALENCE_RELATION",
12330 ``!R s:real->bool.
12331        (!x y. R x y ==> R y x) /\
12332        (!x y z. R x y /\ R y z ==> R x z) /\
12333        (!a. a IN s
12334             ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
12335                     !x. x IN t ==> R a x)
12336        ==> !a b. connected_component s a b ==> R a b``,
12337  REPEAT STRIP_TAC THEN
12338  MP_TAC(ISPECL [``R:real->real->bool``, ``connected_component s (a:real)``]
12339    CONNECTED_EQUIVALENCE_RELATION) THEN
12340  ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN
12341  KNOW_TAC ``(!(a' :real).
12342        a' IN connected_component (s :real -> bool) (a :real) ==>
12343        ?(t :real -> bool).
12344          open_in (subtopology euclidean (connected_component s a)) t /\
12345          a' IN t /\
12346          !(x :real). x IN t ==> (R :real -> real -> bool) a' x)`` THENL
12347   [X_GEN_TAC ``c:real`` THEN DISCH_TAC THEN
12348    FIRST_X_ASSUM(MP_TAC o SPEC ``c:real``) THEN
12349    KNOW_TAC ``(c :real) IN (s :real -> bool)`` THENL
12350     [ASM_MESON_TAC[CONNECTED_COMPONENT_SUBSET, SUBSET_DEF],
12351          DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
12352    DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN
12353    EXISTS_TAC ``t INTER connected_component s (a:real)`` THEN
12354    ASM_SIMP_TAC std_ss [IN_INTER, OPEN_IN_OPEN] THEN
12355        UNDISCH_TAC ``open_in (subtopology euclidean s) t`` THEN DISCH_TAC THEN
12356    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_OPEN]) THEN
12357    SIMP_TAC std_ss [] THEN
12358    MP_TAC(ISPECL [``s:real->bool``, ``a:real``]
12359        CONNECTED_COMPONENT_SUBSET) THEN
12360    SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
12361    DISCH_THEN MATCH_MP_TAC THEN ASM_SIMP_TAC std_ss [IN_DEF] THEN
12362    REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN
12363    ASM_MESON_TAC[CONNECTED_COMPONENT_IN]]);
12364
12365val CONNECTED_COMPONENT_INTERMEDIATE_SUBSET = store_thm ("CONNECTED_COMPONENT_INTERMEDIATE_SUBSET",
12366 ``!t u a:real.
12367        connected_component u a SUBSET t /\ t SUBSET u
12368        ==> (connected_component t a = connected_component u a)``,
12369  REPEAT GEN_TAC THEN ASM_CASES_TAC ``(a:real) IN u`` THENL
12370   [REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_UNIQUE THEN
12371    ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN
12372    CONJ_TAC THENL [ASM_MESON_TAC[CONNECTED_COMPONENT_REFL, IN_DEF], ALL_TAC] THEN
12373    REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
12374    ASM_SET_TAC[],
12375    ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY, SUBSET_DEF]]);
12376
12377(* ------------------------------------------------------------------------- *)
12378(* The set of connected components of a set.                                 *)
12379(* ------------------------------------------------------------------------- *)
12380
12381val components = new_definition ("components",
12382  ``components s = {connected_component s x | x | x:real IN s}``);
12383
12384val IN_COMPONENTS = store_thm ("IN_COMPONENTS",
12385 ``!u:real->bool s. s IN components u
12386    <=> ?x. x IN u /\ (s = connected_component u x)``,
12387  REPEAT GEN_TAC THEN REWRITE_TAC[components] THEN EQ_TAC
12388  THENL [SET_TAC[], STRIP_TAC THEN ASM_SIMP_TAC std_ss [] THEN
12389  UNDISCH_TAC ``x:real IN u`` THEN SET_TAC[]]);
12390
12391val BIGUNION_COMPONENTS = store_thm
12392  ("BIGUNION_COMPONENTS",
12393  ``!u:real->bool. u = BIGUNION (components u)``,
12394    REWRITE_TAC [EXTENSION]
12395 >> REPEAT GEN_TAC >> EQ_TAC
12396 >| [ (* goal 1 (of 2) *)
12397      DISCH_TAC >> REWRITE_TAC [IN_BIGUNION] \\
12398      EXISTS_TAC ``connected_component (u:real->bool) x`` \\
12399      CONJ_TAC >|
12400      [ REWRITE_TAC [CONNECTED_COMPONENT_SET] \\
12401        SUBGOAL_THEN ``?s:real->bool. connected s /\ s SUBSET u /\ x IN s`` MP_TAC >|
12402        [ EXISTS_TAC ``{x:real}`` \\
12403          ASM_REWRITE_TAC [CONNECTED_SING] \\
12404          POP_ASSUM MP_TAC >> SET_TAC [],
12405          SET_TAC [] ],
12406        REWRITE_TAC [components] >> ASM_SET_TAC [] ],
12407      (* goal 2 of 2 *)
12408      REWRITE_TAC [IN_BIGUNION] \\
12409      STRIP_TAC \\
12410      MATCH_MP_TAC (SET_RULE ``!x:real s u. x IN s /\ s SUBSET u ==> x IN u``) \\
12411      EXISTS_TAC ``s :real -> bool`` >> ASM_REWRITE_TAC [] \\
12412      `?(y :real). ((s :real -> bool) = connected_component u y)`
12413                by METIS_TAC [IN_COMPONENTS] \\
12414      ASM_REWRITE_TAC [CONNECTED_COMPONENT_SUBSET] ]);
12415
12416val PAIRWISE_DISJOINT_COMPONENTS = store_thm ("PAIRWISE_DISJOINT_COMPONENTS",
12417 ``!u:real->bool. pairwise DISJOINT (components u)``,
12418  GEN_TAC THEN REWRITE_TAC[pairwise, DISJOINT_DEF] THEN
12419  MAP_EVERY X_GEN_TAC [``s:real->bool``, ``t:real->bool``] THEN STRIP_TAC THEN
12420  ASSERT_TAC ``(?a. s:real->bool = connected_component u a) /\
12421                ?b. t:real->bool = connected_component u b``
12422  THENL [ASM_MESON_TAC[IN_COMPONENTS],
12423  ASM_MESON_TAC[CONNECTED_COMPONENT_NONOVERLAP]]);
12424
12425val IN_COMPONENTS_NONEMPTY = store_thm ("IN_COMPONENTS_NONEMPTY",
12426 ``!s c. c IN components s ==> ~(c = {})``,
12427  REPEAT GEN_TAC THEN SIMP_TAC std_ss [components, GSPECIFICATION] THEN
12428  STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY]);
12429
12430val IN_COMPONENTS_SUBSET = store_thm ("IN_COMPONENTS_SUBSET",
12431 ``!s c. c IN components s ==> c SUBSET s``,
12432  REPEAT GEN_TAC THEN SIMP_TAC std_ss [components, GSPECIFICATION] THEN
12433  STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]);
12434
12435val IN_COMPONENTS_CONNECTED = store_thm ("IN_COMPONENTS_CONNECTED",
12436 ``!s c. c IN components s ==> connected c``,
12437  REPEAT GEN_TAC THEN SIMP_TAC std_ss [components, GSPECIFICATION] THEN
12438  STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT]);
12439
12440val IN_COMPONENTS_MAXIMAL = store_thm ("IN_COMPONENTS_MAXIMAL",
12441 ``!s c:real->bool.
12442        c IN components s <=>
12443        ~(c = {}) /\ c SUBSET s /\ connected c /\
12444        !c'. ~(c' = {}) /\ c SUBSET c' /\ c' SUBSET s /\ connected c'
12445             ==> (c' = c)``,
12446  REPEAT GEN_TAC THEN SIMP_TAC std_ss [components, GSPECIFICATION] THEN EQ_TAC THENL
12447   [DISCH_THEN(X_CHOOSE_THEN ``x:real`` STRIP_ASSUME_TAC) THEN
12448    ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY, CONNECTED_COMPONENT_SUBSET,
12449                    CONNECTED_CONNECTED_COMPONENT] THEN
12450    REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
12451    ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
12452    ASM_MESON_TAC[CONNECTED_COMPONENT_REFL, IN_DEF, SUBSET_DEF],
12453    STRIP_TAC THEN
12454        UNDISCH_TAC ``(c:real->bool) <> {}`` THEN DISCH_TAC THEN
12455    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
12456        STRIP_TAC THEN EXISTS_TAC ``x:real`` THEN CONJ_TAC THENL
12457        [ALL_TAC, ASM_SET_TAC[]] THEN
12458    MATCH_MP_TAC(GSYM CONNECTED_COMPONENT_UNIQUE) THEN
12459    ASM_REWRITE_TAC[] THEN X_GEN_TAC ``c':real->bool`` THEN STRIP_TAC THEN
12460    REWRITE_TAC[SET_RULE ``c' SUBSET c <=> (c' UNION c = c)``] THEN
12461    FIRST_X_ASSUM MATCH_MP_TAC THEN
12462    REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN
12463    MATCH_MP_TAC CONNECTED_UNION THEN ASM_SET_TAC[]]);
12464
12465val JOINABLE_COMPONENTS_EQ = store_thm ("JOINABLE_COMPONENTS_EQ",
12466 ``!s t c1 c2.
12467        connected t /\ t SUBSET s /\
12468        c1 IN components s /\ c2 IN components s /\
12469        ~(c1 INTER t = {}) /\ ~(c2 INTER t = {})
12470        ==> (c1 = c2)``,
12471  SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, components, FORALL_IN_GSPEC] THEN
12472  MESON_TAC[JOINABLE_CONNECTED_COMPONENT_EQ]);
12473
12474val CLOSED_IN_COMPONENT = store_thm ("CLOSED_IN_COMPONENT",
12475 ``!s c:real->bool.
12476        c IN components s ==> closed_in (subtopology euclidean s) c``,
12477  SIMP_TAC std_ss [components, FORALL_IN_GSPEC, CLOSED_IN_CONNECTED_COMPONENT]);
12478
12479val CLOSED_COMPONENTS = store_thm ("CLOSED_COMPONENTS",
12480 ``!s c. closed s /\ c IN components s ==> closed c``,
12481  SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, components, FORALL_IN_GSPEC] THEN
12482  SIMP_TAC std_ss [CLOSED_CONNECTED_COMPONENT]);
12483
12484val COMPACT_COMPONENTS = store_thm ("COMPACT_COMPONENTS",
12485 ``!s c:real->bool. compact s /\ c IN components s ==> compact c``,
12486  REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
12487  MESON_TAC[CLOSED_COMPONENTS, IN_COMPONENTS_SUBSET, BOUNDED_SUBSET]);
12488
12489val CONTINUOUS_ON_COMPONENTS_GEN = store_thm ("CONTINUOUS_ON_COMPONENTS_GEN",
12490 ``!f:real->real s.
12491        (!c. c IN components s
12492             ==> open_in (subtopology euclidean s) c /\ f continuous_on c)
12493        ==> f continuous_on s``,
12494  REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_OPEN_IN_PREIMAGE_EQ] THEN
12495  DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN DISCH_TAC THEN
12496  SUBGOAL_THEN
12497   ``{x | x IN s /\ (f:real->real) x IN t} =
12498     BIGUNION {{x | x IN c /\ f x IN t} | c IN components s}``
12499  SUBST1_TAC THENL
12500   [GEN_REWR_TAC LAND_CONV [METIS [BIGUNION_COMPONENTS] ``{x | x IN s /\ f x IN t} =
12501          {x | x IN BIGUNION (components s) /\ f x IN t}``] THEN
12502    SIMP_TAC std_ss [BIGUNION_GSPEC, IN_BIGUNION] THEN SET_TAC[],
12503    MATCH_MP_TAC OPEN_IN_BIGUNION THEN SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN
12504    METIS_TAC[OPEN_IN_TRANS]]);
12505
12506val CONTINUOUS_ON_COMPONENTS_FINITE = store_thm ("CONTINUOUS_ON_COMPONENTS_FINITE",
12507 ``!f:real->real s.
12508        FINITE(components s) /\
12509        (!c. c IN components s ==> f continuous_on c)
12510        ==> f continuous_on s``,
12511  REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN
12512  DISCH_TAC THEN X_GEN_TAC ``t:real->bool`` THEN DISCH_TAC THEN
12513  SUBGOAL_THEN
12514   ``{x | x IN s /\ (f:real->real) x IN t} =
12515    BIGUNION {{x | x IN c /\ f x IN t} | c IN components s}``
12516  SUBST1_TAC THENL
12517   [GEN_REWR_TAC LAND_CONV [METIS [BIGUNION_COMPONENTS] ``{x | x IN s /\ f x IN t} =
12518          {x | x IN BIGUNION (components s) /\ f x IN t}``] THEN
12519    SIMP_TAC std_ss [BIGUNION_GSPEC, IN_BIGUNION] THEN SET_TAC[],
12520    MATCH_MP_TAC CLOSED_IN_BIGUNION THEN
12521    ASM_SIMP_TAC std_ss [GSYM IMAGE_DEF, IMAGE_FINITE, FORALL_IN_IMAGE] THEN
12522    METIS_TAC[CLOSED_IN_TRANS, CLOSED_IN_COMPONENT]]);
12523
12524val COMPONENTS_NONOVERLAP = store_thm ("COMPONENTS_NONOVERLAP",
12525 ``!s c c'. c IN components s /\ c' IN components s
12526            ==> ((c INTER c' = {}) <=> ~(c = c'))``,
12527  SIMP_TAC std_ss [components, GSPECIFICATION] THEN REPEAT STRIP_TAC THEN
12528  ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_NONOVERLAP]);
12529
12530val COMPONENTS_EQ = store_thm ("COMPONENTS_EQ",
12531 ``!s c c'. c IN components s /\ c' IN components s
12532            ==> ((c = c') <=> ~(c INTER c' = {}))``,
12533  MESON_TAC[COMPONENTS_NONOVERLAP]);
12534
12535val COMPONENTS_EQ_EMPTY = store_thm ("COMPONENTS_EQ_EMPTY",
12536 ``!s. (components s = {}) <=> (s = {})``,
12537  GEN_TAC THEN REWRITE_TAC[EXTENSION] THEN
12538  SIMP_TAC std_ss [components, connected_component, GSPECIFICATION] THEN
12539  SET_TAC[]);
12540
12541val COMPONENTS_EMPTY = store_thm ("COMPONENTS_EMPTY",
12542 ``components {} = {}``,
12543  REWRITE_TAC[COMPONENTS_EQ_EMPTY]);
12544
12545val CONNECTED_EQ_CONNECTED_COMPONENTS_EQ = store_thm ("CONNECTED_EQ_CONNECTED_COMPONENTS_EQ",
12546 ``!s. connected s <=>
12547       !c c'. c IN components s /\ c' IN components s ==> (c = c')``,
12548  SIMP_TAC std_ss [components, GSPECIFICATION] THEN
12549  MESON_TAC[CONNECTED_EQ_CONNECTED_COMPONENT_EQ]);
12550
12551val COMPONENTS_EQ_SING_N_EXISTS = store_thm ("COMPONENTS_EQ_SING_N_EXISTS",
12552 ``(!s:real->bool. (components s = {s}) <=> connected s /\ ~(s = {})) /\
12553   (!s:real->bool. (?a. (components s = {a})) <=> connected s /\ ~(s = {}))``,
12554  SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN X_GEN_TAC ``s:real->bool`` THEN
12555  MATCH_MP_TAC(TAUT `(p ==> q) /\ (q ==> r) /\ (r ==> p)
12556                     ==> (p <=> r) /\ (q <=> r)`) THEN
12557  REPEAT CONJ_TAC THENL
12558   [MESON_TAC[],
12559    STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_EQ_CONNECTED_COMPONENTS_EQ] THEN
12560    ASM_MESON_TAC[IN_SING, COMPONENTS_EQ_EMPTY, NOT_INSERT_EMPTY],
12561    STRIP_TAC THEN ONCE_REWRITE_TAC[EXTENSION] THEN
12562    REWRITE_TAC[IN_SING] THEN
12563    SIMP_TAC std_ss [components, GSPECIFICATION] THEN
12564    ASM_MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET, MEMBER_NOT_EMPTY]]);
12565
12566val COMPONENTS_EQ_SING = store_thm ("COMPONENTS_EQ_SING",
12567 ``(!s:real->bool. (components s = {s}) <=> connected s /\ ~(s = {}))``,
12568   REWRITE_TAC [COMPONENTS_EQ_SING_N_EXISTS]);
12569
12570val COMPONENTS_EQ_SING_EXISTS = store_thm ("COMPONENTS_EQ_SING_EXISTS",
12571 `` (!s:real->bool. (?a. (components s = {a})) <=> connected s /\ ~(s = {}))``,
12572   REWRITE_TAC [COMPONENTS_EQ_SING_N_EXISTS]);
12573
12574val COMPONENTS_UNIV = store_thm ("COMPONENTS_UNIV",
12575 ``components univ(:real) = {univ(:real)}``,
12576  REWRITE_TAC[COMPONENTS_EQ_SING, CONNECTED_UNIV, UNIV_NOT_EMPTY]);
12577
12578val CONNECTED_EQ_COMPONENTS_SUBSET_SING = store_thm ("CONNECTED_EQ_COMPONENTS_SUBSET_SING",
12579 ``!s:real->bool. connected s <=> components s SUBSET {s}``,
12580  GEN_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN
12581  ASM_REWRITE_TAC[COMPONENTS_EMPTY, CONNECTED_EMPTY, EMPTY_SUBSET] THEN
12582  REWRITE_TAC[SET_RULE ``s SUBSET {a} <=> (s = {}) \/ (s = {a})``] THEN
12583  ASM_REWRITE_TAC[COMPONENTS_EQ_EMPTY, COMPONENTS_EQ_SING]);
12584
12585val CONNECTED_EQ_COMPONENTS_SUBSET_SING_EXISTS = store_thm ("CONNECTED_EQ_COMPONENTS_SUBSET_SING_EXISTS",
12586 ``!s:real->bool. connected s <=> ?a. components s SUBSET {a}``,
12587  GEN_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN
12588  ASM_REWRITE_TAC[COMPONENTS_EMPTY, CONNECTED_EMPTY, EMPTY_SUBSET] THEN
12589  REWRITE_TAC[SET_RULE ``s SUBSET {a} <=> (s = {}) \/ (s = {a})``] THEN
12590  ASM_REWRITE_TAC[COMPONENTS_EQ_EMPTY, COMPONENTS_EQ_SING_EXISTS]);
12591
12592val IN_COMPONENTS_SELF = store_thm ("IN_COMPONENTS_SELF",
12593 ``!s:real->bool. s IN components s <=> connected s /\ ~(s = {})``,
12594  GEN_TAC THEN EQ_TAC THENL
12595   [MESON_TAC[IN_COMPONENTS_NONEMPTY, IN_COMPONENTS_CONNECTED],
12596    SIMP_TAC std_ss [GSYM COMPONENTS_EQ_SING, IN_SING]]);
12597
12598val     COMPONENTS_MAXIMAL = store_thm ("COMPONENTS_MAXIMAL",
12599 ``!s t c:real->bool.
12600     c IN components s /\ connected t /\ t SUBSET s /\ ~(c INTER t = {})
12601     ==> t SUBSET c``,
12602  SIMP_TAC std_ss [CONJ_EQ_IMP, components, FORALL_IN_GSPEC] THEN
12603  REPEAT STRIP_TAC THEN
12604  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
12605  SIMP_TAC std_ss [IN_INTER, LEFT_IMP_EXISTS_THM] THEN
12606  X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN
12607  FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP CONNECTED_COMPONENT_EQ) THEN
12608  MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN ASM_REWRITE_TAC[]);
12609
12610val COMPONENTS_UNIQUE = store_thm ("COMPONENTS_UNIQUE",
12611 ``!s:real->bool k.
12612        (BIGUNION k = s) /\
12613        (!c. c IN k
12614             ==> connected c /\ ~(c = {}) /\
12615                 !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> (c' = c))
12616        ==> (components s = k)``,
12617  REPEAT STRIP_TAC THEN GEN_REWR_TAC I [EXTENSION] THEN
12618  X_GEN_TAC ``c:real->bool`` THEN REWRITE_TAC[IN_COMPONENTS] THEN
12619  EQ_TAC THENL
12620   [DISCH_THEN(X_CHOOSE_THEN ``x:real``
12621     (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN
12622        UNDISCH_TAC `` !c. c IN k ==>
12623            connected c /\ c <> {} /\
12624            !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> (c' = c)`` THEN DISCH_TAC THEN
12625    FIRST_ASSUM(MP_TAC o SPEC ``x:real`` o REWRITE_RULE [EXTENSION]) THEN
12626    REWRITE_TAC[IN_BIGUNION] THEN ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN
12627    X_GEN_TAC ``c:real->bool`` THEN STRIP_TAC THEN
12628    SUBGOAL_THEN ``connected_component s (x:real) = c``
12629     (fn th => ASM_REWRITE_TAC[th]) THEN
12630    MATCH_MP_TAC CONNECTED_COMPONENT_UNIQUE THEN
12631    FIRST_X_ASSUM(MP_TAC o SPEC ``c:real->bool``) THEN
12632    ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
12633    CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
12634    X_GEN_TAC ``c':real->bool`` THEN STRIP_TAC THEN
12635    REWRITE_TAC[SET_RULE ``c' SUBSET c <=> (c' UNION c = c)``] THEN
12636    FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL
12637     [MATCH_MP_TAC CONNECTED_UNION, ASM_SET_TAC[]] THEN
12638    ASM_SET_TAC[],
12639    DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``c:real->bool``) THEN
12640    ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
12641        UNDISCH_TAC ``c <> {}:real->bool`` THEN DISCH_TAC THEN
12642    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
12643        STRIP_TAC THEN EXISTS_TAC ``x:real`` THEN
12644    CONJ_TAC THENL [ASM_SET_TAC[], CONV_TAC SYM_CONV] THEN
12645    FIRST_X_ASSUM MATCH_MP_TAC THEN
12646    REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT, CONNECTED_COMPONENT_SUBSET] THEN
12647    MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
12648    ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]]);
12649
12650val COMPONENTS_UNIQUE_EQ = store_thm ("COMPONENTS_UNIQUE_EQ",
12651 ``!s:real->bool k.
12652        (components s = k) <=>
12653        (BIGUNION k = s) /\
12654        (!c. c IN k
12655             ==> connected c /\ ~(c = {}) /\
12656                 !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> (c' = c))``,
12657  REPEAT GEN_TAC THEN EQ_TAC THENL
12658   [DISCH_THEN(SUBST1_TAC o SYM), REWRITE_TAC[COMPONENTS_UNIQUE]] THEN
12659  REWRITE_TAC[GSYM BIGUNION_COMPONENTS] THEN
12660  X_GEN_TAC ``c:real->bool`` THEN DISCH_TAC THEN REPEAT CONJ_TAC THENL
12661   [ASM_MESON_TAC[IN_COMPONENTS_CONNECTED],
12662    ASM_MESON_TAC[IN_COMPONENTS_NONEMPTY],
12663    RULE_ASSUM_TAC(REWRITE_RULE[IN_COMPONENTS_MAXIMAL]) THEN
12664    ASM_MESON_TAC[SUBSET_EMPTY]]);
12665
12666val EXISTS_COMPONENT_SUPERSET = store_thm ("EXISTS_COMPONENT_SUPERSET",
12667 ``!s t:real->bool.
12668        t SUBSET s /\ ~(s = {}) /\ connected t
12669        ==> ?c. c IN components s /\ t SUBSET c``,
12670  REPEAT STRIP_TAC THEN ASM_CASES_TAC ``t:real->bool = {}`` THENL
12671   [ASM_REWRITE_TAC[EMPTY_SUBSET] THEN
12672    ASM_MESON_TAC[COMPONENTS_EQ_EMPTY, MEMBER_NOT_EMPTY],
12673    FIRST_X_ASSUM(X_CHOOSE_TAC ``a:real`` o
12674      REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
12675    EXISTS_TAC ``connected_component s (a:real)`` THEN
12676    REWRITE_TAC[IN_COMPONENTS] THEN CONJ_TAC THENL
12677     [ASM_SET_TAC[], ASM_MESON_TAC[CONNECTED_COMPONENT_MAXIMAL]]]);
12678
12679val COMPONENTS_INTERMEDIATE_SUBSET = store_thm ("COMPONENTS_INTERMEDIATE_SUBSET",
12680 ``!s t u:real->bool.
12681        s IN components u /\ s SUBSET t /\ t SUBSET u
12682        ==> s IN components t``,
12683  REPEAT GEN_TAC THEN SIMP_TAC std_ss [IN_COMPONENTS, GSYM LEFT_EXISTS_AND_THM] THEN
12684  MESON_TAC[CONNECTED_COMPONENT_INTERMEDIATE_SUBSET, SUBSET_DEF,
12685            CONNECTED_COMPONENT_REFL, IN_DEF, CONNECTED_COMPONENT_SUBSET]);
12686
12687val IN_COMPONENTS_BIGUNION_COMPLEMENT = store_thm ("IN_COMPONENTS_BIGUNION_COMPLEMENT",
12688 ``!s c:real->bool.
12689        c IN components s
12690        ==> (s DIFF c = BIGUNION(components s DELETE c))``,
12691  SIMP_TAC std_ss [components, FORALL_IN_GSPEC,
12692              COMPLEMENT_CONNECTED_COMPONENT_BIGUNION]);
12693
12694val CONNECTED_SUBSET_CLOPEN = store_thm ("CONNECTED_SUBSET_CLOPEN",
12695 ``!u s c:real->bool.
12696        closed_in (subtopology euclidean u) s /\
12697        open_in (subtopology euclidean u) s /\
12698        connected c /\ c SUBSET u /\ ~(c INTER s = {})
12699        ==> c SUBSET s``,
12700  REPEAT STRIP_TAC THEN
12701  UNDISCH_TAC ``connected c`` THEN DISCH_TAC THEN
12702  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [CONNECTED_CLOSED_IN]) THEN
12703  SIMP_TAC std_ss [NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o
12704    SPECL [``c INTER s:real->bool``, ``c DIFF s:real->bool``]) THEN
12705  KNOW_TAC ``~((((closed_in (subtopology euclidean (c :real -> bool))
12706               (c INTER (s :real -> bool)) /\
12707               closed_in (subtopology euclidean c) (c DIFF s)) /\
12708               (c SUBSET c INTER s UNION (c DIFF s))) /\
12709               (c INTER s INTER (c DIFF s) = ({} :real -> bool))) /\
12710     ~(c SUBSET s)) ==> c SUBSET s`` THENL
12711         [ALL_TAC, METIS_TAC [CONJ_ASSOC, SET_RULE ``(c DIFF s = {}) <=> c SUBSET s``]] THEN
12712  MATCH_MP_TAC(TAUT `p ==> ~(p /\ ~q) ==> q`) THEN
12713  CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
12714  CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
12715  CONJ_TAC THENL
12716   [UNDISCH_TAC ``closed_in (subtopology euclidean u) s`` THEN DISCH_TAC THEN
12717    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [CLOSED_IN_CLOSED]),
12718        UNDISCH_TAC ``open_in (subtopology euclidean u) s`` THEN DISCH_TAC THEN
12719    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_OPEN])] THEN
12720  DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN
12721  REWRITE_TAC[OPEN_IN_OPEN, CLOSED_IN_CLOSED] THENL
12722   [EXISTS_TAC ``t:real->bool``, EXISTS_TAC ``univ(:real) DIFF t``] THEN
12723  ASM_REWRITE_TAC[GSYM OPEN_CLOSED] THEN ASM_SET_TAC[]);
12724
12725val CLOPEN_BIGUNION_COMPONENTS = store_thm ("CLOPEN_BIGUNION_COMPONENTS",
12726 ``!u s:real->bool.
12727        closed_in (subtopology euclidean u) s /\
12728        open_in (subtopology euclidean u) s
12729        ==> ?k. k SUBSET components u /\ (s = BIGUNION k)``,
12730  REPEAT STRIP_TAC THEN
12731  EXISTS_TAC ``{c:real->bool | c IN components u /\ ~(c INTER s = {})}`` THEN
12732  SIMP_TAC std_ss [SUBSET_RESTRICT] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
12733  CONJ_TAC THENL
12734   [MP_TAC(ISPEC ``u:real->bool`` BIGUNION_COMPONENTS) THEN
12735    FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN SET_TAC[],
12736    SIMP_TAC std_ss [BIGUNION_SUBSET, FORALL_IN_GSPEC] THEN
12737    REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_SUBSET_CLOPEN THEN
12738    EXISTS_TAC ``u:real->bool`` THEN
12739    ASM_MESON_TAC[IN_COMPONENTS_CONNECTED, IN_COMPONENTS_SUBSET]]);
12740
12741val CLOPEN_IN_COMPONENTS = store_thm ("CLOPEN_IN_COMPONENTS",
12742 ``!u s:real->bool.
12743        closed_in (subtopology euclidean u) s /\
12744        open_in (subtopology euclidean u) s /\
12745        connected s /\ ~(s = {})
12746        ==> s IN components u``,
12747  REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[CONJ_ASSOC] THEN
12748  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
12749  FIRST_ASSUM(MP_TAC o MATCH_MP CLOPEN_BIGUNION_COMPONENTS) THEN
12750  DISCH_THEN(X_CHOOSE_THEN ``k:(real->bool)->bool`` STRIP_ASSUME_TAC) THEN
12751  ASM_CASES_TAC ``k:(real->bool)->bool = {}`` THEN
12752  ASM_REWRITE_TAC[BIGUNION_EMPTY] THEN
12753  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
12754  DISCH_THEN(X_CHOOSE_TAC ``c:real->bool``) THEN
12755  ASM_CASES_TAC ``k = {c:real->bool}`` THENL
12756   [METIS_TAC[BIGUNION_SING, GSYM SING_SUBSET], ALL_TAC] THEN
12757  MATCH_MP_TAC(TAUT `~p ==> p /\ q ==> r`) THEN
12758  SUBGOAL_THEN ``?c':real->bool. c' IN k /\ ~(c = c')`` STRIP_ASSUME_TAC THENL
12759   [ASM_MESON_TAC[SET_RULE
12760     ``a IN s /\ ~(s = {a}) ==> ?b. b IN s /\ ~(b = a)``],
12761    REWRITE_TAC[CONNECTED_EQ_CONNECTED_COMPONENTS_EQ] THEN
12762    DISCH_THEN(MP_TAC o SPECL [``c:real->bool``, ``c':real->bool``]) THEN
12763    ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THEN
12764    MATCH_MP_TAC COMPONENTS_INTERMEDIATE_SUBSET THEN
12765    EXISTS_TAC ``u:real->bool`` THEN
12766    MP_TAC(ISPEC ``u:real->bool`` BIGUNION_COMPONENTS) THEN ASM_SET_TAC[]]);
12767
12768(* ------------------------------------------------------------------------- *)
12769(* Continuity implies uniform continuity on a compact domain.                *)
12770(* ------------------------------------------------------------------------- *)
12771
12772val COMPACT_UNIFORMLY_EQUICONTINUOUS = store_thm ("COMPACT_UNIFORMLY_EQUICONTINUOUS",
12773 ``!(fs:(real->real)->bool) s.
12774     (!x e. x IN s /\ &0 < e
12775            ==> ?d. &0 < d /\
12776                    (!f x'. f IN fs /\ x' IN s /\ dist (x',x) < d
12777                            ==> dist (f x',f x) < e)) /\
12778     compact s
12779     ==> !e. &0 < e
12780             ==> ?d. &0 < d /\
12781                     !f x x'. f IN fs /\ x IN s /\ x' IN s /\ dist (x',x) < d
12782                              ==> dist(f x',f x) < e``,
12783  REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
12784  DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN
12785  SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN
12786  X_GEN_TAC ``d:real->real->real`` THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN
12787  DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP HEINE_BOREL_LEMMA) THEN
12788  DISCH_THEN(MP_TAC o SPEC
12789    ``{ ball(x:real,d x (e / &2:real)) | x IN s}``) THEN
12790  SIMP_TAC std_ss [FORALL_IN_GSPEC, OPEN_BALL, BIGUNION_GSPEC, SUBSET_DEF, GSPECIFICATION] THEN
12791  KNOW_TAC ``(!(x :real).
12792        x IN (s :real -> bool) ==>
12793        ?(x' :real).
12794          x' IN s /\
12795          x IN
12796          ball
12797            (x',
12798             (d :real -> real -> real) x'
12799               ((e :real) / (2 :real))))`` THENL
12800  [ASM_MESON_TAC[CENTRE_IN_BALL, REAL_HALF], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
12801  DISCH_THEN (X_CHOOSE_TAC ``k:real``) THEN EXISTS_TAC ``k:real`` THEN
12802  POP_ASSUM MP_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
12803  MAP_EVERY X_GEN_TAC [``f:real->real``, ``u:real``, ``v:real``] THEN
12804  STRIP_TAC THEN FIRST_X_ASSUM(fn th => MP_TAC(SPEC ``v:real`` th) THEN
12805    ASM_REWRITE_TAC[] THEN DISCH_THEN(CHOOSE_THEN MP_TAC)) THEN
12806  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
12807  DISCH_THEN(fn th =>
12808    MP_TAC(SPEC ``u:real`` th) THEN MP_TAC(SPEC ``v:real`` th)) THEN
12809  ASM_SIMP_TAC std_ss [DIST_REFL] THEN POP_ASSUM MP_TAC THEN
12810  DISCH_THEN (X_CHOOSE_TAC ``w:real``) THEN ASM_REWRITE_TAC [] THEN
12811  ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN ASM_REWRITE_TAC[IN_BALL] THEN
12812  ONCE_REWRITE_TAC[DIST_SYM] THEN REPEAT STRIP_TAC THEN
12813  FIRST_X_ASSUM(MP_TAC o SPECL [``w:real``, ``e / &2:real``]) THEN
12814  ASM_REWRITE_TAC[REAL_HALF] THEN
12815  DISCH_THEN(MP_TAC o SPEC ``f:real->real`` o CONJUNCT2) THEN
12816  DISCH_THEN(fn th => MP_TAC(SPEC ``u:real`` th) THEN
12817                        MP_TAC(SPEC ``v:real`` th)) THEN
12818  ASM_REWRITE_TAC[] THEN GEN_REWR_TAC (LAND_CONV o LAND_CONV) [DIST_SYM] THEN
12819  REWRITE_TAC [dist] THEN GEN_REWR_TAC (RAND_CONV o RAND_CONV o RAND_CONV) [GSYM REAL_HALF] THEN
12820  REAL_ARITH_TAC);
12821
12822val COMPACT_UNIFORMLY_CONTINUOUS = store_thm ("COMPACT_UNIFORMLY_CONTINUOUS",
12823 ``!f:real->real s.
12824        f continuous_on s /\ compact s ==> f uniformly_continuous_on s``,
12825  REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on, uniformly_continuous_on] THEN
12826  STRIP_TAC THEN
12827  MP_TAC(ISPECL [``{f:real->real}``, ``s:real->bool``]
12828        COMPACT_UNIFORMLY_EQUICONTINUOUS) THEN
12829  SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM, CONJ_EQ_IMP, IN_SING, UNWIND_FORALL_THM2] THEN
12830  ASM_MESON_TAC[]);
12831
12832(* ------------------------------------------------------------------------- *)
12833(* A uniformly convergent limit of continuous functions is continuous.       *)
12834(* ------------------------------------------------------------------------- *)
12835
12836val ABS_TRIANGLE_LE = store_thm ("ABS_TRIANGLE_LE",
12837 ``!x y. abs(x) + abs(y) <= e ==> abs(x + y) <= e:real``,
12838  METIS_TAC[REAL_LE_TRANS, ABS_TRIANGLE]);
12839
12840val CONTINUOUS_UNIFORM_LIMIT = store_thm ("CONTINUOUS_UNIFORM_LIMIT",
12841 ``!net f:'a->real->real g s.
12842        ~(trivial_limit net) /\
12843        eventually (\n. (f n) continuous_on s) net /\
12844        (!e. &0 < e
12845             ==> eventually (\n. !x. x IN s ==> abs(f n x - g x) < e) net)
12846        ==> g continuous_on s``,
12847  REWRITE_TAC[continuous_on] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
12848  X_GEN_TAC ``x:real`` THEN STRIP_TAC THEN
12849  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
12850  FIRST_X_ASSUM(MP_TAC o SPEC ``e / &3:real``) THEN
12851  ASM_SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT] THEN
12852  UNDISCH_TAC ``eventually
12853        (\n. !x. x IN s ==>
12854             !e. 0 < e ==>
12855               ?d. 0 < d /\
12856                 !x'. x' IN s /\ dist (x',x) < d ==>
12857                   dist (f n x',f n x) < e) net`` THEN DISCH_TAC THEN
12858  FIRST_X_ASSUM(fn th => MP_TAC th THEN REWRITE_TAC[AND_IMP_INTRO] THEN
12859        GEN_REWR_TAC LAND_CONV [GSYM EVENTUALLY_AND]) THEN
12860  DISCH_THEN(MP_TAC o MATCH_MP EVENTUALLY_HAPPENS) THEN
12861  ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC ``a:'a`` THEN
12862  DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC ``x:real``) ASSUME_TAC) THEN
12863  ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``e / &3:real``) THEN
12864  ASM_SIMP_TAC arith_ss [REAL_LT_DIV, REAL_LT] THEN
12865  DISCH_THEN (X_CHOOSE_TAC ``d:real``) THEN EXISTS_TAC ``d:real`` THEN
12866  POP_ASSUM MP_TAC THEN
12867  MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
12868  DISCH_TAC THEN X_GEN_TAC ``y:real`` THEN POP_ASSUM (MP_TAC o Q.SPEC `y:real`) THEN
12869  DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
12870  FIRST_X_ASSUM(fn th =>
12871   MP_TAC(SPEC ``x:real`` th) THEN MP_TAC(SPEC ``y:real`` th)) THEN
12872  ASM_REWRITE_TAC[] THEN SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 3:real``] THEN
12873  MATCH_MP_TAC(REAL_ARITH ``w <= x + y + z
12874    ==> x * &3 < e ==> y * &3 < e ==> z * &3 < e ==> w < e:real``) THEN
12875  REWRITE_TAC[dist] THEN
12876  SUBST1_TAC(REAL_ARITH
12877   ``(g:real->real) y - g x =
12878    -(f (a:'a) y - g y) + (f a x - g x) + (f a y - f a x)``) THEN
12879  MATCH_MP_TAC ABS_TRIANGLE_LE THEN SIMP_TAC std_ss [ABS_NEG, REAL_LE_LADD] THEN
12880  MATCH_MP_TAC REAL_LE_ADD2 THEN SIMP_TAC std_ss [REAL_LE_REFL] THEN
12881  MATCH_MP_TAC ABS_TRIANGLE_LE THEN REWRITE_TAC[ABS_NEG, REAL_LE_REFL]);
12882
12883(* ------------------------------------------------------------------------- *)
12884(* Topological stuff lifted from and dropped to R                            *)
12885(* ------------------------------------------------------------------------- *)
12886
12887val OPEN = store_thm ("OPEN",
12888 ``!s. open s <=>
12889        !x. x IN s ==> ?e. &0 < e /\ !x'. abs(x' - x) < e ==> x' IN s``,
12890  REWRITE_TAC[open_def, dist]);
12891
12892val CLOSED = store_thm ("CLOSED",
12893 ``!s. closed s <=>
12894        !x. (!e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ abs(x' - x) < e)
12895            ==> x IN s``,
12896   SIMP_TAC std_ss [open_def, closed_def, dist, IN_DIFF, IN_UNIV] THEN
12897   SET_TAC []);
12898
12899val CONTINUOUS_AT_RANGE = store_thm ("CONTINUOUS_AT_RANGE",
12900 ``!f x. f continuous (at x) <=>
12901                !e. &0 < e
12902                    ==> ?d. &0 < d /\
12903                            (!x'. abs(x' - x) < d
12904                                  ==> abs(f x' - f x) < e)``,
12905  REWRITE_TAC[continuous_at, o_THM, dist] THEN REWRITE_TAC[dist]);
12906
12907val CONTINUOUS_ON_RANGE = store_thm ("CONTINUOUS_ON_RANGE",
12908 ``!f s. f continuous_on s <=>
12909         !x. x IN s
12910             ==> !e. &0 < e
12911                     ==> ?d. &0 < d /\
12912                             (!x'. x' IN s /\ abs(x' - x) < d
12913                                   ==> abs(f x' - f x) < e)``,
12914  REWRITE_TAC[continuous_on, o_THM, dist] THEN REWRITE_TAC[dist]);
12915
12916val CONTINUOUS_ABS_COMPOSE = store_thm ("CONTINUOUS_ABS_COMPOSE",
12917 ``!net f:'a->real.
12918        f continuous net
12919        ==> (\x. abs(f x)) continuous net``,
12920  REPEAT GEN_TAC THEN REWRITE_TAC[continuous, tendsto] THEN
12921  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `e:real`) THEN
12922  MATCH_MP_TAC MONO_IMP THEN
12923  REWRITE_TAC[] THEN
12924  MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] EVENTUALLY_MONO) THEN
12925  SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
12926
12927val CONTINUOUS_ON_ABS_COMPOSE = store_thm ("CONTINUOUS_ON_ABS_COMPOSE",
12928 ``!f:real->real s.
12929        f continuous_on s
12930        ==> (\x. abs(f x)) continuous_on s``,
12931  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_ABS_COMPOSE]);
12932
12933val CONTINUOUS_AT_ABS = store_thm ("CONTINUOUS_AT_ABS",
12934 ``!x. abs continuous (at x)``,
12935  REWRITE_TAC[CONTINUOUS_AT_RANGE] THEN
12936  METIS_TAC [ABS_SUB_ABS, REAL_LET_TRANS]);
12937
12938val CONTINUOUS_AT_DIST = store_thm ("CONTINUOUS_AT_DIST",
12939 ``!a:real x. (\x. dist(a,x)) continuous (at x)``,
12940  REWRITE_TAC[CONTINUOUS_AT_RANGE, dist] THEN
12941  METIS_TAC[REAL_ARITH ``abs(abs(a:real - x) - abs(a - y)) <= abs(x - y)``,
12942            REAL_LET_TRANS]);
12943
12944val CONTINUOUS_ON_DIST = store_thm ("CONTINUOUS_ON_DIST",
12945 ``!a s. (\x. dist(a,x)) continuous_on s``,
12946  REWRITE_TAC[CONTINUOUS_ON_RANGE, dist] THEN
12947  METIS_TAC [REAL_ARITH ``abs(abs(a:real - x) - abs(a - y)) <= abs(x - y)``,
12948            REAL_LET_TRANS]);
12949
12950(* ------------------------------------------------------------------------- *)
12951(* Hence some handy theorems on distance, diameter etc. of/from a set.       *)
12952(* ------------------------------------------------------------------------- *)
12953
12954val COMPACT_ATTAINS_SUP = store_thm ("COMPACT_ATTAINS_SUP",
12955 ``!s. compact s /\ ~(s = {})
12956       ==> ?x. x IN s /\ !y. y IN s ==> y <= x``,
12957  REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN REPEAT STRIP_TAC THEN
12958  MP_TAC(SPEC ``s:real->bool`` BOUNDED_HAS_SUP) THEN ASM_REWRITE_TAC[] THEN
12959  STRIP_TAC THEN EXISTS_TAC ``sup (s:real->bool)`` THEN ASM_SIMP_TAC std_ss [] THEN
12960  METIS_TAC [CLOSED, REAL_ARITH ``s <= s - e <=> ~(&0 < e:real)``,
12961             REAL_ARITH ``x <= s /\ ~(x <= s - e) ==> abs(x - s) < e:real``]);
12962
12963val COMPACT_ATTAINS_INF = store_thm ("COMPACT_ATTAINS_INF",
12964 ``!s. compact s /\ ~(s = {})
12965       ==> ?x. x IN s /\ !y. y IN s ==> x <= y``,
12966  REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN REPEAT STRIP_TAC THEN
12967  MP_TAC(SPEC ``s:real->bool`` BOUNDED_HAS_INF) THEN ASM_REWRITE_TAC[] THEN
12968  STRIP_TAC THEN EXISTS_TAC ``inf (s:real->bool)`` THEN ASM_REWRITE_TAC[] THEN
12969  METIS_TAC[ CLOSED, REAL_ARITH ``s + e <= s <=> ~(&0 < e:real)``,
12970                REAL_ARITH ``s <= x /\ ~(s + e <= x) ==> abs(x - s) < e:real``]);
12971
12972val CONTINUOUS_ATTAINS_SUP = store_thm ("CONTINUOUS_ATTAINS_SUP",
12973 ``!f:real->real s.
12974        compact s /\ ~(s = {}) /\ (f) continuous_on s
12975        ==> ?x. x IN s /\ !y. y IN s ==> f(y) <= f(x)``,
12976  REPEAT STRIP_TAC THEN
12977  MP_TAC(SPEC ``IMAGE (f:real->real) s`` COMPACT_ATTAINS_SUP) THEN
12978  ASM_SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, COMPACT_CONTINUOUS_IMAGE, IMAGE_EQ_EMPTY] THEN
12979  MESON_TAC[IN_IMAGE]);
12980
12981val CONTINUOUS_ATTAINS_INF = store_thm ("CONTINUOUS_ATTAINS_INF",
12982 ``!f:real->real s.
12983        compact s /\ ~(s = {}) /\ (f) continuous_on s
12984        ==> ?x. x IN s /\ !y. y IN s ==> f(x) <= f(y)``,
12985  REPEAT STRIP_TAC THEN
12986  MP_TAC(SPEC ``IMAGE (f:real->real) s`` COMPACT_ATTAINS_INF) THEN
12987  ASM_SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, COMPACT_CONTINUOUS_IMAGE, IMAGE_EQ_EMPTY] THEN
12988  MESON_TAC[IN_IMAGE]);
12989
12990val DISTANCE_ATTAINS_SUP = store_thm ("DISTANCE_ATTAINS_SUP",
12991 ``!s a. compact s /\ ~(s = {})
12992         ==> ?x. x IN s /\ !y. y IN s ==> dist(a,y) <= dist(a,x)``,
12993  REPEAT STRIP_TAC THEN
12994  ONCE_REWRITE_TAC [METIS [] ``dist (a,x) = (\x. dist (a,x)) x:real``] THEN
12995  MATCH_MP_TAC CONTINUOUS_ATTAINS_SUP THEN
12996  ASM_REWRITE_TAC[CONTINUOUS_ON_RANGE] THEN REWRITE_TAC[dist] THEN
12997  ASM_MESON_TAC[REAL_LET_TRANS, ABS_SUB_ABS, ABS_NEG,
12998                REAL_ARITH ``(a - x) - (a - y) = -(x - y):real``]);
12999
13000(* ------------------------------------------------------------------------- *)
13001(* For *minimal* distance, we only need closure, not compactness.            *)
13002(* ------------------------------------------------------------------------- *)
13003
13004val DISTANCE_ATTAINS_INF = store_thm ("DISTANCE_ATTAINS_INF",
13005 ``!s a:real.
13006        closed s /\ ~(s = {})
13007        ==> ?x. x IN s /\ !y. y IN s ==> dist(a,x) <= dist(a,y)``,
13008  REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
13009  REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
13010  DISCH_THEN(X_CHOOSE_TAC ``b:real``) THEN
13011  MP_TAC(ISPECL [``\x:real. dist(a,x)``, ``cball(a:real,dist(b,a)) INTER s``]
13012                CONTINUOUS_ATTAINS_INF) THEN
13013  KNOW_TAC ``compact
13014   (cball ((a :real),(dist ((b :real),a) :real)) INTER
13015    (s :real -> bool)) /\
13016    cball (a,(dist (b,a) :real)) INTER s <> ({} :real -> bool) /\
13017    (\(x :real). (dist (a,x) :real)) continuous_on
13018    cball (a,(dist (b,a) :real)) INTER s`` THENL
13019   [ASM_SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_INTER, BOUNDED_INTER,
13020                 BOUNDED_CBALL, CLOSED_CBALL, GSYM MEMBER_NOT_EMPTY] THEN
13021    SIMP_TAC std_ss [dist, CONTINUOUS_ON_RANGE, IN_INTER, IN_CBALL] THEN
13022    METIS_TAC[REAL_LET_TRANS, ABS_SUB_ABS, ABS_NEG, REAL_LE_REFL,
13023            ABS_SUB, REAL_ARITH ``(a - x) - (a - y) = -(x - y:real):real``],
13024    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
13025    DISCH_THEN (X_CHOOSE_TAC ``x:real``) THEN EXISTS_TAC ``x:real`` THEN
13026    POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [IN_INTER, IN_CBALL] THEN
13027    METIS_TAC[DIST_SYM, REAL_LE_TOTAL, REAL_LE_TRANS]]);
13028
13029(* ------------------------------------------------------------------------- *)
13030(* We can now extend limit compositions to consider the scalar multiplier.   *)
13031(* ------------------------------------------------------------------------- *)
13032
13033val LIM_MUL = store_thm ("LIM_MUL",
13034 ``!net:('a)net f l:real c d.
13035        (c --> d) net /\ (f --> l) net
13036        ==> ((\x. c(x) * f(x)) --> (d * l)) net``,
13037  REPEAT STRIP_TAC THEN
13038  MP_TAC(ISPECL [``net:('a)net``, ``\x y:real. x * y``, ``c:'a->real``,
13039  ``f:'a->real``, ``d:real``, ``l:real``] LIM_BILINEAR) THEN
13040  BETA_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_THEN MATCH_MP_TAC THEN
13041  REWRITE_TAC[bilinear, linear] THEN BETA_TAC THEN
13042  REPEAT STRIP_TAC THEN REAL_ARITH_TAC);
13043
13044val LIM_VMUL = store_thm ("LIM_VMUL",
13045 ``!net:('a)net c d v:real.
13046  (c --> d) net ==> ((\x. c(x) * v) --> (d * v)) net``,
13047  REPEAT STRIP_TAC THEN
13048  KNOW_TAC ``(((\(x :'a). (c :'a -> real) x * (v :real)) -->
13049                             ((d :real) * v)) (net :'a net)) =
13050             (((\(x :'a). (c :'a -> real) x * (\x. v :real) x) -->
13051                             ((d :real) * v)) (net :'a net))`` THENL
13052 [SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
13053 MATCH_MP_TAC LIM_MUL THEN ASM_REWRITE_TAC[LIM_CONST]);
13054
13055val CONTINUOUS_VMUL = store_thm ("CONTINUOUS_VMUL",
13056 ``!net c v. c continuous net ==> (\x. c(x) * v) continuous net``,
13057  SIMP_TAC std_ss [continuous, LIM_VMUL, o_THM]);
13058
13059val CONTINUOUS_MUL = store_thm ("CONTINUOUS_MUL",
13060 ``!net f c. c continuous net /\ f continuous net
13061             ==> (\x. c(x) * f(x)) continuous net``,
13062  SIMP_TAC std_ss [continuous, LIM_MUL, o_THM]);
13063
13064val CONTINUOUS_ON_VMUL = store_thm ("CONTINUOUS_ON_VMUL",
13065 ``!s c v. c continuous_on s ==> (\x. c(x) * v) continuous_on s``,
13066  REWRITE_TAC [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
13067  SIMP_TAC std_ss [CONTINUOUS_VMUL]);
13068
13069val CONTINUOUS_ON_MUL = store_thm ("CONTINUOUS_ON_MUL",
13070 ``!s c f. c continuous_on s /\ f continuous_on s
13071           ==> (\x. c(x) * f(x)) continuous_on s``,
13072  REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
13073  SIMP_TAC std_ss [CONTINUOUS_MUL]);
13074
13075val CONTINUOUS_POW = store_thm ("CONTINUOUS_POW",
13076 ``!net f:'a->real n.
13077        (\x. f x) continuous net
13078        ==> (\x. f x pow n) continuous net``,
13079  SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
13080  INDUCT_TAC THEN ASM_SIMP_TAC std_ss [pow, CONTINUOUS_CONST] THEN
13081  KNOW_TAC ``((\x:'a. f x * f x pow n) continuous net) =
13082             ((\x:'a. f x * (\x. f x pow n) x)  continuous net)`` THENL
13083  [SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
13084  MATCH_MP_TAC CONTINUOUS_MUL THEN METIS_TAC [o_DEF, ETA_AX]);
13085
13086val CONTINUOUS_ON_POW = store_thm ("CONTINUOUS_ON_POW",
13087 ``!f:real->real s n.
13088        (\x. f x) continuous_on s
13089        ==> (\x. f x pow n) continuous_on s``,
13090  SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN
13091  DISCH_TAC THEN INDUCT_TAC THEN
13092  ASM_SIMP_TAC std_ss[pow, CONTINUOUS_ON_CONST] THEN
13093  KNOW_TAC ``((\x. (f:real->real) x * f x pow n) continuous_on s:real->bool) =
13094             ((\x. f x * (\x. f x pow n) x)  continuous_on s)`` THENL
13095  [SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
13096  MATCH_MP_TAC CONTINUOUS_ON_MUL THEN METIS_TAC [o_DEF, ETA_AX]);
13097
13098val CONTINUOUS_PRODUCT = store_thm ("CONTINUOUS_PRODUCT",
13099 ``!net:('a)net f (t:'b->bool).
13100        FINITE t /\
13101        (!i. i IN t ==> (\x. (f x i)) continuous net)
13102        ==> (\x. (product t (f x))) continuous net``,
13103  GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[CONJ_EQ_IMP] THEN
13104  ONCE_REWRITE_TAC [METIS []
13105    ``!t. ((!i. i IN t ==> (\x. f x i) continuous net) ==>
13106  (\x. product t (f x)) continuous net) =
13107     (\t. (!i. i IN t ==> (\x. f x i) continuous net) ==>
13108  (\x. product t (f x)) continuous net) t``] THEN
13109  MATCH_MP_TAC FINITE_INDUCT THEN BETA_TAC THEN SIMP_TAC std_ss [PRODUCT_CLAUSES] THEN
13110  SIMP_TAC std_ss [CONTINUOUS_CONST, FORALL_IN_INSERT] THEN
13111  REPEAT STRIP_TAC THEN
13112  ONCE_REWRITE_TAC [METIS [] ``(\x. f x e * product s (f x)) =
13113                  (\x. (\x. f x e) x * (\x. product s (f x)) x)``] THEN
13114  MATCH_MP_TAC CONTINUOUS_MUL THEN ASM_SIMP_TAC std_ss [o_DEF]);
13115
13116val CONTINUOUS_ON_PRODUCT = store_thm ("CONTINUOUS_ON_PRODUCT",
13117 ``!f:real->'a->real s t.
13118        FINITE t /\
13119        (!i. i IN t ==> (\x. (f x i)) continuous_on s)
13120        ==> (\x. (product t (f x))) continuous_on s``,
13121  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_PRODUCT]);
13122
13123(* ------------------------------------------------------------------------- *)
13124(* And so we have continuity of inverse.                                     *)
13125(* ------------------------------------------------------------------------- *)
13126
13127val LIM_INV = store_thm ("LIM_INV",
13128 ``!net:('a)net f l.
13129        (f --> l) net /\ ~(l = &0)
13130        ==> ((inv o f) --> (inv l)) net``,
13131  REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
13132  ASM_CASES_TAC ``trivial_limit(net:('a)net)`` THEN ASM_REWRITE_TAC[] THEN
13133  REWRITE_TAC[o_THM, dist] THEN STRIP_TAC THEN
13134  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
13135  FIRST_X_ASSUM(MP_TAC o SPEC ``min (abs(l) / &2) ((l pow 2 * e) / &2:real)``) THEN
13136  REWRITE_TAC[REAL_LT_MIN] THEN
13137  KNOW_TAC ``0 < abs l / 2 /\ 0 < l pow 2 * e / 2:real`` THENL
13138   [ASM_SIMP_TAC arith_ss [GSYM ABS_NZ, REAL_LT_DIV, REAL_LT] THEN
13139    MATCH_MP_TAC REAL_LT_DIV THEN SIMP_TAC arith_ss [REAL_LT] THEN
13140    ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN
13141    ASM_SIMP_TAC std_ss [REAL_LT_MUL, GSYM ABS_NZ, REAL_POW_LT],
13142    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
13143  DISCH_THEN (X_CHOOSE_TAC ``a:'a``) THEN EXISTS_TAC ``a:'a`` THEN
13144  POP_ASSUM MP_TAC THEN
13145  MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
13146  DISCH_TAC THEN X_GEN_TAC ``b:'a`` THEN POP_ASSUM (MP_TAC o Q.SPEC `b:'a`) THEN
13147  MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
13148  SIMP_TAC arith_ss [REAL_LT_RDIV_EQ, REAL_LT] THEN STRIP_TAC THEN
13149  FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_ARITH
13150   ``abs(x - l) * &2 < abs l ==> ~(x = &0:real)``)) THEN
13151  ASM_SIMP_TAC std_ss [REAL_SUB_INV2, ABS_DIV, REAL_LT_LDIV_EQ,
13152               GSYM ABS_NZ, REAL_ENTIRE] THEN
13153  FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
13154   ``abs(x - y) * &2 < b * c ==> c * b <= d * &2 ==> abs(y - x) < d:real``)) THEN
13155  ASM_SIMP_TAC std_ss [GSYM REAL_MUL_ASSOC, REAL_LE_LMUL] THEN
13156  ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
13157  ASM_SIMP_TAC std_ss [ABS_MUL, POW_2, REAL_MUL_ASSOC, GSYM ABS_NZ,
13158               REAL_LE_RMUL] THEN
13159  ASM_SIMP_TAC std_ss [REAL_ARITH ``abs(x - y) * &2 < abs y ==> abs y <= &2 * abs x:real``]);
13160
13161val CONTINUOUS_INV = store_thm ("CONTINUOUS_INV",
13162 ``!net f. f continuous net /\ ~(f(netlimit net) = &0)
13163           ==> (inv o f) continuous net``,
13164  SIMP_TAC std_ss [continuous, LIM_INV, o_THM]);
13165
13166val CONTINUOUS_AT_WITHIN_INV = store_thm ("CONTINUOUS_AT_WITHIN_INV",
13167 ``!f s a:real.
13168        f continuous (at a within s) /\ ~(f a = &0)
13169        ==> (inv o f) continuous (at a within s)``,
13170  REPEAT GEN_TAC THEN
13171  ASM_CASES_TAC ``trivial_limit (at (a:real) within s)`` THENL
13172   [ASM_REWRITE_TAC[continuous, LIM],
13173    ASM_SIMP_TAC std_ss [NETLIMIT_WITHIN, CONTINUOUS_INV]]);
13174
13175val CONTINUOUS_AT_INV = store_thm ("CONTINUOUS_AT_INV",
13176 ``!f a. f continuous at a /\ ~(f a = &0)
13177         ==> (inv o f) continuous at a``,
13178  ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
13179  REWRITE_TAC[CONTINUOUS_AT_WITHIN_INV]);
13180
13181val CONTINUOUS_ON_INV = store_thm ("CONTINUOUS_ON_INV",
13182 ``!f s. f continuous_on s /\ (!x. x IN s ==> ~(f x = &0))
13183         ==> (inv o f) continuous_on s``,
13184  SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN, CONTINUOUS_AT_WITHIN_INV]);
13185
13186(* ------------------------------------------------------------------------- *)
13187(* Hence some useful properties follow quite easily.                         *)
13188(* ------------------------------------------------------------------------- *)
13189
13190val CONNECTED_SCALING = store_thm ("CONNECTED_SCALING",
13191 ``!s:real->bool c. connected s ==> connected (IMAGE (\x. c * x) s)``,
13192  REPEAT STRIP_TAC THEN
13193  MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
13194  MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
13195  REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
13196  REWRITE_TAC[linear] THEN CONJ_TAC THEN SIMP_TAC std_ss [] THEN REAL_ARITH_TAC);
13197
13198val CONNECTED_NEGATIONS = store_thm ("CONNECTED_NEGATIONS",
13199 ``!s:real->bool. connected s ==> connected (IMAGE (\x. -x) s)``,
13200  REPEAT STRIP_TAC THEN
13201  MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
13202  MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
13203  REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
13204  REWRITE_TAC[linear] THEN CONJ_TAC THEN SIMP_TAC std_ss [] THEN REAL_ARITH_TAC);
13205
13206val COMPACT_SCALING = store_thm ("COMPACT_SCALING",
13207 ``!s:real->bool c. compact s ==> compact (IMAGE (\x. c * x) s)``,
13208  REPEAT STRIP_TAC THEN
13209  MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
13210  MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
13211  REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
13212  REWRITE_TAC[linear] THEN CONJ_TAC THEN SIMP_TAC std_ss [] THEN REAL_ARITH_TAC);
13213
13214val COMPACT_NEGATIONS = store_thm ("COMPACT_NEGATIONS",
13215 ``!s:real->bool. compact s ==> compact (IMAGE (\x. -x) s)``,
13216  REPEAT STRIP_TAC THEN
13217  MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
13218  MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
13219  REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
13220  REWRITE_TAC[linear] THEN CONJ_TAC THEN SIMP_TAC std_ss [] THEN REAL_ARITH_TAC);
13221
13222val COMPACT_AFFINITY = store_thm ("COMPACT_AFFINITY",
13223 ``!s a:real c.
13224        compact s ==> compact (IMAGE (\x. a + c * x) s)``,
13225  REPEAT STRIP_TAC THEN
13226  SUBGOAL_THEN ``(\x:real. a + c * x) = (\x. a + x) o (\x. c * x)``
13227  SUBST1_TAC THENL [REWRITE_TAC[o_DEF], ALL_TAC] THEN
13228  ASM_SIMP_TAC std_ss [IMAGE_COMPOSE, COMPACT_TRANSLATION, COMPACT_SCALING]);
13229
13230(* ------------------------------------------------------------------------- *)
13231(* We can state this in terms of diameter of a set.                          *)
13232(* ------------------------------------------------------------------------- *)
13233
13234val diameter = new_definition ("diameter",
13235  ``diameter s =
13236        if s = {} then (&0:real)
13237        else sup {abs(x - y) | x IN s /\ y IN s}``);
13238
13239val DIAMETER_BOUNDED = store_thm ("DIAMETER_BOUNDED",
13240 ``!s. bounded s
13241       ==> (!x:real y. x IN s /\ y IN s ==> abs(x - y) <= diameter s) /\
13242           (!d. &0 <= d /\ d < diameter s
13243                ==> ?x y. x IN s /\ y IN s /\ abs(x - y) > d)``,
13244  GEN_TAC THEN DISCH_TAC THEN
13245  ASM_CASES_TAC ``s:real->bool = {}`` THEN
13246  ASM_REWRITE_TAC[diameter, NOT_IN_EMPTY, REAL_LET_ANTISYM] THENL
13247  [SIMP_TAC std_ss [REAL_NOT_LE, REAL_NOT_LT, REAL_LTE_TOTAL], ALL_TAC] THEN
13248  MP_TAC(SPEC ``{abs(x - y:real) | x IN s /\ y IN s}`` SUP) THEN
13249  ABBREV_TAC ``b = sup {abs(x - y:real) | x IN s /\ y IN s}`` THEN
13250  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN
13251  REWRITE_TAC[NOT_IN_EMPTY, real_gt] THEN
13252  KNOW_TAC ``(?(x :real) (p_1 :real) (p_2 :real).
13253    (x = abs (p_1 - p_2)) /\ p_1 IN (s :real -> bool) /\ p_2 IN s) /\
13254 (?(b :real).
13255    !(x :real).
13256      (?(p_1 :real) (p_2 :real).
13257         (x = abs (p_1 - p_2)) /\ p_1 IN s /\ p_2 IN s) ==>
13258      x <= b)`` THENL
13259   [CONJ_TAC THENL [METIS_TAC[MEMBER_NOT_EMPTY], ALL_TAC],
13260    METIS_TAC[REAL_NOT_LE]] THEN
13261  SIMP_TAC std_ss [REAL_SUB, LEFT_IMP_EXISTS_THM] THEN
13262  UNDISCH_TAC ``bounded s`` THEN DISCH_TAC THEN
13263  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [bounded_def]) THEN
13264  REWRITE_TAC [real_sub] THEN
13265  METIS_TAC [REAL_ARITH ``x <= y + z /\ y <= b /\ z <= b ==> x <= b + b:real``,
13266            ABS_TRIANGLE, ABS_NEG]);
13267
13268val DIAMETER_BOUNDED_BOUND = store_thm ("DIAMETER_BOUNDED_BOUND",
13269 ``!s x y. bounded s /\ x IN s /\ y IN s ==> abs(x - y) <= diameter s``,
13270  MESON_TAC[DIAMETER_BOUNDED]);
13271
13272val DIAMETER_LINEAR_IMAGE = store_thm ("DIAMETER_LINEAR_IMAGE",
13273 ``!f:real->real s.
13274        linear f /\ (!x. abs(f x) = abs x)
13275        ==> (diameter(IMAGE f s) = diameter s)``,
13276  REWRITE_TAC[diameter] THEN
13277  REPEAT STRIP_TAC THEN REWRITE_TAC[diameter, IMAGE_EQ_EMPTY] THEN
13278  COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN
13279  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN
13280  ONCE_REWRITE_TAC [CONJ_SYM] THEN
13281  SIMP_TAC std_ss [GSYM CONJ_ASSOC, RIGHT_EXISTS_AND_THM, EXISTS_IN_IMAGE] THEN
13282  METIS_TAC[LINEAR_SUB]);
13283
13284val DIAMETER_EMPTY = store_thm ("DIAMETER_EMPTY",
13285 ``diameter {} = &0``,
13286  REWRITE_TAC[diameter]);
13287
13288val DIAMETER_SING = store_thm ("DIAMETER_SING",
13289 ``!a. diameter {a} = &0``,
13290  REWRITE_TAC[diameter, NOT_INSERT_EMPTY, IN_SING] THEN
13291  ONCE_REWRITE_TAC [METIS [] ``abs (x - y:real) = (\x y. abs (x - y:real)) x y``] THEN
13292  KNOW_TAC ``!a:real f x:real y:real. {f x y | (x = a) /\ (y = a)} = {(f a a):real }`` THENL
13293  [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD, IN_SING],
13294   DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
13295  SIMP_TAC std_ss [REAL_SUB_REFL, ABS_0] THEN
13296  MATCH_MP_TAC REAL_SUP_UNIQUE THEN
13297  REWRITE_TAC [METIS [SPECIFICATION] ``{0:real} x <=> x IN {0}``] THEN
13298  SET_TAC [REAL_LE_LT]);
13299
13300val DIAMETER_POS_LE = store_thm ("DIAMETER_POS_LE",
13301 ``!s:real->bool. bounded s ==> &0 <= diameter s``,
13302  REPEAT STRIP_TAC THEN REWRITE_TAC[diameter] THEN
13303  COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN
13304  MP_TAC(SPEC ``{abs(x - y:real) | x IN s /\ y IN s}`` SUP) THEN
13305  SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN
13306  KNOW_TAC ``{abs (x - y) | x IN (s :real -> bool) /\ y IN s} <>
13307      ({} :real -> bool) /\ (?(b :real).
13308    !(x :real) (y :real). x IN s /\ y IN s ==> abs (x - y) <= b)`` THENL
13309   [CONJ_TAC THENL [FULL_SIMP_TAC std_ss [EXTENSION, GSPECIFICATION,
13310     EXISTS_PROD, NOT_IN_EMPTY] THEN METIS_TAC [MEMBER_NOT_EMPTY], ALL_TAC] THEN
13311    UNDISCH_TAC ``bounded s`` THEN DISCH_TAC THEN
13312    FIRST_X_ASSUM(X_CHOOSE_TAC ``B:real`` o REWRITE_RULE [BOUNDED_POS]) THEN
13313    EXISTS_TAC ``&2 * B:real`` THEN
13314    ASM_SIMP_TAC std_ss [REAL_ARITH
13315      ``abs x <= B /\ abs y <= B ==> abs(x - y) <= &2 * B:real``],
13316    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
13317    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
13318    DISCH_THEN(X_CHOOSE_TAC ``a:real``) THEN
13319    DISCH_THEN(MP_TAC o SPECL [``a:real``, ``a:real``] o CONJUNCT1) THEN
13320    ASM_REWRITE_TAC[REAL_SUB_REFL, ABS_0]]);
13321
13322val DIAMETER_SUBSET = store_thm ("DIAMETER_SUBSET",
13323 ``!s t:real->bool. s SUBSET t /\ bounded t ==> diameter s <= diameter t``,
13324  REPEAT STRIP_TAC THEN
13325  ASM_CASES_TAC ``s:real->bool = {}`` THEN
13326  ASM_SIMP_TAC std_ss [DIAMETER_EMPTY, DIAMETER_POS_LE] THEN
13327  ASM_REWRITE_TAC[diameter] THEN
13328  COND_CASES_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
13329  MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN
13330  REPEAT(CONJ_TAC THENL
13331  [FULL_SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, SUBSET_DEF,
13332     EXISTS_PROD, NOT_IN_EMPTY] THEN METIS_TAC [MEMBER_NOT_EMPTY], ALL_TAC]) THEN
13333  SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN
13334  UNDISCH_TAC ``bounded t`` THEN DISCH_TAC THEN
13335  FIRST_X_ASSUM(X_CHOOSE_TAC ``B:real`` o REWRITE_RULE [BOUNDED_POS]) THEN
13336  EXISTS_TAC ``&2 * B:real`` THEN
13337  ASM_SIMP_TAC std_ss [REAL_ARITH
13338    ``abs x <= B /\ abs y <= B ==> abs(x - y) <= &2 * B:real``]);
13339
13340val DIAMETER_CLOSURE = store_thm ("DIAMETER_CLOSURE",
13341 ``!s:real->bool. bounded s ==> (diameter(closure s) = diameter s)``,
13342  REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN REPEAT STRIP_TAC THEN
13343  ASM_SIMP_TAC std_ss [DIAMETER_SUBSET, BOUNDED_CLOSURE, CLOSURE_SUBSET] THEN
13344  REWRITE_TAC[GSYM REAL_NOT_LT] THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN
13345  DISCH_TAC THEN MP_TAC(ISPEC ``closure s:real->bool`` DIAMETER_BOUNDED) THEN
13346  ABBREV_TAC ``d = diameter(closure s) - diameter(s:real->bool)`` THEN
13347  ASM_SIMP_TAC std_ss [BOUNDED_CLOSURE] THEN
13348  CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
13349  POP_ASSUM (MP_TAC o
13350    SPEC ``diameter(closure(s:real->bool)) - d / &2:real``) THEN
13351  SIMP_TAC std_ss [NOT_IMP, GSYM CONJ_ASSOC, NOT_EXISTS_THM] THEN
13352  ONCE_REWRITE_TAC [SET_RULE ``(x:real) NOTIN y <=> ~(x IN y)``, GSYM DE_MORGAN_THM] THEN
13353  ONCE_REWRITE_TAC [SET_RULE ``(x:real) NOTIN y <=> ~(x IN y)``, GSYM DE_MORGAN_THM] THEN
13354  FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIAMETER_POS_LE) THEN
13355  CONJ_TAC THENL
13356  [SIMP_TAC std_ss [REAL_SUB_LE, REAL_LE_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
13357   EXPAND_TAC "d" THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN
13358   SIMP_TAC std_ss [GSYM REAL_DOUBLE, real_sub] THEN
13359   MATCH_MP_TAC REAL_LE_ADD2 THEN SIMP_TAC std_ss [REAL_LE_REFL] THEN
13360   FULL_SIMP_TAC std_ss [REAL_ARITH ``(a - b = c) <=> (a = c + b:real)``] THEN
13361   ONCE_REWRITE_TAC [GSYM REAL_SUB_LE] THEN
13362   REWRITE_TAC [REAL_ARITH ``0 < a + b - -c <=> 0 + 0 < a + (b + c):real``, REAL_LE_LT] THEN
13363   DISJ1_TAC THEN MATCH_MP_TAC REAL_LTE_ADD2 THEN ASM_REWRITE_TAC [] THEN
13364   ONCE_REWRITE_TAC [REAL_ARITH ``0 = 0 + 0:real``] THEN
13365   MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC [], ALL_TAC] THEN
13366  CONJ_TAC THENL
13367  [ONCE_REWRITE_TAC [REAL_ARITH ``a - b < c <=> a - c < b:real``] THEN
13368   SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
13369   ASM_REWRITE_TAC [REAL_SUB_REFL, REAL_MUL_LZERO], ALL_TAC] THEN
13370  MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN
13371  SIMP_TAC std_ss [CLOSURE_APPROACHABLE, CONJ_ASSOC, GSYM FORALL_AND_THM] THEN
13372  CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
13373  UNDISCH_TAC ``!e. ~(0 < e) \/ ?y'. y' IN s /\ dist (y',y) < e:real`` THEN DISCH_TAC THEN
13374  POP_ASSUM (MP_TAC o Q.SPEC `d / 4:real`) THEN
13375  UNDISCH_TAC ``!e. ~(0 < e) \/ ?y. y IN s /\ dist (y,x) < e:real`` THEN DISCH_TAC THEN
13376  POP_ASSUM (MP_TAC o Q.SPEC `d / 4:real`) THEN REWRITE_TAC [AND_IMP_INTRO] THEN
13377  ASM_REWRITE_TAC[METIS [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 4:real``, REAL_MUL_LZERO]
13378                         ``&0 < d / &4 <=> &0 < d:real``] THEN
13379  DISCH_THEN(CONJUNCTS_THEN2
13380   (X_CHOOSE_THEN ``u:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC))
13381   (X_CHOOSE_THEN ``v:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC))) THEN
13382  FIRST_ASSUM(MP_TAC o MATCH_MP DIAMETER_BOUNDED) THEN
13383  DISCH_THEN(MP_TAC o SPECL [``u:real``, ``v:real``] o CONJUNCT1) THEN
13384  ASM_REWRITE_TAC[dist] THEN
13385  RULE_ASSUM_TAC (REWRITE_RULE [real_gt]) THEN
13386  RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH ``a - b < c <=> a - c < b:real``]) THEN
13387  RULE_ASSUM_TAC (SIMP_RULE std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``]) THEN
13388  UNDISCH_TAC `` (diameter (closure s) - abs (x - y)) * 2 < d:real`` THEN
13389  EXPAND_TAC "d" THEN SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 4:real``] THEN
13390  REAL_ARITH_TAC);
13391
13392val DIAMETER_SUBSET_CBALL_NONEMPTY = store_thm ("DIAMETER_SUBSET_CBALL_NONEMPTY",
13393 ``!s:real->bool.
13394       bounded s /\ ~(s = {}) ==> ?z. z IN s /\ s SUBSET cball(z,diameter s)``,
13395   REPEAT STRIP_TAC THEN
13396   FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
13397   DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN
13398   ASM_REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``b:real`` THEN
13399   DISCH_TAC THEN REWRITE_TAC[IN_CBALL, dist] THEN
13400   ASM_MESON_TAC[DIAMETER_BOUNDED]);
13401
13402val DIAMETER_SUBSET_CBALL = store_thm ("DIAMETER_SUBSET_CBALL",
13403 ``!s:real->bool. bounded s ==> ?z. s SUBSET cball(z,diameter s)``,
13404  REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN
13405  ASM_MESON_TAC[DIAMETER_SUBSET_CBALL_NONEMPTY, EMPTY_SUBSET]);
13406
13407val DIAMETER_EQ_0 = store_thm ("DIAMETER_EQ_0",
13408 ``!s:real->bool.
13409        bounded s ==> ((diameter s = &0) <=> (s = {}) \/ ?a. (s = {a}))``,
13410  REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THEN
13411  ASM_REWRITE_TAC[DIAMETER_EMPTY, DIAMETER_SING] THEN
13412  REWRITE_TAC[SET_RULE
13413   ``(s = {}) \/ (?a. s = {a}) <=> !a b. a IN s /\ b IN s ==> (a = b)``] THEN
13414  MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``] THEN STRIP_TAC THEN
13415  MP_TAC(ISPECL [``s:real->bool``, ``a:real``, ``b:real``]
13416        DIAMETER_BOUNDED_BOUND) THEN
13417  ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);
13418
13419val DIAMETER_LE = store_thm ("DIAMETER_LE",
13420 ``!s:real->bool d.
13421        (~(s = {}) \/ &0 <= d) /\
13422        (!x y. x IN s /\ y IN s ==> abs(x - y) <= d) ==> diameter s <= d``,
13423  NTAC 2 GEN_TAC THEN REWRITE_TAC[diameter] THEN
13424  COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [] THEN
13425  STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_LE' THEN
13426  CONJ_TAC THENL [
13427   SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC[],
13428   SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC []]);
13429
13430val DIAMETER_CBALL = store_thm ("DIAMETER_CBALL",
13431 ``!a:real r. diameter(cball(a,r)) = if r < &0 then &0 else &2 * r``,
13432  REPEAT GEN_TAC THEN COND_CASES_TAC THENL
13433   [ASM_MESON_TAC[CBALL_EQ_EMPTY, DIAMETER_EMPTY], ALL_TAC] THEN
13434  RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LT]) THEN
13435  REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
13436   [MATCH_MP_TAC DIAMETER_LE THEN
13437    ASM_SIMP_TAC std_ss [CBALL_EQ_EMPTY, REAL_LE_MUL, REAL_POS, REAL_NOT_LT] THEN
13438    REWRITE_TAC[IN_CBALL, dist] THEN REAL_ARITH_TAC,
13439    MATCH_MP_TAC REAL_LE_TRANS THEN
13440    EXISTS_TAC ``abs((a + r) - (a - r):real)`` THEN
13441    CONJ_TAC THENL
13442     [REWRITE_TAC[REAL_ARITH ``(a + r) - (a - r) = (&2 * r:real)``] THEN
13443      ASM_REAL_ARITH_TAC,
13444      MATCH_MP_TAC DIAMETER_BOUNDED_BOUND THEN
13445      REWRITE_TAC[BOUNDED_CBALL, IN_CBALL, dist] THEN
13446      REWRITE_TAC[REAL_ARITH
13447       ``(abs(a - (a + b)) = abs b) /\ (abs(a - (a - b)) = abs b:real)``] THEN
13448      ASM_REAL_ARITH_TAC]]);
13449
13450val DIAMETER_BALL = store_thm ("DIAMETER_BALL",
13451 ``!a:real r. diameter(ball(a,r)) = if r < &0 then &0 else &2 * r``,
13452  REPEAT GEN_TAC THEN COND_CASES_TAC THENL
13453   [ASM_SIMP_TAC std_ss [BALL_EMPTY, REAL_LT_IMP_LE, DIAMETER_EMPTY], ALL_TAC] THEN
13454  ASM_CASES_TAC ``r = &0:real`` THEN
13455  ASM_SIMP_TAC std_ss [BALL_EMPTY, REAL_LE_REFL, DIAMETER_EMPTY, REAL_MUL_RZERO] THEN
13456  MATCH_MP_TAC EQ_TRANS THEN
13457  EXISTS_TAC ``diameter(cball(a:real,r))`` THEN CONJ_TAC THENL
13458   [SUBGOAL_THEN ``&0 < r:real`` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC, ALL_TAC] THEN
13459    ASM_SIMP_TAC std_ss [GSYM CLOSURE_BALL, DIAMETER_CLOSURE, BOUNDED_BALL],
13460    ASM_SIMP_TAC std_ss [DIAMETER_CBALL]]);
13461
13462val DIAMETER_SUMS = store_thm ("DIAMETER_SUMS",
13463 ``!s t:real->bool.
13464        bounded s /\ bounded t
13465        ==> diameter {x + y | x IN s /\ y IN t} <= diameter s + diameter t``,
13466  REPEAT STRIP_TAC THEN
13467  KNOW_TAC ``!x y:real. {x + y| F} = {}:real->bool`` THENL
13468  [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN SET_TAC [], DISCH_TAC] THEN
13469  ASM_CASES_TAC ``s:real->bool = {}`` THEN
13470  ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, DIAMETER_EMPTY, REAL_ADD_LID, DIAMETER_POS_LE] THEN
13471  ASM_CASES_TAC ``t:real->bool = {}`` THEN
13472  ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, DIAMETER_EMPTY, REAL_ADD_RID, DIAMETER_POS_LE] THEN
13473  MATCH_MP_TAC DIAMETER_LE THEN CONJ_TAC THENL
13474  [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD, NOT_IN_EMPTY] THEN
13475   ASM_SET_TAC [], ALL_TAC] THEN
13476  SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM, CONJ_EQ_IMP, FORALL_IN_GSPEC] THEN
13477  REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH
13478   ``abs(x - x') <= s /\ abs(y - y') <= t
13479    ==> abs((x + y) - (x' + y'):real) <= s + t``) THEN
13480  ASM_SIMP_TAC std_ss [DIAMETER_BOUNDED_BOUND]);
13481
13482val LEBESGUE_COVERING_LEMMA = store_thm ("LEBESGUE_COVERING_LEMMA",
13483 ``!s:real->bool c.
13484        compact s /\ ~(c = {}) /\ s SUBSET BIGUNION c /\ (!b. b IN c ==> open b)
13485        ==> ?d. &0 < d /\
13486                !t. t SUBSET s /\ diameter t <= d
13487                    ==> ?b. b IN c /\ t SUBSET b``,
13488  REPEAT STRIP_TAC THEN
13489  FIRST_ASSUM(MP_TAC o MATCH_MP HEINE_BOREL_LEMMA) THEN
13490  DISCH_THEN(MP_TAC o SPEC ``c:(real->bool)->bool``) THEN ASM_SIMP_TAC std_ss [] THEN
13491  ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC ``e:real`` THEN
13492  STRIP_TAC THEN EXISTS_TAC ``e / &2:real`` THEN ASM_REWRITE_TAC[REAL_HALF] THEN
13493  X_GEN_TAC ``t:real->bool`` THEN STRIP_TAC THEN
13494  ASM_CASES_TAC ``t:real->bool = {}`` THENL [ASM_SET_TAC[], ALL_TAC] THEN
13495  MP_TAC(ISPEC ``t:real->bool`` DIAMETER_SUBSET_CBALL_NONEMPTY) THEN
13496  KNOW_TAC ``(bounded (t :real -> bool) :bool) /\ t <> ({} :real -> bool)`` THENL
13497   [ASM_MESON_TAC[BOUNDED_SUBSET, COMPACT_IMP_BOUNDED],
13498    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
13499  DISCH_THEN(X_CHOOSE_THEN ``x:real`` STRIP_ASSUME_TAC) THEN
13500  FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN
13501  KNOW_TAC ``(x :real) IN (s :real -> bool)`` THENL
13502  [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
13503  DISCH_THEN (X_CHOOSE_TAC ``b:real->bool``) THEN EXISTS_TAC ``b:real->bool`` THEN
13504  STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN
13505  EXISTS_TAC ``cball(x:real,diameter(t:real->bool))`` THEN
13506  ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN
13507  EXISTS_TAC ``ball(x:real,e)`` THEN ASM_REWRITE_TAC[] THEN
13508  REWRITE_TAC[SUBSET_DEF, IN_CBALL, IN_BALL] THEN
13509  MAP_EVERY UNDISCH_TAC [``&0 < e:real``, ``diameter(t:real->bool) <= e / &2:real``] THEN
13510  SIMP_TAC std_ss [dist, REAL_LE_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN REAL_ARITH_TAC);
13511
13512(* ------------------------------------------------------------------------- *)
13513(* Related results with closure as the conclusion.                           *)
13514(* ------------------------------------------------------------------------- *)
13515
13516val CLOSED_SCALING = store_thm ("CLOSED_SCALING",
13517 ``!s:real->bool c. closed s ==> closed (IMAGE (\x. c * x) s)``,
13518  REPEAT GEN_TAC THEN
13519  ASM_CASES_TAC ``s :real->bool = {}`` THEN
13520  ASM_REWRITE_TAC[CLOSED_EMPTY, IMAGE_EMPTY, IMAGE_INSERT] THEN
13521  ASM_CASES_TAC ``c = &0:real`` THENL
13522   [SUBGOAL_THEN ``IMAGE (\x:real. c * x) s = {(0)}``
13523     (fn th => REWRITE_TAC[th, CLOSED_SING]) THEN
13524    ASM_REWRITE_TAC[EXTENSION, IN_IMAGE, IN_SING, REAL_MUL_LZERO] THEN
13525    ASM_MESON_TAC[MEMBER_NOT_EMPTY],
13526    ALL_TAC] THEN
13527  SIMP_TAC std_ss [CLOSED_SEQUENTIAL_LIMITS, IN_IMAGE, SKOLEM_THM] THEN
13528  STRIP_TAC THEN X_GEN_TAC ``x:num->real`` THEN X_GEN_TAC ``l:real`` THEN
13529  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
13530  DISCH_THEN(X_CHOOSE_THEN ``y:num->real`` MP_TAC) THEN
13531  SIMP_TAC std_ss [FORALL_AND_THM] THEN STRIP_TAC THEN
13532  EXISTS_TAC ``inv(c) * l :real`` THEN
13533  ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_RINV, REAL_MUL_LID] THEN
13534  FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC ``\n:num. inv(c) * x n:real`` THEN
13535  ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THENL
13536   [ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_LID],
13537    ONCE_REWRITE_TAC [METIS [] ``(\n:num. inv c * (c * (y:num->real) n)) =
13538                                 (\n. inv c:real * (\n. (c * y n)) n)``] THEN
13539    MATCH_MP_TAC LIM_CMUL THEN
13540    FIRST_ASSUM(fn th => REWRITE_TAC[SYM(SPEC_ALL th)]) THEN
13541    ASM_SIMP_TAC std_ss [ETA_AX]]);
13542
13543val CLOSED_NEGATIONS = store_thm ("CLOSED_NEGATIONS",
13544 ``!s:real->bool. closed s ==> closed (IMAGE (\x. -x) s)``,
13545  REPEAT GEN_TAC THEN
13546  SUBGOAL_THEN ``IMAGE (\x. -x) s = IMAGE (\x:real. -(&1) * x) s``
13547  SUBST1_TAC THEN SIMP_TAC std_ss [CLOSED_SCALING] THEN
13548  REWRITE_TAC[REAL_ARITH ``-(&1) * x = -x:real``] THEN SIMP_TAC std_ss [ETA_AX]);
13549
13550val COMPACT_CLOSED_SUMS = store_thm ("COMPACT_CLOSED_SUMS",
13551 ``!s:real->bool t.
13552        compact s /\ closed t ==> closed {x + y | x IN s /\ y IN t}``,
13553  REPEAT GEN_TAC THEN
13554  SIMP_TAC std_ss [compact, GSPECIFICATION, CLOSED_SEQUENTIAL_LIMITS, EXISTS_PROD] THEN
13555  STRIP_TAC THEN X_GEN_TAC ``f:num->real`` THEN X_GEN_TAC ``l:real`` THEN
13556  SIMP_TAC std_ss [SKOLEM_THM, FORALL_AND_THM] THEN
13557  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
13558  DISCH_THEN(X_CHOOSE_THEN ``a:num->real`` MP_TAC) THEN
13559  DISCH_THEN(X_CHOOSE_THEN ``b:num->real`` STRIP_ASSUME_TAC) THEN
13560  UNDISCH_TAC `` !f:num->real.
13561        (!n. f n IN s) ==>
13562        ?l r.
13563          l IN s /\ (!m n. m < n ==> r m < r n) /\
13564          (f o r --> l) sequentially`` THEN DISCH_TAC THEN
13565  FIRST_X_ASSUM(MP_TAC o SPEC ``a:num->real``) THEN
13566  ASM_REWRITE_TAC[] THEN
13567  DISCH_THEN(X_CHOOSE_THEN ``la:real`` (X_CHOOSE_THEN ``sub:num->num``
13568        STRIP_ASSUME_TAC)) THEN
13569  MAP_EVERY EXISTS_TAC [``la:real``, ``l - la:real``] THEN
13570  ASM_REWRITE_TAC[REAL_ARITH ``a + (b - a) = b:real``] THEN
13571  FIRST_X_ASSUM MATCH_MP_TAC THEN
13572  EXISTS_TAC ``\n. (f o (sub:num->num)) n - (a o sub) n:real`` THEN
13573  CONJ_TAC THENL [ASM_SIMP_TAC std_ss [REAL_ADD_SUB, o_THM], ALL_TAC] THEN
13574  MATCH_MP_TAC LIM_SUB THEN ASM_SIMP_TAC std_ss [LIM_SUBSEQUENCE, ETA_AX]);
13575
13576val CLOSED_COMPACT_SUMS = store_thm ("CLOSED_COMPACT_SUMS",
13577 ``!s:real->bool t.
13578        closed s /\ compact t ==> closed {x + y | x IN s /\ y IN t}``,
13579  REPEAT GEN_TAC THEN
13580  SUBGOAL_THEN ``{x + y:real | x IN s /\ y IN t} = {y + x | y IN t /\ x IN s}``
13581  SUBST1_TAC THEN  SIMP_TAC std_ss [COMPACT_CLOSED_SUMS] THEN
13582  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN METIS_TAC [REAL_ADD_SYM]);
13583
13584val CLOSURE_SUMS = store_thm ("CLOSURE_SUMS",
13585 ``!s t:real->bool.
13586        bounded s \/ bounded t
13587        ==> (closure {x + y | x IN s /\ y IN t} =
13588             {x + y | x IN closure s /\ y IN closure t})``,
13589  REWRITE_TAC[TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN
13590  SIMP_TAC std_ss [FORALL_AND_THM] THEN
13591  GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SUMS_SYM] THEN
13592  MATCH_MP_TAC(TAUT `(p ==> q) /\ p ==> p /\ q`) THEN
13593  SIMP_TAC std_ss [] THEN
13594  REPEAT STRIP_TAC THEN SIMP_TAC std_ss [EXTENSION, CLOSURE_SEQUENTIAL] THEN
13595  X_GEN_TAC ``z:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD] THEN EQ_TAC THENL
13596   [GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [CONJ_SYM] THEN
13597    SIMP_TAC std_ss [GSPECIFICATION, IN_DELETE, SKOLEM_THM, GSYM LEFT_EXISTS_AND_THM] THEN
13598    SIMP_TAC std_ss [FORALL_AND_THM] THEN
13599    ONCE_REWRITE_TAC[TAUT `(p /\ q) /\ r <=> q /\ p /\ r`] THEN
13600    KNOW_TAC ``(?(x' :num -> real) (f :num -> real) (f' :num -> real).
13601   (\x' f f'. ((!(n :num). f n IN (s :real -> bool)) /\
13602    !(n :num). f' n IN (t :real -> bool)) /\
13603   (!(n :num). x' n = f n + f' n) /\
13604   ((x' --> (z :real)) sequentially :bool)) x' f f') ==>
13605?(p_1 :real) (p_2 :real) (x' :num -> real).
13606  (\p_1 p_2 x'. (?(x :num -> real).
13607     (!(n :num). x n IN t) /\ ((x --> p_2) sequentially :bool)) /\
13608  ((!(n :num). x' n IN s) /\ ((x' --> p_1) sequentially :bool)) /\
13609  (z = p_1 + p_2)) p_1 p_2 x'`` THENL
13610    [ALL_TAC, METIS_TAC []] THEN
13611    ONCE_REWRITE_TAC[MESON[] ``(?f x y. P f x y) <=> (?x y f. P f x y)``] THEN
13612    SIMP_TAC std_ss [GSYM FUN_EQ_THM] THEN
13613    SIMP_TAC std_ss [ETA_AX, UNWIND_THM2] THEN
13614    SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN
13615    MAP_EVERY X_GEN_TAC [``a:num->real``, ``b:num->real``] THEN
13616    STRIP_TAC THEN
13617    MP_TAC(ISPEC ``closure s:real->bool`` compact) THEN
13618    ASM_SIMP_TAC std_ss [COMPACT_CLOSURE] THEN
13619    DISCH_THEN(MP_TAC o SPEC ``a:num->real``) THEN
13620    ASM_SIMP_TAC std_ss [SIMP_RULE std_ss [SUBSET_DEF] CLOSURE_SUBSET, LEFT_IMP_EXISTS_THM] THEN
13621    MAP_EVERY X_GEN_TAC [``u:real``, ``r:num->num``] THEN STRIP_TAC THEN
13622    EXISTS_TAC ``z - u:real`` THEN
13623    EXISTS_TAC ``(a:num->real) o (r:num->num)`` THEN EXISTS_TAC ``u:real`` THEN
13624    ASM_SIMP_TAC std_ss [o_THM] THEN
13625    CONJ_TAC THENL [ALL_TAC, REAL_ARITH_TAC] THEN
13626    EXISTS_TAC ``(\n. ((\n. a n + b n) o (r:num->num)) n - (a o r) n)
13627                :num->real`` THEN
13628    CONJ_TAC THENL
13629     [ASM_SIMP_TAC real_ss [o_DEF, REAL_ARITH ``(a + b) - a:real = b``],
13630      MATCH_MP_TAC LIM_SUB THEN ASM_SIMP_TAC std_ss [ETA_AX] THEN
13631      MATCH_MP_TAC LIM_SUBSEQUENCE THEN ASM_REWRITE_TAC[]],
13632    SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM] THEN
13633    SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, GSYM LEFT_EXISTS_AND_THM,
13634                GSYM RIGHT_EXISTS_AND_THM] THEN
13635    MAP_EVERY X_GEN_TAC
13636     [``x:real``, ``y:real``, ``a:num->real``, ``b:num->real``] THEN
13637    STRIP_TAC THEN EXISTS_TAC ``(\n. a n + b n):num->real`` THEN
13638    ASM_SIMP_TAC std_ss [LIM_ADD] THEN ASM_MESON_TAC[]]);
13639
13640val COMPACT_CLOSED_DIFFERENCES = store_thm ("COMPACT_CLOSED_DIFFERENCES",
13641 ``!s:real->bool t.
13642        compact s /\ closed t ==> closed {x - y | x IN s /\ y IN t}``,
13643  REPEAT STRIP_TAC THEN
13644  SUBGOAL_THEN ``{x - y | x:real IN s /\ y IN t} =
13645                 {x + y | x IN s /\ y IN (IMAGE (\x. -x) t)}``
13646    (fn th => ASM_SIMP_TAC std_ss [th, COMPACT_CLOSED_SUMS, CLOSED_NEGATIONS]) THEN
13647  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD, IN_IMAGE] THEN
13648  ONCE_REWRITE_TAC[REAL_ARITH ``(x:real = -y) <=> (y = -x:real)``] THEN
13649  SIMP_TAC std_ss [real_sub, GSYM CONJ_ASSOC, UNWIND_THM2] THEN
13650  METIS_TAC[REAL_NEG_NEG]);
13651
13652val CLOSED_COMPACT_DIFFERENCES = store_thm ("CLOSED_COMPACT_DIFFERENCES",
13653 ``!s:real->bool t.
13654        closed s /\ compact t ==> closed {x - y | x IN s /\ y IN t}``,
13655  REPEAT STRIP_TAC THEN
13656  SUBGOAL_THEN ``{x - y | x:real IN s /\ y IN t} =
13657                 {x + y | x IN s /\ y IN (IMAGE (\x. -x) t)}``
13658    (fn th => ASM_SIMP_TAC std_ss [th, CLOSED_COMPACT_SUMS, COMPACT_NEGATIONS]) THEN
13659  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD, IN_IMAGE] THEN
13660  ONCE_REWRITE_TAC[REAL_ARITH ``(x:real = -y) <=> (y = -x)``] THEN
13661  SIMP_TAC std_ss [real_sub, GSYM CONJ_ASSOC, UNWIND_THM2] THEN
13662  METIS_TAC[REAL_NEG_NEG]);
13663
13664val TRANSLATION_DIFF = store_thm ("TRANSLATION_DIFF",
13665 ``!s t:real->bool.
13666        IMAGE (\x. a + x) (s DIFF t) =
13667        (IMAGE (\x. a + x) s) DIFF (IMAGE (\x. a + x) t)``,
13668  SIMP_TAC std_ss [EXTENSION, IN_DIFF, IN_IMAGE] THEN
13669  ONCE_REWRITE_TAC[REAL_ARITH ``(x:real = a + y) <=> (y = x - a)``] THEN
13670  SIMP_TAC std_ss [UNWIND_THM2]);
13671
13672(* ------------------------------------------------------------------------- *)
13673(* Separation between points and sets.                                       *)
13674(* ------------------------------------------------------------------------- *)
13675
13676val SEPARATE_POINT_CLOSED = store_thm ("SEPARATE_POINT_CLOSED",
13677 ``!s a:real.
13678        closed s /\ ~(a IN s)
13679        ==> ?d. &0 < d /\ !x. x IN s ==> d <= dist(a,x)``,
13680  REPEAT STRIP_TAC THEN
13681  ASM_CASES_TAC ``s:real->bool = {}`` THENL
13682   [EXISTS_TAC ``&1:real`` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY, REAL_LT_01],
13683    ALL_TAC] THEN
13684  MP_TAC(ISPECL [``s:real->bool``, ``a:real``] DISTANCE_ATTAINS_INF) THEN
13685  ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC ``b:real`` THEN
13686  STRIP_TAC THEN EXISTS_TAC ``dist(a:real,b)`` THEN
13687  METIS_TAC[DIST_POS_LT]);
13688
13689val SEPARATE_COMPACT_CLOSED = store_thm ("SEPARATE_COMPACT_CLOSED",
13690 ``!s t:real->bool.
13691        compact s /\ closed t /\ (s INTER t = {})
13692        ==> ?d. &0 < d /\ !x y. x IN s /\ y IN t ==> d <= dist(x,y)``,
13693  REPEAT STRIP_TAC THEN
13694  MP_TAC(ISPECL [``{x - y:real | x IN s /\ y IN t}``, ``0:real``]
13695                SEPARATE_POINT_CLOSED) THEN
13696  ASM_SIMP_TAC std_ss [COMPACT_CLOSED_DIFFERENCES, GSPECIFICATION, EXISTS_PROD] THEN
13697  REWRITE_TAC[REAL_ARITH ``(0 = x - y) <=> (x = y:real)``] THEN
13698  KNOW_TAC ``(!(p_1 :real) (p_2 :real).
13699    p_1 <> p_2 \/ p_1 NOTIN (s :real -> bool) \/
13700    p_2 NOTIN (t :real -> bool))`` THENL
13701  [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
13702  DISCH_THEN (X_CHOOSE_TAC ``d:real``) THEN EXISTS_TAC ``d:real`` THEN
13703  POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN
13704  REWRITE_TAC [dist] THEN
13705  METIS_TAC[REAL_ARITH ``abs(0 - (x - y)) = abs(x - y:real)``]);
13706
13707val SEPARATE_CLOSED_COMPACT = store_thm ("SEPARATE_CLOSED_COMPACT",
13708 ``!s t:real->bool.
13709        closed s /\ compact t /\ (s INTER t = {})
13710        ==> ?d. &0 < d /\ !x y. x IN s /\ y IN t ==> d <= dist(x,y)``,
13711  ONCE_REWRITE_TAC[DIST_SYM, INTER_COMM] THEN
13712  MESON_TAC[SEPARATE_COMPACT_CLOSED]);
13713
13714(* ------------------------------------------------------------------------- *)
13715(* Representing sets as the union of a chain of compact sets.                *)
13716(* ------------------------------------------------------------------------- *)
13717
13718val CLOSED_UNION_COMPACT_SUBSETS = store_thm ("CLOSED_UNION_COMPACT_SUBSETS",
13719 ``!s. closed s
13720       ==> ?f:num->real->bool.
13721                (!n. compact(f n)) /\
13722                (!n. (f n) SUBSET s) /\
13723                (!n. (f n) SUBSET f(n + 1)) /\
13724                (BIGUNION {f n | n IN univ(:num)} = s) /\
13725                (!k. compact k /\ k SUBSET s
13726                     ==> ?N. !n. n >= N ==> k SUBSET (f n))``,
13727  REPEAT STRIP_TAC THEN
13728  EXISTS_TAC ``\n. s INTER cball(0:real,&n)`` THEN
13729  ASM_SIMP_TAC std_ss [INTER_SUBSET, COMPACT_CBALL, CLOSED_INTER_COMPACT] THEN
13730  REPEAT CONJ_TAC THENL
13731   [GEN_TAC THEN MATCH_MP_TAC(SET_RULE
13732     ``t SUBSET u ==> s INTER t SUBSET s INTER u``) THEN
13733    REWRITE_TAC[SUBSET_BALLS, DIST_REFL, GSYM REAL_OF_NUM_ADD] THEN
13734    REAL_ARITH_TAC,
13735    SIMP_TAC std_ss [EXTENSION, BIGUNION_GSPEC, GSPECIFICATION, IN_UNIV, IN_INTER] THEN
13736    X_GEN_TAC ``x:real`` THEN REWRITE_TAC[IN_CBALL_0] THEN
13737    MESON_TAC[SIMP_REAL_ARCH],
13738    X_GEN_TAC ``k:real->bool`` THEN SIMP_TAC std_ss [SUBSET_INTER] THEN
13739    REPEAT STRIP_TAC THEN
13740    FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN DISCH_THEN
13741     (MP_TAC o SPEC ``0:real`` o MATCH_MP BOUNDED_SUBSET_CBALL) THEN
13742    DISCH_THEN(X_CHOOSE_THEN ``r:real`` STRIP_ASSUME_TAC) THEN
13743    MP_TAC(ISPEC ``r:real`` SIMP_REAL_ARCH) THEN
13744    DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN
13745    POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM REAL_OF_NUM_GE] THEN
13746    REPEAT STRIP_TAC THEN
13747    FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP]
13748        SUBSET_TRANS)) THEN
13749    REWRITE_TAC[SUBSET_BALLS, DIST_REFL] THEN ASM_REAL_ARITH_TAC]);
13750
13751val OPEN_UNION_COMPACT_SUBSETS = store_thm ("OPEN_UNION_COMPACT_SUBSETS",
13752 ``!s. open s
13753       ==> ?f:num->real->bool.
13754                (!n. compact(f n)) /\
13755                (!n. (f n) SUBSET s) /\
13756                (!n. (f n) SUBSET interior(f(n + 1))) /\
13757                (BIGUNION {f n | n IN univ(:num)} = s) /\
13758                (!k. compact k /\ k SUBSET s
13759                     ==> ?N. !n. n >= N ==> k SUBSET (f n))``,
13760  GEN_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THENL
13761   [DISCH_TAC THEN EXISTS_TAC ``(\n. {}):num->real->bool`` THEN
13762    ASM_SIMP_TAC std_ss [EMPTY_SUBSET, SUBSET_EMPTY, COMPACT_EMPTY] THEN
13763    SIMP_TAC std_ss [EXTENSION, BIGUNION_GSPEC, GSPECIFICATION, NOT_IN_EMPTY],
13764    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
13765    DISCH_THEN(X_CHOOSE_TAC ``a:real``) THEN STRIP_TAC] THEN
13766  KNOW_TAC ``?(f :num -> real -> bool).
13767           (\f. !(n :num). compact (f n)) f /\
13768           (\f. !(n :num). f n SUBSET (s :real -> bool)) f /\
13769           (\f. !(n :num). f n SUBSET interior (f (n + (1 :num)))) f /\
13770           (\f. BIGUNION {f n | n IN univ((:num) :num itself)} = s) f /\
13771  (\f. !(k :real -> bool).
13772    compact k /\ k SUBSET s ==>
13773    ?(N :num). !(n :num). n >= N ==> k SUBSET f n) f`` THENL
13774  [ALL_TAC, METIS_TAC []] THEN
13775  MATCH_MP_TAC(METIS[]
13776  ``(!f. p1 f /\ p3 f /\ p4 f ==> p5 f) /\
13777    (?f. p1 f /\ p2 f /\ p3 f /\ (p2 f ==> p4 f))
13778    ==> ?f. p1 f /\ p2 f /\ p3 f /\ p4 f /\ p5 f``) THEN
13779  CONJ_TAC THENL
13780   [BETA_TAC THEN X_GEN_TAC ``f:num->real->bool`` THEN STRIP_TAC THEN
13781    FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
13782    X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN
13783    UNDISCH_TAC ``compact k`` THEN DISCH_TAC THEN
13784    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [COMPACT_EQ_HEINE_BOREL]) THEN
13785    DISCH_THEN(MP_TAC o SPEC ``{interior(f n):real->bool | n IN univ(:num)}``) THEN
13786    SIMP_TAC std_ss [FORALL_IN_GSPEC, OPEN_INTERIOR] THEN
13787    KNOW_TAC ``(k :real -> bool) SUBSET
13788        BIGUNION {interior ((f :num -> real -> bool) n) |
13789                               n IN univ((:num) :num itself)}`` THENL
13790     [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP]
13791        SUBSET_TRANS)) THEN
13792      SIMP_TAC std_ss [SUBSET_DEF, BIGUNION_GSPEC, GSPECIFICATION] THEN ASM_SET_TAC[],
13793      DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
13794      ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
13795      ONCE_REWRITE_TAC [METIS [] ``interior (f n) = (\n. interior (f n)) (n:num)``] THEN
13796      SIMP_TAC std_ss [GSYM IMAGE_DEF, EXISTS_FINITE_SUBSET_IMAGE] THEN
13797      REWRITE_TAC[SUBSET_UNIV] THEN
13798      DISCH_THEN(X_CHOOSE_THEN ``i:num->bool`` STRIP_ASSUME_TAC) THEN
13799      FIRST_ASSUM(MP_TAC o SPEC ``\n:num. n`` o
13800        MATCH_MP UPPER_BOUND_FINITE_SET) THEN
13801      DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN
13802      POP_ASSUM MP_TAC THEN
13803      REWRITE_TAC[GE] THEN DISCH_TAC THEN X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN
13804      FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP]
13805        SUBSET_TRANS)) THEN
13806      SIMP_TAC std_ss [BIGUNION_SUBSET, FORALL_IN_IMAGE] THEN
13807      X_GEN_TAC ``m:num`` THEN DISCH_TAC THEN MATCH_MP_TAC SUBSET_TRANS THEN
13808      EXISTS_TAC ``(f:num->real->bool) m`` THEN
13809      REWRITE_TAC[INTERIOR_SUBSET] THEN
13810      SUBGOAL_THEN ``!m n. m <= n ==> (f:num->real->bool) m SUBSET f n``
13811       (fn th => METIS_TAC[th, LESS_EQ_TRANS]) THEN
13812      ONCE_REWRITE_TAC [METIS [] ``f m SUBSET f n <=> (\m n. f m SUBSET f n) m n``] THEN
13813      MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
13814      METIS_TAC[SUBSET_DEF, ADD1, INTERIOR_SUBSET]],
13815    BETA_TAC THEN EXISTS_TAC ``\n. cball(a,&n) DIFF
13816         {x + e | x IN univ(:real) DIFF s /\ e IN ball(0,inv(&n + &1))}`` THEN
13817    SIMP_TAC std_ss [] THEN REPEAT CONJ_TAC THENL
13818     [X_GEN_TAC ``n:num`` THEN MATCH_MP_TAC COMPACT_DIFF THEN
13819      SIMP_TAC std_ss [COMPACT_CBALL, OPEN_SUMS, OPEN_BALL],
13820      GEN_TAC THEN MATCH_MP_TAC(SET_RULE
13821       ``(UNIV DIFF s) SUBSET t ==> c DIFF t SUBSET s``) THEN
13822      SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN
13823      X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
13824      MAP_EVERY EXISTS_TAC [``x:real``, ``0:real``] THEN
13825      ASM_SIMP_TAC std_ss [REAL_ADD_RID, CENTRE_IN_BALL, REAL_LT_INV_EQ] THEN
13826      SIMP_TAC std_ss [REAL_LT, REAL_OF_NUM_ADD] THEN ARITH_TAC,
13827      GEN_TAC THEN REWRITE_TAC[INTERIOR_DIFF] THEN MATCH_MP_TAC(SET_RULE
13828       ``s SUBSET s' /\ t' SUBSET t ==> (s DIFF t) SUBSET (s' DIFF t')``) THEN
13829      CONJ_TAC THENL
13830       [REWRITE_TAC[INTERIOR_CBALL, SUBSET_DEF, IN_BALL, IN_CBALL] THEN
13831        SIMP_TAC std_ss [GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC,
13832        MATCH_MP_TAC SUBSET_TRANS THEN
13833        EXISTS_TAC ``{x + e | x IN univ(:real) DIFF s /\
13834                             e IN cball(0,inv(&n + &2))}`` THEN
13835        CONJ_TAC THENL
13836         [MATCH_MP_TAC CLOSURE_MINIMAL THEN
13837          ASM_SIMP_TAC std_ss [CLOSED_COMPACT_SUMS, COMPACT_CBALL,
13838                       GSYM OPEN_CLOSED] THEN
13839          KNOW_TAC ``ball (0,inv (&n + 1)) SUBSET ball (0,inv (&n + 1))`` THENL
13840          [SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN
13841           SIMP_TAC std_ss [ball, cball, dist, GSYM REAL_OF_NUM_ADD,
13842                            REAL_ARITH ``n + 1 + 1:real = n + 2``,
13843                            GSPECIFICATION] THEN
13844           METIS_TAC [REAL_LE_LT], ALL_TAC] THEN
13845          SIMP_TAC std_ss [SUBSET_DEF, IN_BALL, IN_CBALL, GSYM REAL_OF_NUM_ADD] THEN
13846          SIMP_TAC std_ss [GSPECIFICATION, EXISTS_PROD, dist,
13847                           REAL_ARITH ``n + 1 + 1:real = n + 2``] THEN
13848          METIS_TAC [REAL_LE_LT],
13849          KNOW_TAC ``cball (0,inv (&n + &2)) SUBSET ball (0,inv (&n + &1))`` THENL
13850          [ALL_TAC,
13851           SIMP_TAC std_ss [cball, ball, dist, SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN
13852           METIS_TAC [REAL_LE_LT]] THEN
13853          REWRITE_TAC[SUBSET_DEF, IN_BALL, IN_CBALL, GSYM REAL_OF_NUM_ADD] THEN
13854          GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH
13855           ``a < b ==> x <= a ==> x < b:real``) THEN
13856          MATCH_MP_TAC REAL_LT_INV2 THEN
13857          SIMP_TAC arith_ss [REAL_LT, REAL_OF_NUM_ADD]]],
13858      DISCH_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
13859      ASM_SIMP_TAC std_ss [BIGUNION_SUBSET, FORALL_IN_GSPEC] THEN
13860      SIMP_TAC std_ss [SUBSET_DEF, BIGUNION_GSPEC, IN_UNIV, GSPECIFICATION] THEN
13861      X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN REWRITE_TAC[IN_DIFF] THEN
13862      SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV, IN_BALL_0, EXISTS_PROD] THEN
13863      REWRITE_TAC[REAL_ARITH ``(x:real = y + e) <=> (e = x - y)``] THEN
13864      SIMP_TAC std_ss [TAUT `(p /\ q) /\ r <=> r /\ p /\ q`, UNWIND_THM2] THEN
13865      ONCE_REWRITE_TAC [METIS [DE_MORGAN_THM]
13866           ``(!p_1:real. p_1 IN s \/ ~(abs (x - p_1) < inv (&n + 1))) <=>
13867             ~(?p_1:real. (~(\p_1. (p_1 IN s)) p_1 /\
13868                            (\p_1. abs (x - p_1) < inv (&n + 1)) p_1))``] THEN
13869      REWRITE_TAC[METIS [] ``~(?x. ~P x /\ Q x) <=> !x. Q x ==> P x``] THEN
13870      UNDISCH_TAC ``open s`` THEN DISCH_TAC THEN BETA_TAC THEN
13871      FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_CONTAINS_BALL]) THEN
13872      DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN
13873      ASM_REWRITE_TAC[SUBSET_DEF, IN_BALL, dist] THEN
13874      DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
13875      UNDISCH_TAC ``0 < e:real`` THEN DISCH_TAC THEN
13876      FIRST_ASSUM(MP_TAC o ONCE_REWRITE_RULE [REAL_ARCH_INV]) THEN
13877      DISCH_THEN(X_CHOOSE_THEN ``N1:num`` STRIP_ASSUME_TAC) THEN
13878      MP_TAC(ISPEC ``abs(x - a:real)`` SIMP_REAL_ARCH) THEN
13879      DISCH_THEN(X_CHOOSE_TAC ``N2:num``) THEN EXISTS_TAC ``N1 + N2:num`` THEN
13880      CONJ_TAC THENL
13881       [REWRITE_TAC[IN_CBALL] THEN ONCE_REWRITE_TAC[DIST_SYM, dist] THEN
13882        UNDISCH_TAC ``abs(x - a:real) <= &N2`` THEN
13883        REWRITE_TAC[dist, GSYM REAL_OF_NUM_ADD] THEN
13884        FULL_SIMP_TAC std_ss [REAL_LT_INV_EQ] THEN
13885        DISCH_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
13886        EXISTS_TAC ``&N2:real`` THEN ASM_REWRITE_TAC [] THEN
13887        SIMP_TAC arith_ss [REAL_OF_NUM_LE, REAL_OF_NUM_ADD],
13888        REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
13889        SUBGOAL_THEN ``inv(&(N1 + N2) + &1) <= inv(&N1:real)`` MP_TAC THENL
13890         [MATCH_MP_TAC REAL_LE_INV2 THEN
13891          ASM_SIMP_TAC arith_ss [REAL_LT, LE_1] THEN
13892          REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN
13893          SIMP_TAC arith_ss [REAL_OF_NUM_LE, REAL_OF_NUM_ADD],
13894          METIS_TAC [REAL_LTE_TRANS, REAL_LET_TRANS, REAL_LE_TRANS, REAL_LT_TRANS]]]]]);
13895
13896(* ------------------------------------------------------------------------- *)
13897(* A cute way of denoting open and closed intervals using overloading.       *)
13898(* ------------------------------------------------------------------------- *)
13899
13900Definition OPEN_interval :
13901    OPEN_interval ((a:real),(b:real)) = {x:real | a < x /\ x < b}
13902End
13903
13904Definition CLOSED_interval :
13905    CLOSED_interval (l :(real # real) list) =
13906      {x:real | FST (HD l) <= x /\ x <= SND (HD l)}
13907End
13908
13909val _ = overload_on ("interval", ``OPEN_interval``);
13910val _ = overload_on ("interval", ``CLOSED_interval``);
13911
13912val interval = store_thm ("interval",
13913 ``(interval (a,b) = {x:real | a < x /\ x < b}) /\
13914   (interval [a,b] = {x:real | a <= x /\ x <= b})``,
13915  REWRITE_TAC [OPEN_interval, CLOSED_interval, HD]);
13916
13917val IN_INTERVAL = store_thm ("IN_INTERVAL",
13918 ``(x IN interval (a,b) <=> a < x /\ x < b) /\
13919   (x IN interval [a,b] <=> a <= x /\ x <= b)``,
13920  SIMP_TAC std_ss [interval, GSPECIFICATION]);
13921
13922val IN_INTERVAL_REFLECT = store_thm ("IN_INTERVAL_REFLECT",
13923 ``(!a b x. (-x) IN interval[-b,-a] <=> x IN interval[a,b]) /\
13924   (!a b x. (-x) IN interval(-b,-a) <=> x IN interval(a,b))``,
13925  SIMP_TAC std_ss [IN_INTERVAL, REAL_LT_NEG, REAL_LE_NEG] THEN
13926  METIS_TAC[]);
13927
13928val REFLECT_INTERVAL = store_thm ("REFLECT_INTERVAL",
13929 ``(!a b:real. IMAGE (\x. -x) (interval[a,b]) = interval[-b,-a]) /\
13930   (!a b:real. IMAGE (\x. -x) (interval(a,b)) = interval(-b,-a))``,
13931  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_INTERVAL,
13932   IN_IMAGE] THEN REPEAT STRIP_TAC THEN EQ_TAC THEN
13933  METIS_TAC [REAL_LE_NEG, REAL_LT_NEG, REAL_NEG_NEG]);
13934
13935val INTERVAL_EQ_EMPTY = store_thm ("INTERVAL_EQ_EMPTY",
13936 ``!a b. (b < a <=> (interval [a,b] = {})) /\
13937         (b <= a <=> (interval (a,b) = {}))``,
13938  REPEAT GEN_TAC THEN CONJ_TAC THENL
13939  [EQ_TAC THENL [RW_TAC std_ss [EXTENSION, IN_INTERVAL] THEN EQ_TAC THENL
13940  [SIMP_TAC std_ss [NOT_IN_EMPTY] THEN CCONTR_TAC THEN
13941   FULL_SIMP_TAC std_ss [REAL_NEG_NEG] THEN UNDISCH_TAC (Term `b < a:real`) THEN
13942   FULL_SIMP_TAC std_ss [REAL_NOT_LT] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
13943   EXISTS_TAC ``x:real`` THEN ASM_REWRITE_TAC [], SIMP_TAC std_ss [NOT_IN_EMPTY]],
13944   RW_TAC std_ss [EXTENSION, IN_INTERVAL] THEN
13945   CCONTR_TAC THEN UNDISCH_TAC (Term `!x:real. a <= x /\ x <= b <=> x IN {}`) THEN
13946   FULL_SIMP_TAC std_ss [NOT_IN_EMPTY, REAL_NOT_LT] THEN EXISTS_TAC ``a:real``
13947   THEN FULL_SIMP_TAC std_ss [REAL_LE_LT]],
13948   EQ_TAC THENL [RW_TAC std_ss [EXTENSION, IN_INTERVAL] THEN EQ_TAC THENL
13949    [SIMP_TAC std_ss [NOT_IN_EMPTY] THEN CCONTR_TAC THEN
13950     FULL_SIMP_TAC std_ss [REAL_NEG_NEG] THEN UNDISCH_TAC (Term `b <= a:real`) THEN
13951     FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN MATCH_MP_TAC REAL_LT_TRANS THEN
13952     EXISTS_TAC ``x:real`` THEN ASM_REWRITE_TAC [], SIMP_TAC std_ss [NOT_IN_EMPTY]],
13953     RW_TAC std_ss [EXTENSION, IN_INTERVAL] THEN
13954     CCONTR_TAC THEN UNDISCH_TAC (Term `!x:real. a < x /\ x < b <=> x IN {}`) THEN
13955     FULL_SIMP_TAC std_ss [NOT_IN_EMPTY, REAL_NOT_LE, REAL_MEAN]]]);
13956
13957val INTERVAL_NE_EMPTY = store_thm ("INTERVAL_NE_EMPTY",
13958 ``(~(interval [a:real,b] = {}) <=> a <= b) /\
13959   (~(interval (a:real,b) = {}) <=> a < b)``,
13960  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, NOT_IN_EMPTY, IN_INTERVAL] THEN
13961  CONJ_TAC THEN EQ_TAC THENL [SIMP_TAC std_ss [REAL_LE_TRANS],
13962  DISCH_TAC THEN EXISTS_TAC ``a:real`` THEN ASM_SIMP_TAC std_ss [REAL_LE_LT],
13963  SIMP_TAC std_ss [REAL_LT_TRANS], FULL_SIMP_TAC std_ss [REAL_MEAN]]);
13964
13965val SUBSET_INTERVAL_IMP = store_thm ("SUBSET_INTERVAL_IMP",
13966 ``((a <= c /\ d <= b) ==> interval[c,d] SUBSET interval[a:real,b]) /\
13967   ((a < c  /\ d < b)  ==> interval[c,d] SUBSET interval(a:real,b)) /\
13968   ((a <= c /\ d <= b) ==> interval(c,d) SUBSET interval[a:real,b]) /\
13969   ((a <= c /\ d <= b) ==> interval(c,d) SUBSET interval(a:real,b))``,
13970  REWRITE_TAC[SUBSET_DEF, IN_INTERVAL] THEN REPEAT CONJ_TAC THEN
13971  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM MP_TAC THEN REPEAT STRIP_TAC THEN
13972  METIS_TAC [REAL_LE_TRANS, REAL_LET_TRANS, REAL_LTE_TRANS, REAL_LT_IMP_LE]);
13973
13974val INTERVAL_SING = store_thm ("INTERVAL_SING",
13975 ``(interval[a,a] = {a}) /\ (interval(a,a) = {})``,
13976  REWRITE_TAC[EXTENSION, IN_SING, NOT_IN_EMPTY, IN_INTERVAL] THEN
13977  REWRITE_TAC[REAL_LE_ANTISYM, REAL_LT_ANTISYM] THEN
13978  MESON_TAC[EQ_SYM_EQ]);
13979
13980val SUBSET_INTERVAL = store_thm ("SUBSET_INTERVAL",
13981 ``(interval[c,d] SUBSET interval[a:real,b] <=>
13982        (c <= d) ==> (a <= c /\ d <= b)) /\
13983   (interval[c,d] SUBSET interval(a:real,b) <=>
13984        (c <= d) ==> (a < c /\ d < b)) /\
13985   (interval(c,d) SUBSET interval[a:real,b] <=>
13986        (c < d) ==> (a <= c /\ d <= b)) /\
13987   (interval(c,d) SUBSET interval(a:real,b) <=>
13988        (c < d) ==> (a <= c /\ d <= b))``,
13989  REPEAT STRIP_TAC THEN
13990  (MATCH_MP_TAC(TAUT
13991    `(~q ==> p) /\ (q ==> (p <=> r)) ==> (p <=> q ==> r)`) THEN
13992   CONJ_TAC THENL
13993    [DISCH_TAC THEN MATCH_MP_TAC(SET_RULE ``(s = {}) ==> s SUBSET t``) THEN
13994     ASM_MESON_TAC[INTERVAL_EQ_EMPTY, REAL_NOT_LE], ALL_TAC] THEN
13995   DISCH_TAC THEN EQ_TAC THEN REWRITE_TAC[SUBSET_INTERVAL_IMP] THEN
13996   REWRITE_TAC[SUBSET_DEF, IN_INTERVAL]) THENL
13997   [KNOW_TAC ``((?y. c <= y /\ y <= d)
13998           ==> (!y. c <= y /\ y <= d
13999                ==> a <= y /\ y <= b))
14000          ==> (a <= c:real /\ d <= b:real)`` THENL
14001    [ALL_TAC, METIS_TAC []] THEN
14002    KNOW_TAC ``(?y:real. c <= y /\ y <= d)`` THENL
14003    [ASM_MESON_TAC[REAL_MEAN, REAL_LE_BETWEEN], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
14004    STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_TRANS, REAL_LE_REFL],
14005    KNOW_TAC ``((?y. c <= y /\ y <= d)
14006           ==> (!y. c <= y /\ y <= d
14007                 ==> a < y /\ y < b))
14008           ==> (a < c:real /\ d < b:real)`` THENL
14009    [ALL_TAC, METIS_TAC []] THEN
14010    KNOW_TAC ``(?y:real. c <= y /\ y <= d)`` THENL
14011    [ASM_MESON_TAC[REAL_MEAN, REAL_LE_BETWEEN], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
14012    STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_TRANS, REAL_LE_REFL],
14013    KNOW_TAC ``((?y. c < y /\ y < d)
14014           ==> (!y. c < y /\ y < d
14015               ==> a <= y /\ y <= b))
14016         ==> (a <= c:real /\ d <= b:real)`` THENL
14017    [ALL_TAC, METIS_TAC []] THEN
14018    KNOW_TAC ``(?y:real. c < y /\ y < d)`` THENL
14019    [ASM_MESON_TAC[REAL_MEAN, REAL_LE_BETWEEN], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
14020    REPEAT STRIP_TAC THENL
14021    [CCONTR_TAC THEN UNDISCH_TAC ``!y:real. c < y /\ y < d ==> a <= y /\ y <= b`` THEN
14022    FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN
14023    EXISTS_TAC ``((c:real) + min ((a:real)) ((d:real))) / &2:real`` THEN
14024    METIS_TAC [min_def, max_def, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``, REAL_LT_LDIV_EQ,
14025               GSYM REAL_DOUBLE, REAL_LT_LADD, REAL_ADD_SYM, REAL_MUL_SYM, REAL_LT_ADD2,
14026               REAL_LTE_ADD2, REAL_NOT_LE],
14027    CCONTR_TAC THEN UNDISCH_TAC ``!y:real. c < y /\ y < d ==> a <= y /\ y <= b`` THEN
14028    FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN
14029    EXISTS_TAC ``(max ((b:real)) ((c:real)) + (d:real)) / &2:real`` THEN
14030    METIS_TAC [min_def, max_def, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``, REAL_LT_LDIV_EQ,
14031               GSYM REAL_DOUBLE, REAL_LT_LADD, REAL_ADD_SYM, REAL_MUL_SYM, REAL_LT_ADD2,
14032               REAL_LTE_ADD2, REAL_NOT_LE]],
14033    KNOW_TAC ``((?y. c < y /\ y < d)
14034           ==> (!y. c < y /\ y < d
14035                ==> a < y /\ y < b))
14036         ==> (a <= c:real /\ d <= b:real)`` THENL
14037    [ALL_TAC, METIS_TAC []] THEN
14038    KNOW_TAC ``(?y:real. c < y /\ y < d)`` THENL
14039    [ASM_MESON_TAC[REAL_MEAN, REAL_LE_BETWEEN], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
14040    REPEAT STRIP_TAC THENL
14041    [CCONTR_TAC THEN UNDISCH_TAC ``!y:real. c < y /\ y < d ==> a < y /\ y < b`` THEN
14042    FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN
14043    EXISTS_TAC ``((c:real) + min ((a:real)) ((d:real))) / &2:real`` THEN
14044    METIS_TAC [min_def, max_def, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``, REAL_LT_LDIV_EQ,
14045               GSYM REAL_DOUBLE, REAL_LT_LADD, REAL_ADD_SYM, REAL_MUL_SYM, REAL_LT_ADD2,
14046               REAL_LTE_ADD2, REAL_NOT_LE, REAL_NOT_LT, REAL_LT_RDIV_EQ, REAL_LT_LDIV_EQ,
14047               REAL_LE_LADD, REAL_LE_ADD2, REAL_LE_RADD, REAL_LE_LT],
14048    CCONTR_TAC THEN UNDISCH_TAC ``!y:real. c < y /\ y < d ==> a < y /\ y < b`` THEN
14049    FULL_SIMP_TAC std_ss [REAL_NOT_LE] THEN
14050    EXISTS_TAC ``(max ((b:real)) ((c:real)) + (d:real)) / &2:real`` THEN
14051    METIS_TAC [min_def, max_def, REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``, REAL_LT_LDIV_EQ,
14052               GSYM REAL_DOUBLE, REAL_LT_LADD, REAL_ADD_SYM, REAL_MUL_SYM, REAL_LT_ADD2,
14053               REAL_LTE_ADD2, REAL_NOT_LE, REAL_NOT_LT, REAL_LT_RDIV_EQ, REAL_LT_LDIV_EQ,
14054               REAL_LE_LADD, REAL_LE_ADD2, REAL_LE_RADD, REAL_LE_LT]]]);
14055
14056val DISJOINT_INTERVAL = store_thm ("DISJOINT_INTERVAL",
14057  ``!a b c d:real.
14058        ((interval[a,b] INTER interval[c,d] = {}) <=>
14059          b < a \/ d < c \/
14060          b < c \/ d < a) /\
14061        ((interval[a,b] INTER interval(c,d) = {}) <=>
14062          b < a \/ d <= c \/
14063          b <= c \/ d <= a) /\
14064        ((interval(a,b) INTER interval[c,d] = {}) <=>
14065          b <= a \/ d < c \/
14066          b <= c \/ d <= a) /\
14067        ((interval(a,b) INTER interval(c,d) = {}) <=>
14068          b <= a \/ d <= c \/
14069          b <= c \/ d <= a)``,
14070  REWRITE_TAC [EXTENSION, IN_INTER, IN_INTERVAL, NOT_IN_EMPTY] THEN
14071  SIMP_TAC std_ss [GSYM FORALL_AND_THM, NOT_FORALL_THM] THEN
14072  REWRITE_TAC [TAUT `~((p ==> q) /\ (p ==> r)) <=> p /\ (~q \/ ~r)`] THEN
14073  REWRITE_TAC [DE_MORGAN_THM] THEN
14074  REPEAT STRIP_TAC THEN (* 4 subgoals *)
14075  (EQ_TAC THENL
14076    [DISCH_THEN (MP_TAC o SPEC ``(@f. f = (max ((a:real)) ((c:real)) +
14077                                           min ((b:real)) ((d:real))) / &2):real``) THEN
14078     DISCH_TAC THEN
14079     FULL_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_LE_LDIV_EQ,
14080                           REAL_LT_RDIV_EQ, REAL_LT_LDIV_EQ,
14081                           REAL_ARITH ``0 < 2:real``] THEN (* 4 subgoals *)
14082     FULL_SIMP_TAC bool_ss [REAL_NOT_LE, min_def, max_def] THEN
14083     POP_ASSUM MP_TAC THEN
14084     REPEAT COND_CASES_TAC THEN ASM_REAL_ARITH_TAC,
14085
14086     DISCH_THEN (fn th => GEN_TAC THEN MP_TAC th) THEN
14087     SIMP_TAC std_ss [] THEN REAL_ARITH_TAC ]));
14088
14089val ENDS_IN_INTERVAL = store_thm ("ENDS_IN_INTERVAL",
14090 ``(!a b. a IN interval[a,b] <=> ~(interval[a,b] = {})) /\
14091   (!a b. b IN interval[a,b] <=> ~(interval[a,b] = {})) /\
14092   (!a b. ~(a IN interval(a,b))) /\
14093   (!a b. ~(b IN interval(a,b)))``,
14094  REWRITE_TAC[IN_INTERVAL, INTERVAL_NE_EMPTY] THEN
14095  REWRITE_TAC[REAL_LE_REFL, REAL_LT_REFL] THEN
14096  MESON_TAC[REAL_LE_REFL]);
14097
14098val ENDS_IN_UNIT_INTERVAL = store_thm ("ENDS_IN_UNIT_INTERVAL",
14099 ``0 IN interval[0,1] /\ 1 IN interval[0,1] /\
14100   ~(0 IN interval(0,1)) /\ ~(1 IN interval(0,1))``,
14101  REWRITE_TAC[ENDS_IN_INTERVAL, INTERVAL_NE_EMPTY] THEN
14102  REWRITE_TAC[REAL_POS]);
14103
14104val INTER_INTERVAL = store_thm ("INTER_INTERVAL",
14105 ``interval[a,b] INTER interval[c,d] =
14106        interval[(max (a) (c)),(min (b) (d))]``,
14107  REWRITE_TAC[EXTENSION, IN_INTER, IN_INTERVAL] THEN
14108  SIMP_TAC std_ss [REAL_MAX_LE, REAL_LE_MIN] THEN MESON_TAC[]);
14109
14110val INTERVAL_OPEN_SUBSET_CLOSED = store_thm ("INTERVAL_OPEN_SUBSET_CLOSED",
14111 ``!a b. interval(a,b) SUBSET interval[a,b]``,
14112  REWRITE_TAC[SUBSET_DEF, IN_INTERVAL] THEN MESON_TAC[REAL_LT_IMP_LE]);
14113
14114val OPEN_INTERVAL_LEMMA = store_thm ("OPEN_INTERVAL_LEMMA",
14115 ``!a b x. a < x /\ x < b
14116           ==> ?d. (0:real) < d /\ !x'. abs(x' - x) < d ==> a < x' /\ x' < b``,
14117  REPEAT STRIP_TAC THEN
14118  EXISTS_TAC ``min (x - a) (b - x:real)`` THEN REWRITE_TAC[REAL_LT_MIN] THEN
14119  REPEAT (POP_ASSUM MP_TAC) THEN REAL_ARITH_TAC);
14120
14121val OPEN_INTERVAL = store_thm ("OPEN_INTERVAL",
14122 ``!a:real b. open(interval (a,b))``,
14123  REPEAT GEN_TAC THEN
14124  SIMP_TAC std_ss [open_def, interval, GSPECIFICATION, dist, OPEN_INTERVAL_LEMMA]);
14125
14126val CLOSED_INTERVAL = store_thm ("CLOSED_INTERVAL",
14127 ``!a:real b. closed(interval [a,b])``,
14128  REWRITE_TAC[CLOSED_LIMPT, LIMPT_APPROACHABLE, IN_INTERVAL] THEN
14129  REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THENL
14130   [FIRST_X_ASSUM(MP_TAC o SPEC ``(a:real) - (x:real)``),
14131    FIRST_X_ASSUM(MP_TAC o SPEC ``(x:real) - (b:real)``)] THEN
14132  ASM_REWRITE_TAC[REAL_SUB_LT] THEN
14133  DISCH_THEN(X_CHOOSE_THEN ``z:real`` MP_TAC) THEN
14134  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
14135  REWRITE_TAC[dist, REAL_NOT_LT] THEN
14136  MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``abs((z - x :real))`` THEN
14137  ASM_SIMP_TAC std_ss [REAL_ARITH ``x < a /\ a <= z ==> a - x:real <= abs(z - x)``,
14138                       REAL_ARITH ``z <= b /\ b < x ==> x - b:real <= abs(z - x)``,
14139                       REAL_LE_REFL]);
14140
14141val INTERIOR_CLOSED_INTERVAL = store_thm ("INTERIOR_CLOSED_INTERVAL",
14142 ``!a:real b. interior(interval [a,b]) = interval (a,b)``,
14143  REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
14144   [ALL_TAC,
14145    MATCH_MP_TAC INTERIOR_MAXIMAL THEN
14146    REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED, OPEN_INTERVAL]] THEN
14147  SIMP_TAC std_ss [interior, SUBSET_DEF, IN_INTERVAL, GSPECIFICATION] THEN
14148  X_GEN_TAC ``x:real`` THEN
14149  DISCH_THEN(X_CHOOSE_THEN ``s:real->bool`` STRIP_ASSUME_TAC) THEN
14150  ASM_SIMP_TAC std_ss [REAL_LT_LE] THEN REPEAT STRIP_TAC THEN
14151  UNDISCH_TAC ``open s`` THEN REWRITE_TAC [open_def] THEN
14152  DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
14153  DISCH_THEN(X_CHOOSE_THEN ``e:real`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THENL
14154  [DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x - (e / 2:real)`),
14155   DISCH_TAC THEN POP_ASSUM (MP_TAC o Q.SPEC `x + (e / 2:real)`)] THEN
14156   ASM_SIMP_TAC std_ss [dist, REAL_ADD_SUB, REAL_ARITH ``x - y - x = -y:real``,
14157                                   REAL_ARITH ``x + y - x =  y:real``] THEN
14158   ASM_SIMP_TAC std_ss [ABS_MUL, ABS_NEG, REAL_MUL_RID] THENL [CONJ_TAC THENL
14159   [METIS_TAC [ABS_REFL, REAL_LT_HALF1, REAL_LT_HALF2, REAL_LE_LT], ALL_TAC],
14160    CONJ_TAC THENL [METIS_TAC [ABS_REFL, REAL_LT_HALF1, REAL_LT_HALF2, REAL_LE_LT],
14161   ALL_TAC]] THEN CCONTR_TAC THEN
14162   UNDISCH_TAC ``!x. x IN s ==> a <= x /\ x <= b:real`` THEN DISCH_TAC THENL
14163   [POP_ASSUM (MP_TAC o Q.SPEC `x - e / 2:real`),
14164    POP_ASSUM (MP_TAC o Q.SPEC `x + e / 2:real`)] THEN FULL_SIMP_TAC std_ss [] THENL
14165   [DISJ1_TAC THEN REWRITE_TAC[REAL_ARITH ``a <= a - b <=> ~(&0 < b:real)``],
14166    DISJ2_TAC THEN REWRITE_TAC[REAL_ARITH ``a + b <= a <=> ~(&0 < b:real)``]] THEN
14167   FULL_SIMP_TAC std_ss [REAL_LT_HALF1]);
14168
14169val INTERIOR_INTERVAL = store_thm ("INTERIOR_INTERVAL",
14170 ``(!a b. interior(interval[a,b]) = interval(a,b)) /\
14171   (!a b. interior(interval(a,b)) = interval(a,b))``,
14172  SIMP_TAC std_ss [INTERIOR_CLOSED_INTERVAL, INTERIOR_OPEN, OPEN_INTERVAL]);
14173
14174val BOUNDED_CLOSED_INTERVAL = store_thm ("BOUNDED_CLOSED_INTERVAL",
14175 ``!a b:real. bounded (interval [a,b])``,
14176  REPEAT STRIP_TAC THEN REWRITE_TAC[bounded_def, interval] THEN
14177  SIMP_TAC std_ss [GSPECIFICATION] THEN
14178  EXISTS_TAC ``abs(a) + abs(b:real)`` THEN REAL_ARITH_TAC);
14179
14180val BOUNDED_INTERVAL = store_thm ("BOUNDED_INTERVAL",
14181 ``(!a b. bounded (interval [a,b])) /\ (!a b. bounded (interval (a,b)))``,
14182  MESON_TAC[BOUNDED_CLOSED_INTERVAL, BOUNDED_SUBSET,
14183            INTERVAL_OPEN_SUBSET_CLOSED]);
14184
14185val NOT_INTERVAL_UNIV = store_thm ("NOT_INTERVAL_UNIV",
14186 ``(!a b. ~(interval[a,b] = UNIV)) /\
14187   (!a b. ~(interval(a,b) = UNIV))``,
14188  MESON_TAC[BOUNDED_INTERVAL, NOT_BOUNDED_UNIV]);
14189
14190val COMPACT_INTERVAL = store_thm ("COMPACT_INTERVAL",
14191 ``!a b. compact (interval [a,b])``,
14192  SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_INTERVAL, CLOSED_INTERVAL]);
14193
14194val OPEN_INTERVAL_MIDPOINT = store_thm ("OPEN_INTERVAL_MIDPOINT",
14195 ``!a b:real.
14196        ~(interval(a,b) = {}) ==> (inv(&2) * (a + b)) IN interval(a,b)``,
14197  REWRITE_TAC[INTERVAL_NE_EMPTY, IN_INTERVAL] THEN
14198  ONCE_REWRITE_TAC [REAL_MUL_COMM] THEN ONCE_REWRITE_TAC [GSYM real_div] THEN
14199  KNOW_TAC ``0 < 2:real`` THENL [REAL_ARITH_TAC, ALL_TAC] THEN
14200  REPEAT STRIP_TAC THEN ASM_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_LT_LDIV_EQ] THEN
14201  REWRITE_TAC [REAL_MUL_COMM, GSYM REAL_DOUBLE] THEN
14202  FULL_SIMP_TAC std_ss [REAL_LT_LADD, REAL_LT_RADD]);
14203
14204val OPEN_CLOSED_INTERVAL_CONVEX = store_thm ("OPEN_CLOSED_INTERVAL_CONVEX",
14205 ``!a b x y:real e.
14206        x IN interval(a,b) /\ y IN interval[a,b] /\ &0 < e /\ e <= &1
14207        ==> (e * x + (&1 - e) * y) IN interval(a,b)``,
14208  REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
14209   `(c /\ d ==> a /\ b ==> e) ==> a /\ b /\ c /\ d ==> e`) THEN
14210  STRIP_TAC THEN REWRITE_TAC[IN_INTERVAL] THEN STRIP_TAC THEN
14211  SUBST1_TAC(REAL_ARITH ``(a:real) = e * a + (&1 - e) * a``) THEN
14212  SUBST1_TAC(REAL_ARITH ``(b:real) = e * b + (&1 - e) * b``) THEN
14213  KNOW_TAC ``0:real <= 1 - e`` THENL
14214 [FULL_SIMP_TAC std_ss [REAL_SUB_LE], ALL_TAC] THEN
14215  REWRITE_TAC [REAL_LE_LT] THEN STRIP_TAC THENL
14216  [CONJ_TAC THEN MATCH_MP_TAC REAL_LTE_ADD2 THEN
14217  ASM_SIMP_TAC std_ss [REAL_LT_LMUL, REAL_LE_LMUL, REAL_SUB_LE],
14218  POP_ASSUM MP_TAC THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN
14219  DISCH_TAC THEN CONJ_TAC THEN MATCH_MP_TAC REAL_LTE_ADD2 THEN
14220  ASM_SIMP_TAC std_ss [REAL_LT_LMUL, REAL_LE_LMUL, REAL_SUB_LE, REAL_MUL_LZERO, REAL_LE_REFL]]);
14221
14222val REAL_LE_INV2 = store_thm ("REAL_LE_INV2",
14223 ``!x:real y. &0 < x /\ x <= y ==> inv(y) <= inv(x)``,
14224  REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_LT] THEN
14225  ASM_CASES_TAC ``x:real = y`` THEN ASM_REWRITE_TAC[] THEN
14226  STRIP_TAC THEN DISJ1_TAC THEN MATCH_MP_TAC REAL_LT_INV THEN
14227  ASM_REWRITE_TAC[]);
14228
14229val REAL_INV_LE_1 = store_thm ("REAL_INV_LE_1",
14230 ``!x:real. &1 <= x ==> inv(x) <= &1``,
14231  REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_INV1] THEN
14232  MATCH_MP_TAC REAL_LE_INV2 THEN ASM_REWRITE_TAC[REAL_LT_01]);
14233
14234val CLOSURE_OPEN_INTERVAL = store_thm ("CLOSURE_OPEN_INTERVAL",
14235 ``!a b:real.
14236     ~(interval(a,b) = {}) ==> (closure(interval(a,b)) = interval[a,b])``,
14237  REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
14238   [MATCH_MP_TAC CLOSURE_MINIMAL THEN
14239    REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED, CLOSED_INTERVAL],
14240    ALL_TAC] THEN
14241  REWRITE_TAC[SUBSET_DEF, closure, IN_UNION] THEN X_GEN_TAC ``x:real`` THEN
14242  DISCH_TAC THEN MATCH_MP_TAC(TAUT `(~b ==> c) ==> b \/ c`) THEN DISCH_TAC THEN
14243  SIMP_TAC std_ss [GSPECIFICATION, LIMPT_SEQUENTIAL] THEN
14244  ABBREV_TAC ``(c:real) = inv(&2:real) * (a + b)`` THEN
14245  EXISTS_TAC ``\n. (x:real) + inv(&n + &1:real) * (c - x)`` THEN CONJ_TAC THENL
14246   [X_GEN_TAC ``n:num`` THEN REWRITE_TAC[IN_DELETE] THEN BETA_TAC THEN
14247    REWRITE_TAC[REAL_ARITH ``(x + a = x) <=> (a = 0:real)``] THEN
14248    REWRITE_TAC[REAL_ENTIRE, REAL_INV_EQ_0] THEN
14249    SIMP_TAC std_ss [REAL_SUB_0, REAL_OF_NUM_SUC, SUC_NOT, REAL_OF_NUM_EQ, EQ_SYM_EQ] THEN
14250    CONJ_TAC THENL [ALL_TAC, ASM_MESON_TAC[OPEN_INTERVAL_MIDPOINT]] THEN
14251    REWRITE_TAC[REAL_ARITH ``x + a * (y - x) = a * y + (&1 - a) * x:real``] THEN
14252    MATCH_MP_TAC OPEN_CLOSED_INTERVAL_CONVEX THEN
14253    CONJ_TAC THENL [ASM_MESON_TAC[OPEN_INTERVAL_MIDPOINT], ALL_TAC] THEN
14254    KNOW_TAC ``&0:real < &n + &1`` THENL [SIMP_TAC std_ss [REAL_OF_NUM_SUC] THEN
14255    ASM_REWRITE_TAC[REAL_LT_INV_EQ, REAL_OF_NUM_SUC, REAL_LT, LESS_0], ALL_TAC] THEN
14256    DISCH_TAC THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ, REAL_OF_NUM_SUC, REAL_LT, LESS_0] THEN
14257    MATCH_MP_TAC REAL_INV_LE_1 THEN REWRITE_TAC [REAL_LE, ONE, LESS_EQ_MONO,
14258    ZERO_LESS_EQ], ALL_TAC] THEN
14259  GEN_REWR_TAC LAND_CONV [REAL_ARITH ``x:real = x + &0 * (c - x)``] THEN
14260  KNOW_TAC ``!n:num x:real. (\n. x + inv (&n + 1) * (c - x)) =
14261                     (\n. (\n. x) n + (\n. inv (&n + 1) * (c - x)) n)`` THENL
14262  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
14263  MATCH_MP_TAC LIM_ADD THEN REWRITE_TAC[LIM_CONST] THEN
14264  KNOW_TAC ``!n:num. (\n. inv (&n + 1) * (c - x:real)) =
14265                     (\n. (\n. inv (&n + 1)) n * (\n. (c - x)) n)`` THENL
14266  [FULL_SIMP_TAC std_ss [], ALL_TAC] THEN DISC_RW_KILL THEN
14267  MATCH_MP_TAC LIM_MUL THEN REWRITE_TAC[LIM_CONST] THEN
14268  REWRITE_TAC[LIM_SEQUENTIALLY, o_THM, REAL_SUB_RZERO] THEN BETA_TAC THEN
14269  X_GEN_TAC ``e:real`` THEN GEN_REWR_TAC LAND_CONV [REAL_ARCH_INV] THEN
14270  DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN
14271  X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN
14272  KNOW_TAC ``&n + 1 <> 0:real`` THENL
14273  [ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN MATCH_MP_TAC REAL_LT_IMP_NE THEN
14274   SIMP_TAC arith_ss [REAL_OF_NUM_SUC, REAL_LT, ADD1], ALL_TAC] THEN DISCH_TAC THEN
14275  ASM_SIMP_TAC std_ss [DIST_0, ABS_INV] THEN MATCH_MP_TAC REAL_LET_TRANS THEN
14276  EXISTS_TAC ``inv(&N:real)`` THEN ASM_REWRITE_TAC[] THEN
14277  MATCH_MP_TAC REAL_LE_INV2 THEN FULL_SIMP_TAC std_ss [] THEN
14278  UNDISCH_TAC ``N:num <= n`` THEN UNDISCH_TAC ``N <> 0:num`` THEN
14279  REWRITE_TAC[NOT_ZERO_LT_ZERO, GSYM REAL_OF_NUM_LE, GSYM REAL_LT] THEN
14280  REAL_ARITH_TAC);
14281
14282val CLOSURE_INTERVAL = store_thm ("CLOSURE_INTERVAL",
14283 ``(!a b. closure(interval[a,b]) = interval[a,b]) /\
14284   (!a b. closure(interval(a,b)) =
14285          if interval(a,b) = {} then {} else interval[a,b])``,
14286  SIMP_TAC std_ss [CLOSURE_CLOSED, CLOSED_INTERVAL] THEN REPEAT GEN_TAC THEN
14287  COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [CLOSURE_OPEN_INTERVAL, CLOSURE_EMPTY]);
14288
14289val BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC = store_thm ("BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC",
14290 ``!s:real->bool. bounded s ==> ?a. s SUBSET interval(-a,a)``,
14291  SIMP_TAC std_ss [BOUNDED_POS, LEFT_IMP_EXISTS_THM] THEN
14292  MAP_EVERY X_GEN_TAC [``s:real->bool``, ``B:real``] THEN STRIP_TAC THEN
14293  EXISTS_TAC ``(B + &1):real`` THEN
14294  REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
14295  SIMP_TAC std_ss [IN_INTERVAL, REAL_BOUNDS_LT] THEN
14296  METIS_TAC[REAL_LE_REFL, REAL_ARITH ``x <= y ==> a <= x ==> a < y + &1:real``]);
14297
14298val BOUNDED_SUBSET_OPEN_INTERVAL = store_thm ("BOUNDED_SUBSET_OPEN_INTERVAL",
14299 ``!s:real->bool. bounded s ==> ?a b. s SUBSET interval(a,b)``,
14300  MESON_TAC[BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC]);
14301
14302val BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC = store_thm ("BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC",
14303 ``!s:real->bool. bounded s ==> ?a. s SUBSET interval[-a,a]``,
14304  GEN_TAC THEN
14305  DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC) THEN
14306  STRIP_TAC THEN EXISTS_TAC ``a:real`` THEN POP_ASSUM MP_TAC THEN
14307  SIMP_TAC std_ss [IN_BALL, IN_INTERVAL, SUBSET_DEF, REAL_LT_IMP_LE]);
14308
14309val BOUNDED_SUBSET_CLOSED_INTERVAL = store_thm ("BOUNDED_SUBSET_CLOSED_INTERVAL",
14310 ``!s:real->bool. bounded s ==> ?a b. s SUBSET interval[a,b]``,
14311  MESON_TAC[BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC]);
14312
14313val FRONTIER_CLOSED_INTERVAL = store_thm ("FRONTIER_CLOSED_INTERVAL",
14314 ``!a b. frontier(interval[a,b]) = interval[a,b] DIFF interval(a,b)``,
14315  SIMP_TAC std_ss [frontier, INTERIOR_CLOSED_INTERVAL, CLOSURE_CLOSED,
14316           CLOSED_INTERVAL]);
14317
14318val FRONTIER_OPEN_INTERVAL = store_thm ("FRONTIER_OPEN_INTERVAL",
14319 ``!a b. frontier(interval(a,b)) =
14320                if interval(a,b) = {} then {}
14321                else interval[a,b] DIFF interval(a,b)``,
14322  REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[FRONTIER_EMPTY] THEN
14323  ASM_SIMP_TAC std_ss [frontier, CLOSURE_OPEN_INTERVAL, INTERIOR_OPEN,
14324               OPEN_INTERVAL]);
14325
14326val INTER_INTERVAL_MIXED_EQ_EMPTY = store_thm ("INTER_INTERVAL_MIXED_EQ_EMPTY",
14327 ``!a b c d:real.
14328        ~(interval(c,d) = {})
14329        ==> ((interval(a,b) INTER interval[c,d] = {}) <=>
14330             (interval(a,b) INTER interval(c,d) = {}))``,
14331  SIMP_TAC std_ss [GSYM CLOSURE_OPEN_INTERVAL, OPEN_INTER_CLOSURE_EQ_EMPTY,
14332           OPEN_INTERVAL]);
14333
14334val INTERVAL_TRANSLATION = store_thm ("INTERVAL_TRANSLATION",
14335 ``(!c a b. interval[c + a,c + b] = IMAGE (\x. c + x) (interval[a,b])) /\
14336   (!c a b. interval(c + a,c + b) = IMAGE (\x. c + x) (interval(a,b)))``,
14337  REWRITE_TAC[interval] THEN CONJ_TAC THEN
14338  (SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE] THEN
14339   REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN
14340   TRY (EXISTS_TAC ``-c + x:real``) THEN ASM_REAL_ARITH_TAC));
14341
14342val EMPTY_AS_INTERVAL = store_thm ("EMPTY_AS_INTERVAL",
14343 ``{} = interval[1,0]``,
14344  SIMP_TAC std_ss [EXTENSION, NOT_IN_EMPTY, IN_INTERVAL] THEN
14345  REAL_ARITH_TAC);
14346
14347val UNIT_INTERVAL_NONEMPTY = store_thm ("UNIT_INTERVAL_NONEMPTY",
14348 ``~(interval[0:real,1] = {}) /\
14349   ~(interval(0:real,1) = {})``,
14350  SIMP_TAC std_ss [INTERVAL_NE_EMPTY, REAL_LT_01, REAL_POS]);
14351
14352val IMAGE_STRETCH_INTERVAL = store_thm
14353  ("IMAGE_STRETCH_INTERVAL",
14354 ``!a b:real m.
14355    IMAGE (\x. @f. f = m(1:num) * x) (interval[a,b]) =
14356        if interval[a,b] = {} then {}
14357        else interval[(@f. f = min (m(1:num) * a) (m(1:num) * b)):real,
14358                      (@f. f = max (m(1:num) * a) (m(1:num) * b))]``,
14359  REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [IMAGE_EMPTY, IMAGE_INSERT] THEN
14360  ASM_SIMP_TAC std_ss [EXTENSION, IN_IMAGE, IN_INTERVAL, GSYM FORALL_AND_THM,
14361               TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN
14362  X_GEN_TAC ``x:real`` THEN
14363  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [INTERVAL_NE_EMPTY]) THEN
14364  ASM_CASES_TAC ``(m:num->real) (1:num) = &0`` THENL
14365   [ASM_SIMP_TAC std_ss [REAL_MUL_LZERO, REAL_MAX_ACI, REAL_MIN_ACI] THEN
14366    METIS_TAC[REAL_LE_ANTISYM, REAL_LE_REFL],
14367    ALL_TAC] THEN
14368  KNOW_TAC ``!m x y:real. ~(m = 0:real) ==> ((x = m * y) <=> (y = x / m))`` THENL
14369  [REPEAT GEN_TAC THEN DISCH_TAC THEN ASSUME_TAC REAL_LE_TOTAL THEN
14370   GEN_REWR_TAC RAND_CONV [EQ_SYM_EQ] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN
14371   POP_ASSUM (MP_TAC o Q.SPECL [`m':real`,`0:real`]) THEN
14372   ASM_SIMP_TAC std_ss [REAL_LE_LT] THEN STRIP_TAC THENL
14373   [ALL_TAC, METIS_TAC [REAL_EQ_LDIV_EQ]] THEN
14374   ONCE_REWRITE_TAC [GSYM REAL_EQ_NEG] THEN REWRITE_TAC [real_div] THEN
14375   REWRITE_TAC [REAL_ARITH ``-(a * b) = a * -b:real``] THEN
14376   ASM_SIMP_TAC std_ss [REAL_NEG_INV, GSYM real_div] THEN POP_ASSUM MP_TAC THEN
14377   GEN_REWR_TAC LAND_CONV [GSYM REAL_LT_NEG] THEN REWRITE_TAC [REAL_NEG_0] THEN
14378   DISCH_TAC THEN REWRITE_TAC [REAL_ARITH ``(-x = y * -m) <=> (x = -y * -m:real)``] THEN
14379   METIS_TAC [REAL_EQ_LDIV_EQ], DISCH_TAC THEN ASM_SIMP_TAC std_ss []] THEN
14380  SIMP_TAC std_ss [UNWIND_THM2] THEN FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP
14381   (REAL_ARITH ``~(z = &0) ==> &0 < z \/ &0 < -z:real``))
14382  >- ( ASM_SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_LE_RDIV_EQ] \\
14383       DISCH_TAC \\
14384       `(m 1) * a <= (m 1) * b` by PROVE_TAC [REAL_LE_LMUL] \\
14385       ASM_SIMP_TAC std_ss [min_def, max_def] \\
14386       METIS_TAC [REAL_MUL_SYM] )
14387  >> ONCE_REWRITE_TAC[GSYM REAL_LE_NEG2]
14388  >> ONCE_REWRITE_TAC[REAL_MUL_SYM]
14389  >> KNOW_TAC ``!a b. -(max a b) = min (-a) (-b:real)``
14390  >- PROVE_TAC [REAL_MAX_MIN, REAL_NEG_NEG] >> DISCH_TAC
14391  >> KNOW_TAC ``!a b. -(min a b) = max (-a) (-b:real)``
14392  >- PROVE_TAC [REAL_MIN_MAX, REAL_NEG_NEG] >> DISCH_TAC
14393  >> ASM_SIMP_TAC std_ss [real_div, GSYM REAL_MUL_RNEG, REAL_NEG_INV]
14394  >> REWRITE_TAC [GSYM real_div]
14395  >> ASM_SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_LE_RDIV_EQ]
14396  >> ONCE_REWRITE_TAC [REAL_LE_NEG2]
14397  >> DISCH_TAC
14398  >> `a * -(m 1) <= b * -(m 1)` by PROVE_TAC [REAL_LE_RMUL]
14399  >> ASM_SIMP_TAC std_ss [min_def, max_def]
14400  >> REAL_ARITH_TAC);
14401
14402val INTERVAL_IMAGE_STRETCH_INTERVAL = store_thm ("INTERVAL_IMAGE_STRETCH_INTERVAL",
14403 ``!a b:real m. ?u v:real.
14404     IMAGE (\x. @f. f = m (1:num) * x) (interval[a,b]) = interval[u,v]``,
14405  SIMP_TAC std_ss [IMAGE_STRETCH_INTERVAL] THEN METIS_TAC[EMPTY_AS_INTERVAL]);
14406
14407val CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL = store_thm ("CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL",
14408 ``!a b:real.
14409        ~(interval[a,b] = {})
14410        ==> (interval[a,b] = IMAGE (\x:real. a + x)
14411                                  (IMAGE (\x. (@f. f = (b - a) * x))
14412                                         (interval[0:real,1])))``,
14413  REWRITE_TAC[INTERVAL_NE_EMPTY] THEN REPEAT STRIP_TAC THEN
14414  ONCE_REWRITE_TAC [METIS [] ``(\x. @f. f = (b - a) * x) =
14415                               (\x. @f. f = (\x. (b - a)) (1:num) * x:real)``] THEN
14416  REWRITE_TAC[IMAGE_STRETCH_INTERVAL] THEN
14417  SIMP_TAC std_ss [REAL_MUL_RZERO, REAL_MUL_RID, UNIT_INTERVAL_NONEMPTY] THEN
14418  REWRITE_TAC[EXTENSION, IN_INTERVAL] THEN
14419  GEN_TAC THEN SIMP_TAC std_ss [IN_IMAGE, IN_INTERVAL, min_def, max_def] THEN
14420  ASM_SIMP_TAC std_ss [REAL_SUB_LE] THEN EQ_TAC THENL
14421  [DISCH_TAC THEN EXISTS_TAC ``x - a:real`` THEN ASM_REAL_ARITH_TAC, ASM_REAL_ARITH_TAC]);
14422
14423val SUMS_INTERVALS = store_thm ("SUMS_INTERVALS",
14424 ``(!a b c d:real.
14425        ~(interval[a,b] = {}) /\ ~(interval[c,d] = {})
14426        ==> ({x + y | x IN interval[a,b] /\ y IN interval[c,d]} =
14427             interval[a+c,b+d])) /\
14428   (!a b c d:real.
14429        ~(interval(a,b) = {}) /\ ~(interval(c,d) = {})
14430        ==> ({x + y | x IN interval(a,b) /\ y IN interval(c,d)} =
14431             interval(a+c,b+d)))``,
14432  CONJ_TAC THEN REPEAT GEN_TAC THEN REWRITE_TAC[INTERVAL_NE_EMPTY] THEN
14433  STRIP_TAC THEN SIMP_TAC std_ss [EXTENSION, IN_INTERVAL, GSPECIFICATION, EXISTS_PROD] THEN
14434  ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c <=> c /\ a /\ b`] THEN
14435  REWRITE_TAC[REAL_ARITH ``(x:real = y + z) <=> (z = x - y)``] THEN
14436  SIMP_TAC std_ss [UNWIND_THM2] THEN (* 2 subgoals *)
14437  ( X_GEN_TAC ``x:real`` THEN EQ_TAC
14438 >- ( DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) >> ASM_REAL_ARITH_TAC )
14439 >> STRIP_TAC
14440 >> ONCE_REWRITE_TAC [CONJ_SYM]
14441 >> KNOW_TAC
14442    ``(!y. (a <= y /\ y <= b) /\ c <= x - y /\ x - y <= d <=>
14443       ((if a <= x - d then x - d else a) <= y /\
14444    y <= if b <= x - c then b else x - c:real)) /\
14445      (!y. (a < y /\ y < b) /\ c < x - y /\ x - y < d <=>
14446       ((if a <= x - d then x - d else a) < y /\
14447    y < if b <= x - c then b else x - c:real))``
14448 >- ( CONJ_TAC >> GEN_TAC >> rpt COND_CASES_TAC >> ASM_REAL_ARITH_TAC )
14449 >> STRIP_TAC >> ASM_REWRITE_TAC []
14450 >> REWRITE_TAC [GSYM min_def, GSYM max_def, GSYM REAL_LE_BETWEEN, GSYM REAL_LT_BETWEEN]
14451 >> ASM_REWRITE_TAC [min_def, max_def]
14452 >> rpt COND_CASES_TAC (* 4 subgoals *)
14453 >> METIS_TAC [REAL_LE_SUB_LADD, REAL_LE_SUB_RADD, REAL_LE_LADD, REAL_LE_NEG, real_sub,
14454               REAL_LT_SUB_LADD, REAL_LT_SUB_RADD, REAL_LT_LADD, REAL_LT_NEG] ));
14455
14456val OPEN_CONTAINS_INTERVAL_OPEN_INTERVAL = store_thm ("OPEN_CONTAINS_INTERVAL_OPEN_INTERVAL",
14457 ``(!s:real->bool.
14458        open s <=>
14459        !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval[a,b] SUBSET s) /\
14460   (!s:real->bool.
14461        open s <=>
14462        !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval(a,b) SUBSET s)``,
14463  SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN GEN_TAC THEN
14464  MATCH_MP_TAC(TAUT
14465   `(q ==> r) /\ (r ==> p) /\ (p ==> q) ==> (p <=> q) /\ (p <=> r)`) THEN
14466  REPEAT CONJ_TAC THENL
14467   [MESON_TAC[SUBSET_TRANS, INTERVAL_OPEN_SUBSET_CLOSED],
14468    DISCH_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN
14469    X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
14470    FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN
14471    ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN
14472    MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``] THEN STRIP_TAC THEN
14473    MP_TAC(ISPEC ``interval(a:real,b)`` OPEN_CONTAINS_BALL) THEN
14474    REWRITE_TAC[OPEN_INTERVAL] THEN
14475    DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
14476        REPEAT STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[] THEN
14477    ASM_MESON_TAC[SUBSET_TRANS, INTERVAL_OPEN_SUBSET_CLOSED],
14478    DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
14479    FIRST_ASSUM(MP_TAC o SPEC ``x:real`` o
14480      REWRITE_RULE [OPEN_CONTAINS_CBALL]) THEN
14481    ASM_REWRITE_TAC[] THEN
14482    DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
14483    EXISTS_TAC ``x - e:real`` THEN
14484    EXISTS_TAC ``x + e:real`` THEN
14485    FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
14486     ``b SUBSET s ==> x IN i /\ j SUBSET b ==> x IN i /\ j SUBSET s``)) THEN
14487    SIMP_TAC std_ss [IN_INTERVAL, IN_CBALL, SUBSET_DEF, REAL_MUL_RID] THEN
14488    REWRITE_TAC[REAL_ARITH ``x - e < x /\ x < x + e <=> &0 < e:real``,
14489                REAL_ARITH ``x - e <= y /\ y <= x + e <=> abs(x - y) <= e:real``] THEN
14490    ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT, LE_1] THEN
14491    X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN ASM_REWRITE_TAC[dist]]);
14492
14493val OPEN_CONTAINS_INTERVAL = store_thm ("OPEN_CONTAINS_INTERVAL",
14494 ``(!s:real->bool.
14495        open s <=>
14496        !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval[a,b] SUBSET s)``,
14497   REWRITE_TAC [OPEN_CONTAINS_INTERVAL_OPEN_INTERVAL]);
14498
14499val OPEN_CONTAINS_OPEN_INTERVAL = store_thm ("OPEN_CONTAINS_OPEN_INTERVAL",
14500 ``(!s:real->bool.
14501        open s <=>
14502        !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval(a,b) SUBSET s)``,
14503   METIS_TAC [OPEN_CONTAINS_INTERVAL_OPEN_INTERVAL]);
14504
14505val DIAMETER_INTERVAL = store_thm ("DIAMETER_INTERVAL",
14506 ``(!a b:real.
14507        diameter(interval[a,b]) =
14508        if interval[a,b] = {} then &0 else abs(b - a)) /\
14509   (!a b:real.
14510        diameter(interval(a,b)) =
14511        if interval(a,b) = {} then &0 else abs(b - a))``,
14512  SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT GEN_TAC THEN
14513  ASM_CASES_TAC ``interval[a:real,b] = {}`` THENL
14514   [METIS_TAC[INTERVAL_OPEN_SUBSET_CLOSED, SUBSET_EMPTY, DIAMETER_EMPTY],
14515    ASM_REWRITE_TAC[]] THEN
14516  MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
14517   [REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
14518    ASM_SIMP_TAC std_ss [DIAMETER_BOUNDED_BOUND,
14519                 ENDS_IN_INTERVAL, BOUNDED_INTERVAL] THEN
14520    MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
14521     ``diameter(cball(inv(&2) * (a + b):real,abs(b - a) / &2))`` THEN
14522    CONJ_TAC THENL
14523     [MATCH_MP_TAC DIAMETER_SUBSET THEN REWRITE_TAC[BOUNDED_CBALL] THEN
14524      REWRITE_TAC[SUBSET_DEF, IN_INTERVAL, IN_CBALL] THEN
14525      GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[dist] THEN
14526      KNOW_TAC ``x = x * (2 / 2:real)`` THENL
14527      [METIS_TAC [REAL_DIV_REFL, REAL_MUL_RID, REAL_ARITH ``2 <> 0:real``],
14528       DISCH_TAC THEN ONCE_ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
14529       REWRITE_TAC [real_div]] THEN
14530      REWRITE_TAC [REAL_ARITH ``a * (b * inv b) = inv b * (a * b:real)``] THEN
14531      REWRITE_TAC [GSYM REAL_SUB_LDISTRIB, ABS_MUL] THEN
14532      SIMP_TAC std_ss [ABS_INV, REAL_ARITH ``2 <> 0:real``, ABS_N] THEN
14533      GEN_REWR_TAC RAND_CONV [REAL_MUL_SYM] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
14534      SIMP_TAC std_ss [ABS_POS, REAL_LE_REFL, REAL_INV_1OVER, REAL_HALF_BETWEEN] THEN
14535      ASM_REAL_ARITH_TAC,
14536      REWRITE_TAC[DIAMETER_CBALL] THEN COND_CASES_TAC THEN
14537      REWRITE_TAC [ABS_POS, real_div] THEN
14538      ONCE_REWRITE_TAC [REAL_ARITH ``a * (b * c) = (a * c) * b:real``] THEN
14539      SIMP_TAC std_ss [REAL_MUL_RINV, REAL_ARITH ``2 <> 0:real``] THEN
14540      REAL_ARITH_TAC],
14541    DISCH_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[DIAMETER_EMPTY] THEN
14542    SUBGOAL_THEN ``interval[a:real,b] = closure(interval(a,b))``
14543    SUBST_ALL_TAC THEN ASM_REWRITE_TAC[CLOSURE_INTERVAL] THEN
14544    ASM_MESON_TAC[DIAMETER_CLOSURE, BOUNDED_INTERVAL]]);
14545
14546val IMAGE_TWIZZLE_INTERVAL = store_thm ("IMAGE_TWIZZLE_INTERVAL",
14547 ``!p a b. IMAGE ((\x. x):real->real) (interval[a,b]) =
14548               interval[a,b]``,
14549  SET_TAC [interval]);
14550
14551val EQ_INTERVAL = store_thm ("EQ_INTERVAL",
14552 ``(!a b c d:real.
14553        (interval[a,b] = interval[c,d]) <=>
14554        ((interval[a,b] = {}) /\ (interval[c,d] = {})) \/ ((a = c) /\ (b = d))) /\
14555   (!a b c d:real.
14556        (interval[a,b] = interval(c,d)) <=>
14557        (interval[a,b] = {}) /\ (interval(c,d) = {})) /\
14558   (!a b c d:real.
14559        (interval(a,b) = interval[c,d]) <=>
14560        (interval(a,b) = {}) /\ (interval[c,d] = {})) /\
14561   (!a b c d:real.
14562        (interval(a,b) = interval(c,d)) <=>
14563        ((interval(a,b) = {}) /\ (interval(c,d) = {})) \/ ((a = c) /\ (b = d)))``,
14564  REPEAT CONJ_TAC THEN REPEAT GEN_TAC THEN
14565  (EQ_TAC THENL [ALL_TAC, STRIP_TAC THEN ASM_REWRITE_TAC[]]) THEN
14566  MATCH_MP_TAC(MESON[]
14567   ``((p = {}) /\ (q = {}) ==> r) /\ (~(p = {}) /\ ~(q = {}) ==> (p = q) ==> r)
14568    ==> (p = q) ==> r``) THEN
14569  SIMP_TAC std_ss [] THENL
14570   [REWRITE_TAC[INTERVAL_NE_EMPTY] THEN
14571    REWRITE_TAC[GSYM SUBSET_ANTISYM] THEN
14572    METIS_TAC [SUBSET_INTERVAL, GSYM REAL_LE_ANTISYM],
14573    STRIP_TAC THEN MATCH_MP_TAC(MESON[CLOPEN]
14574     ``closed s /\ open t /\ ~(s = {}) /\ ~(s = UNIV) ==> ~(s = t)``) THEN
14575    ASM_REWRITE_TAC[CLOSED_INTERVAL, OPEN_INTERVAL, NOT_INTERVAL_UNIV],
14576    STRIP_TAC THEN MATCH_MP_TAC(MESON[CLOPEN]
14577     ``closed s /\ open t /\ ~(s = {}) /\ ~(s = UNIV) ==> ~(t = s)``) THEN
14578    ASM_REWRITE_TAC[CLOSED_INTERVAL, OPEN_INTERVAL, NOT_INTERVAL_UNIV],
14579    REWRITE_TAC[INTERVAL_NE_EMPTY] THEN
14580    REWRITE_TAC[GSYM SUBSET_ANTISYM] THEN
14581    METIS_TAC [SUBSET_INTERVAL, GSYM REAL_LE_ANTISYM]]);
14582
14583val CLOSED_INTERVAL_EQ = store_thm ("CLOSED_INTERVAL_EQ",
14584 ``(!a b:real. closed(interval[a,b])) /\
14585   (!a b:real. closed(interval(a,b)) <=> (interval(a,b) = {}))``,
14586  REWRITE_TAC[CLOSED_INTERVAL] THEN
14587  REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN
14588  ASM_REWRITE_TAC[CLOSED_EMPTY] THEN
14589  MP_TAC(ISPEC ``interval(a:real,b)`` CLOPEN) THEN
14590  ASM_REWRITE_TAC[OPEN_INTERVAL] THEN
14591  METIS_TAC[BOUNDED_INTERVAL, NOT_BOUNDED_UNIV]);
14592
14593val OPEN_INTERVAL_EQ = store_thm ("OPEN_INTERVAL_EQ",
14594 ``(!a b:real. open(interval[a,b]) <=> (interval[a,b] = {})) /\
14595   (!a b:real. open(interval(a,b)))``,
14596  REWRITE_TAC[OPEN_INTERVAL] THEN
14597  REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN
14598  ASM_REWRITE_TAC[CLOSED_EMPTY] THEN
14599  MP_TAC(ISPEC ``interval[a:real,b]`` CLOPEN) THEN
14600  ASM_REWRITE_TAC[CLOSED_INTERVAL] THEN
14601  METIS_TAC[BOUNDED_INTERVAL, NOT_BOUNDED_UNIV]);
14602
14603val COMPACT_INTERVAL_EQ = store_thm ("COMPACT_INTERVAL_EQ",
14604 ``(!a b:real. compact(interval[a,b])) /\
14605   (!a b:real. compact(interval(a,b)) <=> (interval(a,b) = {}))``,
14606  REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_INTERVAL] THEN
14607  REWRITE_TAC[CLOSED_INTERVAL_EQ]);
14608
14609val EQ_BALLS = store_thm ("EQ_BALLS",
14610 ``(!a a':real r r'.
14611      (ball(a,r) = ball(a',r')) <=> (a = a') /\ (r = r') \/ r <= &0 /\ r' <= &0) /\
14612   (!a a':real r r'.
14613      (ball(a,r) = cball(a',r')) <=> r <= &0 /\ r' < &0) /\
14614   (!a a':real r r'.
14615      (cball(a,r) = ball(a',r')) <=> r < &0 /\ r' <= &0) /\
14616   (!a a':real r r'.
14617      (cball(a,r) = cball(a',r')) <=> (a = a') /\ (r = r') \/ r < &0 /\ r' < &0)``,
14618  SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT STRIP_TAC THEN
14619  (EQ_TAC THENL
14620    [ALL_TAC, REWRITE_TAC[EXTENSION, IN_BALL, IN_CBALL, dist] THEN REAL_ARITH_TAC])
14621  THENL
14622   [SIMP_TAC std_ss [SET_EQ_SUBSET, SUBSET_BALLS, dist] THEN REAL_ARITH_TAC,
14623    ONCE_REWRITE_TAC[EQ_SYM_EQ],
14624    ALL_TAC,
14625    REWRITE_TAC[SET_EQ_SUBSET, SUBSET_BALLS, dist] THEN REAL_ARITH_TAC] THEN
14626  DISCH_THEN(MP_TAC o MATCH_MP (METIS [CLOPEN, BOUNDED_BALL, NOT_BOUNDED_UNIV]
14627    ``(s = t) ==> closed s /\ open t /\ bounded t ==> (s = {}) /\ (t = {})``)) THEN
14628  REWRITE_TAC[OPEN_BALL, CLOSED_CBALL, BOUNDED_BALL,
14629              BALL_EQ_EMPTY, CBALL_EQ_EMPTY] THEN
14630  REAL_ARITH_TAC);
14631
14632(* ------------------------------------------------------------------------- *)
14633(* Some special cases for intervals in R^1.                                  *)
14634(* ------------------------------------------------------------------------- *)
14635
14636val INTERVAL_CASES = store_thm ("INTERVAL_CASES",
14637 ``!x:real. x IN interval[a,b] ==> x IN interval(a,b) \/ (x = a) \/ (x = b)``,
14638  REWRITE_TAC[IN_INTERVAL] THEN REAL_ARITH_TAC);
14639
14640val OPEN_CLOSED_INTERVAL = store_thm ("OPEN_CLOSED_INTERVAL",
14641 ``!a b:real. interval(a,b) = interval[a,b] DIFF {a;b}``,
14642  REWRITE_TAC[EXTENSION, IN_INTERVAL, IN_DIFF, IN_INSERT, NOT_IN_EMPTY] THEN
14643  SIMP_TAC std_ss [] THEN REAL_ARITH_TAC);
14644
14645val CLOSED_OPEN_INTERVAL = store_thm ("CLOSED_OPEN_INTERVAL",
14646 ``!a b:real. a <= b ==> (interval[a,b] = interval(a,b) UNION {a;b})``,
14647  REWRITE_TAC[EXTENSION, IN_INTERVAL, IN_UNION, IN_INSERT, NOT_IN_EMPTY] THEN
14648  SIMP_TAC std_ss [] THEN REAL_ARITH_TAC);
14649
14650val BALL = store_thm ("BALL",
14651 ``!x:real r. (cball(x,r) = interval[x - r,x + r]) /\
14652               (ball(x,r) = interval(x - r,x + r))``,
14653  REWRITE_TAC[EXTENSION, IN_BALL, IN_CBALL, IN_INTERVAL] THEN
14654  REWRITE_TAC[dist] THEN REAL_ARITH_TAC);
14655
14656val SPHERE = store_thm ("SPHERE",
14657 ``!a:real r. sphere(a,r) = if r < (&0:real) then {} else {a - r;a + r}``,
14658  REPEAT GEN_TAC THEN REWRITE_TAC[sphere] THEN COND_CASES_TAC THEN
14659  SIMP_TAC std_ss [EXTENSION, IN_INSERT, NOT_IN_EMPTY, GSPECIFICATION, dist] THEN
14660  ASM_REAL_ARITH_TAC);
14661
14662val FINITE_SPHERE = store_thm ("FINITE_SPHERE",
14663 ``!a:real r. FINITE(sphere(a,r))``,
14664  REPEAT GEN_TAC THEN REWRITE_TAC[SPHERE] THEN
14665  METIS_TAC[FINITE_INSERT, FINITE_EMPTY]);
14666
14667val FINITE_INTERVAL = store_thm ("FINITE_INTERVAL",
14668 ``(!a b. FINITE(interval[a,b]) <=> b <= a) /\
14669   (!a b. FINITE(interval(a,b)) <=> b <= a)``,
14670  REWRITE_TAC[OPEN_CLOSED_INTERVAL] THEN
14671  REWRITE_TAC[SET_RULE ``s DIFF {a;b} = s DELETE a DELETE b``] THEN
14672  REWRITE_TAC[FINITE_DELETE] THEN REPEAT GEN_TAC THEN
14673  SIMP_TAC std_ss [interval, FINITE_IMAGE_INJ_EQ, FINITE_REAL_INTERVAL]);
14674
14675val BALL_INTERVAL = store_thm ("BALL_INTERVAL",
14676 ``!x:real e. ball(x,e) = interval(x - e,x + e)``,
14677  REWRITE_TAC[EXTENSION, IN_BALL, IN_INTERVAL, dist] THEN
14678  REAL_ARITH_TAC);
14679
14680val CBALL_INTERVAL = store_thm ("CBALL_INTERVAL",
14681 ``!x:real e. cball(x,e) = interval[x - e,x + e]``,
14682  REWRITE_TAC[EXTENSION, IN_CBALL, IN_INTERVAL, dist] THEN
14683  REAL_ARITH_TAC);
14684
14685val BALL_INTERVAL_0 = store_thm ("BALL_INTERVAL_0",
14686 ``!e. ball(0:real,e) = interval(-e,e)``,
14687  GEN_TAC THEN REWRITE_TAC[BALL_INTERVAL] THEN AP_TERM_TAC THEN
14688  BINOP_TAC THEN REAL_ARITH_TAC);
14689
14690val CBALL_INTERVAL_0 = store_thm ("CBALL_INTERVAL_0",
14691 ``!e. cball(0:real,e) = interval[-e,e]``,
14692  GEN_TAC THEN REWRITE_TAC[CBALL_INTERVAL] THEN AP_TERM_TAC THEN
14693  AP_THM_TAC THEN AP_TERM_TAC THEN BINOP_TAC THEN REAL_ARITH_TAC);
14694
14695val CLOSED_DIFF_OPEN_INTERVAL = store_thm ("CLOSED_DIFF_OPEN_INTERVAL",
14696 ``!a b:real.
14697        interval[a,b] DIFF interval(a,b) =
14698        if interval[a,b] = {} then {} else {a;b}``,
14699  REWRITE_TAC[EXTENSION, IN_DIFF, GSYM INTERVAL_EQ_EMPTY, IN_INTERVAL] THEN
14700  REPEAT GEN_TAC THEN COND_CASES_TAC THEN
14701  ASM_REWRITE_TAC[NOT_IN_EMPTY, IN_INSERT, NOT_IN_EMPTY] THEN
14702  FULL_SIMP_TAC std_ss [NOT_IN_EMPTY] THEN
14703  ASM_REAL_ARITH_TAC);
14704
14705val INTERVAL = store_thm ("INTERVAL",
14706 ``(!a b:real. interval[a,b] =
14707                 if a <= b then cball(midpoint(a,b),dist(a,b) / &2)
14708                 else {}) /\
14709   (!a b:real. interval(a,b) =
14710                 if a < b then ball(midpoint(a,b),dist(a,b) / &2)
14711                 else {})``,
14712  REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
14713  RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LE, REAL_NOT_LT]) THEN
14714  ASM_REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN
14715  REWRITE_TAC[BALL, dist] THEN
14716  ASM_SIMP_TAC std_ss [REAL_SUB_LE, REAL_LT_IMP_LE,
14717                       REAL_ARITH ``a <= b ==> (abs(a - b) = b - a:real)``] THEN
14718  REWRITE_TAC[METIS [real_div, REAL_MUL_SYM] ``x / &2 = inv(&2:real) * x``] THEN
14719  REWRITE_TAC[midpoint] THEN
14720  TRY AP_TERM_TAC THEN ASM_SIMP_TAC std_ss [PAIR_EQ, CONS_11, GSYM INTERVAL_EQ_EMPTY] THEN
14721  REWRITE_TAC [GSYM REAL_SUB_LDISTRIB, GSYM REAL_ADD_LDISTRIB] THEN
14722  REWRITE_TAC [REAL_ARITH ``a + b - (b - a) = 2 * a:real``] THEN
14723  REWRITE_TAC [REAL_ARITH ``a + b + (b - a) = 2 * b:real``] THEN
14724  SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_ARITH ``2 <> 0:real``, REAL_MUL_LINV] THEN REAL_ARITH_TAC);
14725
14726val SEGMENT = store_thm ("SEGMENT",
14727 ``(!a b. segment[a,b] =
14728          if a <= b then interval[a,b] else interval[b,a]) /\
14729   (!a b. segment(a,b) =
14730          if a <= b then interval(a,b) else interval(b,a))``,
14731  CONJ_TAC THEN REPEAT GEN_TAC THEN REWRITE_TAC[open_segment] THEN
14732  COND_CASES_TAC THEN
14733  REWRITE_TAC[IN_DIFF, IN_INSERT, NOT_IN_EMPTY,
14734              EXTENSION, GSYM BETWEEN_IN_SEGMENT, between, IN_INTERVAL] THEN
14735  REWRITE_TAC[dist] THEN ASM_REAL_ARITH_TAC);
14736
14737val OPEN_SEGMENT = store_thm ("OPEN_SEGMENT",
14738 ``!a b:real. open(segment(a,b))``,
14739  REPEAT GEN_TAC THEN REWRITE_TAC[SEGMENT] THEN
14740  COND_CASES_TAC THEN REWRITE_TAC[OPEN_INTERVAL]);
14741
14742val SEGMENT_SCALAR_MULTIPLE = store_thm ("SEGMENT_SCALAR_MULTIPLE",
14743 ``(!a b v:real. segment[a * v,b * v] =
14744            {x * v:real | a <= x /\ x <= b \/ b <= x /\ x <= a}) /\
14745   (!a b v:real. ~(v = 0)
14746            ==> (segment(a * v,b * v) =
14747                 {x * v:real | a < x /\ x < b \/ b < x /\ x < a}))``,
14748  MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN REPEAT STRIP_TAC THENL
14749   [REPEAT GEN_TAC THEN
14750    MP_TAC(SPECL [``a * 1:real``, ``b * 1:real``]
14751     (CONJUNCT1 SEGMENT)) THEN
14752    REWRITE_TAC[segment, REAL_MUL_ASSOC, GSYM REAL_ADD_RDISTRIB] THEN
14753        ONCE_REWRITE_TAC [METIS [] ``((1 - u) * a + u * b:real) =
14754                                (\u. ((1 - u) * a + u * b)) u``] THEN
14755        ONCE_REWRITE_TAC [METIS [] ``(0 <= u /\ u <= 1:real) =
14756                                (\u.  0 <= u /\ u <= 1) u``] THEN
14757        ONCE_REWRITE_TAC [METIS []
14758        ``{x:real * v | a <= x /\ x <= b \/ b <= x /\ x <= a} =
14759          {(\x. x) x * v | (\x. a <= x /\ x <= b \/ b <= x /\ x <= a) x}``] THEN
14760    REWRITE_TAC [SET_RULE ``{f x * b:real | p (x:real)} =
14761                                IMAGE (\a. a * b) {f x | p x}``] THEN
14762    BETA_TAC THEN DISCH_TAC THEN AP_TERM_TAC THEN
14763    FIRST_X_ASSUM(MP_TAC o SIMP_RULE std_ss [REAL_MUL_RID, IMAGE_ID]) THEN
14764    DISCH_THEN SUBST1_TAC THEN COND_CASES_TAC THEN
14765        SIMP_TAC std_ss [EXTENSION, IN_INTERVAL, GSPECIFICATION] THEN ASM_REAL_ARITH_TAC,
14766    ASM_REWRITE_TAC[open_segment] THEN
14767        ONCE_REWRITE_TAC [METIS [] ``{x * v | a <= x /\ x <= b \/ b <= x /\ x <= a:real} =
14768                        {(\x. x) x * v | (\x. a <= x /\ x <= b \/ b <= x /\ x <= a) x}``] THEN
14769    ASM_SIMP_TAC std_ss [REAL_EQ_RMUL, SET_RULE
14770     ``(!x y:real. (x * v = y * v) <=> (x = y))
14771      ==> ({x * v | P x} DIFF {a * v;b * v} =
14772           {x * v | P x /\ ~(x = a) /\ ~(x = b)})``] THEN
14773        ONCE_REWRITE_TAC [SET_RULE
14774        ``{x * v | (a <= x /\ x <= b \/ b <= x /\ x <= a) /\ x <> a /\ x <> b:real} =
14775     {(\x. x * v) x | x IN (\x. (a <= x /\ x <= b \/ b <= x /\ x <= a) /\ x <> a /\ x <> b)}``] THEN
14776        ONCE_REWRITE_TAC [SET_RULE
14777              ``{x * v | a < x /\ x < b \/ b < x /\ x < a:real} =
14778       {(\x. x * v) x | x IN (\x. (a < x /\ x < b \/ b < x /\ x < a))}``] THEN
14779    ONCE_REWRITE_TAC[GSYM IMAGE_DEF] THEN AP_TERM_TAC THEN
14780    ABS_TAC THEN REAL_ARITH_TAC]);
14781
14782(* ------------------------------------------------------------------------- *)
14783(* Intervals in general, including infinite and mixtures of open and closed. *)
14784(* ------------------------------------------------------------------------- *)
14785
14786val is_interval = new_definition ("is_interval",
14787  ``is_interval(s:real->bool) <=>
14788        !a b x. a IN s /\ b IN s
14789                     ==> (a <= x /\ x <= b) \/
14790                         (b <= x /\ x <= a)
14791                ==> x IN s``);
14792
14793val IS_INTERVAL_INTERVAL = store_thm ("IS_INTERVAL_INTERVAL",
14794 ``!a:real b. is_interval(interval (a,b)) /\ is_interval(interval [a,b])``,
14795  REWRITE_TAC[is_interval, IN_INTERVAL] THEN
14796  METIS_TAC[REAL_LT_TRANS, REAL_LE_TRANS, REAL_LET_TRANS, REAL_LTE_TRANS]);
14797
14798val IS_INTERVAL_EMPTY = store_thm ("IS_INTERVAL_EMPTY",
14799 ``is_interval {}``,
14800  REWRITE_TAC[is_interval, NOT_IN_EMPTY]);
14801
14802val IS_INTERVAL_UNIV = store_thm ("IS_INTERVAL_UNIV",
14803 ``is_interval(UNIV:real->bool)``,
14804  REWRITE_TAC[is_interval, IN_UNIV]);
14805
14806val IS_INTERVAL_POINTWISE = store_thm ("IS_INTERVAL_POINTWISE",
14807 ``!s:real->bool x.
14808        is_interval s ==> (?a. a IN s /\ (a = x))
14809        ==> x IN s``,
14810  METIS_TAC [is_interval]);
14811
14812Theorem IS_INTERVAL_COMPACT :
14813    !s:real->bool. is_interval s /\ compact s <=> ?a b. s = interval[a,b]
14814Proof
14815  GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN
14816  ASM_SIMP_TAC std_ss [IS_INTERVAL_INTERVAL, COMPACT_INTERVAL] THEN
14817  ASM_CASES_TAC ``s:real->bool = {}``
14818  >- ASM_MESON_TAC[EMPTY_AS_INTERVAL] THEN (* one goal left *)
14819  EXISTS_TAC ``(@f. f = inf { (x:real) | x IN s}):real`` THEN
14820  EXISTS_TAC ``(@f. f = sup { (x:real) | x IN s}):real`` THEN
14821  SIMP_TAC std_ss [EXTENSION, IN_INTERVAL] THEN X_GEN_TAC ``x:real`` THEN
14822  EQ_TAC THENL (* 2 subgoals *)
14823  [ (* goal 1 (of 2) *)
14824    DISCH_TAC THEN
14825    MP_TAC(ISPEC ``{ (x:real) | x IN s}`` INF) THEN
14826    MP_TAC(ISPEC ``{ (x:real) | x IN s}`` SUP) THEN
14827    SIMP_TAC std_ss [METIS [] ``x = (\x. x) x``, GSYM IMAGE_DEF] THEN
14828    ASM_SIMP_TAC std_ss [IMAGE_EQ_EMPTY, FORALL_IN_IMAGE] THEN
14829    FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN
14830    REWRITE_TAC[bounded_def] THEN
14831    ASM_MESON_TAC[REAL_LE_TRANS, MEMBER_NOT_EMPTY,
14832                  REAL_ARITH ``abs(x) <= B ==> -B <= x /\ x <= B:real``],
14833    (* goal 2 (of 2) *)
14834    DISCH_TAC THEN
14835    SUFF_TAC ``?a:real. a IN s /\ (a = x)``
14836    >- (MATCH_MP_TAC IS_INTERVAL_POINTWISE >> ASM_REWRITE_TAC []) THEN
14837    SUBGOAL_THEN
14838     ``?a b:real. a IN s /\ b IN s /\ a <= (x:real) /\ x <= b``
14839    STRIP_ASSUME_TAC THENL (* 2 subgoals *)
14840    [ (* goal 2.1 (of 2) *)
14841      MP_TAC (ISPECL [``\x:real. x``, ``s:real->bool``]
14842                     CONTINUOUS_ATTAINS_INF) THEN
14843      ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ID, o_DEF] THEN
14844      DISCH_THEN (X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN
14845      EXISTS_TAC ``a:real`` THEN
14846      MP_TAC (ISPECL [``\x:real. x``, ``s:real->bool``]
14847                     CONTINUOUS_ATTAINS_SUP) THEN
14848      ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ID, o_DEF] THEN
14849      DISCH_THEN (X_CHOOSE_THEN ``b:real`` STRIP_ASSUME_TAC) THEN
14850      EXISTS_TAC ``b:real`` THEN ASM_REWRITE_TAC [] THEN
14851      CONJ_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THENL (* 2 subgoals *)
14852      [ (* goal 2.1.1 (of 2) *)
14853        EXISTS_TAC ``inf {(x:real) | x IN s}`` THEN ASM_SIMP_TAC std_ss [] THEN
14854        MATCH_MP_TAC REAL_LE_INF THEN
14855        ONCE_REWRITE_TAC [METIS [SPECIFICATION] ``{x | x IN s} x <=> x IN {x | x IN s}``] THEN
14856        ASM_SET_TAC [],
14857        (* goal 2.1.2 (of 2) *)
14858        EXISTS_TAC ``sup {(x:real) | x IN s}`` THEN ASM_SIMP_TAC std_ss [] THEN
14859        MATCH_MP_TAC REAL_SUP_LE' THEN
14860        ONCE_REWRITE_TAC [METIS [SPECIFICATION] ``{x | x IN s} x <=> x IN {x | x IN s}``] THEN
14861        ASM_SET_TAC [] ],
14862      (* goal 2.2 (of 2) *)
14863      EXISTS_TAC ``x:real`` THEN ASM_SIMP_TAC std_ss [] THEN
14864      UNDISCH_TAC ``is_interval s`` THEN DISCH_TAC THEN
14865      FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[is_interval, AND_IMP_INTRO]) THEN
14866      MAP_EVERY EXISTS_TAC [``a:real``, ``b:real``] THEN
14867      ASM_SIMP_TAC std_ss [] ] ]
14868QED
14869
14870val IS_INTERVAL = store_thm ("IS_INTERVAL",
14871 ``!s:real->bool.
14872        is_interval s <=>
14873          !a b x. a IN s /\ b IN s /\ a <= x /\ x <= b
14874                  ==> x IN s``,
14875  REWRITE_TAC[is_interval] THEN MESON_TAC[]);
14876
14877val IS_INTERVAL_CASES = store_thm ("IS_INTERVAL_CASES",
14878 ``!s:real->bool.
14879        is_interval s <=>
14880        (s = {}) \/
14881        (s = univ(:real)) \/
14882        (?a. s = {x | a < x}) \/
14883        (?a. s = {x | a <= x}) \/
14884        (?b. s = {x | x <= b}) \/
14885        (?b. s = {x | x < b}) \/
14886        (?a b. s = {x | a < x /\ x < b}) \/
14887        (?a b. s = {x | a < x /\ x <= b}) \/
14888        (?a b. s = {x | a <= x /\ x < b}) \/
14889        (?a b. s = {x | a <= x /\ x <= b})``,
14890  GEN_TAC THEN REWRITE_TAC[IS_INTERVAL] THEN EQ_TAC THENL
14891   [DISCH_TAC,
14892    STRIP_TAC THEN ASM_SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV, NOT_IN_EMPTY] THEN
14893    REAL_ARITH_TAC] THEN
14894  ASM_CASES_TAC ``s:real->bool = {}`` THEN ASM_REWRITE_TAC[] THEN
14895  MP_TAC(ISPEC ``s:real->bool`` SUP) THEN
14896  MP_TAC(ISPEC ``s:real->bool`` INF) THEN
14897  ASM_SIMP_TAC std_ss [IMAGE_EQ_EMPTY, FORALL_IN_IMAGE] THEN
14898  ASM_CASES_TAC ``?a. !x:real. x IN s ==> a <= x`` THEN
14899  ASM_CASES_TAC ``?b. !x:real. x IN s ==> x <= b`` THEN
14900  ASM_REWRITE_TAC[] THENL
14901   [STRIP_TAC THEN STRIP_TAC THEN
14902    MAP_EVERY ASM_CASES_TAC
14903     [``inf(s) IN s:real->bool``, ``sup(s) IN s:real->bool``]
14904    THENL
14905     [DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN
14906          DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC,
14907      DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN
14908      DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ1_TAC,
14909      DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN
14910          DISJ2_TAC THEN DISJ2_TAC THEN DISJ1_TAC,
14911      DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN
14912      DISJ2_TAC THEN DISJ1_TAC] THEN
14913    MAP_EVERY EXISTS_TAC [``inf(s:real->bool)``, ``sup(s:real->bool)``],
14914    STRIP_TAC THEN ASM_CASES_TAC ``inf(s:real->bool) IN s`` THENL
14915     [DISJ2_TAC THEN DISJ2_TAC THEN DISJ1_TAC,
14916      DISJ2_TAC THEN DISJ1_TAC] THEN
14917    EXISTS_TAC ``inf(s:real->bool)``,
14918    STRIP_TAC THEN ASM_CASES_TAC ``sup(s:real->bool) IN s`` THENL
14919     [DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ1_TAC,
14920      DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN DISJ2_TAC THEN
14921          DISJ1_TAC] THEN
14922    EXISTS_TAC ``sup(s:real->bool)``,
14923    DISJ1_TAC] THEN
14924  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_UNIV] THEN
14925  RULE_ASSUM_TAC(REWRITE_RULE[IN_IMAGE]) THEN
14926  REWRITE_TAC[GSYM REAL_NOT_LE] THEN
14927  ASM_MESON_TAC [REAL_LE_TRANS, REAL_LE_TOTAL, REAL_LE_ANTISYM]);
14928
14929val IS_INTERVAL_INTER = store_thm ("IS_INTERVAL_INTER",
14930 ``!s t:real->bool.
14931        is_interval s /\ is_interval t ==> is_interval(s INTER t)``,
14932  REWRITE_TAC[is_interval, IN_INTER] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
14933  MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``, ``x:real``] THEN
14934  REPEAT STRIP_TAC THENL
14935  [UNDISCH_TAC ``!a b x.
14936            a IN s /\ b IN s ==>
14937            a <= x /\ x <= b \/ b <= x /\ x <= a ==>
14938            x IN s:real->bool`` THEN DISCH_TAC THEN
14939   FIRST_X_ASSUM (MATCH_MP_TAC o REWRITE_RULE [AND_IMP_INTRO]),
14940   UNDISCH_TAC ``!a b x.
14941            a IN t /\ b IN t ==>
14942            a <= x /\ x <= b \/ b <= x /\ x <= a ==>
14943            x IN t:real->bool`` THEN DISCH_TAC THEN
14944   FIRST_X_ASSUM (MATCH_MP_TAC o REWRITE_RULE [AND_IMP_INTRO]),
14945   UNDISCH_TAC ``!a b x.
14946            a IN s /\ b IN s ==>
14947            a <= x /\ x <= b \/ b <= x /\ x <= a ==>
14948            x IN s:real->bool`` THEN DISCH_TAC THEN
14949   FIRST_X_ASSUM (MATCH_MP_TAC o REWRITE_RULE [AND_IMP_INTRO]),
14950   UNDISCH_TAC ``!a b x.
14951            a IN t /\ b IN t ==>
14952            a <= x /\ x <= b \/ b <= x /\ x <= a ==>
14953            x IN t:real->bool`` THEN DISCH_TAC THEN
14954   FIRST_X_ASSUM (MATCH_MP_TAC o REWRITE_RULE [AND_IMP_INTRO])] THEN
14955  MAP_EVERY EXISTS_TAC [``a:real``, ``b:real``] THEN ASM_REWRITE_TAC[]);
14956
14957val INTERVAL_SUBSET_IS_INTERVAL = store_thm ("INTERVAL_SUBSET_IS_INTERVAL",
14958 ``!s a b:real.
14959     is_interval s
14960     ==> (interval[a,b] SUBSET s <=> (interval[a,b] = {}) \/ a IN s /\ b IN s)``,
14961  REWRITE_TAC[is_interval] THEN REPEAT STRIP_TAC THEN
14962  ASM_CASES_TAC ``interval[a:real,b] = {}`` THEN
14963  ASM_REWRITE_TAC[EMPTY_SUBSET] THEN
14964  EQ_TAC THENL [ASM_MESON_TAC[ENDS_IN_INTERVAL, SUBSET_DEF], ALL_TAC] THEN
14965  REWRITE_TAC[SUBSET_DEF, IN_INTERVAL] THEN ASM_MESON_TAC[]);
14966
14967val INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD = store_thm
14968  ("INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD",
14969 ``!s x:real.
14970        is_interval s /\ x IN s
14971        ==> ?a b d. &0 < d /\ x IN interval[a,b] /\
14972                    interval[a,b] SUBSET s /\
14973                    ball(x,d) INTER s SUBSET interval[a,b]``,
14974  REPEAT STRIP_TAC THEN ASM_SIMP_TAC std_ss [INTERVAL_SUBSET_IS_INTERVAL] THEN
14975  SUBGOAL_THEN ``?a. (?y. y IN s /\ (y = a)) /\
14976                    (a < x \/ (a = (x:real)) /\
14977                        !y:real. y IN s ==> a <= y)``
14978  MP_TAC THENL [ASM_MESON_TAC[REAL_NOT_LT], SIMP_TAC std_ss []] THEN
14979  DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN
14980  SUBGOAL_THEN
14981   ``?b. (?y. y IN s /\ (y = b)) /\
14982                (x < b \/ (b = (x:real)) /\
14983                            !y:real. y IN s ==> y <= b)``
14984  MP_TAC THENL [ASM_MESON_TAC[REAL_NOT_LT], SIMP_TAC std_ss []] THEN
14985  DISCH_THEN (X_CHOOSE_TAC ``b:real``) THEN EXISTS_TAC ``b:real`` THEN
14986  EXISTS_TAC ``min (if a < x then (x:real) - a else &1)
14987                   (if x < b then (b:real) - x else &1)`` THEN
14988  REWRITE_TAC[REAL_LT_MIN, SUBSET_DEF, IN_BALL, IN_INTER] THEN
14989  SIMP_TAC std_ss [REAL_LT_INF_FINITE, IMAGE_EQ_EMPTY, IMAGE_FINITE,
14990                   FINITE_NUMSEG, NUMSEG_EMPTY, GSYM NOT_LESS_EQUAL] THEN
14991  SIMP_TAC std_ss [FORALL_IN_IMAGE, IN_INTERVAL] THEN REPEAT CONJ_TAC THENL
14992   [METIS_TAC[REAL_SUB_LT, REAL_LT_01],
14993    METIS_TAC[REAL_SUB_LT, REAL_LT_01],
14994    ASM_MESON_TAC[REAL_LE_LT],
14995    ASM_MESON_TAC[REAL_LE_LT],
14996        METIS_TAC [], ALL_TAC] THEN
14997    X_GEN_TAC ``y:real`` THEN
14998    DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
14999    MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN
15000    (COND_CASES_TAC THENL [REWRITE_TAC[dist], ASM_MESON_TAC[]]) THEN
15001        REWRITE_TAC [abs] THEN COND_CASES_TAC THEN DISCH_TAC THENL
15002        [FULL_SIMP_TAC std_ss [REAL_ARITH ``x - y < x - a <=> a < y:real``, REAL_LE_LT],
15003     FULL_SIMP_TAC std_ss [REAL_NOT_LE, REAL_ARITH ``x - y < 0 <=> x < y:real``] THEN
15004         METIS_TAC [REAL_LE_TRANS, REAL_LE_LT],
15005         FULL_SIMP_TAC std_ss [REAL_SUB_LE] THEN METIS_TAC [REAL_LE_TRANS, REAL_LE_LT],
15006         FULL_SIMP_TAC std_ss [REAL_NEG_SUB,
15007          REAL_ARITH ``y - x < b - x <=> y < b:real``, REAL_LE_LT]]);
15008
15009Theorem IS_INTERVAL_SUMS :
15010    !s t:real->bool.
15011        is_interval s /\ is_interval t
15012        ==> is_interval {x + y | x IN s /\ y IN t}
15013Proof
15014  REPEAT GEN_TAC THEN REWRITE_TAC[is_interval] THEN
15015  SIMP_TAC std_ss [IMP_CONJ, RIGHT_FORALL_IMP_THM] THEN
15016  SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN
15017  SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN
15018  REWRITE_TAC[AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN
15019  MAP_EVERY X_GEN_TAC
15020   [``a:real``, ``a':real``, ``b:real``, ``b':real``, ``y:real``] THEN
15021  DISCH_THEN(CONJUNCTS_THEN2
15022   (MP_TAC o SPECL [``a:real``, ``b:real``]) MP_TAC) THEN
15023  DISCH_THEN(CONJUNCTS_THEN2
15024   (MP_TAC o SPECL [``a':real``, ``b':real``]) ASSUME_TAC) THEN
15025  ASM_SIMP_TAC std_ss [AND_IMP_INTRO, GSPECIFICATION, EXISTS_PROD] THEN
15026  ONCE_REWRITE_TAC[REAL_ARITH ``(z:real = x + y) <=> (y = z - x)``] THEN
15027  SIMP_TAC std_ss [UNWIND_THM2] THEN
15028  ONCE_REWRITE_TAC [METIS []
15029   ``!a b s. (!x. a <= x /\ x <= b \/ b <= x /\ x <= a ==> x IN s:real->bool) =
15030             (!x. (\x. a <= x /\ x <= b \/ b <= x /\ x <= a) x ==> x IN s)``] THEN
15031  ONCE_REWRITE_TAC [METIS [] ``(y - p_1) = (\x. y - x) (p_1:real)``] THEN
15032  MATCH_MP_TAC(METIS []
15033   ``(?x. P x /\ Q(f x))
15034    ==> (!x. Q x ==> x IN t) /\ (!x. P x ==> x IN s)
15035        ==> ?x. x IN s /\ f x IN t``) THEN
15036  POP_ASSUM MP_TAC THEN DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
15037  DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
15038  DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
15039  DISCH_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
15040  SIMP_TAC std_ss [REAL_ARITH
15041   ``c <= y - x /\ y - x <= d <=> y - d <= x /\ x <= y - c:real``] THEN
15042  Know `!a b x. a <= x /\ x <= b \/ b <= x /\ x <= a:real <=>
15043                min a b <= x /\ x <= max a b`
15044  >- (KILL_TAC >> RW_TAC std_ss [max_def, min_def] \\
15045      REAL_ASM_ARITH_TAC) >> Rewr \\
15046  ONCE_REWRITE_TAC[TAUT `(p /\ q) /\ (r /\ s) <=> (p /\ r) /\ (q /\ s)`] THEN
15047  REWRITE_TAC[GSYM REAL_LE_MIN, GSYM REAL_MAX_LE] THEN
15048  REWRITE_TAC[GSYM REAL_LE_BETWEEN] THEN
15049  SIMP_TAC std_ss [min_def, max_def] THEN REPEAT COND_CASES_TAC THEN
15050  FULL_SIMP_TAC std_ss [] THEN ASM_REAL_ARITH_TAC
15051QED
15052
15053val IS_INTERVAL_SING = store_thm ("IS_INTERVAL_SING",
15054 ``!a:real. is_interval {a}``,
15055  SIMP_TAC std_ss [is_interval, IN_SING, CONJ_EQ_IMP, REAL_LE_ANTISYM]);
15056
15057val IS_INTERVAL_SCALING = store_thm ("IS_INTERVAL_SCALING",
15058 ``!s:real->bool c. is_interval s ==> is_interval(IMAGE (\x. c * x) s)``,
15059  REPEAT GEN_TAC THEN ASM_CASES_TAC ``c = &0:real`` THENL
15060   [ASM_REWRITE_TAC[REAL_MUL_LZERO] THEN
15061    SUBGOAL_THEN ``(IMAGE ((\x. 0):real->real) (s:real->bool) = {}) \/
15062                   (IMAGE ((\x. 0):real->real) s = {0})``
15063    STRIP_ASSUME_TAC THENL
15064     [SET_TAC[],
15065      ASM_REWRITE_TAC[IS_INTERVAL_EMPTY],
15066      ASM_REWRITE_TAC[IS_INTERVAL_SING]],
15067    SIMP_TAC std_ss [is_interval, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN
15068    SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN DISCH_TAC THEN
15069        SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN
15070        POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_FORALL_THM]) THEN
15071    REWRITE_TAC[AND_IMP_INTRO] THEN
15072        DISCH_TAC THEN MAP_EVERY X_GEN_TAC [``a:real``,``b:real``] THEN
15073        POP_ASSUM (MP_TAC o Q.SPECL [`a:real`,`b:real`]) THEN
15074    DISCH_THEN(fn th => X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
15075                         MP_TAC(SPEC ``inv(c) * x:real`` th)) THEN
15076    ASM_SIMP_TAC std_ss [IN_IMAGE] THEN
15077    KNOW_TAC ``a <= inv c * x /\ inv c * x <= b \/
15078               b <= inv c * x /\ inv c * x <= a:real`` THENL
15079     [FIRST_X_ASSUM(MP_TAC) THEN
15080          DISCH_THEN (CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
15081          ASM_REWRITE_TAC[] THEN
15082      ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN
15083          UNDISCH_TAC ``c <> 0:real`` THEN DISCH_TAC THEN
15084      FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH
15085       ``~(c = &0:real) ==> &0 < c \/ &0 < -c``)) THEN
15086      ASM_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_LE_LDIV_EQ] THEN
15087      GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_LE_NEG2] THEN
15088      ASM_SIMP_TAC std_ss [GSYM REAL_MUL_RNEG, GSYM REAL_LE_RDIV_EQ, GSYM
15089                   REAL_LE_LDIV_EQ] THEN
15090      ASM_SIMP_TAC std_ss [real_div, GSYM REAL_NEG_INV] THEN REAL_ARITH_TAC,
15091          DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
15092      DISCH_TAC THEN EXISTS_TAC ``inv c * x:real`` THEN
15093      ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_RINV, REAL_MUL_LID]]]);
15094
15095val IS_INTERVAL_SCALING_EQ = store_thm ("IS_INTERVAL_SCALING_EQ",
15096 ``!s:real->bool c.
15097        is_interval(IMAGE (\x. c * x) s) <=> (c = &0) \/ is_interval s``,
15098  REPEAT GEN_TAC THEN ASM_CASES_TAC ``c = &0:real`` THENL
15099   [ASM_REWRITE_TAC[REAL_MUL_LZERO] THEN
15100    SUBGOAL_THEN ``(IMAGE ((\x. 0):real->real) s = {}) \/
15101                   (IMAGE ((\x. 0):real->real) s = {0})``
15102    STRIP_ASSUME_TAC THENL
15103     [SET_TAC[],
15104      ASM_REWRITE_TAC[IS_INTERVAL_EMPTY],
15105      ASM_REWRITE_TAC[IS_INTERVAL_SING]],
15106    ASM_REWRITE_TAC[] THEN EQ_TAC THEN REWRITE_TAC[IS_INTERVAL_SCALING] THEN
15107    DISCH_THEN(MP_TAC o SPEC ``inv c:real`` o MATCH_MP IS_INTERVAL_SCALING) THEN
15108    ASM_SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, REAL_MUL_ASSOC, o_DEF, REAL_MUL_LINV,
15109                 REAL_MUL_LID, IMAGE_ID]]);
15110
15111val lemma0 = prove ((* unused *)
15112  ``!c. &0 < c
15113       ==> !s:real->bool. is_interval(IMAGE (\x. c * x) s) <=>
15114                            is_interval s``,
15115  SIMP_TAC std_ss [IS_INTERVAL_SCALING_EQ, REAL_LT_IMP_NE]);
15116
15117val lemma = prove (
15118  ``~(?a b c:real. a < b /\ b < c /\
15119               a IN s /\ b IN s /\ c IN s)
15120     ==> FINITE s /\ CARD(s) <= 2``,
15121    ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN
15122    REWRITE_TAC[TAUT `~(p /\ q) <=> p ==> ~q`] THEN
15123    REWRITE_TAC[ARITH_PROVE ``~(n <= 2) <=> 3 <= n:num``] THEN
15124    DISCH_THEN(MP_TAC o MATCH_MP CHOOSE_SUBSET_STRONG) THEN
15125    REWRITE_TAC [ARITH_PROVE ``3 = SUC 2``, TWO, ONE,  HAS_SIZE_CLAUSES] THEN
15126    DISCH_TAC THEN KNOW_TAC ``(?a b c:real.
15127      ((~(b = c) /\ ~(a = c)) /\ ~(a = b)) /\ {a; b; c} SUBSET s)`` THENL
15128    [POP_ASSUM MP_TAC THEN
15129     REWRITE_TAC [ARITH_PROVE ``3 = SUC 2``, TWO, ONE,  HAS_SIZE_CLAUSES] THEN
15130     SET_TAC [], POP_ASSUM K_TAC] THEN
15131    SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM, GSYM CONJ_ASSOC] THEN
15132    REWRITE_TAC[INSERT_SUBSET, EMPTY_SUBSET] THEN
15133    ONCE_REWRITE_TAC [METIS []
15134     ``(b <> c /\ a <> c /\ a <> b /\ a IN s /\ b IN s /\ c IN s ==>
15135     ?a b c:real. a < b /\ b < c /\ a IN s /\ b IN s /\ c IN s) =
15136    (\a b c. b <> c /\ a <> c /\ a <> b /\ a IN s /\ b IN s /\ c IN s ==>
15137     ?a b c:real. a < b /\ b < c /\ a IN s /\ b IN s /\ c IN s) a b c``] THEN
15138    MATCH_MP_TAC(METIS [REAL_LE_TOTAL]
15139     ``(!m n p:real. P m n p ==> P n p m /\ P n m p) /\
15140       (!m n p. m <= n /\ n <= p ==> P m n p)
15141       ==> !m n p. P m n p``) THEN
15142    CONJ_TAC THENL [METIS_TAC[], ALL_TAC] THEN
15143    SIMP_TAC std_ss [REAL_LT_LE] THEN METIS_TAC[]);
15144
15145val CARD_FRONTIER_INTERVAL = store_thm ("CARD_FRONTIER_INTERVAL",
15146 ``!s:real->bool.
15147        is_interval s ==> FINITE(frontier s) /\ CARD(frontier s) <= 2``,
15148  GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC lemma THEN
15149  SIMP_TAC std_ss [NOT_EXISTS_THM, FRONTIER_CLOSURES, IN_INTER] THEN
15150  MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``, ``c:real``] THEN
15151  CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
15152  MAP_EVERY UNDISCH_TAC
15153   [``b IN closure (univ(:real) DIFF s)``,
15154    ``(a:real) IN closure s``, ``(c:real) IN closure s``] THEN
15155  SIMP_TAC std_ss [CLOSURE_APPROACHABLE, IN_DIFF, IN_UNIV, dist] THEN
15156  DISCH_THEN(MP_TAC o SPEC ``(c - b) / &2:real``) THEN
15157  ASM_REWRITE_TAC[REAL_HALF, REAL_SUB_LT] THEN
15158  DISCH_THEN(X_CHOOSE_THEN ``v:real`` STRIP_ASSUME_TAC) THEN
15159  DISCH_THEN(MP_TAC o SPEC ``(b - a) / &2:real``) THEN
15160  ASM_REWRITE_TAC[REAL_HALF, REAL_SUB_LT] THEN
15161  DISCH_THEN(X_CHOOSE_THEN ``u:real`` STRIP_ASSUME_TAC) THEN
15162  EXISTS_TAC ``min ((b - a) / &2:real) ((c - b) / &2:real)`` THEN
15163  ASM_REWRITE_TAC[REAL_HALF, REAL_SUB_LT, REAL_LT_MIN] THEN
15164  X_GEN_TAC ``w:real`` THEN CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
15165  UNDISCH_TAC ``is_interval s`` THEN DISCH_TAC THEN
15166  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [IS_INTERVAL]) THEN
15167  DISCH_THEN(MP_TAC o SPECL [``u:real``, ``v:real``, ``w:real``]) THEN
15168  ASM_REWRITE_TAC[] THEN FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
15169  ASM_REAL_ARITH_TAC);
15170
15171(* ------------------------------------------------------------------------- *)
15172(* Limit component bounds.                                                   *)
15173(* ------------------------------------------------------------------------- *)
15174
15175val LIM_COMPONENT_UBOUND = store_thm ("LIM_COMPONENT_UBOUND",
15176 ``!net:('a)net f (l:real) b k.
15177        ~(trivial_limit net) /\ (f --> l) net /\
15178        eventually (\x. f x <= b) net
15179        ==> l <= b``,
15180  REPEAT STRIP_TAC THEN MP_TAC(ISPECL
15181   [``net:('a)net``, ``f:'a->real``, ``{y:real | y <= b}``, ``l:real``]
15182   LIM_IN_CLOSED_SET) THEN
15183  ASM_SIMP_TAC std_ss [CLOSED_HALFSPACE_COMPONENT_LE, GSPECIFICATION]);
15184
15185val LIM_COMPONENT_LBOUND = store_thm ("LIM_COMPONENT_LBOUND",
15186 ``!net:('a)net f (l:real) b.
15187        ~(trivial_limit net) /\ (f --> l) net /\
15188        eventually (\x. b <= (f x)) net
15189        ==> b <= l``,
15190  REPEAT STRIP_TAC THEN MP_TAC(ISPECL
15191   [``net:('a)net``, ``f:'a->real``, ``{y:real | b <= y}``, ``l:real``]
15192   LIM_IN_CLOSED_SET) THEN
15193  ASM_SIMP_TAC std_ss [REWRITE_RULE[real_ge] CLOSED_HALFSPACE_COMPONENT_GE,
15194    GSPECIFICATION]);
15195
15196val LIM_COMPONENT_EQ = store_thm ("LIM_COMPONENT_EQ",
15197 ``!net f:'a->real i l b.
15198        (f --> l) net /\
15199        ~(trivial_limit net) /\ eventually (\x. f(x) = b) net
15200        ==> (l = b)``,
15201  SIMP_TAC std_ss [GSYM REAL_LE_ANTISYM, EVENTUALLY_AND] THEN
15202  METIS_TAC [LIM_COMPONENT_UBOUND, LIM_COMPONENT_LBOUND]);
15203
15204val LIM_COMPONENT_LE = store_thm ("LIM_COMPONENT_LE",
15205 ``!net:('a)net f:'a->real g:'a->real l m.
15206         ~(trivial_limit net) /\ (f --> l) net /\ (g --> m) net /\
15207        eventually (\x. (f x) <= (g x)) net
15208        ==> (l <= m)``,
15209  REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LE] THEN
15210  SIMP_TAC std_ss [LIM_COMPONENT_LBOUND] THEN
15211  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
15212  ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> b /\ a ==> c ==> d`] THEN
15213  DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN REPEAT STRIP_TAC THEN
15214  MATCH_MP_TAC LIM_COMPONENT_LBOUND THEN EXISTS_TAC ``net:'a net`` THEN
15215  EXISTS_TAC ``(\(x :'a). (g :'a -> real) x - (f :'a -> real) x)`` THEN
15216  METIS_TAC []);
15217
15218val LIM_DROP_LE = store_thm ("LIM_DROP_LE",
15219 ``!net:('a)net f g l m.
15220         ~(trivial_limit net) /\ (f --> l) net /\ (g --> m) net /\
15221        eventually (\x. f x <= g x) net
15222        ==> l <= m``,
15223  REPEAT STRIP_TAC THEN
15224  MATCH_MP_TAC(ISPEC ``net:('a)net`` LIM_COMPONENT_LE) THEN
15225  MAP_EVERY EXISTS_TAC [``f:'a->real``, ``g:'a->real``] THEN
15226  ASM_REWRITE_TAC[LESS_EQ_REFL]);
15227
15228val LIM_DROP_UBOUND = store_thm ("LIM_DROP_UBOUND",
15229 ``!net f:'a->real l b.
15230        (f --> l) net /\
15231        ~(trivial_limit net) /\ eventually (\x. f x <= b) net
15232        ==> l <= b``,
15233  REPEAT STRIP_TAC THEN
15234  MATCH_MP_TAC LIM_COMPONENT_UBOUND THEN
15235  REWRITE_TAC[LESS_EQ_REFL] THEN METIS_TAC[]);
15236
15237val LIM_DROP_LBOUND = store_thm ("LIM_DROP_LBOUND",
15238 ``!net f:'a->real l b.
15239        (f --> l) net /\
15240        ~(trivial_limit net) /\ eventually (\x. b <= f x) net
15241        ==> b <= l``,
15242  REPEAT STRIP_TAC THEN
15243  MATCH_MP_TAC LIM_COMPONENT_LBOUND THEN
15244  REWRITE_TAC[LESS_EQ_REFL] THEN METIS_TAC[]);
15245
15246(* ------------------------------------------------------------------------- *)
15247(* Also extending closed bounds to closures.                                 *)
15248(* ------------------------------------------------------------------------- *)
15249
15250val IMAGE_CLOSURE_SUBSET = store_thm ("IMAGE_CLOSURE_SUBSET",
15251 ``!f (s:real->bool) (t:real->bool).
15252      f continuous_on closure s /\ closed t /\ IMAGE f s SUBSET t
15253      ==> IMAGE f (closure s) SUBSET t``,
15254  REPEAT STRIP_TAC THEN
15255  SUBGOAL_THEN ``closure s SUBSET {x | (f:real->real) x IN t}`` MP_TAC
15256  THENL [MATCH_MP_TAC SUBSET_TRANS, SET_TAC []]  THEN
15257  EXISTS_TAC ``{x | x IN closure s /\ (f:real->real) x IN t}`` THEN
15258  CONJ_TAC THENL
15259  [MATCH_MP_TAC CLOSURE_MINIMAL, SET_TAC[]] THEN
15260  ASM_SIMP_TAC std_ss [CONTINUOUS_CLOSED_PREIMAGE, CLOSED_CLOSURE] THEN
15261  MP_TAC (ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[]);
15262
15263val CLOSURE_IMAGE_CLOSURE = store_thm ("CLOSURE_IMAGE_CLOSURE",
15264 ``!f:real->real s.
15265        f continuous_on closure s
15266        ==> (closure(IMAGE f (closure s)) = closure(IMAGE f s))``,
15267  REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
15268  SIMP_TAC std_ss [SUBSET_CLOSURE, IMAGE_SUBSET, CLOSURE_SUBSET] THEN
15269  SIMP_TAC std_ss [CLOSURE_MINIMAL_EQ, CLOSED_CLOSURE] THEN
15270  MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN
15271  ASM_REWRITE_TAC[CLOSED_CLOSURE, CLOSURE_SUBSET]);
15272
15273val CLOSURE_IMAGE_BOUNDED = store_thm ("CLOSURE_IMAGE_BOUNDED",
15274 ``!f:real->real s.
15275        f continuous_on closure s /\ bounded s
15276        ==> (closure(IMAGE f s) = IMAGE f (closure s))``,
15277  REPEAT STRIP_TAC THEN
15278  MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC ``closure(IMAGE (f:real->real) (closure s))`` THEN
15279  CONJ_TAC THENL [ASM_MESON_TAC[CLOSURE_IMAGE_CLOSURE], ALL_TAC] THEN
15280  MATCH_MP_TAC CLOSURE_CLOSED THEN MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
15281  MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
15282  ASM_REWRITE_TAC[COMPACT_CLOSURE]);
15283
15284val CONTINUOUS_ON_CLOSURE_ABS_LE = store_thm ("CONTINUOUS_ON_CLOSURE_ABS_LE",
15285 ``!f:real->real s x b.
15286      f continuous_on (closure s) /\
15287      (!y. y IN s ==> abs(f y) <= b) /\
15288      x IN (closure s)
15289      ==> abs(f x) <= b``,
15290  REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN
15291  SUBGOAL_THEN ``IMAGE (f:real->real) (closure s) SUBSET cball(0,b)``
15292    MP_TAC THENL
15293  [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET, ASM_SET_TAC []] THEN
15294  ASM_REWRITE_TAC [CLOSED_CBALL] THEN ASM_SET_TAC []);
15295
15296val CONTINUOUS_ON_CLOSURE_COMPONENT_LE = store_thm ("CONTINUOUS_ON_CLOSURE_COMPONENT_LE",
15297 ``!f:real->real s x b.
15298      f continuous_on (closure s) /\
15299      (!y. y IN s ==> (f y) <= b) /\
15300      x IN (closure s)
15301      ==> (f x) <= b``,
15302  REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN
15303  SUBGOAL_THEN ``IMAGE (f:real->real) (closure s) SUBSET {x | x <= b}``
15304  MP_TAC THENL
15305   [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET, ASM_SET_TAC []] THEN
15306  ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE] THEN ASM_SET_TAC[]);
15307
15308val CONTINUOUS_ON_CLOSURE_COMPONENT_GE = store_thm ("CONTINUOUS_ON_CLOSURE_COMPONENT_GE",
15309 ``!f:real->real s x b.
15310      f continuous_on (closure s) /\
15311      (!y. y IN s ==> b <= (f y)) /\
15312      x IN (closure s)
15313      ==> b <= (f x)``,
15314  REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN
15315  SUBGOAL_THEN ``IMAGE (f:real->real) (closure s) SUBSET {x | x >= b}``
15316  MP_TAC THENL
15317   [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET, ASM_SET_TAC [real_ge]] THEN
15318  ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_GE] THEN ASM_SET_TAC[real_ge]);
15319
15320val CONTINUOUS_MAP_CLOSURES = store_thm ("CONTINUOUS_MAP_CLOSURES",
15321 ``!f:real->real.
15322        f continuous_on UNIV <=>
15323        !s. IMAGE f (closure s) SUBSET closure(IMAGE f s)``,
15324  GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL
15325   [GEN_TAC THEN MATCH_MP_TAC(MESON[SUBSET_DEF, CLOSURE_SUBSET]
15326     ``(closure s = t) ==> s SUBSET t``) THEN
15327    MATCH_MP_TAC CLOSURE_IMAGE_CLOSURE THEN
15328    ASM_MESON_TAC[CONTINUOUS_ON_SUBSET, SUBSET_UNIV],
15329    REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN
15330    REWRITE_TAC[GSYM CLOSED_IN, SUBTOPOLOGY_UNIV, IN_UNIV] THEN
15331    X_GEN_TAC ``t:real->bool`` THEN DISCH_TAC THEN
15332    FIRST_X_ASSUM(MP_TAC o SPEC ``{x | (f:real->real) x IN t}``) THEN
15333    REWRITE_TAC[GSYM CLOSURE_SUBSET_EQ] THEN
15334    SUBGOAL_THEN
15335     ``closure(IMAGE (f:real->real) {x | f x IN t}) SUBSET t``
15336    MP_TAC THENL
15337     [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SET_TAC[], SET_TAC[]]]);
15338
15339(* ------------------------------------------------------------------------- *)
15340(* Limits relative to a union.                                               *)
15341(* ------------------------------------------------------------------------- *)
15342
15343val LIM_WITHIN_UNION = store_thm ("LIM_WITHIN_UNION",
15344 ``(f --> l) (at x within (s UNION t)) <=>
15345   (f --> l) (at x within s) /\ (f --> l) (at x within t)``,
15346  SIMP_TAC std_ss [LIM_WITHIN, IN_UNION, GSYM FORALL_AND_THM] THEN
15347  AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``e:real`` THEN
15348  ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [] THEN
15349  EQ_TAC THENL [MESON_TAC[], ALL_TAC] THEN DISCH_THEN
15350   (CONJUNCTS_THEN2 (X_CHOOSE_TAC ``d:real``) (X_CHOOSE_TAC ``k:real``)) THEN
15351  EXISTS_TAC ``min d k:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
15352  ASM_MESON_TAC[]);
15353
15354val CONTINUOUS_ON_UNION = store_thm ("CONTINUOUS_ON_UNION",
15355 ``!f s t. closed s /\ closed t /\ f continuous_on s /\ f continuous_on t
15356           ==> f continuous_on (s UNION t)``,
15357  REWRITE_TAC[CONTINUOUS_ON, CLOSED_LIMPT, IN_UNION, LIM_WITHIN_UNION] THEN
15358  MESON_TAC[LIM, TRIVIAL_LIMIT_WITHIN]);
15359
15360val CONTINUOUS_ON_CASES = store_thm ("CONTINUOUS_ON_CASES",
15361 ``!P f g:real->real s t.
15362        closed s /\ closed t /\ f continuous_on s /\ g continuous_on t /\
15363        (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> (f x = g x))
15364        ==> (\x. if P x then f x else g x) continuous_on (s UNION t)``,
15365  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION THEN
15366  ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL
15367   [EXISTS_TAC ``f:real->real``, EXISTS_TAC ``g:real->real``] THEN
15368  METIS_TAC[]);
15369
15370val CONTINUOUS_ON_UNION_LOCAL = store_thm ("CONTINUOUS_ON_UNION_LOCAL",
15371 ``!f:real->real s.
15372        closed_in (subtopology euclidean (s UNION t)) s /\
15373        closed_in (subtopology euclidean (s UNION t)) t /\
15374        f continuous_on s /\ f continuous_on t
15375        ==> f continuous_on (s UNION t)``,
15376  REWRITE_TAC[CONTINUOUS_ON, CLOSED_IN_LIMPT, IN_UNION, LIM_WITHIN_UNION] THEN
15377  MESON_TAC[LIM, TRIVIAL_LIMIT_WITHIN]);
15378
15379val CONTINUOUS_ON_CASES_LOCAL = store_thm ("CONTINUOUS_ON_CASES_LOCAL",
15380 ``!P f g:real->real s t.
15381        closed_in (subtopology euclidean (s UNION t)) s /\
15382        closed_in (subtopology euclidean (s UNION t)) t /\
15383        f continuous_on s /\ g continuous_on t /\
15384        (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> (f x = g x))
15385        ==> (\x. if P x then f x else g x) continuous_on (s UNION t)``,
15386  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL THEN
15387  ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL
15388   [EXISTS_TAC ``f:real->real``, EXISTS_TAC ``g:real->real``] THEN
15389  METIS_TAC[]);
15390
15391val CONTINUOUS_ON_CASES_LE = store_thm ("CONTINUOUS_ON_CASES_LE",
15392 ``!f g:real->real h s a.
15393        f continuous_on {t | t IN s /\ h t <= a} /\
15394        g continuous_on {t | t IN s /\ a <= h t} /\
15395        (h) continuous_on s /\
15396        (!t. t IN s /\ (h t = a) ==> (f t = g t))
15397        ==> (\t. if h t <= a then f(t) else g(t)) continuous_on s``,
15398  REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC
15399   ``{t | t IN s /\ (h:real->real) t <= a} UNION
15400     {t | t IN s /\ a <= h t}`` THEN
15401  CONJ_TAC THENL
15402   [ALL_TAC, SIMP_TAC std_ss [SUBSET_DEF, IN_UNION, GSPECIFICATION, REAL_LE_TOTAL]] THEN
15403  ONCE_REWRITE_TAC [METIS [] ``h t <= a <=> (\t:real. h t <= a:real) t``] THEN
15404  MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN ASM_SIMP_TAC std_ss [] THEN
15405  SIMP_TAC std_ss [GSPECIFICATION, GSYM CONJ_ASSOC, REAL_LE_ANTISYM] THEN
15406  REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL
15407   [ALL_TAC, METIS_TAC[]] THEN
15408  CONJ_TAC THENL
15409   [SUBGOAL_THEN
15410     ``{t | t IN s /\ (h:real->real) t <= a} =
15411       {t | t IN ({t | t IN s /\ h t <= a} UNION {t | t IN s /\ a <= h t}) /\
15412           (h) t IN {x | x <= a}}``
15413     (fn th => GEN_REWR_TAC RAND_CONV [th])
15414    THENL
15415     [SIMP_TAC std_ss [o_THM, GSPECIFICATION, EXTENSION, IN_UNION] THEN
15416      GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC std_ss [],
15417      MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN
15418      ASM_SIMP_TAC std_ss [CLOSED_HALFSPACE_COMPONENT_LE, ETA_AX] THEN
15419      FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP]
15420        CONTINUOUS_ON_SUBSET)) THEN SET_TAC[]],
15421    SUBGOAL_THEN
15422     ``{t | t IN s /\ a <= (h:real->real) t} =
15423       {t | t IN ({t | t IN s /\ h t <= a} UNION {t | t IN s /\ a <= h t}) /\
15424           (h) t IN {x | x >= a}}``
15425     (fn th => GEN_REWR_TAC RAND_CONV [th])
15426    THENL
15427     [SIMP_TAC std_ss [o_THM, GSPECIFICATION, EXTENSION, IN_UNION] THEN
15428      GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC std_ss [real_ge] THEN
15429      ASM_REAL_ARITH_TAC,
15430      MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN
15431      ASM_SIMP_TAC std_ss [CLOSED_HALFSPACE_COMPONENT_GE, ETA_AX] THEN
15432      FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP]
15433        CONTINUOUS_ON_SUBSET)) THEN
15434      SET_TAC[]]]);
15435
15436val CONTINUOUS_ON_CASES_1 = store_thm ("CONTINUOUS_ON_CASES_1",
15437 ``!f g:real->real s a.
15438        f continuous_on {t | t IN s /\ t <= a} /\
15439        g continuous_on {t | t IN s /\ a <= t} /\
15440        (a IN s ==> (f(a) = g(a)))
15441        ==> (\t. if t <= a then f(t) else g(t)) continuous_on s``,
15442  REPEAT STRIP_TAC THEN
15443  ONCE_REWRITE_TAC [METIS [] ``t <= a <=> (\t. t) t <= a:real``] THEN
15444  MATCH_MP_TAC CONTINUOUS_ON_CASES_LE THEN
15445  ASM_SIMP_TAC std_ss [o_DEF, CONTINUOUS_ON_ID] THEN
15446  METIS_TAC[]);
15447
15448val EXTENSION_FROM_CLOPEN = store_thm ("EXTENSION_FROM_CLOPEN",
15449 ``!f:real->real s t u.
15450        open_in (subtopology euclidean s) t /\
15451        closed_in (subtopology euclidean s) t /\
15452        f continuous_on t /\ IMAGE f t SUBSET u /\ ((u = {}) ==> (s = {}))
15453        ==> ?g. g continuous_on s /\ IMAGE g s SUBSET u /\
15454                !x. x IN t ==> (g x = f x)``,
15455  REPEAT GEN_TAC THEN ASM_CASES_TAC ``u:real->bool = {}`` THEN
15456  ASM_SIMP_TAC std_ss [CONTINUOUS_ON_EMPTY, IMAGE_EMPTY, IMAGE_INSERT, SUBSET_EMPTY,
15457               IMAGE_EQ_EMPTY, NOT_IN_EMPTY] THEN
15458  STRIP_TAC THEN UNDISCH_TAC ``u <> {}:real->bool`` THEN DISCH_TAC THEN
15459  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
15460  DISCH_THEN(X_CHOOSE_TAC ``a:real``) THEN
15461  EXISTS_TAC ``\x. if x IN t then (f:real->real) x else a`` THEN
15462  SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE] THEN
15463  CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
15464  FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
15465  SUBGOAL_THEN ``s:real->bool = t UNION (s DIFF t)`` SUBST1_TAC THENL
15466   [ASM_SET_TAC[],
15467    ONCE_REWRITE_TAC [METIS [] ``(\x. if x IN t then f x else a) =
15468                                 (\x. if (\x. x IN t) x then f x else (\x. a) x)``] THEN
15469    MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL] THEN
15470  ASM_SIMP_TAC std_ss [SET_RULE ``t SUBSET s ==> (t UNION (s DIFF t) = s)``] THEN
15471  REWRITE_TAC[CONTINUOUS_ON_CONST, IN_DIFF] THEN
15472  CONJ_TAC THENL [MATCH_MP_TAC CLOSED_IN_DIFF, MESON_TAC[]] THEN
15473  ASM_REWRITE_TAC[CLOSED_IN_REFL]);
15474
15475(* ------------------------------------------------------------------------- *)
15476(* Some more convenient intermediate-value theorem formulations.             *)
15477(* ------------------------------------------------------------------------- *)
15478
15479val CONNECTED_IVT_HYPERPLANE = store_thm ("CONNECTED_IVT_HYPERPLANE",
15480 ``!s x y:real a b.
15481        connected s /\
15482        x IN s /\ y IN s /\ a * x <= b /\ b <= a * y
15483        ==> ?z. z IN s /\ (a * z = b)``,
15484  REPEAT STRIP_TAC THEN
15485  UNDISCH_TAC ``connected s`` THEN DISCH_TAC THEN
15486  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [connected]) THEN
15487  SIMP_TAC std_ss [NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o SPECL
15488   [``{x:real | a * x < b}``, ``{x:real | a * x > b}``]) THEN
15489  SIMP_TAC std_ss [OPEN_HALFSPACE_LT, OPEN_HALFSPACE_GT] THEN
15490  ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN SIMP_TAC std_ss [] THEN STRIP_TAC THEN
15491  SIMP_TAC real_ss [EXTENSION, GSPECIFICATION, IN_INTER, NOT_IN_EMPTY, SUBSET_DEF,
15492              IN_UNION, REAL_LT_LE, real_gt] THEN
15493  METIS_TAC[REAL_LE_TOTAL, REAL_LE_ANTISYM]);
15494
15495val CONNECTED_IVT_COMPONENT = store_thm ("CONNECTED_IVT_COMPONENT",
15496 ``!s x y:real a.
15497        connected s /\ x IN s /\ y IN s /\ x <= a /\ a <= y
15498        ==> ?z. z IN s /\ (z = a)``,
15499  REPEAT STRIP_TAC THEN MP_TAC(ISPECL
15500   [``s:real->bool``, ``x:real``, ``y:real``, ``1:real``,
15501    ``a:real``] CONNECTED_IVT_HYPERPLANE) THEN
15502  ASM_SIMP_TAC std_ss [REAL_MUL_LID]);
15503
15504(* ------------------------------------------------------------------------- *)
15505(* Rather trivial observation that we can map any connected set on segment.  *)
15506(* ------------------------------------------------------------------------- *)
15507
15508val MAPPING_CONNECTED_ONTO_SEGMENT = store_thm ("MAPPING_CONNECTED_ONTO_SEGMENT",
15509 ``!s:real->bool a b:real.
15510        connected s /\ ~(?a. s SUBSET {a})
15511        ==> ?f. f continuous_on s /\ (IMAGE f s = segment[a,b])``,
15512  REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE
15513   ``~(?a. s SUBSET {a}) ==> ?a b. a IN s /\ b IN s /\ ~(a = b)``)) THEN
15514  SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN
15515  MAP_EVERY X_GEN_TAC [``u:real``, ``v:real``] THEN STRIP_TAC THEN EXISTS_TAC
15516   ``\x:real. a + dist(u,x) / (dist(u,x) + dist(v,x)) * (b - a:real)`` THEN
15517  CONJ_TAC THEN SIMP_TAC std_ss [] THENL
15518   [ONCE_REWRITE_TAC [METIS []
15519     ``(\x. a + dist (u,x) / (dist (u,x) + dist (v,x)) * (b - a)) =
15520       (\x. (\x. a) x + (\x. dist (u,x) / (dist (u,x) + dist (v,x)) * (b - a)) x)``] THEN
15521    MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
15522    ONCE_REWRITE_TAC [METIS []
15523    ``(\x. dist (u,x) / (dist (u,x) + dist (v,x)) * (b - a)) =
15524      (\x. (\x. dist (u,x) / (dist (u,x) + dist (v,x))) x * (\x. (b - a)) x)``] THEN
15525    MATCH_MP_TAC CONTINUOUS_ON_MUL THEN SIMP_TAC std_ss [o_DEF, CONTINUOUS_ON_CONST],
15526
15527    REWRITE_TAC[segment, REAL_ARITH
15528     ``(&1 - u) * a + u * b:real = a + u * (b - a)``] THEN
15529    ONCE_REWRITE_TAC [METIS []
15530    ``(\x. a + dist (u,x) / (dist (u,x) + dist (v,x)) * (b - a)) =
15531      (\x. a + (\x. dist (u,x) / (dist (u,x) + dist (v,x))) x * (b - a))``] THEN
15532    ONCE_REWRITE_TAC [METIS [] ``(0 <= u /\ u <= 1:real) <=> (\u. 0 <= u /\ u <= 1) u``] THEN
15533    MATCH_MP_TAC(SET_RULE
15534     ``(IMAGE f s = {x | P x})
15535      ==> (IMAGE (\x. a + f x * b) s = {a + u * b:real | P u})``) THEN
15536    SIMP_TAC std_ss [GSYM SUBSET_ANTISYM_EQ, SUBSET_DEF, FORALL_IN_IMAGE] THEN
15537    ASM_SIMP_TAC real_ss [dist, GSPECIFICATION, REAL_LE_RDIV_EQ, REAL_LE_LDIV_EQ,
15538      REAL_ARITH ``~(u:real = v) ==> &0 < abs(u - x) + abs(v - x)``] THEN
15539    CONJ_TAC THENL [REAL_ARITH_TAC, REWRITE_TAC[IN_IMAGE]] THEN
15540    X_GEN_TAC ``t:real`` THEN STRIP_TAC THEN
15541    MP_TAC(ISPECL
15542     [``IMAGE (\x:real. dist(u,x) / (dist(u,x) + dist(v,x))) s``,
15543      ``0:real``, ``1:real``, ``t:real``]
15544        CONNECTED_IVT_COMPONENT) THEN
15545    ASM_SIMP_TAC arith_ss [] THEN
15546    SIMP_TAC std_ss [EXISTS_IN_IMAGE] THEN
15547    KNOW_TAC ``connected
15548   (IMAGE
15549      (\(x :real).
15550         (dist ((u :real),x) :real) /
15551         ((dist (u,x) :real) + (dist ((v :real),x) :real)))
15552      (s :real -> bool)) /\
15553 (0 :real) IN
15554 IMAGE
15555   (\(x :real).
15556      (dist (u,x) :real) / ((dist (u,x) :real) + (dist (v,x) :real)))
15557   s /\
15558 (1 :real) IN
15559 IMAGE
15560   (\(x :real).
15561      (dist (u,x) :real) / ((dist (u,x) :real) + (dist (v,x) :real)))
15562   s`` THENL
15563   [REWRITE_TAC[IN_IMAGE], DISCH_TAC THEN ASM_REWRITE_TAC [IN_IMAGE] THEN
15564    BETA_TAC THEN MESON_TAC[dist]] THEN
15565    REPEAT CONJ_TAC THENL
15566     [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[],
15567      EXISTS_TAC ``u:real`` THEN ASM_REWRITE_TAC[DIST_REFL, real_div, dist] THEN
15568      BETA_TAC THEN REAL_ARITH_TAC,
15569      EXISTS_TAC ``v:real`` THEN ASM_REWRITE_TAC[DIST_REFL] THEN
15570      ASM_SIMP_TAC std_ss [REAL_DIV_REFL, DIST_EQ_0, REAL_ADD_RID] THEN
15571      RULE_ASSUM_TAC (ONCE_REWRITE_RULE
15572       [REAL_ARITH ``(u <> v) = (abs (u - v) <> 0:real)``]) THEN
15573      ASM_SIMP_TAC real_ss [REAL_DIV_REFL]]] THEN
15574  REWRITE_TAC[real_div] THENL
15575  [ONCE_REWRITE_TAC [METIS [] ``(\x. dist (u,x) * inv (dist (u,x) + dist (v,x))) =
15576                  (\x. (\x. dist (u,x)) x * (\x. inv (dist (u,x) + dist (v,x))) x)``] THEN
15577  MATCH_MP_TAC CONTINUOUS_ON_MUL THEN
15578  REWRITE_TAC[CONTINUOUS_ON_DIST] THEN
15579  ONCE_REWRITE_TAC [METIS [] ``(\x. inv (dist (u,x) + dist (v,x))) =
15580                          (\x. inv ((\x. (dist (u,x) + dist (v,x))) x))``] THEN
15581  MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN
15582  ASM_SIMP_TAC std_ss [dist, REAL_ARITH
15583   ``~(u:real = v) ==> ~(abs(u - x) + abs(v - x) = &0)``] THEN
15584  ONCE_REWRITE_TAC [METIS [] ``(\x:real. abs (u - x) + abs (v - x)) =
15585                       (\x. (\x. abs (u - x)) x + (\x. abs (v - x)) x)``] THEN
15586  MATCH_MP_TAC CONTINUOUS_ON_ADD THEN
15587  SIMP_TAC std_ss [GSYM dist, REWRITE_RULE[o_DEF] CONTINUOUS_ON_DIST],
15588   ONCE_REWRITE_TAC [METIS [] ``(\x. dist (u,x) * inv (dist (u,x) + dist (v,x))) =
15589                  (\x. (\x. dist (u,x)) x * (\x. inv (dist (u,x) + dist (v,x))) x)``] THEN
15590  MATCH_MP_TAC CONTINUOUS_ON_MUL THEN
15591  REWRITE_TAC[CONTINUOUS_ON_DIST] THEN
15592  ONCE_REWRITE_TAC [METIS [] ``(\x. inv (dist (u,x) + dist (v,x))) =
15593                          (\x. inv ((\x. (dist (u,x) + dist (v,x))) x))``] THEN
15594  MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN
15595  ASM_SIMP_TAC std_ss [dist, REAL_ARITH
15596   ``~(u:real = v) ==> ~(abs(u - x) + abs(v - x) = &0)``] THEN
15597  ONCE_REWRITE_TAC [METIS [] ``(\x:real. abs (u - x) + abs (v - x)) =
15598                       (\x. (\x. abs (u - x)) x + (\x. abs (v - x)) x)``] THEN
15599  MATCH_MP_TAC CONTINUOUS_ON_ADD THEN
15600  SIMP_TAC std_ss [GSYM dist, REWRITE_RULE[o_DEF] CONTINUOUS_ON_DIST],
15601  ALL_TAC] THEN
15602  FULL_SIMP_TAC std_ss [GSYM dist, DIST_REFL, REAL_ADD_RID] THEN
15603  REWRITE_TAC [GSYM real_div] THEN METIS_TAC [REAL_DIV_REFL]);
15604
15605(* ------------------------------------------------------------------------- *)
15606(* Also more convenient formulations of monotone convergence.                *)
15607(* ------------------------------------------------------------------------- *)
15608
15609val BOUNDED_INCREASING_CONVERGENT = store_thm ("BOUNDED_INCREASING_CONVERGENT",
15610 ``!s:num->real.
15611        bounded {s n | n IN univ(:num)} /\ (!n. (s n) <= (s(SUC n)))
15612        ==> ?l. (s --> l) sequentially``,
15613  GEN_TAC THEN
15614  SIMP_TAC std_ss [bounded_def, GSPECIFICATION, LIM_SEQUENTIALLY, dist,
15615              IN_UNIV] THEN
15616  DISCH_TAC THEN MATCH_MP_TAC CONVERGENT_BOUNDED_MONOTONE THEN
15617  SIMP_TAC std_ss [LEFT_EXISTS_AND_THM] THEN
15618  CONJ_TAC THENL [METIS_TAC[], ALL_TAC] THEN DISJ1_TAC THEN
15619  ONCE_REWRITE_TAC [METIS [] ``!m n. ((s:num->real) m <= s n) = (\m n. s m <= s n) m n``] THEN
15620  MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
15621  METIS_TAC [REAL_LE_TRANS, REAL_LE_REFL]);
15622
15623val BOUNDED_DECREASING_CONVERGENT = store_thm ("BOUNDED_DECREASING_CONVERGENT",
15624 ``!s:num->real.
15625        bounded {s n | n IN univ(:num)} /\ (!n. (s(SUC n)) <= (s(n)))
15626        ==> ?l. (s --> l) sequentially``,
15627  GEN_TAC THEN SIMP_TAC std_ss [bounded_def, FORALL_IN_GSPEC] THEN
15628  DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
15629  MP_TAC(ISPEC ``\n. -((s:num->real) n)`` BOUNDED_INCREASING_CONVERGENT) THEN
15630  ASM_SIMP_TAC std_ss [bounded_def, FORALL_IN_GSPEC, ABS_NEG, REAL_LE_NEG2] THEN
15631  GEN_REWR_TAC (LAND_CONV o BINDER_CONV) [GSYM LIM_NEG_EQ] THEN
15632  SIMP_TAC std_ss [REAL_NEG_NEG, ETA_AX] THEN METIS_TAC[]);
15633
15634(* ------------------------------------------------------------------------- *)
15635(* Basic homeomorphism definitions.                                          *)
15636(* ------------------------------------------------------------------------- *)
15637
15638val homeomorphism = new_definition ("homeomorphism",
15639  ``homeomorphism (s,t) (f,g) <=>
15640     (!x. x IN s ==> (g(f(x)) = x)) /\ (IMAGE f s = t) /\ f continuous_on s /\
15641     (!y. y IN t ==> (f(g(y)) = y)) /\ (IMAGE g t = s) /\ g continuous_on t``);
15642
15643val _ = set_fixity "homeomorphic" (Infix(NONASSOC, 450));
15644
15645val homeomorphic = new_definition ("homeomorphic",
15646  ``s homeomorphic t <=> ?f g. homeomorphism (s,t) (f,g)``);
15647
15648val HOMEOMORPHISM = store_thm ("HOMEOMORPHISM",
15649 ``!s:real->bool t:real->bool f g.
15650        homeomorphism (s,t) (f,g) <=>
15651         f continuous_on s /\ IMAGE f s SUBSET t /\
15652         g continuous_on t /\ IMAGE g t SUBSET s /\
15653         (!x. x IN s ==> (g (f x) = x)) /\
15654         (!y. y IN t ==> (f (g y) = y))``,
15655  REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphism] THEN
15656  EQ_TAC THEN SIMP_TAC std_ss [] THEN SET_TAC[]);
15657
15658val HOMEOMORPHISM_OF_SUBSETS = store_thm ("HOMEOMORPHISM_OF_SUBSETS",
15659 ``!f g s t s' t'.
15660    homeomorphism (s,t) (f,g) /\ s' SUBSET s /\ t' SUBSET t /\ (IMAGE f s' = t')
15661    ==> homeomorphism (s',t') (f,g)``,
15662  REWRITE_TAC[homeomorphism] THEN
15663  REPEAT STRIP_TAC THEN
15664  TRY(MATCH_MP_TAC CONTINUOUS_ON_SUBSET) THEN ASM_SET_TAC[]);
15665
15666val HOMEOMORPHISM_ID = store_thm ("HOMEOMORPHISM_ID",
15667 ``!s:real->bool. homeomorphism (s,s) ((\x. x),(\x. x))``,
15668  SIMP_TAC std_ss [homeomorphism, IMAGE_ID, CONTINUOUS_ON_ID]);
15669
15670val HOMEOMORPHIC_REFL = store_thm ("HOMEOMORPHIC_REFL",
15671 ``!s:real->bool. s homeomorphic s``,
15672  REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_ID]);
15673
15674val HOMEOMORPHISM_SYM = store_thm ("HOMEOMORPHISM_SYM",
15675 ``!f:real->real g s t.
15676        homeomorphism (s,t) (f,g) <=> homeomorphism (t,s) (g,f)``,
15677  REWRITE_TAC[homeomorphism] THEN MESON_TAC[]);
15678
15679val HOMEOMORPHIC_SYM = store_thm ("HOMEOMORPHIC_SYM",
15680 ``!s t. s homeomorphic t <=> t homeomorphic s``,
15681  REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic, homeomorphism] THEN
15682  ONCE_REWRITE_TAC [METIS []
15683       ``((!x. x IN t ==> (g (f x) = x)) /\ (IMAGE f t = s) /\
15684     f continuous_on t /\ (!y. y IN s ==> (f (g y) = y)) /\
15685     (IMAGE g s = t) /\ g continuous_on s) =
15686   (\f g. (!x. x IN t ==> (g (f x) = x)) /\ (IMAGE f t = s) /\
15687     f continuous_on t /\ (!y. y IN s ==> (f (g y) = y)) /\
15688     (IMAGE g s = t) /\ g continuous_on s) f g``] THEN
15689  GEN_REWR_TAC RAND_CONV [SWAP_EXISTS_THM] THEN
15690  REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN SIMP_TAC std_ss [] THEN
15691  TAUT_TAC);
15692
15693val HOMEOMORPHISM_COMPOSE = store_thm ("HOMEOMORPHISM_COMPOSE",
15694 ``!f:real->real g h:real->real k s t u.
15695        homeomorphism (s,t) (f,g) /\ homeomorphism (t,u) (h,k)
15696        ==> homeomorphism (s,u) (h o f,g o k)``,
15697  SIMP_TAC std_ss [homeomorphism, CONTINUOUS_ON_COMPOSE, IMAGE_COMPOSE, o_THM] THEN
15698  SET_TAC[]);
15699
15700val HOMEOMORPHIC_TRANS = store_thm ("HOMEOMORPHIC_TRANS",
15701 ``!s:real->bool t:real->bool u:real->bool.
15702        s homeomorphic t /\ t homeomorphic u ==> s homeomorphic u``,
15703  REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_COMPOSE]);
15704
15705val HOMEOMORPHIC_IMP_CARD_EQ = store_thm ("HOMEOMORPHIC_IMP_CARD_EQ",
15706 ``!s:real->bool t:real->bool. s homeomorphic t ==> s =_c t``,
15707  REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic, homeomorphism, eq_c] THEN
15708  STRIP_TAC THEN EXISTS_TAC ``f:real->real`` THEN ASM_SET_TAC []);
15709
15710val HOMEOMORPHIC_FINITENESS = store_thm ("HOMEOMORPHIC_FINITENESS",
15711 ``!s:real->bool t:real->bool.
15712        s homeomorphic t ==> (FINITE s <=> FINITE t)``,
15713  REPEAT GEN_TAC THEN
15714  DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN
15715  DISCH_THEN(ACCEPT_TAC o MATCH_MP CARD_FINITE_CONG));
15716
15717val HOMEOMORPHIC_EMPTY = store_thm ("HOMEOMORPHIC_EMPTY",
15718 ``(!s. (s:real->bool) homeomorphic ({}:real->bool) <=> (s = {})) /\
15719   (!s. ({}:real->bool) homeomorphic (s:real->bool) <=> (s = {}))``,
15720  REWRITE_TAC[homeomorphic, homeomorphism, IMAGE_EMPTY, IMAGE_INSERT, IMAGE_EQ_EMPTY] THEN
15721  REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN
15722  ASM_SIMP_TAC std_ss [continuous_on, NOT_IN_EMPTY]);
15723
15724val HOMEOMORPHIC_MINIMAL = store_thm ("HOMEOMORPHIC_MINIMAL",
15725 ``!s t. s homeomorphic t <=>
15726            ?f g. (!x. x IN s ==> f(x) IN t /\ (g(f(x)) = x)) /\
15727                  (!y. y IN t ==> g(y) IN s /\ (f(g(y)) = y)) /\
15728                  f continuous_on s /\ g continuous_on t``,
15729  REWRITE_TAC[homeomorphic, homeomorphism, EXTENSION, IN_IMAGE] THEN
15730  REPEAT GEN_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN MESON_TAC[]);
15731
15732val HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF = store_thm ("HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF",
15733 ``!f:real->real s.
15734        linear f /\ (!x y. (f x = f y) ==> (x = y))
15735        ==> (IMAGE f s) homeomorphic s``,
15736  REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
15737  FIRST_ASSUM(MP_TAC o REWRITE_RULE [INJECTIVE_LEFT_INVERSE]) THEN
15738  STRIP_TAC THEN EXISTS_TAC ``g:real->real`` THEN
15739  EXISTS_TAC ``f:real->real`` THEN
15740  ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON, FORALL_IN_IMAGE, FUN_IN_IMAGE] THEN
15741  ASM_SIMP_TAC std_ss [continuous_on, CONJ_EQ_IMP, FORALL_IN_IMAGE] THEN
15742  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
15743  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
15744  MP_TAC(ISPEC ``f:real->real`` LINEAR_INJECTIVE_BOUNDED_BELOW_POS) THEN
15745  ASM_REWRITE_TAC[] THEN
15746  DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN
15747  EXISTS_TAC ``e * B:real`` THEN ASM_SIMP_TAC real_ss [REAL_LT_MUL] THEN
15748  X_GEN_TAC ``y:real`` THEN ASM_SIMP_TAC std_ss [dist, GSYM LINEAR_SUB] THEN
15749  DISCH_TAC THEN ASM_SIMP_TAC real_ss [GSYM REAL_LT_LDIV_EQ] THEN
15750  MATCH_MP_TAC(REAL_ARITH ``a <= b ==> b < x ==> a < x:real``) THEN
15751  ASM_SIMP_TAC real_ss [REAL_LE_RDIV_EQ]);
15752
15753val HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ = store_thm ("HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ",
15754 ``!f:real->real s t.
15755        linear f /\ (!x y. (f x = f y) ==> (x = y))
15756        ==> ((IMAGE f s) homeomorphic t <=> s homeomorphic t)``,
15757  REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o SPEC ``s:real->bool`` o
15758    MATCH_MP HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF) THEN
15759  EQ_TAC THENL
15760   [FIRST_X_ASSUM(MP_TAC o ONCE_REWRITE_RULE [HOMEOMORPHIC_SYM]),
15761    POP_ASSUM MP_TAC] THEN
15762  METIS_TAC[AND_IMP_INTRO, HOMEOMORPHIC_TRANS]);
15763
15764val HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ = store_thm ("HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ",
15765 ``!f:real->real s t.
15766        linear f /\ (!x y. (f x = f y) ==> (x = y))
15767        ==> (s homeomorphic (IMAGE f t) <=> s homeomorphic t)``,
15768  ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN
15769  REWRITE_TAC[HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ]);
15770
15771val HOMEOMORPHIC_TRANSLATION_SELF = store_thm ("HOMEOMORPHIC_TRANSLATION_SELF",
15772 ``!a:real s. (IMAGE (\x. a + x) s) homeomorphic s``,
15773  REPEAT GEN_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
15774  EXISTS_TAC ``\x:real. x - a`` THEN
15775  EXISTS_TAC ``\x:real. a + x`` THEN
15776  SIMP_TAC std_ss [FORALL_IN_IMAGE, CONTINUOUS_ON_SUB, CONTINUOUS_ON_ID,
15777           CONTINUOUS_ON_CONST, CONTINUOUS_ON_ADD, REAL_ADD_SUB] THEN
15778  REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[]);
15779
15780val HOMEOMORPHIC_TRANSLATION_LEFT_EQ = store_thm ("HOMEOMORPHIC_TRANSLATION_LEFT_EQ",
15781 ``!a:real s t.
15782      (IMAGE (\x. a + x) s) homeomorphic t <=> s homeomorphic t``,
15783  METIS_TAC[HOMEOMORPHIC_TRANSLATION_SELF,
15784            HOMEOMORPHIC_SYM, HOMEOMORPHIC_TRANS]);
15785
15786val HOMEOMORPHIC_TRANSLATION_RIGHT_EQ = store_thm ("HOMEOMORPHIC_TRANSLATION_RIGHT_EQ",
15787 ``!a:real s t.
15788      s homeomorphic (IMAGE (\x. a + x) t) <=> s homeomorphic t``,
15789  ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN
15790  REWRITE_TAC[HOMEOMORPHIC_TRANSLATION_LEFT_EQ]);
15791
15792val HOMEOMORPHISM_IMP_QUOTIENT_MAP = store_thm ("HOMEOMORPHISM_IMP_QUOTIENT_MAP",
15793 ``!f:real->real g s t.
15794    homeomorphism (s,t) (f,g)
15795    ==> !u. u SUBSET t
15796            ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
15797                 open_in (subtopology euclidean t) u)``,
15798  REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphism] THEN
15799  STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN
15800  EXISTS_TAC ``g:real->real`` THEN ASM_REWRITE_TAC[SUBSET_REFL]);
15801
15802val HOMEOMORPHIC_SCALING_LEFT = store_thm ("HOMEOMORPHIC_SCALING_LEFT",
15803 ``!c. &0 < c
15804       ==> (!s t. (IMAGE (\x. c * x) s) homeomorphic t <=> s homeomorphic t)``,
15805  SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
15806  MATCH_MP_TAC HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ THEN
15807  ASM_SIMP_TAC std_ss [REAL_EQ_LMUL, REAL_LT_IMP_NE, LINEAR_SCALING]);
15808
15809val HOMEOMORPHIC_SCALING_RIGHT = store_thm ("HOMEOMORPHIC_SCALING_RIGHT",
15810 ``!c. &0 < c
15811       ==> (!s t. s homeomorphic (IMAGE (\x. c * x) t) <=> s homeomorphic t)``,
15812  SIMP_TAC std_ss [RIGHT_IMP_FORALL_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
15813  MATCH_MP_TAC HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ THEN
15814  ASM_SIMP_TAC std_ss [REAL_EQ_LMUL, REAL_LT_IMP_NE, LINEAR_SCALING]);
15815
15816val HOMEOMORPHIC_FINITE = store_thm ("HOMEOMORPHIC_FINITE",
15817 ``!s:real->bool t:real->bool.
15818        FINITE s /\ FINITE t ==> (s homeomorphic t <=> (CARD s = CARD t))``,
15819  REPEAT STRIP_TAC THEN EQ_TAC THENL
15820   [DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN
15821    ASM_SIMP_TAC std_ss [CARD_EQ_CARD],
15822    STRIP_TAC THEN REWRITE_TAC[homeomorphic, HOMEOMORPHISM] THEN
15823    MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``]
15824        CARD_EQ_BIJECTIONS) THEN
15825    ASM_REWRITE_TAC[] THEN
15826    DISCH_THEN (X_CHOOSE_TAC ``f:real->real``) THEN POP_ASSUM MP_TAC THEN
15827    DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN
15828    MAP_EVERY EXISTS_TAC [``f:real->real``,``g:real->real``] THEN
15829    POP_ASSUM MP_TAC THEN
15830    ASM_SIMP_TAC std_ss [CONTINUOUS_ON_FINITE] THEN ASM_SET_TAC[]]);
15831
15832val HOMEOMORPHIC_FINITE_STRONG = store_thm ("HOMEOMORPHIC_FINITE_STRONG",
15833 ``!s:real->bool t:real->bool.
15834        FINITE s \/ FINITE t
15835        ==> (s homeomorphic t <=> FINITE s /\ FINITE t /\ (CARD s = CARD t))``,
15836  REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THEN
15837  SIMP_TAC std_ss [HOMEOMORPHIC_FINITE] THEN DISCH_TAC THEN
15838  FIRST_ASSUM(MP_TAC o MATCH_MP CARD_FINITE_CONG o MATCH_MP
15839    HOMEOMORPHIC_IMP_CARD_EQ) THEN
15840  FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
15841  ASM_MESON_TAC[HOMEOMORPHIC_FINITE]);
15842
15843val HOMEOMORPHIC_SING = store_thm ("HOMEOMORPHIC_SING",
15844 ``!a:real b:real. {a} homeomorphic {b}``,
15845  SIMP_TAC std_ss [HOMEOMORPHIC_FINITE, FINITE_SING, CARD_SING]);
15846
15847val LIFT_TO_QUOTIENT_SPACE_UNIQUE = store_thm ("LIFT_TO_QUOTIENT_SPACE_UNIQUE",
15848 ``!f:real->real g:real->real s t u.
15849        (IMAGE f s = t) /\
15850        (IMAGE g s = u) /\
15851        (!v. v SUBSET t
15852             ==> (open_in (subtopology euclidean s)
15853                  {x | x IN s /\ f x IN v} <=>
15854                  open_in (subtopology euclidean t) v)) /\
15855         (!v. v SUBSET u
15856             ==> (open_in (subtopology euclidean s)
15857                  {x | x IN s /\ g x IN v} <=>
15858                  open_in (subtopology euclidean u) v)) /\
15859        (!x y. x IN s /\ y IN s ==> ((f x = f y) <=> (g x = g y)))
15860        ==> t homeomorphic u``,
15861  REPEAT STRIP_TAC THEN
15862  MP_TAC(ISPECL
15863   [``f:real->real``, ``g:real->real``, ``s:real->bool``,
15864    ``t:real->bool``, ``u:real->bool``] LIFT_TO_QUOTIENT_SPACE) THEN
15865  MP_TAC(ISPECL
15866   [``g:real->real``, ``f:real->real``, ``s:real->bool``,
15867    ``u:real->bool``, ``t:real->bool``] LIFT_TO_QUOTIENT_SPACE) THEN
15868  ASM_REWRITE_TAC[] THEN
15869  MP_TAC(ISPECL [``f:real->real``, ``s:real->bool``, ``t:real->bool``]
15870        CONTINUOUS_ON_OPEN_GEN) THEN
15871  ASM_SIMP_TAC std_ss [SUBSET_REFL] THEN DISCH_THEN SUBST1_TAC THEN
15872  KNOW_TAC ``(!(u :real -> bool).
15873    open_in (subtopology euclidean (t :real -> bool)) u ==>
15874    open_in (subtopology euclidean (s :real -> bool))
15875      {x | x IN s /\ (f :real -> real) x IN u})`` THENL
15876   [METIS_TAC[OPEN_IN_IMP_SUBSET],
15877    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
15878    DISCH_THEN(X_CHOOSE_THEN ``h:real->real`` STRIP_ASSUME_TAC)] THEN
15879  MP_TAC(ISPECL [``g:real->real``, ``s:real->bool``, ``u:real->bool``]
15880        CONTINUOUS_ON_OPEN_GEN) THEN
15881  ASM_SIMP_TAC std_ss [SUBSET_REFL] THEN DISCH_THEN SUBST1_TAC THEN
15882  KNOW_TAC ``(!(u' :real -> bool).
15883    open_in (subtopology euclidean (u :real -> bool)) u' ==>
15884    open_in (subtopology euclidean (s :real -> bool))
15885      {x | x IN s /\ (g :real -> real) x IN u'}) /\
15886 (!(x :real) (y :real).
15887    x IN s /\ y IN s /\ ((f :real -> real) x = f y) ==> (g x = g y))`` THENL
15888   [METIS_TAC[OPEN_IN_IMP_SUBSET],
15889    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
15890    DISCH_THEN(X_CHOOSE_THEN ``k:real->real`` STRIP_ASSUME_TAC)] THEN
15891  REWRITE_TAC[homeomorphic, homeomorphism] THEN
15892  MAP_EVERY EXISTS_TAC
15893   [``k:real->real``, ``h:real->real``] THEN
15894  ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]);
15895
15896(* ------------------------------------------------------------------------- *)
15897(* Inverse function property for open/closed maps.                           *)
15898(* ------------------------------------------------------------------------- *)
15899
15900val CONTINUOUS_ON_INVERSE_OPEN_MAP = store_thm ("CONTINUOUS_ON_INVERSE_OPEN_MAP",
15901 ``!f:real->real g s t.
15902        f continuous_on s /\ (IMAGE f s = t) /\ (!x. x IN s ==> (g(f x) = x)) /\
15903        (!u. open_in (subtopology euclidean s) u
15904             ==> open_in (subtopology euclidean t) (IMAGE f u))
15905        ==> g continuous_on t``,
15906  REPEAT STRIP_TAC THEN
15907  MP_TAC(ISPECL [``g:real->real``, ``t:real->bool``, ``s:real->bool``]
15908        CONTINUOUS_ON_OPEN_GEN) THEN
15909  KNOW_TAC ``IMAGE (g :real -> real) (t :real -> bool) SUBSET (s :real -> bool)`` THENL
15910  [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
15911   DISCH_THEN SUBST1_TAC] THEN
15912  X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN
15913  FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN ASM_REWRITE_TAC[] THEN
15914  MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN
15915  FIRST_ASSUM(MP_TAC o CONJUNCT1 o REWRITE_RULE [open_in]) THEN
15916  ASM_SET_TAC[]);
15917
15918val CONTINUOUS_ON_INVERSE_CLOSED_MAP = store_thm ("CONTINUOUS_ON_INVERSE_CLOSED_MAP",
15919 ``!f:real->real g s t.
15920        f continuous_on s /\ (IMAGE f s = t) /\ (!x. x IN s ==> (g(f x) = x)) /\
15921        (!u. closed_in (subtopology euclidean s) u
15922             ==> closed_in (subtopology euclidean t) (IMAGE f u))
15923        ==> g continuous_on t``,
15924  REPEAT STRIP_TAC THEN
15925  MP_TAC(ISPECL [``g:real->real``, ``t:real->bool``, ``s:real->bool``]
15926        CONTINUOUS_ON_CLOSED_GEN) THEN
15927  KNOW_TAC ``IMAGE (g :real -> real) (t :real -> bool) SUBSET (s :real -> bool)`` THENL
15928  [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
15929   DISCH_THEN SUBST1_TAC] THEN
15930  X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN
15931  FIRST_X_ASSUM(MP_TAC o SPEC ``u:real->bool``) THEN ASM_REWRITE_TAC[] THEN
15932  MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN
15933  FIRST_ASSUM(MP_TAC o CONJUNCT1 o REWRITE_RULE [closed_in]) THEN
15934  REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM_SET_TAC[]);
15935
15936val HOMEOMORPHISM_INJECTIVE_OPEN_MAP = store_thm ("HOMEOMORPHISM_INJECTIVE_OPEN_MAP",
15937 ``!f:real->real s t.
15938        f continuous_on s /\ (IMAGE f s = t) /\
15939        (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) /\
15940        (!u. open_in (subtopology euclidean s) u
15941             ==> open_in (subtopology euclidean t) (IMAGE f u))
15942        ==> ?g. homeomorphism (s,t) (f,g)``,
15943  REPEAT STRIP_TAC THEN
15944  UNDISCH_TAC ``!(x :real) (y :real).
15945        x IN (s :real -> bool) /\ y IN s /\
15946        ((f :real -> real) x = f y) ==>
15947        (x = y)`` THEN DISCH_TAC THEN
15948  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [INJECTIVE_ON_LEFT_INVERSE]) THEN
15949  DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN EXISTS_TAC ``g:real->real`` THEN
15950  ASM_SIMP_TAC std_ss [homeomorphism] THEN
15951  REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN
15952  MATCH_MP_TAC CONTINUOUS_ON_INVERSE_OPEN_MAP THEN ASM_MESON_TAC[]);
15953
15954val HOMEOMORPHISM_INJECTIVE_CLOSED_MAP = store_thm ("HOMEOMORPHISM_INJECTIVE_CLOSED_MAP",
15955 ``!f:real->real s t.
15956        f continuous_on s /\ (IMAGE f s = t) /\
15957        (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y)) /\
15958        (!u. closed_in (subtopology euclidean s) u
15959             ==> closed_in (subtopology euclidean t) (IMAGE f u))
15960        ==> ?g. homeomorphism (s,t) (f,g)``,
15961  REPEAT STRIP_TAC THEN
15962  UNDISCH_TAC ``!(x :real) (y :real).
15963        x IN (s :real -> bool) /\ y IN s /\
15964        ((f :real -> real) x = f y) ==>
15965        (x = y)`` THEN DISCH_TAC THEN
15966  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [INJECTIVE_ON_LEFT_INVERSE]) THEN
15967  DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN EXISTS_TAC ``g:real->real`` THEN
15968  ASM_SIMP_TAC std_ss [homeomorphism] THEN
15969  REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN
15970  MATCH_MP_TAC CONTINUOUS_ON_INVERSE_CLOSED_MAP THEN ASM_MESON_TAC[]);
15971
15972val HOMEOMORPHISM_IMP_OPEN_MAP = store_thm ("HOMEOMORPHISM_IMP_OPEN_MAP",
15973 ``!f:real->real g s t u.
15974        homeomorphism (s,t) (f,g) /\ open_in (subtopology euclidean s) u
15975        ==> open_in (subtopology euclidean t) (IMAGE f u)``,
15976  REWRITE_TAC[homeomorphism] THEN REPEAT STRIP_TAC THEN
15977  SUBGOAL_THEN ``IMAGE (f:real->real) u =
15978                 {y | y IN t /\ g(y) IN u}``
15979  SUBST1_TAC THENL
15980   [FIRST_ASSUM(MP_TAC o CONJUNCT1 o REWRITE_RULE [open_in]) THEN
15981    ASM_SET_TAC[],
15982    MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]]);
15983
15984val HOMEOMORPHISM_IMP_CLOSED_MAP = store_thm ("HOMEOMORPHISM_IMP_CLOSED_MAP",
15985 ``!f:real->real g s t u.
15986        homeomorphism (s,t) (f,g) /\ closed_in (subtopology euclidean s) u
15987        ==> closed_in (subtopology euclidean t) (IMAGE f u)``,
15988  REWRITE_TAC[homeomorphism] THEN REPEAT STRIP_TAC THEN
15989  SUBGOAL_THEN ``IMAGE (f:real->real) u =
15990                  {y | y IN t /\ g(y) IN u}``
15991  SUBST1_TAC THENL
15992   [FIRST_ASSUM(MP_TAC o CONJUNCT1 o REWRITE_RULE [closed_in]) THEN
15993    REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM_SET_TAC[],
15994    MATCH_MP_TAC CONTINUOUS_ON_IMP_CLOSED_IN THEN ASM_REWRITE_TAC[]]);
15995
15996val HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ = store_thm ("HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ",
15997 ``!f:real->real s t.
15998        f continuous_on s /\ (IMAGE f s = t) /\
15999        (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y))
16000        ==> ((?g. homeomorphism (s,t) (f,g)) <=>
16001             !u. open_in (subtopology euclidean s) u
16002                 ==> open_in (subtopology euclidean t) (IMAGE f u))``,
16003  REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
16004   [MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN ASM_MESON_TAC[],
16005    MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN
16006    ASM_REWRITE_TAC[]]);
16007
16008val HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ = store_thm ("HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ",
16009 ``!f:real->real s t.
16010        f continuous_on s /\ (IMAGE f s = t) /\
16011        (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y))
16012        ==> ((?g. homeomorphism (s,t) (f,g)) <=>
16013             !u. closed_in (subtopology euclidean s) u
16014                 ==> closed_in (subtopology euclidean t) (IMAGE f u))``,
16015  REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
16016   [MATCH_MP_TAC HOMEOMORPHISM_IMP_CLOSED_MAP THEN ASM_MESON_TAC[],
16017    MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_CLOSED_MAP THEN
16018    ASM_REWRITE_TAC[]]);
16019
16020val INJECTIVE_MAP_OPEN_IFF_CLOSED = store_thm ("INJECTIVE_MAP_OPEN_IFF_CLOSED",
16021 ``!f:real->real s t.
16022        f continuous_on s /\ (IMAGE f s = t) /\
16023        (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y))
16024        ==> ((!u. open_in (subtopology euclidean s) u
16025                  ==> open_in (subtopology euclidean t) (IMAGE f u)) <=>
16026             (!u. closed_in (subtopology euclidean s) u
16027                  ==> closed_in (subtopology euclidean t) (IMAGE f u)))``,
16028  REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
16029  EXISTS_TAC ``?g:real->real. homeomorphism (s,t) (f,g)`` THEN
16030  CONJ_TAC THENL
16031   [CONV_TAC SYM_CONV THEN MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ,
16032    MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ] THEN
16033  ASM_REWRITE_TAC[]);
16034
16035(* ------------------------------------------------------------------------- *)
16036(* Relatively weak hypotheses if the domain of the function is compact.      *)
16037(* ------------------------------------------------------------------------- *)
16038
16039val CONTINUOUS_IMP_CLOSED_MAP = store_thm ("CONTINUOUS_IMP_CLOSED_MAP",
16040 ``!f:real->real s t.
16041        f continuous_on s /\ (IMAGE f s = t) /\ compact s
16042        ==> !u. closed_in (subtopology euclidean s) u
16043                ==> closed_in (subtopology euclidean t) (IMAGE f u)``,
16044  SIMP_TAC std_ss [CLOSED_IN_CLOSED_EQ, COMPACT_IMP_CLOSED] THEN
16045  REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSED_SUBSET THEN
16046  ASM_SIMP_TAC std_ss [IMAGE_SUBSET] THEN
16047  MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
16048  MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
16049  ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_IN_CLOSED_TRANS,
16050                BOUNDED_SUBSET, CONTINUOUS_ON_SUBSET]);
16051
16052val CONTINUOUS_IMP_QUOTIENT_MAP = store_thm ("CONTINUOUS_IMP_QUOTIENT_MAP",
16053 ``!f:real->real s t.
16054        f continuous_on s /\ (IMAGE f s = t) /\ compact s
16055        ==> !u. u SUBSET t
16056                ==> (open_in (subtopology euclidean s)
16057                             {x | x IN s /\ f x IN u} <=>
16058                     open_in (subtopology euclidean t) u)``,
16059  REPEAT GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
16060  MATCH_MP_TAC CLOSED_MAP_IMP_QUOTIENT_MAP THEN
16061  ASM_REWRITE_TAC[] THEN
16062  MATCH_MP_TAC CONTINUOUS_IMP_CLOSED_MAP THEN
16063  ASM_REWRITE_TAC[]);
16064
16065val CONTINUOUS_ON_INVERSE = store_thm ("CONTINUOUS_ON_INVERSE",
16066 ``!f:real->real g s.
16067        f continuous_on s /\ compact s /\ (!x. x IN s ==> (g(f(x)) = x))
16068        ==> g continuous_on (IMAGE f s)``,
16069  REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN
16070  SUBGOAL_THEN ``IMAGE g (IMAGE (f:real->real) s) = s`` SUBST1_TAC THENL
16071   [REWRITE_TAC[EXTENSION, IN_IMAGE] THEN ASM_MESON_TAC[], ALL_TAC] THEN
16072  X_GEN_TAC ``t:real->bool`` THEN DISCH_TAC THEN
16073  REWRITE_TAC[CLOSED_IN_CLOSED] THEN
16074  EXISTS_TAC ``IMAGE (f:real->real) t`` THEN CONJ_TAC THENL
16075   [MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
16076    MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
16077    FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN
16078    REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
16079    ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_IN_CLOSED_TRANS,
16080                  BOUNDED_SUBSET, CONTINUOUS_ON_SUBSET],
16081    SIMP_TAC std_ss [EXTENSION, IN_INTER, GSPECIFICATION, IN_IMAGE] THEN
16082    ASM_MESON_TAC[CLOSED_IN_SUBSET, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY, SUBSET_DEF]]);
16083
16084val HOMEOMORPHISM_COMPACT = store_thm ("HOMEOMORPHISM_COMPACT",
16085 ``!s f t. compact s /\ f continuous_on s /\ (IMAGE f s = t) /\
16086           (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y))
16087           ==> ?g. homeomorphism(s,t) (f,g)``,
16088  REWRITE_TAC[INJECTIVE_ON_LEFT_INVERSE] THEN REPEAT GEN_TAC THEN
16089  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
16090  DISCH_THEN (X_CHOOSE_TAC ``g:real->real``) THEN EXISTS_TAC ``g:real->real`` THEN
16091  ASM_SIMP_TAC std_ss [EXTENSION, homeomorphism] THEN
16092  FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
16093  ASM_MESON_TAC[CONTINUOUS_ON_INVERSE, IN_IMAGE]);
16094
16095val HOMEOMORPHIC_COMPACT = store_thm ("HOMEOMORPHIC_COMPACT",
16096 ``!s f t. compact s /\ f continuous_on s /\ (IMAGE f s = t) /\
16097           (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y))
16098           ==> s homeomorphic t``,
16099  REWRITE_TAC[homeomorphic] THEN METIS_TAC[HOMEOMORPHISM_COMPACT]);
16100
16101(* ------------------------------------------------------------------------- *)
16102(* Lemmas about composition of homeomorphisms.                               *)
16103(* ------------------------------------------------------------------------- *)
16104
16105val HOMEOMORPHISM_FROM_COMPOSITION_SURJECTIVE = store_thm ("HOMEOMORPHISM_FROM_COMPOSITION_SURJECTIVE",
16106 ``!f:real->real g:real->real s t u.
16107        f continuous_on s /\ (IMAGE f s = t) /\
16108        g continuous_on t /\ IMAGE g t SUBSET u /\
16109        (?h. homeomorphism (s,u) (g o f,h))
16110        ==> (?f'. homeomorphism (s,t) (f,f')) /\
16111            (?g'. homeomorphism (t,u) (g,g'))``,
16112  REPEAT GEN_TAC THEN STRIP_TAC THEN
16113  RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism, o_THM]) THEN
16114  MATCH_MP_TAC(TAUT `q /\ (q ==> p) ==> p /\ q`) THEN CONJ_TAC THENL
16115   [MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN
16116    REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN
16117    MATCH_MP_TAC OPEN_MAP_FROM_COMPOSITION_SURJECTIVE THEN
16118    MAP_EVERY EXISTS_TAC [``f:real->real``, ``s:real->bool``] THEN
16119    ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
16120    MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN
16121    MAP_EVERY EXISTS_TAC [``h:real->real``, ``s:real->bool``] THEN
16122    ASM_SIMP_TAC std_ss [homeomorphism, o_THM],
16123    REWRITE_TAC[homeomorphism, o_THM] THEN
16124    DISCH_THEN(X_CHOOSE_THEN ``g':real->real`` STRIP_ASSUME_TAC) THEN
16125    EXISTS_TAC ``((h:real->real) o (g:real->real))`` THEN
16126    ASM_SIMP_TAC std_ss [o_THM, IMAGE_COMPOSE] THEN
16127    CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
16128    MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
16129    ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]);
16130
16131val HOMEOMORPHISM_FROM_COMPOSITION_INJECTIVE = store_thm ("HOMEOMORPHISM_FROM_COMPOSITION_INJECTIVE",
16132 ``!f:real->real g:real->real s t u.
16133        f continuous_on s /\ IMAGE f s SUBSET t /\
16134        g continuous_on t /\ IMAGE g t SUBSET u /\
16135        (!x y. x IN t /\ y IN t /\ (g x = g y) ==> (x = y)) /\
16136        (?h. homeomorphism (s,u) (g o f,h))
16137        ==> (?f'. homeomorphism (s,t) (f,f')) /\
16138            (?g'. homeomorphism (t,u) (g,g'))``,
16139  REPEAT GEN_TAC THEN STRIP_TAC THEN
16140  RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism, o_THM]) THEN
16141  MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
16142   [MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN
16143    REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN
16144    MATCH_MP_TAC OPEN_MAP_FROM_COMPOSITION_INJECTIVE THEN
16145    MAP_EVERY EXISTS_TAC [``g:real->real``, ``u:real->bool``] THEN
16146    ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
16147    MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN
16148    MAP_EVERY EXISTS_TAC [``h:real->real``, ``s:real->bool``] THEN
16149    ASM_REWRITE_TAC[homeomorphism, o_THM],
16150    REWRITE_TAC[homeomorphism, o_THM] THEN
16151    DISCH_THEN(X_CHOOSE_THEN ``f':real->real`` STRIP_ASSUME_TAC) THEN
16152    EXISTS_TAC ``(f:real->real) o (h:real->real)`` THEN
16153    ASM_SIMP_TAC std_ss [o_THM, IMAGE_COMPOSE] THEN
16154    REPEAT(CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC]) THEN
16155    MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
16156    ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]);
16157
16158(* ------------------------------------------------------------------------- *)
16159(* Preservation of topological properties.                                   *)
16160(* ------------------------------------------------------------------------- *)
16161
16162val HOMEOMORPHIC_COMPACTNESS = store_thm ("HOMEOMORPHIC_COMPACTNESS",
16163 ``!s t. s homeomorphic t ==> (compact s <=> compact t)``,
16164  REWRITE_TAC[homeomorphic, homeomorphism] THEN
16165  MESON_TAC[COMPACT_CONTINUOUS_IMAGE]);
16166
16167val HOMEOMORPHIC_CONNECTEDNESS = store_thm ("HOMEOMORPHIC_CONNECTEDNESS",
16168 ``!s t. s homeomorphic t ==> (connected s <=> connected t)``,
16169  REWRITE_TAC[homeomorphic, homeomorphism] THEN
16170  MESON_TAC[CONNECTED_CONTINUOUS_IMAGE]);
16171
16172(* ------------------------------------------------------------------------- *)
16173(* Results on translation, scaling etc.                                      *)
16174(* ------------------------------------------------------------------------- *)
16175
16176val HOMEOMORPHIC_SCALING = store_thm ("HOMEOMORPHIC_SCALING",
16177 ``!s:real->bool c. ~(c = &0) ==> s homeomorphic (IMAGE (\x. c * x) s)``,
16178  REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
16179  MAP_EVERY EXISTS_TAC [``\x:real. c * x``, ``\x:real. inv(c) * x``] THEN
16180  ASM_SIMP_TAC std_ss [CONTINUOUS_ON_CMUL, CONTINUOUS_ON_ID, FORALL_IN_IMAGE] THEN
16181  ASM_SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_RINV] THEN
16182  SIMP_TAC std_ss [REAL_MUL_LID, IN_IMAGE, REAL_MUL_LID] THEN MESON_TAC[]);
16183
16184val HOMEOMORPHIC_TRANSLATION = store_thm ("HOMEOMORPHIC_TRANSLATION",
16185 ``!s a:real. s homeomorphic (IMAGE (\x. a + x) s)``,
16186  REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
16187  MAP_EVERY EXISTS_TAC [``\x:real. a +  x``, ``\x:real. -a + x``] THEN
16188  ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ADD, CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID] THEN
16189  SIMP_TAC std_ss [REAL_ADD_ASSOC, REAL_ADD_LINV, REAL_ADD_RINV,
16190           FORALL_IN_IMAGE, REAL_ADD_LID] THEN
16191  REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[]);
16192
16193val HOMEOMORPHIC_AFFINITY = store_thm ("HOMEOMORPHIC_AFFINITY",
16194 ``!s a:real c. ~(c = &0) ==> s homeomorphic (IMAGE (\x. a + c * x) s)``,
16195  REPEAT STRIP_TAC THEN
16196  MATCH_MP_TAC HOMEOMORPHIC_TRANS THEN
16197  EXISTS_TAC ``IMAGE (\x:real. c * x) s`` THEN
16198  ASM_SIMP_TAC std_ss [HOMEOMORPHIC_SCALING] THEN
16199  SUBGOAL_THEN ``(\x:real. a + c * x) = (\x. a + x) o (\x. c * x)``
16200  SUBST1_TAC THENL [REWRITE_TAC[o_DEF], ALL_TAC] THEN
16201  SIMP_TAC std_ss [IMAGE_COMPOSE, HOMEOMORPHIC_TRANSLATION]);
16202
16203val HOMEOMORPHIC_BALLS_CBALL_SPHERE = store_thm ("HOMEOMORPHIC_BALLS_CBALL_SPHERE",
16204 ``(!a:real b:real d e.
16205      &0 < d /\ &0 < e ==> ball(a,d) homeomorphic ball(b,e)) /\
16206   (!a:real b:real d e.
16207      &0 < d /\ &0 < e ==> cball(a,d) homeomorphic cball(b,e)) /\
16208   (!a:real b:real d e.
16209      &0 < d /\ &0 < e ==> sphere(a,d) homeomorphic sphere(b,e))``,
16210  REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
16211  EXISTS_TAC ``\x:real. b + (e / d) * (x - a)`` THEN
16212  EXISTS_TAC ``\x:real. a + (d / e) * (x - b)`` THEN
16213  ASM_SIMP_TAC std_ss [CONTINUOUS_ON_ADD, CONTINUOUS_ON_SUB, CONTINUOUS_ON_CMUL,
16214    CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID, IN_BALL, IN_CBALL, IN_SPHERE] THEN
16215  REWRITE_TAC[dist, REAL_ARITH ``a - (a + b) = -b:real``, ABS_NEG] THEN
16216  REWRITE_TAC[real_div, REAL_ARITH
16217   ``a + d * ((b + e * (x - a)) - b) = (&1 - d * e) * a + (d * e) * x:real``] THEN
16218  ONCE_REWRITE_TAC[REAL_ARITH
16219    ``(e * d') * (d * e') = (d * d') * (e * e':real)``] THEN
16220  ASM_SIMP_TAC std_ss [REAL_MUL_RINV, REAL_LT_IMP_NE, REAL_MUL_LID, REAL_SUB_REFL] THEN
16221  REWRITE_TAC[ABS_MUL, REAL_MUL_LZERO, REAL_MUL_LID, REAL_ADD_LID] THEN
16222  ASM_SIMP_TAC std_ss [ABS_MUL, ABS_INV, REAL_ARITH
16223   ``&0 < x ==> (abs x = x:real)``, REAL_LT_IMP_NE] THEN
16224  GEN_REWR_TAC(BINOP_CONV o BINDER_CONV o funpow 2 RAND_CONV)
16225        [GSYM REAL_MUL_RID] THEN
16226  ONCE_REWRITE_TAC[REAL_ARITH ``(a * b) * c = (a * c) * b:real``] THEN
16227  ASM_SIMP_TAC std_ss [REAL_LE_LMUL, GSYM real_div, REAL_LE_LDIV_EQ, REAL_MUL_LID,
16228    GSYM REAL_MUL_ASSOC, REAL_LT_LMUL, REAL_LT_LDIV_EQ, ABS_SUB] THEN
16229  ASM_SIMP_TAC std_ss [REAL_DIV_REFL, REAL_LT_IMP_NE, REAL_MUL_RID]);
16230
16231val HOMEOMORPHIC_BALLS = store_thm ("HOMEOMORPHIC_BALLS",
16232 ``(!a:real b:real d e.
16233      &0 < d /\ &0 < e ==> ball(a,d) homeomorphic ball(b,e))``,
16234 REWRITE_TAC [HOMEOMORPHIC_BALLS_CBALL_SPHERE]);
16235
16236val HOMEOMORPHIC_CBALL = store_thm ("HOMEOMORPHIC_CBALL",
16237 ``(!a:real b:real d e.
16238      &0 < d /\ &0 < e ==> cball(a,d) homeomorphic cball(b,e))``,
16239 REWRITE_TAC [HOMEOMORPHIC_BALLS_CBALL_SPHERE]);
16240
16241val HOMEOMORPHIC_SPHERE = store_thm ("HOMEOMORPHIC_SPHERE",
16242 ``(!a:real b:real d e.
16243      &0 < d /\ &0 < e ==> sphere(a,d) homeomorphic sphere(b,e))``,
16244 REWRITE_TAC [HOMEOMORPHIC_BALLS_CBALL_SPHERE]);
16245
16246(* ------------------------------------------------------------------------- *)
16247(* Homeomorphism of one-point compactifications.                             *)
16248(* ------------------------------------------------------------------------- *)
16249
16250val HOMEOMORPHIC_ONE_POINT_COMPACTIFICATIONS = store_thm ("HOMEOMORPHIC_ONE_POINT_COMPACTIFICATIONS",
16251 ``!s:real->bool t:real->bool a b.
16252        compact s /\ compact t /\ a IN s /\ b IN t /\
16253        (s DELETE a) homeomorphic (t DELETE b)
16254        ==> s homeomorphic t``,
16255  REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_COMPACT THEN
16256  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [homeomorphic]) THEN
16257  SIMP_TAC std_ss [HOMEOMORPHISM, LEFT_IMP_EXISTS_THM] THEN
16258  MAP_EVERY X_GEN_TAC [``f:real->real``, ``g:real->real``] THEN
16259  STRIP_TAC THEN
16260  EXISTS_TAC ``\x. if x = a then b else (f:real->real) x`` THEN
16261  ASM_SIMP_TAC std_ss [] THEN CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
16262  REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
16263  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
16264  ASM_CASES_TAC ``x:real = a`` THEN ASM_REWRITE_TAC[] THENL
16265   [REWRITE_TAC[continuous_within] THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
16266    MP_TAC(ISPECL [``b:real``, ``e:real``] CENTRE_IN_BALL) THEN
16267    ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
16268    SUBGOAL_THEN
16269      ``closed_in (subtopology euclidean s)
16270                 { x | x IN (s DELETE a) /\
16271                       (f:real->real)(x) IN t DIFF ball(b,e)}``
16272    MP_TAC THENL
16273     [MATCH_MP_TAC CLOSED_SUBSET THEN CONJ_TAC THENL [SET_TAC[], ALL_TAC] THEN
16274      MATCH_MP_TAC COMPACT_IMP_CLOSED THEN SUBGOAL_THEN
16275       ``{x | x IN s DELETE a /\ f x IN t DIFF ball(b,e)} =
16276        IMAGE (g:real->real) (t DIFF ball (b,e))``
16277      SUBST1_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
16278      MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
16279      ASM_SIMP_TAC std_ss [COMPACT_DIFF, OPEN_BALL] THEN
16280      FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP]
16281        CONTINUOUS_ON_SUBSET)) THEN ASM_SET_TAC[],
16282      REWRITE_TAC[closed_in, open_in, TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
16283      DISCH_THEN(MP_TAC o SPEC ``a:real`` o last o CONJUNCTS) THEN
16284      ASM_SIMP_TAC std_ss [GSPECIFICATION, IN_DIFF, IN_DELETE] THEN
16285      SIMP_TAC std_ss [CONJ_EQ_IMP, DE_MORGAN_THM] THEN
16286      STRIP_TAC THEN EXISTS_TAC ``e':real`` THEN
16287      ASM_REWRITE_TAC[] THEN GEN_TAC THEN COND_CASES_TAC THEN
16288      ASM_REWRITE_TAC[DIST_REFL] THEN
16289      GEN_REWR_TAC (RAND_CONV o RAND_CONV o LAND_CONV) [DIST_SYM] THEN
16290      RULE_ASSUM_TAC(REWRITE_RULE[IN_BALL]) THEN ASM_SET_TAC[]],
16291    UNDISCH_TAC ``(f:real->real) continuous_on (s DELETE a)`` THEN
16292    SIMP_TAC std_ss [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
16293    DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[IN_DELETE] THEN
16294    REWRITE_TAC[continuous_within] THEN
16295    DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN
16296    ASM_CASES_TAC ``&0 < e:real`` THEN ASM_REWRITE_TAC[IN_DELETE] THEN
16297    DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
16298    EXISTS_TAC ``min d (dist(a:real,x))`` THEN
16299    ASM_SIMP_TAC std_ss [REAL_LT_MIN, GSYM DIST_NZ] THEN
16300    METIS_TAC[REAL_LT_REFL]]);
16301
16302(* ------------------------------------------------------------------------- *)
16303(* Homeomorphisms between open intervals in real and then in real.       *)
16304(* Could prove similar things for closed intervals, but they drop out of     *)
16305(* later stuff in "convex.ml" even more easily.                              *)
16306(* ------------------------------------------------------------------------- *)
16307
16308val HOMEOMORPHIC_OPEN_INTERVALS = store_thm ("HOMEOMORPHIC_OPEN_INTERVALS",
16309 ``!a b c d.
16310        a < b /\ c < d
16311        ==> interval(a,b) homeomorphic interval(c,d)``,
16312  SUBGOAL_THEN
16313   ``!a b. a < b
16314          ==> interval(0:real,1) homeomorphic interval(a,b)``
16315  ASSUME_TAC THENL
16316   [REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
16317    EXISTS_TAC ``(\x. a + x * (b - a)):real->real`` THEN
16318    EXISTS_TAC ``(\x. inv(b - a) * (x - a)):real->real`` THEN
16319    ASM_SIMP_TAC std_ss [IN_INTERVAL] THEN
16320    REWRITE_TAC[METIS [REAL_MUL_SYM, GSYM real_div] ``inv b * a:real = a / b``] THEN
16321    ASM_SIMP_TAC std_ss [REAL_LT_LDIV_EQ, REAL_LT_RDIV_EQ, REAL_SUB_LT,
16322       REAL_LT_ADDR, REAL_EQ_LDIV_EQ, REAL_DIV_RMUL, REAL_LT_IMP_NE,
16323       REAL_LT_MUL, REAL_MUL_LZERO, REAL_ADD_SUB, REAL_LT_RMUL,
16324       REAL_ARITH ``a + x < b <=> x < &1 * (b - a:real)``] THEN
16325    REPEAT CONJ_TAC THENL
16326     [REAL_ARITH_TAC,
16327      ONCE_REWRITE_TAC [METIS [] ``(\x. a + x * (b - a)) =
16328                      (\x. (\x. a) x + (\x. x * (b - a)) x:real)``] THEN
16329      MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
16330      ONCE_REWRITE_TAC [METIS [] ``(\x. x * (b - a)) =
16331                      (\x. (\x. x) x * (\x. (b - a)) x:real)``] THEN
16332      MATCH_MP_TAC CONTINUOUS_ON_MUL THEN
16333      REWRITE_TAC[o_DEF, CONTINUOUS_ON_ID, CONTINUOUS_ON_CONST],
16334      ONCE_REWRITE_TAC [METIS [real_div, REAL_MUL_SYM] ``(\x. (x - a) / (b - a))  =
16335                                       (\x. inv(b - a) * (\x. (x - a)) x:real)``] THEN
16336      MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN
16337      ASM_SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID]],
16338    REPEAT STRIP_TAC THEN
16339    FIRST_ASSUM(MP_TAC o SPECL [``a:real``, ``b:real``]) THEN
16340    FIRST_X_ASSUM(MP_TAC o SPECL [``c:real``, ``d:real``]) THEN
16341    ASM_REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN
16342    GEN_REWR_TAC (LAND_CONV o LAND_CONV) [HOMEOMORPHIC_SYM] THEN
16343    REWRITE_TAC[HOMEOMORPHIC_TRANS]]);
16344
16345val HOMEOMORPHIC_OPEN_INTERVAL_UNIV = store_thm ("HOMEOMORPHIC_OPEN_INTERVAL_UNIV",
16346 ``!a b. a < b ==> interval(a,b) homeomorphic univ(:real)``,
16347  REPEAT STRIP_TAC THEN
16348  MP_TAC(SPECL [``a:real``, ``b:real``, ``-1:real``, ``1:real``]
16349        HOMEOMORPHIC_OPEN_INTERVALS) THEN
16350  ASM_REWRITE_TAC[] THEN REWRITE_TAC [REAL_ARITH ``-1 < 1:real``] THEN
16351  MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] HOMEOMORPHIC_TRANS) THEN
16352  POP_ASSUM_LIST(K ALL_TAC) THEN
16353  REWRITE_TAC[HOMEOMORPHIC_MINIMAL, IN_UNIV] THEN
16354  EXISTS_TAC ``\x:real. inv(&1 - abs x) * x`` THEN
16355  EXISTS_TAC ``\y:real. if &0 <= y then inv(&1 + y) * y
16356                  else inv(&1 - y) * y`` THEN
16357  SIMP_TAC std_ss [] THEN REPEAT CONJ_TAC THENL
16358   [X_GEN_TAC ``x:real`` THEN REWRITE_TAC[IN_INTERVAL] THEN
16359    SIMP_TAC std_ss [REAL_LE_MUL, REAL_LT_INV_EQ, REAL_LE_MUL, REAL_ARITH
16360     ``-a < x /\ x < a ==> &0 < a - abs x:real``] THEN
16361    SIMP_TAC std_ss [abs, REAL_MUL_ASSOC] THEN
16362    COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
16363    GEN_REWR_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN
16364    AP_THM_TAC THEN AP_TERM_TAC THEN COND_CASES_TAC THEN
16365    (Cases_on `x = 0:real` THENL
16366     [ASM_REWRITE_TAC [REAL_INV1, REAL_NEG_0, REAL_SUB_RZERO,
16367      REAL_ADD_RID, REAL_MUL_RZERO] THEN REAL_ARITH_TAC, ALL_TAC]) THEN
16368     (KNOW_TAC ``!y. y <> 0:real ==> ((1 + inv y * x) = (y + x) / y:real) /\
16369                                     ((1 - inv y * x) = (y - x) / y:real)`` THENL
16370     [ASM_SIMP_TAC real_ss [real_div, REAL_ADD_RDISTRIB, REAL_MUL_RINV, REAL_SUB_RDISTRIB] THEN
16371      REAL_ARITH_TAC, STRIP_TAC] THEN
16372     KNOW_TAC ``(1 - x) <> 0 /\ (1 - -x) <> 0:real`` THENL
16373     [METIS_TAC [REAL_ARITH ``x < 1 ==> 1 - x <> 0:real``,
16374                 REAL_ARITH ``-1 < x ==> 1 - -x <> 0:real``],
16375      STRIP_TAC] THEN ASM_SIMP_TAC real_ss []) THENL
16376     [METIS_TAC [REAL_INV_1OVER, REAL_MUL_RINV, REAL_INV_INV],
16377      FULL_SIMP_TAC real_ss [REAL_LT_IMP_LE] THEN
16378      RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_MUL_SYM]) THEN
16379      FULL_SIMP_TAC real_ss [GSYM real_div, REAL_LE_RDIV_EQ,
16380       REAL_ARITH ``(-1 < x) =  (0 < 1 + x:real)``],
16381      FULL_SIMP_TAC real_ss [REAL_LT_IMP_LE, REAL_NOT_LE] THEN
16382      RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_MUL_SYM]) THEN
16383      FULL_SIMP_TAC real_ss [GSYM real_div, REAL_LT_LDIV_EQ,
16384       REAL_ARITH ``(x < 1) =  (0 < 1 - x:real)``] THEN
16385      METIS_TAC [REAL_ARITH ``~(x < 0 /\ 0 <= x:real)``],
16386      FULL_SIMP_TAC real_ss [] THEN
16387      METIS_TAC [REAL_INV_1OVER, REAL_MUL_RINV, REAL_INV_INV]],
16388    X_GEN_TAC ``y:real`` THEN COND_CASES_TAC THEN
16389    ASM_SIMP_TAC real_ss [IN_INTERVAL, REAL_BOUNDS_LT] THEN
16390    ASM_SIMP_TAC real_ss [ABS_MUL, ABS_INV, REAL_ARITH
16391     ``(0 <= y ==> 1 + y <> 0:real) /\ (~(0 <= y) ==> 1 - y <> 0:real)``] THEN
16392    REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div)] THEN
16393    ASM_SIMP_TAC real_ss [REAL_LT_LDIV_EQ, REAL_ARITH ``&0 <= x ==> &0 < abs(&1 + x:real)``,
16394                 REAL_ARITH ``~(&0 <= x) ==> &0 < abs(&1 - x:real)``] THEN
16395    (CONJ_TAC THENL [ASM_REAL_ARITH_TAC, ALL_TAC]) THEN
16396    REWRITE_TAC [real_div] THEN
16397    ONCE_REWRITE_TAC [REAL_ARITH ``a * b * c = c * b * a:real``] THEN
16398    REWRITE_TAC[REAL_MUL_ASSOC] THEN REWRITE_TAC[ABS_MUL] THEN
16399    ASM_REWRITE_TAC[abs,  REAL_LE_INV_EQ] THEN
16400    ASM_SIMP_TAC real_ss [REAL_ARITH ``&0 <= x ==> &0 <= &1 + x:real``,
16401                 REAL_ARITH ``~(&0 <= x) ==> &0 <= &1 - x:real``] THEN
16402    GEN_REWR_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN
16403    AP_THM_TAC THEN AP_TERM_TAC THEN
16404    (KNOW_TAC ``!x. x <> 0:real ==> ((1 + y * inv x) = (x + y) / x:real) /\
16405                                   ((1 - y * inv x) = (x - y) / x:real)`` THENL
16406     [ASM_SIMP_TAC real_ss [real_div, REAL_ADD_RDISTRIB, REAL_MUL_RINV, REAL_SUB_RDISTRIB],
16407      STRIP_TAC]) THENL
16408     [KNOW_TAC ``(1 + y) <> 0:real`` THENL
16409      [METIS_TAC [REAL_ARITH ``(0 <= x) ==> 1 + x <> 0:real``],
16410       STRIP_TAC] THEN ASM_SIMP_TAC real_ss [],
16411      KNOW_TAC ``(1 - y) <> 0:real`` THENL
16412      [METIS_TAC [REAL_ARITH ``~(0 <= x) ==> 1 - x <> 0:real``],
16413       STRIP_TAC] THEN ASM_SIMP_TAC real_ss []] THEN
16414     METIS_TAC [REAL_INV_1OVER, REAL_MUL_RINV, REAL_INV_INV],
16415    MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
16416    X_GEN_TAC ``x:real`` THEN
16417    REWRITE_TAC[IN_INTERVAL] THEN DISCH_TAC THEN
16418    ONCE_REWRITE_TAC [METIS [] ``(\x. inv (1 - abs x) * x) =
16419                    (\x. (\x. inv (1 - abs x)) x * (\x. x) x:real)``] THEN
16420    MATCH_MP_TAC CONTINUOUS_MUL THEN
16421    REWRITE_TAC[CONTINUOUS_AT_ID] THEN
16422    ONCE_REWRITE_TAC [METIS [] ``(\x. inv (1 - abs x)) =
16423                             (\x. inv ((\x. 1 - abs x) x:real))``] THEN
16424    ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN
16425    SIMP_TAC real_ss [NETLIMIT_AT, o_DEF] THEN
16426    CONJ_TAC THENL
16427     [ONCE_REWRITE_TAC [METIS []
16428      ``(\x. 1 - abs x) = (\x. (\x. 1) x - (\x. abs x) x:real)``] THEN
16429      MATCH_MP_TAC CONTINUOUS_SUB THEN
16430      SIMP_TAC std_ss [CONTINUOUS_CONST] THEN
16431      ONCE_REWRITE_TAC [METIS [] ``(\x. abs x) = (\x. abs ((\x. x) x:real))``] THEN
16432      METIS_TAC [REWRITE_RULE[o_DEF] CONTINUOUS_AT_ABS], ASM_REAL_ARITH_TAC],
16433    SUBGOAL_THEN ``univ(:real) = {x | x >= &0} UNION {x | x <= &0}``
16434    SUBST1_TAC THENL
16435     [SIMP_TAC std_ss [EXTENSION, IN_UNION, IN_UNION, GSPECIFICATION, IN_UNIV] THEN
16436      REAL_ARITH_TAC,
16437      ONCE_REWRITE_TAC [METIS []
16438      ``(\y. if 0 <= y then inv (1 + y) * y else inv (1 - y) * y) =
16439        (\y. if (\y. 0 <= y) y then (\y. inv (1 + y) * y) y
16440                               else (\y. inv (1 - y) * y) y:real)``] THEN
16441      MATCH_MP_TAC CONTINUOUS_ON_CASES THEN
16442      SIMP_TAC std_ss [CLOSED_HALFSPACE_COMPONENT_LE, CLOSED_HALFSPACE_COMPONENT_GE,
16443                  GSPECIFICATION] THEN
16444      REWRITE_TAC[REAL_NOT_LE, real_ge, REAL_LET_ANTISYM] THEN
16445      SIMP_TAC std_ss [REAL_LE_ANTISYM, REAL_SUB_RZERO, REAL_ADD_RID] THEN
16446      CONJ_TAC THENL
16447      [MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
16448       X_GEN_TAC ``y:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, real_ge] THEN
16449       DISCH_TAC THEN ONCE_REWRITE_TAC [METIS [] ``(\y. inv (1 + y) * y) =
16450                                      (\y. (\y. inv (1 + y)) y * (\y. y) y:real)``] THEN
16451      MATCH_MP_TAC CONTINUOUS_MUL THEN
16452      REWRITE_TAC[CONTINUOUS_AT_ID] THEN
16453      ONCE_REWRITE_TAC [METIS [] ``(\y. inv (1 + y)) = (\y. inv ((\y. (1 + y)) y:real))``] THEN
16454      ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN
16455      SIMP_TAC std_ss [NETLIMIT_AT, o_DEF] THEN
16456      ASM_SIMP_TAC std_ss [CONTINUOUS_ADD, CONTINUOUS_AT_ID, CONTINUOUS_SUB,
16457                   CONTINUOUS_CONST] THEN
16458      ASM_REAL_ARITH_TAC, ALL_TAC] THEN CONJ_TAC THENL
16459      [MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
16460       X_GEN_TAC ``y:real`` THEN SIMP_TAC std_ss [GSPECIFICATION, real_ge] THEN
16461       DISCH_TAC THEN ONCE_REWRITE_TAC [METIS [] ``(\y. inv (1 - y) * y) =
16462                                      (\y. (\y. inv (1 - y)) y * (\y. y) y:real)``] THEN
16463       MATCH_MP_TAC CONTINUOUS_MUL THEN
16464       REWRITE_TAC[CONTINUOUS_AT_ID] THEN
16465       ONCE_REWRITE_TAC [METIS [] ``(\y. inv (1 - y)) = (\y. inv ((\y. (1 - y)) y:real))``] THEN
16466       ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN
16467       SIMP_TAC std_ss [NETLIMIT_AT, o_DEF] THEN
16468       ASM_SIMP_TAC std_ss [CONTINUOUS_ADD, CONTINUOUS_AT_ID, CONTINUOUS_SUB,
16469                   CONTINUOUS_CONST] THEN
16470       ASM_REAL_ARITH_TAC,
16471       REPEAT STRIP_TAC THENL [METIS_TAC [REAL_ARITH ``~(0 <= x /\ x < 0:real)``],
16472        ASM_REWRITE_TAC [] THEN REAL_ARITH_TAC]]]]);
16473
16474(* ------------------------------------------------------------------------- *)
16475(* Cardinality of the reals. This is done in a rather laborious way to avoid *)
16476(* any dependence on the theories of analysis.                               *)
16477(* ------------------------------------------------------------------------- *)
16478
16479Triviality lemma:
16480  !s m n. sum (s INTER (m..n)) (\i. inv(&3 pow i)) < &3 / &2 / &3 pow m
16481Proof
16482    REPEAT GEN_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
16483    EXISTS_TAC ``sum (m..n) (\i. inv(&3 pow i))`` THEN CONJ_TAC THENL
16484    [ (* goal 1 (of 2) *)
16485      MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
16486      SIMP_TAC std_ss [FINITE_NUMSEG, INTER_SUBSET, REAL_LE_INV_EQ,
16487               POW_POS, REAL_POS],
16488      (* goal 2 (of 2) *)
16489      completeInduct_on `n - m:num` THEN GEN_TAC THEN GEN_TAC THEN
16490      DISCH_TAC THEN FULL_SIMP_TAC std_ss [] THEN POP_ASSUM K_TAC THEN
16491      KNOW_TAC ``(!m'. m' < n - m ==>
16492        !n m''. (m' = n - m'') ==>
16493          sum (m'' .. n) (\i. inv (3 pow i)) < 3 / 2 / 3 pow m'') ==>
16494       (!n' m''. (n' - m'' < n - m) ==>
16495          sum (m'' .. n') (\i. inv (3 pow i)) < 3 / 2 / 3 pow m'')`` THENL
16496      [ METIS_TAC [], ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN DISCH_TAC ] THEN
16497      ASM_CASES_TAC ``m:num <= n`` THENL
16498      [ (* goal 2.1 (of 2) *)
16499        ASM_SIMP_TAC std_ss [SUM_CLAUSES_LEFT] THEN ASM_CASES_TAC ``m + 1 <= n:num`` THENL
16500        [ (* goal 2.1.1 (of 2) *)
16501          FIRST_X_ASSUM (MP_TAC o SPECL [``n:num``, ``SUC m``]) THEN
16502          KNOW_TAC ``n - SUC m < n - m`` THENL
16503          [ASM_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
16504           ASM_SIMP_TAC arith_ss [ADD1, REAL_POW_ADD]] THEN
16505          MATCH_MP_TAC (REAL_ARITH
16506                        ``a + j:real <= k ==> x < j ==> a + x < k:real``) THEN
16507          KNOW_TAC ``3 pow m <> 0:real`` THENL
16508          [MATCH_MP_TAC POW_NZ THEN REAL_ARITH_TAC, DISCH_TAC] THEN
16509          ASM_SIMP_TAC real_ss [real_div, REAL_INV_MUL, POW_1] THEN
16510          ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN
16511          GEN_REWR_TAC (LAND_CONV o LAND_CONV) [GSYM REAL_MUL_RID] THEN
16512          REWRITE_TAC [GSYM REAL_ADD_LDISTRIB, GSYM REAL_MUL_ASSOC] THEN
16513          MATCH_MP_TAC REAL_LE_LMUL_IMP THEN CONJ_TAC THENL
16514          [REWRITE_TAC [REAL_LE_INV_EQ] THEN MATCH_MP_TAC POW_POS THEN
16515           REAL_ARITH_TAC, ALL_TAC] THEN REWRITE_TAC [GSYM real_div] THEN
16516           SIMP_TAC real_ss [REAL_LE_RDIV_EQ, REAL_ADD_RDISTRIB, real_div] THEN
16517           REWRITE_TAC [REAL_MUL_ASSOC] THEN SIMP_TAC real_ss [REAL_MUL_LINV],
16518          ALL_TAC], ALL_TAC] THEN
16519      RULE_ASSUM_TAC (REWRITE_RULE[NOT_LESS_EQUAL, GSYM NUMSEG_EMPTY]) THEN
16520      ASM_REWRITE_TAC [SUM_CLAUSES, REAL_ADD_RID] THEN
16521      (KNOW_TAC ``0:real < 3 pow m`` THENL
16522          [MATCH_MP_TAC REAL_POW_LT THEN REAL_ARITH_TAC, DISCH_TAC] THEN
16523       ASM_SIMP_TAC real_ss [REAL_LT_RDIV_EQ, REAL_MUL_LINV, REAL_LT_IMP_NE])]
16524QED
16525
16526Theorem CARD_EQ_REAL:   univ(:real) =_c univ(:num->bool)
16527Proof
16528  REWRITE_TAC [GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
16529  [ (* goal 1 (of 2) *)
16530    KNOW_TAC ``univ(:real) <=_c (univ(:num) *_c univ(:num->bool)) /\
16531               (univ(:num) *_c univ(:num->bool)) <=_c univ(:num -> bool)`` THENL
16532    [ALL_TAC, METIS_TAC [CARD_LE_TRANS]] THEN
16533    CONJ_TAC THENL
16534     [ALL_TAC,
16535      MATCH_MP_TAC CARD_MUL2_ABSORB_LE THEN REWRITE_TAC[INFINITE_CARD_LE] THEN
16536      SIMP_TAC std_ss [CANTOR_THM_UNIV, CARD_LT_IMP_LE, CARD_LE_REFL]] THEN
16537    `univ(:real) <=_c (univ(:num) *_c {x:real | &0 <= x}) /\
16538     univ(:num) *_c {x:real | &0 <= x} <=_c univ(:num) *_c univ(:num -> bool)`
16539       suffices_by METIS_TAC[CARD_LE_TRANS] THEN
16540    CONJ_TAC THENL
16541     [SIMP_TAC std_ss [LE_C, mul_c, EXISTS_PROD, IN_ELIM_PAIR_THM, IN_UNIV] THEN
16542      EXISTS_TAC ``\(n,x:real). -(&1) pow n * x`` THEN X_GEN_TAC ``x:real`` THEN
16543      `?p_2. (p_2 IN {x | 0r <= x} /\ ((\ (n,x). -1 pow n * x) (0,p_2) = x)) \/
16544             (p_2 IN {x | 0r <= x} /\ ((\ (n,x). -1 pow n * x) (1,p_2) = x))`
16545        suffices_by METIS_TAC[OR_EXISTS_THM] THEN EXISTS_TAC ``abs x:real`` THEN
16546      SIMP_TAC std_ss [GSPECIFICATION, pow, POW_1] THEN REAL_ARITH_TAC,
16547      ALL_TAC] THEN
16548    MATCH_MP_TAC CARD_LE_MUL THEN SIMP_TAC std_ss [CARD_LE_REFL] THEN
16549    MP_TAC(ISPECL [``univ(:num)``, ``univ(:num)``] CARD_MUL_ABSORB_LE) THEN
16550    SIMP_TAC std_ss [CARD_LE_REFL, num_INFINITE] THEN
16551    SIMP_TAC std_ss [le_c, mul_c, IN_UNIV, FORALL_PROD, IN_ELIM_PAIR_THM] THEN
16552    REWRITE_TAC [GSYM PAIR_EQ] THEN
16553    SIMP_TAC std_ss [GSYM FORALL_PROD, INJECTIVE_LEFT_INVERSE] THEN
16554    SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM]
16555
16556    THEN
16557    MAP_EVERY X_GEN_TAC [``Pair:num#num->num``, ``Unpair:num->num#num``] THEN
16558    DISCH_TAC THEN
16559    EXISTS_TAC ``\x:real n:num. &(FST(Unpair n)) * x <= &(SND(Unpair n))`` THEN
16560    SIMP_TAC std_ss [] THEN
16561    HO_MATCH_MP_TAC REAL_WLOG_LT THEN
16562    SIMP_TAC std_ss [GSPECIFICATION, FUN_EQ_THM] THEN
16563    CONJ_TAC THENL [SIMP_TAC std_ss [EQ_SYM_EQ, CONJ_ACI], ALL_TAC] THEN
16564    MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN REPEAT STRIP_TAC THEN
16565    FIRST_X_ASSUM(MP_TAC o GENL [``p:num``, ``q:num``] o
16566      SPEC ``(Pair:num#num->num) (p,q)``) THEN
16567    ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT `~p ==> p ==> q`) THEN
16568    MP_TAC(SPEC ``y - x:real`` REAL_ARCH) THEN
16569    ASM_SIMP_TAC std_ss [REAL_SUB_LT, NOT_FORALL_THM] THEN
16570    DISCH_THEN(MP_TAC o SPEC ``&2:real``) THEN
16571    DISCH_THEN (X_CHOOSE_TAC ``p:num``) THEN EXISTS_TAC ``p:num`` THEN
16572    MP_TAC(ISPEC ``&p * x:real`` REAL_BIGNUM) THEN
16573    ONCE_REWRITE_TAC [METIS [] ``(?n. &p * x < &n:real) = (?n. (\n. &p * x < &n) n)``] THEN
16574    DISCH_THEN (MP_TAC o MATCH_MP WOP) THEN SIMP_TAC std_ss [] THEN
16575    DISCH_THEN (X_CHOOSE_TAC ``n:num``) THEN EXISTS_TAC ``n:num`` THEN
16576    POP_ASSUM MP_TAC THEN SPEC_TAC (``n:num``,``n:num``) THEN
16577    KNOW_TAC ``!n. (\n. &p * x < &n:real /\ (!m. m < n ==> ~(&p * x < &m)) ==>
16578                      ~(&p * x <= &n <=> &p * y <= &n:real)) n`` THENL
16579    [ALL_TAC, METIS_TAC []] THEN MATCH_MP_TAC INDUCTION THEN
16580
16581    ASM_SIMP_TAC std_ss [REAL_LE_MUL, REAL_POS,
16582      REAL_ARITH ``x:real < &0 <=> ~(&0 <= x)``]
16583
16584    THEN
16585    X_GEN_TAC ``q:num`` THEN REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN
16586    DISCH_THEN(K ALL_TAC) THEN STRIP_TAC THEN
16587    FIRST_X_ASSUM(MP_TAC o SPEC ``q:num``) THEN
16588    SIMP_TAC arith_ss [LT] THEN POP_ASSUM MP_TAC THEN
16589    POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN
16590    POP_ASSUM MP_TAC THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC,
16591
16592    (* goal 2 (of 2) *)
16593    REWRITE_TAC[le_c, IN_UNIV] THEN
16594    EXISTS_TAC ``\s:num->bool. sup { sum (s INTER ((0:num)..n)) (\i. inv(&3 pow i)) |
16595                                    n IN univ(:num) }`` THEN
16596    MAP_EVERY X_GEN_TAC [``x:num->bool``, ``y:num->bool``] THEN
16597    ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN
16598    SIMP_TAC std_ss [EXTENSION, NOT_FORALL_THM] THEN
16599    ONCE_REWRITE_TAC [METIS [] ``(?x':num. x' IN x <=/=> x' IN y) =
16600                           (?x'. (\x'. x' IN x <=/=> x' IN y) x')``] THEN
16601    DISCH_THEN (MP_TAC o MATCH_MP WOP) THEN SIMP_TAC std_ss [] THEN
16602    MAP_EVERY (fn w => SPEC_TAC(w,w)) [``y:num->bool``, ``x:num->bool``] THEN
16603    KNOW_TAC ``!x y.
16604     (?n. ~(n IN x <=> n IN y) /\ (\x y n. !m. m < n ==> (m IN x <=> m IN y)) x y n) ==>
16605     (\x y. sup {sum (x INTER (0 .. n)) (\i. inv (3 pow i)) | n IN univ(:num)} <>
16606            sup {sum (y INTER (0 .. n)) (\i. inv (3 pow i)) | n IN univ(:num)}) x y`` THENL
16607    [ALL_TAC, METIS_TAC []] THEN
16608    MATCH_MP_TAC(MESON[]
16609     ``((!P Q n. R P Q n <=> R Q P n) /\ (!P Q. SS P Q <=> SS Q P)) /\
16610       (!P Q. (?n. n IN P /\ ~(n IN Q) /\ R P Q n) ==> SS P Q)
16611       ==> !P Q. (?n:num. ~(n IN P <=> n IN Q) /\ R P Q n) ==> SS P Q``) THEN
16612    SIMP_TAC std_ss [] THEN CONJ_TAC THENL
16613    [ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN METIS_TAC [], SIMP_TAC std_ss []] THEN
16614    MAP_EVERY X_GEN_TAC [``x:num->bool``, ``y:num->bool``] THEN
16615    DISCH_THEN(X_CHOOSE_THEN ``n:num`` STRIP_ASSUME_TAC) THEN
16616    MATCH_MP_TAC(REAL_ARITH ``!z:real. y < z /\ z <= x ==> ~(x = y)``) THEN
16617
16618    EXISTS_TAC ``sum (x INTER ((0:num)..n)) (\i. inv(&3 pow i))`` THEN CONJ_TAC THENL
16619    [ (* goal 2.1 (of 2) *)
16620      MATCH_MP_TAC REAL_LET_TRANS THEN
16621      EXISTS_TAC
16622       ``sum (y INTER ((0:num)..n)) (\i. inv(&3 pow i)) +
16623         &3 / &2 / &3 pow (SUC n)`` THEN
16624
16625      CONJ_TAC THENL
16626       [MATCH_MP_TAC REAL_SUP_LE' THEN
16627        CONJ_TAC THENL [SET_TAC[], SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV]] THEN
16628        X_GEN_TAC ``p:num`` THEN ASM_CASES_TAC ``n:num <= p`` THENL
16629         [MATCH_MP_TAC(REAL_ARITH
16630           ``!d. (s:real = t + d) /\ d <= e ==> s <= t + e``) THEN
16631          EXISTS_TAC ``sum(y INTER (n+(1:num)..p)) (\i. inv (&3 pow i))`` THEN
16632          CONJ_TAC THENL
16633           [ONCE_REWRITE_TAC[INTER_COMM] THEN
16634            SIMP_TAC std_ss [INTER_DEF, SUM_RESTRICT_SET] THEN
16635            ASM_SIMP_TAC std_ss [SUM_COMBINE_R, ZERO_LESS_EQ],
16636            SIMP_TAC std_ss [ADD1, lemma, REAL_LT_IMP_LE]],
16637          MATCH_MP_TAC(REAL_ARITH ``y:real <= x /\ &0 <= d ==> y <= x + d``) THEN
16638          SIMP_TAC real_ss [REAL_LE_DIV, REAL_POS, POW_POS] THEN
16639          MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
16640          SIMP_TAC real_ss [REAL_LE_INV_EQ, POW_POS, REAL_POS] THEN
16641          SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG] THEN MATCH_MP_TAC
16642           (SET_RULE ``s SUBSET t ==> u INTER s SUBSET u INTER t``) THEN
16643          REWRITE_TAC[SUBSET_NUMSEG] THEN ASM_SIMP_TAC arith_ss []],
16644        ONCE_REWRITE_TAC[INTER_COMM] THEN
16645        SIMP_TAC std_ss [INTER_DEF, SUM_RESTRICT_SET] THEN ASM_CASES_TAC ``n = 0:num`` THENL
16646         [FIRST_X_ASSUM SUBST_ALL_TAC THEN
16647          FULL_SIMP_TAC real_ss [SUM_SING, NUMSEG_SING, pow] THEN
16648          SIMP_TAC real_ss [REAL_LT_LDIV_EQ, REAL_INV1] THEN REAL_ARITH_TAC,
16649          ASM_SIMP_TAC std_ss [SUM_CLAUSES_RIGHT, LE_1, ZERO_LESS_EQ, REAL_ADD_RID] THEN
16650          MATCH_MP_TAC(REAL_ARITH ``(s:real = t) /\ d < e ==> s + d < t + e``) THEN
16651          CONJ_TAC THENL
16652           [MATCH_MP_TAC SUM_EQ_NUMSEG THEN
16653            ASM_SIMP_TAC std_ss [ARITH_PROVE ``~(n = 0:num) /\ m <= n - 1 ==> m < n``],
16654            SIMP_TAC real_ss [pow, real_div, REAL_INV_MUL, REAL_MUL_ASSOC] THEN
16655            KNOW_TAC ``3 pow n <> 0:real`` THENL
16656            [MATCH_MP_TAC POW_NZ THEN REAL_ARITH_TAC, DISCH_TAC] THEN
16657            KNOW_TAC ``0:real < 3 pow n`` THENL
16658            [MATCH_MP_TAC REAL_POW_LT THEN REAL_ARITH_TAC, DISCH_TAC] THEN
16659            ASM_SIMP_TAC real_ss [REAL_INV_MUL, REAL_MUL_ASSOC] THEN
16660            GEN_REWR_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN
16661            MATCH_MP_TAC REAL_LT_RMUL_IMP THEN ASM_SIMP_TAC real_ss [REAL_LT_INV_EQ] THEN
16662            ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN
16663            SIMP_TAC real_ss [REAL_MUL_ASSOC, REAL_MUL_LINV] THEN
16664            SIMP_TAC real_ss [REAL_INV_1OVER, REAL_LT_LDIV_EQ]]]],
16665      MP_TAC(ISPEC ``{ sum (x INTER ((0:num)..n)) (\i. inv(&3 pow i)) | n IN univ(:num) }``
16666          SUP) THEN SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV] THEN
16667      KNOW_TAC ``{sum (x INTER (0 .. n)) (\i. inv (3 pow i)) | n | T} <> {} /\
16668         (?b. !n. sum (x INTER (0 .. n)) (\i. inv (3 pow i)) <= b)`` THENL
16669      [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
16670       SIMP_TAC std_ss []] THEN
16671      CONJ_TAC THENL [SET_TAC[], ALL_TAC] THEN
16672      EXISTS_TAC ``&3 / &2 / (&3:real) pow 0`` THEN
16673      SIMP_TAC std_ss [lemma, REAL_LT_IMP_LE]]
16674  ]
16675QED
16676
16677val UNCOUNTABLE_REAL = store_thm ("UNCOUNTABLE_REAL",
16678 ``~COUNTABLE univ(:real)``,
16679  REWRITE_TAC[COUNTABLE, ge_c] THEN
16680  KNOW_TAC ``univ(:num) <_c univ(:num->bool) /\
16681             univ(:num->bool) <=_c univ(:real)`` THENL
16682  [ALL_TAC, METIS_TAC [CARD_LTE_TRANS]] THEN
16683  REWRITE_TAC[CANTOR_THM_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN
16684  ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN REWRITE_TAC[CARD_EQ_REAL]);
16685
16686val CARD_EQ_REAL_IMP_UNCOUNTABLE = store_thm ("CARD_EQ_REAL_IMP_UNCOUNTABLE",
16687 ``!s:real->bool. s =_c univ(:real) ==> ~COUNTABLE s``,
16688  GEN_TAC THEN STRIP_TAC THEN
16689  DISCH_THEN (MP_TAC o SPEC ``univ(:real)`` o MATCH_MP
16690    (SIMP_RULE std_ss [CONJ_EQ_IMP] CARD_EQ_COUNTABLE)) THEN
16691  REWRITE_TAC[UNCOUNTABLE_REAL] THEN ASM_MESON_TAC[CARD_EQ_SYM]);
16692
16693(* ------------------------------------------------------------------------- *)
16694(* Cardinalities of various useful sets.                                     *)
16695(* ------------------------------------------------------------------------- *)
16696
16697val CARD_EQ_EUCLIDEAN = store_thm ("CARD_EQ_EUCLIDEAN",
16698 ``univ(:real) =_c univ(:real)``,
16699  REWRITE_TAC [eq_c, IN_UNIV] THEN EXISTS_TAC ``(\x. x:real)`` THEN
16700  METIS_TAC []);
16701
16702val UNCOUNTABLE_EUCLIDEAN = store_thm ("UNCOUNTABLE_EUCLIDEAN",
16703 ``~COUNTABLE univ(:real)``,
16704  MATCH_MP_TAC CARD_EQ_REAL_IMP_UNCOUNTABLE THEN
16705  REWRITE_TAC[CARD_EQ_EUCLIDEAN]);
16706
16707val CARD_EQ_INTERVAL = store_thm ("CARD_EQ_INTERVAL",
16708 ``(!a b:real. ~(interval(a,b) = {}) ==> (interval[a,b] =_c univ(:real))) /\
16709   (!a b:real. ~(interval(a,b) = {}) ==> (interval(a,b) =_c univ(:real)))``,
16710  SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN REPEAT GEN_TAC THEN
16711  ASM_CASES_TAC ``interval(a:real,b) = {}`` THEN ASM_REWRITE_TAC[] THEN
16712  CONJ_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
16713   [REWRITE_TAC[CARD_LE_UNIV],
16714    KNOW_TAC ``univ(:real) <=_c interval(a:real,b) /\
16715               interval(a:real,b) <=_c interval [(a,b)]`` THENL
16716    [ALL_TAC, METIS_TAC [CARD_LE_TRANS]] THEN
16717    SIMP_TAC std_ss [CARD_LE_SUBSET, INTERVAL_OPEN_SUBSET_CLOSED],
16718    REWRITE_TAC[CARD_LE_UNIV],
16719    ALL_TAC] THEN
16720  RULE_ASSUM_TAC (REWRITE_RULE [INTERVAL_NE_EMPTY]) THEN
16721  FIRST_X_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_OPEN_INTERVAL_UNIV) THEN
16722  DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN
16723  MESON_TAC[CARD_EQ_IMP_LE, CARD_EQ_SYM]);
16724
16725val UNCOUNTABLE_INTERVAL = store_thm ("UNCOUNTABLE_INTERVAL",
16726 ``(!a b. ~(interval(a,b) = {}) ==> ~COUNTABLE(interval[a,b])) /\
16727   (!a b. ~(interval(a,b) = {}) ==> ~COUNTABLE(interval(a,b)))``,
16728  SIMP_TAC std_ss [CARD_EQ_REAL_IMP_UNCOUNTABLE, CARD_EQ_INTERVAL]);
16729
16730val COUNTABLE_OPEN_INTERVAL = store_thm ("COUNTABLE_OPEN_INTERVAL",
16731 ``!a b. COUNTABLE(interval(a,b)) <=> (interval(a,b) = {})``,
16732  MESON_TAC[COUNTABLE_EMPTY, UNCOUNTABLE_INTERVAL]);
16733
16734val CARD_EQ_OPEN = store_thm ("CARD_EQ_OPEN",
16735 ``!s:real->bool. open s /\ ~(s = {}) ==> s =_c univ(:real)``,
16736  REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
16737   [REWRITE_TAC[CARD_LE_UNIV],
16738    UNDISCH_TAC ``open s`` THEN DISCH_TAC THEN
16739    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_CONTAINS_INTERVAL]) THEN
16740    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
16741    DISCH_THEN(X_CHOOSE_TAC ``c:real``) THEN
16742    DISCH_THEN(MP_TAC o SPEC ``c:real``) THEN
16743    ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN
16744    MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``] THEN
16745    ASM_CASES_TAC ``interval(a:real,b) = {}`` THEN
16746    ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN STRIP_TAC THEN
16747    KNOW_TAC ``univ(:real) <=_c interval[a:real,b] /\
16748               interval[a:real,b] <=_c s:real->bool`` THENL
16749    [ALL_TAC, METIS_TAC [CARD_LE_TRANS]] THEN
16750    ASM_SIMP_TAC std_ss [CARD_LE_SUBSET] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN
16751    ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN ASM_SIMP_TAC std_ss [CARD_EQ_INTERVAL]]);
16752
16753val UNCOUNTABLE_OPEN = store_thm ("UNCOUNTABLE_OPEN",
16754 ``!s:real->bool. open s /\ ~(s = {}) ==> ~(COUNTABLE s)``,
16755  SIMP_TAC std_ss [CARD_EQ_OPEN, CARD_EQ_REAL_IMP_UNCOUNTABLE]);
16756
16757val CARD_EQ_BALL = store_thm ("CARD_EQ_BALL",
16758 ``!a:real r. &0 < r ==> ball(a,r) =_c  univ(:real)``,
16759  SIMP_TAC std_ss [CARD_EQ_OPEN, OPEN_BALL, BALL_EQ_EMPTY, GSYM REAL_NOT_LT]);
16760
16761val CARD_EQ_CBALL = store_thm ("CARD_EQ_CBALL",
16762 ``!a:real r. &0 < r ==> cball(a,r) =_c univ(:real)``,
16763  REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
16764   [REWRITE_TAC[CARD_LE_UNIV],
16765    KNOW_TAC ``univ(:real) <=_c ball(a:real,r) /\
16766               ball(a:real,r) <=_c cball (a,r:real)`` THENL
16767    [ALL_TAC, METIS_TAC [CARD_LE_TRANS]] THEN
16768    SIMP_TAC std_ss [CARD_LE_SUBSET, BALL_SUBSET_CBALL] THEN
16769    MATCH_MP_TAC CARD_EQ_IMP_LE THEN
16770    ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN ASM_SIMP_TAC std_ss [CARD_EQ_BALL]]);
16771
16772val FINITE_IMP_NOT_OPEN = store_thm ("FINITE_IMP_NOT_OPEN",
16773 ``!s:real->bool. FINITE s /\ ~(s = {}) ==> ~(open s)``,
16774  MESON_TAC[UNCOUNTABLE_OPEN, FINITE_IMP_COUNTABLE]);
16775
16776val OPEN_IMP_INFINITE = store_thm ("OPEN_IMP_INFINITE",
16777 ``!s. open s ==> (s = {}) \/ INFINITE s``,
16778  MESON_TAC[FINITE_IMP_NOT_OPEN]);
16779
16780val EMPTY_INTERIOR_FINITE = store_thm ("EMPTY_INTERIOR_FINITE",
16781 ``!s:real->bool. FINITE s ==> (interior s = {})``,
16782  REPEAT STRIP_TAC THEN MP_TAC(ISPEC ``s:real->bool`` OPEN_INTERIOR) THEN
16783  ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN
16784  MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] FINITE_IMP_NOT_OPEN) THEN
16785  MATCH_MP_TAC SUBSET_FINITE_I THEN EXISTS_TAC ``s:real->bool`` THEN
16786  ASM_REWRITE_TAC[INTERIOR_SUBSET]);
16787
16788val FINITE_CBALL = store_thm ("FINITE_CBALL",
16789 ``!a:real r. FINITE(cball(a,r)) <=> r <= &0``,
16790  REPEAT STRIP_TAC THEN ASM_CASES_TAC ``r < &0:real`` THEN
16791  ASM_SIMP_TAC std_ss [CBALL_EMPTY, REAL_LT_IMP_LE, FINITE_EMPTY] THEN
16792  ASM_CASES_TAC ``r = &0:real`` THEN
16793  ASM_REWRITE_TAC[CBALL_TRIVIAL, FINITE_SING, REAL_LE_REFL] THEN
16794  EQ_TAC THENL [ALL_TAC, ASM_REAL_ARITH_TAC] THEN
16795  DISCH_THEN(MP_TAC o MATCH_MP EMPTY_INTERIOR_FINITE) THEN
16796  REWRITE_TAC[INTERIOR_CBALL, BALL_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC);
16797
16798val FINITE_BALL = store_thm ("FINITE_BALL",
16799 ``!a:real r. FINITE(ball(a,r)) <=> r <= &0``,
16800  REPEAT STRIP_TAC THEN ASM_CASES_TAC ``r <= &0:real`` THEN
16801  ASM_SIMP_TAC std_ss [BALL_EMPTY, REAL_LT_IMP_LE, FINITE_EMPTY] THEN
16802  DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[CONJ_EQ_IMP]
16803        FINITE_IMP_NOT_OPEN)) THEN
16804  REWRITE_TAC[OPEN_BALL, BALL_EQ_EMPTY] THEN ASM_REAL_ARITH_TAC);
16805
16806(* ------------------------------------------------------------------------- *)
16807(* "Iff" forms of constancy of function from connected set into a set that   *)
16808(* is smaller than R, or countable, or finite, or disconnected, or discrete. *)
16809(* ------------------------------------------------------------------------- *)
16810
16811val CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ = store_thm
16812  ("CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ",
16813  ``(!s. connected s <=>
16814         !f:real->real t.
16815            f continuous_on s /\ IMAGE f s SUBSET t /\
16816            (!y. y IN t ==> (connected_component t y = {y}))
16817            ==> ?a. !x. x IN s ==> (f x = a)) /\
16818    (!s. connected s <=>
16819         !f:real->real.
16820            f continuous_on s /\
16821            (!x. x IN s
16822                 ==> ?e. &0 < e /\
16823                         !y. y IN s /\ ~(f y = f x) ==> e <= abs(f y - f x))
16824            ==> ?a. !x. x IN s ==> (f x = a)) /\
16825    (!s. connected s <=>
16826         !f:real->real.
16827            f continuous_on s /\ FINITE(IMAGE f s)
16828            ==> ?a. !x. x IN s ==> (f x = a))``,
16829  SIMP_TAC std_ss [GSYM FORALL_AND_THM] THEN X_GEN_TAC ``s:real->bool`` THEN
16830  MATCH_MP_TAC(TAUT
16831    `(s ==> t) /\ (t ==> u) /\ (u ==> v) /\ (v ==> s)
16832     ==> (s <=> t) /\ (s <=> u) /\ (s <=> v)`) THEN
16833  REPEAT CONJ_TAC THENL
16834   [REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN
16835    ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
16836    FIRST_X_ASSUM(X_CHOOSE_TAC ``x:real`` o
16837        REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
16838    EXISTS_TAC ``(f:real->real) x`` THEN
16839    MATCH_MP_TAC(SET_RULE
16840     ``IMAGE f s SUBSET {a} ==> !y. y IN s ==> (f y = a)``) THEN
16841    FIRST_X_ASSUM(MP_TAC o SPEC ``(f:real->real) x``) THEN
16842    KNOW_TAC ``(f:real->real) x IN t`` THENL
16843    [ASM_SET_TAC [], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
16844     DISCH_THEN(SUBST1_TAC o SYM)] THEN
16845    MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
16846    ASM_SIMP_TAC std_ss [CONNECTED_CONTINUOUS_IMAGE] THEN ASM_SET_TAC [],
16847    REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
16848    EXISTS_TAC ``IMAGE (f:real->real) s`` THEN
16849    ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE, SUBSET_REFL] THEN
16850    X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
16851    FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
16852    DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
16853    MATCH_MP_TAC(SET_RULE
16854     ``(!y. y IN s /\ f y IN connected_component (IMAGE f s) a ==> (f y = a)) /\
16855       connected_component (IMAGE f s) a SUBSET (IMAGE f s) /\
16856       connected_component (IMAGE f s) a a
16857       ==> (connected_component (IMAGE f s) a = {a})``) THEN
16858    SIMP_TAC std_ss [CONNECTED_COMPONENT_SUBSET, CONNECTED_COMPONENT_REFL_EQ] THEN
16859    ASM_SIMP_TAC std_ss [FUN_IN_IMAGE] THEN X_GEN_TAC ``y:real`` THEN STRIP_TAC THEN
16860    MP_TAC(ISPEC ``connected_component (IMAGE (f:real->real) s) (f x)``
16861        CONNECTED_CLOSED) THEN
16862    REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN
16863    ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN
16864    ASM_REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC
16865     [``cball((f:real->real) x,e / &2)``,
16866      ``univ(:real) DIFF ball((f:real->real) x,e)``] THEN
16867    SIMP_TAC std_ss [GSYM OPEN_CLOSED, OPEN_BALL, CLOSED_CBALL] THEN
16868    REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REPEAT CONJ_TAC THENL
16869     [REWRITE_TAC[SUBSET_DEF, IN_CBALL, IN_UNION, IN_DIFF, IN_BALL, IN_UNIV] THEN
16870      ONCE_REWRITE_TAC [METIS []
16871       ``(dist (f x,x') <= e / 2 \/ ~(dist (f x,x') < e)) =
16872         (\x'. dist (f x,x') <= e / 2 \/ ~(dist (f x,x') < e)) x'``] THEN
16873      MATCH_MP_TAC(MESON[SUBSET_DEF, CONNECTED_COMPONENT_SUBSET]
16874       ``(!x. x IN s ==> P x)
16875        ==> (!x. x IN connected_component s y ==> P x)``) THEN
16876      SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN X_GEN_TAC ``z:real`` THEN
16877      DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``z:real``) THEN
16878      ASM_SIMP_TAC real_ss [dist, REAL_LE_RDIV_EQ] THEN ASM_REAL_ARITH_TAC,
16879      MATCH_MP_TAC(SET_RULE
16880       ``(!x. x IN s /\ x IN t ==> F) ==> (s INTER t INTER u = {})``) THEN
16881      REWRITE_TAC[IN_BALL, IN_CBALL, IN_DIFF, IN_UNIV] THEN
16882      UNDISCH_TAC ``&0 < e:real`` THEN
16883      ASM_SIMP_TAC real_ss [dist, REAL_LE_RDIV_EQ] THEN REAL_ARITH_TAC,
16884      EXISTS_TAC ``(f:real->real) x`` THEN
16885      ASM_SIMP_TAC std_ss [CENTRE_IN_CBALL, REAL_HALF, REAL_LT_IMP_LE, IN_INTER] THEN
16886      SIMP_TAC std_ss [SPECIFICATION] THEN
16887      ASM_SIMP_TAC std_ss [CONNECTED_COMPONENT_REFL_EQ, FUN_IN_IMAGE],
16888      EXISTS_TAC ``(f:real->real) y`` THEN
16889      ASM_REWRITE_TAC[IN_INTER, IN_DIFF, IN_UNIV, IN_BALL, REAL_NOT_LT] THEN
16890      ASM_SIMP_TAC std_ss [ONCE_REWRITE_RULE[DIST_SYM] dist]],
16891    DISCH_TAC THEN X_GEN_TAC ``f:real->real`` THEN
16892    POP_ASSUM (MP_TAC o SPEC ``f:real->real``) THEN
16893    DISCH_THEN(fn th => STRIP_TAC THEN MATCH_MP_TAC th) THEN
16894    ASM_REWRITE_TAC[] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
16895    ASM_CASES_TAC ``IMAGE (f:real->real) s DELETE (f x) = {}`` THENL
16896     [EXISTS_TAC ``&1:real`` THEN REWRITE_TAC[REAL_LT_01] THEN ASM_SET_TAC [],
16897      ALL_TAC] THEN
16898    EXISTS_TAC
16899     ``inf{abs(z - f x) |z| z IN IMAGE (f:real->real) s DELETE (f x)}`` THEN
16900    SIMP_TAC real_ss [GSYM IMAGE_DEF] THEN
16901    ASM_SIMP_TAC std_ss [REAL_LT_INF_FINITE, REAL_INF_LE_FINITE, FINITE_DELETE,
16902                 IMAGE_FINITE, IMAGE_EQ_EMPTY] THEN
16903    SIMP_TAC std_ss [FORALL_IN_IMAGE, EXISTS_IN_IMAGE] THEN
16904    SIMP_TAC real_ss [IN_DELETE, GSYM ABS_NZ, REAL_SUB_0, IN_IMAGE] THEN
16905    MESON_TAC[REAL_LE_REFL],
16906    REWRITE_TAC[CONNECTED_CLOSED_IN_EQ] THEN
16907    ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN
16908    SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN
16909    MAP_EVERY X_GEN_TAC [``t:real->bool``, ``u:real->bool``] THEN
16910    STRIP_TAC THEN EXISTS_TAC
16911     ``(\x. if x IN t then 0 else 1:real):real->real`` THEN
16912    SIMP_TAC std_ss [NOT_IMP] THEN REPEAT CONJ_TAC THENL
16913     [EXPAND_TAC "s" THEN
16914      ONCE_REWRITE_TAC [METIS [] ``(\x:real. if x IN t then 0 else 1:real) =
16915                   (\x. if (\x. x IN t) x then (\x. 0) x else (\x. 1) x)``] THEN
16916      MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN
16917      ASM_SIMP_TAC std_ss [CONTINUOUS_ON_CONST] THEN ASM_SET_TAC [],
16918      MATCH_MP_TAC SUBSET_FINITE_I THEN EXISTS_TAC ``{0:real;1:real}`` THEN
16919      REWRITE_TAC[FINITE_INSERT, FINITE_EMPTY] THEN SET_TAC[],
16920      SUBGOAL_THEN ``?a b:real. a IN s /\ a IN t /\ b IN s /\ ~(b IN t)``
16921      STRIP_ASSUME_TAC THENL
16922       [ASM_SET_TAC [], GEN_TAC] THEN CCONTR_TAC THEN
16923      POP_ASSUM (MP_TAC o SIMP_RULE std_ss []) THEN
16924      DISCH_THEN(fn th => MP_TAC(SPEC ``a:real`` th) THEN
16925                           MP_TAC(SPEC ``b:real`` th)) THEN
16926      ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC]]);
16927
16928val CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ = store_thm
16929  ("CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ",
16930 ``(!s. connected s <=>
16931         !f:real->real t.
16932            f continuous_on s /\ IMAGE f s SUBSET t /\
16933            (!y. y IN t ==> (connected_component t y = {y}))
16934            ==> ?a. !x. x IN s ==> (f x = a))``,
16935  REWRITE_TAC [CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ]);
16936
16937val CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ = store_thm
16938  ("CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ",
16939 ``(!s. connected s <=>
16940         !f:real->real.
16941            f continuous_on s /\
16942            (!x. x IN s
16943                 ==> ?e. &0 < e /\
16944                         !y. y IN s /\ ~(f y = f x) ==> e <= abs(f y - f x))
16945            ==> ?a. !x. x IN s ==> (f x = a)) ``,
16946  METIS_TAC [CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ]);
16947
16948val CONTINUOUS_FINITE_RANGE_CONSTANT_EQ = store_thm
16949  ("CONTINUOUS_FINITE_RANGE_CONSTANT_EQ",
16950 ``(!s. connected s <=>
16951         !f:real->real.
16952            f continuous_on s /\ FINITE(IMAGE f s)
16953            ==> ?a. !x. x IN s ==> (f x = a))``,
16954  METIS_TAC [CONTINUOUS_DISCONNECTED_DISCRETE_FINITE_RANGE_CONSTANT_EQ]);
16955
16956val CONTINUOUS_DISCONNECTED_RANGE_CONSTANT = store_thm
16957  ("CONTINUOUS_DISCONNECTED_RANGE_CONSTANT",
16958 ``!f:real->real s.
16959        connected s /\
16960        f continuous_on s /\ IMAGE f s SUBSET t /\
16961        (!y. y IN t ==> (connected_component t y = {y}))
16962        ==> ?a. !x. x IN s ==> (f x = a)``,
16963  MESON_TAC[CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ]);
16964
16965val CONTINUOUS_DISCRETE_RANGE_CONSTANT = store_thm
16966  ("CONTINUOUS_DISCRETE_RANGE_CONSTANT",
16967 ``!f:real->real s.
16968        connected s /\
16969        f continuous_on s /\
16970        (!x. x IN s
16971             ==> ?e. &0 < e /\
16972                     !y. y IN s /\ ~(f y = f x) ==> e <= abs(f y - f x))
16973        ==> ?a. !x. x IN s ==> (f x = a)``,
16974  KNOW_TAC ``!s f:real->real.
16975        connected s /\
16976        f continuous_on s /\
16977        (!x. x IN s
16978             ==> ?e. &0 < e /\
16979                     !y. y IN s /\ ~(f y = f x) ==> e <= abs(f y - f x))
16980        ==> ?a. !x. x IN s ==> (f x = a)`` THENL
16981  [ALL_TAC, METIS_TAC [SWAP_FORALL_THM]] THEN
16982  SIMP_TAC std_ss [RIGHT_FORALL_IMP_THM, CONJ_EQ_IMP] THEN
16983  SIMP_TAC std_ss [AND_IMP_INTRO, GSYM CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ]);
16984
16985val CONTINUOUS_FINITE_RANGE_CONSTANT = store_thm
16986  ("CONTINUOUS_FINITE_RANGE_CONSTANT",
16987 ``!f:real->real s.
16988        connected s /\
16989        f continuous_on s /\
16990        FINITE(IMAGE f s)
16991        ==> ?a. !x. x IN s ==> (f x = a)``,
16992  MESON_TAC[CONTINUOUS_FINITE_RANGE_CONSTANT_EQ]);
16993
16994(* ------------------------------------------------------------------------- *)
16995(* Homeomorphism of hyperplanes.                                             *)
16996(* ------------------------------------------------------------------------- *)
16997
16998val lemma = prove (
16999   ``~(a = 0)
17000     ==> {x:real | a * x = b} homeomorphic {x:real | x = &0}``,
17001    REPEAT STRIP_TAC THEN SUBGOAL_THEN ``?c:real. a * c = b``
17002    STRIP_ASSUME_TAC THENL
17003     [EXISTS_TAC ``inv a * b:real`` THEN
17004      ASM_SIMP_TAC real_ss [REAL_MUL_RINV, REAL_MUL_ASSOC], ALL_TAC] THEN
17005     REWRITE_TAC [homeomorphic, homeomorphism] THEN
17006     EXISTS_TAC ``(\x. 0):real->real`` THEN
17007     EXISTS_TAC ``(\x:real. inv a * b:real)`` THEN
17008     SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE] THEN
17009     SIMP_TAC std_ss [CONTINUOUS_ON_CONST] THEN
17010     REPEAT STRIP_TAC THENL
17011     [ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN
17012      ASM_CASES_TAC ``0 < a:real`` THENL
17013      [ASM_SIMP_TAC real_ss [REAL_EQ_LDIV_EQ] THEN ASM_REAL_ARITH_TAC, ALL_TAC] THEN
17014      FULL_SIMP_TAC real_ss [REAL_NOT_LT, REAL_LE_LT] THENL [ALL_TAC, METIS_TAC []] THEN
17015      KNOW_TAC ``a < 0 ==> 0 < -a:real`` THENL [REAL_ARITH_TAC, ASM_REWRITE_TAC []] THEN
17016      DISCH_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_EQ_NEG] THEN
17017      REWRITE_TAC [real_div, REAL_ARITH ``-(a * b) = a * -b:real``] THEN
17018      ASM_SIMP_TAC std_ss [REAL_NEG_INV, GSYM real_div] THEN
17019      ASM_SIMP_TAC real_ss [REAL_EQ_LDIV_EQ] THEN ASM_REAL_ARITH_TAC,
17020      METIS_TAC [],
17021      ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN
17022      ASM_CASES_TAC ``0 < a:real`` THENL
17023      [ASM_SIMP_TAC real_ss [REAL_EQ_RDIV_EQ] THEN ASM_REAL_ARITH_TAC, ALL_TAC] THEN
17024      FULL_SIMP_TAC real_ss [REAL_NOT_LT, REAL_LE_LT] THENL [ALL_TAC, METIS_TAC []] THEN
17025      KNOW_TAC ``a < 0 ==> 0 < -a:real`` THENL [REAL_ARITH_TAC, ASM_REWRITE_TAC []] THEN
17026      DISCH_TAC THEN ONCE_REWRITE_TAC [GSYM REAL_EQ_NEG] THEN
17027      REWRITE_TAC [real_div, REAL_ARITH ``-(a * b) = a * -b:real``] THEN
17028      ASM_SIMP_TAC std_ss [REAL_NEG_INV, GSYM real_div] THEN
17029      ASM_SIMP_TAC real_ss [REAL_EQ_RDIV_EQ] THEN ASM_REAL_ARITH_TAC]);
17030
17031val HOMEOMORPHIC_HYPERPLANES = store_thm ("HOMEOMORPHIC_HYPERPLANES",
17032 ``!a:real b c:real d.
17033        ~(a = 0) /\ ~(c = 0)
17034        ==> {x | a * x = b} homeomorphic {x | c * x = d}``,
17035  REPEAT STRIP_TAC THEN
17036  MATCH_MP_TAC HOMEOMORPHIC_TRANS THEN EXISTS_TAC ``{x:real | x = &0}`` THEN
17037  ASM_SIMP_TAC std_ss [lemma] THEN ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN
17038  ASM_SIMP_TAC std_ss [lemma]);
17039
17040val HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE = store_thm
17041  ("HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE",
17042 ``!a:real b c.
17043        ~(a = 0)
17044        ==> {x | a * x = b} homeomorphic {x:real | x = c}``,
17045  REPEAT STRIP_TAC THEN
17046  SUBGOAL_THEN ``{x:real | x = c} = {x | 1 * x = c}`` SUBST1_TAC
17047  THENL [ASM_SIMP_TAC real_ss [], MATCH_MP_TAC HOMEOMORPHIC_HYPERPLANES] THEN
17048  ASM_SIMP_TAC real_ss []);
17049
17050val HOMEOMORPHIC_STANDARD_HYPERPLANE_HYPERPLANE = store_thm
17051  ("HOMEOMORPHIC_STANDARD_HYPERPLANE_HYPERPLANE",
17052 ``!a:real b c.
17053        ~(a = 0)
17054        ==> {x:real | x = c} homeomorphic {x | a * x = b}``,
17055  ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN
17056  SIMP_TAC std_ss [HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE]);
17057
17058(* ------------------------------------------------------------------------- *)
17059(* "Isometry" (up to constant bounds) of injective linear map etc.           *)
17060(* ------------------------------------------------------------------------- *)
17061
17062val CAUCHY_ISOMETRIC = store_thm ("CAUCHY_ISOMETRIC",
17063 ``!f s e x.
17064        &0 < e /\ subspace s /\
17065        linear f /\ (!x. x IN s ==> abs(f x) >= e * abs(x)) /\
17066        (!n. x(n) IN s) /\ cauchy(f o x)
17067        ==> cauchy x``,
17068  REPEAT GEN_TAC THEN REWRITE_TAC[real_ge] THEN
17069  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
17070  SIMP_TAC std_ss [CAUCHY, dist, o_THM] THEN
17071  FIRST_ASSUM(fn th => REWRITE_TAC[GSYM(MATCH_MP LINEAR_SUB th)]) THEN
17072  DISCH_THEN(fn th => X_GEN_TAC ``d:real`` THEN DISCH_TAC THEN MP_TAC th) THEN
17073  DISCH_THEN(MP_TAC o SPEC ``d * e:real``) THEN ASM_SIMP_TAC std_ss [REAL_LT_MUL] THEN
17074  METIS_TAC[REAL_LE_RDIV_EQ, REAL_MUL_SYM, REAL_LET_TRANS, SUBSPACE_SUB,
17075                REAL_LT_LDIV_EQ]);
17076
17077val COMPLETE_ISOMETRIC_IMAGE = store_thm ("COMPLETE_ISOMETRIC_IMAGE",
17078 ``!f:real->real s e.
17079        &0 < e /\ subspace s /\
17080        linear f /\ (!x. x IN s ==> abs(f x) >= e * abs(x)) /\
17081        complete s
17082        ==> complete(IMAGE f s)``,
17083  REPEAT GEN_TAC THEN SIMP_TAC std_ss [complete, EXISTS_IN_IMAGE] THEN
17084  STRIP_TAC THEN X_GEN_TAC ``g:num->real`` THEN
17085  SIMP_TAC std_ss [IN_IMAGE, SKOLEM_THM, FORALL_AND_THM] THEN
17086  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
17087  DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` MP_TAC) THEN
17088  ONCE_REWRITE_TAC [METIS [] ``(!n. g n = f (x n)) = (!n. g n = (\n. f (x n)) n)``] THEN
17089  GEN_REWR_TAC (LAND_CONV o LAND_CONV) [GSYM FUN_EQ_THM] THEN
17090  REWRITE_TAC[GSYM o_DEF] THEN
17091  DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN
17092  FIRST_X_ASSUM(MP_TAC o SPEC ``x:num->real``) THEN
17093  ASM_MESON_TAC[CAUCHY_ISOMETRIC, LINEAR_CONTINUOUS_AT,
17094                CONTINUOUS_AT_SEQUENTIALLY]);
17095
17096val INJECTIVE_IMP_ISOMETRIC = store_thm ("INJECTIVE_IMP_ISOMETRIC",
17097 ``!f:real->real s.
17098        closed s /\ subspace s /\
17099        linear f /\ (!x. x IN s /\ (f x = 0) ==> (x = 0))
17100        ==> ?e. &0 < e /\ !x. x IN s ==> abs(f x) >= e * abs(x)``,
17101  REPEAT STRIP_TAC THEN
17102  ASM_CASES_TAC ``s SUBSET {0 :real}`` THENL
17103   [EXISTS_TAC ``&1:real`` THEN REWRITE_TAC[REAL_LT_01, REAL_MUL_LID, real_ge] THEN
17104    ASM_MESON_TAC[SUBSET_DEF, IN_SING, ABS_0, LINEAR_0, REAL_LE_REFL],
17105    ALL_TAC] THEN
17106  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN
17107  SIMP_TAC std_ss [NOT_FORALL_THM, NOT_IMP, IN_SING] THEN
17108  DISCH_THEN(X_CHOOSE_THEN ``a:real`` STRIP_ASSUME_TAC) THEN
17109  MP_TAC(ISPECL
17110   [``{(f:real->real) x | x IN s /\ (abs(x) = abs(a:real))}``,
17111    ``0:real``] DISTANCE_ATTAINS_INF) THEN
17112  KNOW_TAC ``closed {(f:real->real) x | x IN s /\ (abs x = abs a)} /\
17113   {f x | x IN s /\ (abs x = abs a)} <> {}`` THENL
17114   [SIMP_TAC std_ss [GSYM MEMBER_NOT_EMPTY, GSPECIFICATION] THEN
17115    CONJ_TAC THENL [ALL_TAC, METIS_TAC[]] THEN
17116    MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
17117    SUBST1_TAC(SET_RULE
17118     ``{f x | x IN s /\ (abs(x) = abs(a:real))} =
17119       IMAGE (f:real->real) (s INTER {x | abs x = abs a})``) THEN
17120    MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
17121    ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON] THEN
17122    MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN
17123    SUBGOAL_THEN
17124     ``{x:real | abs x = abs(a:real)} = frontier(cball(0,abs a))``
17125    SUBST1_TAC THENL
17126     [ASM_SIMP_TAC real_ss [FRONTIER_CBALL, GSYM ABS_NZ, dist, REAL_SUB_LZERO,
17127                   ABS_NEG, sphere],
17128      ASM_SIMP_TAC std_ss [COMPACT_FRONTIER, COMPACT_CBALL]],
17129    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
17130  ONCE_REWRITE_TAC [METIS [] ``{(f:real->real) x | x IN s /\ (abs x = abs a)} =
17131                          {f x | (\x. x IN s /\ (abs x = abs a)) x}``] THEN
17132  ONCE_REWRITE_TAC[SET_RULE ``{f x | P x} = IMAGE f {x | P x}``] THEN
17133  SIMP_TAC std_ss [FORALL_IN_IMAGE, EXISTS_IN_IMAGE] THEN
17134  DISCH_THEN(X_CHOOSE_THEN ``b:real`` MP_TAC) THEN
17135  SIMP_TAC std_ss [GSPECIFICATION, dist, REAL_SUB_LZERO, ABS_NEG] THEN
17136  STRIP_TAC THEN SIMP_TAC std_ss [CLOSED_LIMPT, LIMPT_APPROACHABLE] THEN
17137  EXISTS_TAC ``abs((f:real->real) b) / abs(b)`` THEN CONJ_TAC THENL
17138   [ASM_MESON_TAC[REAL_LT_DIV, GSYM ABS_NZ, ABS_ZERO], ALL_TAC] THEN
17139  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
17140  ASM_CASES_TAC ``x:real = 0`` THENL
17141   [FIRST_ASSUM(fn th => ASM_REWRITE_TAC[MATCH_MP LINEAR_0 th]) THEN
17142    REWRITE_TAC[ABS_0, REAL_MUL_RZERO, real_ge, REAL_LE_REFL],
17143    ALL_TAC] THEN
17144  FIRST_X_ASSUM(MP_TAC o SPEC ``(abs(a:real) / abs(x)) * x:real``) THEN
17145  KNOW_TAC ``abs a / abs x * x IN s /\ (abs (abs a / abs x * x) = abs a:real)`` THENL
17146   [KNOW_TAC ``(abs x <> 0:real) /\ (abs a <> 0:real)`` THENL
17147    [UNDISCH_TAC ``a <> 0:real`` THEN POP_ASSUM MP_TAC THEN
17148     REAL_ARITH_TAC, STRIP_TAC] THEN
17149    ASM_SIMP_TAC real_ss [ABS_MUL, ABS_DIV, ABS_ABS] THEN
17150    FULL_SIMP_TAC std_ss [subspace] THEN
17151    ASM_SIMP_TAC real_ss [REAL_DIV_RMUL, ABS_ZERO],
17152    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
17153  UNDISCH_TAC ``linear f`` THEN DISCH_TAC THEN
17154  FIRST_ASSUM(fn th => SIMP_TAC std_ss [MATCH_MP LINEAR_CMUL th]) THEN
17155  KNOW_TAC ``(abs x <> 0:real) /\ (abs a <> 0:real)`` THENL
17156    [UNDISCH_TAC ``a <> 0:real`` THEN UNDISCH_TAC ``x <> 0:real`` THEN
17157     REAL_ARITH_TAC, STRIP_TAC] THEN
17158  ASM_SIMP_TAC real_ss [ABS_MUL, ABS_DIV, ABS_ABS, real_ge] THEN
17159  ASM_SIMP_TAC real_ss [GSYM REAL_LE_RDIV_EQ, REAL_LE_LDIV_EQ, GSYM ABS_NZ] THEN
17160  SIMP_TAC std_ss [real_div, REAL_MUL_ASSOC] THEN REAL_ARITH_TAC);
17161
17162val CLOSED_INJECTIVE_IMAGE_SUBSPACE = store_thm ("CLOSED_INJECTIVE_IMAGE_SUBSPACE",
17163 ``!f s. subspace s /\
17164         linear f /\
17165         (!x. x IN s /\ (f(x) = 0) ==> (x = 0)) /\
17166         closed s
17167         ==> closed(IMAGE f s)``,
17168  REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM COMPLETE_EQ_CLOSED] THEN
17169  MATCH_MP_TAC COMPLETE_ISOMETRIC_IMAGE THEN
17170  ASM_SIMP_TAC std_ss [COMPLETE_EQ_CLOSED] THEN
17171  MATCH_MP_TAC INJECTIVE_IMP_ISOMETRIC THEN
17172  ASM_REWRITE_TAC[]);
17173
17174(* ------------------------------------------------------------------------- *)
17175(* Relating linear images to open/closed/interior/closure.                   *)
17176(* ------------------------------------------------------------------------- *)
17177
17178val OPEN_SURJECTIVE_LINEAR_IMAGE = store_thm ("OPEN_SURJECTIVE_LINEAR_IMAGE",
17179 ``!f:real->real.
17180        linear f /\ (!y. ?x. f x = y)
17181        ==> !s. open s ==> open(IMAGE f s)``,
17182  GEN_TAC THEN STRIP_TAC THEN
17183  SIMP_TAC std_ss [open_def, FORALL_IN_IMAGE] THEN
17184  FIRST_ASSUM(MP_TAC o GEN ``k:num`` o SPEC ``if (1 = k:num) then &1 else &0:real``) THEN
17185  SIMP_TAC std_ss [SKOLEM_THM] THEN
17186  DISCH_THEN(X_CHOOSE_THEN ``b:num->real`` STRIP_ASSUME_TAC) THEN
17187  SUBGOAL_THEN ``bounded(IMAGE (b:num->real) ((1:num)..(1:num)))`` MP_TAC THENL
17188   [SIMP_TAC std_ss [FINITE_IMP_BOUNDED, IMAGE_FINITE, FINITE_NUMSEG], ALL_TAC] THEN
17189  SIMP_TAC std_ss [BOUNDED_POS, FORALL_IN_IMAGE, IN_NUMSEG] THEN
17190  DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN
17191  X_GEN_TAC ``s:real->bool`` THEN DISCH_TAC THEN
17192  X_GEN_TAC ``x:real`` THEN POP_ASSUM (MP_TAC o SPEC ``x:real``) THEN
17193  ASM_CASES_TAC ``(x:real) IN s`` THEN
17194  ASM_REWRITE_TAC[] THEN
17195  DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
17196  EXISTS_TAC ``e / B / &(1):real`` THEN
17197  ASM_SIMP_TAC real_ss [REAL_LT_DIV, REAL_LT, LE_1] THEN
17198  X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN REWRITE_TAC[IN_IMAGE] THEN
17199  ABBREV_TAC ``u = y - (f:real->real) x`` THEN
17200  EXISTS_TAC ``x + sum(1 .. 1) (\i. (u:real) * b i):real`` THEN
17201  ASM_SIMP_TAC std_ss [LINEAR_ADD, LINEAR_SUM, FINITE_NUMSEG, o_DEF,
17202               LINEAR_CMUL] THEN
17203  CONJ_TAC THENL [EXPAND_TAC "u" THEN SIMP_TAC std_ss [NUMSEG_SING, SUM_SING] THEN
17204                  REAL_ARITH_TAC, ALL_TAC] THEN
17205  FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC [dist] THEN
17206  REWRITE_TAC[REAL_ARITH ``abs(x + y - x) = abs y:real``] THEN
17207  MATCH_MP_TAC REAL_LET_TRANS THEN
17208  EXISTS_TAC ``(dist(y,(f:real->real) x) * &(1)) * B:real`` THEN
17209  ASM_SIMP_TAC real_ss [GSYM REAL_LT_RDIV_EQ, REAL_LT, LE_1] THEN
17210  MATCH_MP_TAC SUM_ABS_TRIANGLE THEN REWRITE_TAC[FINITE_NUMSEG] THEN
17211  EXPAND_TAC "u" THEN SIMP_TAC std_ss [NUMSEG_SING, SUM_SING] THEN
17212  REWRITE_TAC [ABS_MUL] THEN
17213  UNDISCH_TAC ``!x. 1 <= x /\ x <= 1 ==> abs ((b:num->real) x) <= B`` THEN
17214  DISCH_THEN (MP_TAC o SPEC ``1:num``) THEN ASM_SIMP_TAC real_ss [dist] THEN
17215  DISCH_TAC THEN MATCH_MP_TAC REAL_LE_LMUL_IMP THEN
17216  ASM_SIMP_TAC std_ss [ABS_POS]);
17217
17218val OPEN_BIJECTIVE_LINEAR_IMAGE_EQ = store_thm ("OPEN_BIJECTIVE_LINEAR_IMAGE_EQ",
17219 ``!f:real->real s.
17220        linear f /\ (!x y. (f x = f y) ==> (x = y)) /\ (!y. ?x. f x = y)
17221        ==> (open(IMAGE f s) <=> open s)``,
17222  REPEAT STRIP_TAC THEN EQ_TAC THENL
17223   [DISCH_TAC, ASM_MESON_TAC[OPEN_SURJECTIVE_LINEAR_IMAGE]] THEN
17224  SUBGOAL_THEN ``s = {x | (f:real->real) x IN IMAGE f s}``
17225  SUBST1_TAC THENL [ASM_SET_TAC [], ALL_TAC] THEN
17226  MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE_UNIV THEN
17227  ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_AT]);
17228
17229val CLOSED_INJECTIVE_LINEAR_IMAGE = store_thm ("CLOSED_INJECTIVE_LINEAR_IMAGE",
17230 ``!f:real->real.
17231        linear f /\ (!x y. (f x = f y) ==> (x = y))
17232        ==> !s. closed s ==> closed(IMAGE f s)``,
17233  REPEAT STRIP_TAC THEN
17234  MP_TAC(ISPEC ``f:real->real`` LINEAR_INJECTIVE_LEFT_INVERSE) THEN
17235  ASM_REWRITE_TAC[] THEN
17236  DISCH_THEN(X_CHOOSE_THEN ``g:real->real`` STRIP_ASSUME_TAC) THEN
17237  MATCH_MP_TAC CLOSED_IN_CLOSED_TRANS THEN
17238  EXISTS_TAC ``IMAGE (f:real->real) univ(:real)`` THEN
17239  CONJ_TAC THENL
17240   [MP_TAC(ISPECL [``g:real->real``, ``IMAGE (f:real->real) univ(:real)``,
17241                   ``IMAGE (g:real->real) (IMAGE (f:real->real) s)``]
17242        CONTINUOUS_CLOSED_IN_PREIMAGE) THEN
17243    ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_ON] THEN
17244    KNOW_TAC ``closed (IMAGE (g:real->real) (IMAGE (f:real->real) s))`` THENL
17245     [ASM_REWRITE_TAC[GSYM IMAGE_COMPOSE, IMAGE_ID],
17246      DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
17247    MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN
17248    FIRST_X_ASSUM(MP_TAC o SIMP_RULE std_ss [FUN_EQ_THM]) THEN
17249    SIMP_TAC std_ss [EXTENSION, o_THM, I_THM] THEN SET_TAC[],
17250    MATCH_MP_TAC CLOSED_INJECTIVE_IMAGE_SUBSPACE THEN
17251    ASM_REWRITE_TAC[IN_UNIV, SUBSPACE_UNIV, CLOSED_UNIV] THEN
17252    X_GEN_TAC ``x:real`` THEN
17253    DISCH_THEN(MP_TAC o AP_TERM ``g:real->real``) THEN
17254    RULE_ASSUM_TAC(SIMP_RULE std_ss [FUN_EQ_THM, I_THM, o_THM]) THEN
17255    ASM_MESON_TAC[LINEAR_0]]);
17256
17257val CLOSED_INJECTIVE_LINEAR_IMAGE_EQ = store_thm ("CLOSED_INJECTIVE_LINEAR_IMAGE_EQ",
17258 ``!f:real->real s.
17259        linear f /\ (!x y. (f x = f y) ==> (x = y))
17260        ==> (closed(IMAGE f s) <=> closed s)``,
17261  REPEAT STRIP_TAC THEN EQ_TAC THENL
17262   [DISCH_TAC, ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE]] THEN
17263  SUBGOAL_THEN ``s = {x | (f:real->real) x IN IMAGE f s}``
17264  SUBST1_TAC THENL [ASM_SET_TAC [], ALL_TAC] THEN
17265  MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN
17266  ASM_SIMP_TAC std_ss [LINEAR_CONTINUOUS_AT]);
17267
17268val CLOSURE_LINEAR_IMAGE_SUBSET = store_thm ("CLOSURE_LINEAR_IMAGE_SUBSET",
17269 ``!f:real->real s.
17270        linear f ==> IMAGE f (closure s) SUBSET closure(IMAGE f s)``,
17271  REPEAT STRIP_TAC THEN
17272  MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN
17273  ASM_SIMP_TAC std_ss [CLOSED_CLOSURE, CLOSURE_SUBSET, LINEAR_CONTINUOUS_ON]);
17274
17275val CLOSURE_INJECTIVE_LINEAR_IMAGE  = store_thm ("CLOSURE_INJECTIVE_LINEAR_IMAGE",
17276 ``!f:real->real s.
17277        linear f /\ (!x y. (f x = f y) ==> (x = y))
17278        ==> (closure(IMAGE f s) = IMAGE f (closure s))``,
17279  REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
17280  ASM_SIMP_TAC std_ss [CLOSURE_LINEAR_IMAGE_SUBSET] THEN
17281  MATCH_MP_TAC CLOSURE_MINIMAL THEN
17282  SIMP_TAC std_ss [CLOSURE_SUBSET, IMAGE_SUBSET] THEN
17283  ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE, CLOSED_CLOSURE]);
17284
17285val CLOSURE_BOUNDED_LINEAR_IMAGE = store_thm ("CLOSURE_BOUNDED_LINEAR_IMAGE",
17286 ``!f:real->real s.
17287        linear f /\ bounded s
17288        ==> (closure(IMAGE f s) = IMAGE f (closure s))``,
17289  REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
17290  ASM_SIMP_TAC std_ss [CLOSURE_LINEAR_IMAGE_SUBSET] THEN
17291  MATCH_MP_TAC CLOSURE_MINIMAL THEN
17292  SIMP_TAC std_ss [CLOSURE_SUBSET, IMAGE_SUBSET] THEN
17293  MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
17294  MATCH_MP_TAC COMPACT_LINEAR_IMAGE THEN
17295  ASM_REWRITE_TAC[COMPACT_CLOSURE]);
17296
17297val LINEAR_INTERIOR_IMAGE_SUBSET = store_thm ("LINEAR_INTERIOR_IMAGE_SUBSET",
17298 ``!f:real->real s.
17299        linear f /\ (!x y. (f x = f y) ==> (x = y))
17300       ==> interior(IMAGE f s) SUBSET IMAGE f (interior s)``,
17301  MESON_TAC[INTERIOR_IMAGE_SUBSET, LINEAR_CONTINUOUS_AT]);
17302
17303val LINEAR_IMAGE_SUBSET_INTERIOR = store_thm ("LINEAR_IMAGE_SUBSET_INTERIOR",
17304 ``!f:real->real s.
17305        linear f /\ (!y. ?x. f x = y)
17306        ==> IMAGE f (interior s) SUBSET interior(IMAGE f s)``,
17307  REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_MAXIMAL THEN
17308  ASM_SIMP_TAC std_ss [OPEN_SURJECTIVE_LINEAR_IMAGE, OPEN_INTERIOR,
17309               IMAGE_SUBSET, INTERIOR_SUBSET]);
17310
17311val INTERIOR_BIJECTIVE_LINEAR_IMAGE = store_thm ("INTERIOR_BIJECTIVE_LINEAR_IMAGE",
17312 ``!f:real->real s.
17313        linear f /\ (!x y. (f x = f y) ==> (x = y)) /\ (!y. ?x. f x = y)
17314        ==> (interior(IMAGE f s) = IMAGE f (interior s))``,
17315  ONCE_REWRITE_TAC [GSYM SURJECTIVE_IMAGE] THEN REPEAT STRIP_TAC THEN
17316  REWRITE_TAC [interior] THEN
17317  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_IMAGE] THEN
17318  GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
17319  [FIRST_ASSUM (MP_TAC o SPEC ``t:real->bool``) THEN
17320   STRIP_TAC THEN UNDISCH_TAC ``(t:real->bool) SUBSET IMAGE (f:real->real) s`` THEN
17321   DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SIMP_RULE std_ss [SUBSET_DEF, IN_IMAGE]) THEN
17322   DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC [] THEN STRIP_TAC THEN
17323   EXISTS_TAC ``x':real`` THEN ASM_REWRITE_TAC [] THEN EXISTS_TAC ``s':real->bool`` THEN
17324   REPEAT CONJ_TAC THENL
17325   [UNDISCH_TAC ``open t`` THEN MATCH_MP_TAC EQ_IMPLIES THEN
17326    EXPAND_TAC "t" THEN MATCH_MP_TAC OPEN_BIJECTIVE_LINEAR_IMAGE_EQ THEN
17327    METIS_TAC [SURJECTIVE_IMAGE],
17328    UNDISCH_TAC ``IMAGE (f:real->real) s' = t`` THEN REWRITE_TAC [EXTENSION] THEN
17329    DISCH_THEN (MP_TAC o SPEC ``(f:real->real) x'``) THEN SIMP_TAC std_ss [IN_IMAGE] THEN
17330    METIS_TAC [],
17331    REWRITE_TAC [SUBSET_DEF] THEN X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN
17332    UNDISCH_TAC ``IMAGE (f:real->real) s' = t`` THEN REWRITE_TAC [EXTENSION] THEN
17333    DISCH_THEN (MP_TAC o SPEC ``(f:real->real) y``) THEN REWRITE_TAC [IN_IMAGE] THEN
17334    KNOW_TAC ``(?x. (f y = (f:real->real) x) /\ x IN s')`` THENL
17335    [METIS_TAC [], ALL_TAC] THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
17336    DISCH_TAC THEN UNDISCH_TAC ``t SUBSET IMAGE (f:real->real) s`` THEN
17337    REWRITE_TAC [SUBSET_DEF] THEN DISCH_THEN (MP_TAC o SPEC ``(f:real->real) y``) THEN
17338    ASM_REWRITE_TAC [] THEN REWRITE_TAC [IN_IMAGE] THEN STRIP_TAC THEN
17339    METIS_TAC []], ALL_TAC] THEN
17340  POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [GSPECIFICATION] THEN
17341  STRIP_TAC THEN FIRST_ASSUM (MP_TAC o SPEC ``t:real->bool``) THEN
17342  STRIP_TAC THEN EXISTS_TAC ``IMAGE (f:real->real) t`` THEN
17343  REPEAT CONJ_TAC THENL
17344  [UNDISCH_TAC ``open t`` THEN MATCH_MP_TAC OPEN_SURJECTIVE_LINEAR_IMAGE THEN
17345   METIS_TAC [SURJECTIVE_IMAGE],
17346   REWRITE_TAC [IN_IMAGE] THEN EXISTS_TAC ``x':real`` THEN
17347   ASM_REWRITE_TAC [],
17348   MATCH_MP_TAC IMAGE_SUBSET THEN ASM_REWRITE_TAC []]);
17349
17350(* ------------------------------------------------------------------------- *)
17351(* Corollaries, reformulations and special cases for M = N.                  *)
17352(* ------------------------------------------------------------------------- *)
17353
17354val IN_INTERIOR_LINEAR_IMAGE = store_thm ("IN_INTERIOR_LINEAR_IMAGE",
17355 ``!f:real->real g s x.
17356        linear f /\ linear g /\ (f o g = I) /\ x IN interior s
17357        ==> (f x) IN interior (IMAGE f s)``,
17358  SIMP_TAC std_ss [FUN_EQ_THM, o_THM, I_THM] THEN REPEAT STRIP_TAC THEN
17359  MP_TAC(ISPECL [``f:real->real``, ``s:real->bool``]
17360    LINEAR_IMAGE_SUBSET_INTERIOR) THEN
17361  ASM_SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE] THEN
17362  ASM_MESON_TAC[]);
17363
17364val LINEAR_OPEN_MAPPING = store_thm ("LINEAR_OPEN_MAPPING",
17365 ``!f:real->real g.
17366        linear f /\ linear g /\ (f o g = I)
17367        ==> !s. open s ==> open(IMAGE f s)``,
17368  REPEAT GEN_TAC THEN SIMP_TAC std_ss [FUN_EQ_THM, o_THM, I_THM] THEN DISCH_TAC THEN
17369  MATCH_MP_TAC OPEN_SURJECTIVE_LINEAR_IMAGE THEN
17370  ASM_MESON_TAC[]);
17371
17372val INTERIOR_INJECTIVE_LINEAR_IMAGE = store_thm ("INTERIOR_INJECTIVE_LINEAR_IMAGE",
17373 ``!f:real->real s.
17374        linear f /\ (!x y. (f x = f y) ==> (x = y))
17375        ==> (interior(IMAGE f s) = IMAGE f (interior s))``,
17376  REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_BIJECTIVE_LINEAR_IMAGE THEN
17377  METIS_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE]);
17378
17379val COMPLETE_INJECTIVE_LINEAR_IMAGE = store_thm ("COMPLETE_INJECTIVE_LINEAR_IMAGE",
17380 ``!f:real->real.
17381        linear f /\ (!x y. (f x = f y) ==> (x = y))
17382        ==> !s. complete s ==> complete(IMAGE f s)``,
17383  REWRITE_TAC[COMPLETE_EQ_CLOSED, CLOSED_INJECTIVE_LINEAR_IMAGE]);
17384
17385val COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ = store_thm ("COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ",
17386 ``!f:real->real s.
17387        linear f /\ (!x y. (f x = f y) ==> (x = y))
17388        ==> (complete(IMAGE f s) <=> complete s)``,
17389  REWRITE_TAC[COMPLETE_EQ_CLOSED, CLOSED_INJECTIVE_LINEAR_IMAGE_EQ]);
17390
17391val LIMPT_INJECTIVE_LINEAR_IMAGE_EQ = store_thm ("LIMPT_INJECTIVE_LINEAR_IMAGE_EQ",
17392 ``!f:real->real s.
17393        linear f /\ (!x y. (f x = f y) ==> (x = y))
17394        ==> ((f x) limit_point_of (IMAGE f s) <=> x limit_point_of s)``,
17395  SIMP_TAC std_ss [LIMPT_APPROACHABLE, EXISTS_IN_IMAGE] THEN
17396  REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN
17397  DISCH_TAC THENL
17398   [MP_TAC(ISPEC ``f:real->real`` LINEAR_INJECTIVE_BOUNDED_BELOW_POS),
17399    MP_TAC(ISPEC ``f:real->real`` LINEAR_BOUNDED_POS)] THEN
17400  ASM_REWRITE_TAC [] THEN
17401  DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THENL
17402   [UNDISCH_TAC ``!(e :real).
17403        (0 :real) < e ==>
17404        ?(x' :real).
17405          x' IN (s :real -> bool) /\
17406          (f :real -> real) x' <> f (x :real) /\
17407          (dist (f x',f x) :real) < e`` THEN
17408    DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``e * B:real``),
17409    UNDISCH_TAC ``!(e :real).
17410        (0 :real) < e ==>
17411        ?(x' :real).
17412          x' IN (s :real -> bool) /\ x' <> (x :real) /\
17413          (dist (x',x) :real) < e`` THEN DISCH_TAC THEN
17414    FIRST_X_ASSUM(MP_TAC o SPEC ``e / B:real``)] THEN
17415  ASM_SIMP_TAC real_ss [REAL_LT_DIV, REAL_LT_MUL, dist, GSYM LINEAR_SUB] THEN
17416  DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN
17417  POP_ASSUM MP_TAC THEN
17418  REPEAT(MATCH_MP_TAC MONO_AND THEN
17419         CONJ_TAC THENL [ASM_MESON_TAC[], ALL_TAC]) THEN
17420  ASM_SIMP_TAC real_ss [GSYM REAL_LT_LDIV_EQ, REAL_LT_RDIV_EQ] THEN
17421  MATCH_MP_TAC(REAL_ARITH ``a <= b ==> b < x ==> a < x:real``) THEN
17422  ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_SIMP_TAC real_ss [REAL_LE_RDIV_EQ]);
17423
17424(* ------------------------------------------------------------------------- *)
17425(* Even more special cases.                                                  *)
17426(* ------------------------------------------------------------------------- *)
17427
17428val INTERIOR_NEGATIONS = store_thm ("INTERIOR_NEGATIONS",
17429 ``!s. interior(IMAGE (\x. -x) s) = IMAGE (\x. -x) (interior s)``,
17430  GEN_TAC THEN MATCH_MP_TAC INTERIOR_INJECTIVE_LINEAR_IMAGE THEN
17431  SIMP_TAC std_ss [linear] THEN REPEAT CONJ_TAC THEN REAL_ARITH_TAC);
17432
17433val SYMMETRIC_INTERIOR = store_thm ("SYMMETRIC_INTERIOR",
17434 ``!s:real->bool.
17435        (!x. x IN s ==> -x IN s)
17436        ==> !x. x IN interior s ==> (-x) IN interior s``,
17437  REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
17438  DISCH_THEN(MP_TAC o MATCH_MP(ISPEC ``(\x. -x):real->real`` FUN_IN_IMAGE)) THEN
17439  SIMP_TAC std_ss [GSYM INTERIOR_NEGATIONS] THEN
17440  MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
17441  SIMP_TAC std_ss [EXTENSION, IN_IMAGE] THEN METIS_TAC[REAL_NEG_NEG]);
17442
17443val CLOSURE_NEGATIONS = store_thm ("CLOSURE_NEGATIONS",
17444 ``!s. closure(IMAGE (\x. -x) s) = IMAGE (\x. -x) (closure s)``,
17445  GEN_TAC THEN MATCH_MP_TAC CLOSURE_INJECTIVE_LINEAR_IMAGE THEN
17446  SIMP_TAC std_ss [linear] THEN REPEAT CONJ_TAC THEN REAL_ARITH_TAC);
17447
17448val SYMMETRIC_CLOSURE = store_thm ("SYMMETRIC_CLOSURE",
17449 ``!s:real->bool.
17450        (!x. x IN s ==> -x IN s)
17451        ==> !x. x IN closure s ==> (-x) IN closure s``,
17452  REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
17453  DISCH_THEN(MP_TAC o MATCH_MP(ISPEC ``(\x. -x):real->real`` FUN_IN_IMAGE)) THEN
17454  SIMP_TAC std_ss [GSYM CLOSURE_NEGATIONS] THEN
17455  MATCH_MP_TAC EQ_IMPLIES THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
17456  SIMP_TAC std_ss [EXTENSION, IN_IMAGE] THEN ASM_MESON_TAC[REAL_NEG_NEG]);
17457
17458(* ------------------------------------------------------------------------- *)
17459(* Some properties of a canonical subspace.                                  *)
17460(* ------------------------------------------------------------------------- *)
17461
17462val SUBSPACE_SUBSTANDARD = store_thm ("SUBSPACE_SUBSTANDARD",
17463 ``subspace {x:real | (x = &0)}``,
17464  SIMP_TAC std_ss [subspace, GSPECIFICATION, REAL_MUL_RZERO, REAL_ADD_LID]);
17465
17466val CLOSED_SUBSTANDARD = store_thm ("CLOSED_SUBSTANDARD",
17467 ``closed {x:real | x = &0}``,
17468  REWRITE_TAC [GSPEC_EQ, CLOSED_SING]);
17469
17470val DIM_SUBSTANDARD = store_thm ("DIM_SUBSTANDARD",
17471  ``dim {x:real | x = &0} = 0``,
17472  REWRITE_TAC [dim, GSPEC_EQ] THEN MATCH_MP_TAC SELECT_UNIQUE THEN
17473  RW_TAC std_ss [] THEN EQ_TAC THENL
17474  [ONCE_REWRITE_TAC [MONO_NOT_EQ] THEN RW_TAC std_ss [] THEN
17475   ASM_CASES_TAC ``~(b SUBSET {0:real})`` THEN
17476   ASM_REWRITE_TAC [] THEN FULL_SIMP_TAC std_ss [SET_RULE
17477    ``b SUBSET {0:real} <=> (b = {}) \/ (b = {0})``] THENL
17478   [DISJ2_TAC THEN DISJ2_TAC THEN SIMP_TAC std_ss [HAS_SIZE] THEN
17479    DISJ2_TAC THEN REWRITE_TAC [CARD_EMPTY] THEN METIS_TAC [],
17480    REWRITE_TAC [INDEPENDENT_SING]], ALL_TAC] THEN
17481  DISCH_TAC THEN EXISTS_TAC ``{}:real->bool`` THEN
17482  ASM_SIMP_TAC std_ss [SPAN_EMPTY, SUBSET_REFL, EMPTY_SUBSET, INDEPENDENT_EMPTY] THEN
17483  ASM_REWRITE_TAC [HAS_SIZE_0]);
17484
17485(* ------------------------------------------------------------------------- *)
17486(* Affine transformations of intervals.                                      *)
17487(* ------------------------------------------------------------------------- *)
17488
17489val AFFINITY_INVERSES = store_thm ("AFFINITY_INVERSES",
17490 ``!m c. ~(m = &0:real)
17491         ==> ((\x. m * x + c) o (\x. inv(m) * x + (-(inv(m) * c))) = (\x. x)) /\
17492             ((\x. inv(m) * x + (-(inv(m) * c))) o (\x. m * x + c) = (\x. x))``,
17493  SIMP_TAC std_ss [FUN_EQ_THM, o_THM] THEN
17494  SIMP_TAC std_ss [REAL_ADD_LDISTRIB, REAL_MUL_RNEG] THEN
17495  SIMP_TAC std_ss [REAL_MUL_ASSOC, REAL_MUL_LINV, REAL_MUL_RINV] THEN
17496  REPEAT STRIP_TAC THEN REAL_ARITH_TAC);
17497
17498val REAL_AFFINITY_LE = store_thm ("REAL_AFFINITY_LE",
17499 ``!m c x y. &0:real < m ==> ((m * x + c <= y) <=> (x <= inv(m) * y + -(c / m)))``,
17500  REWRITE_TAC[REAL_ARITH ``(m * x + c <= y:real) <=> (x * m <= y - c)``] THEN
17501  SIMP_TAC std_ss [GSYM REAL_LE_RDIV_EQ] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN
17502  REWRITE_TAC [real_div, GSYM real_sub, REAL_SUB_RDISTRIB]);
17503
17504val REAL_LE_AFFINITY = store_thm ("REAL_LE_AFFINITY",
17505 ``!m c x y. &0:real < m ==> ((y <= m * x + c) <=> (inv(m) * y + -(c / m) <= x))``,
17506  REWRITE_TAC[REAL_ARITH ``(y <= m * x + c:real) <=> (y - c <= x * m)``] THEN
17507  SIMP_TAC std_ss [GSYM REAL_LE_LDIV_EQ] THEN ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN
17508  REWRITE_TAC [real_div, GSYM real_sub, REAL_SUB_RDISTRIB]);
17509
17510val REAL_AFFINITY_LT = store_thm ("REAL_AFFINITY_LT",
17511 ``!m c x y. &0:real < m ==> (m * x + c < y <=> x < inv(m) * y + -(c / m))``,
17512  SIMP_TAC std_ss [REAL_LE_AFFINITY, GSYM REAL_NOT_LE]);
17513
17514val REAL_LT_AFFINITY = store_thm ("REAL_LT_AFFINITY",
17515 ``!m c x y. &0:real < m ==> (y < m * x + c <=> inv(m) * y + -(c / m) < x)``,
17516  SIMP_TAC std_ss [REAL_AFFINITY_LE, GSYM REAL_NOT_LE]);
17517
17518val REAL_AFFINITY_EQ = store_thm ("REAL_AFFINITY_EQ",
17519 ``!m c x y. ~(m = &0:real) ==> ((m * x + c = y) <=> (x = inv(m) * y + -(c / m)))``,
17520  ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN
17521  REWRITE_TAC [real_div, GSYM real_sub, GSYM REAL_SUB_RDISTRIB] THEN
17522  REWRITE_TAC [GSYM REAL_EQ_SUB_LADD, GSYM real_div] THEN
17523  REPEAT STRIP_TAC THEN EQ_TAC THENL
17524  [GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN
17525   ASM_SIMP_TAC arith_ss [real_div, GSYM REAL_MUL_ASSOC, REAL_MUL_RINV,
17526   REAL_MUL_RID], DISCH_TAC THEN METIS_TAC [REAL_DIV_RMUL]]);
17527
17528val REAL_EQ_AFFINITY = store_thm ("REAL_EQ_AFFINITY",
17529 ``!m c x y. ~(m = &0:real) ==> ((y = m * x + c)  <=> (inv(m) * y + -(c / m) = x))``,
17530  ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN
17531  REWRITE_TAC [real_div, GSYM real_sub, GSYM REAL_SUB_RDISTRIB] THEN
17532  REPEAT STRIP_TAC THEN GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN
17533  REWRITE_TAC [GSYM REAL_EQ_SUB_LADD, GSYM real_div] THEN EQ_TAC THENL
17534  [GEN_REWR_TAC LAND_CONV [EQ_SYM_EQ] THEN DISCH_TAC THEN
17535   ASM_SIMP_TAC arith_ss [real_div, GSYM REAL_MUL_ASSOC, REAL_MUL_RINV,
17536   REAL_MUL_RID], DISCH_TAC THEN METIS_TAC [REAL_DIV_RMUL]]);
17537
17538val IMAGE_AFFINITY_INTERVAL = store_thm ("IMAGE_AFFINITY_INTERVAL",
17539 ``!a b:real m c.
17540        IMAGE (\x. m * x + c) (interval[a,b]) =
17541            if interval[a,b] = {} then {}
17542            else if &0 <= m then interval[m * a + c,m * b + c]
17543            else interval[m * b + c,m * a + c]``,
17544  REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[IMAGE_EMPTY, IMAGE_INSERT] THEN
17545  ASM_CASES_TAC ``m = &0:real`` THEN ASM_REWRITE_TAC[REAL_LE_LT] THENL
17546   [ASM_REWRITE_TAC[REAL_MUL_LZERO, REAL_ADD_LID, COND_ID] THEN
17547    REWRITE_TAC[INTERVAL_SING] THEN ASM_SET_TAC[],
17548    ALL_TAC] THEN
17549  FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH
17550   ``~(x = &0:real) ==> &0 < x \/ &0 < -x``)) THEN
17551  ASM_SIMP_TAC std_ss [EXTENSION, IN_IMAGE, REAL_ARITH ``&0 < -x ==> ~(&0 < x:real)``] THENL
17552   [ALL_TAC,
17553    ONCE_REWRITE_TAC[REAL_ARITH ``(x = m * y + c:real) <=> (c = (-m) * y + x)``]] THEN
17554  (ASM_SIMP_TAC std_ss [REAL_EQ_AFFINITY, REAL_LT_IMP_NE, UNWIND_THM1] THEN
17555  SIMP_TAC std_ss [IN_INTERVAL] THEN
17556  POP_ASSUM(MP_TAC o ONCE_REWRITE_RULE [GSYM REAL_LT_INV_EQ]) THEN
17557  SIMP_TAC std_ss [REAL_AFFINITY_LE, REAL_LE_AFFINITY, real_div] THEN
17558  DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[REAL_INV_INV] THEN
17559  REWRITE_TAC[REAL_MUL_LNEG, REAL_NEGNEG] THEN
17560  KNOW_TAC ``-m <> 0:real`` THENL [ASM_REAL_ARITH_TAC, DISCH_TAC] THEN
17561  ASM_SIMP_TAC std_ss [METIS [REAL_MUL_RID, GSYM REAL_MUL_ASSOC, REAL_MUL_RINV,
17562   REAL_ARITH ``b * inv a * a = b * a * inv a:real``]
17563   ``m <> 0:real ==> (x * inv m * m = x)``] THEN
17564  GEN_TAC THEN ONCE_REWRITE_TAC [REAL_ADD_SYM] THEN REWRITE_TAC [GSYM real_sub] THEN
17565  REAL_ARITH_TAC));
17566
17567(* ------------------------------------------------------------------------- *)
17568(* Infinite sums of vectors. Allow general starting point (and more).        *)
17569(* ------------------------------------------------------------------------- *)
17570
17571val _ = hide "sums";
17572val _ = hide "summable";
17573
17574val _ = set_fixity "sums" (Infix(NONASSOC, 450));
17575
17576Definition sums : (* cf. seqTheory.sums *)
17577   (f sums l) s = ((\n. sum (s INTER ((0:num)..n)) f) --> l) sequentially
17578End
17579
17580Definition infsum : (* cf. seqTheory.suminf *)
17581    infsum s f = @l. (f sums l) s
17582End
17583val _ = overload_on ("suminf", ``infsum``);
17584
17585Definition summable : (* cf. seqTheory.summable *)
17586    summable s f = ?l. (f sums l) s
17587End
17588
17589(* connections to related concepts in seqTheory *)
17590Theorem sums_univ :
17591    !(f :num -> real) (l :real). (f sums l) univ(:num) <=> seq$sums f l
17592Proof
17593    RW_TAC std_ss [seqTheory.sums, sums, dist, INTER_UNIV, SEQ, LIM_SEQUENTIALLY]
17594 >> EQ_TAC >> rpt STRIP_TAC
17595 >| [ (* goal 1 (of 2) *)
17596      Q.PAT_X_ASSUM `!e. 0 < e ==> P` (MP_TAC o (Q.SPEC `e`)) \\
17597      RW_TAC std_ss [] \\
17598      Q.EXISTS_TAC `SUC N` >> rpt STRIP_TAC \\
17599      Cases_on `n` >- fs [] \\
17600      REWRITE_TAC [GSYM sum_real] \\
17601      FIRST_X_ASSUM MATCH_MP_TAC >> rw [],
17602      (* goal 2 (of 2) *)
17603      Q.PAT_X_ASSUM `!e. 0 < e ==> P` (MP_TAC o (Q.SPEC `e`)) \\
17604      RW_TAC std_ss [] \\
17605      Q.EXISTS_TAC `N` >> rpt STRIP_TAC \\
17606      REWRITE_TAC [sum_real] \\
17607      FIRST_X_ASSUM MATCH_MP_TAC >> rw [] ]
17608QED
17609
17610Theorem suminf_univ :
17611    !(f :num -> real). infsum univ(:num) f = seq$suminf f
17612Proof
17613    RW_TAC std_ss [infsum, suminf, sums_univ]
17614QED
17615
17616Theorem summable_univ :
17617    !(f :num -> real). summable univ(:num) f <=> seq$summable f
17618Proof
17619    RW_TAC std_ss [summable, seqTheory.summable, sums_univ]
17620QED
17621
17622val SUMS_SUMMABLE = store_thm ("SUMS_SUMMABLE",
17623 ``!f l s. (f sums l) s ==> summable s f``,
17624  REWRITE_TAC[summable] THEN MESON_TAC[]);
17625
17626val SUMS_INFSUM = store_thm ("SUMS_INFSUM",
17627 ``!f s. (f sums (infsum s f)) s <=> summable s f``,
17628  REWRITE_TAC[infsum, summable] THEN METIS_TAC[]);
17629
17630val SUMS_LIM = store_thm ("SUMS_LIM",
17631 ``!f:num->real s.
17632      (f sums lim sequentially (\n. sum (s INTER ((0:num)..n)) f)) s
17633      <=> summable s f``,
17634  GEN_TAC THEN GEN_TAC THEN EQ_TAC THENL [MESON_TAC[summable],
17635  REWRITE_TAC[summable, sums] THEN STRIP_TAC THEN REWRITE_TAC[lim_def] THEN
17636  METIS_TAC[]]);
17637
17638val FINITE_INTER_NUMSEG = store_thm ("FINITE_INTER_NUMSEG",
17639 ``!s m n. FINITE(s INTER (m..n))``,
17640  MESON_TAC[SUBSET_FINITE_I, FINITE_NUMSEG, INTER_SUBSET]);
17641
17642val SERIES_FROM = store_thm ("SERIES_FROM",
17643 ``!f l k. (f sums l) (from k) = ((\n. sum(k..n) f) --> l) sequentially``,
17644  REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN
17645  AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
17646  AP_THM_TAC THEN AP_TERM_TAC THEN
17647  SIMP_TAC std_ss [EXTENSION, numseg, from_def, GSPECIFICATION, IN_INTER] THEN ARITH_TAC);
17648
17649val SERIES_UNIQUE = store_thm ("SERIES_UNIQUE",
17650 ``!f:num->real l l' s. (f sums l) s /\ (f sums l') s ==> (l = l')``,
17651  REWRITE_TAC[sums] THEN MESON_TAC[TRIVIAL_LIMIT_SEQUENTIALLY, LIM_UNIQUE]);
17652
17653val INFSUM_UNIQUE = store_thm ("INFSUM_UNIQUE",
17654 ``!f:num->real l s. (f sums l) s ==> (infsum s f = l)``,
17655  MESON_TAC[SERIES_UNIQUE, SUMS_INFSUM, summable]);
17656
17657val SERIES_TERMS_TOZERO = store_thm ("SERIES_TERMS_TOZERO",
17658 ``!f l n. (f sums l) (from n) ==> (f --> 0) sequentially``,
17659  REPEAT GEN_TAC THEN SIMP_TAC std_ss [sums, LIM_SEQUENTIALLY, FROM_INTER_NUMSEG] THEN
17660  DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
17661  FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN
17662  ASM_REWRITE_TAC[REAL_HALF] THEN DISCH_THEN(X_CHOOSE_TAC ``N:num``) THEN
17663  EXISTS_TAC ``N + n + 1:num`` THEN X_GEN_TAC ``m:num`` THEN DISCH_TAC THEN
17664  FIRST_X_ASSUM(fn th =>
17665    MP_TAC(SPEC ``m - 1:num`` th) THEN MP_TAC(SPEC ``m:num`` th)) THEN
17666  SUBGOAL_THEN ``0 < m:num /\ n <= m`` (fn th => SIMP_TAC std_ss [SUM_CLAUSES_RIGHT, th])
17667  THENL [CONJ_TAC THENL
17668   [MATCH_MP_TAC LESS_LESS_EQ_TRANS THEN EXISTS_TAC ``N + n + 1:num`` THEN
17669    ASM_REWRITE_TAC [] THEN ARITH_TAC,
17670    MATCH_MP_TAC LESS_EQ_TRANS THEN EXISTS_TAC ``N + n + 1:num`` THEN
17671    ASM_REWRITE_TAC [] THEN ARITH_TAC], ALL_TAC] THEN
17672  KNOW_TAC ``N <= m:num`` THENL [MATCH_MP_TAC LESS_EQ_TRANS THEN
17673   EXISTS_TAC ``N + n + 1:num`` THEN ASM_REWRITE_TAC [] THEN ARITH_TAC,
17674  DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN
17675  KNOW_TAC ``N <= m:num - 1`` THENL [MATCH_MP_TAC LESS_EQ_TRANS THEN
17676   EXISTS_TAC ``N + n:num`` THEN CONJ_TAC THENL [ARITH_TAC, ALL_TAC] THEN
17677   ONCE_REWRITE_TAC [ARITH_PROVE ``(a <= b) = (a + 1 <= b + 1:num)``] THEN
17678   MATCH_MP_TAC LESS_EQ_TRANS THEN EXISTS_TAC ``m:num`` THEN
17679   ASM_REWRITE_TAC [] THEN ARITH_TAC,
17680  DISCH_TAC THEN ASM_REWRITE_TAC [] THEN DISCH_TAC] THEN
17681  REWRITE_TAC [DIST_0] THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN
17682  FULL_SIMP_TAC std_ss [dist] THEN ASM_REAL_ARITH_TAC);
17683
17684val SERIES_FINITE = store_thm ("SERIES_FINITE",
17685 ``!f s. FINITE s ==> (f sums (sum s f)) s``,
17686  REPEAT GEN_TAC THEN SIMP_TAC std_ss [num_FINITE, LEFT_IMP_EXISTS_THM] THEN
17687  X_GEN_TAC ``n:num`` THEN SIMP_TAC std_ss [sums, LIM_SEQUENTIALLY] THEN
17688  DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN EXISTS_TAC ``n:num`` THEN
17689  X_GEN_TAC ``m:num`` THEN DISCH_TAC THEN
17690  SUBGOAL_THEN ``s INTER ((0:num)..m) = s``
17691   (fn th => ASM_REWRITE_TAC[th, DIST_REFL]) THEN
17692  SIMP_TAC std_ss [EXTENSION, IN_INTER, IN_NUMSEG, ZERO_LESS_EQ] THEN
17693  METIS_TAC[LESS_EQ_TRANS]);
17694
17695val SERIES_LINEAR = store_thm ("SERIES_LINEAR",
17696 ``!f h l s. (f sums l) s /\ linear h ==> ((\n. h(f n)) sums h l) s``,
17697  SIMP_TAC std_ss [sums, LIM_LINEAR, FINITE_INTER, FINITE_NUMSEG,
17698           GSYM(REWRITE_RULE[o_DEF] LINEAR_SUM)]);
17699
17700val SERIES_0 = store_thm ("SERIES_0",
17701 ``!s. ((\n. 0) sums (0)) s``,
17702  REWRITE_TAC[sums, SUM_0, LIM_CONST]);
17703
17704val SERIES_ADD = store_thm ("SERIES_ADD",
17705 ``!x x0 y y0 s.
17706     (x sums x0) s /\ (y sums y0) s ==> ((\n. x n + y n) sums (x0 + y0)) s``,
17707  SIMP_TAC std_ss [sums, FINITE_INTER_NUMSEG, SUM_ADD, LIM_ADD]);
17708
17709val SERIES_SUB = store_thm ("SERIES_SUB",
17710 ``!x x0 y y0 s.
17711     (x sums x0) s /\ (y sums y0) s ==> ((\n. x n - y n) sums (x0 - y0)) s``,
17712  SIMP_TAC std_ss [sums, FINITE_INTER_NUMSEG, SUM_SUB, LIM_SUB]);
17713
17714val SERIES_CMUL = store_thm ("SERIES_CMUL",
17715 ``!x x0 c s. (x sums x0) s ==> ((\n. c * x n) sums (c * x0)) s``,
17716  SIMP_TAC std_ss [sums, FINITE_INTER_NUMSEG, SUM_LMUL, LIM_CMUL]);
17717
17718val SERIES_NEG = store_thm ("SERIES_NEG",
17719 ``!x x0 s. (x sums x0) s ==> ((\n. -(x n)) sums (-x0)) s``,
17720  SIMP_TAC std_ss [sums, FINITE_INTER_NUMSEG, SUM_NEG, LIM_NEG]);
17721
17722val SUMS_IFF = store_thm ("SUMS_IFF",
17723 ``!f g k. (!x. x IN k ==> (f x = g x)) ==> ((f sums l) k <=> (g sums l) k)``,
17724  REPEAT STRIP_TAC THEN REWRITE_TAC[sums] THEN
17725  AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
17726  MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC std_ss [IN_INTER]);
17727
17728val SUMS_EQ = store_thm ("SUMS_EQ",
17729 ``!f g k. (!x. x IN k ==> (f x = g x)) /\ (f sums l) k ==> (g sums l) k``,
17730  MESON_TAC[SUMS_IFF]);
17731
17732val SUMS_0 = store_thm ("SUMS_0",
17733 ``!f:num->real s. (!n. n IN s ==> (f n = 0)) ==> (f sums 0) s``,
17734  REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMS_EQ THEN
17735  EXISTS_TAC ``\n:num. 0:real`` THEN ASM_SIMP_TAC std_ss [SERIES_0]);
17736
17737val SERIES_FINITE_SUPPORT = store_thm ("SERIES_FINITE_SUPPORT",
17738 ``!f:num->real s k.
17739     FINITE (s INTER k) /\ (!x. x IN k /\ ~(x IN s) ==> (f x = 0))
17740     ==> (f sums sum (s INTER k) f) k``,
17741  REWRITE_TAC[sums, LIM_SEQUENTIALLY] THEN REPEAT STRIP_TAC THEN
17742  FIRST_ASSUM(MP_TAC o ISPEC ``\x:num. x`` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN
17743  REWRITE_TAC[] THEN DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN
17744  EXISTS_TAC ``N:num`` THEN POP_ASSUM MP_TAC THEN
17745  STRIP_TAC THEN X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN
17746  SIMP_TAC std_ss [] THEN
17747  SUBGOAL_THEN ``sum (k INTER ((0:num)..n)) (f:num->real) = sum(s INTER k) f``
17748   (fn th => ASM_SIMP_TAC std_ss [DIST_REFL, th]) THEN
17749  MATCH_MP_TAC SUM_SUPERSET THEN
17750  ASM_SIMP_TAC std_ss [SUBSET_DEF, IN_INTER, IN_NUMSEG, ZERO_LESS_EQ] THEN
17751  METIS_TAC[IN_INTER, LESS_EQ_TRANS]);
17752
17753val SERIES_COMPONENT = store_thm ("SERIES_COMPONENT",
17754 ``!f s l:real. (f sums l) s
17755          ==> ((\i. f(i)) sums l) s``,
17756  METIS_TAC []);
17757
17758val SERIES_DIFFS = store_thm ("SERIES_DIFFS",
17759 ``!f:num->real k. (f --> 0) sequentially
17760        ==> ((\n. f(n) - f(n + 1)) sums f(k)) (from k)``,
17761  REWRITE_TAC[sums, FROM_INTER_NUMSEG, SUM_DIFFS] THEN
17762  REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
17763  EXISTS_TAC ``\n. (f:num->real) k - f(n + 1)`` THEN CONJ_TAC THENL
17764   [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC ``k:num`` THEN
17765    SIMP_TAC std_ss [],
17766    GEN_REWR_TAC LAND_CONV [GSYM REAL_SUB_RZERO] THEN
17767    KNOW_TAC ``((\n. (\n. f k) n - (\n. f (n + 1)) n)
17768                   --> ((f:num->real) k - 0)) sequentially`` THENL
17769    [ALL_TAC, SIMP_TAC std_ss []] THEN
17770    MATCH_MP_TAC LIM_SUB THEN REWRITE_TAC[LIM_CONST] THEN
17771    MATCH_MP_TAC SEQ_OFFSET THEN ASM_REWRITE_TAC[]]);
17772
17773val SERIES_TRIVIAL = store_thm ("SERIES_TRIVIAL",
17774 ``!f. (f sums 0) {}``,
17775  SIMP_TAC std_ss [sums, INTER_EMPTY, SUM_CLAUSES, LIM_CONST]);
17776
17777val SERIES_RESTRICT = store_thm ("SERIES_RESTRICT",
17778 ``!f k l:real.
17779        ((\n. if n IN k then f(n) else 0) sums l) univ(:num) <=>
17780        (f sums l) k``,
17781  REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN
17782  AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
17783  REWRITE_TAC[FUN_EQ_THM, INTER_UNIV] THEN GEN_TAC THEN
17784  SIMP_TAC std_ss [] THEN
17785  MATCH_MP_TAC(METIS [] ``(sum s f = sum t f) /\ (sum t f = sum t g)
17786                        ==> (sum s f = sum t g)``) THEN
17787  CONJ_TAC THENL
17788   [MATCH_MP_TAC SUM_SUPERSET THEN SET_TAC[],
17789    MATCH_MP_TAC SUM_EQ THEN SIMP_TAC std_ss [IN_INTER]]);
17790
17791val SERIES_SUM = store_thm ("SERIES_SUM",
17792 ``!f l k s. FINITE s /\ s SUBSET k /\ (!x. ~(x IN s) ==> (f x = 0)) /\
17793             (sum s f = l) ==> (f sums l) k``,
17794  REPEAT STRIP_TAC THEN EXPAND_TAC "l" THEN
17795  SUBGOAL_THEN ``s INTER k = s:num->bool`` ASSUME_TAC THENL
17796   [ASM_SET_TAC [], ASM_MESON_TAC [SERIES_FINITE_SUPPORT]]);
17797
17798val SUMS_REINDEX = store_thm ("SUMS_REINDEX",
17799 ``!k a l:real n.
17800   ((\x. a(x + k)) sums l) (from n) <=> (a sums l) (from(n + k))``,
17801  REPEAT GEN_TAC THEN REWRITE_TAC[sums, FROM_INTER_NUMSEG] THEN
17802  REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUM_OFFSET] THEN
17803  REWRITE_TAC[LIM_SEQUENTIALLY] THEN
17804  ASM_MESON_TAC[ARITH_PROVE ``N + k:num <= n ==> (n = (n - k) + k) /\ N <= n - k``,
17805                ARITH_PROVE ``N + k:num <= n ==> N <= n + k``]);
17806
17807val SUMS_REINDEX_GEN = store_thm ("SUMS_REINDEX_GEN",
17808 ``!k a l:real s.
17809     ((\x. a(x + k)) sums l) s <=> (a sums l) (IMAGE (\i. i + k) s)``,
17810  REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN
17811  MP_TAC(ISPECL
17812   [``k:num``,
17813    ``\i. if i IN IMAGE (\i. i + k) s then (a:num->real) i else 0``,
17814    ``l:real``, ``0:num``] SUMS_REINDEX) THEN
17815  REWRITE_TAC[FROM_0] THEN
17816  SIMP_TAC std_ss [EQ_ADD_RCANCEL, SET_RULE
17817   ``(!x y:num. (x + k = y + k) <=> (x = y))
17818         ==> ((x + k) IN IMAGE (\i. i + k) s <=> x IN s)``] THEN
17819  DISCH_THEN SUBST1_TAC THEN
17820  GEN_REWR_TAC LAND_CONV [GSYM SERIES_RESTRICT] THEN
17821  AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
17822  REWRITE_TAC[FUN_EQ_THM, IN_FROM, ADD_CLAUSES] THEN
17823  SUBGOAL_THEN ``!x:num. x IN IMAGE (\i. i + k) s ==> k <= x`` MP_TAC THENL
17824   [SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN ARITH_TAC, SET_TAC[]]);
17825
17826(* ------------------------------------------------------------------------- *)
17827(* Similar combining theorems just for summability.                          *)
17828(* ------------------------------------------------------------------------- *)
17829
17830val SUMMABLE_LINEAR = store_thm ("SUMMABLE_LINEAR",
17831 ``!f h s. summable s f /\ linear h ==> summable s (\n. h(f n))``,
17832  REWRITE_TAC[summable] THEN METIS_TAC[SERIES_LINEAR]);
17833
17834val SUMMABLE_0 = store_thm ("SUMMABLE_0",
17835 ``!s. summable s (\n. 0)``,
17836  REWRITE_TAC[summable] THEN MESON_TAC[SERIES_0]);
17837
17838val SUMMABLE_ADD = store_thm ("SUMMABLE_ADD",
17839 ``!x y s. summable s x /\ summable s y ==> summable s (\n. x n + y n)``,
17840  REWRITE_TAC[summable] THEN METIS_TAC[SERIES_ADD]);
17841
17842val SUMMABLE_SUB = store_thm ("SUMMABLE_SUB",
17843 ``!x y s. summable s x /\ summable s y ==> summable s (\n. x n - y n)``,
17844  REWRITE_TAC[summable] THEN METIS_TAC[SERIES_SUB]);
17845
17846val SUMMABLE_CMUL = store_thm ("SUMMABLE_CMUL",
17847 ``!s x c. summable s x ==> summable s (\n. c * x n)``,
17848  REWRITE_TAC[summable] THEN METIS_TAC[SERIES_CMUL]);
17849
17850val SUMMABLE_NEG = store_thm ("SUMMABLE_NEG",
17851 ``!x s. summable s x ==> summable s (\n. -(x n))``,
17852  REWRITE_TAC[summable] THEN METIS_TAC[SERIES_NEG]);
17853
17854val SUMMABLE_IFF = store_thm ("SUMMABLE_IFF",
17855 ``!f g k. (!x. x IN k ==> (f x = g x)) ==> (summable k f <=> summable k g)``,
17856  REWRITE_TAC[summable] THEN METIS_TAC[SUMS_IFF]);
17857
17858val SUMMABLE_EQ = store_thm ("SUMMABLE_EQ",
17859 ``!f g k. (!x. x IN k ==> (f x = g x)) /\ summable k f ==> summable k g``,
17860  REWRITE_TAC[summable] THEN METIS_TAC[SUMS_EQ]);
17861
17862val SUMMABLE_COMPONENT = store_thm ("SUMMABLE_COMPONENT",
17863 ``!f:num->real s.
17864        summable s f ==> summable s (\i. f(i))``,
17865  METIS_TAC []);
17866
17867val SERIES_SUBSET = store_thm ("SERIES_SUBSET",
17868 ``!x s t l.
17869        s SUBSET t /\
17870        ((\i. if i IN s then x i else 0) sums l) t
17871        ==> (x sums l) s``,
17872  REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
17873  REWRITE_TAC[sums] THEN MATCH_MP_TAC EQ_IMPLIES THEN
17874  AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
17875  ASM_SIMP_TAC std_ss [GSYM SUM_RESTRICT_SET, FINITE_INTER_NUMSEG] THEN
17876  AP_THM_TAC THEN AP_TERM_TAC THEN POP_ASSUM MP_TAC THEN SET_TAC[]);
17877
17878val SUMMABLE_SUBSET = store_thm ("SUMMABLE_SUBSET",
17879 ``!x s t.
17880        s SUBSET t /\
17881        summable t (\i. if i IN s then x i else 0)
17882        ==> summable s x``,
17883  REWRITE_TAC[summable] THEN METIS_TAC[SERIES_SUBSET]);
17884
17885val SUMMABLE_TRIVIAL = store_thm ("SUMMABLE_TRIVIAL",
17886 ``!f:num->real. summable {} f``,
17887  GEN_TAC THEN REWRITE_TAC[summable] THEN EXISTS_TAC ``0:real`` THEN
17888  REWRITE_TAC[SERIES_TRIVIAL]);
17889
17890val SUMMABLE_RESTRICT = store_thm ("SUMMABLE_RESTRICT",
17891 ``!f:num->real k.
17892        summable univ(:num) (\n. if n IN k then f(n) else 0) <=>
17893        summable k f``,
17894  SIMP_TAC std_ss [summable, SERIES_RESTRICT]);
17895
17896val SUMS_FINITE_DIFF = store_thm ("SUMS_FINITE_DIFF",
17897 ``!f:num->real t s l.
17898        t SUBSET s /\ FINITE t /\ (f sums l) s
17899        ==> (f sums (l - sum t f)) (s DIFF t)``,
17900  REPEAT GEN_TAC THEN
17901  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
17902  FIRST_ASSUM(MP_TAC o ISPEC ``f:num->real`` o MATCH_MP SERIES_FINITE) THEN
17903  ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN
17904  REWRITE_TAC[AND_IMP_INTRO] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
17905  DISCH_THEN(MP_TAC o MATCH_MP SERIES_SUB) THEN
17906  MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
17907  REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``x:num`` THEN REWRITE_TAC[IN_DIFF] THEN
17908  UNDISCH_TAC ``t SUBSET s:num->bool`` THEN DISCH_TAC THEN
17909  FIRST_ASSUM(MP_TAC o SPEC ``x:num`` o REWRITE_RULE [SUBSET_DEF]) THEN
17910  MAP_EVERY ASM_CASES_TAC [``(x:num) IN s``, ``(x:num) IN t``] THEN
17911  ASM_SIMP_TAC arith_ss [] THEN REAL_ARITH_TAC);
17912
17913val SUMS_FINITE_UNION = store_thm ("SUMS_FINITE_UNION",
17914 ``!f:num->real s t l.
17915        FINITE t /\ (f sums l) s
17916        ==> (f sums (l + sum (t DIFF s) f)) (s UNION t)``,
17917  REPEAT GEN_TAC THEN
17918  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
17919  FIRST_ASSUM(MP_TAC o SPEC ``s:num->bool`` o MATCH_MP FINITE_DIFF) THEN
17920  DISCH_THEN(MP_TAC o ISPEC ``f:num->real`` o MATCH_MP SERIES_FINITE) THEN
17921  ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN
17922  REWRITE_TAC[AND_IMP_INTRO] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
17923  DISCH_THEN(MP_TAC o MATCH_MP SERIES_ADD) THEN
17924  MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
17925  REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``x:num`` THEN
17926  REWRITE_TAC[IN_DIFF, IN_UNION] THEN
17927  MAP_EVERY ASM_CASES_TAC [``(x:num) IN s``, ``(x:num) IN t``] THEN
17928  ASM_SIMP_TAC arith_ss [] THEN REAL_ARITH_TAC);
17929
17930val SUMS_OFFSET = store_thm ("SUMS_OFFSET",
17931 ``!f l:real m n.
17932           (f sums l) (from m) /\ 0 < n /\ m <= n
17933           ==> (f sums l - sum (m..n - 1) f) (from n)``,
17934  REPEAT STRIP_TAC THEN
17935  SUBGOAL_THEN ``from n = from m DIFF (m..(n-1:num))`` SUBST1_TAC THENL
17936   [SIMP_TAC std_ss [EXTENSION, IN_FROM, IN_DIFF, IN_NUMSEG] THEN
17937    GEN_TAC THEN EQ_TAC THENL [DISCH_TAC THEN CONJ_TAC THENL
17938     [MATCH_MP_TAC LESS_EQ_TRANS THEN EXISTS_TAC ``n:num`` THEN ASM_REWRITE_TAC [],
17939      REWRITE_TAC [NOT_LESS_EQUAL] THEN DISJ2_TAC THEN
17940      MATCH_MP_TAC LESS_LESS_EQ_TRANS THEN EXISTS_TAC ``n:num`` THEN ASM_REWRITE_TAC [] THEN
17941      MATCH_MP_TAC SUB_LESS THEN CONJ_TAC THENL [ARITH_TAC , ALL_TAC] THEN
17942      REWRITE_TAC [ONE] THEN ASM_REWRITE_TAC [GSYM LESS_EQ]], ARITH_TAC],
17943    MATCH_MP_TAC SUMS_FINITE_DIFF THEN ASM_REWRITE_TAC[FINITE_NUMSEG] THEN
17944    SIMP_TAC std_ss [SUBSET_DEF, IN_FROM, IN_NUMSEG]]);
17945
17946val SUMS_OFFSET_REV = store_thm ("SUMS_OFFSET_REV",
17947 ``!f:num->real l m n.
17948        (f sums l) (from m) /\ 0 < m /\ n <= m
17949        ==> (f sums (l + sum(n..m-1) f)) (from n)``,
17950  REPEAT STRIP_TAC THEN
17951  MP_TAC(ISPECL [``f:num->real``, ``from m``, ``n..m-1``, ``l:real``]
17952                SUMS_FINITE_UNION) THEN
17953  ASM_REWRITE_TAC[FINITE_NUMSEG] THEN MATCH_MP_TAC EQ_IMPLIES THEN
17954  BINOP_TAC THENL [AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC, ALL_TAC] THEN
17955  REWRITE_TAC[EXTENSION, IN_DIFF, IN_UNION, IN_FROM, IN_NUMSEG] THEN
17956  ASM_SIMP_TAC arith_ss []);
17957
17958val SUMMABLE_REINDEX = store_thm ("SUMMABLE_REINDEX",
17959 ``!k a n. summable (from n) (\x. a (x + k)) <=> summable (from(n + k)) a``,
17960  REWRITE_TAC[summable, GSYM SUMS_REINDEX]);
17961
17962val SERIES_DROP_LE = store_thm ("SERIES_DROP_LE",
17963 ``!f g s a b.
17964        (f sums a) s /\ (g sums b) s /\
17965        (!x. x IN s ==> (f x <= g x))
17966        ==> a <= b``,
17967  REWRITE_TAC[sums] THEN REPEAT STRIP_TAC THEN
17968  MATCH_MP_TAC(ISPEC ``sequentially`` LIM_DROP_LE) THEN
17969  REWRITE_TAC[EVENTUALLY_SEQUENTIALLY, TRIVIAL_LIMIT_SEQUENTIALLY] THEN
17970  EXISTS_TAC ``\n. sum (s INTER ((0:num)..n)) (f:num->real)`` THEN
17971  EXISTS_TAC ``\n. sum (s INTER ((0:num)..n)) (g:num->real)`` THEN
17972  ASM_REWRITE_TAC[] THEN EXISTS_TAC ``0:num`` THEN REPEAT STRIP_TAC THEN
17973  SIMP_TAC std_ss [] THEN MATCH_MP_TAC SUM_LE THEN
17974  ASM_SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG, IN_INTER, IN_NUMSEG]);
17975
17976val SERIES_DROP_POS = store_thm ("SERIES_DROP_POS",
17977 ``!f s a.
17978        (f sums a) s /\ (!x. x IN s ==> &0 <= f x)
17979        ==> &0 <= a``,
17980  REPEAT STRIP_TAC THEN
17981  MP_TAC(ISPECL [``(\n. 0):num->real``, ``f:num->real``, ``s:num->bool``,
17982                 ``0:real``, ``a:real``] SERIES_DROP_LE) THEN
17983  ASM_SIMP_TAC std_ss [SUMS_0]);
17984
17985val SERIES_BOUND = store_thm ("SERIES_BOUND",
17986 ``!f:num->real g s a b.
17987        (f sums a) s /\ (g sums b) s /\
17988        (!i. i IN s ==> abs(f i) <= g i)
17989        ==> abs (a) <= b``,
17990  REWRITE_TAC[sums] THEN REPEAT STRIP_TAC THEN
17991  MATCH_MP_TAC(ISPEC ``sequentially`` LIM_ABS_UBOUND) THEN
17992  EXISTS_TAC ``\n. sum (s INTER ((0:num)..n)) (f:num->real)`` THEN
17993  ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
17994  REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC ``0:num`` THEN
17995  X_GEN_TAC ``m:num`` THEN DISCH_TAC THEN
17996  SIMP_TAC std_ss [] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
17997  EXISTS_TAC ``sum (s INTER ((0:num)..m)) g`` THEN CONJ_TAC THEN
17998  ASM_SIMP_TAC std_ss [SUM_ABS_LE, IN_INTER, FINITE_NUMSEG, FINITE_INTER] THEN
17999  RULE_ASSUM_TAC(REWRITE_RULE[GSYM sums]) THEN
18000  UNDISCH_TAC ``(g sums b) s`` THEN
18001  GEN_REWR_TAC LAND_CONV [GSYM SERIES_RESTRICT] THEN
18002  REWRITE_TAC[GSYM FROM_0] THEN DISCH_THEN(MP_TAC o SPEC ``m + 1:num`` o MATCH_MP
18003   (ONCE_REWRITE_RULE[CONJ_EQ_IMP] SUMS_OFFSET)) THEN
18004  KNOW_TAC ``0 < m + 1 /\ 0 <= m + 1:num`` THENL
18005  [ASM_SIMP_TAC arith_ss [], DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
18006  REWRITE_TAC[ARITH_PROVE ``0 < m + 1:num``, o_DEF, ADD_SUB] THEN
18007  SIMP_TAC std_ss [GSYM SUM_RESTRICT_SET] THEN
18008  SIMP_TAC std_ss [ETA_AX] THEN
18009  DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP] SERIES_DROP_POS)) THEN
18010  REWRITE_TAC[ONCE_REWRITE_RULE[INTER_COMM] (GSYM INTER_DEF),
18011              REAL_SUB_LE] THEN
18012  DISCH_THEN MATCH_MP_TAC THEN REPEAT STRIP_TAC THEN SIMP_TAC std_ss [] THEN
18013  COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [REAL_LE_REFL] THEN
18014  ASM_MESON_TAC[REAL_ARITH ``abs(x:real) <= y ==> &0 <= y``]);
18015
18016(* ------------------------------------------------------------------------- *)
18017(* Similar combining theorems for infsum.                                    *)
18018(* ------------------------------------------------------------------------- *)
18019
18020val INFSUM_LINEAR = store_thm ("INFSUM_LINEAR",
18021 ``!f h s. summable s f /\ linear h
18022           ==> (infsum s (\n. h(f n)) = h(infsum s f))``,
18023  REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
18024  MATCH_MP_TAC SERIES_LINEAR THEN ASM_REWRITE_TAC[SUMS_INFSUM]);
18025
18026val INFSUM_0 = store_thm ("INFSUM_0",
18027 ``infsum s (\i. 0) = 0``,
18028  MATCH_MP_TAC INFSUM_UNIQUE THEN REWRITE_TAC[SERIES_0]);
18029
18030val INFSUM_ADD = store_thm ("INFSUM_ADD",
18031 ``!x y s. summable s x /\ summable s y
18032           ==> (infsum s (\i. x i + y i) = infsum s x + infsum s y)``,
18033  REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
18034  MATCH_MP_TAC SERIES_ADD THEN ASM_REWRITE_TAC[SUMS_INFSUM]);
18035
18036val INFSUM_SUB = store_thm ("INFSUM_SUB",
18037 ``!x y s. summable s x /\ summable s y
18038           ==> (infsum s (\i. x i - y i) = infsum s x - infsum s y)``,
18039  REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
18040  MATCH_MP_TAC SERIES_SUB THEN ASM_REWRITE_TAC[SUMS_INFSUM]);
18041
18042val INFSUM_CMUL = store_thm ("INFSUM_CMUL",
18043 ``!s x c. summable s x ==> (infsum s (\n. c * x n) = c * infsum s x)``,
18044  REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
18045  MATCH_MP_TAC SERIES_CMUL THEN ASM_REWRITE_TAC[SUMS_INFSUM]);
18046
18047val INFSUM_NEG = store_thm ("INFSUM_NEG",
18048 ``!s x. summable s x ==> (infsum s (\n. -(x n)) = -(infsum s x))``,
18049  REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
18050  MATCH_MP_TAC SERIES_NEG THEN ASM_REWRITE_TAC[SUMS_INFSUM]);
18051
18052val INFSUM_EQ = store_thm ("INFSUM_EQ",
18053 ``!f g k. summable k f /\ summable k g /\ (!x. x IN k ==> (f x = g x))
18054           ==> (infsum k f = infsum k g)``,
18055  REPEAT STRIP_TAC THEN REWRITE_TAC[infsum] THEN
18056  AP_TERM_TAC THEN ABS_TAC THEN ASM_MESON_TAC[SUMS_EQ, SUMS_INFSUM]);
18057
18058val INFSUM_RESTRICT = store_thm ("INFSUM_RESTRICT",
18059 ``!k a:num->real.
18060        infsum univ(:num) (\n. if n IN k then a n else 0) = infsum k a``,
18061  REPEAT GEN_TAC THEN
18062  MP_TAC(ISPECL [``a:num->real``, ``k:num->bool``] SUMMABLE_RESTRICT) THEN
18063  ASM_CASES_TAC ``summable k (a:num->real)`` THEN ASM_REWRITE_TAC[] THEN
18064  STRIP_TAC THENL
18065   [MATCH_MP_TAC INFSUM_UNIQUE THEN
18066    ASM_REWRITE_TAC[SERIES_RESTRICT, SUMS_INFSUM],
18067    FULL_SIMP_TAC std_ss [summable, NOT_EXISTS_THM] THEN
18068    ASM_REWRITE_TAC[infsum]]);
18069
18070val PARTIAL_SUMS_COMPONENT_LE_INFSUM = store_thm ("PARTIAL_SUMS_COMPONENT_LE_INFSUM",
18071 ``!f:num->real s n.
18072        (!i. i IN s ==> &0 <= f i) /\ summable s f
18073        ==> (sum (s INTER ((0:num)..n)) f) <= (infsum s f)``,
18074  REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUMS_INFSUM] THEN
18075  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
18076  REWRITE_TAC[sums, LIM_SEQUENTIALLY] THEN DISCH_TAC THEN
18077  REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
18078  FIRST_X_ASSUM(MP_TAC o SPEC
18079   ``sum (s INTER ((0:num)..n)) (f:num->real) - (infsum s f)``) THEN
18080  ASM_REWRITE_TAC[REAL_SUB_LT] THEN
18081  DISCH_THEN(X_CHOOSE_THEN ``N:num`` (MP_TAC o SPEC ``N + n:num``)) THEN
18082  REWRITE_TAC[LE_ADD, REAL_NOT_LT, dist] THEN
18083  MATCH_MP_TAC REAL_LE_TRANS THEN
18084  EXISTS_TAC ``abs((sum (s INTER ((0:num)..N + n)) f - infsum s f:real))`` THEN
18085  ASM_SIMP_TAC std_ss [REAL_LE_REFL] THEN
18086  MATCH_MP_TAC(REAL_ARITH ``s < a /\ a <= b ==> a - s <= abs(b - s:real)``) THEN
18087  ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN
18088  KNOW_TAC ``sum (s INTER ((0:num)..n)) f <=
18089              sum (s INTER ((0:num)..n) UNION s INTER (n + (1:num)..n + N)) f`` THENL
18090  [ALL_TAC, SIMP_TAC std_ss [GSYM NUMSEG_ADD_SPLIT, ZERO_LESS_EQ, GSYM UNION_OVER_INTER]] THEN
18091  KNOW_TAC ``(sum (s INTER ((0:num)..n) UNION s INTER (n + (1:num)..n + N)) f =
18092              sum (s INTER ((0:num)..n)) f + sum (s INTER (n + (1:num)..n + N)) f)`` THENL
18093  [MATCH_MP_TAC SUM_UNION THEN
18094   SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG, DISJOINT_DEF, EXTENSION] THEN
18095   SIMP_TAC arith_ss [IN_INTER, NOT_IN_EMPTY, IN_NUMSEG] THEN CCONTR_TAC THEN
18096   FULL_SIMP_TAC arith_ss [], ALL_TAC] THEN
18097  DISCH_THEN SUBST1_TAC THEN
18098  REWRITE_TAC[REAL_LE_ADDR] THEN
18099  ASM_SIMP_TAC std_ss [] THEN MATCH_MP_TAC SUM_POS_LE THEN
18100  ASM_SIMP_TAC std_ss [FINITE_INTER, IN_INTER, FINITE_NUMSEG]);
18101
18102val PARTIAL_SUMS_DROP_LE_INFSUM = store_thm ("PARTIAL_SUMS_DROP_LE_INFSUM",
18103 ``!f s n.
18104        (!i. i IN s ==> &0 <= f i) /\
18105        summable s f
18106        ==> sum (s INTER ((0:num)..n)) f <= (infsum s f)``,
18107  REPEAT STRIP_TAC THEN
18108  MATCH_MP_TAC PARTIAL_SUMS_COMPONENT_LE_INFSUM THEN
18109  ASM_REWRITE_TAC[LESS_EQ_REFL]);
18110
18111(* ------------------------------------------------------------------------- *)
18112(* Cauchy criterion for series.                                              *)
18113(* ------------------------------------------------------------------------- *)
18114
18115val SEQUENCE_CAUCHY_WLOG = store_thm ("SEQUENCE_CAUCHY_WLOG",
18116 ``!P s. (!m n:num. P m /\ P n ==> dist(s m,s n) < e) <=>
18117         (!m n. P m /\ P n /\ m <= n ==> dist(s m,s n) < e)``,
18118  MESON_TAC[DIST_SYM, LE_CASES]);
18119
18120val SUM_DIFF_LEMMA = store_thm ("SUM_DIFF_LEMMA",
18121 ``!f:num->real k m n.
18122        m <= n
18123        ==> (sum (k INTER ((0:num) .. n)) f - sum (k INTER ((0:num)..m)) f =
18124             sum (k INTER ((m+1:num) .. n)) f)``,
18125  REPEAT STRIP_TAC THEN
18126  MP_TAC(ISPECL [``f:num->real``, ``k INTER ((0:num)..n)``, ``k INTER ((0:num)..m)``]
18127    SUM_DIFF) THEN
18128  KNOW_TAC ``FINITE (k INTER ((0:num) .. n)) /\
18129             k INTER ((0:num) .. m) SUBSET k INTER ((0:num) .. n)`` THENL
18130   [SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG] THEN MATCH_MP_TAC
18131     (SET_RULE ``s SUBSET t ==> (u INTER s SUBSET u INTER t)``) THEN
18132    REWRITE_TAC[SUBSET_DEF, IN_NUMSEG] THEN POP_ASSUM MP_TAC THEN ARITH_TAC,
18133    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
18134    DISCH_THEN(SUBST1_TAC o SYM) THEN AP_THM_TAC THEN AP_TERM_TAC THEN
18135    REWRITE_TAC[SET_RULE
18136     ``(k INTER s) DIFF (k INTER t) = k INTER (s DIFF t)``] THEN
18137    AP_TERM_TAC THEN REWRITE_TAC[EXTENSION, IN_DIFF, IN_NUMSEG] THEN
18138    POP_ASSUM MP_TAC THEN ARITH_TAC]);
18139
18140val ABS_SUM_TRIVIAL_LEMMA = store_thm ("ABS_SUM_TRIVIAL_LEMMA",
18141 ``!e:real. &0 < e ==> (P ==> abs(sum(s INTER (m..n)) f) < e <=>
18142                        P ==> n < m \/ abs(sum(s INTER (m..n)) f) < e)``,
18143  REPEAT STRIP_TAC THEN ASM_CASES_TAC ``n:num < m`` THEN ASM_REWRITE_TAC[] THEN
18144  FIRST_X_ASSUM(SUBST1_TAC o REWRITE_RULE [GSYM NUMSEG_EMPTY]) THEN
18145  ASM_REWRITE_TAC[SUM_CLAUSES, ABS_0, INTER_EMPTY]);
18146
18147val SERIES_CAUCHY = store_thm ("SERIES_CAUCHY",
18148 ``!f s. (?l. (f sums l) s) =
18149         !e. &0 < e
18150             ==> ?N. !m n. m >= N
18151                           ==> abs(sum(s INTER (m..n)) f) < e``,
18152  REPEAT GEN_TAC THEN REWRITE_TAC[sums, CONVERGENT_EQ_CAUCHY, cauchy] THEN
18153  SIMP_TAC std_ss [SEQUENCE_CAUCHY_WLOG] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
18154  SIMP_TAC std_ss [dist, SUM_DIFF_LEMMA, ABS_SUM_TRIVIAL_LEMMA] THEN
18155  REWRITE_TAC[GE, TAUT `a ==> b \/ c <=> a /\ ~b ==> c`] THEN
18156  REWRITE_TAC[NOT_LESS, ARITH_PROVE
18157   ``(N:num <= m /\ N <= n /\ m <= n) /\ m + 1 <= n <=>
18158    N + 1 <= m + 1 /\ m + 1 <= n``] THEN
18159  AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``e:real`` THEN
18160  ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [] THEN
18161  EQ_TAC THEN DISCH_THEN(X_CHOOSE_TAC ``N:num``) THENL
18162   [EXISTS_TAC ``N + 1:num``, EXISTS_TAC ``N:num``] THEN
18163  REPEAT STRIP_TAC THEN
18164  ASM_SIMP_TAC std_ss [ARITH_PROVE ``N + 1 <= m + 1 ==> N <= m + 1:num``] THEN
18165  FIRST_X_ASSUM(MP_TAC o SPECL [``m - 1:num``, ``n:num``]) THEN
18166  SUBGOAL_THEN ``m - 1 + 1 = m:num`` SUBST_ALL_TAC THENL
18167   [ALL_TAC,
18168    KNOW_TAC ``N <= m - 1 /\ m <= n:num`` THENL
18169    [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC []]] THEN
18170  ASM_ARITH_TAC);
18171
18172val SUMMABLE_CAUCHY = store_thm ("SUMMABLE_CAUCHY",
18173 ``!f s. summable s f <=>
18174         !e. &0 < e
18175             ==> ?N. !m n. m >= N ==> abs(sum(s INTER (m..n)) f) < e``,
18176  REWRITE_TAC[summable, GSYM SERIES_CAUCHY]);
18177
18178val SUMMABLE_IFF_EVENTUALLY = store_thm ("SUMMABLE_IFF_EVENTUALLY",
18179 ``!f g k. (?N. !n. N <= n /\ n IN k ==> (f n = g n))
18180           ==> (summable k f <=> summable k g)``,
18181  REWRITE_TAC[summable, SERIES_CAUCHY] THEN REPEAT GEN_TAC THEN
18182  DISCH_THEN(X_CHOOSE_THEN ``N0:num`` STRIP_ASSUME_TAC) THEN
18183  AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``e:real`` THEN
18184  BETA_TAC THEN AP_TERM_TAC THEN EQ_TAC THEN
18185  DISCH_THEN(X_CHOOSE_THEN ``N1:num``
18186   (fn th => EXISTS_TAC ``N0 + N1:num`` THEN MP_TAC th)) THEN
18187  DISCH_TAC THEN GEN_TAC THEN GEN_TAC THEN
18188  POP_ASSUM (MP_TAC o Q.SPECL [`m:num`,`n:num`]) THEN
18189  DISCH_THEN(fn th => DISCH_TAC THEN MP_TAC th) THEN
18190  (KNOW_TAC ``m >= N1:num`` THENL [POP_ASSUM MP_TAC THEN ARITH_TAC,
18191   DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC]) THEN
18192  MATCH_MP_TAC EQ_IMPLIES THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
18193  MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC std_ss [IN_INTER, IN_NUMSEG] THEN
18194  REPEAT STRIP_TAC THENL [ALL_TAC, CONV_TAC SYM_CONV] THEN
18195  FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
18196  ASM_ARITH_TAC);
18197
18198val SUMMABLE_EQ_EVENTUALLY = store_thm ("SUMMABLE_EQ_EVENTUALLY",
18199 ``!f g k. (?N. !n. N <= n /\ n IN k ==> (f n = g n)) /\ summable k f
18200           ==> summable k g``,
18201  MESON_TAC[SUMMABLE_IFF_EVENTUALLY]);
18202
18203val SUMMABLE_IFF_COFINITE = store_thm ("SUMMABLE_IFF_COFINITE",
18204 ``!f s t. FINITE((s DIFF t) UNION (t DIFF s))
18205           ==> (summable s f <=> summable t f)``,
18206  REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM SUMMABLE_RESTRICT] THEN
18207  MATCH_MP_TAC SUMMABLE_IFF_EVENTUALLY THEN
18208  FIRST_ASSUM(MP_TAC o ISPEC ``\x:num.x`` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN
18209  DISCH_THEN(X_CHOOSE_THEN ``N:num`` MP_TAC) THEN REWRITE_TAC[IN_UNIV] THEN
18210  DISCH_TAC THEN EXISTS_TAC ``N + 1:num`` THEN
18211  REWRITE_TAC[ARITH_PROVE ``N + 1 <= n <=> ~(n <= N:num)``] THEN ASM_SET_TAC[]);
18212
18213val SUMMABLE_EQ_COFINITE = store_thm ("SUMMABLE_EQ_COFINITE",
18214 ``!f s t. FINITE((s DIFF t) UNION (t DIFF s)) /\ summable s f
18215           ==> summable t f``,
18216  MESON_TAC[SUMMABLE_IFF_COFINITE]);
18217
18218val SUMMABLE_FROM_ELSEWHERE = store_thm ("SUMMABLE_FROM_ELSEWHERE",
18219 ``!f m n. summable (from m) f ==> summable (from n) f``,
18220  REPEAT GEN_TAC THEN
18221  MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] SUMMABLE_EQ_COFINITE) THEN
18222  MATCH_MP_TAC SUBSET_FINITE_I THEN EXISTS_TAC ``(0:num)..(m+n)`` THEN
18223  SIMP_TAC std_ss [FINITE_NUMSEG, SUBSET_DEF, IN_NUMSEG, IN_UNION, IN_DIFF, IN_FROM] THEN
18224  ARITH_TAC);
18225
18226(* ------------------------------------------------------------------------- *)
18227(* Uniform vesion of Cauchy criterion.                                       *)
18228(* ------------------------------------------------------------------------- *)
18229
18230val SERIES_CAUCHY_UNIFORM = store_thm ("SERIES_CAUCHY_UNIFORM",
18231 ``!P f:'a->num->real k.
18232        (?l. !e. &0 < e
18233                 ==> ?N. !n x. N <= n /\ P x
18234                               ==> dist(sum(k INTER ((0:num)..n)) (f x),
18235                                        l x) < e) <=>
18236        (!e. &0 < e ==> ?N. !m n x. N <= m /\ P x
18237                                    ==> abs(sum(k INTER (m..n)) (f x)) < e)``,
18238  REPEAT GEN_TAC THEN
18239  SIMP_TAC std_ss [sums, UNIFORMLY_CONVERGENT_EQ_CAUCHY, cauchy] THEN
18240  ONCE_REWRITE_TAC [METIS [] ``(dist (sum (k INTER (0 .. n)) (f x),
18241                                      sum (k INTER (0 .. n')) (f x)) < e) =
18242                      (\n n' x. dist (sum (k INTER (0 .. n)) (f x),
18243                                      sum (k INTER (0 .. n')) (f x)) < e) n n' x``] THEN
18244  ONCE_REWRITE_TAC[MESON[]
18245   ``(!m n:num y. N <= m /\ N <= n /\ P y ==> Q m n y) <=>
18246     (!y. P y ==> !m n. N <= m /\ N <= n ==> Q m n y)``] THEN
18247  SIMP_TAC std_ss [SEQUENCE_CAUCHY_WLOG] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
18248  SIMP_TAC std_ss [dist, SUM_DIFF_LEMMA, ABS_SUM_TRIVIAL_LEMMA] THEN
18249  REWRITE_TAC[GE, TAUT `a ==> b \/ c <=> a /\ ~b ==> c`] THEN
18250  REWRITE_TAC[NOT_LESS, ARITH_PROVE
18251   ``(N <= m /\ N <= n /\ m <= n) /\ m + 1 <= n <=>
18252      N + 1 <= m + 1 /\ m + 1 <= n:num``] THEN
18253  AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC ``e:real`` THEN
18254  ASM_CASES_TAC ``&0 < e:real`` THEN ASM_SIMP_TAC std_ss [] THEN
18255  EQ_TAC THEN DISCH_THEN(X_CHOOSE_TAC ``N:num``) THENL
18256   [EXISTS_TAC ``N + 1:num``, EXISTS_TAC ``N:num``] THEN
18257  REPEAT STRIP_TAC THEN
18258  ASM_SIMP_TAC std_ss [ARITH_PROVE ``N + 1 <= m + 1 ==> N <= m + 1:num``] THEN
18259  FIRST_X_ASSUM(MP_TAC o SPEC ``x:'a``) THEN ASM_REWRITE_TAC[] THEN
18260  DISCH_THEN(MP_TAC o SPECL [``m - 1:num``, ``n:num``]) THEN
18261  SUBGOAL_THEN ``m - 1 + 1 = m:num`` SUBST_ALL_TAC THENL
18262   [ASM_ARITH_TAC, ALL_TAC] THEN
18263  KNOW_TAC ``N <= m - 1 /\ m <= n:num`` THENL
18264  [ASM_ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC []]);
18265
18266(* ------------------------------------------------------------------------- *)
18267(* So trivially, terms of a convergent series go to zero.                    *)
18268(* ------------------------------------------------------------------------- *)
18269
18270val SERIES_GOESTOZERO = store_thm ("SERIES_GOESTOZERO",
18271 ``!s x. summable s x
18272         ==> !e. &0 < e
18273                 ==> eventually (\n. n IN s ==> abs(x n) < e) sequentially``,
18274  REPEAT GEN_TAC THEN REWRITE_TAC[summable, SERIES_CAUCHY] THEN
18275  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN
18276  MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
18277  DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN
18278  X_GEN_TAC ``n:num`` THEN BETA_TAC THEN REPEAT STRIP_TAC THEN
18279  FIRST_X_ASSUM(MP_TAC o SPECL [``n:num``, ``n:num``]) THEN
18280  ASM_SIMP_TAC std_ss [NUMSEG_SING, GE, SET_RULE ``n IN s ==> (s INTER {n} = {n})``] THEN
18281  REWRITE_TAC[SUM_SING]);
18282
18283val SUMMABLE_IMP_TOZERO = store_thm ("SUMMABLE_IMP_TOZERO",
18284 ``!f:num->real k.
18285       summable k f
18286       ==> ((\n. if n IN k then f(n) else 0) --> 0) sequentially``,
18287  REPEAT GEN_TAC THEN GEN_REWR_TAC LAND_CONV [GSYM SUMMABLE_RESTRICT] THEN
18288  REWRITE_TAC[summable, LIM_SEQUENTIALLY, INTER_UNIV, sums] THEN
18289  DISCH_THEN(X_CHOOSE_TAC ``l:real``) THEN X_GEN_TAC ``e:real`` THEN
18290  DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``e / &2:real``) THEN
18291  ASM_SIMP_TAC std_ss [REAL_HALF, LEFT_IMP_EXISTS_THM] THEN
18292  X_GEN_TAC ``N:num`` THEN DISCH_TAC THEN EXISTS_TAC ``N + 1:num`` THEN
18293  X_GEN_TAC ``n:num`` THEN DISCH_TAC THEN
18294  UNDISCH_TAC ``!n:num. N <= n ==>
18295        dist (sum ((0:num) .. n) (\n. if n IN k then f n else 0),l) < e / 2:real`` THEN
18296  DISCH_TAC THEN
18297  FIRST_X_ASSUM(fn th =>
18298    MP_TAC(SPEC ``n - 1:num`` th) THEN MP_TAC(SPEC ``n:num`` th)) THEN
18299  ASM_SIMP_TAC std_ss [ARITH_PROVE ``N + 1 <= n ==> N <= n /\ N <= n - 1:num``] THEN
18300  ABBREV_TAC ``m = n - 1:num`` THEN
18301  SUBGOAL_THEN ``n = SUC m`` SUBST1_TAC THENL
18302   [ASM_ARITH_TAC, ALL_TAC] THEN
18303  SIMP_TAC std_ss [SUM_CLAUSES_NUMSEG, ZERO_LESS_EQ, dist] THEN
18304  SIMP_TAC std_ss [REAL_ARITH ``abs(x - 0) = abs x:real``] THEN
18305  COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [ABS_0] THEN
18306  SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
18307  REAL_ARITH_TAC);
18308
18309val SUMMABLE_IMP_BOUNDED = store_thm ("SUMMABLE_IMP_BOUNDED",
18310 ``!f:num->real k. summable k f ==> bounded (IMAGE f k)``,
18311  REPEAT GEN_TAC THEN
18312  DISCH_THEN(MP_TAC o MATCH_MP SUMMABLE_IMP_TOZERO) THEN
18313  DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN
18314  SIMP_TAC std_ss [BOUNDED_POS, FORALL_IN_IMAGE, IN_UNIV] THEN
18315  METIS_TAC[REAL_LT_IMP_LE, ABS_0]);
18316
18317val SUMMABLE_IMP_SUMS_BOUNDED = store_thm ("SUMMABLE_IMP_SUMS_BOUNDED",
18318 ``!f:num->real k.
18319       summable (from k) f ==> bounded { sum(k..n) f | n IN univ(:num) }``,
18320  SIMP_TAC std_ss [summable, sums, LEFT_IMP_EXISTS_THM] THEN REPEAT GEN_TAC THEN
18321  DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN
18322  SIMP_TAC std_ss [FROM_INTER_NUMSEG, GSYM IMAGE_DEF]);
18323
18324(* ------------------------------------------------------------------------- *)
18325(* Comparison test.                                                          *)
18326(* ------------------------------------------------------------------------- *)
18327
18328val SERIES_COMPARISON = store_thm ("SERIES_COMPARISON",
18329 ``!f g s. (?l. (g sums l) s) /\
18330           (?N. !n. n >= N /\ n IN s ==> abs(f n) <= g n)
18331           ==> ?l:real. (f sums l) s``,
18332  REPEAT GEN_TAC THEN REWRITE_TAC[SERIES_CAUCHY] THEN
18333  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC ``N1:num``)) THEN
18334  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN
18335  MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
18336  DISCH_THEN(X_CHOOSE_TAC ``N2:num``) THEN
18337  EXISTS_TAC ``N1 + N2:num`` THEN
18338  MAP_EVERY X_GEN_TAC [``m:num``, ``n:num``] THEN DISCH_TAC THEN
18339  MATCH_MP_TAC REAL_LET_TRANS THEN
18340  EXISTS_TAC ``abs (sum (s INTER (m .. n)) g)`` THEN CONJ_TAC THENL
18341   [SIMP_TAC std_ss [FINITE_INTER_NUMSEG] THEN
18342    MATCH_MP_TAC(REAL_ARITH ``x <= a ==> x <= abs(a:real)``) THEN
18343    MATCH_MP_TAC SUM_ABS_LE THEN
18344    REWRITE_TAC[FINITE_INTER_NUMSEG, IN_INTER, IN_NUMSEG] THEN
18345    ASM_MESON_TAC[ARITH_PROVE ``m >= N1 + N2:num /\ m <= x ==> x >= N1``],
18346    ASM_MESON_TAC[ARITH_PROVE ``m >= N1 + N2:num ==> m >= N2``]]);
18347
18348val SUMMABLE_COMPARISON = store_thm ("SUMMABLE_COMPARISON",
18349 ``!f g s. summable s g /\
18350           (?N. !n. n >= N /\ n IN s ==> abs(f n) <= g n)
18351           ==> summable s f``,
18352  REWRITE_TAC[summable, SERIES_COMPARISON]);
18353
18354val SERIES_ABSCONV_IMP_CONV = store_thm ("SERIES_ABSCONV_IMP_CONV",
18355 ``!x:num->real k. summable k (\n. (abs(x n))) ==> summable k x``,
18356  REWRITE_TAC[summable] THEN REPEAT STRIP_TAC THEN
18357  MATCH_MP_TAC SERIES_COMPARISON THEN
18358  EXISTS_TAC ``\n:num. abs(x n:real)`` THEN
18359  ASM_SIMP_TAC std_ss [o_DEF, REAL_LE_REFL] THEN ASM_MESON_TAC[]);
18360
18361val SUMMABLE_SUBSET_ABSCONV = store_thm ("SUMMABLE_SUBSET_ABSCONV",
18362 ``!x:num->real s t.
18363        summable s (\n. abs(x n)) /\ t SUBSET s
18364        ==> summable t (\n. abs(x n))``,
18365  REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMMABLE_SUBSET THEN
18366  EXISTS_TAC ``s:num->bool`` THEN ASM_REWRITE_TAC[] THEN
18367  REWRITE_TAC[summable] THEN MATCH_MP_TAC SERIES_COMPARISON THEN
18368  EXISTS_TAC ``\n:num. abs(x n:real)`` THEN
18369  ASM_SIMP_TAC std_ss [o_DEF, GSYM summable] THEN
18370  EXISTS_TAC ``0:num`` THEN REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
18371  SIMP_TAC std_ss [REAL_LE_REFL, ABS_ABS, ABS_0, ABS_POS]);
18372
18373val SERIES_COMPARISON_BOUND = store_thm ("SERIES_COMPARISON_BOUND",
18374 ``!f:num->real g s a.
18375        (g sums a) s /\ (!i. i IN s ==> abs(f i) <= (g i))
18376        ==> ?l. (f sums l) s /\ abs(l) <= a``,
18377  REPEAT STRIP_TAC THEN
18378  MP_TAC(ISPECL [``f:num->real``, ``g:num->real``, ``s:num->bool``]
18379        SUMMABLE_COMPARISON) THEN
18380  SIMP_TAC std_ss [o_DEF, GE, ETA_AX, summable] THEN
18381  KNOW_TAC ``(?l. ((g:num->real) sums l) s) /\
18382             (?N:num. !n. N <= n /\ n IN s ==> abs (f n) <= g n)`` THENL
18383  [ASM_MESON_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
18384  STRIP_TAC THEN EXISTS_TAC ``l:real`` THEN ASM_REWRITE_TAC[] THEN
18385  RULE_ASSUM_TAC(REWRITE_RULE[FROM_0, INTER_UNIV, sums]) THEN
18386  MATCH_MP_TAC SERIES_BOUND THEN MAP_EVERY EXISTS_TAC
18387   [``f:num->real``, ``g:num->real``, ``s:num->bool``] THEN
18388  ASM_SIMP_TAC std_ss [sums, o_DEF, ETA_AX]);
18389
18390(* ------------------------------------------------------------------------- *)
18391(* Uniform version of comparison test.                                       *)
18392(* ------------------------------------------------------------------------- *)
18393
18394val SERIES_COMPARISON_UNIFORM = store_thm ("SERIES_COMPARISON_UNIFORM",
18395 ``!f g P s. (?l. (g sums l) s) /\
18396             (?N. !n x. N <= n /\ n IN s /\ P x ==> abs(f x n) <= g n)
18397             ==> ?l:'a->real.
18398                    !e. &0 < e
18399                        ==> ?N. !n x. N <= n /\ P x
18400                                      ==> dist(sum(s INTER ((0:num)..n)) (f x),
18401                                               l x) < e``,
18402  REPEAT GEN_TAC THEN SIMP_TAC std_ss [GE, SERIES_CAUCHY, SERIES_CAUCHY_UNIFORM] THEN
18403  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC ``N1:num``)) THEN
18404  DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN POP_ASSUM (MP_TAC o SPEC ``e:real``) THEN
18405  MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
18406  DISCH_THEN(X_CHOOSE_TAC ``N2:num``) THEN
18407  EXISTS_TAC ``N1 + N2:num`` THEN
18408  MAP_EVERY X_GEN_TAC [``m:num``, ``n:num``, ``x:'a``] THEN DISCH_TAC THEN
18409  MATCH_MP_TAC REAL_LET_TRANS THEN
18410  EXISTS_TAC ``abs (sum (s INTER (m .. n)) g)`` THEN CONJ_TAC THENL
18411   [SIMP_TAC std_ss [FINITE_INTER_NUMSEG] THEN
18412    MATCH_MP_TAC(REAL_ARITH ``x <= a ==> x <= abs(a:real)``) THEN
18413    MATCH_MP_TAC SUM_ABS_LE THEN
18414    REWRITE_TAC[FINITE_INTER_NUMSEG, IN_INTER, IN_NUMSEG] THEN
18415    ASM_MESON_TAC[ARITH_PROVE ``N1 + N2:num <= m /\ m <= x ==> N1 <= x``],
18416    ASM_MESON_TAC[ARITH_PROVE ``N1 + N2:num <= m ==> N2 <= m``]]);
18417
18418(* ------------------------------------------------------------------------- *)
18419(* Ratio test.                                                               *)
18420(* ------------------------------------------------------------------------- *)
18421
18422val SERIES_RATIO = store_thm ("SERIES_RATIO",
18423 ``!c a s N.
18424      c < &1 /\
18425      (!n. n >= N ==> abs(a(SUC n)) <= c * abs(a(n)))
18426      ==> ?l:real. (a sums l) s``,
18427  REWRITE_TAC[GE] THEN REPEAT STRIP_TAC THEN
18428  MATCH_MP_TAC SERIES_COMPARISON THEN
18429  DISJ_CASES_TAC(REAL_ARITH ``c <= &0 \/ &0 < c:real``) THENL
18430   [EXISTS_TAC ``\n:num. &0:real`` THEN REWRITE_TAC[o_DEF] THEN
18431    CONJ_TAC THENL [MESON_TAC[SERIES_0], ALL_TAC] THEN
18432    EXISTS_TAC ``N + 1:num`` THEN REWRITE_TAC[GE] THEN REPEAT STRIP_TAC THEN
18433    MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``c * abs(a(n - 1:num):real)`` THEN
18434    CONJ_TAC THENL
18435     [ASM_MESON_TAC[ARITH_PROVE ``N + 1 <= n ==> (SUC(n - 1) = n) /\ N <= n - 1``],
18436      ALL_TAC] THEN
18437    MATCH_MP_TAC(REAL_ARITH ``&0 <= -c * x ==> c * x <= &0:real``) THEN
18438    MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[ABS_POS] THEN
18439    UNDISCH_TAC ``c <= &0:real`` THEN REAL_ARITH_TAC,
18440    ASSUME_TAC(MATCH_MP REAL_LT_IMP_LE (ASSUME ``&0 < c:real``))] THEN
18441  EXISTS_TAC ``\n:num. abs(a(N):real) * c pow (n - N)`` THEN
18442  REWRITE_TAC[] THEN CONJ_TAC THENL
18443   [ALL_TAC,
18444    EXISTS_TAC ``N:num`` THEN
18445    SIMP_TAC std_ss [GE, LESS_EQ_EXISTS, CONJ_EQ_IMP, ADD_SUB2, LEFT_IMP_EXISTS_THM] THEN
18446    SUBGOAL_THEN ``!d:num. abs(a(N + d):real) <= abs(a N) * c pow d``
18447     (fn th => MESON_TAC[th]) THEN INDUCT_TAC THEN
18448    REWRITE_TAC[ADD_CLAUSES, pow, REAL_MUL_RID, REAL_LE_REFL] THEN
18449    MATCH_MP_TAC REAL_LE_TRANS THEN
18450    EXISTS_TAC ``c * abs((a:num->real) (N + d:num))`` THEN
18451    ASM_SIMP_TAC std_ss [LE_ADD] THEN
18452    ASM_MESON_TAC[REAL_LE_LMUL, REAL_MUL_ASSOC, REAL_MUL_COMM]] THEN
18453  GEN_REWR_TAC I [SERIES_CAUCHY] THEN X_GEN_TAC ``e:real`` THEN
18454  SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG] THEN
18455  DISCH_TAC THEN SIMP_TAC std_ss [SUM_LMUL, FINITE_INTER, FINITE_NUMSEG] THEN
18456  ASM_CASES_TAC ``(a:num->real) N = 0:real`` THENL
18457   [ASM_REWRITE_TAC[ABS_0, REAL_MUL_LZERO, ABS_N], ALL_TAC] THEN
18458  MP_TAC(SPECL [``c:real``, ``((&1 - c) * e) / abs((a:num->real) N)``]
18459               REAL_ARCH_POW_INV) THEN
18460  ASM_SIMP_TAC std_ss [REAL_LT_DIV, REAL_LT_MUL, REAL_SUB_LT, GSYM ABS_NZ, GE] THEN
18461  DISCH_THEN(X_CHOOSE_TAC ``M:num``) THEN EXISTS_TAC ``N + M:num`` THEN
18462  MAP_EVERY X_GEN_TAC [``m:num``, ``n:num``] THEN DISCH_TAC THEN
18463  MATCH_MP_TAC REAL_LET_TRANS THEN
18464  EXISTS_TAC ``abs(abs((a:num->real) N) *
18465                  sum(m..n) (\i. c pow (i - N)))`` THEN
18466  CONJ_TAC THENL
18467   [REWRITE_TAC[ABS_MUL] THEN MATCH_MP_TAC REAL_LE_LMUL_IMP THEN
18468    REWRITE_TAC[ABS_POS] THEN
18469    MATCH_MP_TAC(REAL_ARITH ``&0 <= x /\ x <= y ==> abs x <= abs y:real``) THEN
18470    ASM_SIMP_TAC std_ss [SUM_POS_LE, FINITE_INTER_NUMSEG, POW_POS] THEN
18471    MATCH_MP_TAC SUM_SUBSET THEN ASM_SIMP_TAC std_ss [POW_POS] THEN
18472    REWRITE_TAC[FINITE_INTER_NUMSEG, FINITE_NUMSEG] THEN
18473    REWRITE_TAC[IN_INTER, IN_DIFF] THEN MESON_TAC[],
18474    ALL_TAC] THEN
18475  REWRITE_TAC[ABS_MUL, ABS_ABS] THEN
18476  DISJ_CASES_TAC(ARITH_PROVE ``n:num < m \/ m <= n``) THENL
18477   [ASM_SIMP_TAC std_ss [SUM_TRIV_NUMSEG, ABS_N, REAL_MUL_RZERO], ALL_TAC] THEN
18478  SUBGOAL_THEN ``(m = 0 + m) /\ (n = (n - m) + m:num)`` (CONJUNCTS_THEN SUBST1_TAC) THENL
18479   [UNDISCH_TAC ``m:num <= n`` THEN ARITH_TAC, ALL_TAC] THEN
18480  REWRITE_TAC[SUM_OFFSET] THEN UNDISCH_TAC ``N + M:num <= m`` THEN
18481  SIMP_TAC std_ss [LESS_EQ_EXISTS] THEN DISCH_THEN(X_CHOOSE_THEN ``d:num`` SUBST_ALL_TAC) THEN
18482  REWRITE_TAC[ARITH_PROVE ``(i + (N + M + d) - N:num) = (M + d) + i``] THEN
18483  ONCE_REWRITE_TAC[POW_ADD] THEN SIMP_TAC arith_ss [SUM_LMUL, SUM_GP] THEN
18484  ASM_SIMP_TAC std_ss [LT, REAL_LT_IMP_NE] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
18485  FULL_SIMP_TAC std_ss [GSYM REAL_LT_RDIV_EQ, ABS_NZ, ABS_MUL] THEN
18486  REWRITE_TAC[GSYM POW_ABS] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
18487  KNOW_TAC ``1 - c:real <> 0`` THENL
18488  [UNDISCH_TAC ``c < 1:real`` THEN REAL_ARITH_TAC, DISCH_TAC] THEN
18489  ASM_SIMP_TAC std_ss [GSYM REAL_LT_RDIV_EQ, ABS_DIV, REAL_POW_LT, ABS_NZ, REAL_ARITH
18490   ``&0 < c /\ c < &1 ==> &0 < abs c /\ &0 < abs(&1 - c:real)``, REAL_LT_LDIV_EQ] THEN
18491  ONCE_REWRITE_TAC [METIS [pow] ``x pow 0 = 1:real``] THEN
18492  MATCH_MP_TAC(REAL_ARITH
18493   ``&0 < x /\ x <= &1 /\ &1 <= e ==> abs(1 - x) < e:real``) THEN
18494  ASM_SIMP_TAC std_ss [REAL_POW_LT, REAL_POW_1_LE, REAL_LT_IMP_LE] THEN
18495  ASM_SIMP_TAC std_ss [REAL_ARITH ``c < &1 ==> (x * abs(&1 - c) = (&1 - c) * x:real)``] THEN
18496  KNOW_TAC ``(abs (c pow M) <> 0:real) /\ (abs (c pow d) <> 0:real)`` THENL
18497  [CONJ_TAC THEN ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN MATCH_MP_TAC REAL_LT_IMP_NE THEN
18498   REWRITE_TAC [GSYM ABS_NZ] THEN ONCE_REWRITE_TAC [EQ_SYM_EQ] THEN
18499   MATCH_MP_TAC REAL_LT_IMP_NE THEN METIS_TAC [REAL_POW_LT], STRIP_TAC] THEN
18500  FULL_SIMP_TAC real_ss [real_div, REAL_INV_MUL, ABS_NZ, REAL_POW_LT, REAL_POW_ADD,
18501                        REAL_MUL_ASSOC, REAL_LT_IMP_NE, POW_ABS, ABS_MUL] THEN
18502  REWRITE_TAC[REAL_ARITH
18503   ``(a * b * c * d * e) = (e * ((a * b) * c)) * d:real``] THEN
18504  ASM_SIMP_TAC real_ss [GSYM real_div, REAL_LE_RDIV_EQ, REAL_POW_LT, REAL_MUL_LID,
18505               REAL_ARITH ``&0 < c ==> (abs c = c:real)``] THEN
18506  REWRITE_TAC [real_div] THEN
18507  FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
18508   ``xm < e ==> &0 <= (d - &1) * e ==> xm <= d * e:real``)) THEN
18509  MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THENL
18510   [REWRITE_TAC[REAL_SUB_LE, GSYM REAL_POW_INV] THEN
18511    MATCH_MP_TAC REAL_POW_LE_1 THEN
18512    MATCH_MP_TAC REAL_INV_1_LE THEN ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE],
18513    MATCH_MP_TAC REAL_LT_IMP_LE THEN
18514    ASM_SIMP_TAC std_ss [REAL_SUB_LT, REAL_LT_MUL, REAL_LT_DIV, ABS_NZ, GSYM real_div]]);
18515
18516(* ------------------------------------------------------------------------- *)
18517(* Ostensibly weaker versions of the boundedness of partial sums.            *)
18518(* ------------------------------------------------------------------------- *)
18519
18520val BOUNDED_PARTIAL_SUMS = store_thm ("BOUNDED_PARTIAL_SUMS",
18521 ``!f:num->real k.
18522        bounded { sum(k..n) f | n IN univ(:num) }
18523        ==> bounded { sum(m..n) f | m IN univ(:num) /\ n IN univ(:num) }``,
18524  REPEAT STRIP_TAC THEN
18525  SUBGOAL_THEN ``bounded { sum((0:num)..n) f:real | n IN univ(:num) }`` MP_TAC THENL
18526   [FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [BOUNDED_POS]) THEN
18527    REWRITE_TAC[bounded_def] THEN
18528    SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, IN_UNIV] THEN
18529    DISCH_THEN(X_CHOOSE_THEN ``B:real`` STRIP_ASSUME_TAC) THEN
18530    EXISTS_TAC ``sum { i:num | i < k} (\i. abs(f i:real)) + B`` THEN
18531    X_GEN_TAC ``i:num`` THEN ASM_CASES_TAC ``i:num < k`` THENL
18532     [MATCH_MP_TAC(REAL_ARITH
18533       ``!y. x <= y /\ y <= a /\ &0 < b ==> x <= a + b:real``) THEN
18534      EXISTS_TAC ``sum ((0:num)..i) (\i. abs(f i:real))`` THEN
18535      ASM_SIMP_TAC std_ss [SUM_ABS, FINITE_NUMSEG] THEN
18536      MATCH_MP_TAC SUM_SUBSET THEN
18537      REWRITE_TAC[FINITE_NUMSEG, FINITE_NUMSEG_LT, ABS_POS] THEN
18538      SIMP_TAC std_ss [IN_DIFF, IN_NUMSEG, GSPECIFICATION] THEN
18539      ASM_SIMP_TAC arith_ss [] THEN REAL_ARITH_TAC,
18540      ALL_TAC] THEN
18541    ASM_CASES_TAC ``k = 0:num`` THENL
18542     [FIRST_X_ASSUM SUBST_ALL_TAC THEN MATCH_MP_TAC(REAL_ARITH
18543       ``x <= B /\ &0 <= b ==> x <= b + B:real``) THEN
18544      ASM_SIMP_TAC std_ss [SUM_POS_LE, FINITE_NUMSEG_LT, ABS_POS],
18545      ALL_TAC] THEN
18546    MP_TAC(ISPECL [``f:num->real``, ``0:num``, ``k:num``, ``i:num``]
18547      SUM_COMBINE_L) THEN
18548    KNOW_TAC ``0 < k /\ 0 <= k /\ k <= i + 1:num`` THENL
18549    [ASM_SIMP_TAC arith_ss [],
18550     DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
18551    DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[NUMSEG_LT] THEN
18552    MATCH_MP_TAC(REAL_ARITH
18553     ``abs(x) <= a /\ abs(y) <= b ==> abs(x + y) <= a + b:real``) THEN
18554    ASM_SIMP_TAC std_ss [SUM_ABS, FINITE_NUMSEG],
18555    ALL_TAC] THEN
18556  DISCH_THEN(fn th =>
18557    MP_TAC(MATCH_MP BOUNDED_DIFFS (W CONJ th)) THEN MP_TAC th) THEN
18558  REWRITE_TAC[AND_IMP_INTRO, GSYM BOUNDED_UNION] THEN
18559  MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b ==> c <=> b ==> a ==> c`]
18560        BOUNDED_SUBSET) THEN
18561  KNOW_TAC ``!x:real m n:num.
18562     (x = sum (m..n) f)
18563     ==> (?n. x = sum ((0:num)..n) f) \/
18564         (?x' y.
18565              ((?n. x' = sum ((0:num)..n) f) /\ (?n. y = sum ((0:num)..n) f)) /\
18566              (x = x' - y))`` THENL
18567  [ALL_TAC, SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_UNION, LEFT_IMP_EXISTS_THM,
18568                             IN_UNIV, EXISTS_PROD] THEN METIS_TAC []] THEN
18569  MAP_EVERY X_GEN_TAC [``x:real``, ``m:num``, ``n:num``] THEN
18570  DISCH_THEN SUBST1_TAC THEN
18571  ASM_CASES_TAC ``m = 0:num`` THENL [ASM_MESON_TAC[], ALL_TAC] THEN
18572  ASM_CASES_TAC ``n:num < m`` THENL
18573   [DISJ2_TAC THEN REPEAT(EXISTS_TAC ``sum((0:num)..(0:num)) (f:num->real)``) THEN
18574    ASM_SIMP_TAC std_ss [SUM_TRIV_NUMSEG, REAL_SUB_REFL] THEN MESON_TAC[],
18575    ALL_TAC] THEN
18576  DISJ2_TAC THEN MAP_EVERY EXISTS_TAC
18577   [``sum((0:num)..n) (f:num->real)``, ``sum((0:num)..(m-1:num)) (f:num->real)``] THEN
18578  CONJ_TAC THENL [MESON_TAC[], ALL_TAC] THEN
18579  MP_TAC(ISPECL [``f:num->real``, ``0:num``, ``m:num``, ``n:num``]
18580      SUM_COMBINE_L) THEN ASM_SIMP_TAC arith_ss [] THEN
18581  REAL_ARITH_TAC);
18582
18583(* ------------------------------------------------------------------------- *)
18584(* General Dirichlet convergence test (could make this uniform on a set).    *)
18585(* ------------------------------------------------------------------------- *)
18586
18587val SUMMABLE_BILINEAR_PARTIAL_PRE = store_thm ("SUMMABLE_BILINEAR_PARTIAL_PRE",
18588 ``!f g h:real->real->real l k.
18589        bilinear h /\
18590        ((\n. h (f(n + 1)) (g(n))) --> l) sequentially /\
18591        summable (from k) (\n. h (f(n + 1) - f(n)) (g(n)))
18592        ==> summable (from k) (\n. h (f n) (g(n) - g(n - 1)))``,
18593  REPEAT GEN_TAC THEN
18594  SIMP_TAC std_ss [summable, sums, FROM_INTER_NUMSEG] THEN
18595  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
18596  FIRST_ASSUM(fn th =>
18597   REWRITE_TAC[MATCH_MP BILINEAR_SUM_PARTIAL_PRE th]) THEN
18598  DISCH_THEN(X_CHOOSE_TAC ``l':real``) THEN
18599  EXISTS_TAC ``l - (h:real->real->real) ((f:num->real) k) (g(k - 1)) - l'`` THEN
18600  SIMP_TAC std_ss [LIM_CASES_SEQUENTIALLY] THEN
18601  KNOW_TAC  ``(((\(n :num).
18602     (\n. (h :real -> real -> real) ((f :num -> real) (n + (1 :num)))
18603       ((g :num -> real) n) - h (f (k :num)) (g (k - (1 :num)))) n -
18604     (\n. sum (k .. n) (\(k :num). h (f (k + (1 :num)) - f k) (g k))) n) -->
18605  ((l :real) - h (f k) (g (k - (1 :num))) - (l' :real))) sequentially :
18606   bool)`` THENL
18607  [ALL_TAC, METIS_TAC []] THEN
18608  MATCH_MP_TAC LIM_SUB THEN ASM_SIMP_TAC std_ss [LIM_CONST] THEN
18609  KNOW_TAC ``(((\(n :num).
18610     (\n. (h :real -> real -> real) ((f :num -> real) (n + (1 :num)))
18611       ((g :num -> real) n)) n - (\n. h (f (k :num)) (g (k - (1 :num)))) n) -->
18612  ((l :real) - h (f k) (g (k - (1 :num))))) sequentially :bool)`` THENL
18613  [ALL_TAC, METIS_TAC []] THEN MATCH_MP_TAC LIM_SUB THEN
18614  ASM_SIMP_TAC std_ss [LIM_CONST]);
18615
18616val SERIES_DIRICHLET_BILINEAR = store_thm ("SERIES_DIRICHLET_BILINEAR",
18617 ``!f g h:real->real->real k m p l.
18618        bilinear h /\
18619        bounded {sum (m..n) f | n IN univ(:num)} /\
18620        summable (from p) (\n. abs(g(n + 1) - g(n))) /\
18621        ((\n. h (g(n + 1)) (sum((1:num)..n) f)) --> l) sequentially
18622        ==> summable (from k) (\n. h (g n) (f n))``,
18623  REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE THEN
18624  EXISTS_TAC ``1:num`` THEN
18625  FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP BOUNDED_PARTIAL_SUMS) THEN
18626  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [BOUNDED_POS]) THEN
18627  SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV, LEFT_IMP_EXISTS_THM, EXISTS_PROD] THEN
18628  X_GEN_TAC ``B:real`` THEN STRIP_TAC THEN
18629  FIRST_ASSUM(MP_TAC o MATCH_MP BILINEAR_BOUNDED_POS) THEN
18630  DISCH_THEN(X_CHOOSE_THEN ``C:real`` STRIP_ASSUME_TAC) THEN
18631  MATCH_MP_TAC SUMMABLE_EQ THEN
18632  EXISTS_TAC ``\n. (h:real->real->real)
18633                   (g n) (sum ((1:num)..n) f - sum ((1:num)..n-1:num) f)`` THEN
18634  SIMP_TAC std_ss [IN_FROM, GSYM NUMSEG_RREC] THEN
18635  SIMP_TAC std_ss [SUM_CLAUSES, FINITE_NUMSEG, IN_NUMSEG,
18636           ARITH_PROVE ``1 <= n ==> ~(n <= n - 1:num)``] THEN
18637  CONJ_TAC THENL
18638   [REPEAT STRIP_TAC THEN ASM_SIMP_TAC std_ss [BILINEAR_RADD, BILINEAR_RSUB] THEN
18639    REAL_ARITH_TAC,
18640    ALL_TAC] THEN
18641  MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE THEN EXISTS_TAC ``p:num`` THEN
18642  MP_TAC(ISPECL [``g:num->real``, ``\n. sum((1:num)..n) f:real``,
18643                 ``h:real->real->real``, ``l:real``, ``p:num``]
18644         SUMMABLE_BILINEAR_PARTIAL_PRE) THEN
18645  SIMP_TAC std_ss [] THEN DISCH_THEN MATCH_MP_TAC THEN
18646  ASM_REWRITE_TAC[] THEN
18647  SUBGOAL_THEN
18648    ``summable (from p) ((\n. C * B * abs(g(n + 1) - g(n):real)))``
18649  MP_TAC THENL [ASM_SIMP_TAC std_ss [o_DEF, SUMMABLE_CMUL], ALL_TAC] THEN
18650  MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUMMABLE_COMPARISON) THEN
18651  EXISTS_TAC ``0:num`` THEN REWRITE_TAC[IN_FROM, GE, ZERO_LESS_EQ] THEN
18652  REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
18653   ``C * abs(g(n + 1:num) - g(n):real) * abs(sum ((1:num)..n) f:real)`` THEN
18654  ASM_SIMP_TAC std_ss [REAL_LE_LMUL] THEN
18655  REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN
18656  ASM_SIMP_TAC std_ss [REAL_LE_LMUL] THEN
18657  GEN_REWR_TAC RAND_CONV [REAL_MUL_SYM] THEN
18658  ASM_SIMP_TAC std_ss [REAL_LE_LMUL_IMP, ABS_POS]);
18659
18660val SERIES_DIRICHLET = store_thm ("SERIES_DIRICHLET",
18661 ``!f:num->real g N k m.
18662        bounded {sum (m..n) f | n IN univ(:num)} /\
18663        (!n. N <= n ==> g(n + 1) <= g(n)) /\
18664        (g --> 0) sequentially
18665        ==> summable (from k) (\n. g(n) * f(n))``,
18666  REPEAT STRIP_TAC THEN
18667  MP_TAC(ISPECL [``f:num->real``, ``g:num->real``,
18668                 ``\x y:real. x * y``] SERIES_DIRICHLET_BILINEAR) THEN
18669  SIMP_TAC std_ss [o_THM] THEN DISCH_THEN MATCH_MP_TAC THEN
18670  MAP_EVERY EXISTS_TAC [``m:num``, ``N:num``, ``0:real``] THEN CONJ_TAC THENL
18671   [SIMP_TAC std_ss [bilinear, linear] THEN
18672    REPEAT STRIP_TAC THEN REAL_ARITH_TAC,
18673    ALL_TAC] THEN
18674  ASM_REWRITE_TAC [] THEN
18675  FIRST_ASSUM(MP_TAC o SPEC ``1:num`` o MATCH_MP SEQ_OFFSET) THEN
18676  SIMP_TAC std_ss [o_THM] THEN DISCH_TAC THEN CONJ_TAC THENL
18677   [MATCH_MP_TAC SUMMABLE_EQ_EVENTUALLY THEN
18678    EXISTS_TAC ``(\n. (g:num->real)(n) - g(n + 1))`` THEN SIMP_TAC std_ss [] THEN
18679    CONJ_TAC THENL
18680     [EXISTS_TAC ``N:num`` THEN REPEAT STRIP_TAC THEN
18681      UNDISCH_TAC ``!n. N <= n ==> g (n + 1) <= (g:num->real) n`` THEN
18682      DISCH_THEN (MP_TAC o SPEC ``n:num``) THEN
18683      ASM_REWRITE_TAC [] THEN REAL_ARITH_TAC,
18684      SIMP_TAC std_ss [summable, sums, FROM_INTER_NUMSEG, SUM_DIFFS] THEN
18685      SIMP_TAC std_ss [LIM_CASES_SEQUENTIALLY] THEN
18686      EXISTS_TAC ``(g(N:num)) - 0:real`` THEN
18687      ONCE_REWRITE_TAC [METIS [] ``((\n:num. g N - g (n + 1)) --> (g N - 0:real)) =
18688                       ((\n. (\n. g N) n - (\n. g (n + 1)) n) --> (g N - 0))``] THEN
18689      MATCH_MP_TAC LIM_SUB THEN ASM_REWRITE_TAC[LIM_CONST]],
18690    ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN
18691    ONCE_REWRITE_TAC [METIS []
18692        ``((\n. sum (1 .. n) f * (g:num->real) (n + 1)) --> 0) =
18693      ((\n. (\n. sum (1 .. n) f) n * (\n. g (n + 1)) n) --> 0)``] THEN
18694    MATCH_MP_TAC LIM_NULL_CMUL_BOUNDED THEN ASM_SIMP_TAC std_ss [o_DEF] THEN
18695    REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
18696    FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP BOUNDED_PARTIAL_SUMS) THEN
18697    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [BOUNDED_POS]) THEN
18698    SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV, EXISTS_PROD] THEN METIS_TAC[]]);
18699
18700(* ------------------------------------------------------------------------- *)
18701(* Rearranging absolutely convergent series.                                 *)
18702(* ------------------------------------------------------------------------- *)
18703
18704val lemma = prove (
18705   ``!f:'a->real s t.
18706          FINITE s /\ FINITE t
18707          ==> (sum s f - sum t f = sum (s DIFF t) f - sum (t DIFF s) f)``,
18708    REPEAT STRIP_TAC THEN
18709    ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s DIFF (s INTER t)``] THEN
18710    ASM_SIMP_TAC std_ss [SUM_DIFF, INTER_SUBSET] THEN
18711    GEN_REWR_TAC (RAND_CONV o RAND_CONV o ONCE_DEPTH_CONV) [INTER_COMM] THEN
18712    REAL_ARITH_TAC);
18713
18714val SERIES_INJECTIVE_IMAGE_STRONG = store_thm ("SERIES_INJECTIVE_IMAGE_STRONG",
18715 ``!x:num->real s f.
18716        summable (IMAGE f s) (\n. abs(x n)) /\
18717        (!m n. m IN s /\ n IN s /\ (f m = f n) ==> (m = n))
18718        ==> ((\n. sum (IMAGE f s INTER ((0:num)..n)) x -
18719                  sum (s INTER ((0:num)..n)) (x o f)) --> 0)
18720            sequentially``,
18721  REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY] THEN
18722  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
18723  UNDISCH_TAC ``(summable (IMAGE (f :num -> num) (s :num -> bool))
18724         (\(n :num). abs ((x :num -> real) n)) :bool)`` THEN DISCH_TAC THEN
18725  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUMMABLE_CAUCHY]) THEN
18726  SIMP_TAC std_ss [FINITE_INTER, FINITE_NUMSEG] THEN
18727  GEN_REWR_TAC (LAND_CONV o ONCE_DEPTH_CONV) [o_DEF] THEN
18728  SIMP_TAC std_ss [SUM_POS_LE, ABS_POS, FINITE_INTER, FINITE_NUMSEG] THEN
18729  DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN
18730  ASM_REWRITE_TAC[dist, GE, REAL_SUB_RZERO, REAL_HALF] THEN
18731  DISCH_THEN(X_CHOOSE_THEN ``N:num`` STRIP_ASSUME_TAC) THEN
18732  UNDISCH_TAC ``!(m :num) (n :num).
18733        m IN (s :num -> bool) /\ n IN s /\ ((f :num -> num) m = f n) ==>
18734        (m = n)`` THEN DISCH_TAC THEN
18735  FIRST_ASSUM(MP_TAC o REWRITE_RULE [INJECTIVE_ON_LEFT_INVERSE]) THEN
18736  DISCH_THEN(X_CHOOSE_TAC ``g:num->num``) THEN
18737  MP_TAC(ISPECL [``g:num->num``, ``((0:num)..N)``] UPPER_BOUND_FINITE_SET) THEN
18738  REWRITE_TAC[FINITE_NUMSEG, IN_NUMSEG, ZERO_LESS_EQ] THEN
18739  DISCH_THEN(X_CHOOSE_TAC ``P:num``) THEN
18740  EXISTS_TAC ``MAX N P:num`` THEN X_GEN_TAC ``n:num`` THEN
18741  REWRITE_TAC [MAX_DEF] THEN
18742  SIMP_TAC std_ss [ARITH_PROVE ``(if a < b then b else a) <= c <=> a <= c /\ b <= c:num``] THEN
18743  DISCH_TAC THEN
18744  W(MP_TAC o PART_MATCH (rand o rand) SUM_IMAGE o rand o
18745    rand o lhand o snd) THEN
18746  KNOW_TAC ``(!(x :num) (y :num).
18747    x IN (s :num -> bool) INTER ((0 :num) .. (n :num)) /\
18748    y IN s INTER ((0 :num) .. n) /\ ((f :num -> num) x = f y) ==>
18749    (x = y))`` THENL
18750   [ASM_MESON_TAC[FINITE_INTER, FINITE_NUMSEG, IN_INTER],
18751    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
18752    DISCH_THEN(SUBST1_TAC o SYM)] THEN
18753  W(MP_TAC o PART_MATCH (lhand o rand) lemma o rand o lhand o snd) THEN
18754  SIMP_TAC std_ss [FINITE_INTER, IMAGE_FINITE, FINITE_NUMSEG] THEN
18755  DISCH_THEN SUBST1_TAC THEN GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN
18756   MATCH_MP_TAC(REAL_ARITH
18757   ``abs a < x /\ abs b < y ==> abs(a - b:real) < x + y:real``) THEN
18758  CONJ_TAC THEN
18759  W(MP_TAC o PART_MATCH (lhand o rand) SUM_ABS o lhand o snd) THEN
18760  SIMP_TAC std_ss [FINITE_DIFF, IMAGE_FINITE, FINITE_INTER, FINITE_NUMSEG] THEN
18761  MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LET_TRANS) THEN
18762  MATCH_MP_TAC REAL_LET_TRANS THENL
18763   [EXISTS_TAC
18764     ``sum((IMAGE (f:num->num) s) INTER (N..n)) (\i. abs(x i :real))`` THEN
18765    CONJ_TAC THENL [ALL_TAC,
18766     MATCH_MP_TAC (REAL_ARITH ``abs x < y ==> x < y:real``) THEN
18767     ASM_SIMP_TAC real_ss []] THEN
18768    MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
18769    SIMP_TAC std_ss [ABS_POS, FINITE_INTER, FINITE_NUMSEG] THEN
18770    MATCH_MP_TAC(SET_RULE
18771     ``(!x. x IN s /\ f(x) IN n /\ ~(x IN m) ==> f x IN t)
18772      ==> (IMAGE f s INTER n) DIFF (IMAGE f (s INTER m)) SUBSET
18773          IMAGE f s INTER t``) THEN
18774    ASM_SIMP_TAC std_ss [IN_NUMSEG, ZERO_LESS_EQ, NOT_LESS_EQUAL] THEN
18775    X_GEN_TAC ``i:num`` THEN STRIP_TAC THEN
18776    MATCH_MP_TAC LESS_IMP_LESS_OR_EQ THEN ONCE_REWRITE_TAC[GSYM NOT_LESS_EQUAL] THEN
18777    UNDISCH_TAC ``!(x :num). x <= (N :num) ==> (g :num -> num) x <= (P :num)`` THEN
18778    DISCH_TAC THEN POP_ASSUM(MATCH_MP_TAC o ONCE_REWRITE_RULE [MONO_NOT_EQ]) THEN
18779    ASM_SIMP_TAC arith_ss [],
18780    MP_TAC(ISPECL [``f:num->num``, ``((0:num)..n)``] UPPER_BOUND_FINITE_SET) THEN
18781    REWRITE_TAC[FINITE_NUMSEG, IN_NUMSEG, ZERO_LESS_EQ] THEN
18782    DISCH_THEN(X_CHOOSE_TAC ``p:num``) THEN
18783    EXISTS_TAC
18784     ``sum(IMAGE (f:num->num) s INTER (N..p)) (\i. abs(x i :real))`` THEN
18785    CONJ_TAC THENL [ALL_TAC,
18786     MATCH_MP_TAC (REAL_ARITH ``abs x < y ==> x < y:real``) THEN
18787     ASM_SIMP_TAC real_ss []] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
18788    SIMP_TAC std_ss [ABS_POS, FINITE_INTER, FINITE_NUMSEG] THEN
18789    MATCH_MP_TAC(SET_RULE
18790     ``(!x. x IN s /\ x IN n /\ ~(f x IN m) ==> f x IN t)
18791      ==> (IMAGE f (s INTER n) DIFF (IMAGE f s) INTER m) SUBSET
18792          (IMAGE f s INTER t)``) THEN
18793    ASM_SIMP_TAC arith_ss [IN_NUMSEG, ZERO_LESS_EQ]]);
18794
18795val SERIES_INJECTIVE_IMAGE = store_thm ("SERIES_INJECTIVE_IMAGE",
18796 ``!x:num->real s f l.
18797        summable (IMAGE f s) (\n. abs(x n)) /\
18798        (!m n. m IN s /\ n IN s /\ (f m = f n) ==> (m = n))
18799        ==> (((x o f) sums l) s <=> (x sums l) (IMAGE f s))``,
18800  REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN REWRITE_TAC[sums] THEN
18801  MATCH_MP_TAC LIM_TRANSFORM_EQ THEN SIMP_TAC std_ss [] THEN
18802  MATCH_MP_TAC SERIES_INJECTIVE_IMAGE_STRONG THEN
18803  ASM_REWRITE_TAC[]);
18804
18805val SERIES_REARRANGE_EQ = store_thm ("SERIES_REARRANGE_EQ",
18806 ``!x:num->real s p l.
18807        (summable s (\n. abs(x n))) /\ (p permutes s)
18808        ==> (((x o p) sums l) s <=> (x sums l) s)``,
18809  REPEAT STRIP_TAC THEN
18810  MP_TAC(ISPECL [``x:num->real``, ``s:num->bool``, ``p:num->num``, ``l:real``]
18811        SERIES_INJECTIVE_IMAGE) THEN
18812  ASM_SIMP_TAC std_ss [PERMUTES_IMAGE] THEN
18813  ASM_MESON_TAC[PERMUTES_INJECTIVE]);
18814
18815val SERIES_REARRANGE = store_thm ("SERIES_REARRANGE",
18816 ``!x:num->real s p l.
18817        summable s (\n. abs(x n)) /\ p permutes s /\ (x sums l) s
18818        ==> ((x o p) sums l) s``,
18819  METIS_TAC[SERIES_REARRANGE_EQ]);
18820
18821val SUMMABLE_REARRANGE = store_thm ("SUMMABLE_REARRANGE",
18822 ``!x s p.
18823        summable s (\n. abs(x n)) /\ p permutes s
18824        ==> summable s (x o p)``,
18825  METIS_TAC[SERIES_ABSCONV_IMP_CONV, summable, SERIES_REARRANGE]);
18826
18827(* ------------------------------------------------------------------------- *)
18828(* Banach fixed point theorem (not really topological...)                    *)
18829(* ------------------------------------------------------------------------- *)
18830
18831val BANACH_FIX = store_thm ("BANACH_FIX",
18832 ``!f s c. complete s /\ ~(s = {}) /\
18833           &0 <= c /\ c < &1 /\
18834           (IMAGE f s) SUBSET s /\
18835           (!x y. x IN s /\ y IN s ==> dist(f(x),f(y)) <= c * dist(x,y))
18836           ==> ?!x:real. x IN s /\ (f x = x)``,
18837  REPEAT STRIP_TAC THEN SIMP_TAC std_ss [EXISTS_UNIQUE_THM] THEN CONJ_TAC THENL
18838   [ALL_TAC,
18839    MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN
18840    SUBGOAL_THEN ``dist((f:real->real) x,f y) <= c * dist(x,y)`` MP_TAC THENL
18841     [ASM_MESON_TAC[], ALL_TAC] THEN
18842    ASM_REWRITE_TAC[REAL_ARITH ``a <= c * a <=> &0 <= -a * (&1 - c:real)``] THEN
18843    ASM_SIMP_TAC std_ss [GSYM REAL_LE_LDIV_EQ, REAL_SUB_LT, real_div] THEN
18844    REWRITE_TAC[REAL_MUL_LZERO, REAL_ARITH ``&0:real <= -x <=> ~(&0 < x)``] THEN
18845    MESON_TAC[DIST_POS_LT]] THEN
18846  KNOW_TAC ``?z. (z 0 = @x:real. x IN s) /\ (!n. z(SUC n) = f(z n))`` THENL
18847  [RW_TAC std_ss [num_Axiom], STRIP_TAC] THEN
18848  SUBGOAL_THEN ``!n. (z:num->real) n IN s`` ASSUME_TAC THENL
18849   [INDUCT_TAC THEN ASM_SIMP_TAC std_ss [] THEN
18850    METIS_TAC[MEMBER_NOT_EMPTY, SUBSET_DEF, IN_IMAGE],
18851    ALL_TAC] THEN
18852  UNDISCH_THEN ``z (0:num) = @x:real. x IN s`` (K ALL_TAC) THEN
18853  SUBGOAL_THEN ``?x:real. x IN s /\ (z --> x) sequentially`` MP_TAC THENL
18854   [ALL_TAC,
18855    DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN
18856    POP_ASSUM MP_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
18857    ABBREV_TAC ``e = dist(f(a:real),a)`` THEN
18858    SUBGOAL_THEN ``~(&0 < e:real)`` (fn th => METIS_TAC[th, DIST_POS_LT]) THEN
18859    DISCH_TAC THEN UNDISCH_TAC ``(z --> a) sequentially`` THEN DISCH_TAC THEN
18860    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LIM_SEQUENTIALLY]) THEN
18861    DISCH_THEN(MP_TAC o SPEC ``e / &2:real``) THEN
18862    ASM_REWRITE_TAC[REAL_HALF] THEN DISCH_THEN(X_CHOOSE_TAC ``N:num``) THEN
18863    SUBGOAL_THEN
18864     ``dist(f(z N),a:real) < e / &2 /\ dist(f(z(N:num)),f(a)) < e / &2``
18865     (fn th => ASM_MESON_TAC[th, DIST_TRIANGLE_HALF_R, REAL_LT_REFL]) THEN
18866    CONJ_TAC THENL [ASM_MESON_TAC[ARITH_PROVE ``N <= SUC N``], ALL_TAC] THEN
18867    MATCH_MP_TAC REAL_LET_TRANS THEN
18868    EXISTS_TAC ``c * dist((z:num->real) N,a)`` THEN ASM_SIMP_TAC std_ss [] THEN
18869    MATCH_MP_TAC(REAL_ARITH ``x < y /\ c * x <= &1 * x ==> c * x < y:real``) THEN
18870    ASM_SIMP_TAC std_ss [LESS_EQ_REFL, REAL_LE_RMUL_IMP, DIST_POS_LE, REAL_LT_IMP_LE]] THEN
18871  UNDISCH_TAC ``complete s`` THEN DISCH_TAC THEN
18872  FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE [complete]) THEN
18873  ASM_REWRITE_TAC[CAUCHY] THEN
18874  SUBGOAL_THEN ``!n. dist(z(n):real,z(SUC n)) <= c pow n * dist(z(0),z(1))``
18875  ASSUME_TAC THENL
18876   [INDUCT_TAC THEN
18877    SIMP_TAC arith_ss [pow, REAL_MUL_LID, REAL_LE_REFL] THEN
18878    MATCH_MP_TAC REAL_LE_TRANS THEN
18879    EXISTS_TAC ``c * dist(z(n):real,z(SUC n))`` THEN
18880    CONJ_TAC THENL [ASM_MESON_TAC[], ALL_TAC] THEN
18881    REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC std_ss [REAL_LE_LMUL_IMP],
18882    ALL_TAC] THEN
18883  SUBGOAL_THEN
18884   ``!m n:num. (&1 - c) * dist(z(m):real,z(m+n))
18885                <= c pow m * dist(z(0),z(1:num)) * (&1 - c pow n)``
18886  ASSUME_TAC THENL
18887   [GEN_TAC THEN INDUCT_TAC THENL
18888     [REWRITE_TAC[ADD_CLAUSES, DIST_REFL, REAL_MUL_RZERO, GSYM REAL_MUL_ASSOC] THEN
18889      MATCH_MP_TAC REAL_LE_MUL THEN
18890      ASM_SIMP_TAC std_ss [REAL_LE_MUL, POW_POS, DIST_POS_LE, REAL_SUB_LE,
18891                   REAL_POW_1_LE, REAL_LT_IMP_LE],
18892      ALL_TAC] THEN
18893    MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
18894    ``(&1 - c) * (dist(z m:real,z(m + n)) + dist(z(m + n),z(m + SUC n)))`` THEN
18895    ASM_SIMP_TAC std_ss [REAL_LE_LMUL_IMP, REAL_SUB_LE, REAL_LT_IMP_LE, DIST_TRIANGLE] THEN
18896    FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
18897      ``c * x <= y ==> c * x' + y <= y' ==> c * (x + x') <= y':real``)) THEN
18898    REWRITE_TAC[REAL_ARITH
18899     ``q + a * b * (&1 - x) <= a * b * (&1 - y) <=> q <= a * b * (x - y:real)``] THEN
18900    REWRITE_TAC[ADD_CLAUSES, pow] THEN
18901    REWRITE_TAC[REAL_ARITH ``a * b * (d - c * d) = (&1 - c) * a * d * b:real``] THEN
18902    REWRITE_TAC [GSYM REAL_MUL_ASSOC] THEN MATCH_MP_TAC REAL_LE_LMUL_IMP THEN
18903    ASM_SIMP_TAC std_ss [REAL_SUB_LE, REAL_LT_IMP_LE] THEN
18904    REWRITE_TAC[GSYM REAL_POW_ADD, REAL_MUL_ASSOC] THEN ASM_MESON_TAC[],
18905    ALL_TAC] THEN
18906  X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
18907  ASM_CASES_TAC ``(z:num->real) 0 = z 1`` THENL
18908   [FIRST_X_ASSUM SUBST_ALL_TAC THEN EXISTS_TAC ``0:num`` THEN
18909    REWRITE_TAC[GE, ZERO_LESS_EQ] THEN X_GEN_TAC ``n:num`` THEN
18910    FIRST_X_ASSUM(MP_TAC o SPECL [``0:num``, ``n:num``]) THEN
18911    REWRITE_TAC[ADD_CLAUSES, DIST_REFL, REAL_MUL_LZERO, REAL_MUL_RZERO] THEN
18912    ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN
18913    ASM_CASES_TAC ``(z:num->real) 0 = z n`` THEN
18914    ASM_REWRITE_TAC[DIST_REFL, REAL_NOT_LE] THEN
18915    ASM_SIMP_TAC std_ss [REAL_LT_MUL, DIST_POS_LT, REAL_SUB_LT],
18916    ALL_TAC] THEN
18917  MP_TAC(SPECL [``c:real``, ``e * (&1 - c) / dist((z:num->real) 0,z 1)``]
18918   REAL_ARCH_POW_INV) THEN
18919  ASM_SIMP_TAC std_ss [REAL_LT_MUL, REAL_LT_DIV, REAL_SUB_LT, DIST_POS_LT] THEN
18920  DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN
18921  POP_ASSUM MP_TAC THEN REWRITE_TAC[real_div, GE, REAL_MUL_ASSOC] THEN
18922  ASM_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, GSYM real_div, DIST_POS_LT] THEN
18923  ASM_SIMP_TAC std_ss [GSYM REAL_LT_LDIV_EQ, REAL_SUB_LT] THEN DISCH_TAC THEN
18924  SIMP_TAC std_ss [LESS_EQ_EXISTS, LEFT_IMP_EXISTS_THM] THEN
18925  X_GEN_TAC ``d:num`` THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
18926  FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(REAL_ARITH
18927    ``d < e ==> x <= d ==> x < e:real``)) THEN
18928  ASM_SIMP_TAC std_ss [REAL_LE_RDIV_EQ, REAL_SUB_LT] THEN
18929  FIRST_X_ASSUM(MP_TAC o SPECL [``N:num``, ``d:num``]) THEN
18930  MATCH_MP_TAC(REAL_ARITH
18931  ``(c * d) * e <= (c * d) * &1 ==> x * y <= c * d * e ==> y * x <= c * d:real``) THEN
18932  MATCH_MP_TAC REAL_LE_LMUL_IMP THEN
18933  ASM_SIMP_TAC std_ss [REAL_LE_MUL, POW_POS, DIST_POS_LE, REAL_ARITH
18934   ``&0 <= x ==> &1 - x <= &1:real``]);
18935
18936(* ------------------------------------------------------------------------- *)
18937(* Dini's theorem.                                                           *)
18938(* ------------------------------------------------------------------------- *)
18939
18940val DINI = store_thm ("DINI",
18941 ``!f:num->real->real g s.
18942        compact s /\ (!n. (f n) continuous_on s) /\ g continuous_on s /\
18943        (!x. x IN s ==> ((\n. (f n x)) --> g x) sequentially) /\
18944        (!n x. x IN s ==> (f n x) <= (f (n + 1) x))
18945        ==> !e. &0 < e
18946                ==> eventually (\n. !x. x IN s ==> abs(f n x - g x) < e)
18947                               sequentially``,
18948  REPEAT STRIP_TAC THEN
18949  SUBGOAL_THEN
18950   ``!x:real m n:num. x IN s /\ m <= n ==> (f m x):real <= (f n x)``
18951  ASSUME_TAC THENL
18952   [GEN_TAC THEN ASM_CASES_TAC ``(x:real) IN s`` THEN ASM_REWRITE_TAC[] THEN
18953    ONCE_REWRITE_TAC [METIS [] ``!m n. (f:num->real->real) m x <= f n x <=>
18954                                       (\m n. f m x <= f n x) m n``] THEN
18955    MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_SIMP_TAC std_ss [ADD1] THEN
18956    REAL_ARITH_TAC, ALL_TAC] THEN
18957  SUBGOAL_THEN ``!n:num x:real. x IN s ==> (f n x):real <= (g x)``
18958  ASSUME_TAC THENL
18959   [REPEAT STRIP_TAC THEN
18960    MATCH_MP_TAC(ISPEC ``sequentially`` LIM_DROP_LE) THEN
18961    EXISTS_TAC ``\m:num. (f:num->real->real) n x`` THEN
18962    EXISTS_TAC ``\m:num. (f:num->real->real) m x`` THEN
18963    ASM_SIMP_TAC std_ss [LIM_CONST, TRIVIAL_LIMIT_SEQUENTIALLY] THEN
18964    REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN ASM_MESON_TAC[],
18965    ALL_TAC] THEN
18966  RULE_ASSUM_TAC(REWRITE_RULE[LIM_SEQUENTIALLY, dist]) THEN
18967  UNDISCH_TAC ``compact s`` THEN DISCH_TAC THEN
18968  FIRST_ASSUM(MP_TAC o REWRITE_RULE
18969   [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN
18970  DISCH_THEN(MP_TAC o SPEC
18971   ``IMAGE (\n. { x | x IN s /\ abs((f:num->real->real) n x - g x) < e})
18972          univ(:num)``) THEN
18973  SIMP_TAC std_ss [FORALL_IN_IMAGE, IN_UNIV] THEN
18974  ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
18975  SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE, SUBSET_UNION, BIGUNION_IMAGE] THEN
18976  SIMP_TAC std_ss [IN_UNIV, GSPECIFICATION, EVENTUALLY_SEQUENTIALLY] THEN
18977  SIMP_TAC std_ss [SUBSET_DEF, IN_UNIV, GSPECIFICATION] THEN
18978  KNOW_TAC ``(!(n :num).
18979    open_in (subtopology euclidean (s :real -> bool))
18980      {x |
18981       x IN s /\
18982       abs ((f :num -> real -> real) n x - (g :real -> real) x) <
18983       (e :real)}) /\
18984 (!(x :real). x IN s ==> ?(n :num). abs (f n x - g x) < e)`` THENL
18985   [CONJ_TAC THENL [ALL_TAC, ASM_MESON_TAC[LESS_EQ_REFL]] THEN
18986    X_GEN_TAC ``n:num`` THEN REWRITE_TAC[GSYM IN_BALL_0] THEN
18987    ONCE_REWRITE_TAC [METIS [] ``f n x - g x =
18988          (\x. (f:num->real->real) n x - g x) x``] THEN
18989    MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE THEN
18990    METIS_TAC [OPEN_BALL, CONTINUOUS_ON_SUB, ETA_AX],
18991    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
18992    DISCH_THEN(X_CHOOSE_THEN ``k:num->bool`` (CONJUNCTS_THEN2
18993     (MP_TAC o SPEC ``\n:num. n`` o MATCH_MP UPPER_BOUND_FINITE_SET)
18994     ASSUME_TAC)) THEN
18995    DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN EXISTS_TAC ``N:num`` THEN
18996    POP_ASSUM MP_TAC THEN
18997    SIMP_TAC std_ss [] THEN STRIP_TAC THEN X_GEN_TAC ``n:num`` THEN
18998    DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
18999    UNDISCH_TAC ``!x. x IN s ==> ?n. n IN k /\
19000                  abs ((f:num->real->real) n x - g x) < e`` THEN
19001    DISCH_TAC THEN
19002    FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
19003    DISCH_THEN(X_CHOOSE_THEN ``m:num`` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
19004    MATCH_MP_TAC(REAL_ARITH
19005     ``m <= n /\ n <= g ==> abs(m - g) < e ==> abs(n - g) < e:real``) THEN
19006    METIS_TAC[LESS_EQ_TRANS]]);
19007
19008(* ------------------------------------------------------------------------- *)
19009(* Closest point of a (closed) set to a point.                               *)
19010(* ------------------------------------------------------------------------- *)
19011
19012val closest_point = new_definition ("closest_point",
19013 ``closest_point s a = @x. x IN s /\ !y. y IN s ==> dist(a,x) <= dist(a,y)``);
19014
19015val CLOSEST_POINT_EXISTS = store_thm ("CLOSEST_POINT_EXISTS",
19016 ``!s a. closed s /\ ~(s = {})
19017         ==> (closest_point s a) IN s /\
19018             !y. y IN s ==> dist(a,closest_point s a) <= dist(a,y)``,
19019  REWRITE_TAC[closest_point] THEN CONV_TAC(ONCE_DEPTH_CONV SELECT_CONV) THEN
19020  REWRITE_TAC[DISTANCE_ATTAINS_INF]);
19021
19022val CLOSEST_POINT_IN_SET = store_thm ("CLOSEST_POINT_IN_SET",
19023 ``!s a. closed s /\ ~(s = {}) ==> (closest_point s a) IN s``,
19024  MESON_TAC[CLOSEST_POINT_EXISTS]);
19025
19026val CLOSEST_POINT_LE = store_thm ("CLOSEST_POINT_LE",
19027 ``!s a x. closed s /\ x IN s ==> dist(a,closest_point s a) <= dist(a,x)``,
19028  MESON_TAC[CLOSEST_POINT_EXISTS, MEMBER_NOT_EMPTY]);
19029
19030val CLOSEST_POINT_SELF = store_thm ("CLOSEST_POINT_SELF",
19031 ``!s x:real. x IN s ==> (closest_point s x = x)``,
19032  REPEAT STRIP_TAC THEN REWRITE_TAC[closest_point] THEN
19033  MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN GEN_TAC THEN EQ_TAC THENL
19034   [BETA_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN
19035    ASM_SIMP_TAC std_ss [DIST_LE_0, DIST_REFL],
19036    BETA_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[DIST_REFL, DIST_POS_LE]]);
19037
19038val CLOSEST_POINT_REFL = store_thm ("CLOSEST_POINT_REFL",
19039 ``!s x:real. closed s /\ ~(s = {}) ==> ((closest_point s x = x) <=> x IN s)``,
19040  MESON_TAC[CLOSEST_POINT_IN_SET, CLOSEST_POINT_SELF]);
19041
19042val DIST_CLOSEST_POINT_LIPSCHITZ = store_thm ("DIST_CLOSEST_POINT_LIPSCHITZ",
19043 ``!s x y:real.
19044        closed s /\ ~(s = {})
19045        ==> abs(dist(x,closest_point s x) - dist(y,closest_point s y))
19046            <= dist(x,y)``,
19047  REPEAT GEN_TAC THEN DISCH_TAC THEN
19048  FIRST_ASSUM(MP_TAC o MATCH_MP CLOSEST_POINT_EXISTS) THEN
19049  DISCH_THEN(fn th =>
19050    CONJUNCTS_THEN2 ASSUME_TAC
19051     (MP_TAC o SPEC ``closest_point s (y:real)``) (SPEC ``x:real`` th) THEN
19052    CONJUNCTS_THEN2 ASSUME_TAC
19053     (MP_TAC o SPEC ``closest_point s (x:real)``) (SPEC ``y:real`` th)) THEN
19054  ASM_SIMP_TAC std_ss [dist] THEN REAL_ARITH_TAC);
19055
19056val CONTINUOUS_AT_DIST_CLOSEST_POINT = store_thm ("CONTINUOUS_AT_DIST_CLOSEST_POINT",
19057 ``!s x:real.
19058        closed s /\ ~(s = {})
19059        ==> (\x. (dist(x,closest_point s x))) continuous (at x)``,
19060  REPEAT STRIP_TAC THEN SIMP_TAC std_ss [continuous_at] THEN REWRITE_TAC [dist] THEN
19061  METIS_TAC[REWRITE_RULE [dist] DIST_CLOSEST_POINT_LIPSCHITZ, REAL_LET_TRANS]);
19062
19063val CONTINUOUS_ON_DIST_CLOSEST_POINT = store_thm ("CONTINUOUS_ON_DIST_CLOSEST_POINT",
19064 ``!s t. closed s /\ ~(s = {})
19065         ==> (\x. (dist(x,closest_point s x))) continuous_on t``,
19066  METIS_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON,
19067            CONTINUOUS_AT_DIST_CLOSEST_POINT]);
19068
19069val UNIFORMLY_CONTINUOUS_ON_DIST_CLOSEST_POINT = store_thm ("UNIFORMLY_CONTINUOUS_ON_DIST_CLOSEST_POINT",
19070 ``!s t:real->bool.
19071        closed s /\ ~(s = {})
19072        ==> (\x. (dist(x,closest_point s x))) uniformly_continuous_on t``,
19073  REPEAT STRIP_TAC THEN REWRITE_TAC[uniformly_continuous_on] THEN
19074  REWRITE_TAC [dist] THEN
19075  METIS_TAC[REWRITE_RULE [dist] DIST_CLOSEST_POINT_LIPSCHITZ, REAL_LET_TRANS]);
19076
19077val SEGMENT_TO_CLOSEST_POINT = store_thm ("SEGMENT_TO_CLOSEST_POINT",
19078 ``!s a:real.
19079        closed s /\ ~(s = {})
19080        ==> (segment(a,closest_point s a) INTER s = {})``,
19081  REPEAT STRIP_TAC THEN
19082  REWRITE_TAC[SET_RULE ``(s INTER t = {}) <=> !x. x IN s ==> ~(x IN t)``] THEN
19083  GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP DIST_IN_OPEN_SEGMENT) THEN
19084  MATCH_MP_TAC(TAUT `(r ==> ~p) ==> p /\ q ==> ~r`) THEN
19085  METIS_TAC [CLOSEST_POINT_EXISTS, REAL_NOT_LT, DIST_SYM]);
19086
19087val SEGMENT_TO_POINT_EXISTS = store_thm ("SEGMENT_TO_POINT_EXISTS",
19088 ``!s a:real.
19089        closed s /\ ~(s = {}) ==> ?b. b IN s /\ (segment(a,b) INTER s = {})``,
19090  MESON_TAC[SEGMENT_TO_CLOSEST_POINT, CLOSEST_POINT_EXISTS]);
19091
19092val CLOSEST_POINT_IN_INTERIOR = store_thm
19093  ("CLOSEST_POINT_IN_INTERIOR",
19094 ``!s x:real.
19095        closed s /\ ~(s = {})
19096        ==> ((closest_point s x) IN interior s <=> x IN interior s)``,
19097  REPEAT STRIP_TAC THEN ASM_CASES_TAC ``(x:real) IN s`` THEN
19098  ASM_SIMP_TAC std_ss [CLOSEST_POINT_SELF] THEN
19099  MATCH_MP_TAC(TAUT `~q /\ ~p ==> (p <=> q)`) THEN
19100  CONJ_TAC THENL [METIS_TAC[INTERIOR_SUBSET, SUBSET_DEF], STRIP_TAC] THEN
19101  FIRST_ASSUM(MP_TAC o REWRITE_RULE [IN_INTERIOR_CBALL]) THEN
19102  DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
19103  SUBGOAL_THEN ``closest_point s (x:real) IN s`` ASSUME_TAC THENL
19104   [METIS_TAC[INTERIOR_SUBSET, SUBSET_DEF], ALL_TAC] THEN
19105  SUBGOAL_THEN ``~(closest_point s (x:real) = x)`` ASSUME_TAC THENL
19106   [ASM_MESON_TAC[], ALL_TAC] THEN
19107  MP_TAC(ISPECL [``s:real->bool``, ``x:real``,
19108  ``closest_point s x -
19109    (min (&1) (e / abs(closest_point s x - x))) *
19110    (closest_point s x - x):real``]
19111    CLOSEST_POINT_LE) THEN
19112  ASM_REWRITE_TAC[dist, NOT_IMP, REAL_ARITH
19113   ``x - (y - e * (y - x)):real = (&1 - e) * (x - y:real)``] THEN
19114  CONJ_TAC THENL
19115  [ (* goal 1 (of 2) *)
19116    UNDISCH_TAC ``cball (closest_point s x,e) SUBSET s`` THEN DISCH_TAC THEN
19117    FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN
19118    REWRITE_TAC[dist, IN_CBALL, REAL_ARITH ``abs(a:real - a - x) = abs x``] THEN
19119    SIMP_TAC real_ss [ABS_MUL, ABS_DIV, ABS_ABS] THEN
19120    RULE_ASSUM_TAC (ONCE_REWRITE_RULE [GSYM REAL_SUB_0]) THEN
19121    RULE_ASSUM_TAC (ONCE_REWRITE_RULE [ABS_NZ]) THEN
19122
19123    ASM_SIMP_TAC std_ss [GSYM REAL_LE_RDIV_EQ, min_def] THEN
19124    KNOW_TAC ``!a:real. &0 <= a ==> abs (if 1 <= a then 1 else a) <= a``
19125    >- ( RW_TAC real_ss [] >> PROVE_TAC [abs, REAL_LE_REFL] ) THEN
19126    DISCH_THEN MATCH_MP_TAC THEN
19127    ASM_SIMP_TAC std_ss [REAL_LT_IMP_LE, REAL_LE_DIV, ABS_POS],
19128    (* goal 2 (of 2) *)
19129    REWRITE_TAC[ABS_MUL, REAL_ARITH
19130     ``~(n <= a * n) <=> &0 < (&1 - a) * n:real``] THEN
19131    MATCH_MP_TAC REAL_LT_MUL THEN
19132    RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH ``(a <> b) <=> (b - a <> 0:real)``]) THEN
19133    RULE_ASSUM_TAC (ONCE_REWRITE_RULE [ABS_NZ]) THEN ASM_SIMP_TAC std_ss [] THEN
19134    KNOW_TAC ``!e:real. &0 < e /\ e <= &1 ==> &0 < &1 - abs(&1 - e)``
19135    >- ( RW_TAC real_ss [] \\
19136         `0 <= 1 - e'` by ASM_REAL_ARITH_TAC \\
19137         ASM_SIMP_TAC real_ss [abs] ) THEN
19138    DISCH_THEN MATCH_MP_TAC THEN
19139    REWRITE_TAC[REAL_MIN_LE, REAL_LT_MIN, REAL_LT_01, REAL_LE_REFL] THEN
19140    METIS_TAC [REAL_LT_DIV, ABS_SUB] ]);
19141
19142val CLOSEST_POINT_IN_FRONTIER = store_thm ("CLOSEST_POINT_IN_FRONTIER",
19143 ``!s x:real.
19144        closed s /\ ~(s = {}) /\ ~(x IN interior s)
19145        ==> (closest_point s x) IN frontier s``,
19146  SIMP_TAC std_ss [frontier, IN_DIFF, CLOSEST_POINT_IN_INTERIOR] THEN
19147  SIMP_TAC std_ss [CLOSEST_POINT_IN_SET, CLOSURE_CLOSED]);
19148
19149(* ------------------------------------------------------------------------- *)
19150(* More general infimum of distance between two sets.                        *)
19151(* ------------------------------------------------------------------------- *)
19152
19153val setdist = new_definition ("setdist",
19154 ``setdist(s,t) =
19155        if (s = {}) \/ (t = {}) then &0
19156        else inf {dist(x,y) | x IN s /\ y IN t}``);
19157
19158val SETDIST_EMPTY = store_thm ("SETDIST_EMPTY",
19159 ``(!t. setdist({},t) = &0) /\ (!s. setdist(s,{}) = &0)``,
19160  REWRITE_TAC[setdist]);
19161
19162val SETDIST_POS_LE = store_thm ("SETDIST_POS_LE",
19163 ``!s t. &0 <= setdist(s,t)``,
19164  REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN
19165  COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN
19166  MATCH_MP_TAC REAL_LE_INF THEN
19167  SIMP_TAC std_ss [FORALL_IN_GSPEC, DIST_POS_LE] THEN
19168  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC[]);
19169
19170val SETDIST_SUBSETS_EQ = store_thm ("SETDIST_SUBSETS_EQ",
19171 ``!s t s' t':real->bool.
19172     s' SUBSET s /\ t' SUBSET t /\
19173     (!x y. x IN s /\ y IN t
19174            ==> ?x' y'. x' IN s' /\ y' IN t' /\ dist(x',y') <= dist(x,y))
19175     ==> (setdist(s',t') = setdist(s,t))``,
19176  REPEAT STRIP_TAC THEN
19177  ASM_CASES_TAC ``s:real->bool = {}`` THENL
19178   [ASM_CASES_TAC ``s':real->bool = {}`` THEN
19179    ASM_REWRITE_TAC[SETDIST_EMPTY] THEN ASM_SET_TAC[],
19180    ALL_TAC] THEN
19181  ASM_CASES_TAC ``t:real->bool = {}`` THENL
19182   [ASM_CASES_TAC ``t':real->bool = {}`` THEN
19183    ASM_REWRITE_TAC[SETDIST_EMPTY] THEN ASM_SET_TAC[],
19184    ALL_TAC] THEN
19185  ASM_CASES_TAC ``s':real->bool = {}`` THENL [ASM_SET_TAC[], ALL_TAC] THEN
19186  ASM_CASES_TAC ``t':real->bool = {}`` THENL [ASM_SET_TAC[], ALL_TAC] THEN
19187  ASM_REWRITE_TAC[setdist] THEN MATCH_MP_TAC INF_EQ THEN
19188  SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN
19189  CONJ_TAC >- (SIMP_TAC std_ss [EXTENSION, GSPECIFICATION,
19190                                EXISTS_PROD, NOT_IN_EMPTY] \\
19191               fs [GSYM MEMBER_NOT_EMPTY] \\
19192               rename1 `a IN s'` >> Q.EXISTS_TAC `a` \\
19193               rename1 `b IN t'` >> Q.EXISTS_TAC `b` \\
19194               ASM_REWRITE_TAC []) \\
19195  CONJ_TAC >- (Q.EXISTS_TAC `0` >> rw [DIST_POS_LE]) \\
19196  CONJ_TAC >- (SIMP_TAC std_ss [EXTENSION, GSPECIFICATION,
19197                                EXISTS_PROD, NOT_IN_EMPTY] \\
19198               fs [GSYM MEMBER_NOT_EMPTY] \\
19199               rename1 `a IN s` >> Q.EXISTS_TAC `a` \\
19200               rename1 `b IN t` >> Q.EXISTS_TAC `b` \\
19201               ASM_REWRITE_TAC []) \\
19202  CONJ_TAC >- (Q.EXISTS_TAC `0` >> rw [DIST_POS_LE]) \\
19203  ASM_MESON_TAC[SUBSET_DEF, REAL_LE_TRANS]);
19204
19205val REAL_LE_SETDIST = store_thm ("REAL_LE_SETDIST",
19206  ``!s t:real->bool d.
19207        ~(s = {}) /\ ~(t = {}) /\
19208        (!x y. x IN s /\ y IN t ==> d <= dist(x,y))
19209        ==> d <= setdist(s,t)``,
19210  REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[setdist] THEN
19211  MP_TAC(ISPEC ``{dist(x:real,y) | x IN s /\ y IN t}`` INF) THEN
19212  SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN
19213  KNOW_TAC ``{dist (x,y) | x IN s /\ y IN t} <> {} /\
19214             (?b. !x y. x IN s /\ y IN t ==> b <= dist (x,y))`` THENL
19215   [CONJ_TAC THENL
19216    [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN
19217     ASM_SET_TAC[], MESON_TAC[DIST_POS_LE]],
19218     DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
19219  ASM_MESON_TAC[]);
19220
19221val SETDIST_LE_DIST = store_thm ("SETDIST_LE_DIST",
19222 ``!s t x y:real. x IN s /\ y IN t ==> setdist(s,t) <= dist(x,y)``,
19223  REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN
19224  COND_CASES_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
19225  MP_TAC(ISPEC ``{dist(x:real,y) | x IN s /\ y IN t}`` INF) THEN
19226  SIMP_TAC std_ss [FORALL_IN_GSPEC] THEN
19227  KNOW_TAC ``{dist (x,y) | x IN s /\ y IN t} <> {} /\
19228             (?b. !x y. x IN s /\ y IN t ==> b <= dist (x,y))`` THENL
19229   [CONJ_TAC THENL
19230    [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN
19231     ASM_SET_TAC[], MESON_TAC[DIST_POS_LE]],
19232     DISCH_TAC THEN ASM_REWRITE_TAC []] THEN
19233  ASM_MESON_TAC[]);
19234
19235val REAL_LE_SETDIST_EQ = store_thm ("REAL_LE_SETDIST_EQ",
19236 ``!d s t:real->bool.
19237        d <= setdist(s,t) <=>
19238        (!x y. x IN s /\ y IN t ==> d <= dist(x,y)) /\
19239        ((s = {}) \/ (t = {}) ==> d <= &0)``,
19240  REPEAT GEN_TAC THEN MAP_EVERY ASM_CASES_TAC
19241   [``s:real->bool = {}``, ``t:real->bool = {}``] THEN
19242  ASM_REWRITE_TAC[SETDIST_EMPTY, NOT_IN_EMPTY] THEN
19243  ASM_MESON_TAC[REAL_LE_SETDIST, SETDIST_LE_DIST, REAL_LE_TRANS]);
19244
19245val REAL_SETDIST_LT_EXISTS = store_thm ("REAL_SETDIST_LT_EXISTS",
19246 ``!s t:real->bool b.
19247        ~(s = {}) /\ ~(t = {}) /\ setdist(s,t) < b
19248        ==> ?x y. x IN s /\ y IN t /\ dist(x,y) < b``,
19249  REWRITE_TAC[GSYM REAL_NOT_LE, REAL_LE_SETDIST_EQ] THEN MESON_TAC[]);
19250
19251val SETDIST_REFL = store_thm ("SETDIST_REFL",
19252 ``!s:real->bool. setdist(s,s) = &0``,
19253  GEN_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM, SETDIST_POS_LE] THEN
19254  ASM_CASES_TAC ``s:real->bool = {}`` THENL
19255   [ASM_REWRITE_TAC[setdist, REAL_LE_REFL], ALL_TAC] THEN
19256  ASM_MESON_TAC[SETDIST_LE_DIST, MEMBER_NOT_EMPTY, DIST_REFL]);
19257
19258val SETDIST_SYM = store_thm ("SETDIST_SYM",
19259 ``!s t. setdist(s,t) = setdist(t,s)``,
19260  REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN ONCE_REWRITE_TAC [DISJ_SYM] THEN
19261  COND_CASES_TAC THEN ONCE_REWRITE_TAC [DISJ_SYM] THEN ASM_SIMP_TAC std_ss [] THEN
19262  AP_TERM_TAC THEN SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN
19263  METIS_TAC[DIST_SYM]);
19264
19265val SETDIST_TRIANGLE = store_thm ("SETDIST_TRIANGLE",
19266 ``!s a t:real->bool.
19267        setdist(s,t) <= setdist(s,{a}) + setdist({a},t)``,
19268  REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN
19269  ASM_REWRITE_TAC[SETDIST_EMPTY, REAL_ADD_LID, SETDIST_POS_LE] THEN
19270  ASM_CASES_TAC ``t:real->bool = {}`` THEN
19271  ASM_REWRITE_TAC[SETDIST_EMPTY, REAL_ADD_RID, SETDIST_POS_LE] THEN
19272  ONCE_REWRITE_TAC[GSYM REAL_LE_SUB_RADD] THEN
19273  MATCH_MP_TAC REAL_LE_SETDIST THEN
19274  ASM_SIMP_TAC std_ss [NOT_INSERT_EMPTY, IN_SING, CONJ_EQ_IMP,
19275                  RIGHT_FORALL_IMP_THM, UNWIND_FORALL_THM2] THEN
19276  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
19277  ONCE_REWRITE_TAC[REAL_ARITH ``x - y <= z <=> x - z <= y:real``] THEN
19278  MATCH_MP_TAC REAL_LE_SETDIST THEN
19279  ASM_REWRITE_TAC[NOT_INSERT_EMPTY, IN_SING, CONJ_EQ_IMP,
19280                  RIGHT_FORALL_IMP_THM, UNWIND_FORALL_THM2] THEN
19281  X_GEN_TAC ``y:real`` THEN REPEAT STRIP_TAC THEN
19282  REWRITE_TAC[REAL_LE_SUB_RADD] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
19283  EXISTS_TAC ``dist(x:real,y')`` THEN
19284  ASM_SIMP_TAC std_ss [SETDIST_LE_DIST, dist] THEN REAL_ARITH_TAC);
19285
19286val SETDIST_SINGS = store_thm ("SETDIST_SINGS",
19287 ``!x y. setdist({x},{y}) = dist(x,y)``,
19288  REWRITE_TAC[setdist, NOT_INSERT_EMPTY] THEN
19289  ONCE_REWRITE_TAC [METIS [] ``dist (x,y) = (\x y. dist (x,y)) x y``] THEN
19290  KNOW_TAC ``!f:real->real->real x y a b. {f x y | x IN {a} /\ y IN {b}} = {f a b}`` THENL
19291  [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN SET_TAC [],
19292   DISCH_TAC] THEN ASM_REWRITE_TAC [] THEN
19293  SIMP_TAC std_ss [INF_INSERT_FINITE, FINITE_EMPTY]);
19294
19295val SETDIST_LIPSCHITZ = store_thm ("SETDIST_LIPSCHITZ",
19296 ``!s t x y:real. abs(setdist({x},s) - setdist({y},s)) <= dist(x,y)``,
19297  REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM SETDIST_SINGS] THEN
19298  REWRITE_TAC[REAL_ARITH
19299   ``abs(x - y) <= z <=> x <= z + y /\ y <= z + x:real``] THEN
19300  MESON_TAC[SETDIST_TRIANGLE, SETDIST_SYM]);
19301
19302val CONTINUOUS_AT_SETDIST = store_thm ("CONTINUOUS_AT_SETDIST",
19303 ``!s x:real. (\y. setdist({y},s)) continuous (at x)``,
19304  REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_at] THEN
19305  SIMP_TAC std_ss [dist] THEN
19306  METIS_TAC[REWRITE_RULE [dist] SETDIST_LIPSCHITZ, REAL_LET_TRANS]);
19307
19308val CONTINUOUS_ON_SETDIST = store_thm ("CONTINUOUS_ON_SETDIST",
19309 ``!s t:real->bool. (\y. setdist({y},s)) continuous_on t``,
19310  METIS_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON,
19311            CONTINUOUS_AT_SETDIST]);
19312
19313val UNIFORMLY_CONTINUOUS_ON_SETDIST = store_thm ("UNIFORMLY_CONTINUOUS_ON_SETDIST",
19314 ``!s t:real->bool.
19315         (\y. setdist({y},s)) uniformly_continuous_on t``,
19316  REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on] THEN
19317  BETA_TAC THEN METIS_TAC[dist, SETDIST_LIPSCHITZ, REAL_LET_TRANS]);
19318
19319val SETDIST_DIFFERENCES = store_thm ("SETDIST_DIFFERENCES",
19320 ``!s t. setdist(s,t) = setdist({0},{x - y:real | x IN s /\ y IN t})``,
19321  REPEAT GEN_TAC THEN
19322  KNOW_TAC ``!f:real->real->real x y s t.
19323   ({f x y | x IN s /\ y IN t} = {}) <=> (s = {}) \/ (t = {})`` THENL
19324  [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN SET_TAC [],
19325   DISCH_TAC] THEN
19326  ONCE_REWRITE_TAC [METIS [] ``x - y = (\x y. x - y) x y:real``] THEN
19327  ASM_REWRITE_TAC[setdist, NOT_INSERT_EMPTY] THEN
19328  COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [] THEN AP_TERM_TAC THEN
19329  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, IN_SING, EXISTS_PROD] THEN
19330  SIMP_TAC std_ss [GSYM CONJ_ASSOC, RIGHT_EXISTS_AND_THM, UNWIND_THM2, DIST_0] THEN
19331  REWRITE_TAC[dist] THEN MESON_TAC[]);
19332
19333val SETDIST_SUBSET_RIGHT = store_thm ("SETDIST_SUBSET_RIGHT",
19334 ``!s t u:real->bool.
19335    ~(t = {}) /\ t SUBSET u ==> setdist(s,u) <= setdist(s,t)``,
19336  REPEAT STRIP_TAC THEN
19337  MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``u:real->bool = {}``] THEN
19338  ASM_SIMP_TAC std_ss [SETDIST_EMPTY, SETDIST_POS_LE, REAL_LE_REFL] THEN
19339  ASM_REWRITE_TAC[setdist] THEN MATCH_MP_TAC REAL_LE_INF_SUBSET THEN
19340  ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, SUBSET_DEF, EXISTS_PROD, GSPECIFICATION] THEN
19341  REPEAT(CONJ_TAC THENL
19342  [ASM_SIMP_TAC std_ss [EXTENSION, EXISTS_PROD, GSPECIFICATION] THEN ASM_SET_TAC[],
19343   ALL_TAC]) THEN METIS_TAC[DIST_POS_LE]);
19344
19345val SETDIST_SUBSET_LEFT = store_thm ("SETDIST_SUBSET_LEFT",
19346 ``!s t u:real->bool.
19347    ~(s = {}) /\ s SUBSET t ==> setdist(t,u) <= setdist(s,u)``,
19348  MESON_TAC[SETDIST_SUBSET_RIGHT, SETDIST_SYM]);
19349
19350val SETDIST_CLOSURE = store_thm ("SETDIST_CLOSURE",
19351 ``(!s t:real->bool. setdist(closure s,t) = setdist(s,t)) /\
19352   (!s t:real->bool. setdist(s,closure t) = setdist(s,t))``,
19353  REWRITE_TAC [METIS [SWAP_FORALL_THM]
19354   ``(!s t. setdist (s,closure t) = setdist (s,t)) =
19355     (!t s. setdist (s,closure t) = setdist (s,t))``] THEN
19356  GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SETDIST_SYM] THEN
19357  SIMP_TAC std_ss [] THEN
19358  REWRITE_TAC[MESON[REAL_LE_ANTISYM]
19359   ``(x:real = y) <=> !d. d <= x <=> d <= y``] THEN
19360  REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN
19361  MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``t:real->bool = {}``] THEN
19362  ASM_REWRITE_TAC[CLOSURE_EQ_EMPTY, CLOSURE_EMPTY, NOT_IN_EMPTY] THEN
19363  ONCE_REWRITE_TAC [METIS [] ``d <= dist (x,y) <=> (\x y. d <= dist (x,y)) x y``] THEN
19364  ONCE_REWRITE_TAC [METIS [] ``x IN s /\ y IN t <=> x IN s /\ (\y. y IN t) y``] THEN
19365  MATCH_MP_TAC(SET_RULE
19366   ``s SUBSET c /\
19367    (!y. Q y /\ (!x. x IN s ==> P x y) ==> (!x. x IN c ==> P x y))
19368   ==> ((!x y. x IN c /\ Q y ==> P x y) <=>
19369        (!x y. x IN s /\ Q y ==> P x y))``) THEN
19370  SIMP_TAC std_ss [CLOSURE_SUBSET] THEN GEN_TAC THEN STRIP_TAC THEN
19371  ONCE_REWRITE_TAC [METIS [] ``dist (x,y) = (\x. dist (x, y)) x``] THEN
19372  MATCH_MP_TAC CONTINUOUS_GE_ON_CLOSURE THEN ASM_SIMP_TAC std_ss [] THEN
19373  ASM_SIMP_TAC std_ss [o_DEF, dist] THEN
19374  ONCE_REWRITE_TAC [METIS [] ``abs (x - y) = abs ((\x. x - y) x:real)``] THEN
19375  MATCH_MP_TAC CONTINUOUS_ON_ABS_COMPOSE THEN
19376  SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID]);
19377
19378val SETDIST_FRONTIER = store_thm ("SETDIST_FRONTIER",
19379 ``(!s t:real->bool.
19380        DISJOINT s t ==> (setdist(frontier s,t) = setdist(s,t))) /\
19381   (!s t:real->bool.
19382        DISJOINT s t ==> (setdist(s,frontier t) = setdist(s,t)))``,
19383  MATCH_MP_TAC(TAUT `(p ==> q) /\ p ==> p /\ q`) THEN
19384  CONJ_TAC THENL [MESON_TAC[SETDIST_SYM, DISJOINT_SYM], ALL_TAC] THEN
19385  REPEAT STRIP_TAC THEN
19386  GEN_REWR_TAC RAND_CONV [GSYM(CONJUNCT1 SETDIST_CLOSURE)] THEN
19387  MATCH_MP_TAC SETDIST_SUBSETS_EQ THEN
19388  SIMP_TAC std_ss [frontier, IN_DIFF, DIFF_SUBSET, SUBSET_REFL] THEN
19389  MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN
19390  ASM_CASES_TAC  ``(x:real) IN interior s`` THENL
19391   [ALL_TAC, ASM_MESON_TAC[REAL_LE_REFL]] THEN
19392  KNOW_TAC ``?y' x'. (x' IN closure s /\ x' NOTIN interior s) /\
19393                      y' IN t /\ dist (x',y') <= dist (x,y)`` THENL
19394  [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN
19395  EXISTS_TAC ``y:real`` THEN ASM_REWRITE_TAC[] THEN
19396  MP_TAC(ISPECL [``segment[x:real,y]``, ``s:real->bool``]
19397        CONNECTED_INTER_FRONTIER) THEN
19398  REWRITE_TAC[CONNECTED_SEGMENT, GSYM MEMBER_NOT_EMPTY] THEN
19399  KNOW_TAC ``(?x'. x' IN segment [(x,y)] INTER s) /\
19400             (?x'. x' IN segment [(x,y)] DIFF s)`` THENL
19401   [CONJ_TAC THENL [EXISTS_TAC ``x:real``, EXISTS_TAC ``y:real``] THEN
19402    ASM_SIMP_TAC std_ss [IN_INTER, IN_DIFF, ENDS_IN_SEGMENT] THEN
19403    MP_TAC(ISPEC ``s:real->bool`` INTERIOR_SUBSET) THEN ASM_SET_TAC[],
19404    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
19405    DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN
19406    POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [IN_INTER, frontier, IN_DIFF] THEN
19407    MESON_TAC[DIST_IN_CLOSED_SEGMENT]]);
19408
19409val SETDIST_COMPACT_CLOSED = store_thm ("SETDIST_COMPACT_CLOSED",
19410 ``!s t:real->bool.
19411        compact s /\ closed t /\ ~(s = {}) /\ ~(t = {})
19412        ==> ?x y. x IN s /\ y IN t /\ (dist(x,y) = setdist(s,t))``,
19413  REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
19414  KNOW_TAC ``?x y. (\x. x IN s) x /\ (\y. y IN t) y /\
19415                   (\x y. dist (x,y) <= setdist (s,t)) x y /\
19416                   (\x y. setdist (s,t) <= dist (x,y)) x y`` THENL
19417  [ALL_TAC, METIS_TAC []] THEN
19418  MATCH_MP_TAC(METIS []
19419   ``(!x y. P x /\ Q y ==> R' x y) /\ (?x y. (P x /\ Q y /\ R x y))
19420    ==> (?x y. P x /\ Q y /\ R x y /\ R' x y)``) THEN
19421  SIMP_TAC std_ss [SETDIST_LE_DIST] THEN
19422  ASM_REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN
19423  MP_TAC(ISPECL [``{x - y:real | x IN s /\ y IN t}``, ``0:real``]
19424        DISTANCE_ATTAINS_INF) THEN
19425  ASM_SIMP_TAC std_ss [COMPACT_CLOSED_DIFFERENCES, EXISTS_IN_GSPEC, FORALL_IN_GSPEC,
19426               DIST_0, GSYM CONJ_ASSOC, GSPECIFICATION, EXISTS_PROD] THEN
19427  REWRITE_TAC[dist] THEN DISCH_THEN MATCH_MP_TAC THEN
19428  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC[]);
19429
19430val SETDIST_CLOSED_COMPACT = store_thm ("SETDIST_CLOSED_COMPACT",
19431 ``!s t:real->bool.
19432        closed s /\ compact t /\ ~(s = {}) /\ ~(t = {})
19433        ==> ?x y. x IN s /\ y IN t /\ (dist(x,y) = setdist(s,t))``,
19434  REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
19435   KNOW_TAC ``?x y. (\x. x IN s) x /\ (\y. y IN t) y /\
19436                   (\x y. dist (x,y) <= setdist (s,t)) x y /\
19437                   (\x y. setdist (s,t) <= dist (x,y)) x y`` THENL
19438  [ALL_TAC, METIS_TAC []] THEN
19439  MATCH_MP_TAC(METIS[]
19440   ``(!x y. P x /\ Q y ==> R' x y) /\ (?x y. P x /\ Q y /\ R x y)
19441    ==> ?x y. P x /\ Q y /\ R x y /\ R' x y``) THEN
19442  SIMP_TAC std_ss [SETDIST_LE_DIST] THEN
19443  ASM_REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN
19444  MP_TAC(ISPECL [``{x - y:real | x IN s /\ y IN t}``, ``0:real``]
19445        DISTANCE_ATTAINS_INF) THEN
19446  ASM_SIMP_TAC std_ss [CLOSED_COMPACT_DIFFERENCES, EXISTS_IN_GSPEC, FORALL_IN_GSPEC,
19447               DIST_0, GSYM CONJ_ASSOC, GSPECIFICATION, EXISTS_PROD] THEN
19448  REWRITE_TAC[dist] THEN DISCH_THEN MATCH_MP_TAC THEN
19449  SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN ASM_SET_TAC[]);
19450
19451val SETDIST_EQ_0_COMPACT_CLOSED = store_thm ("SETDIST_EQ_0_COMPACT_CLOSED",
19452 ``!s t:real->bool.
19453        compact s /\ closed t
19454        ==> ((setdist(s,t) = &0) <=> (s = {}) \/ (t = {}) \/ ~(s INTER t = {}))``,
19455  REPEAT STRIP_TAC THEN
19456  MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``t:real->bool = {}``] THEN
19457  ASM_REWRITE_TAC[SETDIST_EMPTY] THEN EQ_TAC THENL
19458   [MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``]
19459      SETDIST_COMPACT_CLOSED) THEN ASM_REWRITE_TAC[] THEN
19460    REWRITE_TAC[EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN MESON_TAC[DIST_EQ_0],
19461    REWRITE_TAC[GSYM REAL_LE_ANTISYM, SETDIST_POS_LE] THEN
19462    REWRITE_TAC[EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN
19463    MESON_TAC[SETDIST_LE_DIST, DIST_EQ_0]]);
19464
19465val SETDIST_EQ_0_CLOSED_COMPACT = store_thm ("SETDIST_EQ_0_CLOSED_COMPACT",
19466 ``!s t:real->bool.
19467        closed s /\ compact t
19468        ==> ((setdist(s,t) = &0) <=> (s = {}) \/ (t = {}) \/ ~(s INTER t = {}))``,
19469  ONCE_REWRITE_TAC[SETDIST_SYM] THEN
19470  SIMP_TAC std_ss [SETDIST_EQ_0_COMPACT_CLOSED] THEN SET_TAC[]);
19471
19472val SETDIST_EQ_0_BOUNDED = store_thm ("SETDIST_EQ_0_BOUNDED",
19473 ``!s t:real->bool.
19474        (bounded s \/ bounded t)
19475        ==> ((setdist(s,t) = &0) <=>
19476             (s = {}) \/ (t = {}) \/ ~(closure(s) INTER closure(t) = {}))``,
19477  REPEAT GEN_TAC THEN
19478  MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``t:real->bool = {}``] THEN
19479  ASM_REWRITE_TAC[SETDIST_EMPTY] THEN STRIP_TAC THEN
19480  ONCE_REWRITE_TAC[MESON[SETDIST_CLOSURE]
19481   ``setdist(s,t) = setdist(closure s,closure t)``] THEN
19482  ASM_SIMP_TAC std_ss [SETDIST_EQ_0_COMPACT_CLOSED, SETDIST_EQ_0_CLOSED_COMPACT,
19483               COMPACT_CLOSURE, CLOSED_CLOSURE, CLOSURE_EQ_EMPTY]);
19484
19485val SETDIST_TRANSLATION = store_thm ("SETDIST_TRANSLATION",
19486 ``!a:real s t.
19487        setdist(IMAGE (\x. a + x) s,IMAGE (\x. a + x) t) = setdist(s,t)``,
19488  REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[SETDIST_DIFFERENCES] THEN
19489  AP_TERM_TAC THEN AP_TERM_TAC THEN
19490  KNOW_TAC ``!f:real->real->real x:real y:real g:real->real s:real->bool t:real->bool.
19491   {f x y | x IN IMAGE g s /\ y IN IMAGE g t} = {f (g x) (g y) | x IN s /\ y IN t}`` THENL
19492  [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN
19493   ASM_SET_TAC[], DISCH_TAC] THEN
19494  ONCE_REWRITE_TAC [METIS [] ``x - y = (\x y. x - y) x y:real``] THEN
19495  ASM_REWRITE_TAC [] THEN
19496  SIMP_TAC std_ss [REAL_ARITH ``(a + x) - (a + y):real = x - y``]);
19497
19498val SETDIST_LINEAR_IMAGE = store_thm ("SETDIST_LINEAR_IMAGE",
19499 ``!f:real->real s t.
19500        linear f /\ (!x. abs(f x) = abs x)
19501        ==> (setdist(IMAGE f s,IMAGE f t) = setdist(s,t))``,
19502  REPEAT STRIP_TAC THEN REWRITE_TAC[setdist, IMAGE_EQ_EMPTY] THEN
19503  COND_CASES_TAC THEN ASM_REWRITE_TAC[dist] THEN AP_TERM_TAC THEN
19504  ONCE_REWRITE_TAC [METIS [] ``abs (x - y) = (\x y. abs (x - y)) x y:real``] THEN
19505  KNOW_TAC ``!f:real->real->real x:real y:real g:real->real s:real->bool t:real->bool.
19506   {f x y | x IN IMAGE g s /\ y IN IMAGE g t} = {f (g x) (g y) | x IN s /\ y IN t}`` THENL
19507  [SIMP_TAC std_ss [EXTENSION, GSPECIFICATION, EXISTS_PROD] THEN
19508   ASM_SET_TAC[], DISCH_TAC] THEN ASM_REWRITE_TAC [] THEN BETA_TAC THEN
19509  FIRST_X_ASSUM(fn th => REWRITE_TAC[GSYM(MATCH_MP LINEAR_SUB th)]) THEN
19510  ASM_SIMP_TAC std_ss []);
19511
19512val SETDIST_UNIQUE = store_thm ("SETDIST_UNIQUE",
19513 ``!s t a b:real d.
19514        a IN s /\ b IN t /\ (dist(a,b) = d) /\
19515        (!x y. x IN s /\ y IN t ==> dist(a,b) <= dist(x,y))
19516        ==> (setdist(s,t) = d)``,
19517  REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
19518   [ASM_MESON_TAC[SETDIST_LE_DIST],
19519    MATCH_MP_TAC REAL_LE_SETDIST THEN ASM_SET_TAC[]]);
19520
19521val SETDIST_UNIV = store_thm ("SETDIST_UNIV",
19522 ``(!s. setdist(s,univ(:real)) = &0) /\
19523   (!t. setdist(univ(:real),t) = &0)``,
19524  GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SETDIST_SYM] THEN
19525  REWRITE_TAC[] THEN X_GEN_TAC ``s:real->bool`` THEN
19526  ASM_CASES_TAC ``s:real->bool = {}`` THEN ASM_REWRITE_TAC[SETDIST_EMPTY] THEN
19527  MATCH_MP_TAC SETDIST_UNIQUE THEN
19528  SIMP_TAC std_ss [IN_UNIV, DIST_EQ_0, RIGHT_EXISTS_AND_THM] THEN
19529  ASM_REWRITE_TAC[UNWIND_THM1, DIST_REFL, DIST_POS_LE, MEMBER_NOT_EMPTY]);
19530
19531val SETDIST_ZERO = store_thm ("SETDIST_ZERO",
19532 ``!s t:real->bool. ~(DISJOINT s t) ==> (setdist(s,t) = &0)``,
19533  REPEAT STRIP_TAC THEN MATCH_MP_TAC SETDIST_UNIQUE THEN
19534  KNOW_TAC ``?a. a IN s /\ a IN t /\ (dist (a,a) = 0) /\
19535             !x y. x IN s /\ y IN t ==> dist (a,a) <= dist (x,y)`` THENL
19536  [ALL_TAC, METIS_TAC []] THEN
19537  ONCE_REWRITE_TAC[TAUT `p /\ q /\ r /\ s <=> r /\ p /\ q /\ s`] THEN
19538  REWRITE_TAC[DIST_EQ_0, UNWIND_THM2, DIST_REFL, DIST_POS_LE] THEN
19539  ASM_SET_TAC[]);
19540
19541val SETDIST_ZERO_STRONG = store_thm ("SETDIST_ZERO_STRONG",
19542 ``!s t:real->bool.
19543      ~(DISJOINT (closure s) (closure t)) ==> (setdist(s,t) = &0)``,
19544  MESON_TAC[SETDIST_CLOSURE, SETDIST_ZERO]);
19545
19546val SETDIST_FRONTIERS = store_thm ("SETDIST_FRONTIERS",
19547 ``!s t:real->bool.
19548        setdist(s,t) =
19549        if DISJOINT s t then setdist(frontier s,frontier t) else &0``,
19550  REPEAT STRIP_TAC THEN
19551  COND_CASES_TAC THEN ASM_SIMP_TAC std_ss [SETDIST_ZERO] THEN
19552  ASSUME_TAC SETDIST_FRONTIER THEN POP_ASSUM (MP_TAC o ONCE_REWRITE_RULE [EQ_SYM_EQ]) THEN
19553  DISCH_THEN (CONJUNCTS_THEN2 K_TAC ASSUME_TAC) THEN ASM_SIMP_TAC std_ss [] THEN
19554  POP_ASSUM K_TAC THEN
19555  ASM_CASES_TAC ``DISJOINT s (frontier t:real->bool)`` THENL
19556   [ASM_MESON_TAC[SETDIST_FRONTIER], ALL_TAC] THEN
19557  GEN_REWR_TAC LAND_CONV [GSYM(CONJUNCT1 SETDIST_CLOSURE)] THEN
19558  CONV_TAC SYM_CONV THEN MATCH_MP_TAC SETDIST_SUBSETS_EQ THEN
19559  SIMP_TAC std_ss [frontier, DIFF_SUBSET, SUBSET_REFL, IN_DIFF] THEN
19560  MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN
19561  KNOW_TAC ``?y' x'.
19562  (x' IN closure s /\ x' NOTIN interior s) /\
19563  (y' IN closure t /\ y' NOTIN interior t) /\ dist (x',y') <= dist (x,y)`` THENL
19564  [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN EXISTS_TAC ``y:real`` THEN
19565  ASM_REWRITE_TAC[] THEN
19566  ASM_CASES_TAC ``(x:real) IN interior s`` THENL
19567   [ALL_TAC, ASM_MESON_TAC[REAL_LE_REFL]] THEN
19568  MP_TAC(ISPECL [``segment[x:real,y]``, ``interior s:real->bool``]
19569        CONNECTED_INTER_FRONTIER) THEN
19570  REWRITE_TAC[CONNECTED_SEGMENT, GSYM MEMBER_NOT_EMPTY] THEN
19571  KNOW_TAC ``(?x'. x' IN segment [(x,y)] INTER interior s) /\
19572             (?x'. x' IN segment [(x,y)] DIFF interior s)`` THENL
19573   [CONJ_TAC THENL [EXISTS_TAC ``x:real``, EXISTS_TAC ``y:real``] THEN
19574    ASM_SIMP_TAC std_ss [IN_INTER, IN_DIFF, ENDS_IN_SEGMENT] THEN
19575    FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
19576     ``y IN u ==> (u INTER v = {}) ==> ~(y IN v)``)) THEN
19577    REWRITE_TAC[INTERIOR_CLOSURE, SET_RULE
19578     ``(s INTER (UNIV DIFF t) = {}) <=> s SUBSET t``] THEN
19579    MATCH_MP_TAC SUBSET_CLOSURE THEN ASM_SET_TAC[],
19580    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
19581    DISCH_THEN (X_CHOOSE_TAC ``z:real``) THEN EXISTS_TAC ``z:real`` THEN
19582    POP_ASSUM MP_TAC THEN
19583    SIMP_TAC std_ss [IN_INTER, GSYM frontier, GSYM IN_DIFF] THEN
19584    MESON_TAC[FRONTIER_INTERIOR_SUBSET, SUBSET_DEF, DIST_IN_CLOSED_SEGMENT]]);
19585
19586val SETDIST_SING_FRONTIER = store_thm ("SETDIST_SING_FRONTIER",
19587 ``!s x:real. ~(x IN s) ==> (setdist({x},frontier s) = setdist({x},s))``,
19588  MESON_TAC[SET_RULE ``DISJOINT {x} s <=> ~(x IN s)``, SETDIST_FRONTIER]);
19589
19590val SETDIST_CLOSEST_POINT = store_thm ("SETDIST_CLOSEST_POINT",
19591 ``!a:real s.
19592      closed s /\ ~(s = {}) ==> (setdist({a},s) = dist(a,closest_point s a))``,
19593  REPEAT STRIP_TAC THEN MATCH_MP_TAC SETDIST_UNIQUE THEN
19594  SIMP_TAC std_ss [RIGHT_EXISTS_AND_THM, IN_SING, UNWIND_THM2] THEN
19595  EXISTS_TAC ``closest_point s (a:real)`` THEN
19596  ASM_MESON_TAC[CLOSEST_POINT_EXISTS, DIST_SYM]);
19597
19598val SETDIST_EQ_0_SING = store_thm ("SETDIST_EQ_0_SING",
19599 ``(!s x:real. (setdist({x},s) = &0) <=> (s = {}) \/ x IN closure s) /\
19600   (!s x:real. (setdist(s,{x}) = &0) <=> (s = {}) \/ x IN closure s)``,
19601  SIMP_TAC std_ss [SETDIST_EQ_0_BOUNDED, BOUNDED_SING, CLOSURE_SING] THEN SET_TAC[]);
19602
19603val SETDIST_EQ_0_CLOSED = store_thm ("SETDIST_EQ_0_CLOSED",
19604 ``!s x. closed s ==> ((setdist({x},s) = &0) <=> (s = {}) \/ x IN s)``,
19605  SIMP_TAC std_ss [SETDIST_EQ_0_COMPACT_CLOSED, COMPACT_SING] THEN SET_TAC[]);
19606
19607val SETDIST_EQ_0_CLOSED_IN = store_thm ("SETDIST_EQ_0_CLOSED_IN",
19608 ``!u s x. closed_in (subtopology euclidean u) s /\ x IN u
19609           ==> ((setdist({x},s) = &0) <=> (s = {}) \/ x IN s)``,
19610  REWRITE_TAC[SETDIST_EQ_0_SING, CLOSED_IN_INTER_CLOSURE] THEN SET_TAC[]);
19611
19612val SETDIST_SING_IN_SET = store_thm ("SETDIST_SING_IN_SET",
19613 ``!x s. x IN s ==> (setdist({x},s) = &0)``,
19614  SIMP_TAC std_ss [SETDIST_EQ_0_SING, REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET]);
19615
19616val SETDIST_SING_FRONTIER_CASES = store_thm ("SETDIST_SING_FRONTIER_CASES",
19617 ``!s x:real.
19618        setdist({x},s) = if x IN s then &0 else setdist({x},frontier s)``,
19619  REPEAT GEN_TAC THEN COND_CASES_TAC THEN
19620  ASM_SIMP_TAC std_ss [SETDIST_SING_IN_SET, SETDIST_SING_FRONTIER]);
19621
19622val SETDIST_SING_TRIANGLE = store_thm ("SETDIST_SING_TRIANGLE",
19623 ``!s x y:real. abs(setdist({x},s) - setdist({y},s)) <= dist(x,y)``,
19624  REPEAT GEN_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN
19625  ASM_REWRITE_TAC[SETDIST_EMPTY, REAL_SUB_REFL, ABS_N, DIST_POS_LE] THEN
19626  REWRITE_TAC[ABS_BOUNDS, REAL_NEG_SUB] THEN REPEAT STRIP_TAC THEN
19627  ONCE_REWRITE_TAC[REAL_ARITH ``a - b <= c <=> a - c <= b:real``,
19628                   REAL_ARITH ``-a <= b - c <=> c - a <= b:real``] THEN
19629  MATCH_MP_TAC REAL_LE_SETDIST THEN ASM_REWRITE_TAC[NOT_INSERT_EMPTY] THEN
19630  SIMP_TAC std_ss [IN_SING, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, UNWIND_FORALL_THM2] THEN
19631  X_GEN_TAC ``z:real`` THEN DISCH_TAC THEN REWRITE_TAC [dist] THENL
19632   [MATCH_MP_TAC(REAL_ARITH
19633     ``a <= abs(y:real - z) ==> a - abs(x - y) <= abs(x - z:real)``),
19634    MATCH_MP_TAC(REAL_ARITH
19635     ``a <= abs(x:real - z) ==> a - abs(x - y) <= abs(y - z)``)] THEN
19636  REWRITE_TAC [GSYM dist] THEN
19637  MATCH_MP_TAC SETDIST_LE_DIST THEN ASM_REWRITE_TAC[IN_SING]);
19638
19639val SETDIST_LE_SING = store_thm ("SETDIST_LE_SING",
19640 ``!s t x:real. x IN s ==> setdist(s,t) <= setdist({x},t)``,
19641  REPEAT STRIP_TAC THEN MATCH_MP_TAC SETDIST_SUBSET_LEFT THEN ASM_SET_TAC[]);
19642
19643val SETDIST_BALLS = store_thm ("SETDIST_BALLS",
19644 ``(!a b:real r s.
19645        setdist(ball(a,r),ball(b,s)) =
19646        if r <= &0 \/ s <= &0 then &0 else max (&0) (dist(a,b) - (r + s))) /\
19647   (!a b:real r s.
19648        setdist(ball(a,r),cball(b,s)) =
19649        if r <= &0 \/ s < &0 then &0 else max (&0) (dist(a,b) - (r + s))) /\
19650   (!a b:real r s.
19651        setdist(cball(a,r),ball(b,s)) =
19652        if r < &0 \/ s <= &0 then &0 else max (&0) (dist(a,b) - (r + s))) /\
19653   (!a b:real r s.
19654        setdist(cball(a,r),cball(b,s)) =
19655        if r < &0 \/ s < &0 then &0 else max (&0) (dist(a,b) - (r + s)))``,
19656  REWRITE_TAC[METIS[]
19657   ``(x = if p then y else z) <=> (p ==> (x = y)) /\ (~p ==> (x = z))``] THEN
19658  SIMP_TAC std_ss [TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN
19659  SIMP_TAC std_ss [BALL_EMPTY, CBALL_EMPTY, SETDIST_EMPTY, DE_MORGAN_THM] THEN
19660  ONCE_REWRITE_TAC[METIS[SETDIST_CLOSURE]
19661   ``setdist(s,t) = setdist(closure s,closure t)``] THEN
19662  SIMP_TAC std_ss [REAL_NOT_LE, REAL_NOT_LT, CLOSURE_BALL] THEN
19663  REWRITE_TAC[SETDIST_CLOSURE] THEN
19664  MATCH_MP_TAC(TAUT `(s ==> p /\ q /\ r) /\ s ==> p /\ q /\ r /\ s`) THEN
19665  CONJ_TAC THENL [METIS_TAC[REAL_LT_IMP_LE], REPEAT GEN_TAC] THEN
19666  REWRITE_TAC[max_def, REAL_SUB_LE] THEN COND_CASES_TAC THEN
19667  SIMP_TAC std_ss [SETDIST_EQ_0_BOUNDED, BOUNDED_CBALL, CLOSED_CBALL, CLOSURE_CLOSED,
19668           CBALL_EQ_EMPTY, INTER_BALLS_EQ_EMPTY]
19669  THENL [ALL_TAC, ASM_REAL_ARITH_TAC] THEN
19670  ASM_CASES_TAC ``b:real = a`` THENL
19671   [FIRST_X_ASSUM SUBST_ALL_TAC THEN
19672    RULE_ASSUM_TAC(REWRITE_RULE[DIST_REFL]) THEN
19673    ASM_CASES_TAC ``(r = &0:real) /\ (s = &0:real)`` THENL [ALL_TAC, ASM_REAL_ARITH_TAC] THEN
19674    ASM_SIMP_TAC std_ss [CBALL_SING, SETDIST_SINGS, dist] THEN REAL_ARITH_TAC,
19675    STRIP_TAC] THEN
19676  REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
19677   [ALL_TAC,
19678    MATCH_MP_TAC REAL_LE_SETDIST THEN
19679    ASM_REWRITE_TAC[CBALL_EQ_EMPTY, REAL_NOT_LT, IN_CBALL, dist] THEN
19680    REAL_ARITH_TAC] THEN
19681  MATCH_MP_TAC REAL_LE_TRANS THEN
19682  EXISTS_TAC ``dist(a + r / dist(a,b) * (b - a):real,
19683                   b - s / dist(a,b) * (b - a))`` THEN
19684  CONJ_TAC THENL
19685   [MATCH_MP_TAC SETDIST_LE_DIST THEN
19686    REWRITE_TAC[dist, IN_CBALL, REAL_ARITH ``abs(a - (a + x)) = abs x:real``,
19687                                REAL_ARITH ``abs(a - (a - x)) = abs x:real``] THEN
19688    REWRITE_TAC [GSYM dist] THEN ONCE_REWRITE_TAC [DIST_SYM] THEN
19689    FULL_SIMP_TAC real_ss [dist, ABS_MUL, ABS_DIV, ABS_ABS, ABS_NZ,
19690      REAL_LT_IMP_NE, REAL_ARITH ``(b <> a) = (b - a <> 0:real)``] THEN
19691    KNOW_TAC ``abs (b - a:real) <> 0`` THENL [METIS_TAC [REAL_LT_IMP_NE], DISCH_TAC] THEN
19692    ASM_SIMP_TAC std_ss [REAL_DIV_RMUL, REAL_SUB_0, ABS_ZERO] THEN
19693    ASM_REAL_ARITH_TAC,
19694    REWRITE_TAC[dist, REAL_ARITH
19695     ``(a + d * (b - a)) - (b - e * (b - a)):real =
19696       (&1 - d - e) * (a - b:real)``] THEN
19697    REWRITE_TAC[ABS_MUL, real_div, REAL_ARITH
19698      ``&1 - r * y - s * y = &1 - (r + s) * y:real``] THEN REWRITE_TAC [GSYM real_div] THEN
19699    REWRITE_TAC [METIS [GSYM ABS_ABS] ``d * abs (a - b) = d * abs(abs (a - b:real))``] THEN
19700    REWRITE_TAC[GSYM ABS_MUL] THEN
19701    KNOW_TAC ``!n x:real. ~(n = &0) ==> ((&1 - x / n) * n = n - x)`` THENL
19702    [REPEAT GEN_TAC THEN DISCH_TAC THEN
19703     ASM_SIMP_TAC std_ss [REAL_SUB_RDISTRIB, REAL_DIV_RMUL] THEN
19704     REAL_ARITH_TAC, DISCH_TAC] THEN
19705    RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH ``(b <> a) = (abs (a - b) <> 0:real)``]) THEN
19706    ASM_SIMP_TAC real_ss [REAL_SUB_0, ABS_ZERO] THEN
19707    FULL_SIMP_TAC std_ss [dist] THEN SIMP_TAC std_ss [REAL_LE_LT] THEN
19708    DISJ2_TAC THEN REWRITE_TAC [ABS_REFL, REAL_SUB_LE] THEN ASM_REWRITE_TAC []]);
19709
19710(* ------------------------------------------------------------------------- *)
19711(* Use set distance for an easy proof of separation properties etc.          *)
19712(* ------------------------------------------------------------------------- *)
19713
19714val SEPARATION_CLOSURES = store_thm ("SEPARATION_CLOSURES",
19715 ``!s t:real->bool.
19716        (s INTER closure(t) = {}) /\ (t INTER closure(s) = {})
19717        ==> ?u v. DISJOINT u v /\ open u /\ open v /\
19718                  s SUBSET u /\ t SUBSET v``,
19719  REPEAT STRIP_TAC THEN
19720  ASM_CASES_TAC ``s:real->bool = {}`` THENL
19721   [MAP_EVERY EXISTS_TAC [``{}:real->bool``, ``univ(:real)``] THEN
19722    ASM_REWRITE_TAC[OPEN_EMPTY, OPEN_UNIV] THEN ASM_SET_TAC[],
19723    ALL_TAC] THEN
19724  ASM_CASES_TAC ``t:real->bool = {}`` THENL
19725   [MAP_EVERY EXISTS_TAC [``univ(:real)``, ``{}:real->bool``] THEN
19726    ASM_REWRITE_TAC[OPEN_EMPTY, OPEN_UNIV] THEN ASM_SET_TAC[],
19727    ALL_TAC] THEN
19728  EXISTS_TAC ``{x | x IN univ(:real) /\
19729                   (setdist({x},t) - setdist({x},s)) IN
19730                   {x | &0 < x}}`` THEN
19731  EXISTS_TAC ``{x | x IN univ(:real) /\
19732                   (setdist({x},t) - setdist({x},s)) IN
19733                   {x | x < &0}}`` THEN
19734  REPEAT CONJ_TAC THENL
19735   [REWRITE_TAC[SET_RULE ``DISJOINT s t <=> !x. x IN s /\ x IN t ==> F``] THEN
19736    SIMP_TAC std_ss [GSPECIFICATION, IN_UNIV] THEN REAL_ARITH_TAC,
19737    ONCE_REWRITE_TAC [METIS [] ``(setdist ({x},t) - setdist ({x},s)) =
19738                             (\x. setdist ({x},t) - setdist ({x},s)) x``] THEN
19739    MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE THEN
19740    SIMP_TAC std_ss [REWRITE_RULE[real_gt] OPEN_HALFSPACE_COMPONENT_GT, OPEN_UNIV] THEN
19741    SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_SETDIST],
19742    ONCE_REWRITE_TAC [METIS [] ``(setdist ({x},t) - setdist ({x},s)) =
19743                             (\x. setdist ({x},t) - setdist ({x},s)) x``] THEN
19744    MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE THEN
19745    SIMP_TAC std_ss [OPEN_HALFSPACE_COMPONENT_LT, OPEN_UNIV] THEN
19746    SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_SETDIST],
19747    SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_UNIV] THEN
19748    GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH
19749     ``&0 <= x /\ (y = &0) /\ ~(x = &0) ==> &0 < x - y:real``),
19750    SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION, IN_UNIV] THEN
19751    GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH
19752     ``&0 <= y /\ (x = &0) /\ ~(y = &0) ==> x - y < &0:real``)] THEN
19753  ASM_SIMP_TAC std_ss [SETDIST_POS_LE, SETDIST_EQ_0_BOUNDED, BOUNDED_SING] THEN
19754  ASM_SIMP_TAC std_ss [CLOSED_SING, CLOSURE_CLOSED, NOT_INSERT_EMPTY,
19755               REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET,
19756               SET_RULE ``({a} INTER s = {}) <=> ~(a IN s)``] THEN
19757  ASM_SET_TAC[]);
19758
19759val SEPARATION_NORMAL = store_thm ("SEPARATION_NORMAL",
19760 ``!s t:real->bool.
19761        closed s /\ closed t /\ (s INTER t = {})
19762        ==> ?u v. open u /\ open v /\
19763                  s SUBSET u /\ t SUBSET v /\ (u INTER v = {})``,
19764  REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM DISJOINT_DEF] THEN
19765  ONCE_REWRITE_TAC[TAUT
19766    `a /\ b /\ c /\ d /\ e <=> e /\ a /\ b /\ c /\ d`] THEN
19767  MATCH_MP_TAC SEPARATION_CLOSURES THEN
19768  ASM_SIMP_TAC std_ss [CLOSURE_CLOSED] THEN ASM_SET_TAC[]);
19769
19770val SEPARATION_NORMAL_LOCAL = store_thm ("SEPARATION_NORMAL_LOCAL",
19771 ``!s t u:real->bool.
19772        closed_in (subtopology euclidean u) s /\
19773        closed_in (subtopology euclidean u) t /\
19774        (s INTER t = {})
19775        ==> ?s' t'. open_in (subtopology euclidean u) s' /\
19776                    open_in (subtopology euclidean u) t' /\
19777                    s SUBSET s' /\ t SUBSET t' /\ (s' INTER t' = {})``,
19778  REPEAT STRIP_TAC THEN
19779  ASM_CASES_TAC ``s:real->bool = {}`` THENL
19780   [MAP_EVERY EXISTS_TAC [``{}:real->bool``, ``u:real->bool``] THEN
19781    ASM_SIMP_TAC std_ss [OPEN_IN_REFL, OPEN_IN_EMPTY, INTER_EMPTY, EMPTY_SUBSET] THEN
19782    ASM_MESON_TAC[CLOSED_IN_IMP_SUBSET],
19783    ALL_TAC] THEN
19784  ASM_CASES_TAC ``t:real->bool = {}`` THENL
19785   [MAP_EVERY EXISTS_TAC [``u:real->bool``, ``{}:real->bool``] THEN
19786    ASM_SIMP_TAC std_ss [OPEN_IN_REFL, OPEN_IN_EMPTY, INTER_EMPTY, EMPTY_SUBSET] THEN
19787    ASM_MESON_TAC[CLOSED_IN_IMP_SUBSET],
19788    ALL_TAC] THEN
19789  EXISTS_TAC ``{x:real | x IN u /\ setdist({x},s) < setdist({x},t)}`` THEN
19790  EXISTS_TAC ``{x:real | x IN u /\ setdist({x},t) < setdist({x},s)}`` THEN
19791  SIMP_TAC std_ss [EXTENSION, SUBSET_DEF, GSPECIFICATION, SETDIST_SING_IN_SET, IN_INTER,
19792           NOT_IN_EMPTY, SETDIST_POS_LE, CONJ_ASSOC,
19793           REAL_ARITH ``&0 < x <=> &0 <= x /\ ~(x = &0:real)``] THEN
19794  CONJ_TAC THENL [ALL_TAC, METIS_TAC[REAL_LT_ANTISYM]] THEN
19795  ONCE_REWRITE_TAC[GSYM CONJ_ASSOC] THEN CONJ_TAC THENL
19796   [ALL_TAC,
19797    ASM_MESON_TAC[SETDIST_EQ_0_CLOSED_IN, CLOSED_IN_IMP_SUBSET, SUBSET_DEF,
19798                  MEMBER_NOT_EMPTY, IN_INTER]] THEN
19799  ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN
19800  ONCE_REWRITE_TAC [METIS [] ``(setdist ({x},t) - setdist ({x},s)) =
19801                           (\x. setdist ({x},t) - setdist ({x},s)) x``] THEN
19802  REWRITE_TAC[SET_RULE
19803   ``{x:real | x IN u /\ &0 < (f:real->real) x} =
19804     {x:real | x IN u /\ f x IN {x | &0 < x}}``] THEN
19805  CONJ_TAC THEN
19806  MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE THEN
19807  REWRITE_TAC[OPEN_HALFSPACE_COMPONENT_LT,
19808           REWRITE_RULE[real_gt] OPEN_HALFSPACE_COMPONENT_GT, OPEN_UNIV] THEN
19809  SIMP_TAC std_ss [CONTINUOUS_ON_SUB, CONTINUOUS_ON_SETDIST]);
19810
19811val SEPARATION_NORMAL_COMPACT = store_thm ("SEPARATION_NORMAL_COMPACT",
19812 ``!s t:real->bool.
19813        compact s /\ closed t /\ (s INTER t = {})
19814        ==> ?u v. open u /\ compact(closure u) /\ open v /\
19815                  s SUBSET u /\ t SUBSET v /\ (u INTER v = {})``,
19816  REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_CLOSURE] THEN
19817  REPEAT STRIP_TAC THEN FIRST_ASSUM
19818   (MP_TAC o SPEC ``0:real`` o MATCH_MP BOUNDED_SUBSET_BALL) THEN
19819  DISCH_THEN(X_CHOOSE_THEN ``r:real`` STRIP_ASSUME_TAC) THEN
19820  MP_TAC(ISPECL [``s:real->bool``, ``t UNION (univ(:real) DIFF ball(0,r))``]
19821        SEPARATION_NORMAL) THEN
19822  ASM_SIMP_TAC std_ss [CLOSED_UNION, GSYM OPEN_CLOSED, OPEN_BALL] THEN
19823  KNOW_TAC ``((s :real -> bool) INTER
19824  ((t :real -> bool) UNION
19825   (univ(:real) DIFF ball ((0 :real),(r :real)))) =
19826  ({} :real -> bool))`` THENL [ASM_SET_TAC[], DISCH_TAC THEN
19827    ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
19828  STRIP_TAC THEN EXISTS_TAC ``u:real->bool`` THEN
19829  EXISTS_TAC ``v:real->bool`` THEN ASM_REWRITE_TAC[] THEN
19830  CONJ_TAC THENL [MATCH_MP_TAC BOUNDED_CLOSURE, ASM_SET_TAC[]] THEN
19831  MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC ``ball(0:real,r)`` THEN
19832  REWRITE_TAC[BOUNDED_BALL] THEN ASM_SET_TAC[]);
19833
19834val SEPARATION_HAUSDORFF = store_thm ("SEPARATION_HAUSDORFF",
19835 ``!x:real y.
19836      ~(x = y)
19837      ==> ?u v. open u /\ open v /\ x IN u /\ y IN v /\ (u INTER v = {})``,
19838  REPEAT STRIP_TAC THEN
19839  MP_TAC(SPECL [``{x:real}``, ``{y:real}``] SEPARATION_NORMAL) THEN
19840  REWRITE_TAC[SING_SUBSET, CLOSED_SING] THEN
19841  DISCH_THEN MATCH_MP_TAC THEN ASM_SET_TAC[]);
19842
19843val SEPARATION_T2 = store_thm ("SEPARATION_T2",
19844 ``!x:real y.
19845        ~(x = y) <=> ?u v. open u /\ open v /\ x IN u /\ y IN v /\
19846                           (u INTER v = {})``,
19847  REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC std_ss [SEPARATION_HAUSDORFF] THEN
19848  REWRITE_TAC[EXTENSION, IN_INTER, NOT_IN_EMPTY] THEN MESON_TAC[]);
19849
19850val SEPARATION_T1 = store_thm ("SEPARATION_T1",
19851 ``!x:real y.
19852        ~(x = y) <=> ?u v. open u /\ open v /\ x IN u /\ ~(y IN u) /\
19853                           ~(x IN v) /\ y IN v``,
19854  REPEAT STRIP_TAC THEN EQ_TAC THENL
19855   [ASM_SIMP_TAC std_ss [SEPARATION_T2, EXTENSION, NOT_IN_EMPTY, IN_INTER],
19856    ALL_TAC] THEN MESON_TAC[]);
19857
19858val SEPARATION_T0 = store_thm ("SEPARATION_T0",
19859 ``!x:real y. ~(x = y) <=> ?u. open u /\ ~(x IN u <=> y IN u)``,
19860  MESON_TAC[SEPARATION_T1]);
19861
19862(* ------------------------------------------------------------------------- *)
19863(* Connectedness of the intersection of a chain.                             *)
19864(* ------------------------------------------------------------------------- *)
19865
19866val CONNECTED_CHAIN = store_thm ("CONNECTED_CHAIN",
19867 ``!f:(real->bool)->bool.
19868        (!s. s IN f ==> compact s /\ connected s) /\
19869        (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s)
19870        ==> connected(BIGINTER f)``,
19871  REPEAT STRIP_TAC THEN
19872  ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THEN
19873  ASM_REWRITE_TAC[BIGINTER_EMPTY, CONNECTED_UNIV] THEN
19874  ABBREV_TAC ``c:real->bool = BIGINTER f`` THEN
19875  SUBGOAL_THEN ``compact(c:real->bool)`` ASSUME_TAC THENL
19876   [EXPAND_TAC "c" THEN MATCH_MP_TAC COMPACT_BIGINTER THEN ASM_SET_TAC[],
19877    ALL_TAC] THEN
19878  ASM_SIMP_TAC std_ss [CONNECTED_CLOSED_SET, COMPACT_IMP_CLOSED, NOT_EXISTS_THM] THEN
19879  MAP_EVERY X_GEN_TAC [``a:real->bool``, ``b:real->bool``] THEN CCONTR_TAC THEN
19880  FULL_SIMP_TAC std_ss [] THEN
19881  MP_TAC(ISPECL [``a:real->bool``, ``b:real->bool``] SEPARATION_NORMAL) THEN
19882  ASM_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN
19883  MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
19884  CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
19885  SUBGOAL_THEN ``?k:real->bool. k IN f`` STRIP_ASSUME_TAC THENL
19886   [ASM_SET_TAC[], ALL_TAC] THEN
19887  SUBGOAL_THEN ``?n:real->bool. open n /\ k SUBSET n`` MP_TAC THENL
19888   [ASM_MESON_TAC[BOUNDED_SUBSET_BALL, COMPACT_IMP_BOUNDED, OPEN_BALL],
19889    REWRITE_TAC[BIGUNION_SUBSET] THEN STRIP_TAC] THEN
19890  MP_TAC(ISPEC ``k:real->bool`` COMPACT_IMP_HEINE_BOREL) THEN
19891  ASM_SIMP_TAC std_ss [] THEN
19892  KNOW_TAC ``~(!(f' :(real -> bool) -> bool).
19893  ((!(t :real -> bool). t IN f' ==> (open t :bool)) /\
19894   (k :real -> bool) SUBSET BIGUNION f') ==>
19895  ?(f'' :(real -> bool) -> bool).
19896    (f'' SUBSET f') /\ FINITE f'' /\ (k SUBSET BIGUNION f''))`` THENL
19897  [ALL_TAC, METIS_TAC []] THEN DISCH_THEN (MP_TAC o SPEC
19898   ``(u UNION v:real->bool) INSERT {n DIFF s | s IN f}``) THEN
19899  SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_INSERT, FORALL_IN_IMAGE] THEN
19900  ASM_SIMP_TAC std_ss [OPEN_UNION, OPEN_DIFF, COMPACT_IMP_CLOSED, NOT_IMP] THEN
19901  CONJ_TAC THENL
19902   [REWRITE_TAC[BIGUNION_INSERT] THEN REWRITE_TAC[SUBSET_DEF] THEN
19903    X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN ONCE_REWRITE_TAC[IN_UNION] THEN
19904    ASM_CASES_TAC ``(x:real) IN c`` THENL [ASM_SET_TAC[], DISJ2_TAC] THEN
19905    SIMP_TAC std_ss [BIGUNION_IMAGE, GSPECIFICATION] THEN
19906    UNDISCH_TAC ``~((x:real) IN c)`` THEN
19907    SUBST1_TAC(SYM(ASSUME ``BIGINTER f:real->bool = c``)) THEN
19908    SIMP_TAC std_ss [IN_BIGINTER, NOT_FORALL_THM] THEN
19909    STRIP_TAC THEN EXISTS_TAC ``P:real->bool`` THEN ASM_SET_TAC[],
19910    ALL_TAC] THEN
19911  X_GEN_TAC ``g:(real->bool)->bool`` THEN
19912  REWRITE_TAC [GSYM DE_MORGAN_THM] THEN
19913  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
19914  REWRITE_TAC[SUBSET_INSERT_DELETE] THEN
19915  SUBGOAL_THEN ``FINITE(g DELETE (u UNION v:real->bool))`` MP_TAC THENL
19916   [ASM_REWRITE_TAC[FINITE_DELETE],
19917    REWRITE_TAC[TAUT `p ==> ~q <=> ~(p /\ q)`]] THEN
19918  REWRITE_TAC[FINITE_SUBSET_IMAGE] THEN
19919  DISCH_THEN(X_CHOOSE_THEN ``f':(real->bool)->bool`` STRIP_ASSUME_TAC) THEN
19920  SUBGOAL_THEN
19921   ``?j:real->bool. j IN f /\
19922                   BIGUNION(IMAGE (\s. n DIFF s) f') SUBSET (n DIFF j)``
19923  STRIP_ASSUME_TAC THENL
19924   [ASM_CASES_TAC ``f':(real->bool)->bool = {}`` THEN
19925    ASM_REWRITE_TAC[IMAGE_EMPTY, IMAGE_INSERT, BIGUNION_EMPTY, EMPTY_SUBSET] THENL
19926     [ASM_SET_TAC[], ALL_TAC] THEN
19927    SUBGOAL_THEN
19928     ``?j:real->bool. j IN f' /\
19929                       BIGUNION(IMAGE (\s. n DIFF s) f') SUBSET (n DIFF j)``
19930    MP_TAC THENL [ALL_TAC, ASM_MESON_TAC[SUBSET_DEF]] THEN
19931    SUBGOAL_THEN
19932     ``!s t:real->bool. s IN f' /\ t IN f' ==> s SUBSET t \/ t SUBSET s``
19933    MP_TAC THENL [ASM_MESON_TAC[SUBSET_DEF], ALL_TAC] THEN
19934    UNDISCH_TAC ``~(f':(real->bool)->bool = {})`` THEN
19935    UNDISCH_TAC ``FINITE(f':(real->bool)->bool)`` THEN
19936    SPEC_TAC(``f':(real->bool)->bool``,``f':(real->bool)->bool``) THEN
19937    KNOW_TAC ``!(f' :(real -> bool) -> bool). (f' <> {} ==>
19938  (!s t. s IN f' /\ t IN f' ==> s SUBSET t \/ t SUBSET s) ==>
19939  ?j. j IN f' /\ BIGUNION (IMAGE (\s. n DIFF s) f') SUBSET n DIFF j) =
19940        (\f'. f' <> {} ==>
19941  (!s t. s IN f' /\ t IN f' ==> s SUBSET t \/ t SUBSET s) ==>
19942  ?j. j IN f' /\ BIGUNION (IMAGE (\s. n DIFF s) f') SUBSET n DIFF j) f'``
19943    THENL [METIS_TAC [], DISC_RW_KILL] THEN
19944    MATCH_MP_TAC FINITE_INDUCT THEN SIMP_TAC std_ss [] THEN
19945    SIMP_TAC std_ss [EXISTS_IN_INSERT, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN
19946    SIMP_TAC std_ss [FORALL_IN_INSERT] THEN POP_ASSUM_LIST(K ALL_TAC) THEN
19947    SIMP_TAC std_ss [GSYM RIGHT_FORALL_IMP_THM] THEN
19948    MAP_EVERY X_GEN_TAC [``f:(real->bool)->bool``, ``i:real->bool``] THEN
19949    ASM_CASES_TAC ``f:(real->bool)->bool = {}`` THEN
19950    ASM_SIMP_TAC std_ss [IMAGE_EMPTY, IMAGE_INSERT, BIGUNION_INSERT, NOT_IN_EMPTY,
19951                    BIGUNION_EMPTY, UNION_EMPTY, SUBSET_REFL] THEN
19952    REWRITE_TAC [AND_IMP_INTRO, GSYM CONJ_ASSOC] THEN ONCE_REWRITE_TAC [CONJ_SYM] THEN
19953    REWRITE_TAC [GSYM CONJ_ASSOC] THEN REWRITE_TAC [GSYM AND_IMP_INTRO] THEN
19954    DISCH_THEN(fn th => REPEAT DISCH_TAC THEN MP_TAC th) THEN
19955    KNOW_TAC ``(!(s' :real -> bool) (t :real -> bool).
19956               s' IN (f :(real -> bool) -> bool) ==> t IN f ==>
19957               s' SUBSET t \/ t SUBSET s')`` THENL
19958    [ASM_MESON_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
19959    DISCH_THEN(X_CHOOSE_THEN ``j:real->bool`` STRIP_ASSUME_TAC) THEN
19960    SUBGOAL_THEN ``(n DIFF j) SUBSET (n DIFF i) \/
19961                  (n DIFF i:real->bool) SUBSET (n DIFF j)``
19962    STRIP_ASSUME_TAC THENL
19963     [ASM_SET_TAC[],
19964      DISJ1_TAC THEN ASM_SET_TAC[],
19965      DISJ2_TAC THEN EXISTS_TAC ``j:real->bool`` THEN ASM_SET_TAC[]],
19966    ALL_TAC] THEN
19967  SUBGOAL_THEN ``(j INTER k:real->bool) SUBSET (u UNION v)`` ASSUME_TAC THENL
19968   [MATCH_MP_TAC(SET_RULE
19969     ``k SUBSET (u UNION v) UNION (n DIFF j)
19970      ==> (j INTER k) SUBSET (u UNION v)``) THEN
19971    MATCH_MP_TAC SUBSET_TRANS THEN
19972    EXISTS_TAC ``BIGUNION g :real->bool`` THEN ASM_SIMP_TAC std_ss [] THEN
19973    MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC
19974     ``BIGUNION((u UNION v:real->bool) INSERT (g DELETE (u UNION v)))`` THEN
19975    CONJ_TAC THENL [MATCH_MP_TAC SUBSET_BIGUNION THEN SET_TAC[], ALL_TAC] THEN
19976    ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[BIGUNION_INSERT] THEN
19977    ASM_SET_TAC[],
19978    ALL_TAC] THEN
19979  SUBGOAL_THEN ``connected(j INTER k:real->bool)`` MP_TAC THENL
19980   [ASM_MESON_TAC[SET_RULE ``s SUBSET t ==> (s INTER t = s)``, INTER_COMM],
19981    REWRITE_TAC[connected] THEN
19982    MAP_EVERY EXISTS_TAC [``u:real->bool``, ``v:real->bool``] THEN
19983    ASM_REWRITE_TAC[] THEN ASM_SET_TAC[]]);
19984
19985val CONNECTED_CHAIN_GEN = store_thm ("CONNECTED_CHAIN_GEN",
19986 ``!f:(real->bool)->bool.
19987       (!s. s IN f ==> closed s /\ connected s) /\
19988       (?s. s IN f /\ compact s) /\
19989       (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s)
19990       ==> connected(BIGINTER f)``,
19991  GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
19992  FIRST_X_ASSUM(X_CHOOSE_THEN ``s:real->bool`` STRIP_ASSUME_TAC) THEN
19993  SUBGOAL_THEN
19994   ``BIGINTER f = BIGINTER(IMAGE (\t:real->bool. s INTER t) f)``
19995  SUBST1_TAC THENL
19996   [SIMP_TAC std_ss [EXTENSION, BIGINTER_IMAGE] THEN ASM_SET_TAC[],
19997    MATCH_MP_TAC CONNECTED_CHAIN THEN
19998    SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, FORALL_IN_IMAGE] THEN
19999    ASM_SIMP_TAC std_ss [COMPACT_INTER_CLOSED] THEN
20000    CONJ_TAC THENL [X_GEN_TAC ``t:real->bool``, ASM_SET_TAC[]] THEN
20001    DISCH_TAC THEN
20002    SUBGOAL_THEN ``(s INTER t:real->bool = s) \/ (s INTER t = t)``
20003     (DISJ_CASES_THEN SUBST1_TAC) THEN
20004    ASM_SET_TAC[]]);
20005
20006val CONNECTED_NEST = store_thm ("CONNECTED_NEST",
20007 ``!s. (!n. compact(s n) /\ connected(s n)) /\
20008       (!m n. m <= n ==> s n SUBSET s m)
20009       ==> connected(BIGINTER {s n | n IN univ(:num)})``,
20010  GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC CONNECTED_CHAIN THEN
20011  ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM] THEN
20012  ONCE_REWRITE_TAC [METIS [] ``(s n SUBSET s n' \/ s n' SUBSET s n) =
20013                        (\n n'. s n SUBSET s n' \/ s n' SUBSET s n) n n'``] THEN
20014  MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]);
20015
20016val CONNECTED_NEST_GEN = store_thm ("CONNECTED_NEST_GEN",
20017 ``!s. (!n. closed(s n) /\ connected(s n)) /\ (?n. compact(s n)) /\
20018       (!m n. m <= n ==> s n SUBSET s m)
20019       ==> connected(BIGINTER {s n | n IN univ(:num)})``,
20020  GEN_TAC THEN
20021  DISCH_THEN(REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC) THEN
20022  MATCH_MP_TAC CONNECTED_CHAIN_GEN THEN
20023  ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, IN_UNIV, CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM,
20024               EXISTS_IN_GSPEC] THEN
20025  ONCE_REWRITE_TAC [METIS [] ``(s n SUBSET s n' \/ s n' SUBSET s n) =
20026                        (\n n'. s n SUBSET s n' \/ s n' SUBSET s n) n n'``] THEN
20027  MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]);
20028
20029(* ------------------------------------------------------------------------- *)
20030(* Hausdorff distance between sets.                                          *)
20031(* ------------------------------------------------------------------------- *)
20032
20033val hausdist = new_definition ("hausdist",
20034 ``hausdist(s:real->bool,t:real->bool) =
20035        if (({setdist({x},t) | x IN s} UNION {setdist({y},s) | y IN t} <> {}) /\
20036            (?b. !d. d IN {setdist({x},t) | x IN s} UNION {setdist({y},s) | y IN t} ==> d <= b))
20037        then sup ({setdist({x},t) | x IN s} UNION {setdist({y},s) | y IN t}) else &0``);
20038
20039val HAUSDIST_POS_LE = store_thm ("HAUSDIST_POS_LE",
20040 ``!s t:real->bool. &0 <= hausdist(s,t)``,
20041  REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN
20042  SIMP_TAC std_ss [FORALL_IN_GSPEC, FORALL_IN_UNION] THEN
20043  COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN
20044  MATCH_MP_TAC REAL_LE_SUP THEN
20045  ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, FORALL_IN_UNION, SETDIST_POS_LE] THEN
20046  KNOW_TAC ``?(y :real) (b :real).
20047  y IN {setdist ({x},(t :real -> bool)) | x IN (s :real -> bool)} UNION
20048  {setdist ({y},s) | y IN t} /\ (0 :real) <= y /\
20049  (!(x :real). x IN s ==> setdist ({x},t) <= b) /\
20050  !(y :real). y IN t ==> setdist ({y},s) <= b`` THENL
20051  [ALL_TAC, METIS_TAC [SWAP_EXISTS_THM]] THEN
20052  ASM_SIMP_TAC std_ss [RIGHT_EXISTS_AND_THM] THEN
20053  ONCE_REWRITE_TAC [METIS [] ``(0 <= y:real) = (\y. 0 <= y) y``] THEN
20054  MATCH_MP_TAC(SET_RULE
20055   ``~(s = {}) /\ (!x. x IN s ==> P x) ==> ?y. y IN s /\ P y``) THEN
20056  ASM_SIMP_TAC std_ss [FORALL_IN_GSPEC, FORALL_IN_UNION, SETDIST_POS_LE]);
20057
20058val HAUSDIST_REFL = store_thm ("HAUSDIST_REFL",
20059 ``!s:real->bool. hausdist(s,s) = &0``,
20060  GEN_TAC THEN SIMP_TAC std_ss [GSYM REAL_LE_ANTISYM, HAUSDIST_POS_LE] THEN
20061  REWRITE_TAC[hausdist] THEN
20062  COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN
20063  MATCH_MP_TAC REAL_SUP_LE' THEN
20064  SIMP_TAC std_ss [FORALL_IN_GSPEC, FORALL_IN_UNION] THEN
20065  ASM_SIMP_TAC std_ss [SETDIST_SING_IN_SET, REAL_LE_REFL]);
20066
20067val HAUSDIST_SYM = store_thm ("HAUSDIST_SYM",
20068 ``!s t:real->bool. hausdist(s,t) = hausdist(t,s)``,
20069  REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN
20070  GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [UNION_COMM] THEN
20071  REWRITE_TAC[]);
20072
20073val HAUSDIST_EMPTY = store_thm ("HAUSDIST_EMPTY",
20074 ``(!t:real->bool. hausdist ({},t) = &0) /\
20075   (!s:real->bool. hausdist (s,{}) = &0)``,
20076  REWRITE_TAC[hausdist, SETDIST_EMPTY] THEN
20077  REWRITE_TAC[SET_RULE ``{setdist ({x},t) | x IN {}} = {}``, UNION_EMPTY] THEN
20078  REWRITE_TAC[SET_RULE ``({c |x| x IN s} = {}) <=> (s = {})``] THEN
20079  X_GEN_TAC ``s:real->bool`` THEN
20080  ASM_CASES_TAC ``s:real->bool = {}`` THEN ASM_REWRITE_TAC[] THEN
20081  ASM_SIMP_TAC std_ss [SET_RULE ``~(s = {}) ==> ({c |x| x IN s} = {c})``] THEN
20082  REWRITE_TAC[SUP_SING, COND_ID]);
20083
20084val HAUSDIST_SINGS = store_thm ("HAUSDIST_SINGS",
20085 ``!x y:real. hausdist({x},{y}) = dist(x,y)``,
20086  REWRITE_TAC[hausdist, SETDIST_SINGS] THEN
20087  REWRITE_TAC[SET_RULE ``{dist (x,y) | x IN {a}} = {dist (a,y)}``] THEN
20088  ONCE_REWRITE_TAC [METIS [DIST_SYM] ``{dist (x,y)} UNION {dist (y,x)} =
20089                               {dist (x,y)} UNION {dist (x,y)}``] THEN
20090  SIMP_TAC std_ss [UNION_IDEMPOT, SUP_SING, NOT_INSERT_EMPTY] THEN
20091  SIMP_TAC std_ss [IN_SING, UNWIND_FORALL_THM2] THEN
20092  METIS_TAC[REAL_LE_REFL]);
20093
20094val HAUSDIST_EQ = store_thm ("HAUSDIST_EQ",
20095 ``!s t:real->bool s' t':real->bool.
20096        (!b. (!x. x IN s ==> setdist({x},t) <= b) /\
20097             (!y. y IN t ==> setdist({y},s) <= b) <=>
20098             (!x. x IN s' ==> setdist({x},t') <= b) /\
20099             (!y. y IN t' ==> setdist({y},s') <= b))
20100        ==> (hausdist(s,t) = hausdist(s',t'))``,
20101  REPEAT STRIP_TAC THEN REWRITE_TAC[hausdist] THEN
20102  MATCH_MP_TAC(METIS[]
20103   ``(p <=> p') /\ (s = s')
20104    ==> ((if p then s else &0:real) = (if p' then s' else &0:real))``) THEN
20105  CONJ_TAC THENL
20106   [BINOP_TAC THENL
20107     [PURE_REWRITE_TAC[SET_RULE ``(s = {}) <=> !x. x IN s ==> F``],
20108      AP_TERM_TAC THEN ABS_TAC],
20109    MATCH_MP_TAC SUP_EQ] THEN
20110  SIMP_TAC std_ss [FORALL_IN_UNION, FORALL_IN_GSPEC] THEN
20111  ASM_REWRITE_TAC[] THEN
20112  ONCE_REWRITE_TAC [METIS [] ``(a = b) = (~a = ~b:bool)``] THEN
20113  REWRITE_TAC [DE_MORGAN_THM] THEN
20114  SIMP_TAC std_ss [NOT_FORALL_THM, MEMBER_NOT_EMPTY] THEN
20115  REWRITE_TAC[GSYM DE_MORGAN_THM] THEN AP_TERM_TAC THEN EQ_TAC THEN
20116  DISCH_THEN(fn th => POP_ASSUM MP_TAC THEN ASSUME_TAC th) THEN
20117  ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
20118  DISCH_THEN(MP_TAC o SPEC ``-(&1):real``) THEN
20119  SIMP_TAC std_ss [SETDIST_POS_LE, REAL_ARITH ``&0 <= x ==> ~(x <= -(&1:real))``] THEN
20120  SET_TAC[]);
20121
20122val HAUSDIST_TRANSLATION = store_thm ("HAUSDIST_TRANSLATION",
20123 ``!a s t:real->bool.
20124        hausdist(IMAGE (\x. a + x) s,IMAGE (\x. a + x) t) = hausdist(s,t)``,
20125  REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN
20126  SIMP_TAC real_ss [SET_RULE ``{f x | x IN IMAGE g s} = {f(g x) | x IN s}``] THEN
20127  SIMP_TAC real_ss [SET_RULE ``{a + x:real} = IMAGE (\x. a + x) {x}``] THEN
20128  REWRITE_TAC[SETDIST_TRANSLATION]);
20129
20130val HAUSDIST_LINEAR_IMAGE = store_thm ("HAUSDIST_LINEAR_IMAGE",
20131 ``!f:real->real s t.
20132           linear f /\ (!x. abs(f x) = abs x)
20133           ==> (hausdist(IMAGE f s,IMAGE f t) = hausdist(s,t))``,
20134  REPEAT STRIP_TAC THEN
20135  REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN
20136  SIMP_TAC real_ss [SET_RULE ``{f x | x IN IMAGE g s} = {f(g x) | x IN s}``] THEN
20137  ONCE_REWRITE_TAC[SET_RULE ``{(f:real->real) x} = IMAGE f {x}``] THEN
20138  ASM_SIMP_TAC std_ss [SETDIST_LINEAR_IMAGE]);
20139
20140val HAUSDIST_CLOSURE = store_thm ("HAUSDIST_CLOSURE",
20141 ``(!s t:real->bool. hausdist(closure s,t) = hausdist(s,t)) /\
20142   (!s t:real->bool. hausdist(s,closure t) = hausdist(s,t))``,
20143  REPEAT STRIP_TAC THEN MATCH_MP_TAC HAUSDIST_EQ THEN
20144  GEN_TAC THEN BINOP_TAC THEN REWRITE_TAC[SETDIST_CLOSURE] THEN
20145  ONCE_REWRITE_TAC [METIS [] ``setdist ({x},t) <= b <=> (\x. setdist ({x},t) <= b) x``] THEN
20146  PURE_ONCE_REWRITE_TAC[SET_RULE
20147   ``(!x. x IN P ==> Q x) <=> (!x. x IN P ==> (\x. x) x IN {x | Q x})``] THEN
20148  MATCH_MP_TAC FORALL_IN_CLOSURE_EQ THEN
20149  SIMP_TAC std_ss [GSPEC_F, CONTINUOUS_ON_ID, CLOSED_EMPTY] THEN
20150  ONCE_REWRITE_TAC [METIS [] ``setdist ({x},t) = (\x. setdist ({x},t)) x``] THEN
20151  REWRITE_TAC[SET_RULE
20152    ``{x | (f x) <= b:real} =
20153      {x | x IN UNIV /\ (f x) IN {x | x <= b}}``] THEN
20154  MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN
20155  SIMP_TAC std_ss [CLOSED_UNIV, CONTINUOUS_ON_SETDIST] THEN
20156  REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE]);
20157
20158val REAL_HAUSDIST_LE = store_thm ("REAL_HAUSDIST_LE",
20159 ``!s t:real->bool b.
20160        ~(s = {}) /\ ~(t = {}) /\
20161        (!x. x IN s ==> setdist({x},t) <= b) /\
20162        (!y. y IN t ==> setdist({y},s) <= b)
20163        ==> hausdist(s,t) <= b``,
20164  REPEAT STRIP_TAC THEN
20165  REWRITE_TAC[hausdist, SETDIST_SINGS] THEN
20166  ASM_SIMP_TAC real_ss [EMPTY_UNION, SET_RULE ``({f x | x IN s} = {}) <=> (s = {})``] THEN
20167  SIMP_TAC std_ss [FORALL_IN_UNION, FORALL_IN_GSPEC] THEN
20168  COND_CASES_TAC THENL [ALL_TAC, METIS_TAC[]] THEN
20169  MATCH_MP_TAC REAL_SUP_LE' THEN
20170  ASM_SIMP_TAC real_ss [EMPTY_UNION, SET_RULE ``({f x | x IN s} = {}) <=> (s = {})``] THEN
20171  ASM_SIMP_TAC real_ss [FORALL_IN_UNION, FORALL_IN_GSPEC]);
20172
20173val REAL_HAUSDIST_LE_SUMS = store_thm ("REAL_HAUSDIST_LE_SUMS",
20174 ``!s t:real->bool b.
20175        ~(s = {}) /\ ~(t = {}) /\
20176        s SUBSET {y + z | y IN t /\ z IN cball(0,b)} /\
20177        t SUBSET {y + z | y IN s /\ z IN cball(0,b)}
20178        ==> hausdist(s,t) <= b``,
20179  SIMP_TAC real_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD, IN_CBALL_0] THEN
20180  SIMP_TAC real_ss [REAL_ARITH ``(a:real = b + x) <=> (a - b = x)``,
20181              ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN
20182  REWRITE_TAC[GSYM dist] THEN REPEAT STRIP_TAC THEN
20183  MATCH_MP_TAC REAL_HAUSDIST_LE THEN
20184  METIS_TAC[SETDIST_LE_DIST, REAL_LE_TRANS, IN_SING]);
20185
20186val REAL_LE_HAUSDIST = store_thm ("REAL_LE_HAUSDIST",
20187 ``!s t:real->bool a b c z.
20188        ~(s = {}) /\ ~(t = {}) /\
20189        (!x. x IN s ==> setdist({x},t) <= b) /\
20190        (!y. y IN t ==> setdist({y},s) <= c) /\
20191        (z IN s /\ a <= setdist({z},t) \/ z IN t /\ a <= setdist({z},s))
20192        ==> a <= hausdist(s,t)``,
20193  REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
20194  REWRITE_TAC[hausdist, SETDIST_SINGS] THEN
20195  ASM_SIMP_TAC real_ss [EMPTY_UNION, SET_RULE ``({f x | x IN s} = {}) <=> (s = {})``] THEN
20196  SIMP_TAC real_ss [FORALL_IN_UNION, FORALL_IN_GSPEC] THEN COND_CASES_TAC THENL
20197   [MATCH_MP_TAC REAL_LE_SUP THEN
20198    ASM_SIMP_TAC real_ss [EMPTY_UNION, SET_RULE ``({f x | x IN s} = {}) <=> (s = {})``] THEN
20199    SIMP_TAC real_ss [FORALL_IN_UNION, FORALL_IN_GSPEC],
20200    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [NOT_EXISTS_THM]) THEN
20201    ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN
20202    SIMP_TAC real_ss [NOT_FORALL_THM]] THEN
20203  EXISTS_TAC ``max b c:real`` THEN
20204  ASM_SIMP_TAC real_ss [REAL_LE_MAX] THEN ASM_SET_TAC[]);
20205
20206val SETDIST_LE_HAUSDIST = store_thm ("SETDIST_LE_HAUSDIST",
20207 ``!s t:real->bool.
20208        bounded s /\ bounded t ==> setdist(s,t) <= hausdist(s,t)``,
20209  REPEAT STRIP_TAC THEN
20210  ASM_CASES_TAC ``s:real->bool = {}`` THEN
20211  ASM_SIMP_TAC real_ss [SETDIST_EMPTY, HAUSDIST_EMPTY, REAL_LE_REFL] THEN
20212  ASM_CASES_TAC ``t:real->bool = {}`` THEN
20213  ASM_SIMP_TAC real_ss [SETDIST_EMPTY, HAUSDIST_EMPTY, REAL_LE_REFL] THEN
20214  MATCH_MP_TAC REAL_LE_HAUSDIST THEN REWRITE_TAC[CONJ_ASSOC] THEN
20215  ASM_SIMP_TAC real_ss [RIGHT_EXISTS_AND_THM, LEFT_EXISTS_AND_THM] THEN
20216  CONJ_TAC THENL
20217   [ALL_TAC, METIS_TAC[SETDIST_LE_SING, MEMBER_NOT_EMPTY]] THEN
20218  MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN
20219  ASM_REWRITE_TAC[] THEN SIMP_TAC real_ss [bounded_def, FORALL_IN_GSPEC, GSYM dist] THEN
20220  DISCH_THEN(X_CHOOSE_TAC ``b:real``) THEN
20221  CONJ_TAC THEN EXISTS_TAC ``b:real`` THEN REPEAT STRIP_TAC THEN
20222  METIS_TAC[REAL_LE_TRANS, SETDIST_LE_DIST, MEMBER_NOT_EMPTY, IN_SING, DIST_SYM]);
20223
20224val SETDIST_SING_LE_HAUSDIST = store_thm ("SETDIST_SING_LE_HAUSDIST",
20225 ``!s t x:real.
20226        bounded s /\ bounded t /\ x IN s ==> setdist({x},t) <= hausdist(s,t)``,
20227  REPEAT GEN_TAC THEN
20228  ASM_CASES_TAC ``s:real->bool = {}`` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
20229  ASM_CASES_TAC ``t:real->bool = {}`` THEN
20230  ASM_REWRITE_TAC[SETDIST_EMPTY, HAUSDIST_EMPTY, REAL_LE_REFL] THEN
20231  STRIP_TAC THEN MATCH_MP_TAC REAL_LE_HAUSDIST THEN
20232  ASM_SIMP_TAC real_ss [RIGHT_EXISTS_AND_THM] THEN
20233  SIMP_TAC real_ss [LEFT_EXISTS_AND_THM, EXISTS_OR_THM, CONJ_ASSOC] THEN
20234  CONJ_TAC THENL [ALL_TAC, ASM_MESON_TAC[REAL_LE_REFL]] THEN CONJ_TAC THEN
20235  MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN
20236  ASM_REWRITE_TAC[] THEN SIMP_TAC real_ss [bounded_def, FORALL_IN_GSPEC] THEN
20237  DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN
20238  POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM dist] THENL
20239   [ALL_TAC,
20240    KNOW_TAC ``(!y x:real. x IN s /\ y IN t ==> dist (x,y) <= a) ==>
20241                !y. y IN t ==> setdist ({y},s) <= a`` THENL
20242    [ALL_TAC, METIS_TAC [SWAP_FORALL_THM]]] THEN
20243  DISCH_TAC THEN X_GEN_TAC ``y:real`` THEN POP_ASSUM (MP_TAC o SPEC ``y:real``) THEN
20244  REPEAT STRIP_TAC THENL
20245   [UNDISCH_TAC ``~(t:real->bool = {})``,
20246    UNDISCH_TAC ``~(s:real->bool = {})``] THEN
20247  REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
20248  DISCH_THEN(X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC) THEN
20249  FIRST_X_ASSUM(MP_TAC o SPEC ``z:real``) THEN ASM_REWRITE_TAC[] THEN
20250  MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] REAL_LE_TRANS) THENL
20251   [ALL_TAC, ONCE_REWRITE_TAC[DIST_SYM]] THEN
20252  MATCH_MP_TAC SETDIST_LE_DIST THEN ASM_REWRITE_TAC[IN_SING]);
20253
20254val SETDIST_HAUSDIST_TRIANGLE = store_thm ("SETDIST_HAUSDIST_TRIANGLE",
20255 ``!s t u:real->bool.
20256        ~(t = {}) /\ bounded t /\ bounded u
20257        ==> setdist(s,u) <= setdist(s,t) + hausdist(t,u)``,
20258  REPEAT STRIP_TAC THEN
20259  MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``u:real->bool = {}``] THEN
20260  ASM_SIMP_TAC real_ss [SETDIST_EMPTY, REAL_LE_ADD, REAL_ADD_LID,
20261                        SETDIST_POS_LE, HAUSDIST_POS_LE] THEN
20262  ONCE_REWRITE_TAC[REAL_ARITH ``a <= b + c <=> a - c <= b:real``] THEN
20263  ASM_SIMP_TAC real_ss [REAL_LE_SETDIST_EQ, NOT_INSERT_EMPTY, IN_SING] THEN
20264  MAP_EVERY X_GEN_TAC [``x:real``, ``y:real``] THEN STRIP_TAC THEN
20265  REWRITE_TAC[REAL_LE_SUB_RADD] THEN
20266  MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``setdist({x:real},u)`` THEN
20267  ASM_SIMP_TAC real_ss [SETDIST_LE_SING] THEN
20268  MP_TAC(ISPECL [``u:real->bool``, ``x:real``, ``y:real``]
20269        SETDIST_SING_TRIANGLE) THEN
20270  MATCH_MP_TAC(REAL_ARITH
20271   ``yu <= z ==> abs(xu - yu) <= d ==> xu <= d + z:real``) THEN
20272  MATCH_MP_TAC SETDIST_SING_LE_HAUSDIST THEN ASM_REWRITE_TAC[]);
20273
20274val HAUSDIST_SETDIST_TRIANGLE = store_thm ("HAUSDIST_SETDIST_TRIANGLE",
20275 ``!s t u:real->bool.
20276        ~(t = {}) /\ bounded s /\ bounded t
20277        ==> setdist(s,u) <= hausdist(s,t) + setdist(t,u)``,
20278  ONCE_REWRITE_TAC[SETDIST_SYM, HAUSDIST_SYM] THEN
20279  ONCE_REWRITE_TAC[REAL_ADD_SYM] THEN
20280  SIMP_TAC real_ss [SETDIST_HAUSDIST_TRIANGLE]);
20281
20282val REAL_LT_HAUSDIST_POINT_EXISTS = store_thm ("REAL_LT_HAUSDIST_POINT_EXISTS",
20283 ``!s t x:real d.
20284        bounded s /\ bounded t /\ ~(t = {}) /\ hausdist(s,t) < d /\ x IN s
20285        ==> ?y. y IN t /\ dist(x,y) < d``,
20286  REPEAT STRIP_TAC THEN
20287  MP_TAC(ISPECL [``{x:real}``, ``t:real->bool``, ``d:real``]
20288        REAL_SETDIST_LT_EXISTS) THEN
20289  SIMP_TAC real_ss [IN_SING, RIGHT_EXISTS_AND_THM, UNWIND_THM2] THEN
20290  DISCH_THEN MATCH_MP_TAC THEN
20291  ASM_REWRITE_TAC[NOT_INSERT_EMPTY] THEN
20292  MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC ``hausdist(s:real->bool,t)`` THEN
20293  ASM_SIMP_TAC real_ss [] THEN MATCH_MP_TAC SETDIST_SING_LE_HAUSDIST THEN
20294  ASM_REWRITE_TAC[]);
20295
20296val UPPER_LOWER_HEMICONTINUOUS = store_thm ("UPPER_LOWER_HEMICONTINUOUS",
20297 ``!f:real->real->bool t s.
20298      (!x. x IN s ==> f(x) SUBSET t) /\
20299      (!u. open_in (subtopology euclidean t) u
20300           ==> open_in (subtopology euclidean s)
20301                       {x | x IN s /\ f(x) SUBSET u}) /\
20302      (!u. closed_in (subtopology euclidean t) u
20303           ==> closed_in (subtopology euclidean s)
20304                         {x | x IN s /\ f(x) SUBSET u})
20305      ==> !x e. x IN s /\ &0 < e /\ bounded(f x)
20306                ==> ?d. &0 < d /\
20307                        !x'. x' IN s /\ dist(x,x') < d
20308                             ==> hausdist(f x,f x') < e``,
20309  REPEAT GEN_TAC THEN DISCH_TAC THEN REPEAT STRIP_TAC THEN
20310  ASM_CASES_TAC ``(f:real->real->bool) x = {}`` THENL
20311   [ASM_REWRITE_TAC[HAUSDIST_EMPTY] THEN METIS_TAC[REAL_LT_01], ALL_TAC] THEN
20312  FIRST_ASSUM(MP_TAC o SPECL [``x:real``, ``e / &2:real``] o MATCH_MP
20313        UPPER_LOWER_HEMICONTINUOUS_EXPLICIT) THEN
20314  ASM_REWRITE_TAC[REAL_HALF] THEN
20315  DISCH_THEN(X_CHOOSE_THEN ``d1:real`` STRIP_ASSUME_TAC) THEN
20316  FIRST_ASSUM(MP_TAC o SPEC ``0:real`` o MATCH_MP BOUNDED_SUBSET_BALL) THEN
20317  DISCH_THEN(X_CHOOSE_THEN ``r:real`` STRIP_ASSUME_TAC) THEN
20318  FIRST_ASSUM(MP_TAC o SPEC ``t INTER ball(0:real,r)`` o
20319        CONJUNCT1 o CONJUNCT2) THEN
20320  SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_BALL] THEN REWRITE_TAC[open_in] THEN
20321  DISCH_THEN(MP_TAC o SPEC ``x:real`` o CONJUNCT2) THEN
20322  ASM_SIMP_TAC std_ss [SUBSET_INTER, GSPECIFICATION] THEN
20323  DISCH_THEN(X_CHOOSE_THEN ``d2:real`` STRIP_ASSUME_TAC) THEN
20324  EXISTS_TAC ``min d1 d2:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
20325  X_GEN_TAC ``x':real`` THEN STRIP_TAC THEN
20326  REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC ``x':real``)) THEN
20327  ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN ASM_SIMP_TAC std_ss [] THEN
20328  STRIP_TAC THEN STRIP_TAC THEN
20329  ASM_CASES_TAC ``(f:real->real->bool) x' = {}`` THEN
20330  ASM_REWRITE_TAC[HAUSDIST_EMPTY] THEN
20331  KNOW_TAC ``0 < e / 2:real`` THENL [ASM_REWRITE_TAC [REAL_HALF], DISCH_TAC] THEN
20332  GEN_REWR_TAC RAND_CONV [GSYM REAL_HALF] THEN
20333  MATCH_MP_TAC(REAL_ARITH ``&0 < e / 2 /\ x <= e / &2 ==> x < e / 2 + e / 2:real``) THEN
20334  ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_HAUSDIST_LE THEN
20335  METIS_TAC[SETDIST_LE_DIST, DIST_SYM, REAL_LE_TRANS,
20336                IN_SING, REAL_LT_IMP_LE]);
20337
20338val HAUSDIST_NONTRIVIAL = store_thm ("HAUSDIST_NONTRIVIAL",
20339 ``!s t:real->bool.
20340        bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {})
20341        ==> (hausdist(s,t) =
20342             sup({setdist ({x},t) | x IN s} UNION {setdist ({y},s) | y IN t}))``,
20343  REPEAT STRIP_TAC THEN REWRITE_TAC[hausdist] THEN
20344  COND_CASES_TAC THEN ASM_SIMP_TAC real_ss [] THEN
20345  FIRST_X_ASSUM(MP_TAC o SIMP_RULE real_ss [DE_MORGAN_THM]) THEN
20346  ASM_SIMP_TAC real_ss [EMPTY_UNION, GSYM IMAGE_DEF, IMAGE_EQ_EMPTY] THEN
20347  REWRITE_TAC [METIS [] ``(!b. ?d. d IN P /\ ~(d <= b)) =
20348                              ~(?b. !d. d IN P ==> d <= b:real)``] THEN
20349  MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN
20350  MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN
20351  ASM_SIMP_TAC real_ss [bounded_def, FORALL_IN_UNION, FORALL_IN_IMAGE, GSYM dist] THEN
20352  DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN POP_ASSUM MP_TAC THEN
20353  SIMP_TAC real_ss [FORALL_IN_GSPEC] THEN
20354  METIS_TAC[SETDIST_LE_DIST, dist, DIST_SYM, REAL_LE_TRANS,
20355                MEMBER_NOT_EMPTY, IN_SING]);
20356
20357val HAUSDIST_NONTRIVIAL_ALT = store_thm ("HAUSDIST_NONTRIVIAL_ALT",
20358 ``!s t:real->bool.
20359        bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {})
20360        ==> (hausdist(s,t) = max (sup {setdist ({x},t) | x IN s})
20361                                (sup {setdist ({y},s) | y IN t}))``,
20362  REPEAT STRIP_TAC THEN ASM_SIMP_TAC real_ss [HAUSDIST_NONTRIVIAL] THEN
20363  MATCH_MP_TAC SUP_UNION THEN
20364  ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, FORALL_IN_IMAGE, IMAGE_EQ_EMPTY] THEN
20365  CONJ_TAC THEN
20366  MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN
20367  ASM_SIMP_TAC real_ss [bounded_def, FORALL_IN_UNION, FORALL_IN_IMAGE, GSYM dist] THEN
20368  DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN
20369  POP_ASSUM MP_TAC THEN SIMP_TAC real_ss [FORALL_IN_GSPEC, GSYM dist] THEN
20370  METIS_TAC [SETDIST_LE_DIST, dist, DIST_SYM, REAL_LE_TRANS,
20371                MEMBER_NOT_EMPTY, IN_SING]);
20372
20373val REAL_HAUSDIST_LE_EQ = store_thm ("REAL_HAUSDIST_LE_EQ",
20374 ``!s t:real->bool b.
20375        ~(s = {}) /\ ~(t = {}) /\ bounded s /\ bounded t
20376        ==> (hausdist(s,t) <= b <=>
20377             (!x. x IN s ==> setdist({x},t) <= b) /\
20378             (!y. y IN t ==> setdist({y},s) <= b))``,
20379  REPEAT STRIP_TAC THEN
20380  ASM_SIMP_TAC real_ss [HAUSDIST_NONTRIVIAL_ALT, REAL_MAX_LE] THEN
20381  BINOP_TAC THEN
20382  ONCE_REWRITE_TAC [METIS [] ``setdist ({x},t) = (\x. setdist ({x},t)) x:real``] THEN
20383  ONCE_REWRITE_TAC [SET_RULE ``(!x. x IN s ==> f x <= b) <=>
20384                               (!y. y IN {f x | x IN s} ==> y <= b:real)``] THEN
20385  MATCH_MP_TAC REAL_SUP_LE_EQ THEN
20386  ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, IMAGE_EQ_EMPTY, FORALL_IN_IMAGE] THEN
20387  MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN
20388  ASM_SIMP_TAC real_ss [bounded_def, FORALL_IN_UNION, FORALL_IN_IMAGE, GSYM dist] THEN
20389  DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN
20390  POP_ASSUM MP_TAC THEN SIMP_TAC real_ss [FORALL_IN_GSPEC, GSYM dist] THEN
20391  METIS_TAC[SETDIST_LE_DIST, dist, DIST_SYM, REAL_LE_TRANS,
20392                MEMBER_NOT_EMPTY, IN_SING]);
20393
20394val HAUSDIST_UNION_LE = store_thm ("HAUSDIST_UNION_LE",
20395 ``!s t u:real->bool.
20396        bounded s /\ bounded t /\ bounded u /\ ~(t = {}) /\ ~(u = {})
20397        ==> hausdist(s UNION t,s UNION u) <= hausdist(t,u)``,
20398  REPEAT STRIP_TAC THEN
20399  ASM_SIMP_TAC real_ss [REAL_HAUSDIST_LE_EQ, BOUNDED_UNION, EMPTY_UNION] THEN
20400  SIMP_TAC real_ss [FORALL_IN_UNION] THEN
20401  SIMP_TAC real_ss [SETDIST_SING_IN_SET, IN_UNION, HAUSDIST_POS_LE] THEN
20402  ASM_SIMP_TAC real_ss [GSYM REAL_HAUSDIST_LE_EQ, BOUNDED_UNION, EMPTY_UNION] THEN
20403  CONJ_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THENL
20404   [MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``setdist({x:real},u)``,
20405    MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``setdist({x:real},t)``] THEN
20406  ASM_SIMP_TAC real_ss [SETDIST_SUBSET_RIGHT, SUBSET_UNION] THENL
20407   [ALL_TAC, ONCE_REWRITE_TAC[HAUSDIST_SYM]] THEN
20408  MATCH_MP_TAC SETDIST_SING_LE_HAUSDIST THEN ASM_REWRITE_TAC[]);
20409
20410val HAUSDIST_INSERT_LE = store_thm ("HAUSDIST_INSERT_LE",
20411 ``!s t a:real.
20412        bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {})
20413        ==> hausdist(a INSERT s,a INSERT t) <= hausdist(s,t)``,
20414  ONCE_REWRITE_TAC[SET_RULE ``a INSERT s = {a} UNION s``] THEN
20415  ASM_SIMP_TAC real_ss [HAUSDIST_UNION_LE, NOT_INSERT_EMPTY, BOUNDED_SING]);
20416
20417val HAUSDIST_COMPACT_EXISTS = store_thm ("HAUSDIST_COMPACT_EXISTS",
20418 ``!s t:real->bool.
20419        bounded s /\ compact t /\ ~(t = {})
20420        ==> !x. x IN s ==> ?y. y IN t /\ dist(x,y) <= hausdist(s,t)``,
20421  REPEAT STRIP_TAC THEN
20422  ASM_CASES_TAC ``s:real->bool = {}`` THENL [ASM_SET_TAC[], ALL_TAC] THEN
20423  MP_TAC(ISPECL [``{x:real}``, ``t:real->bool``]
20424        SETDIST_COMPACT_CLOSED) THEN
20425  ASM_SIMP_TAC real_ss [COMPACT_SING, COMPACT_IMP_CLOSED, NOT_INSERT_EMPTY] THEN
20426  SIMP_TAC real_ss [IN_SING, UNWIND_THM2, RIGHT_EXISTS_AND_THM, UNWIND_THM1] THEN
20427  DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN POP_ASSUM MP_TAC THEN
20428  REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
20429  MATCH_MP_TAC REAL_LE_HAUSDIST THEN
20430  ASM_SIMP_TAC real_ss [LEFT_EXISTS_AND_THM, RIGHT_EXISTS_AND_THM] THEN
20431  REWRITE_TAC[CONJ_ASSOC] THEN
20432  CONJ_TAC THENL [CONJ_TAC, METIS_TAC[REAL_LE_REFL]] THEN
20433  MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``] BOUNDED_DIFFS) THEN
20434  ASM_SIMP_TAC real_ss [COMPACT_IMP_BOUNDED] THEN
20435  SIMP_TAC real_ss [bounded_def, FORALL_IN_GSPEC, GSYM dist] THEN
20436  DISCH_THEN (X_CHOOSE_TAC ``a:real``) THEN EXISTS_TAC ``a:real`` THEN
20437  METIS_TAC[SETDIST_LE_DIST, dist, DIST_SYM, REAL_LE_TRANS,
20438                MEMBER_NOT_EMPTY, IN_SING]);
20439
20440val HAUSDIST_TRIANGLE = store_thm ("HAUSDIST_TRIANGLE",
20441 ``!s t u:real->bool.
20442        bounded s /\ bounded t /\ bounded u /\ ~(t = {})
20443        ==> hausdist(s,u) <= hausdist(s,t) + hausdist(t,u)``,
20444  ONCE_REWRITE_TAC[GSYM(CONJUNCT1 HAUSDIST_CLOSURE)] THEN
20445  ONCE_REWRITE_TAC[GSYM(CONJUNCT2 HAUSDIST_CLOSURE)] THEN
20446  ONCE_REWRITE_TAC[GSYM COMPACT_CLOSURE, GSYM CLOSURE_EQ_EMPTY] THEN
20447  REPEAT GEN_TAC THEN MAP_EVERY
20448   (fn t => SPEC_TAC(mk_comb(``closure:(real->bool)->real->bool``,t),t))
20449   [``u:real->bool``, ``t:real->bool``, ``s:real->bool``] THEN
20450  REPEAT STRIP_TAC THEN ASM_CASES_TAC ``s:real->bool = {}`` THEN
20451  ASM_REWRITE_TAC[HAUSDIST_EMPTY, HAUSDIST_POS_LE, REAL_ADD_LID] THEN
20452  ASM_CASES_TAC ``u:real->bool = {}`` THEN
20453  ASM_REWRITE_TAC[HAUSDIST_EMPTY, HAUSDIST_POS_LE, REAL_ADD_RID] THEN
20454  ASM_SIMP_TAC real_ss [REAL_HAUSDIST_LE_EQ, COMPACT_IMP_BOUNDED] THEN
20455  GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [HAUSDIST_SYM] THEN
20456  GEN_REWR_TAC (RAND_CONV o ONCE_DEPTH_CONV) [REAL_ADD_SYM] THEN
20457  POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
20458   MAP_EVERY (fn t => SPEC_TAC(t,t))
20459   [``u:real->bool``, ``t:real->bool``, ``s:real->bool``] THEN
20460  ONCE_REWRITE_TAC [METIS [] ``(~(u = {}) /\ ~(s = {}) /\ ~(t = {}) /\
20461                                compact u /\ compact t /\ compact s) =
20462                       (\s t u. ~(u = {}) /\ ~(s = {}) /\ ~(t = {}) /\
20463                                compact u /\ compact t /\ compact s) s t u``] THEN
20464  ONCE_REWRITE_TAC [METIS [] ``(!x. x IN s ==> setdist ({x},u) <=
20465                                hausdist (s,t) + hausdist (t,u)) =
20466                       (\s t u. !x. x IN s ==> setdist ({x},u) <=
20467                                hausdist (s,t) + hausdist (t,u)) s t u ``] THEN
20468  MATCH_MP_TAC(METIS[]
20469   ``(!s t u. P s t u ==> P u t s) /\
20470     (!s t u. P s t u ==> Q s t u)
20471     ==> (!s t u. P s t u ==> Q s t u /\ Q u t s)``) THEN BETA_TAC THEN
20472  CONJ_TAC THENL [METIS_TAC[CONJ_ACI], REPEAT GEN_TAC THEN STRIP_TAC] THEN
20473  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
20474  SUBGOAL_THEN ``?y:real. y IN t /\ dist(x,y) <= hausdist(s,t)``
20475  STRIP_ASSUME_TAC THENL
20476   [METIS_TAC[HAUSDIST_COMPACT_EXISTS, COMPACT_IMP_BOUNDED], ALL_TAC] THEN
20477  SUBGOAL_THEN ``?z:real. z IN u /\ dist(y,z) <= hausdist(t,u)``
20478  STRIP_ASSUME_TAC THENL
20479   [METIS_TAC[HAUSDIST_COMPACT_EXISTS, COMPACT_IMP_BOUNDED], ALL_TAC] THEN
20480  RULE_ASSUM_TAC (REWRITE_RULE [dist]) THEN
20481  FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
20482   ``abs(y - z) <= b ==> abs(x - y) <= a /\ s <= abs(x - z) ==> s <= a + b:real``)) THEN
20483  ASM_REWRITE_TAC[GSYM dist] THEN MATCH_MP_TAC SETDIST_LE_DIST THEN
20484  ASM_REWRITE_TAC[IN_SING]);
20485
20486val HAUSDIST_COMPACT_SUMS = store_thm ("HAUSDIST_COMPACT_SUMS",
20487 ``!s t:real->bool.
20488        bounded s /\ compact t /\ ~(t = {})
20489        ==> s SUBSET {y + z | y IN t /\ z IN cball(0,hausdist(s,t))}``,
20490  SIMP_TAC real_ss [SUBSET_DEF, GSPECIFICATION, IN_CBALL_0, EXISTS_PROD] THEN
20491  SIMP_TAC real_ss [REAL_ARITH ``(a:real = b + x) <=> (a - b = x)``,
20492              ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN
20493  SIMP_TAC real_ss [GSYM dist, HAUSDIST_COMPACT_EXISTS]);
20494
20495val lemma = prove (
20496 ``!s t u:real->bool.
20497          bounded s /\ bounded t /\ bounded u /\
20498          ~(s = {}) /\ ~(t = {}) /\ ~(u = {})
20499          ==> !x. x IN s ==> setdist({x},u) <= hausdist(s,t) + hausdist(t,u)``,
20500    REPEAT STRIP_TAC THEN
20501    MP_TAC(ISPECL [``closure s:real->bool``, ``closure t:real->bool``]
20502        HAUSDIST_COMPACT_EXISTS) THEN
20503    ASM_SIMP_TAC real_ss [COMPACT_CLOSURE, BOUNDED_CLOSURE, CLOSURE_EQ_EMPTY] THEN
20504    DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN
20505    ASM_SIMP_TAC real_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET, HAUSDIST_CLOSURE] THEN
20506    DISCH_THEN(X_CHOOSE_THEN ``y:real`` STRIP_ASSUME_TAC) THEN
20507    MP_TAC(ISPECL [``closure t:real->bool``, ``closure u:real->bool``]
20508      HAUSDIST_COMPACT_EXISTS) THEN
20509    ASM_SIMP_TAC real_ss [COMPACT_CLOSURE, BOUNDED_CLOSURE, CLOSURE_EQ_EMPTY] THEN
20510    DISCH_THEN(MP_TAC o SPEC ``y:real``) THEN
20511    ASM_SIMP_TAC real_ss [REWRITE_RULE[SUBSET_DEF] CLOSURE_SUBSET, HAUSDIST_CLOSURE] THEN
20512    DISCH_THEN(X_CHOOSE_THEN ``z:real`` STRIP_ASSUME_TAC) THEN
20513    MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``dist(x:real,z)`` THEN CONJ_TAC THENL
20514     [METIS_TAC[SETDIST_CLOSURE, SETDIST_LE_DIST, IN_SING], ALL_TAC] THEN
20515    MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``dist(x:real,y) + dist(y,z)`` THEN
20516    REWRITE_TAC[DIST_TRIANGLE] THEN ASM_REAL_ARITH_TAC);
20517
20518val HAUSDIST_TRANS = store_thm ("HAUSDIST_TRANS",
20519 ``!s t u:real->bool.
20520        bounded s /\ bounded t /\ bounded u /\ ~(t = {})
20521        ==> hausdist(s,u) <= hausdist(s,t) + hausdist(t,u)``,
20522  REPEAT STRIP_TAC THEN
20523  ASM_CASES_TAC ``s:real->bool = {}`` THEN
20524  ASM_REWRITE_TAC[HAUSDIST_EMPTY, REAL_ADD_LID, HAUSDIST_POS_LE] THEN
20525  ASM_CASES_TAC ``u:real->bool = {}`` THEN
20526  ASM_REWRITE_TAC[HAUSDIST_EMPTY, REAL_ADD_RID, HAUSDIST_POS_LE] THEN
20527  ASM_SIMP_TAC real_ss [REAL_HAUSDIST_LE_EQ] THEN
20528  ASM_MESON_TAC[lemma, HAUSDIST_SYM, SETDIST_SYM, REAL_ADD_SYM]);
20529
20530val HAUSDIST_EQ_0 = store_thm ("HAUSDIST_EQ_0",
20531 ``!s t:real->bool.
20532      bounded s /\ bounded t
20533      ==> ((hausdist(s,t) = &0) <=> (s = {}) \/ (t = {}) \/ (closure s = closure t))``,
20534  REPEAT STRIP_TAC THEN
20535  MAP_EVERY ASM_CASES_TAC [``s:real->bool = {}``, ``t:real->bool = {}``] THEN
20536  ASM_REWRITE_TAC[HAUSDIST_EMPTY] THEN
20537  ASM_SIMP_TAC real_ss [GSYM REAL_LE_ANTISYM, HAUSDIST_POS_LE, REAL_HAUSDIST_LE_EQ] THEN
20538  SIMP_TAC real_ss [SETDIST_POS_LE, REAL_ARITH ``&0 <= x ==> (x <= &0 <=> (x = &0:real))``] THEN
20539  ASM_SIMP_TAC real_ss [SETDIST_EQ_0_SING, GSYM SUBSET_ANTISYM_EQ, SUBSET_DEF] THEN
20540  SIMP_TAC std_ss [FORALL_IN_CLOSURE_EQ, CLOSED_CLOSURE, CONTINUOUS_ON_ID]);
20541
20542val HAUSDIST_COMPACT_NONTRIVIAL = store_thm ("HAUSDIST_COMPACT_NONTRIVIAL",
20543 ``!s t:real->bool.
20544        compact s /\ compact t /\ ~(s = {}) /\ ~(t = {})
20545        ==> (hausdist(s,t) =
20546            inf {e | &0 <= e /\
20547                   s SUBSET {x + y | x IN t /\ abs y <= e} /\
20548                   t SUBSET {x + y | x IN s /\ abs y <= e}})``,
20549  REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
20550  MATCH_MP_TAC REAL_INF_UNIQUE THEN
20551  SIMP_TAC real_ss [FORALL_IN_GSPEC, EXISTS_IN_GSPEC] THEN
20552  SIMP_TAC real_ss [SUBSET_DEF, GSPECIFICATION, EXISTS_PROD] THEN
20553  SIMP_TAC real_ss [REAL_ARITH ``(a:real = b + x) <=> (a - b = x)``,
20554              ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN
20555  REWRITE_TAC[GSYM dist] THEN CONJ_TAC THENL
20556   [REPEAT STRIP_TAC THEN
20557    MATCH_MP_TAC REAL_HAUSDIST_LE THEN
20558    METIS_TAC[SETDIST_LE_DIST, DIST_SYM, REAL_LE_TRANS,
20559              IN_SING, REAL_LT_IMP_LE],
20560    REPEAT STRIP_TAC THEN EXISTS_TAC ``hausdist(s:real->bool,t)`` THEN
20561    ASM_REWRITE_TAC[HAUSDIST_POS_LE] THEN
20562    METIS_TAC[DIST_SYM, HAUSDIST_SYM,
20563                  HAUSDIST_COMPACT_EXISTS, COMPACT_IMP_BOUNDED]]);
20564
20565Theorem HAUSDIST_BALLS :
20566   (!a b:real r s.
20567        hausdist(ball(a,r),ball(b,s)) =
20568        if r <= &0 \/ s <= &0 then &0 else dist(a,b) + abs(r - s)) /\
20569   (!a b:real r s.
20570        hausdist(ball(a,r),cball(b,s)) =
20571        if r <= &0 \/ s < &0 then &0 else dist(a,b) + abs(r - s)) /\
20572   (!a b:real r s.
20573        hausdist(cball(a,r),ball(b,s)) =
20574        if r < &0 \/ s <= &0 then &0 else dist(a,b) + abs(r - s)) /\
20575   (!a b:real r s.
20576        hausdist(cball(a,r),cball(b,s)) =
20577        if r < &0 \/ s < &0 then &0 else dist(a,b) + abs(r - s))
20578Proof
20579  REWRITE_TAC[METIS[]
20580   ``(x = if p then y else z) <=> (p ==> (x = y)) /\ (~p ==> (x = z))``] THEN
20581  SIMP_TAC real_ss [TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN
20582  SIMP_TAC real_ss [BALL_EMPTY, CBALL_EMPTY, HAUSDIST_EMPTY, DE_MORGAN_THM] THEN
20583  ONCE_REWRITE_TAC[METIS[HAUSDIST_CLOSURE]
20584   ``hausdist(s,t) = hausdist(closure s,closure t)``] THEN
20585  SIMP_TAC real_ss [REAL_NOT_LE, REAL_NOT_LT, CLOSURE_BALL] THEN
20586  REWRITE_TAC[HAUSDIST_CLOSURE] THEN
20587  MATCH_MP_TAC(TAUT `(s ==> p /\ q /\ r) /\ s ==> p /\ q /\ r /\ s`) THEN
20588  CONJ_TAC THENL [MESON_TAC[REAL_LT_IMP_LE], REPEAT STRIP_TAC] THEN
20589  ASM_SIMP_TAC real_ss [HAUSDIST_NONTRIVIAL, BOUNDED_CBALL, CBALL_EQ_EMPTY,
20590               REAL_NOT_LT] THEN
20591  MATCH_MP_TAC SUP_UNIQUE THEN
20592  SIMP_TAC real_ss [FORALL_IN_GSPEC, FORALL_IN_UNION] THEN
20593  REWRITE_TAC[MESON[CBALL_SING] ``{a} = cball(a:real,&0)``] THEN
20594  ASM_REWRITE_TAC[SETDIST_BALLS, REAL_LT_REFL] THEN
20595  X_GEN_TAC ``c:real`` THEN REWRITE_TAC[IN_CBALL] THEN
20596  reverse EQ_TAC
20597  >- (RW_TAC real_ss [dist, max_def] \\
20598     `~(r < 0)` by PROVE_TAC [real_lte] >> rw [] \\
20599      REAL_ASM_ARITH_TAC) THEN
20600  ASM_CASES_TAC ``b:real = a`` THENL
20601  [ (* goal 1 (of 2) *)
20602    ONCE_ASM_REWRITE_TAC [DIST_SYM] THEN ASM_REWRITE_TAC[DIST_REFL, REAL_MAX_LE] THEN
20603    DISCH_THEN(CONJUNCTS_THEN2
20604     (MP_TAC o SPEC ``a + r * 1:real``)
20605     (MP_TAC o SPEC ``a + s * 1:real``)) THEN
20606    REWRITE_TAC[dist, REAL_ARITH ``abs(a:real - (a + x)) = abs x``] THEN
20607    SIMP_TAC real_ss [ABS_MUL, LESS_EQ_REFL, max_def] \\
20608   `~(r < 0)` by PROVE_TAC [real_lte] >> rw [] \\
20609    ASM_REAL_ARITH_TAC,
20610    (* goal 2 (of 2) *)
20611    DISCH_THEN(CONJUNCTS_THEN2
20612     (MP_TAC o SPEC ``a - r / dist(a,b) * (b - a):real``)
20613     (MP_TAC o SPEC ``b - s / dist(a,b) * (a - b):real``)) THEN
20614    REWRITE_TAC[dist, REAL_ARITH ``abs(a:real - (a - x)) = abs x``] THEN
20615    REWRITE_TAC[dist, ABS_MUL, REAL_ARITH
20616     ``b - e * (a - b) - a:real = (&1 + e) * (b - a)``] THEN
20617    ONCE_REWRITE_TAC [METIS [ABS_ABS] ``abs x * abs (a - b) =
20618                                        abs x * abs (abs (a - b:real))``] THEN
20619    REWRITE_TAC[GSYM ABS_MUL] THEN REWRITE_TAC[ABS_ABS] THEN
20620    ONCE_REWRITE_TAC [METIS [ABS_SUB] ``r / abs (a - b) * abs (b - a) =
20621                                   r / abs (a - b) * abs (a - b:real)``] THEN
20622    REWRITE_TAC[REAL_ADD_RDISTRIB, REAL_MUL_LID] THEN
20623    RULE_ASSUM_TAC (ONCE_REWRITE_RULE [REAL_ARITH ``(b <> a) = (abs (a - b) <> 0:real)``]) THEN
20624    ONCE_REWRITE_TAC [METIS [ABS_SUB] ``r / abs (a - b) * abs (b - a) =
20625                                   r / abs (a - b) * abs (a - b:real)``] THEN
20626    ASM_SIMP_TAC real_ss [REAL_DIV_RMUL, ABS_ZERO, REAL_SUB_0, max_def] THEN
20627   `~(r < 0)` by PROVE_TAC [real_lte] >> rw [] \\
20628    ASM_REAL_ARITH_TAC ]
20629QED
20630
20631val HAUSDIST_ALT = store_thm ("HAUSDIST_ALT",
20632 ``!s t:real->bool.
20633        bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {})
20634        ==> (hausdist(s,t) =
20635             sup {abs(setdist({x},s) - setdist({x},t)) | x IN univ(:real)})``,
20636  REPEAT GEN_TAC THEN
20637  ONCE_REWRITE_TAC[GSYM COMPACT_CLOSURE, GSYM(CONJUNCT2 SETDIST_CLOSURE),
20638    GSYM CLOSURE_EQ_EMPTY, METIS[HAUSDIST_CLOSURE]
20639    ``hausdist(s:real->bool,t) = hausdist(closure s,closure t)``] THEN
20640  SPEC_TAC(``closure t:real->bool``,``t:real->bool``) THEN
20641  SPEC_TAC(``closure s:real->bool``,``s:real->bool``) THEN
20642  REPEAT STRIP_TAC THEN
20643  ASM_SIMP_TAC real_ss [HAUSDIST_NONTRIVIAL, COMPACT_IMP_BOUNDED] THEN
20644  MATCH_MP_TAC SUP_EQ THEN
20645  SIMP_TAC real_ss [FORALL_IN_UNION, FORALL_IN_GSPEC, IN_UNIV] THEN
20646  REWRITE_TAC[REAL_ARITH ``abs(y - x) <= b <=> x <= y + b /\ y <= x + b:real``] THEN
20647  GEN_TAC THEN SIMP_TAC real_ss [FORALL_AND_THM] THEN BINOP_TAC THEN
20648  (EQ_TAC THENL [ALL_TAC, METIS_TAC[SETDIST_SING_IN_SET, REAL_ADD_LID]]) THEN
20649  DISCH_TAC THEN X_GEN_TAC ``z:real`` THENL
20650   [MP_TAC(ISPECL[``{z:real}``, ``s:real->bool``] SETDIST_CLOSED_COMPACT),
20651    MP_TAC(ISPECL[``{z:real}``, ``t:real->bool``] SETDIST_CLOSED_COMPACT)] THEN
20652  ASM_REWRITE_TAC[CLOSED_SING, NOT_INSERT_EMPTY] THEN
20653  SIMP_TAC real_ss [IN_SING, RIGHT_EXISTS_AND_THM, UNWIND_THM2] THEN
20654  DISCH_THEN(X_CHOOSE_THEN ``y:real`` (STRIP_ASSUME_TAC o GSYM)) THEN
20655  FIRST_X_ASSUM(MP_TAC o SPEC ``y:real``) THEN ASM_REWRITE_TAC[] THENL
20656   [MP_TAC(ISPECL[``{y:real}``, ``t:real->bool``] SETDIST_CLOSED_COMPACT),
20657    MP_TAC(ISPECL[``{y:real}``, ``s:real->bool``] SETDIST_CLOSED_COMPACT)] THEN
20658  ASM_REWRITE_TAC[CLOSED_SING, NOT_INSERT_EMPTY] THEN
20659  SIMP_TAC real_ss [IN_SING, RIGHT_EXISTS_AND_THM, UNWIND_THM2] THEN
20660  DISCH_THEN(X_CHOOSE_THEN ``x:real`` (STRIP_ASSUME_TAC o GSYM)) THEN
20661  ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
20662  MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``dist(z:real,x)`` THEN
20663  ASM_SIMP_TAC real_ss [SETDIST_LE_DIST, IN_SING] THEN
20664  UNDISCH_TAC ``dist(y:real,x) <= b`` THEN REWRITE_TAC [dist] THEN REAL_ARITH_TAC);
20665
20666val CONTINUOUS_DIAMETER = store_thm ("CONTINUOUS_DIAMETER",
20667 ``!s:real->bool e.
20668        bounded s /\ ~(s = {}) /\ &0 < e
20669        ==> ?d. &0 < d /\
20670                !t. bounded t /\ ~(t = {}) /\ hausdist(s,t) < d
20671                    ==> abs(diameter s - diameter t) < e``,
20672  REPEAT STRIP_TAC THEN EXISTS_TAC ``e / &2:real`` THEN
20673  ASM_REWRITE_TAC[REAL_HALF] THEN REPEAT STRIP_TAC THEN
20674  SUBGOAL_THEN ``diameter(s:real->bool) - diameter(t:real->bool) =
20675                 diameter(closure s) - diameter(closure t)``
20676  SUBST1_TAC THENL [ASM_MESON_TAC[DIAMETER_CLOSURE], ALL_TAC] THEN
20677  MATCH_MP_TAC REAL_LET_TRANS THEN
20678  EXISTS_TAC ``&2 * hausdist(s:real->bool,t)`` THEN
20679  CONJ_TAC THENL [ALL_TAC,
20680   FULL_SIMP_TAC std_ss [REAL_LT_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
20681   ASM_REAL_ARITH_TAC] THEN
20682  MP_TAC(ISPECL [``0:real``, ``hausdist(s:real->bool,t)``]
20683    DIAMETER_CBALL) THEN
20684  ASM_SIMP_TAC real_ss [HAUSDIST_POS_LE, GSYM REAL_NOT_LE] THEN
20685  DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC(REAL_ARITH
20686   ``x <= y + e /\ y <= x + e ==> abs(x - y) <= e:real``) THEN
20687  CONJ_TAC THEN
20688  W(MP_TAC o PART_MATCH (rand o rand) DIAMETER_SUMS o rand o snd) THEN
20689  ASM_SIMP_TAC real_ss [BOUNDED_CBALL, BOUNDED_CLOSURE] THEN
20690  MATCH_MP_TAC(REWRITE_RULE[CONJ_EQ_IMP] REAL_LE_TRANS) THEN
20691  MATCH_MP_TAC DIAMETER_SUBSET THEN
20692  ASM_SIMP_TAC real_ss [BOUNDED_SUMS, BOUNDED_CBALL, BOUNDED_CLOSURE] THEN
20693  ONCE_REWRITE_TAC[METIS[HAUSDIST_CLOSURE]
20694   ``hausdist(s:real->bool,t) = hausdist(closure s,closure t)``]
20695  THENL [ALL_TAC, ONCE_REWRITE_TAC[HAUSDIST_SYM]] THEN
20696  MATCH_MP_TAC HAUSDIST_COMPACT_SUMS THEN
20697  ASM_SIMP_TAC real_ss [COMPACT_CLOSURE, BOUNDED_CLOSURE, CLOSURE_EQ_EMPTY]);
20698
20699(* ------------------------------------------------------------------------- *)
20700(* Isometries are embeddings, and even surjective in the compact case.       *)
20701(* ------------------------------------------------------------------------- *)
20702
20703val ISOMETRY_IMP_OPEN_MAP = store_thm ("ISOMETRY_IMP_OPEN_MAP",
20704 ``!f:real->real s t u.
20705        (IMAGE f s = t) /\
20706        (!x y. x IN s /\ y IN s ==> (dist(f x,f y) = dist(x,y))) /\
20707        open_in (subtopology euclidean s) u
20708        ==> open_in (subtopology euclidean t) (IMAGE f u)``,
20709  SIMP_TAC std_ss [open_in, FORALL_IN_IMAGE] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
20710  CONJ_TAC THENL [ASM_SET_TAC[], X_GEN_TAC ``x:real`` THEN DISCH_TAC] THEN
20711  FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
20712  STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[CONJ_EQ_IMP] THEN
20713  SIMP_TAC std_ss [FORALL_IN_IMAGE] THEN
20714  RULE_ASSUM_TAC(REWRITE_RULE[SUBSET_DEF]) THEN
20715  ASM_SIMP_TAC std_ss [IN_IMAGE] THEN ASM_MESON_TAC[]);
20716
20717val ISOMETRY_IMP_EMBEDDING = store_thm ("ISOMETRY_IMP_EMBEDDING",
20718 ``!f:real->real s t.
20719        (IMAGE f s = t) /\ (!x y. x IN s /\ y IN s ==> (dist(f x,f y) = dist(x,y)))
20720        ==> ?g. homeomorphism (s,t) (f,g)``,
20721  REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN
20722  ASM_SIMP_TAC std_ss [ISOMETRY_ON_IMP_CONTINUOUS_ON] THEN
20723  CONJ_TAC THENL [ASM_MESON_TAC[DIST_EQ_0], REPEAT STRIP_TAC] THEN
20724  MATCH_MP_TAC ISOMETRY_IMP_OPEN_MAP THEN ASM_MESON_TAC[]);
20725
20726val ISOMETRY_IMP_HOMEOMORPHISM_COMPACT = store_thm ("ISOMETRY_IMP_HOMEOMORPHISM_COMPACT",
20727 ``!f s:real->bool.
20728        compact s /\ IMAGE f s SUBSET s /\
20729        (!x y. x IN s /\ y IN s ==> (dist(f x,f y) = dist(x,y)))
20730        ==> ?g. homeomorphism (s,s) (f,g)``,
20731  REPEAT STRIP_TAC THEN
20732  SUBGOAL_THEN ``IMAGE (f:real->real) s = s``
20733   (fn th => ASM_MESON_TAC[th, ISOMETRY_IMP_EMBEDDING]) THEN
20734  FIRST_ASSUM(ASSUME_TAC o MATCH_MP ISOMETRY_ON_IMP_CONTINUOUS_ON) THEN
20735  ASM_REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN REWRITE_TAC[SUBSET_DEF] THEN
20736  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
20737  SUBGOAL_THEN ``setdist({x},IMAGE (f:real->real) s) = &0`` MP_TAC THENL
20738   [MATCH_MP_TAC(REAL_ARITH ``&0 <= x /\ ~(&0 < x) ==> (x = &0:real)``) THEN
20739    REWRITE_TAC[SETDIST_POS_LE] THEN DISCH_TAC THEN
20740    KNOW_TAC ``?z. (z 0 = (x:real)) /\ !n. z(SUC n) = f(z n)`` THENL
20741    [RW_TAC std_ss [num_Axiom], STRIP_TAC] THEN
20742    SUBGOAL_THEN ``!n. (z:num->real) n IN s`` ASSUME_TAC THENL
20743     [INDUCT_TAC THEN ASM_SET_TAC[], ALL_TAC] THEN
20744    UNDISCH_TAC ``compact s`` THEN DISCH_TAC THEN
20745    FIRST_ASSUM(MP_TAC o REWRITE_RULE [compact]) THEN
20746    DISCH_THEN(MP_TAC o SPEC ``z:num->real``) THEN
20747    ASM_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN
20748    MAP_EVERY X_GEN_TAC [``l:real``, ``r:num->num``] THEN CCONTR_TAC THEN
20749    FULL_SIMP_TAC std_ss [] THEN
20750    FIRST_ASSUM(MP_TAC o MATCH_MP CONVERGENT_IMP_CAUCHY) THEN
20751    REWRITE_TAC[cauchy] THEN
20752    DISCH_THEN(MP_TAC o SPEC ``setdist({x},IMAGE (f:real->real) s)``) THEN
20753    ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN ``N:num``
20754     (MP_TAC o SPECL [``N:num``, ``N + 1:num``])) THEN
20755    KNOW_TAC ``N >= N /\ N + 1 >= N:num`` THENL
20756    [ARITH_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
20757     POP_ASSUM K_TAC THEN REWRITE_TAC[REAL_NOT_LT, o_THM]] THEN
20758    SUBGOAL_THEN ``(r:num->num) N < r (N + 1)`` MP_TAC THENL
20759     [RULE_ASSUM_TAC (REWRITE_RULE [METIS [] ``(~a \/ b) = (a ==> b)``]) THEN
20760      FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC,
20761      SIMP_TAC std_ss [LT_EXISTS, LEFT_IMP_EXISTS_THM]] THEN
20762    X_GEN_TAC ``d:num`` THEN DISCH_THEN SUBST1_TAC THEN
20763    MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC ``dist(x:real,z(SUC d))`` THEN CONJ_TAC THENL
20764     [MATCH_MP_TAC SETDIST_LE_DIST THEN ASM_SET_TAC[], ALL_TAC] THEN
20765    MATCH_MP_TAC REAL_EQ_IMP_LE THEN
20766    SPEC_TAC(``(r:num->num) N``,``m:num``) THEN
20767    INDUCT_TAC THEN ASM_MESON_TAC[ADD_CLAUSES],
20768    REWRITE_TAC[SETDIST_EQ_0_SING, IMAGE_EQ_EMPTY] THEN
20769    ASM_MESON_TAC[COMPACT_IMP_CLOSED, NOT_IN_EMPTY,
20770                  COMPACT_CONTINUOUS_IMAGE, CLOSURE_CLOSED]]);
20771
20772(* ------------------------------------------------------------------------- *)
20773(* Urysohn's lemma (for real, where the proof is easy using distances).      *)
20774(* ------------------------------------------------------------------------- *)
20775
20776val lemma = prove (
20777   ``!s t u a b.
20778          closed_in (subtopology euclidean u) s /\
20779          closed_in (subtopology euclidean u) t /\
20780          (s INTER t = {}) /\ ~(s = {}) /\ ~(t = {}) /\ ~(a = b)
20781          ==> ?f:real->real.
20782                 f continuous_on u /\
20783                 (!x. x IN u ==> f(x) IN segment[a,b]) /\
20784                 (!x. x IN u ==> ((f x = a) <=> x IN s)) /\
20785                 (!x. x IN u ==> ((f x = b) <=> x IN t))``,
20786    REPEAT STRIP_TAC THEN EXISTS_TAC
20787      ``\x:real. a + setdist({x},s) / (setdist({x},s) + setdist({x},t)) *
20788                      (b - a:real)`` THEN SIMP_TAC std_ss [] THEN
20789    SUBGOAL_THEN
20790     ``(!x:real. x IN u ==> ((setdist({x},s) = &0) <=> x IN s)) /\
20791       (!x:real. x IN u ==> ((setdist({x},t) = &0) <=> x IN t))``
20792    STRIP_ASSUME_TAC THENL
20793     [ASM_REWRITE_TAC[SETDIST_EQ_0_SING] THEN CONJ_TAC THENL
20794       [MP_TAC(ISPEC ``s:real->bool`` CLOSED_IN_CLOSED),
20795        MP_TAC(ISPEC ``t:real->bool`` CLOSED_IN_CLOSED)] THEN
20796      DISCH_THEN(MP_TAC o SPEC ``u:real->bool``) THEN
20797      ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN ``v:real->bool``
20798       (CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC)) THEN
20799      ASM_MESON_TAC[CLOSURE_CLOSED, INTER_SUBSET, SUBSET_CLOSURE, SUBSET_DEF,
20800                    IN_INTER, CLOSURE_SUBSET],
20801      ALL_TAC] THEN
20802    SUBGOAL_THEN ``!x:real. x IN u ==> &0 < setdist({x},s) + setdist({x},t)``
20803    ASSUME_TAC THENL
20804     [REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH
20805        ``&0 <= x /\ &0 <= y /\ ~((x = &0) /\ (y = &0)) ==> &0 < x + y:real``) THEN
20806      REWRITE_TAC[SETDIST_POS_LE] THEN ASM_SET_TAC[],
20807      ALL_TAC] THEN
20808    REPEAT CONJ_TAC THENL
20809     [ONCE_REWRITE_TAC [METIS [] ``(\x. a +
20810       setdist ({x},s) / (setdist ({x},s) + setdist ({x},t)) * (b - a)) =
20811                                   (\x. (\x. a) x +
20812       (\x. setdist ({x},s) / (setdist ({x},s) + setdist ({x},t)) * (b - a)) x)``] THEN
20813      MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
20814      REWRITE_TAC[real_div, GSYM REAL_MUL_ASSOC] THEN
20815      ONCE_REWRITE_TAC [METIS [] ``(\x. setdist ({x},s) *
20816       (inv (setdist ({x},s) + setdist ({x},t)) * (b - a))) =
20817                                   (\x. (\x. setdist ({x},s)) x *
20818       (\x. (inv (setdist ({x},s) + setdist ({x},t)) * (b - a))) x)``] THEN
20819      MATCH_MP_TAC CONTINUOUS_ON_MUL THEN CONJ_TAC THENL
20820      [REWRITE_TAC[CONTINUOUS_ON_SETDIST], ALL_TAC] THEN
20821      ONCE_REWRITE_TAC [METIS [] ``(\x. inv (setdist ({x},s) + setdist ({x},t)) * (b - a)) =
20822            (\x. (\x. inv (setdist ({x},s) + setdist ({x},t))) x * (\x. (b - a)) x)``] THEN
20823      MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[CONTINUOUS_ON_CONST, o_DEF] THEN
20824      REWRITE_TAC[CONTINUOUS_ON_SETDIST] THEN
20825      ONCE_REWRITE_TAC [METIS [] ``(\x. inv (setdist ({x},s) + setdist ({x},t))) =
20826                              (\x. inv ((\x. setdist ({x},s) + setdist ({x},t)) x))``] THEN
20827      MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN
20828      ASM_SIMP_TAC std_ss [REAL_LT_IMP_NE] THEN
20829      ONCE_REWRITE_TAC [METIS [] ``(\x. setdist ({x},s) + setdist ({x},t)) =
20830                      (\x. (\x. setdist ({x},s)) x + (\x. setdist ({x},t)) x)``] THEN
20831      MATCH_MP_TAC CONTINUOUS_ON_ADD THEN
20832      REWRITE_TAC[CONTINUOUS_ON_SETDIST],
20833      X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
20834      SIMP_TAC std_ss[segment, GSPECIFICATION] THEN ONCE_REWRITE_TAC [CONJ_SYM] THEN
20835      SIMP_TAC real_ss [REAL_ENTIRE, LEFT_AND_OVER_OR, REAL_ARITH
20836       ``(a + x * (b - a):real = (&1 - u) * a + u * b) <=>
20837        ((x - u) * (b - a) = 0)``, EXISTS_OR_THM] THEN
20838      DISJ1_TAC THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
20839      REWRITE_TAC[REAL_SUB_0, UNWIND_THM1] THEN
20840      ASM_SIMP_TAC std_ss [REAL_LE_DIV, REAL_LE_ADD, SETDIST_POS_LE, REAL_LE_LDIV_EQ,
20841                   REAL_ARITH ``a <= &1 * (a + b) <=> &0 <= b:real``],
20842      SIMP_TAC real_ss [REAL_ARITH ``(a + x:real = a) <=> (x = 0)``],
20843      REWRITE_TAC[REAL_ARITH ``(a + x * (b - a):real = b) <=>
20844                               ((x - &1) * (b - a) = 0)``]] THEN
20845    ASM_REWRITE_TAC[REAL_ENTIRE, REAL_SUB_0] THEN
20846    ASM_SIMP_TAC std_ss [REAL_SUB_0, REAL_EQ_LDIV_EQ,
20847                 REAL_MUL_LZERO, REAL_MUL_LID] THEN
20848    REWRITE_TAC[REAL_ARITH ``(x:real = x + y) <=> (y = &0)``] THEN
20849    ASM_REWRITE_TAC[]);
20850
20851val URYSOHN_LOCAL_STRONG = store_thm ("URYSOHN_LOCAL_STRONG",
20852 ``!s t u a b.
20853        closed_in (subtopology euclidean u) s /\
20854        closed_in (subtopology euclidean u) t /\
20855        (s INTER t = {}) /\ ~(a = b)
20856        ==> ?f:real->real.
20857               f continuous_on u /\
20858               (!x. x IN u ==> f(x) IN segment[a,b]) /\
20859               (!x. x IN u ==> ((f x = a) <=> x IN s)) /\
20860               (!x. x IN u ==> ((f x = b) <=> x IN t))``,
20861  KNOW_TAC ``!(s :real -> bool) (t :real -> bool).
20862   (\s t. !(u :real -> bool) (a :real) (b :real).
20863  closed_in (subtopology euclidean u) s /\
20864  closed_in (subtopology euclidean u) t /\
20865  (s INTER t = ({} :real -> bool)) /\ a <> b ==>
20866  ?(f :real -> real).
20867    f continuous_on u /\
20868    (!(x :real). x IN u ==> f x IN segment [(a,b)]) /\
20869    (!(x :real). x IN u ==> ((f x = a) <=> x IN s)) /\
20870    !(x :real). x IN u ==> ((f x = b) <=> x IN t)) s t`` THENL
20871  [ALL_TAC, SIMP_TAC std_ss []] THEN
20872  MATCH_MP_TAC(MESON[]
20873   ``(!s t. P s t <=> P t s) /\
20874    (!s t. ~(s = {}) /\ ~(t = {}) ==> P s t) /\
20875    P {} {} /\ (!t. ~(t = {}) ==> P {} t)
20876    ==> !s t. P s t``) THEN
20877  SIMP_TAC std_ss [] THEN REPEAT CONJ_TAC THENL
20878
20879   [REPEAT GEN_TAC THEN
20880    KNOW_TAC ``(!(u :real -> bool) (a :real) (b :real).
20881   closed_in (subtopology euclidean u) (s :real -> bool) /\
20882   closed_in (subtopology euclidean u) (t :real -> bool) /\
20883   (s INTER t = ({} :real -> bool)) /\ a <> b ==>
20884   ?(f :real -> real).
20885     f continuous_on u /\
20886     (!(x :real). x IN u ==> f x IN segment [(a,b)]) /\
20887     (!(x :real). x IN u ==> ((f x = a) <=> x IN s)) /\
20888     !(x :real). x IN u ==> ((f x = b) <=> x IN t)) <=>
20889   !(u :real -> bool) (b :real) (a :real).
20890   closed_in (subtopology euclidean u) t /\
20891   closed_in (subtopology euclidean u) s /\
20892   (t INTER s = ({} :real -> bool)) /\ a <> b ==>
20893   ?(f :real -> real).
20894    f continuous_on u /\
20895    (!(x :real). x IN u ==> f x IN segment [(a,b)]) /\
20896    (!(x :real). x IN u ==> ((f x = a) <=> x IN t)) /\
20897    !(x :real). x IN u ==> ((f x = b) <=> x IN s)`` THENL
20898    [ALL_TAC, DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
20899     EQ_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THENL
20900     [POP_ASSUM (MP_TAC o SPECL [``u:real->bool``,``b:real``,``a:real``]),
20901      POP_ASSUM (MP_TAC o SPECL [``u:real->bool``,``a:real``,``b:real``])] THEN
20902     SIMP_TAC std_ss []] THEN
20903    REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
20904    METIS_TAC[SEGMENT_SYM, INTER_COMM, CONJ_ACI, EQ_SYM_EQ],
20905    SIMP_TAC real_ss [lemma],
20906    REPEAT STRIP_TAC THEN EXISTS_TAC ``(\x. midpoint(a,b)):real->real`` THEN
20907    ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, CONTINUOUS_ON_CONST, MIDPOINT_IN_SEGMENT] THEN
20908    REWRITE_TAC[midpoint] THEN CONJ_TAC THEN GEN_TAC THEN DISCH_TAC THEN
20909    UNDISCH_TAC ``~(a:real = b)`` THEN REWRITE_TAC[GSYM MONO_NOT_EQ] THEN
20910    ONCE_REWRITE_TAC [REAL_MUL_SYM] THEN REWRITE_TAC [GSYM real_div] THEN
20911    SIMP_TAC std_ss [REAL_EQ_LDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
20912    REAL_ARITH_TAC,
20913    REPEAT STRIP_TAC THEN ASM_CASES_TAC ``t:real->bool = u`` THENL
20914     [EXISTS_TAC ``(\x. b):real->real`` THEN
20915      ASM_SIMP_TAC std_ss [NOT_IN_EMPTY, ENDS_IN_SEGMENT, IN_UNIV,
20916                      CONTINUOUS_ON_CONST],
20917      SUBGOAL_THEN ``?c:real. c IN u /\ ~(c IN t)`` STRIP_ASSUME_TAC THENL
20918       [REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET)) THEN
20919        REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM_SET_TAC[],
20920        ALL_TAC] THEN
20921      MP_TAC(ISPECL [``{c:real}``, ``t:real->bool``, ``u:real->bool``,
20922                     ``midpoint(a,b):real``, ``b:real``] lemma) THEN
20923      ASM_REWRITE_TAC[CLOSED_IN_SING, MIDPOINT_EQ_ENDPOINT] THEN
20924      KNOW_TAC ``({(c :real)} INTER (t :real -> bool) = ({} :real -> bool)) /\
20925                   {c} <> ({} :real -> bool)`` THENL
20926      [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
20927      DISCH_THEN (X_CHOOSE_TAC ``f:real->real``) THEN EXISTS_TAC ``f:real->real`` THEN
20928      POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [NOT_IN_EMPTY] THEN
20929      STRIP_TAC THEN CONJ_TAC THENL
20930       [SUBGOAL_THEN
20931         ``segment[midpoint(a,b):real,b] SUBSET segment[a,b]`` MP_TAC
20932        THENL
20933         [REWRITE_TAC[SUBSET_DEF, IN_SEGMENT, midpoint] THEN GEN_TAC THEN
20934          DISCH_THEN(X_CHOOSE_THEN ``u:real`` STRIP_ASSUME_TAC) THEN
20935          EXISTS_TAC ``(&1 + u) / &2:real`` THEN ASM_REWRITE_TAC[] THEN
20936          SIMP_TAC std_ss [REAL_LE_LDIV_EQ, REAL_LE_RDIV_EQ, REAL_ARITH ``0 < 2:real``] THEN
20937          CONJ_TAC THENL [UNDISCH_TAC ``0 <= u:real`` THEN REAL_ARITH_TAC, ALL_TAC] THEN
20938          CONJ_TAC THENL [UNDISCH_TAC ``u <= 1:real`` THEN REAL_ARITH_TAC, ALL_TAC] THEN
20939          ONCE_REWRITE_TAC [REAL_ARITH ``a * (b * c) = (a * c) * b:real``] THEN
20940          GEN_REWR_TAC (LAND_CONV o RAND_CONV) [GSYM REAL_MUL_RID] THEN
20941          ONCE_REWRITE_TAC [METIS [REAL_DIV_REFL, REAL_ARITH ``2 <> 0:real``]
20942           ``u * b * 1 = u * b * (2 / 2:real)``] THEN REWRITE_TAC [real_div] THEN
20943          ONCE_REWRITE_TAC [REAL_ARITH ``u * b * (2 * inv 2) = (u * b * 2) * inv 2:real``] THEN
20944          REWRITE_TAC [GSYM REAL_ADD_RDISTRIB] THEN REWRITE_TAC [GSYM real_div] THEN
20945          SIMP_TAC real_ss [REAL_EQ_LDIV_EQ] THEN REWRITE_TAC [REAL_ADD_RDISTRIB] THEN
20946          REWRITE_TAC [real_div, REAL_SUB_RDISTRIB] THEN
20947          REWRITE_TAC [REAL_ARITH
20948          ``(1 + u) * inv 2 * a * 2 = (1 + u) * a * (inv 2 * 2:real)``] THEN
20949          SIMP_TAC real_ss [REAL_MUL_LINV] THEN REAL_ARITH_TAC,
20950          ASM_SET_TAC[]],
20951        SUBGOAL_THEN ``~(a IN segment[midpoint(a,b):real,b])`` MP_TAC THENL
20952         [ALL_TAC, ASM_MESON_TAC[]] THEN
20953        DISCH_THEN(MP_TAC o CONJUNCT2 o MATCH_MP DIST_IN_CLOSED_SEGMENT) THEN
20954        REWRITE_TAC[DIST_MIDPOINT] THEN
20955        UNDISCH_TAC ``~(a:real = b)`` THEN REWRITE_TAC [dist] THEN
20956        SIMP_TAC real_ss [REAL_LE_RDIV_EQ] THEN REWRITE_TAC [REAL_NOT_LE] THEN
20957        REWRITE_TAC [abs] THEN COND_CASES_TAC THEN POP_ASSUM MP_TAC THEN REAL_ARITH_TAC]]]);
20958
20959val URYSOHN_LOCAL = store_thm ("URYSOHN_LOCAL",
20960 ``!s t u a b.
20961        closed_in (subtopology euclidean u) s /\
20962        closed_in (subtopology euclidean u) t /\
20963        (s INTER t = {})
20964        ==> ?f:real->real.
20965               f continuous_on u /\
20966               (!x. x IN u ==> f(x) IN segment[a,b]) /\
20967               (!x. x IN s ==> (f x = a)) /\
20968               (!x. x IN t ==> (f x = b))``,
20969  REPEAT STRIP_TAC THEN ASM_CASES_TAC ``a:real = b`` THENL
20970   [EXISTS_TAC ``(\x. b):real->real`` THEN
20971    ASM_REWRITE_TAC[ENDS_IN_SEGMENT, CONTINUOUS_ON_CONST],
20972    MP_TAC(ISPECL [``s:real->bool``, ``t:real->bool``, ``u:real->bool``,
20973                   ``a:real``, ``b:real``] URYSOHN_LOCAL_STRONG) THEN
20974    ASM_REWRITE_TAC[] THEN DISCH_THEN (X_CHOOSE_TAC ``f:real->real``) THEN
20975    EXISTS_TAC ``f:real->real`` THEN POP_ASSUM MP_TAC THEN SIMP_TAC std_ss [] THEN
20976    REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET)) THEN
20977    REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN SET_TAC[]]);
20978
20979val URYSOHN_STRONG = store_thm ("URYSOHN_STRONG",
20980 ``!s t a b.
20981        closed s /\ closed t /\ (s INTER t = {}) /\ ~(a = b)
20982        ==> ?f:real->real.
20983               f continuous_on univ(:real) /\ (!x. f(x) IN segment[a,b]) /\
20984               (!x. (f x = a) <=> x IN s) /\ (!x. (f x = b) <=> x IN t)``,
20985  REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN] THEN
20986  ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN
20987  DISCH_THEN(MP_TAC o MATCH_MP URYSOHN_LOCAL_STRONG) THEN
20988  REWRITE_TAC[IN_UNIV]);
20989
20990val URYSOHN = store_thm ("URYSOHN",
20991 ``!s t a b.
20992        closed s /\ closed t /\ (s INTER t = {})
20993        ==> ?f:real->real.
20994               f continuous_on univ(:real) /\ (!x. f(x) IN segment[a,b]) /\
20995               (!x. x IN s ==> (f x = a)) /\ (!x. x IN t ==> (f x = b))``,
20996  REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN] THEN
20997  ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN DISCH_THEN
20998   (MP_TAC o ISPECL [``a:real``, ``b:real``] o MATCH_MP URYSOHN_LOCAL) THEN
20999  REWRITE_TAC[IN_UNIV]);
21000
21001(* ------------------------------------------------------------------------- *)
21002(* Basics about "local" properties in general.                               *)
21003(* ------------------------------------------------------------------------- *)
21004
21005val locally = new_definition ("locally",
21006 ``locally P (s:real->bool) <=>
21007        !w x. open_in (subtopology euclidean s) w /\ x IN w
21008              ==> ?u v. open_in (subtopology euclidean s) u /\ P v /\
21009                        x IN u /\ u SUBSET v /\ v SUBSET w``);
21010
21011val LOCALLY_MONO = store_thm ("LOCALLY_MONO",
21012 ``!P Q s. (!t. P t ==> Q t) /\ locally P s ==> locally Q s``,
21013  REWRITE_TAC[locally] THEN MESON_TAC[]);
21014
21015val LOCALLY_OPEN_SUBSET = store_thm ("LOCALLY_OPEN_SUBSET",
21016 ``!P s t:real->bool.
21017        locally P s /\ open_in (subtopology euclidean s) t
21018        ==> locally P t``,
21019  REPEAT GEN_TAC THEN REWRITE_TAC[locally] THEN STRIP_TAC THEN
21020  MAP_EVERY X_GEN_TAC [``w:real->bool``, ``x:real``] THEN STRIP_TAC THEN
21021  FIRST_X_ASSUM(MP_TAC o SPECL [``w:real->bool``, ``x:real``]) THEN
21022  KNOW_TAC ``open_in (subtopology euclidean s) w /\ x IN w`` THENL
21023  [ASM_MESON_TAC[OPEN_IN_TRANS],
21024   DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
21025  STRIP_TAC THEN EXISTS_TAC ``u:real->bool`` THEN EXISTS_TAC ``v:real->bool`` THEN
21026  ASM_REWRITE_TAC[] THEN MATCH_MP_TAC OPEN_IN_SUBSET_TRANS THEN
21027  EXISTS_TAC ``s:real->bool`` THEN ASM_MESON_TAC[open_in, SUBSET_DEF]);
21028
21029val LOCALLY_DIFF_CLOSED = store_thm ("LOCALLY_DIFF_CLOSED",
21030 ``!P s t:real->bool.
21031        locally P s /\ closed_in (subtopology euclidean s) t
21032        ==> locally P (s DIFF t)``,
21033  REPEAT STRIP_TAC THEN
21034  MATCH_MP_TAC LOCALLY_OPEN_SUBSET THEN
21035  EXISTS_TAC ``s:real->bool`` THEN ASM_REWRITE_TAC[] THEN
21036  MATCH_MP_TAC OPEN_IN_DIFF THEN
21037  ASM_REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL, SUBSET_UNIV, TOPSPACE_EUCLIDEAN]);
21038
21039val LOCALLY_EMPTY = store_thm ("LOCALLY_EMPTY",
21040 ``!P. locally P {}``,
21041  REWRITE_TAC[locally] THEN MESON_TAC[open_in, SUBSET_DEF, NOT_IN_EMPTY]);
21042
21043val LOCALLY_SING = store_thm ("LOCALLY_SING",
21044 ``!P a. locally P {a} <=> P {a}``,
21045  REWRITE_TAC[locally, open_in] THEN
21046  REWRITE_TAC[SET_RULE
21047   ``(w SUBSET {a} /\ P) /\ x IN w <=> (w = {a}) /\ (x = a) /\ P``] THEN
21048  SIMP_TAC std_ss [CONJ_EQ_IMP, RIGHT_FORALL_IMP_THM, UNWIND_FORALL_THM2, IN_SING] THEN
21049  REWRITE_TAC[SET_RULE
21050   ``(u SUBSET {a} /\ P) /\ Q /\ a IN u /\ u SUBSET v /\ v SUBSET {a} <=>
21051    (u = {a}) /\ (v = {a}) /\ P /\ Q``] THEN
21052  SIMP_TAC std_ss [RIGHT_EXISTS_AND_THM, UNWIND_THM2, IN_SING] THEN
21053  REWRITE_TAC[UNWIND_FORALL_THM2, MESON[REAL_LT_01] ``?x:real. &0 < x``]);
21054
21055val LOCALLY_INTER = store_thm ("LOCALLY_INTER",
21056 ``!P:(real->bool)->bool.
21057        (!s t. P s /\ P t ==> P(s INTER t))
21058        ==> !s t. locally P s /\ locally P t ==> locally P (s INTER t)``,
21059  GEN_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THEN
21060  REWRITE_TAC[locally, OPEN_IN_OPEN] THEN
21061  SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM] THEN
21062  REWRITE_TAC [GSYM CONJ_ASSOC] THEN
21063  ONCE_REWRITE_TAC [METIS [] ``( ?v t.
21064     open t /\ P v /\ x IN s INTER t /\ s INTER t SUBSET v /\
21065           v SUBSET w) = (\w x.  ?v t.
21066     open t /\ P v /\ x IN s INTER t /\ s INTER t SUBSET v /\
21067           v SUBSET w) w x``] THEN
21068  ONCE_REWRITE_TAC [METIS [] ``s INTER t = (\t. s INTER t:real->bool) t``] THEN
21069  ONCE_REWRITE_TAC [METIS [] ``x IN w <=> (\w x.  x IN w) w x``] THEN
21070  ONCE_REWRITE_TAC [METIS[]
21071   ``(!w x. (?t. P t /\ (w = f t) /\ Q w x) ==> R w x) <=>
21072     (!t x. P t /\ Q (f t) x ==> R (f t) x)``] THEN
21073  SIMP_TAC std_ss [] THEN
21074  SIMP_TAC std_ss [GSYM FORALL_AND_THM, UNWIND_THM2, IN_INTER] THEN
21075  DISCH_TAC THEN X_GEN_TAC ``w:real->bool`` THEN X_GEN_TAC ``x:real`` THEN
21076  POP_ASSUM (MP_TAC o SPECL [``w:real->bool``,``x:real``]) THEN
21077  DISCH_THEN(fn th => STRIP_TAC THEN MP_TAC th) THEN
21078  ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2
21079   (X_CHOOSE_THEN ``u1:real->bool`` (X_CHOOSE_THEN ``v1:real->bool``
21080        STRIP_ASSUME_TAC))
21081   (X_CHOOSE_THEN ``u2:real->bool`` (X_CHOOSE_THEN ``v2:real->bool``
21082        STRIP_ASSUME_TAC))) THEN
21083  EXISTS_TAC ``u1 INTER u2:real->bool`` THEN
21084  EXISTS_TAC ``v1 INTER v2:real->bool`` THEN
21085  ASM_SIMP_TAC std_ss [OPEN_INTER] THEN ASM_SET_TAC[]);
21086
21087val lemma = prove (
21088  ``!P Q f g. (!s t. P s /\ homeomorphism (s,t) (f,g) ==> Q t)
21089        ==> (!s:real->bool t:real->bool.
21090                locally P s /\ homeomorphism (s,t) (f,g) ==> locally Q t)``,
21091    REPEAT GEN_TAC THEN DISCH_TAC THEN REPEAT GEN_TAC THEN
21092    REWRITE_TAC[locally] THEN STRIP_TAC THEN
21093    FIRST_X_ASSUM(STRIP_ASSUME_TAC o REWRITE_RULE [homeomorphism]) THEN
21094    MAP_EVERY X_GEN_TAC [``w:real->bool``, ``y:real``] THEN STRIP_TAC THEN
21095    FIRST_X_ASSUM(MP_TAC o SPECL
21096     [``IMAGE (g:real->real) w``, ``(g:real->real) y``]) THEN
21097    KNOW_TAC ``open_in (subtopology euclidean (s :real -> bool))
21098                     (IMAGE (g :real -> real) (w :real -> bool)) /\
21099                             g (y :real) IN IMAGE g w`` THENL
21100     [CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
21101      SUBGOAL_THEN ``IMAGE (g:real->real) w =
21102                     {x | x IN s /\ f(x) IN w}``
21103      SUBST1_TAC THENL
21104       [RULE_ASSUM_TAC(REWRITE_RULE[open_in]) THEN ASM_SET_TAC[],
21105        MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]],
21106      DISCH_TAC THEN ASM_REWRITE_TAC [] THEN SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM]] THEN
21107    MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
21108    STRIP_TAC THEN MAP_EVERY EXISTS_TAC
21109     [``IMAGE (f:real->real) u``, ``IMAGE (f:real->real) v``] THEN
21110    CONJ_TAC THENL
21111     [SUBGOAL_THEN ``IMAGE (f:real->real) u =
21112                     {x | x IN t /\ g(x) IN u}``
21113      SUBST1_TAC THENL
21114       [RULE_ASSUM_TAC(REWRITE_RULE[open_in]) THEN ASM_SET_TAC[],
21115        MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]],
21116      ALL_TAC] THEN
21117    CONJ_TAC THENL
21118     [FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC ``v:real->bool`` THEN
21119      ASM_REWRITE_TAC[homeomorphism] THEN
21120      REWRITE_TAC[homeomorphism] THEN REPEAT CONJ_TAC THEN
21121      TRY(FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[CONJ_EQ_IMP]
21122          CONTINUOUS_ON_SUBSET))),
21123      ALL_TAC] THEN
21124    RULE_ASSUM_TAC(REWRITE_RULE[open_in]) THEN ASM_SET_TAC[]);
21125
21126val HOMEOMORPHISM_LOCALLY = store_thm ("HOMEOMORPHISM_LOCALLY",
21127 ``!P Q f:real->real g.
21128        (!s t. homeomorphism (s,t) (f,g) ==> (P s <=> Q t))
21129        ==> (!s t. homeomorphism (s,t) (f,g)
21130                   ==> (locally P s <=> locally Q t))``,
21131  REPEAT STRIP_TAC THEN EQ_TAC THEN
21132  MATCH_MP_TAC(SIMP_RULE std_ss [RIGHT_IMP_FORALL_THM,
21133        TAUT `p ==> q /\ r ==> s <=> p /\ r ==> q ==> s`] lemma) THEN
21134  ASM_MESON_TAC[HOMEOMORPHISM_SYM]);
21135
21136val HOMEOMORPHIC_LOCALLY = store_thm ("HOMEOMORPHIC_LOCALLY",
21137 ``!P Q. (!s:real->bool t:real->bool. s homeomorphic t ==> (P s <=> Q t))
21138         ==> (!s t. s homeomorphic t ==> (locally P s <=> locally Q t))``,
21139  REPEAT GEN_TAC THEN STRIP_TAC THEN
21140  SIMP_TAC std_ss [homeomorphic, LEFT_IMP_EXISTS_THM] THEN
21141  ONCE_REWRITE_TAC [METIS [] ``(homeomorphism (s,t) (f,g) ==>
21142                               (locally P s <=> locally Q t)) =
21143                     (\s t f g. homeomorphism (s,t) (f,g) ==>
21144                               (locally P s <=> locally Q t)) s t f g``] THEN
21145  ONCE_REWRITE_TAC[METIS[]
21146   ``(!a b c d. P a b c d) <=> (!c d a b. P a b c d)``] THEN
21147  GEN_TAC THEN GEN_TAC THEN BETA_TAC THEN MATCH_MP_TAC HOMEOMORPHISM_LOCALLY THEN
21148  ASM_MESON_TAC[homeomorphic]);
21149
21150val LOCALLY_TRANSLATION = store_thm ("LOCALLY_TRANSLATION",
21151 ``!P:(real->bool)->bool.
21152        (!a s. P (IMAGE (\x. a + x) s) <=> P s)
21153        ==> (!a s. locally P (IMAGE (\x. a + x) s) <=> locally P s)``,
21154  GEN_TAC THEN
21155  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``a:real``) THEN
21156  MP_TAC(ISPECL
21157   [``P:(real->bool)->bool``, ``P:(real->bool)->bool``,
21158    ``\x:real. a + x``, ``\x:real. -a + x``]
21159     HOMEOMORPHISM_LOCALLY) THEN
21160  SIMP_TAC real_ss [homeomorphism] THEN
21161  SIMP_TAC real_ss [CONTINUOUS_ON_ADD, CONTINUOUS_ON_CONST, CONTINUOUS_ON_ID] THEN
21162  SIMP_TAC real_ss [UNWIND_FORALL_THM1, CONJ_EQ_IMP, GSYM IMAGE_COMPOSE, o_DEF] THEN
21163  REWRITE_TAC [REAL_ARITH ``(-a + (a + x:real) = x) /\ (a + (-a + x) = x:real)``] THEN
21164  REWRITE_TAC [IMAGE_ID] THEN METIS_TAC[]);
21165
21166val LOCALLY_INJECTIVE_LINEAR_IMAGE = store_thm ("LOCALLY_INJECTIVE_LINEAR_IMAGE",
21167 ``!P:(real->bool)->bool Q:(real->bool)->bool.
21168        (!f s. linear f /\ (!x y. (f x = f y) ==> (x = y))
21169               ==> (P (IMAGE f s) <=> Q s))
21170        ==>  (!f s. linear f /\ (!x y. (f x = f y) ==> (x = y))
21171                    ==> (locally P (IMAGE f s) <=> locally Q s))``,
21172  GEN_TAC THEN GEN_TAC THEN
21173  DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``f:real->real``) THEN
21174  ASM_CASES_TAC ``linear(f:real->real) /\ (!x y. (f x = f y) ==> (x = y))`` THEN
21175  ASM_REWRITE_TAC[] THEN
21176  FIRST_ASSUM(MP_TAC o MATCH_MP LINEAR_INJECTIVE_LEFT_INVERSE) THEN
21177  REWRITE_TAC[FUN_EQ_THM, o_THM, I_THM] THEN
21178  DISCH_THEN(X_CHOOSE_THEN ``g:real->real`` STRIP_ASSUME_TAC) THEN
21179  MP_TAC(ISPECL
21180   [``Q:(real->bool)->bool``, ``P:(real->bool)->bool``,
21181    ``f:real->real``, ``g:real->real``]
21182     HOMEOMORPHISM_LOCALLY) THEN
21183  ASM_SIMP_TAC std_ss [homeomorphism, LINEAR_CONTINUOUS_ON] THEN
21184  ASM_SIMP_TAC std_ss [UNWIND_FORALL_THM1, CONJ_EQ_IMP, FORALL_IN_IMAGE] THEN
21185  ASM_SIMP_TAC std_ss [GSYM IMAGE_COMPOSE, o_DEF, IMAGE_ID] THEN MESON_TAC[]);
21186
21187val LOCALLY_OPEN_MAP_IMAGE = store_thm ("LOCALLY_OPEN_MAP_IMAGE",
21188 ``!P Q f:real->real s.
21189        f continuous_on s /\
21190        (!t. open_in (subtopology euclidean s) t
21191              ==> open_in (subtopology euclidean (IMAGE f s)) (IMAGE f t)) /\
21192        (!t. t SUBSET s /\ P t ==> Q(IMAGE f t)) /\
21193        locally P s
21194        ==> locally Q (IMAGE f s)``,
21195  REPEAT GEN_TAC THEN
21196  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
21197  REWRITE_TAC[locally] THEN DISCH_TAC THEN
21198  MAP_EVERY X_GEN_TAC [``w:real->bool``, ``y:real``] THEN
21199  STRIP_TAC THEN
21200  FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o REWRITE_RULE [open_in]) THEN
21201  UNDISCH_TAC ``f continuous_on s`` THEN DISCH_TAC THEN
21202  FIRST_ASSUM(MP_TAC o  SPEC ``w:real->bool`` o
21203    REWRITE_RULE [CONTINUOUS_ON_OPEN]) THEN
21204  ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
21205  SUBGOAL_THEN ``?x. x IN s /\ ((f:real->real) x = y)`` STRIP_ASSUME_TAC THENL
21206   [ASM_SET_TAC[], ALL_TAC] THEN
21207  FIRST_X_ASSUM(MP_TAC o SPECL
21208   [``{x | x IN s /\ (f:real->real) x IN w}``, ``x:real``]) THEN
21209  ASM_SIMP_TAC real_ss [GSPECIFICATION, LEFT_IMP_EXISTS_THM] THEN
21210  MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
21211  STRIP_TAC THEN MAP_EVERY EXISTS_TAC
21212   [``IMAGE (f:real->real) u``, ``IMAGE (f:real->real) v``] THEN
21213  ASM_SIMP_TAC real_ss [] THEN CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
21214  FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SET_TAC[]);
21215
21216(* ------------------------------------------------------------------------- *)
21217(* F_sigma and G_delta sets.                                                 *)
21218(* ------------------------------------------------------------------------- *)
21219
21220val gdelta = new_definition ("gdelta",
21221 ``gdelta(s:real->bool) <=>
21222    ?g. COUNTABLE g /\ (!u. u IN g ==> open u) /\ (BIGINTER g = s)``);
21223
21224val fsigma = new_definition ("fsigma",
21225 ``fsigma(s:real->bool) <=>
21226    ?g. COUNTABLE g /\ (!c. c IN g ==> closed c) /\ (BIGUNION g = s)``);
21227
21228val GDELTA_COMPLEMENT = store_thm ("GDELTA_COMPLEMENT",
21229 ``!s. gdelta(univ(:real) DIFF s) <=> fsigma s``,
21230  GEN_TAC THEN REWRITE_TAC[gdelta, fsigma] THEN EQ_TAC THEN
21231  DISCH_THEN(X_CHOOSE_THEN ``g:(real->bool)->bool`` STRIP_ASSUME_TAC) THEN
21232  EXISTS_TAC ``IMAGE (\s. univ(:real) DIFF s) g`` THEN
21233  ASM_SIMP_TAC real_ss [COUNTABLE_IMAGE, FORALL_IN_IMAGE] THEN
21234  ASM_REWRITE_TAC[GSYM OPEN_CLOSED, GSYM closed_def] THEN
21235  ONCE_REWRITE_TAC[BIGINTER_BIGUNION, BIGUNION_BIGINTER] THEN
21236  SIMP_TAC real_ss [SET_RULE ``{f x | x IN IMAGE g s} = {f(g x) | x IN s}``] THEN
21237  ASM_SIMP_TAC real_ss [SET_RULE ``UNIV DIFF (UNIV DIFF s) = s``,
21238                  SET_RULE ``{x | x IN s} = s``]);
21239
21240val FSIGMA_COMPLEMENT = store_thm ("FSIGMA_COMPLEMENT",
21241 ``!s. fsigma(univ(:real) DIFF s) <=> gdelta s``,
21242  ONCE_REWRITE_TAC[GSYM GDELTA_COMPLEMENT] THEN
21243  REWRITE_TAC[SET_RULE ``UNIV DIFF (UNIV DIFF s) = s``]);
21244
21245val CLOSED_AS_GDELTA = store_thm ("CLOSED_AS_GDELTA",
21246 ``!s:real->bool. closed s ==> gdelta s``,
21247  REPEAT STRIP_TAC THEN REWRITE_TAC[gdelta] THEN EXISTS_TAC
21248   ``{ BIGUNION { ball(x:real,inv(&n + &1)) | x IN s} | n IN univ(:num)}`` THEN
21249  SIMP_TAC real_ss [GSYM IMAGE_DEF, COUNTABLE_IMAGE, NUM_COUNTABLE] THEN
21250  SIMP_TAC real_ss [FORALL_IN_IMAGE, OPEN_BIGUNION, OPEN_BALL] THEN
21251  MATCH_MP_TAC(SET_RULE
21252   ``(closure s = s) /\ s SUBSET t /\ t SUBSET closure s
21253     ==> (t = s)``) THEN
21254  ASM_REWRITE_TAC[CLOSURE_EQ] THEN CONJ_TAC THENL
21255   [SIMP_TAC real_ss [SUBSET_BIGINTER, FORALL_IN_IMAGE, IN_UNIV] THEN
21256    X_GEN_TAC ``n:num`` THEN SIMP_TAC real_ss [BIGUNION_IMAGE, SUBSET_DEF, GSPECIFICATION] THEN
21257    X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN EXISTS_TAC ``x:real`` THEN
21258    ASM_REWRITE_TAC[CENTRE_IN_BALL, REAL_LT_INV_EQ] THEN
21259    SIMP_TAC arith_ss [REAL_LT],
21260    REWRITE_TAC[SUBSET_DEF, CLOSURE_APPROACHABLE, BIGINTER_IMAGE, IN_UNIV] THEN
21261    X_GEN_TAC ``x:real`` THEN SIMP_TAC real_ss [GSPECIFICATION, BIGUNION_IMAGE] THEN
21262    DISCH_TAC THEN X_GEN_TAC ``e:real`` THEN  DISCH_TAC THEN
21263    FIRST_ASSUM(MP_TAC o ONCE_REWRITE_RULE [REAL_ARCH_INV]) THEN
21264    DISCH_THEN(X_CHOOSE_THEN ``n:num`` STRIP_ASSUME_TAC) THEN
21265    FIRST_X_ASSUM(MP_TAC o SPEC ``n:num``) THEN REWRITE_TAC[IN_BALL] THEN
21266    DISCH_THEN (X_CHOOSE_TAC ``y:real``) THEN EXISTS_TAC ``y:real`` THEN
21267    POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
21268    MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LT_TRANS) THEN
21269    FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
21270        REAL_LT_TRANS)) THEN
21271    MATCH_MP_TAC REAL_LT_INV2 THEN
21272    SIMP_TAC arith_ss [REAL_OF_NUM_ADD, REAL_LT] THEN ASM_ARITH_TAC]);
21273
21274(* ------------------------------------------------------------------------- *)
21275(* Local compactness.                                                        *)
21276(* ------------------------------------------------------------------------- *)
21277
21278val LOCALLY_COMPACT = store_thm ("LOCALLY_COMPACT",
21279 ``!s:real->bool.
21280        locally compact s <=>
21281        !x. x IN s ==> ?u v. x IN u /\ u SUBSET v /\ v SUBSET s /\
21282                             open_in (subtopology euclidean s) u /\
21283                             compact v``,
21284  GEN_TAC THEN REWRITE_TAC[locally] THEN EQ_TAC THEN DISCH_TAC THENL
21285   [X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN FIRST_X_ASSUM
21286     (MP_TAC o SPECL [``s INTER ball(x:real,&1)``, ``x:real``]) THEN
21287    ASM_SIMP_TAC real_ss [OPEN_IN_OPEN_INTER, OPEN_BALL] THEN
21288    ASM_REWRITE_TAC[IN_INTER, CENTRE_IN_BALL, REAL_LT_01] THEN
21289    MESON_TAC[SUBSET_INTER],
21290    MAP_EVERY X_GEN_TAC [``w:real->bool``, ``x:real``] THEN
21291    REWRITE_TAC[CONJ_EQ_IMP] THEN GEN_REWR_TAC LAND_CONV [OPEN_IN_OPEN] THEN
21292    DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN
21293    ASM_REWRITE_TAC[IN_INTER] THEN STRIP_TAC THEN
21294    FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN
21295    ASM_SIMP_TAC real_ss [LEFT_IMP_EXISTS_THM] THEN
21296    MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
21297    STRIP_TAC THEN
21298    UNDISCH_TAC ``open t`` THEN DISCH_TAC THEN
21299    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_CONTAINS_CBALL]) THEN
21300    DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
21301    DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
21302    EXISTS_TAC ``(s INTER ball(x:real,e)) INTER u`` THEN
21303    EXISTS_TAC ``cball(x:real,e) INTER v`` THEN
21304    ASM_SIMP_TAC real_ss [OPEN_IN_INTER, OPEN_IN_OPEN_INTER, OPEN_BALL, CENTRE_IN_BALL,
21305                 COMPACT_INTER, COMPACT_CBALL, IN_INTER] THEN
21306    MP_TAC(ISPECL [``x:real``, ``e:real``] BALL_SUBSET_CBALL) THEN
21307    ASM_SET_TAC[]]);
21308
21309val LOCALLY_COMPACT_ALT = store_thm ("LOCALLY_COMPACT_ALT",
21310 ``!s:real->bool.
21311        locally compact s <=>
21312        !x. x IN s
21313            ==> ?u. x IN u /\
21314                    open_in (subtopology euclidean s) u /\
21315                    compact(closure u) /\ closure u SUBSET s``,
21316  GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN EQ_TAC THEN
21317  DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
21318  FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
21319  DISCH_THEN (X_CHOOSE_TAC ``u:real->bool``) THEN EXISTS_TAC ``u:real->bool`` THEN
21320  POP_ASSUM MP_TAC THEN
21321  METIS_TAC[CLOSURE_SUBSET, SUBSET_TRANS, CLOSURE_MINIMAL,
21322            COMPACT_CLOSURE, BOUNDED_SUBSET, COMPACT_EQ_BOUNDED_CLOSED]);
21323
21324val LOCALLY_COMPACT_INTER_CBALL = store_thm ("LOCALLY_COMPACT_INTER_CBALL",
21325 ``!s:real->bool.
21326        locally compact s <=>
21327        !x. x IN s ==> ?e. &0 < e /\ closed(cball(x,e) INTER s)``,
21328  GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT, OPEN_IN_CONTAINS_CBALL] THEN
21329  EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN POP_ASSUM (MP_TAC o SPEC ``x:real``) THEN
21330  ASM_CASES_TAC ``(x:real) IN s`` THEN ASM_SIMP_TAC real_ss [LEFT_IMP_EXISTS_THM] THENL
21331  [ MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
21332    STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN
21333    ASM_REWRITE_TAC[] THEN STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN
21334    ASM_REWRITE_TAC[] THEN
21335    SUBGOAL_THEN ``cball(x:real,e) INTER s = cball (x,e) INTER v``
21336    SUBST1_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
21337    ASM_SIMP_TAC real_ss [COMPACT_CBALL, COMPACT_INTER, COMPACT_IMP_CLOSED],
21338
21339    X_GEN_TAC ``e:real`` THEN STRIP_TAC THEN
21340    EXISTS_TAC ``ball(x:real,e) INTER s`` THEN
21341    EXISTS_TAC ``cball(x:real,e) INTER s`` THEN
21342    REWRITE_TAC[GSYM OPEN_IN_CONTAINS_CBALL] THEN
21343    ASM_SIMP_TAC real_ss [IN_INTER, CENTRE_IN_BALL, INTER_SUBSET] THEN
21344    ASM_SIMP_TAC real_ss [COMPACT_EQ_BOUNDED_CLOSED, BOUNDED_INTER, BOUNDED_CBALL] THEN
21345    ONCE_REWRITE_TAC[INTER_COMM] THEN
21346    SIMP_TAC real_ss [OPEN_IN_OPEN_INTER, OPEN_BALL] THEN
21347    REWRITE_TAC [SUBSET_DEF, IN_INTER] THEN GEN_TAC THEN DISCH_TAC THEN ASM_REWRITE_TAC [] THEN
21348    METIS_TAC[SUBSET_DEF, BALL_SUBSET_CBALL]]);
21349
21350val LOCALLY_COMPACT_INTER_CBALLS = store_thm ("LOCALLY_COMPACT_INTER_CBALLS",
21351 ``!s:real->bool.
21352      locally compact s <=>
21353      !x. x IN s ==> ?e. &0 < e /\ !d. d <= e ==> closed(cball(x,d) INTER s)``,
21354  GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_INTER_CBALL] THEN
21355  EQ_TAC THENL [ALL_TAC, METIS_TAC[REAL_LE_REFL]] THEN
21356  DISCH_TAC THEN X_GEN_TAC ``x:real`` THEN POP_ASSUM (MP_TAC o SPEC ``x:real``) THEN
21357  ASM_CASES_TAC ``(x:real) IN s`` THEN ASM_REWRITE_TAC[] THEN
21358  STRIP_TAC THEN EXISTS_TAC ``e:real`` THEN ASM_REWRITE_TAC[] THEN
21359  GEN_TAC THEN DISCH_TAC THEN
21360  SUBGOAL_THEN
21361   ``cball(x:real,d) INTER s = cball(x,d) INTER cball(x,e) INTER s``
21362  SUBST1_TAC THENL
21363  [ REWRITE_TAC[INTER_ASSOC, GSYM CBALL_MIN_INTER] THEN
21364    AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
21365    BINOP_TAC THEN REWRITE_TAC[min_def] THEN PROVE_TAC [],
21366    ASM_SIMP_TAC real_ss [GSYM INTER_ASSOC, CLOSED_INTER, CLOSED_CBALL] ]);
21367
21368val LOCALLY_COMPACT_COMPACT = store_thm ("LOCALLY_COMPACT_COMPACT",
21369 ``!s:real->bool.
21370        locally compact s <=>
21371        !k. k SUBSET s /\ compact k
21372            ==> ?u v. k SUBSET u /\
21373                      u SUBSET v /\
21374                      v SUBSET s /\
21375                      open_in (subtopology euclidean s) u /\
21376                      compact v``,
21377  GEN_TAC THEN GEN_REWR_TAC LAND_CONV [LOCALLY_COMPACT] THEN EQ_TAC THEN
21378  REPEAT STRIP_TAC THENL
21379   [ALL_TAC, METIS_TAC[SING_SUBSET, COMPACT_SING]] THEN
21380  UNDISCH_TAC ``!x. x IN s ==>
21381        ?u v. x IN u /\ u SUBSET v /\ v SUBSET s /\
21382          open_in (subtopology euclidean s) u /\ compact v`` THEN DISCH_TAC THEN
21383  FIRST_X_ASSUM(MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN
21384  SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN
21385  MAP_EVERY X_GEN_TAC [``u:real->real->bool``, ``v:real->real->bool``] THEN
21386  DISCH_TAC THEN UNDISCH_TAC ``compact k`` THEN DISCH_TAC THEN
21387  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE
21388   [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN
21389  DISCH_THEN(MP_TAC o SPEC ``IMAGE (\x:real. k INTER u x) k``) THEN
21390  ASM_SIMP_TAC std_ss [FORALL_IN_IMAGE, BIGUNION_IMAGE] THEN
21391  KNOW_TAC ``(!(x :real).
21392    x IN (k :real -> bool) ==>
21393    open_in (subtopology euclidean k)
21394      (k INTER (u :real -> real -> bool) x)) /\
21395    k SUBSET {y | ?(x :real). x IN k /\ y IN k INTER u x}`` THENL
21396   [CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
21397    REPEAT STRIP_TAC THEN MATCH_MP_TAC OPEN_IN_SUBTOPOLOGY_INTER_SUBSET THEN
21398    EXISTS_TAC ``s:real->bool`` THEN ASM_REWRITE_TAC[] THEN
21399    MATCH_MP_TAC OPEN_IN_INTER THEN REWRITE_TAC[OPEN_IN_REFL] THEN
21400    ASM_SET_TAC[],
21401    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
21402    ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
21403    SIMP_TAC std_ss [EXISTS_FINITE_SUBSET_IMAGE, BIGUNION_IMAGE] THEN
21404    DISCH_THEN(X_CHOOSE_THEN ``t:real->bool`` STRIP_ASSUME_TAC) THEN
21405    EXISTS_TAC ``BIGUNION(IMAGE (u:real->real->bool) t)`` THEN
21406    EXISTS_TAC ``BIGUNION(IMAGE (v:real->real->bool) t)`` THEN
21407    REPEAT CONJ_TAC THENL
21408     [ALL_TAC, ALL_TAC, ALL_TAC, MATCH_MP_TAC OPEN_IN_BIGUNION,
21409      MATCH_MP_TAC COMPACT_BIGUNION THEN ASM_SIMP_TAC std_ss [IMAGE_FINITE]] THEN
21410    ASM_SET_TAC[]]);
21411
21412val LOCALLY_COMPACT_COMPACT_ALT = store_thm ("LOCALLY_COMPACT_COMPACT_ALT",
21413 ``!s:real->bool.
21414        locally compact s <=>
21415        !k. k SUBSET s /\ compact k
21416            ==> ?u. k SUBSET u /\
21417                    open_in (subtopology euclidean s) u /\
21418                    compact(closure u) /\ closure u SUBSET s``,
21419  GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_COMPACT] THEN EQ_TAC THEN
21420  DISCH_TAC THEN X_GEN_TAC ``k:real->bool`` THEN DISCH_TAC THEN
21421  FIRST_X_ASSUM(MP_TAC o SPEC ``k:real->bool``) THEN ASM_REWRITE_TAC[] THEN
21422  DISCH_THEN (X_CHOOSE_TAC ``u:real->bool``) THEN EXISTS_TAC ``u:real->bool`` THEN
21423  POP_ASSUM MP_TAC THEN
21424  METIS_TAC[CLOSURE_SUBSET, SUBSET_TRANS, CLOSURE_MINIMAL,
21425            COMPACT_CLOSURE, BOUNDED_SUBSET, COMPACT_EQ_BOUNDED_CLOSED]);
21426
21427val LOCALLY_COMPACT_COMPACT_SUBOPEN = store_thm ("LOCALLY_COMPACT_COMPACT_SUBOPEN",
21428 ``!s:real->bool.
21429        locally compact s <=>
21430        !k t. k SUBSET s /\ compact k /\ open t /\ k SUBSET t
21431              ==> ?u v. k SUBSET u /\ u SUBSET v /\ u SUBSET t /\ v SUBSET s /\
21432                        open_in (subtopology euclidean s) u /\
21433                        compact v``,
21434  GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_COMPACT] THEN
21435  EQ_TAC THEN DISCH_TAC THEN REPEAT STRIP_TAC THENL
21436   [FIRST_X_ASSUM(MP_TAC o SPEC ``k:real->bool``) THEN
21437    ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN
21438    MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
21439    STRIP_TAC THEN MAP_EVERY EXISTS_TAC
21440     [``u INTER t:real->bool``, ``closure(u INTER t:real->bool)``] THEN
21441    REWRITE_TAC[CLOSURE_SUBSET, INTER_SUBSET] THEN REPEAT CONJ_TAC THENL
21442     [ASM_SET_TAC[],
21443      MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC ``closure(u:real->bool)`` THEN
21444      SIMP_TAC std_ss [SUBSET_CLOSURE, INTER_SUBSET] THEN
21445      MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC ``v:real->bool`` THEN ASM_REWRITE_TAC[] THEN
21446      MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED],
21447      ASM_SIMP_TAC std_ss [OPEN_IN_INTER_OPEN],
21448      REWRITE_TAC[COMPACT_CLOSURE] THEN
21449      ASM_MESON_TAC[BOUNDED_SUBSET, INTER_SUBSET, SUBSET_TRANS,
21450                    COMPACT_IMP_BOUNDED]],
21451    FIRST_X_ASSUM(MP_TAC o SPECL [``k:real->bool``, ``univ(:real)``]) THEN
21452    ASM_REWRITE_TAC[OPEN_UNIV, SUBSET_UNIV]]);
21453
21454val OPEN_IMP_LOCALLY_COMPACT = store_thm ("OPEN_IMP_LOCALLY_COMPACT",
21455 ``!s:real->bool. open s ==> locally compact s``,
21456  REPEAT STRIP_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN
21457  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
21458  UNDISCH_TAC ``open s`` THEN DISCH_TAC THEN FIRST_ASSUM
21459   (MP_TAC o REWRITE_RULE [OPEN_CONTAINS_CBALL]) THEN
21460  DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
21461  DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
21462  MAP_EVERY EXISTS_TAC [``ball(x:real,e)``, ``cball(x:real,e)``] THEN
21463  ASM_REWRITE_TAC[BALL_SUBSET_CBALL, CENTRE_IN_BALL, COMPACT_CBALL] THEN
21464  MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN ASM_REWRITE_TAC[OPEN_BALL] THEN
21465  MATCH_MP_TAC SUBSET_TRANS THEN METIS_TAC [BALL_SUBSET_CBALL]);
21466
21467val CLOSED_IMP_LOCALLY_COMPACT = store_thm ("CLOSED_IMP_LOCALLY_COMPACT",
21468 ``!s:real->bool. closed s ==> locally compact s``,
21469  REPEAT STRIP_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN
21470  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN MAP_EVERY EXISTS_TAC
21471   [``s INTER ball(x:real,&1)``, ``s INTER cball(x:real,&1)``] THEN
21472  ASM_REWRITE_TAC[IN_INTER, CENTRE_IN_BALL, INTER_SUBSET, REAL_LT_01] THEN
21473  ASM_SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_BALL] THEN
21474  ASM_SIMP_TAC std_ss [CLOSED_INTER_COMPACT, COMPACT_CBALL] THEN
21475  MP_TAC(ISPECL [``x:real``, ``&1:real``] BALL_SUBSET_CBALL) THEN ASM_SET_TAC[]);
21476
21477val IS_INTERVAL_IMP_LOCALLY_COMPACT = store_thm ("IS_INTERVAL_IMP_LOCALLY_COMPACT",
21478 ``!s:real->bool. is_interval s ==> locally compact s``,
21479  REPEAT STRIP_TAC THEN REWRITE_TAC[LOCALLY_COMPACT] THEN
21480  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
21481  MP_TAC(ISPECL [``s:real->bool``, ``x:real``]
21482   INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD) THEN
21483  ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN
21484  MAP_EVERY X_GEN_TAC [``a:real``, ``b:real``, ``d:real``] THEN STRIP_TAC THEN
21485  MAP_EVERY EXISTS_TAC
21486   [``s INTER ball(x:real,d)``, ``interval[a:real,b]``] THEN
21487  ASM_SIMP_TAC std_ss [COMPACT_INTERVAL, OPEN_IN_OPEN_INTER, OPEN_BALL] THEN
21488  ASM_REWRITE_TAC[CENTRE_IN_BALL, IN_INTER] THEN ASM_SET_TAC[]);
21489
21490val LOCALLY_COMPACT_UNIV = store_thm ("LOCALLY_COMPACT_UNIV",
21491 ``locally compact univ(:real)``,
21492  SIMP_TAC std_ss [OPEN_IMP_LOCALLY_COMPACT, OPEN_UNIV]);
21493
21494val LOCALLY_COMPACT_INTER = store_thm ("LOCALLY_COMPACT_INTER",
21495 ``!s t:real->bool.
21496        locally compact s /\ locally compact t
21497        ==> locally compact (s INTER t)``,
21498  MATCH_MP_TAC LOCALLY_INTER THEN REWRITE_TAC[COMPACT_INTER]);
21499
21500val LOCALLY_COMPACT_OPEN_IN = store_thm ("LOCALLY_COMPACT_OPEN_IN",
21501 ``!s t:real->bool.
21502        open_in (subtopology euclidean s) t /\ locally compact s
21503        ==> locally compact t``,
21504  REWRITE_TAC[OPEN_IN_OPEN] THEN REPEAT STRIP_TAC THEN
21505  ASM_SIMP_TAC std_ss [LOCALLY_COMPACT_INTER, OPEN_IMP_LOCALLY_COMPACT]);
21506
21507val LOCALLY_COMPACT_CLOSED_IN = store_thm ("LOCALLY_COMPACT_CLOSED_IN",
21508 ``!s t:real->bool.
21509        closed_in (subtopology euclidean s) t /\ locally compact s
21510        ==> locally compact t``,
21511  REWRITE_TAC[CLOSED_IN_CLOSED] THEN REPEAT STRIP_TAC THEN
21512  ASM_SIMP_TAC std_ss [LOCALLY_COMPACT_INTER, CLOSED_IMP_LOCALLY_COMPACT]);
21513
21514val LOCALLY_COMPACT_DELETE = store_thm ("LOCALLY_COMPACT_DELETE",
21515 ``!s a:real. locally compact s ==> locally compact (s DELETE a)``,
21516  REPEAT STRIP_TAC THEN MATCH_MP_TAC LOCALLY_COMPACT_OPEN_IN THEN
21517  EXISTS_TAC ``s:real->bool`` THEN
21518  ASM_SIMP_TAC std_ss [OPEN_IN_DELETE, OPEN_IN_REFL]);
21519
21520val HOMEOMORPHIC_LOCAL_COMPACTNESS = store_thm ("HOMEOMORPHIC_LOCAL_COMPACTNESS",
21521 ``!s t:real->bool.
21522        s homeomorphic t ==> (locally compact s <=> locally compact t)``,
21523  MATCH_MP_TAC HOMEOMORPHIC_LOCALLY THEN
21524  REWRITE_TAC[HOMEOMORPHIC_COMPACTNESS]);
21525
21526val LOCALLY_COMPACT_TRANSLATION_EQ = store_thm ("LOCALLY_COMPACT_TRANSLATION_EQ",
21527 ``!a:real s. locally compact (IMAGE (\x. a + x) s) <=>
21528                locally compact s``,
21529  MATCH_MP_TAC LOCALLY_TRANSLATION THEN
21530  REWRITE_TAC[COMPACT_TRANSLATION_EQ]);
21531
21532val LOCALLY_CLOSED = store_thm ("LOCALLY_CLOSED",
21533 ``!s:real->bool. locally closed s <=> locally compact s``,
21534  GEN_TAC THEN EQ_TAC THENL
21535   [ALL_TAC, MESON_TAC[LOCALLY_MONO, COMPACT_IMP_CLOSED]] THEN
21536  REWRITE_TAC[locally] THEN DISCH_TAC THEN
21537  MAP_EVERY X_GEN_TAC [``w:real->bool``, ``x:real``] THEN STRIP_TAC THEN
21538  FIRST_X_ASSUM(MP_TAC o SPECL [``w:real->bool``, ``x:real``]) THEN
21539  ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN
21540  MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
21541  STRIP_TAC THEN
21542  EXISTS_TAC ``u INTER ball(x:real,&1)`` THEN
21543  EXISTS_TAC ``v INTER cball(x:real,&1)`` THEN
21544  ASM_SIMP_TAC std_ss [OPEN_IN_INTER_OPEN, OPEN_BALL] THEN
21545  ASM_SIMP_TAC std_ss [CLOSED_INTER_COMPACT, COMPACT_CBALL] THEN
21546  ASM_REWRITE_TAC[IN_INTER, CENTRE_IN_BALL, REAL_LT_01] THEN
21547  MP_TAC(ISPEC ``x:real`` BALL_SUBSET_CBALL) THEN ASM_SET_TAC[]);
21548
21549val LOCALLY_COMPACT_OPEN_UNION = store_thm ("LOCALLY_COMPACT_OPEN_UNION",
21550 ``!s t:real->bool.
21551        locally compact s /\ locally compact t /\
21552        open_in (subtopology euclidean (s UNION t)) s /\
21553        open_in (subtopology euclidean (s UNION t)) t
21554        ==> locally compact (s UNION t)``,
21555  REPEAT GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_INTER_CBALL, IN_UNION] THEN
21556  STRIP_TAC THEN X_GEN_TAC ``x:real`` THEN STRIP_TAC THENL
21557   [UNDISCH_TAC ``!x. x IN s ==> ?e. 0 < e /\ closed (cball (x,e) INTER s)`` THEN
21558    DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC ``x:real``) THEN
21559    UNDISCH_TAC ``open_in (subtopology euclidean (s UNION t)) s`` THEN DISCH_TAC THEN
21560    FIRST_ASSUM (MP_TAC o REWRITE_RULE [OPEN_IN_CONTAINS_CBALL]),
21561    UNDISCH_TAC ``!x. x IN t ==> ?e. 0 < e /\ closed (cball (x,e) INTER t)`` THEN
21562    DISCH_TAC THEN FIRST_ASSUM (MP_TAC o SPEC ``x:real``) THEN
21563    UNDISCH_TAC ``open_in (subtopology euclidean (s UNION t)) t`` THEN DISCH_TAC THEN
21564    FIRST_ASSUM (MP_TAC o REWRITE_RULE [OPEN_IN_CONTAINS_CBALL])] THEN
21565  DISCH_THEN(MP_TAC o SPEC ``x:real`` o CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN
21566  UNDISCH_TAC ``!x. x IN s ==> ?e. 0 < e /\ closed (cball (x,e) INTER s)`` THEN
21567  DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN
21568  UNDISCH_TAC `` !x. x IN t ==> ?e. 0 < e /\ closed (cball (x,e) INTER t)`` THEN
21569  DISCH_THEN (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC [] THENL
21570  [DISCH_TAC THEN DISCH_THEN (X_CHOOSE_TAC ``e:real``),
21571   DISCH_THEN (X_CHOOSE_TAC ``e:real``) THEN DISCH_TAC] THEN
21572  DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
21573  EXISTS_TAC ``min d e:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
21574  REWRITE_TAC[CBALL_MIN_INTER, INTER_ASSOC] THEN
21575  FIRST_ASSUM(MP_TAC o MATCH_MP (SET_RULE
21576   ``u INTER st SUBSET s ==> s SUBSET st ==> (u INTER st = u INTER s)``)) THEN
21577  REWRITE_TAC[SUBSET_UNION] THEN
21578  ONCE_REWRITE_TAC [SET_RULE ``a INTER b INTER c = b INTER (a INTER c)``] THEN
21579  DISCH_THEN SUBST1_TAC THEN
21580  ONCE_REWRITE_TAC [SET_RULE ``a INTER (b INTER c) = b INTER (a INTER c)``] THEN
21581  METIS_TAC[CLOSED_INTER, CLOSED_CBALL, INTER_ACI]);
21582
21583val LOCALLY_COMPACT_CLOSED_UNION = store_thm ("LOCALLY_COMPACT_CLOSED_UNION",
21584 ``!s t:real->bool.
21585        locally compact s /\ locally compact t /\
21586        closed_in (subtopology euclidean (s UNION t)) s /\
21587        closed_in (subtopology euclidean (s UNION t)) t
21588        ==> locally compact (s UNION t)``,
21589  REPEAT GEN_TAC THEN REWRITE_TAC[LOCALLY_COMPACT_INTER_CBALL, IN_UNION] THEN
21590  STRIP_TAC THEN X_GEN_TAC ``x:real`` THEN
21591  DISCH_THEN(STRIP_ASSUME_TAC o MATCH_MP (TAUT
21592   `p \/ q ==> p /\ q \/ p /\ ~q \/ q /\ ~p`))
21593  THENL
21594   [FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN
21595    FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN
21596    ASM_SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM] THEN
21597    X_GEN_TAC ``d:real`` THEN STRIP_TAC THEN
21598    X_GEN_TAC ``e:real`` THEN STRIP_TAC THEN
21599    EXISTS_TAC ``min d e:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
21600    SIMP_TAC std_ss [SET_RULE ``u INTER (s UNION t) = u INTER s UNION u INTER t``] THEN
21601    MATCH_MP_TAC CLOSED_UNION THEN REWRITE_TAC[CBALL_MIN_INTER] THEN CONJ_TAC THENL
21602    [ONCE_REWRITE_TAC [SET_RULE ``a INTER b INTER c = b INTER (a INTER c)``],
21603     REWRITE_TAC [GSYM INTER_ASSOC]] THEN
21604    METIS_TAC[CLOSED_CBALL, CLOSED_INTER, INTER_ACI],
21605    UNDISCH_TAC ``!x. x IN s ==> ?e. 0 < e /\ closed (cball (x,e) INTER s)`` THEN
21606    DISCH_TAC THEN FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
21607    DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
21608    UNDISCH_TAC ``closed_in (subtopology euclidean (s UNION t)) t`` THEN DISCH_TAC THEN
21609    FIRST_X_ASSUM (STRIP_ASSUME_TAC o REWRITE_RULE [closed_in]),
21610    FIRST_X_ASSUM (MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
21611    DISCH_THEN(X_CHOOSE_THEN ``e:real`` STRIP_ASSUME_TAC) THEN
21612    UNDISCH_TAC ``closed_in (subtopology euclidean (s UNION t)) s`` THEN DISCH_TAC THEN
21613    FIRST_X_ASSUM (STRIP_ASSUME_TAC o REWRITE_RULE [closed_in])] THEN
21614  FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_CONTAINS_CBALL]) THEN
21615  REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY, IN_DIFF, IN_UNION] THEN
21616  DISCH_THEN(MP_TAC o SPEC ``x:real`` o CONJUNCT2) THEN ASM_SIMP_TAC std_ss [] THEN
21617  DISCH_THEN(X_CHOOSE_THEN ``d:real`` STRIP_ASSUME_TAC) THEN
21618  EXISTS_TAC ``min d e:real`` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THENL
21619   [SUBGOAL_THEN ``cball (x:real,min d e) INTER (s UNION t) =
21620                  cball(x,d) INTER cball (x,e) INTER s`` SUBST1_TAC
21621    THENL [REWRITE_TAC[CBALL_MIN_INTER] THEN ASM_SET_TAC[], ALL_TAC],
21622    SUBGOAL_THEN ``cball (x:real,min d e) INTER (s UNION t) =
21623                  cball(x,d) INTER cball (x,e) INTER t`` SUBST1_TAC
21624    THENL [REWRITE_TAC[CBALL_MIN_INTER] THEN ASM_SET_TAC[], ALL_TAC]] THEN
21625  ASM_MESON_TAC[GSYM INTER_ASSOC, CLOSED_INTER, CLOSED_CBALL]);
21626
21627val OPEN_IN_LOCALLY_COMPACT = store_thm ("OPEN_IN_LOCALLY_COMPACT",
21628 ``!s t:real->bool.
21629        locally compact s
21630        ==> (open_in (subtopology euclidean s) t <=>
21631             t SUBSET s /\
21632             !k. compact k /\ k SUBSET s
21633                 ==> open_in (subtopology euclidean k) (k INTER t))``,
21634  REPEAT(STRIP_TAC ORELSE EQ_TAC) THENL
21635   [ASM_MESON_TAC[OPEN_IN_IMP_SUBSET],
21636    UNDISCH_TAC ``open_in (subtopology euclidean s) t`` THEN DISCH_TAC THEN
21637    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [OPEN_IN_OPEN]) THEN
21638    REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_THEN (X_CHOOSE_TAC ``t':real->bool``) THEN
21639    EXISTS_TAC ``t':real->bool`` THEN ASM_SET_TAC[],
21640    ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN
21641    X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN
21642    UNDISCH_TAC ``locally compact s`` THEN DISCH_TAC THEN
21643    FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LOCALLY_COMPACT]) THEN
21644    DISCH_THEN(MP_TAC o SPEC ``a:real``) THEN
21645    KNOW_TAC ``a IN s:real->bool`` THENL
21646    [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
21647     SIMP_TAC std_ss [LEFT_IMP_EXISTS_THM]] THEN
21648    MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
21649    STRIP_TAC THEN EXISTS_TAC ``t INTER u:real->bool`` THEN
21650    ASM_REWRITE_TAC[IN_INTER, INTER_SUBSET] THEN
21651    MATCH_MP_TAC OPEN_IN_TRANS THEN EXISTS_TAC ``u:real->bool`` THEN
21652    ASM_REWRITE_TAC[] THEN
21653    FIRST_X_ASSUM(MP_TAC o SPEC ``closure u:real->bool``) THEN
21654    KNOW_TAC ``compact (closure u) /\ closure u SUBSET s`` THENL
21655     [SUBGOAL_THEN ``(closure u:real->bool) SUBSET v`` MP_TAC THENL
21656       [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED],
21657        REWRITE_TAC[COMPACT_CLOSURE] THEN
21658        ASM_MESON_TAC[SUBSET_TRANS, BOUNDED_SUBSET, COMPACT_IMP_BOUNDED]],
21659      DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
21660      REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_THEN (X_CHOOSE_TAC ``t':real->bool``) THEN
21661      EXISTS_TAC ``t':real->bool`` THEN ASM_REWRITE_TAC [] THEN
21662      MP_TAC(ISPEC ``u:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[]]]);
21663
21664val LOCALLY_COMPACT_PROPER_IMAGE_EQ = store_thm ("LOCALLY_COMPACT_PROPER_IMAGE_EQ",
21665 ``!f:real->real s.
21666        f continuous_on s /\
21667        (!k. k SUBSET (IMAGE f s) /\ compact k
21668             ==> compact {x | x IN s /\ f x IN k})
21669        ==> (locally compact s <=> locally compact (IMAGE f s))``,
21670  REPEAT STRIP_TAC THEN
21671  MP_TAC(ISPECL [``f:real->real``, ``s:real->bool``,
21672                 ``IMAGE (f:real->real) s``] PROPER_MAP) THEN
21673  ASM_REWRITE_TAC[SUBSET_REFL] THEN STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
21674   [REWRITE_TAC[LOCALLY_COMPACT_ALT] THEN X_GEN_TAC ``y:real`` THEN
21675    DISCH_TAC THEN FIRST_ASSUM(MP_TAC o SPEC ``y:real``) THEN
21676    ASM_REWRITE_TAC[] THEN UNDISCH_TAC ``locally compact s`` THEN DISCH_TAC THEN
21677    FIRST_ASSUM(MP_TAC o REWRITE_RULE [LOCALLY_COMPACT_COMPACT_ALT]) THEN
21678    DISCH_THEN(MP_TAC o SPEC ``{x | x IN s /\ ((f:real->real) x = y)}``) THEN
21679    ONCE_REWRITE_TAC [METIS [] ``(f x = y) = (\x. (f x = y)) x``] THEN
21680    ASM_SIMP_TAC std_ss [SUBSET_RESTRICT] THEN
21681    DISCH_THEN(X_CHOOSE_THEN ``u:real->bool`` STRIP_ASSUME_TAC) THEN
21682    SUBGOAL_THEN
21683     ``?v. open_in (subtopology euclidean (IMAGE f s)) v /\
21684          y IN v /\
21685          {x | x IN s /\ (f:real->real) x IN v} SUBSET u``
21686    MP_TAC THENL
21687     [GEN_REWR_TAC (BINDER_CONV o RAND_CONV o LAND_CONV)
21688       [GSYM SING_SUBSET] THEN
21689      MATCH_MP_TAC CLOSED_MAP_OPEN_SUPERSET_PREIMAGE THEN
21690      ASM_REWRITE_TAC[SING_SUBSET, IN_SING],
21691      DISCH_THEN (X_CHOOSE_TAC ``v:real->bool``) THEN EXISTS_TAC ``v:real->bool`` THEN
21692      POP_ASSUM MP_TAC THEN
21693      STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
21694      SUBGOAL_THEN ``closure v SUBSET IMAGE (f:real->real) (closure u)``
21695      ASSUME_TAC THENL
21696       [MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC ``closure(IMAGE (f:real->real) u)`` THEN
21697        CONJ_TAC THENL
21698         [MATCH_MP_TAC SUBSET_CLOSURE THEN
21699          REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET)) THEN
21700          ASM_SET_TAC[],
21701          MATCH_MP_TAC CLOSURE_MINIMAL THEN
21702          SIMP_TAC std_ss [CLOSURE_SUBSET, IMAGE_SUBSET] THEN
21703          MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
21704          MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
21705          ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]],
21706        CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
21707        REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED, CLOSED_CLOSURE] THEN
21708        FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
21709          BOUNDED_SUBSET)) THEN
21710        MATCH_MP_TAC COMPACT_IMP_BOUNDED THEN
21711        MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
21712        ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]],
21713    REWRITE_TAC[LOCALLY_COMPACT_ALT] THEN
21714    X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
21715    UNDISCH_TAC ``locally compact (IMAGE (f :real -> real) (s :real -> bool))`` THEN
21716    DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LOCALLY_COMPACT_ALT]) THEN
21717    DISCH_THEN(MP_TAC o SPEC ``(f:real->real) x``) THEN
21718    ASM_SIMP_TAC std_ss [FUN_IN_IMAGE] THEN
21719    DISCH_THEN(X_CHOOSE_THEN ``v:real->bool`` STRIP_ASSUME_TAC) THEN
21720    FIRST_X_ASSUM(MP_TAC o SPEC ``closure v:real->bool``) THEN
21721    ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
21722    EXISTS_TAC ``{x | x IN s /\ (f:real->real) x IN v}`` THEN
21723    ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN CONJ_TAC THENL
21724     [MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN
21725      ASM_MESON_TAC[SUBSET_REFL],
21726      ALL_TAC] THEN
21727    SUBGOAL_THEN
21728     ``closure {x | x IN s /\ f x IN v} SUBSET
21729       {x | x IN s /\ (f:real->real) x IN closure v}``
21730    ASSUME_TAC THENL
21731     [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED] THEN
21732      MP_TAC(ISPEC ``v:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[],
21733      CONJ_TAC THENL [ALL_TAC, ASM_SET_TAC[]] THEN
21734      SIMP_TAC std_ss [COMPACT_EQ_BOUNDED_CLOSED, CLOSED_CLOSURE] THEN
21735      METIS_TAC[COMPACT_IMP_BOUNDED, BOUNDED_SUBSET]]]);
21736
21737val LOCALLY_COMPACT_PROPER_IMAGE = store_thm ("LOCALLY_COMPACT_PROPER_IMAGE",
21738 ``!f:real->real s.
21739        f continuous_on s /\
21740        (!k. k SUBSET (IMAGE f s) /\ compact k
21741             ==> compact {x | x IN s /\ f x IN k}) /\
21742        locally compact s
21743        ==> locally compact (IMAGE f s)``,
21744  METIS_TAC[LOCALLY_COMPACT_PROPER_IMAGE_EQ]);
21745
21746val MUMFORD_LEMMA = store_thm ("MUMFORD_LEMMA",
21747 ``!f:real->real s t y.
21748        f continuous_on s /\ IMAGE f s SUBSET t /\ locally compact s /\
21749        y IN t /\ compact {x | x IN s /\ (f x = y)}
21750        ==> ?u v. open_in (subtopology euclidean s) u /\
21751                  open_in (subtopology euclidean t) v /\
21752                  {x | x IN s /\ (f x = y)} SUBSET u /\ y IN v /\
21753                  IMAGE f u SUBSET v /\
21754                  (!k. k SUBSET v /\ compact k
21755                       ==> compact {x | x IN u /\ f x IN k})``,
21756  REPEAT STRIP_TAC THEN
21757  FIRST_ASSUM(MP_TAC o SPEC ``{x | x IN s /\ ((f:real->real) x = y)}`` o
21758   REWRITE_RULE [LOCALLY_COMPACT_COMPACT]) THEN
21759  ASM_SIMP_TAC std_ss [SUBSET_RESTRICT, LEFT_IMP_EXISTS_THM] THEN
21760  MAP_EVERY X_GEN_TAC [``u:real->bool``, ``v:real->bool``] THEN
21761  STRIP_TAC THEN
21762  SUBGOAL_THEN ``(closure u:real->bool) SUBSET v`` ASSUME_TAC THENL
21763   [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED],
21764    ALL_TAC] THEN
21765  SUBGOAL_THEN ``compact(closure u:real->bool)`` ASSUME_TAC THENL
21766   [ASM_REWRITE_TAC[COMPACT_CLOSURE] THEN
21767    ASM_MESON_TAC[BOUNDED_SUBSET, COMPACT_IMP_BOUNDED],
21768    ALL_TAC] THEN
21769  MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN
21770  SUBGOAL_THEN
21771   ``!b. open_in (subtopology euclidean t) b /\ y IN b
21772        ==> u INTER {x | x IN s /\ (f:real->real) x IN b} PSUBSET
21773            closure u INTER {x | x IN s /\ (f:real->real) x IN b}``
21774  MP_TAC THENL
21775   [REPEAT STRIP_TAC THEN REWRITE_TAC[PSUBSET_DEF] THEN
21776    SIMP_TAC std_ss [CLOSURE_SUBSET,
21777             SET_RULE ``s SUBSET t ==> s INTER u SUBSET t INTER u``] THEN
21778    MATCH_MP_TAC(MESON[] ``!P. ~P s /\ P t ==> ~(s = t)``) THEN
21779    EXISTS_TAC
21780     ``\a. !k. k SUBSET b /\ compact k
21781              ==> compact {x | x IN a /\ (f:real->real) x IN k}`` THEN
21782    SIMP_TAC std_ss [] THEN CONJ_TAC THENL
21783     [KNOW_TAC ``(open_in (subtopology euclidean s) (u INTER {x | x IN s /\ f x IN b})
21784                  ==> {x | x IN s /\ (f x = y)} SUBSET u INTER {x | x IN s /\ f x IN b}
21785                  ==> IMAGE f (u INTER {x | x IN s /\ f x IN b}) SUBSET b
21786                  ==> ~(!k. k SUBSET b /\ compact k
21787                  ==> compact
21788                    {x | x IN u INTER {x | x IN s /\ f x IN b} /\ f x IN k}))
21789                  ==> ~(!k. k SUBSET b /\ compact k
21790                     ==> compact
21791                     {x | x IN u INTER {x | x IN s /\ f x IN b} /\ f x IN k})`` THENL
21792       [ALL_TAC, METIS_TAC []] THEN
21793       KNOW_TAC ``open_in (subtopology euclidean s)
21794                  (u INTER {x | x IN s /\ (f:real->real) x IN b})`` THENL
21795       [MATCH_MP_TAC OPEN_IN_INTER THEN ASM_SIMP_TAC std_ss [] THEN
21796        MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN ASM_SET_TAC[],
21797        ASM_SET_TAC[]],
21798      X_GEN_TAC ``k:real->bool`` THEN STRIP_TAC THEN
21799      SUBGOAL_THEN
21800       ``{x | x IN closure u INTER {x | x IN s /\ f x IN b} /\ f x IN k} =
21801        v INTER {x | x IN closure u /\ (f:real->real) x IN k}``
21802      SUBST1_TAC THENL [ASM_SET_TAC[], MATCH_MP_TAC COMPACT_INTER_CLOSED] THEN
21803      ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN
21804      ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED, CLOSED_CLOSURE] THEN
21805      ASM_MESON_TAC[CONTINUOUS_ON_SUBSET, SUBSET_TRANS]],
21806    DISCH_THEN(MP_TAC o GEN ``n:num`` o SPEC
21807     ``t INTER ball(y:real,inv(&n + &1))``) THEN
21808    SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_BALL, IN_INTER, CENTRE_IN_BALL] THEN
21809    ASM_REWRITE_TAC[REAL_LT_INV_EQ,
21810     METIS [REAL_LT, REAL_OF_NUM_ADD, GSYM ADD1, LESS_0] ``&0 < &n + &1:real``] THEN
21811    KNOW_TAC ``~(!n. ?x. x IN closure u /\
21812           ~(x IN u) /\
21813           x IN {x | x IN s /\ f x IN t /\ f x IN ball (y,inv (&n + &1))})`` THENL
21814    [ALL_TAC,
21815     METIS_TAC [CLOSURE_SUBSET, REAL_OF_NUM_ADD, SET_RULE
21816     ``u SUBSET u'
21817      ==> (u INTER t PSUBSET u' INTER t <=>
21818           ?x. x IN u' /\ ~(x IN u) /\ x IN t)``]] THEN
21819    KNOW_TAC ``~(?x. (!n. x n IN closure u) /\
21820       (!n. ~(x n IN u)) /\
21821       (!n. x n IN s) /\
21822       (!n. f (x n) IN t) /\
21823       (!n. dist (y,f (x n)) < inv (&n + &1)))`` THENL
21824    [ALL_TAC,
21825     SIMP_TAC std_ss [SKOLEM_THM, GSPECIFICATION, IN_BALL, FORALL_AND_THM] THEN
21826     METIS_TAC [SKOLEM_THM]] THEN
21827    DISCH_THEN(X_CHOOSE_THEN ``x:num->real`` STRIP_ASSUME_TAC) THEN
21828    MP_TAC(ISPEC ``closure u:real->bool`` compact) THEN
21829    ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC ``x:num->real``) THEN
21830    ASM_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN
21831    MAP_EVERY X_GEN_TAC [``l:real``, ``r:num->num``] THEN
21832    CCONTR_TAC THEN FULL_SIMP_TAC std_ss [] THEN
21833    SUBGOAL_THEN ``(f:real->real) l = y`` ASSUME_TAC THENL
21834     [MATCH_MP_TAC(ISPEC ``sequentially`` LIM_UNIQUE) THEN
21835      EXISTS_TAC ``(f:real->real) o x o (r:num->num)`` THEN
21836      ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN CONJ_TAC THENL
21837       [SUBGOAL_THEN ``(f:real->real) continuous_on closure u`` MP_TAC THENL
21838         [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET, SUBSET_TRANS], ALL_TAC] THEN
21839        REWRITE_TAC[CONTINUOUS_ON_SEQUENTIALLY] THEN
21840        DISCH_THEN MATCH_MP_TAC THEN ASM_SIMP_TAC std_ss [o_THM],
21841        REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC LIM_SUBSEQUENCE THEN
21842        ASM_SIMP_TAC std_ss [LIM_SEQUENTIALLY, o_THM] THEN
21843        CONJ_TAC THENL [METIS_TAC [], ALL_TAC] THEN
21844        X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN
21845        MP_TAC(SPEC ``e:real`` REAL_ARCH_INV) THEN
21846        ASM_REWRITE_TAC[] THEN DISCH_THEN (X_CHOOSE_TAC ``N:num``) THEN
21847        EXISTS_TAC ``N:num`` THEN X_GEN_TAC ``n:num`` THEN
21848        DISCH_TAC THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
21849        MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC ``inv(&n + &1:real)`` THEN
21850        ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_TRANS THEN
21851        EXISTS_TAC ``inv(&N:real)`` THEN ASM_REWRITE_TAC[] THEN
21852        MATCH_MP_TAC REAL_LT_INV2 THEN
21853        ASM_SIMP_TAC arith_ss [REAL_OF_NUM_ADD, REAL_LT]],
21854      UNDISCH_TAC ``open_in (subtopology euclidean s) u`` THEN DISCH_TAC THEN
21855      FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [open_in]) THEN
21856      DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC ``l:real``)) THEN
21857      SIMP_TAC std_ss [NOT_IMP, NOT_EXISTS_THM] THEN
21858      CONJ_TAC THENL [ASM_SET_TAC[], X_GEN_TAC ``e:real`` THEN
21859      CCONTR_TAC THEN FULL_SIMP_TAC std_ss []] THEN
21860      UNDISCH_TAC ``(((x :num -> real) o (r :num -> num) --> (l :real))
21861          sequentially :bool)`` THEN DISCH_TAC THEN
21862      FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [LIM_SEQUENTIALLY]) THEN
21863      DISCH_THEN(MP_TAC o SPEC ``e:real``) THEN ASM_REWRITE_TAC[] THEN
21864      DISCH_THEN(X_CHOOSE_THEN ``n:num`` (MP_TAC o SPEC ``n:num``)) THEN
21865      ASM_SIMP_TAC std_ss [LESS_EQ_REFL, o_THM] THEN ASM_SET_TAC[]]]);
21866
21867(* ------------------------------------------------------------------------- *)
21868(* Locally compact sets are closed in an open set and are homeomorphic       *)
21869(* to an absolutely closed set if we have one more dimension to play with.   *)
21870(* ------------------------------------------------------------------------- *)
21871
21872val LOCALLY_COMPACT_OPEN_INTER_CLOSURE = store_thm ("LOCALLY_COMPACT_OPEN_INTER_CLOSURE",
21873 ``!s:real->bool. locally compact s ==> ?t. open t /\ (s = t INTER closure s)``,
21874  GEN_TAC THEN SIMP_TAC std_ss [LOCALLY_COMPACT, OPEN_IN_OPEN, CLOSED_IN_CLOSED] THEN
21875  SIMP_TAC std_ss [GSYM LEFT_EXISTS_AND_THM, GSYM RIGHT_EXISTS_AND_THM] THEN
21876  ONCE_REWRITE_TAC [METIS [] ``(x IN s INTER t /\ s INTER t SUBSET v /\
21877                                v SUBSET s /\ open t /\ compact v) =
21878                         (\v t. x IN s INTER t /\ s INTER t SUBSET v /\
21879                                v SUBSET s /\ open t /\ compact v) v t``] THEN
21880  REWRITE_TAC[GSYM CONJ_ASSOC, TAUT `p /\ (x = y) /\ q <=> (x = y) /\ p /\ q`] THEN
21881  ONCE_REWRITE_TAC[MESON[] ``(?v t. P v t) <=> (?t v. P v t)``] THEN
21882  DISCH_TAC THEN POP_ASSUM (MP_TAC o SIMP_RULE std_ss [RIGHT_IMP_EXISTS_THM]) THEN
21883  SIMP_TAC std_ss [SKOLEM_THM, LEFT_IMP_EXISTS_THM] THEN
21884  MAP_EVERY X_GEN_TAC [``u:real->real->bool``, ``v:real->real->bool``] THEN
21885  DISCH_TAC THEN EXISTS_TAC ``BIGUNION (IMAGE (u:real->real->bool) s)`` THEN
21886  ASM_SIMP_TAC std_ss [CLOSED_CLOSURE, OPEN_BIGUNION, FORALL_IN_IMAGE] THEN
21887  REWRITE_TAC[INTER_BIGUNION] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC
21888   ``BIGUNION {v INTER s | v | v IN IMAGE (u:real->real->bool) s}`` THEN
21889  CONJ_TAC THENL
21890   [SIMP_TAC std_ss [BIGUNION_GSPEC, EXISTS_IN_IMAGE] THEN ASM_SET_TAC[], ALL_TAC] THEN
21891  AP_TERM_TAC THEN
21892  ONCE_REWRITE_TAC [METIS [] ``v INTER s = (\v. v INTER s:real->bool) v``] THEN
21893  MATCH_MP_TAC(SET_RULE ``(!x. x IN s ==> (f(g x) = f'(g x)))
21894    ==> ({f x | x IN IMAGE g s} = {f' x | x IN IMAGE g s})``) THEN
21895  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
21896  SIMP_TAC std_ss [GSYM SUBSET_ANTISYM_EQ] THEN CONJ_TAC THENL
21897   [MP_TAC(ISPEC ``s:real->bool`` CLOSURE_SUBSET) THEN ASM_SET_TAC[],
21898  REWRITE_TAC[SUBSET_INTER, INTER_SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN
21899  EXISTS_TAC ``closure((u:real->real->bool) x INTER s)`` THEN
21900  ASM_SIMP_TAC std_ss [OPEN_INTER_CLOSURE_SUBSET] THEN MATCH_MP_TAC SUBSET_TRANS THEN
21901  EXISTS_TAC ``(v:real->real->bool) x`` THEN
21902  ASM_SIMP_TAC std_ss [] THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN
21903  ASM_SIMP_TAC std_ss [COMPACT_IMP_CLOSED] THEN ASM_SET_TAC[]]);
21904
21905val LOCALLY_COMPACT_CLOSED_IN_OPEN = store_thm ("LOCALLY_COMPACT_CLOSED_IN_OPEN",
21906 ``!s:real->bool.
21907    locally compact s ==> ?t. open t /\ closed_in (subtopology euclidean t) s``,
21908  GEN_TAC THEN
21909  DISCH_THEN(MP_TAC o MATCH_MP LOCALLY_COMPACT_OPEN_INTER_CLOSURE) THEN
21910  STRIP_TAC THEN EXISTS_TAC ``t:real->bool`` THEN ASM_SIMP_TAC std_ss [] THEN
21911  FIRST_X_ASSUM SUBST1_TAC THEN
21912  SIMP_TAC std_ss [CLOSED_IN_CLOSED_INTER, CLOSED_CLOSURE]);
21913
21914val LOCALLY_COMPACT_CLOSED_INTER_OPEN = store_thm ("LOCALLY_COMPACT_CLOSED_INTER_OPEN",
21915 ``!s:real->bool.
21916        locally compact s <=> ?t u. closed t /\ open u /\ (s = t INTER u)``,
21917  MESON_TAC[CLOSED_IMP_LOCALLY_COMPACT, OPEN_IMP_LOCALLY_COMPACT,
21918            LOCALLY_COMPACT_INTER, INTER_COMM, CLOSED_CLOSURE,
21919            LOCALLY_COMPACT_OPEN_INTER_CLOSURE]);
21920
21921(* ------------------------------------------------------------------------- *)
21922(* Forms of the Baire propery of dense sets.                                 *)
21923(* ------------------------------------------------------------------------- *)
21924
21925val BAIRE = store_thm ("BAIRE",
21926 ``!g s:real->bool.
21927        locally compact s /\ COUNTABLE g /\
21928        (!t. t IN g
21929             ==> open_in (subtopology euclidean s) t /\ s SUBSET closure t)
21930        ==> s SUBSET closure(BIGINTER g)``,
21931  REPEAT STRIP_TAC THEN ASM_CASES_TAC ``g:(real->bool)->bool = {}`` THEN
21932  ASM_REWRITE_TAC[BIGINTER_EMPTY, CLOSURE_UNIV, SUBSET_UNIV] THEN
21933  MP_TAC(ISPEC ``g:(real->bool)->bool`` COUNTABLE_AS_IMAGE) THEN
21934  ASM_REWRITE_TAC[] THEN
21935  MAP_EVERY (C UNDISCH_THEN (K ALL_TAC))
21936   [``COUNTABLE(g:(real->bool)->bool)``,
21937    ``~(g:(real->bool)->bool = {})``] THEN
21938  DISCH_THEN(X_CHOOSE_THEN ``g:num->real->bool`` SUBST_ALL_TAC) THEN
21939  RULE_ASSUM_TAC(SIMP_RULE std_ss [FORALL_IN_IMAGE, IN_UNIV]) THEN
21940  REWRITE_TAC[SUBSET_DEF, CLOSURE_NONEMPTY_OPEN_INTER] THEN
21941  X_GEN_TAC ``a:real`` THEN DISCH_TAC THEN
21942  X_GEN_TAC ``v:real->bool`` THEN STRIP_TAC THEN
21943  MP_TAC(ISPECL
21944   [``\n:num u:real->bool.
21945        open_in (subtopology euclidean s) u /\ ~(u = {}) /\ u SUBSET v``,
21946    ``\n:num u v:real->bool.
21947       ?c. compact c /\ v SUBSET c /\ c SUBSET u /\ c SUBSET (g n)``]
21948   DEPENDENT_CHOICE) THEN
21949  SIMP_TAC std_ss [] THEN
21950  KNOW_TAC ``(?(a :real -> bool).
21951    open_in (subtopology euclidean (s :real -> bool)) a /\
21952    a <> ({} :real -> bool) /\ a SUBSET (v :real -> bool)) /\
21953 (!(n :num) (x :real -> bool).
21954    open_in (subtopology euclidean s) x /\ x <> ({} :real -> bool) /\
21955    x SUBSET v ==>
21956    ?(y :real -> bool).
21957      (open_in (subtopology euclidean s) y /\ y <> ({} :real -> bool) /\
21958       y SUBSET v) /\
21959      ?(c :real -> bool).
21960        compact c /\ y SUBSET c /\ c SUBSET x /\
21961        c SUBSET (g :num -> real -> bool) n)`` THENL
21962   [CONJ_TAC THENL
21963     [EXISTS_TAC ``s INTER v:real->bool`` THEN
21964      ASM_SIMP_TAC std_ss [OPEN_IN_OPEN_INTER] THEN ASM_SET_TAC[],
21965      ALL_TAC] THEN
21966    MAP_EVERY X_GEN_TAC [``n:num``, ``w:real->bool``] THEN STRIP_TAC THEN
21967    FIRST_X_ASSUM(STRIP_ASSUME_TAC o SPEC ``n:num``) THEN
21968    SUBGOAL_THEN ``?b:real. b IN w /\ b IN g(n:num)``
21969    STRIP_ASSUME_TAC THENL
21970     [UNDISCH_TAC ``open_in (subtopology euclidean s) (w:real->bool)`` THEN
21971      SIMP_TAC std_ss [OPEN_IN_OPEN, LEFT_IMP_EXISTS_THM] THEN
21972      X_GEN_TAC ``t:real->bool`` THEN
21973      STRIP_TAC THEN ASM_REWRITE_TAC[IN_INTER] THEN
21974      UNDISCH_TAC ``s SUBSET closure((g:num->real->bool) n)`` THEN
21975      REWRITE_TAC[SUBSET_DEF, CLOSURE_NONEMPTY_OPEN_INTER] THEN
21976      FIRST_X_ASSUM(X_CHOOSE_TAC ``x:real`` o
21977        REWRITE_RULE [GSYM MEMBER_NOT_EMPTY]) THEN
21978      DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN
21979      KNOW_TAC ``x:real IN s`` THENL [ASM_SET_TAC[], DISCH_TAC THEN
21980       ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
21981      DISCH_THEN(MP_TAC o SPEC ``t:real->bool``) THEN
21982      KNOW_TAC ``x:real IN t /\ open t`` THENL
21983      [ASM_SET_TAC[], DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC] THEN
21984      FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN SET_TAC[],
21985      UNDISCH_TAC ``locally compact s`` THEN DISCH_TAC THEN
21986      FIRST_ASSUM(MP_TAC o REWRITE_RULE [locally]) THEN
21987      DISCH_THEN(MP_TAC o SPECL
21988       [``w INTER (g:num->real->bool) n``, ``b:real``]) THEN
21989      ASM_SIMP_TAC std_ss [OPEN_IN_INTER, OPEN_IN_REFL, IN_INTER] THEN
21990      SIMP_TAC std_ss [GSYM RIGHT_EXISTS_AND_THM] THEN
21991      STRIP_TAC THEN MAP_EVERY EXISTS_TAC [``u:real->bool``,``v':real->bool``] THEN
21992      ASM_SET_TAC[]],
21993    DISCH_TAC THEN ASM_REWRITE_TAC [] THEN POP_ASSUM K_TAC THEN
21994    SIMP_TAC std_ss [SKOLEM_THM, GSYM RIGHT_EXISTS_AND_THM, LEFT_IMP_EXISTS_THM] THEN
21995    MAP_EVERY X_GEN_TAC [``u:num->real->bool``, ``c:num->real->bool``] THEN
21996    SIMP_TAC std_ss [FORALL_AND_THM] THEN STRIP_TAC THEN
21997    MATCH_MP_TAC(SET_RULE ``!s. s SUBSET t /\ ~(s = {}) ==> ~(t = {})``) THEN
21998    EXISTS_TAC ``BIGINTER {c n:real->bool | n IN univ(:num)}`` THEN
21999    CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
22000    MATCH_MP_TAC COMPACT_NEST THEN ASM_REWRITE_TAC[] THEN
22001    CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
22002    ONCE_REWRITE_TAC [METIS [] ``(c n SUBSET c m) = (\m n. c n SUBSET c m) m n``] THEN
22003    MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_SET_TAC[]]);
22004
22005val BAIRE_ALT = store_thm ("BAIRE_ALT",
22006 ``!g s:real->bool.
22007        locally compact s /\ ~(s = {}) /\ COUNTABLE g /\ (BIGUNION g = s)
22008        ==> ?t u. t IN g /\ open_in (subtopology euclidean s) u /\
22009                  u SUBSET (closure t)``,
22010  REPEAT STRIP_TAC THEN MP_TAC(ISPECL
22011  [``IMAGE (\t:real->bool. s DIFF closure t) g``, ``s:real->bool``] BAIRE) THEN
22012  ASM_SIMP_TAC std_ss [COUNTABLE_IMAGE, FORALL_IN_IMAGE] THEN
22013  MATCH_MP_TAC(TAUT `~q /\ (~r ==> p) ==> (p ==> q) ==> r`) THEN
22014  CONJ_TAC THENL
22015   [MATCH_MP_TAC(SET_RULE
22016     ``~(s = {}) /\ ((t = {}) ==> (closure t = {})) /\ (t = {})
22017      ==> ~(s SUBSET closure t)``) THEN
22018    ASM_SIMP_TAC std_ss [CLOSURE_EMPTY] THEN
22019    MATCH_MP_TAC(SET_RULE ``i SUBSET s /\ (s DIFF i = s) ==> (i = {})``) THEN
22020    CONJ_TAC THENL [SIMP_TAC std_ss [BIGINTER_IMAGE] THEN ASM_SET_TAC[], ALL_TAC] THEN
22021    REWRITE_TAC[DIFF_BIGINTER] THEN
22022    REWRITE_TAC[SET_RULE ``{f x | x IN IMAGE g s} = {f(g x) | x IN s}``] THEN
22023    SIMP_TAC std_ss [SET_RULE ``s DIFF (s DIFF t) = s INTER t``] THEN
22024    REWRITE_TAC[SET_RULE ``{s INTER closure t | t IN g} =
22025                          {s INTER t | t IN IMAGE closure g}``] THEN
22026    SIMP_TAC std_ss [GSYM INTER_BIGUNION, SET_RULE ``(s INTER t = s) <=> s SUBSET t``] THEN
22027    FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
22028    GEN_REWR_TAC (LAND_CONV o RAND_CONV) [GSYM IMAGE_ID] THEN
22029    MATCH_MP_TAC BIGUNION_MONO_IMAGE THEN SIMP_TAC std_ss [CLOSURE_SUBSET],
22030    SIMP_TAC std_ss [NOT_EXISTS_THM] THEN STRIP_TAC THEN
22031    X_GEN_TAC ``t:real->bool`` THEN REPEAT STRIP_TAC THENL
22032     [ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s DIFF (s INTER t)``] THEN
22033      MATCH_MP_TAC OPEN_IN_DIFF THEN
22034      ASM_SIMP_TAC std_ss [CLOSED_IN_CLOSED_INTER, CLOSED_CLOSURE, OPEN_IN_REFL],
22035      REWRITE_TAC[SUBSET_DEF] THEN X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
22036      REWRITE_TAC[CLOSURE_APPROACHABLE] THEN
22037      X_GEN_TAC ``e:real`` THEN DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL
22038       [``t:real->bool``, ``s INTER ball(x:real,e)``]) THEN
22039      ASM_SIMP_TAC std_ss [OPEN_IN_OPEN_INTER, OPEN_BALL, SUBSET_DEF, IN_INTER, IN_BALL,
22040                   IN_DIFF] THEN
22041      METIS_TAC[DIST_SYM]]]);
22042
22043val NOWHERE_DENSE_COUNTABLE_BIGUNION_CLOSED = store_thm ("NOWHERE_DENSE_COUNTABLE_BIGUNION_CLOSED",
22044 ``!g:(real->bool)->bool.
22045        COUNTABLE g /\ (!s. s IN g ==> closed s /\ (interior s = {}))
22046        ==> (interior(BIGUNION g) = {})``,
22047  REPEAT STRIP_TAC THEN
22048  MP_TAC(ISPECL [``{univ(:real) DIFF s | s IN g}``, ``univ(:real)``]
22049        BAIRE) THEN
22050  SIMP_TAC std_ss [LOCALLY_COMPACT_UNIV, GSYM OPEN_IN, SUBTOPOLOGY_UNIV] THEN
22051  ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, COUNTABLE_IMAGE, FORALL_IN_IMAGE] THEN
22052  ASM_SIMP_TAC real_ss [GSYM IMAGE_DEF, COUNTABLE_IMAGE, FORALL_IN_IMAGE] THEN
22053  ASM_SIMP_TAC std_ss [GSYM closed_def, SET_RULE
22054   ``UNIV SUBSET s <=> (UNIV DIFF s = {})``] THEN
22055  SIMP_TAC std_ss[GSYM INTERIOR_COMPLEMENT] THEN
22056  SIMP_TAC std_ss [IMAGE_DEF, GSYM BIGUNION_BIGINTER] THEN
22057  ASM_SIMP_TAC std_ss [SET_RULE ``UNIV DIFF (UNIV DIFF s) = s``]);
22058
22059val NOWHERE_DENSE_COUNTABLE_BIGUNION = store_thm ("NOWHERE_DENSE_COUNTABLE_BIGUNION",
22060 ``!g:(real->bool)->bool.
22061        COUNTABLE g /\ (!s. s IN g ==> (interior(closure s) = {}))
22062        ==> (interior(BIGUNION g) = {})``,
22063  REPEAT STRIP_TAC THEN
22064  MP_TAC(ISPEC ``IMAGE closure (g:(real->bool)->bool)``
22065        NOWHERE_DENSE_COUNTABLE_BIGUNION_CLOSED) THEN
22066  ASM_SIMP_TAC std_ss [COUNTABLE_IMAGE, FORALL_IN_IMAGE, CLOSED_CLOSURE] THEN
22067  MATCH_MP_TAC(SET_RULE ``s SUBSET t ==> (t = {}) ==> (s = {})``) THEN
22068  MATCH_MP_TAC SUBSET_INTERIOR THEN MATCH_MP_TAC BIGUNION_MONO THEN
22069  SIMP_TAC std_ss [EXISTS_IN_IMAGE] THEN MESON_TAC[CLOSURE_SUBSET]);
22070
22071(* ------------------------------------------------------------------------- *)
22072(* Partitions of unity subordinate to locally finite open coverings.         *)
22073(* ------------------------------------------------------------------------- *)
22074
22075val SUBORDINATE_PARTITION_OF_UNITY = store_thm ("SUBORDINATE_PARTITION_OF_UNITY",
22076 ``!c s. s SUBSET BIGUNION c /\ (!u. u IN c ==> open u) /\
22077         (!x. x IN s
22078              ==> ?v. open v /\ x IN v /\
22079                      FINITE {u | u IN c /\ ~(u INTER v = {})})
22080         ==> ?f:(real->bool)->real->real.
22081                      (!u. u IN c
22082                           ==> f u continuous_on s /\
22083                               !x. x IN s ==> &0 <= f u x) /\
22084                      (!x u. u IN c /\ x IN s /\ ~(x IN u) ==> (f u x = &0)) /\
22085                      (!x. x IN s ==> (sum c (\u. f u x) = &1)) /\
22086                      (!x. x IN s
22087                           ==> ?n. open n /\ x IN n /\
22088                                   FINITE {u | u IN c /\
22089                                           ~(!x. x IN n ==> (f u x = &0))})``,
22090  REPEAT STRIP_TAC THEN
22091  ASM_CASES_TAC ``?u:real->bool. u IN c /\ s SUBSET u`` THENL
22092   [FIRST_X_ASSUM(CHOOSE_THEN STRIP_ASSUME_TAC) THEN
22093    EXISTS_TAC ``\v:real->bool x:real. if v = u then &1 else &0:real`` THEN
22094    SIMP_TAC arith_ss [COND_RAND, COND_RATOR, o_DEF, REAL_POS, REAL_OF_NUM_EQ,
22095                METIS [] ``(if p then q else T) <=> p ==> q``] THEN
22096    ASM_SIMP_TAC std_ss [CONTINUOUS_ON_CONST, COND_ID, SUM_DELTA] THEN
22097    CONJ_TAC THENL [ASM_SET_TAC[], ALL_TAC] THEN
22098    X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
22099    EXISTS_TAC ``ball(x:real,&1)`` THEN
22100    REWRITE_TAC[OPEN_BALL, CENTRE_IN_BALL, REAL_LT_01] THEN
22101    MATCH_MP_TAC SUBSET_FINITE_I THEN EXISTS_TAC ``{u:real->bool}`` THEN
22102    SIMP_TAC std_ss [FINITE_SING, SUBSET_DEF, GSPECIFICATION, IN_SING] THEN
22103    X_GEN_TAC ``v:real->bool`` THEN
22104    ASM_CASES_TAC ``v:real->bool = u`` THEN ASM_REWRITE_TAC[],
22105    ALL_TAC] THEN
22106  EXISTS_TAC ``\u:real->bool x:real.
22107        if x IN s
22108        then setdist({x},s DIFF u) / sum c (\v. setdist({x},s DIFF v))
22109        else &0`` THEN
22110  SIMP_TAC std_ss [SUBSET_DEF, FORALL_IN_IMAGE] THEN
22111  SIMP_TAC std_ss [SUM_POS_LE, SETDIST_POS_LE, REAL_LE_DIV] THEN
22112  SIMP_TAC std_ss [SETDIST_SING_IN_SET, IN_DIFF, real_div, REAL_MUL_LZERO] THEN
22113  SIMP_TAC std_ss [SUM_RMUL] THEN REWRITE_TAC[GSYM real_div] THEN
22114  MATCH_MP_TAC(TAUT `r /\ p /\ q ==> p /\ q /\ r`) THEN CONJ_TAC THENL
22115   [X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
22116    FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
22117    DISCH_THEN (X_CHOOSE_TAC ``n:real->bool``) THEN EXISTS_TAC ``n:real->bool`` THEN
22118    POP_ASSUM MP_TAC THEN
22119    REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
22120    ASM_REWRITE_TAC[] THEN
22121    MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUBSET_FINITE_I) THEN
22122    SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN X_GEN_TAC ``u:real->bool`` THEN
22123    ASM_CASES_TAC ``(u:real->bool) IN c`` THENL [ALL_TAC, METIS_TAC []] THEN
22124    ASM_REWRITE_TAC [] THEN ONCE_REWRITE_TAC[MONO_NOT_EQ] THEN DISCH_TAC THEN
22125    FULL_SIMP_TAC std_ss [NOT_EXISTS_THM] THEN X_GEN_TAC ``y:real`` THEN CCONTR_TAC THEN
22126    FULL_SIMP_TAC std_ss [] THEN POP_ASSUM MP_TAC THEN
22127    REWRITE_TAC[real_div, REAL_ENTIRE] THEN
22128    COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
22129    ASM_CASES_TAC ``(y:real) IN u`` THEN
22130    ASM_SIMP_TAC std_ss [SETDIST_SING_IN_SET, IN_DIFF, REAL_MUL_LZERO] THEN
22131    ASM_SET_TAC[], ALL_TAC] THEN
22132  SUBGOAL_THEN
22133   ``!v x:real. v IN c /\ x IN s /\ x IN v ==> &0 < setdist({x},s DIFF v)``
22134  ASSUME_TAC THENL
22135   [REPEAT STRIP_TAC THEN
22136    SIMP_TAC std_ss [SETDIST_POS_LE, REAL_ARITH ``&0 < x <=> &0 <= x /\ ~(x = &0:real)``] THEN
22137    MP_TAC(ISPECL [``s:real->bool``, ``s DIFF v:real->bool``, ``x:real``]
22138        SETDIST_EQ_0_CLOSED_IN) THEN
22139    ONCE_REWRITE_TAC[SET_RULE ``s DIFF t = s INTER (UNIV DIFF t)``] THEN
22140    ASM_SIMP_TAC std_ss [CLOSED_IN_CLOSED_INTER, GSYM OPEN_CLOSED] THEN
22141    DISCH_THEN SUBST1_TAC THEN ASM_REWRITE_TAC[] THEN
22142    ASM_REWRITE_TAC[IN_INTER, IN_DIFF, IN_UNION] THEN ASM_SET_TAC[],
22143    ALL_TAC] THEN
22144  SUBGOAL_THEN
22145   ``!x:real. x IN s ==> &0 < sum c (\v. setdist ({x},s DIFF v))``
22146  ASSUME_TAC THENL
22147   [X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
22148    ONCE_REWRITE_TAC[GSYM SUM_SUPPORT] THEN
22149    REWRITE_TAC[support, NEUTRAL_REAL_ADD] THEN
22150    MATCH_MP_TAC SUM_POS_LT THEN SIMP_TAC std_ss [SETDIST_POS_LE] THEN
22151    CONJ_TAC THENL
22152     [FIRST_X_ASSUM(MP_TAC o SPEC ``x:real``) THEN ASM_REWRITE_TAC[] THEN
22153      DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
22154      DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
22155      MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUBSET_FINITE_I) THEN
22156      SIMP_TAC std_ss [SUBSET_DEF, GSPECIFICATION] THEN X_GEN_TAC ``u:real->bool`` THEN
22157      ASM_CASES_TAC ``(x:real) IN u`` THEN
22158      ASM_SIMP_TAC std_ss [SETDIST_SING_IN_SET, IN_DIFF] THEN ASM_SET_TAC[],
22159      UNDISCH_TAC `` s SUBSET BIGUNION c:real->bool`` THEN DISCH_TAC THEN
22160      FIRST_X_ASSUM(MP_TAC o REWRITE_RULE [SUBSET_DEF]) THEN
22161      DISCH_THEN(MP_TAC o SPEC ``x:real``) THEN REWRITE_TAC[IN_BIGUNION] THEN
22162      ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN DISCH_THEN (X_CHOOSE_TAC ``t:real->bool``) THEN
22163      EXISTS_TAC ``t:real->bool`` THEN METIS_TAC[REAL_LT_IMP_NE]],
22164    ALL_TAC] THEN
22165  ASM_SIMP_TAC std_ss [REAL_LT_IMP_NE, REAL_DIV_REFL, o_DEF] THEN
22166  X_GEN_TAC ``u:real->bool`` THEN DISCH_TAC THEN
22167  MATCH_MP_TAC CONTINUOUS_ON_EQ THEN
22168  EXISTS_TAC ``\x:real.
22169        setdist({x},s DIFF u) / sum c (\v. setdist({x},s DIFF v))`` THEN
22170  SIMP_TAC std_ss [] THEN REWRITE_TAC[real_div] THEN
22171  ONCE_REWRITE_TAC [METIS []
22172   ``(\x. setdist ({x},s DIFF u) *
22173   inv (sum c (\v. setdist ({x},s DIFF v)))) =
22174     (\x. (\x. setdist ({x},s DIFF u)) x *
22175   (\x. inv (sum c (\v. setdist ({x},s DIFF v)))) x)``] THEN
22176  MATCH_MP_TAC CONTINUOUS_ON_MUL THEN
22177  SIMP_TAC std_ss [CONTINUOUS_ON_SETDIST, o_DEF] THEN
22178  ONCE_REWRITE_TAC [METIS []
22179   ``(\x. inv (sum c (\v. setdist ({x},s DIFF v)))) =
22180     (\x. inv ((\x. sum c (\v. setdist ({x},s DIFF v))) x))``] THEN
22181  MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN
22182  ASM_SIMP_TAC std_ss [REAL_LT_IMP_NE, CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
22183  X_GEN_TAC ``x:real`` THEN DISCH_TAC THEN
22184  FIRST_X_ASSUM(fn th =>
22185    MP_TAC(SPEC ``x:real`` th) THEN ASM_REWRITE_TAC[] THEN
22186    DISCH_THEN(X_CHOOSE_THEN ``n:real->bool`` STRIP_ASSUME_TAC)) THEN
22187  MATCH_MP_TAC CONTINUOUS_TRANSFORM_WITHIN_OPEN_IN THEN
22188  MAP_EVERY EXISTS_TAC
22189   [``\x:real. sum {v | v IN c /\ ~(v INTER n = {})}
22190                         (\v. setdist({x},s DIFF v))``,
22191    ``s INTER n:real->bool``] THEN
22192  ASM_SIMP_TAC std_ss [IN_INTER, OPEN_IN_OPEN_INTER] THEN CONJ_TAC THENL
22193   [X_GEN_TAC ``y:real`` THEN DISCH_TAC THEN
22194    CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_EQ_SUPERSET THEN
22195    ASM_REWRITE_TAC[SUBSET_RESTRICT] THEN STRIP_TAC THENL
22196    [ASM_SET_TAC [], ALL_TAC] THEN X_GEN_TAC ``v:real->bool`` THEN
22197    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
22198    ASM_SIMP_TAC std_ss [GSPECIFICATION] THEN DISCH_TAC THEN
22199    MATCH_MP_TAC SETDIST_SING_IN_SET THEN ASM_SET_TAC[],
22200    ONCE_REWRITE_TAC [METIS []
22201     ``(\x. sum {v | v IN c /\ v INTER n <> {}}
22202       (\v. setdist ({x},s DIFF v))) =
22203       (\x. sum {v | v IN c /\ v INTER n <> {}}
22204       (\v. (\v x. setdist ({x},s DIFF v)) v x))``] THEN
22205    MATCH_MP_TAC CONTINUOUS_SUM THEN
22206    ASM_SIMP_TAC std_ss [CONTINUOUS_AT_SETDIST, CONTINUOUS_AT_WITHIN]]);
22207
22208val _ = export_theory();
22209