1 (* ========================================================================= *)
2 (* Elementary topology in Euclidean space. *)
4 (* (c) Copyright, John Harrison 1998-2008 *)
5 (* (c) Copyright, Valentina Bruno 2010 *)
6 (* ========================================================================= *)
8 needs "Library/card.ml";;
9 needs "Multivariate/determinants.ml";;
11 (* ------------------------------------------------------------------------- *)
12 (* General notion of a topology. *)
13 (* ------------------------------------------------------------------------- *)
15 let istopology = new_definition
18 (!s t. s IN L /\ t IN L ==> (s INTER t) IN L) /\
19 (!k. k SUBSET L ==> (UNIONS k) IN L)`;;
21 let topology_tybij_th = prove
22 (`?t:(A->bool)->bool. istopology t`,
23 EXISTS_TAC `UNIV:(A->bool)->bool` THEN REWRITE_TAC[istopology; IN_UNIV]);;
26 new_type_definition "topology" ("topology","open_in") topology_tybij_th;;
28 let ISTOPOLOGY_OPEN_IN = prove
29 (`istopology(open_in top)`,
30 MESON_TAC[topology_tybij]);;
32 let TOPOLOGY_EQ = prove
33 (`!top1 top2. top1 = top2 <=> !s. open_in top1 s <=> open_in top2 s`,
34 REPEAT GEN_TAC THEN GEN_REWRITE_TAC RAND_CONV [GSYM FUN_EQ_THM] THEN
35 REWRITE_TAC[ETA_AX] THEN MESON_TAC[topology_tybij]);;
37 (* ------------------------------------------------------------------------- *)
38 (* Infer the "universe" from union of all sets in the topology. *)
39 (* ------------------------------------------------------------------------- *)
41 let topspace = new_definition
42 `topspace top = UNIONS {s | open_in top s}`;;
44 (* ------------------------------------------------------------------------- *)
45 (* Main properties of open sets. *)
46 (* ------------------------------------------------------------------------- *)
48 let OPEN_IN_CLAUSES = prove
51 (!s t. open_in top s /\ open_in top t ==> open_in top (s INTER t)) /\
52 (!k. (!s. s IN k ==> open_in top s) ==> open_in top (UNIONS k))`,
53 SIMP_TAC[IN; SUBSET; SIMP_RULE[istopology; IN; SUBSET] ISTOPOLOGY_OPEN_IN]);;
55 let OPEN_IN_SUBSET = prove
56 (`!top s. open_in top s ==> s SUBSET (topspace top)`,
57 REWRITE_TAC[topspace] THEN SET_TAC[]);;
59 let OPEN_IN_EMPTY = prove
60 (`!top. open_in top {}`,
61 REWRITE_TAC[OPEN_IN_CLAUSES]);;
63 let OPEN_IN_INTER = prove
64 (`!top s t. open_in top s /\ open_in top t ==> open_in top (s INTER t)`,
65 REWRITE_TAC[OPEN_IN_CLAUSES]);;
67 let OPEN_IN_UNIONS = prove
68 (`!top k. (!s. s IN k ==> open_in top s) ==> open_in top (UNIONS k)`,
69 REWRITE_TAC[OPEN_IN_CLAUSES]);;
71 let OPEN_IN_UNION = prove
72 (`!top s t. open_in top s /\ open_in top t ==> open_in top (s UNION t)`,
73 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM UNIONS_2] THEN
74 MATCH_MP_TAC OPEN_IN_UNIONS THEN ASM SET_TAC[]);;
76 let OPEN_IN_TOPSPACE = prove
77 (`!top. open_in top (topspace top)`,
78 SIMP_TAC[topspace; OPEN_IN_UNIONS; IN_ELIM_THM]);;
80 let OPEN_IN_INTERS = prove
81 (`!top s:(A->bool)->bool.
82 FINITE s /\ ~(s = {}) /\ (!t. t IN s ==> open_in top t)
83 ==> open_in top (INTERS s)`,
84 GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
85 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
86 REWRITE_TAC[INTERS_INSERT; IMP_IMP; NOT_INSERT_EMPTY; FORALL_IN_INSERT] THEN
87 MAP_EVERY X_GEN_TAC [`s:A->bool`; `f:(A->bool)->bool`] THEN
88 ASM_CASES_TAC `f:(A->bool)->bool = {}` THEN
89 ASM_SIMP_TAC[INTERS_0; INTER_UNIV] THEN REPEAT STRIP_TAC THEN
90 MATCH_MP_TAC OPEN_IN_INTER THEN ASM_SIMP_TAC[]);;
92 let OPEN_IN_SUBOPEN = prove
95 !x. x IN s ==> ?t. open_in top t /\ x IN t /\ t SUBSET s`,
96 REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN
97 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
98 REWRITE_TAC[TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN
99 REWRITE_TAC[FORALL_AND_THM; LEFT_IMP_EXISTS_THM] THEN
100 ONCE_REWRITE_TAC[GSYM FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN
101 FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_UNIONS) THEN
102 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]);;
104 (* ------------------------------------------------------------------------- *)
106 (* ------------------------------------------------------------------------- *)
108 let closed_in = new_definition
110 s SUBSET (topspace top) /\ open_in top (topspace top DIFF s)`;;
112 let CLOSED_IN_SUBSET = prove
113 (`!top s. closed_in top s ==> s SUBSET (topspace top)`,
114 MESON_TAC[closed_in]);;
116 let CLOSED_IN_EMPTY = prove
117 (`!top. closed_in top {}`,
118 REWRITE_TAC[closed_in; EMPTY_SUBSET; DIFF_EMPTY; OPEN_IN_TOPSPACE]);;
120 let CLOSED_IN_TOPSPACE = prove
121 (`!top. closed_in top (topspace top)`,
122 REWRITE_TAC[closed_in; SUBSET_REFL; DIFF_EQ_EMPTY; OPEN_IN_EMPTY]);;
124 let CLOSED_IN_UNION = prove
125 (`!top s t. closed_in top s /\ closed_in top t ==> closed_in top (s UNION t)`,
126 SIMP_TAC[closed_in; UNION_SUBSET; OPEN_IN_INTER;
127 SET_RULE `u DIFF (s UNION t) = (u DIFF s) INTER (u DIFF t)`]);;
129 let CLOSED_IN_INTERS = prove
130 (`!top k:(A->bool)->bool.
131 ~(k = {}) /\ (!s. s IN k ==> closed_in top s)
132 ==> closed_in top (INTERS k)`,
133 REPEAT GEN_TAC THEN REWRITE_TAC[closed_in] THEN REPEAT STRIP_TAC THENL
134 [ASM SET_TAC[]; ALL_TAC] THEN
135 SUBGOAL_THEN `topspace top DIFF INTERS k :A->bool =
136 UNIONS {topspace top DIFF s | s IN k}` SUBST1_TAC
137 THENL [ALL_TAC; MATCH_MP_TAC OPEN_IN_UNIONS THEN ASM SET_TAC[]] THEN
138 GEN_REWRITE_TAC I [EXTENSION] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
139 REWRITE_TAC[IN_UNIONS; IN_INTERS; IN_DIFF; EXISTS_IN_IMAGE] THEN
142 let CLOSED_IN_INTER = prove
143 (`!top s t. closed_in top s /\ closed_in top t ==> closed_in top (s INTER t)`,
144 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM INTERS_2] THEN
145 MATCH_MP_TAC CLOSED_IN_INTERS THEN ASM SET_TAC[]);;
147 let OPEN_IN_CLOSED_IN_EQ = prove
148 (`!top s. open_in top s <=>
149 s SUBSET topspace top /\ closed_in top (topspace top DIFF s)`,
150 REWRITE_TAC[closed_in; SET_RULE `(u DIFF s) SUBSET u`] THEN
151 REWRITE_TAC[SET_RULE `u DIFF (u DIFF s) = u INTER s`] THEN
152 MESON_TAC[OPEN_IN_SUBSET; SET_RULE `s SUBSET t ==> t INTER s = s`]);;
154 let OPEN_IN_CLOSED_IN = prove
155 (`!s. s SUBSET topspace top
156 ==> (open_in top s <=> closed_in top (topspace top DIFF s))`,
157 SIMP_TAC[OPEN_IN_CLOSED_IN_EQ]);;
159 let OPEN_IN_DIFF = prove
161 open_in top s /\ closed_in top t ==> open_in top (s DIFF t)`,
162 REPEAT STRIP_TAC THEN
163 SUBGOAL_THEN `s DIFF t :A->bool = s INTER (topspace top DIFF t)`
165 [FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_SUBSET) THEN SET_TAC[];
166 MATCH_MP_TAC OPEN_IN_INTER THEN ASM_MESON_TAC[closed_in]]);;
168 let CLOSED_IN_DIFF = prove
170 closed_in top s /\ open_in top t ==> closed_in top (s DIFF t)`,
171 REPEAT STRIP_TAC THEN
172 SUBGOAL_THEN `s DIFF t :A->bool = s INTER (topspace top DIFF t)`
174 [FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN SET_TAC[];
175 MATCH_MP_TAC CLOSED_IN_INTER THEN ASM_MESON_TAC[OPEN_IN_CLOSED_IN_EQ]]);;
177 let CLOSED_IN_UNIONS = prove
178 (`!top s. FINITE s /\ (!t. t IN s ==> closed_in top t)
179 ==> closed_in top (UNIONS s)`,
180 GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
181 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
182 REWRITE_TAC[UNIONS_INSERT; UNIONS_0; CLOSED_IN_EMPTY; IN_INSERT] THEN
183 MESON_TAC[CLOSED_IN_UNION]);;
185 (* ------------------------------------------------------------------------- *)
186 (* Subspace topology. *)
187 (* ------------------------------------------------------------------------- *)
189 let subtopology = new_definition
190 `subtopology top u = topology {s INTER u | open_in top s}`;;
192 let ISTOPLOGY_SUBTOPOLOGY = prove
193 (`!top u:A->bool. istopology {s INTER u | open_in top s}`,
194 REWRITE_TAC[istopology; SET_RULE
195 `{s INTER u | open_in top s} =
196 IMAGE (\s. s INTER u) {s | open_in top s}`] THEN
197 REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; RIGHT_FORALL_IMP_THM] THEN
198 REWRITE_TAC[SUBSET_IMAGE; IN_IMAGE; IN_ELIM_THM; SUBSET] THEN
199 REPEAT GEN_TAC THEN REPEAT CONJ_TAC THENL
200 [EXISTS_TAC `{}:A->bool` THEN REWRITE_TAC[OPEN_IN_EMPTY; INTER_EMPTY];
201 SIMP_TAC[SET_RULE `(s INTER u) INTER t INTER u = (s INTER t) INTER u`] THEN
202 ASM_MESON_TAC[OPEN_IN_INTER];
203 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
204 MAP_EVERY X_GEN_TAC [`f:(A->bool)->bool`; `g:(A->bool)->bool`] THEN
205 STRIP_TAC THEN EXISTS_TAC `UNIONS g :A->bool` THEN
206 ASM_SIMP_TAC[OPEN_IN_UNIONS; INTER_UNIONS] THEN SET_TAC[]]);;
208 let OPEN_IN_SUBTOPOLOGY = prove
209 (`!top u s. open_in (subtopology top u) s <=>
210 ?t. open_in top t /\ s = t INTER u`,
211 REWRITE_TAC[subtopology] THEN
212 SIMP_TAC[REWRITE_RULE[CONJUNCT2 topology_tybij] ISTOPLOGY_SUBTOPOLOGY] THEN
213 REWRITE_TAC[EXTENSION; IN_ELIM_THM]);;
215 let TOPSPACE_SUBTOPOLOGY = prove
216 (`!top u. topspace(subtopology top u) = topspace top INTER u`,
217 REWRITE_TAC[topspace; OPEN_IN_SUBTOPOLOGY; INTER_UNIONS] THEN
218 REPEAT STRIP_TAC THEN AP_TERM_TAC THEN
219 GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_ELIM_THM]);;
221 let CLOSED_IN_SUBTOPOLOGY = prove
222 (`!top u s. closed_in (subtopology top u) s <=>
223 ?t:A->bool. closed_in top t /\ s = t INTER u`,
224 REWRITE_TAC[closed_in; TOPSPACE_SUBTOPOLOGY] THEN
225 REWRITE_TAC[SUBSET_INTER; OPEN_IN_SUBTOPOLOGY; RIGHT_AND_EXISTS_THM] THEN
226 REPEAT STRIP_TAC THEN EQ_TAC THEN
227 DISCH_THEN(X_CHOOSE_THEN `t:A->bool` STRIP_ASSUME_TAC) THEN
228 EXISTS_TAC `topspace top DIFF t :A->bool` THEN
229 ASM_SIMP_TAC[CLOSED_IN_TOPSPACE; OPEN_IN_DIFF; CLOSED_IN_DIFF;
230 OPEN_IN_TOPSPACE] THEN
233 let OPEN_IN_SUBTOPOLOGY_EMPTY = prove
234 (`!top s. open_in (subtopology top {}) s <=> s = {}`,
235 REWRITE_TAC[OPEN_IN_SUBTOPOLOGY; INTER_EMPTY] THEN
236 MESON_TAC[OPEN_IN_EMPTY]);;
238 let CLOSED_IN_SUBTOPOLOGY_EMPTY = prove
239 (`!top s. closed_in (subtopology top {}) s <=> s = {}`,
240 REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY; INTER_EMPTY] THEN
241 MESON_TAC[CLOSED_IN_EMPTY]);;
243 let OPEN_IN_SUBTOPOLOGY_REFL = prove
244 (`!top u:A->bool. open_in (subtopology top u) u <=> u SUBSET topspace top`,
245 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_SUBTOPOLOGY] THEN EQ_TAC THENL
246 [REPEAT STRIP_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN
247 MATCH_MP_TAC(SET_RULE `s SUBSET u ==> s INTER t SUBSET u`) THEN
248 ASM_SIMP_TAC[OPEN_IN_SUBSET];
249 DISCH_TAC THEN EXISTS_TAC `topspace top:A->bool` THEN
250 REWRITE_TAC[OPEN_IN_TOPSPACE] THEN ASM SET_TAC[]]);;
252 let CLOSED_IN_SUBTOPOLOGY_REFL = prove
253 (`!top u:A->bool. closed_in (subtopology top u) u <=> u SUBSET topspace top`,
254 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY] THEN EQ_TAC THENL
255 [REPEAT STRIP_TAC THEN ONCE_ASM_REWRITE_TAC[] THEN
256 MATCH_MP_TAC(SET_RULE `s SUBSET u ==> s INTER t SUBSET u`) THEN
257 ASM_SIMP_TAC[CLOSED_IN_SUBSET];
258 DISCH_TAC THEN EXISTS_TAC `topspace top:A->bool` THEN
259 REWRITE_TAC[CLOSED_IN_TOPSPACE] THEN ASM SET_TAC[]]);;
261 let SUBTOPOLOGY_SUPERSET = prove
262 (`!top s:A->bool. topspace top SUBSET s ==> subtopology top s = top`,
263 REPEAT GEN_TAC THEN SIMP_TAC[TOPOLOGY_EQ; OPEN_IN_SUBTOPOLOGY] THEN
264 DISCH_TAC THEN X_GEN_TAC `u:A->bool` THEN EQ_TAC THENL
265 [DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 MP_TAC SUBST1_TAC)) THEN
266 DISCH_THEN(fun th -> MP_TAC th THEN
267 ASSUME_TAC(MATCH_MP OPEN_IN_SUBSET th)) THEN
268 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[];
269 DISCH_TAC THEN EXISTS_TAC `u:A->bool` THEN
270 FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_SUBSET) THEN ASM SET_TAC[]]);;
272 let SUBTOPOLOGY_TOPSPACE = prove
273 (`!top. subtopology top (topspace top) = top`,
274 SIMP_TAC[SUBTOPOLOGY_SUPERSET; SUBSET_REFL]);;
276 let SUBTOPOLOGY_UNIV = prove
277 (`!top. subtopology top UNIV = top`,
278 SIMP_TAC[SUBTOPOLOGY_SUPERSET; SUBSET_UNIV]);;
280 let OPEN_IN_IMP_SUBSET = prove
281 (`!top s t. open_in (subtopology top s) t ==> t SUBSET s`,
282 REWRITE_TAC[OPEN_IN_SUBTOPOLOGY] THEN SET_TAC[]);;
284 let CLOSED_IN_IMP_SUBSET = prove
285 (`!top s t. closed_in (subtopology top s) t ==> t SUBSET s`,
286 REWRITE_TAC[closed_in; TOPSPACE_SUBTOPOLOGY] THEN SET_TAC[]);;
288 let OPEN_IN_SUBTOPOLOGY_UNION = prove
289 (`!top s t u:A->bool.
290 open_in (subtopology top t) s /\ open_in (subtopology top u) s
291 ==> open_in (subtopology top (t UNION u)) s`,
292 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_SUBTOPOLOGY] THEN
293 DISCH_THEN(CONJUNCTS_THEN2
294 (X_CHOOSE_THEN `s':A->bool` STRIP_ASSUME_TAC)
295 (X_CHOOSE_THEN `t':A->bool` STRIP_ASSUME_TAC)) THEN
296 EXISTS_TAC `s' INTER t':A->bool` THEN ASM_SIMP_TAC[OPEN_IN_INTER] THEN
299 let CLOSED_IN_SUBTOPOLOGY_UNION = prove
300 (`!top s t u:A->bool.
301 closed_in (subtopology top t) s /\ closed_in (subtopology top u) s
302 ==> closed_in (subtopology top (t UNION u)) s`,
303 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY] THEN
304 DISCH_THEN(CONJUNCTS_THEN2
305 (X_CHOOSE_THEN `s':A->bool` STRIP_ASSUME_TAC)
306 (X_CHOOSE_THEN `t':A->bool` STRIP_ASSUME_TAC)) THEN
307 EXISTS_TAC `s' INTER t':A->bool` THEN ASM_SIMP_TAC[CLOSED_IN_INTER] THEN
310 (* ------------------------------------------------------------------------- *)
311 (* The universal Euclidean versions are what we use most of the time. *)
312 (* ------------------------------------------------------------------------- *)
314 let open_def = new_definition
315 `open s <=> !x. x IN s ==> ?e. &0 < e /\ !x'. dist(x',x) < e ==> x' IN s`;;
317 let closed = new_definition
318 `closed(s:real^N->bool) <=> open(UNIV DIFF s)`;;
320 let euclidean = new_definition
321 `euclidean = topology open`;;
323 let OPEN_EMPTY = prove
325 REWRITE_TAC[open_def; NOT_IN_EMPTY]);;
327 let OPEN_UNIV = prove
329 REWRITE_TAC[open_def; IN_UNIV] THEN MESON_TAC[REAL_LT_01]);;
331 let OPEN_INTER = prove
332 (`!s t. open s /\ open t ==> open (s INTER t)`,
333 REPEAT GEN_TAC THEN REWRITE_TAC[open_def; AND_FORALL_THM; IN_INTER] THEN
334 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
335 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
336 ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2
337 (X_CHOOSE_TAC `d1:real`) (X_CHOOSE_TAC `d2:real`)) THEN
338 MP_TAC(SPECL [`d1:real`; `d2:real`] REAL_DOWN2) THEN
339 ASM_MESON_TAC[REAL_LT_TRANS]);;
341 let OPEN_UNIONS = prove
342 (`(!s. s IN f ==> open s) ==> open(UNIONS f)`,
343 REWRITE_TAC[open_def; IN_UNIONS] THEN MESON_TAC[]);;
345 let OPEN_EXISTS_IN = prove
346 (`!P Q:A->real^N->bool.
347 (!a. P a ==> open {x | Q a x}) ==> open {x | ?a. P a /\ Q a x}`,
348 REPEAT STRIP_TAC THEN
349 SUBGOAL_THEN `open(UNIONS {{x | Q (a:A) (x:real^N)} | P a})` MP_TAC THENL
350 [MATCH_MP_TAC OPEN_UNIONS THEN ASM_REWRITE_TAC[FORALL_IN_GSPEC];
351 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN REWRITE_TAC[UNIONS_GSPEC] THEN
354 let OPEN_EXISTS = prove
355 (`!Q:A->real^N->bool. (!a. open {x | Q a x}) ==> open {x | ?a. Q a x}`,
356 MP_TAC(ISPEC `\x:A. T` OPEN_EXISTS_IN) THEN REWRITE_TAC[]);;
359 (`!s:real^N->bool. open s <=> open_in euclidean s`,
360 GEN_TAC THEN REWRITE_TAC[euclidean] THEN CONV_TAC SYM_CONV THEN
361 AP_THM_TAC THEN REWRITE_TAC[GSYM(CONJUNCT2 topology_tybij)] THEN
362 REWRITE_TAC[REWRITE_RULE[IN] istopology] THEN
363 REWRITE_TAC[OPEN_EMPTY; OPEN_INTER; SUBSET] THEN
364 MESON_TAC[IN; OPEN_UNIONS]);;
366 let TOPSPACE_EUCLIDEAN = prove
367 (`topspace euclidean = (:real^N)`,
368 REWRITE_TAC[topspace; EXTENSION; IN_UNIV; IN_UNIONS; IN_ELIM_THM] THEN
369 MESON_TAC[OPEN_UNIV; IN_UNIV; OPEN_IN]);;
371 let TOPSPACE_EUCLIDEAN_SUBTOPOLOGY = prove
372 (`!s. topspace (subtopology euclidean s) = s`,
373 REWRITE_TAC[TOPSPACE_EUCLIDEAN; TOPSPACE_SUBTOPOLOGY; INTER_UNIV]);;
375 let OPEN_IN_REFL = prove
376 (`!s:real^N->bool. open_in (subtopology euclidean s) s`,
377 REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL; TOPSPACE_EUCLIDEAN; SUBSET_UNIV]);;
379 let CLOSED_IN_REFL = prove
380 (`!s:real^N->bool. closed_in (subtopology euclidean s) s`,
381 REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY_REFL; TOPSPACE_EUCLIDEAN; SUBSET_UNIV]);;
383 let CLOSED_IN = prove
384 (`!s:real^N->bool. closed s <=> closed_in euclidean s`,
385 REWRITE_TAC[closed; closed_in; TOPSPACE_EUCLIDEAN; OPEN_IN; SUBSET_UNIV]);;
387 let OPEN_UNION = prove
388 (`!s t. open s /\ open t ==> open(s UNION t)`,
389 REWRITE_TAC[OPEN_IN; OPEN_IN_UNION]);;
391 let OPEN_SUBOPEN = prove
392 (`!s. open s <=> !x. x IN s ==> ?t. open t /\ x IN t /\ t SUBSET s`,
393 REWRITE_TAC[OPEN_IN; GSYM OPEN_IN_SUBOPEN]);;
395 let CLOSED_EMPTY = prove
397 REWRITE_TAC[CLOSED_IN; CLOSED_IN_EMPTY]);;
399 let CLOSED_UNIV = prove
400 (`closed(UNIV:real^N->bool)`,
401 REWRITE_TAC[CLOSED_IN; GSYM TOPSPACE_EUCLIDEAN; CLOSED_IN_TOPSPACE]);;
403 let CLOSED_UNION = prove
404 (`!s t. closed s /\ closed t ==> closed(s UNION t)`,
405 REWRITE_TAC[CLOSED_IN; CLOSED_IN_UNION]);;
407 let CLOSED_INTER = prove
408 (`!s t. closed s /\ closed t ==> closed(s INTER t)`,
409 REWRITE_TAC[CLOSED_IN; CLOSED_IN_INTER]);;
411 let CLOSED_INTERS = prove
412 (`!f. (!s:real^N->bool. s IN f ==> closed s) ==> closed(INTERS f)`,
413 REWRITE_TAC[CLOSED_IN] THEN REPEAT STRIP_TAC THEN
414 ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN
415 ASM_SIMP_TAC[CLOSED_IN_INTERS; INTERS_0] THEN
416 REWRITE_TAC[GSYM TOPSPACE_EUCLIDEAN; CLOSED_IN_TOPSPACE]);;
418 let CLOSED_FORALL_IN = prove
419 (`!P Q:A->real^N->bool.
420 (!a. P a ==> closed {x | Q a x}) ==> closed {x | !a. P a ==> Q a x}`,
421 REPEAT STRIP_TAC THEN
422 SUBGOAL_THEN `closed(INTERS {{x | Q (a:A) (x:real^N)} | P a})` MP_TAC THENL
423 [MATCH_MP_TAC CLOSED_INTERS THEN ASM_REWRITE_TAC[FORALL_IN_GSPEC];
424 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN REWRITE_TAC[INTERS_GSPEC] THEN
427 let CLOSED_FORALL = prove
428 (`!Q:A->real^N->bool. (!a. closed {x | Q a x}) ==> closed {x | !a. Q a x}`,
429 MP_TAC(ISPEC `\x:A. T` CLOSED_FORALL_IN) THEN REWRITE_TAC[]);;
431 let OPEN_CLOSED = prove
432 (`!s:real^N->bool. open s <=> closed(UNIV DIFF s)`,
433 SIMP_TAC[OPEN_IN; CLOSED_IN; TOPSPACE_EUCLIDEAN; SUBSET_UNIV;
434 OPEN_IN_CLOSED_IN_EQ]);;
436 let OPEN_DIFF = prove
437 (`!s t. open s /\ closed t ==> open(s DIFF t)`,
438 REWRITE_TAC[OPEN_IN; CLOSED_IN; OPEN_IN_DIFF]);;
440 let CLOSED_DIFF = prove
441 (`!s t. closed s /\ open t ==> closed(s DIFF t)`,
442 REWRITE_TAC[OPEN_IN; CLOSED_IN; CLOSED_IN_DIFF]);;
444 let OPEN_INTERS = prove
445 (`!s. FINITE s /\ (!t. t IN s ==> open t) ==> open(INTERS s)`,
446 REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
447 REWRITE_TAC[INTERS_INSERT; INTERS_0; OPEN_UNIV; IN_INSERT] THEN
448 MESON_TAC[OPEN_INTER]);;
450 let CLOSED_UNIONS = prove
451 (`!s. FINITE s /\ (!t. t IN s ==> closed t) ==> closed(UNIONS s)`,
452 REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
453 REWRITE_TAC[UNIONS_INSERT; UNIONS_0; CLOSED_EMPTY; IN_INSERT] THEN
454 MESON_TAC[CLOSED_UNION]);;
456 (* ------------------------------------------------------------------------- *)
457 (* Open and closed balls and spheres. *)
458 (* ------------------------------------------------------------------------- *)
460 let ball = new_definition
461 `ball(x,e) = { y | dist(x,y) < e}`;;
463 let cball = new_definition
464 `cball(x,e) = { y | dist(x,y) <= e}`;;
466 let sphere = new_definition
467 `sphere(x,e) = { y | dist(x,y) = e}`;;
470 (`!x y e. y IN ball(x,e) <=> dist(x,y) < e`,
471 REWRITE_TAC[ball; IN_ELIM_THM]);;
474 (`!x y e. y IN cball(x,e) <=> dist(x,y) <= e`,
475 REWRITE_TAC[cball; IN_ELIM_THM]);;
477 let IN_SPHERE = prove
478 (`!x y e. y IN sphere(x,e) <=> dist(x,y) = e`,
479 REWRITE_TAC[sphere; IN_ELIM_THM]);;
481 let IN_BALL_0 = prove
482 (`!x e. x IN ball(vec 0,e) <=> norm(x) < e`,
483 REWRITE_TAC[IN_BALL; dist; VECTOR_SUB_LZERO; NORM_NEG]);;
485 let IN_CBALL_0 = prove
486 (`!x e. x IN cball(vec 0,e) <=> norm(x) <= e`,
487 REWRITE_TAC[IN_CBALL; dist; VECTOR_SUB_LZERO; NORM_NEG]);;
489 let IN_SPHERE_0 = prove
490 (`!x e. x IN sphere(vec 0,e) <=> norm(x) = e`,
491 REWRITE_TAC[IN_SPHERE; dist; VECTOR_SUB_LZERO; NORM_NEG]);;
493 let BALL_TRIVIAL = prove
494 (`!x. ball(x,&0) = {}`,
495 REWRITE_TAC[EXTENSION; IN_BALL; IN_SING; NOT_IN_EMPTY] THEN NORM_ARITH_TAC);;
497 let CBALL_TRIVIAL = prove
498 (`!x. cball(x,&0) = {x}`,
499 REWRITE_TAC[EXTENSION; IN_CBALL; IN_SING; NOT_IN_EMPTY] THEN NORM_ARITH_TAC);;
501 let CENTRE_IN_CBALL = prove
502 (`!x e. x IN cball(x,e) <=> &0 <= e`,
503 MESON_TAC[IN_CBALL; DIST_REFL]);;
505 let BALL_SUBSET_CBALL = prove
506 (`!x e. ball(x,e) SUBSET cball(x,e)`,
507 REWRITE_TAC[IN_BALL; IN_CBALL; SUBSET] THEN REAL_ARITH_TAC);;
509 let SPHERE_SUBSET_CBALL = prove
510 (`!x e. sphere(x,e) SUBSET cball(x,e)`,
511 REWRITE_TAC[IN_SPHERE; IN_CBALL; SUBSET] THEN REAL_ARITH_TAC);;
513 let SUBSET_BALL = prove
514 (`!x d e. d <= e ==> ball(x,d) SUBSET ball(x,e)`,
515 REWRITE_TAC[SUBSET; IN_BALL] THEN MESON_TAC[REAL_LTE_TRANS]);;
517 let SUBSET_CBALL = prove
518 (`!x d e. d <= e ==> cball(x,d) SUBSET cball(x,e)`,
519 REWRITE_TAC[SUBSET; IN_CBALL] THEN MESON_TAC[REAL_LE_TRANS]);;
521 let BALL_MAX_UNION = prove
522 (`!a r s. ball(a,max r s) = ball(a,r) UNION ball(a,s)`,
523 REWRITE_TAC[IN_BALL; IN_UNION; EXTENSION] THEN REAL_ARITH_TAC);;
525 let BALL_MIN_INTER = prove
526 (`!a r s. ball(a,min r s) = ball(a,r) INTER ball(a,s)`,
527 REWRITE_TAC[IN_BALL; IN_INTER; EXTENSION] THEN REAL_ARITH_TAC);;
529 let CBALL_MAX_UNION = prove
530 (`!a r s. cball(a,max r s) = cball(a,r) UNION cball(a,s)`,
531 REWRITE_TAC[IN_CBALL; IN_UNION; EXTENSION] THEN REAL_ARITH_TAC);;
533 let CBALL_MIN_INTER = prove
534 (`!x d e. cball(x,min d e) = cball(x,d) INTER cball(x,e)`,
535 REWRITE_TAC[EXTENSION; IN_INTER; IN_CBALL] THEN REAL_ARITH_TAC);;
537 let BALL_TRANSLATION = prove
538 (`!a x r. ball(a + x,r) = IMAGE (\y. a + y) (ball(x,r))`,
539 REWRITE_TAC[ball] THEN GEOM_TRANSLATE_TAC[]);;
541 let CBALL_TRANSLATION = prove
542 (`!a x r. cball(a + x,r) = IMAGE (\y. a + y) (cball(x,r))`,
543 REWRITE_TAC[cball] THEN GEOM_TRANSLATE_TAC[]);;
545 let SPHERE_TRANSLATION = prove
546 (`!a x r. sphere(a + x,r) = IMAGE (\y. a + y) (sphere(x,r))`,
547 REWRITE_TAC[sphere] THEN GEOM_TRANSLATE_TAC[]);;
549 add_translation_invariants
550 [BALL_TRANSLATION; CBALL_TRANSLATION; SPHERE_TRANSLATION];;
552 let BALL_LINEAR_IMAGE = prove
553 (`!f:real^M->real^N x r.
554 linear f /\ (!y. ?x. f x = y) /\ (!x. norm(f x) = norm x)
555 ==> ball(f x,r) = IMAGE f (ball(x,r))`,
556 REWRITE_TAC[ball] THEN GEOM_TRANSFORM_TAC[]);;
558 let CBALL_LINEAR_IMAGE = prove
559 (`!f:real^M->real^N x r.
560 linear f /\ (!y. ?x. f x = y) /\ (!x. norm(f x) = norm x)
561 ==> cball(f x,r) = IMAGE f (cball(x,r))`,
562 REWRITE_TAC[cball] THEN GEOM_TRANSFORM_TAC[]);;
564 let SPHERE_LINEAR_IMAGE = prove
565 (`!f:real^M->real^N x r.
566 linear f /\ (!y. ?x. f x = y) /\ (!x. norm(f x) = norm x)
567 ==> sphere(f x,r) = IMAGE f (sphere(x,r))`,
568 REWRITE_TAC[sphere] THEN GEOM_TRANSFORM_TAC[]);;
570 add_linear_invariants
571 [BALL_LINEAR_IMAGE; CBALL_LINEAR_IMAGE; SPHERE_LINEAR_IMAGE];;
573 let BALL_SCALING = prove
574 (`!c. &0 < c ==> !x r. ball(c % x,c * r) = IMAGE (\x. c % x) (ball(x,r))`,
575 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
576 MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN REWRITE_TAC[] THEN CONJ_TAC THENL
577 [ASM_MESON_TAC[SURJECTIVE_SCALING; REAL_LT_IMP_NZ]; ALL_TAC] THEN
578 REWRITE_TAC[IN_BALL; DIST_MUL] THEN
579 ASM_SIMP_TAC[REAL_ARITH `&0 < c ==> abs c = c`; REAL_LT_LMUL_EQ]);;
581 let CBALL_SCALING = prove
582 (`!c. &0 < c ==> !x r. cball(c % x,c * r) = IMAGE (\x. c % x) (cball(x,r))`,
583 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
584 MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN REWRITE_TAC[] THEN CONJ_TAC THENL
585 [ASM_MESON_TAC[SURJECTIVE_SCALING; REAL_LT_IMP_NZ]; ALL_TAC] THEN
586 REWRITE_TAC[IN_CBALL; DIST_MUL] THEN
587 ASM_SIMP_TAC[REAL_ARITH `&0 < c ==> abs c = c`; REAL_LE_LMUL_EQ]);;
589 add_scaling_theorems [BALL_SCALING; CBALL_SCALING];;
591 let CBALL_DIFF_BALL = prove
592 (`!a r. cball(a,r) DIFF ball(a,r) = sphere(a,r)`,
593 REWRITE_TAC[ball; cball; sphere; EXTENSION; IN_DIFF; IN_ELIM_THM] THEN
596 let BALL_UNION_SPHERE = prove
597 (`!a r. ball(a,r) UNION sphere(a,r) = cball(a,r)`,
598 REWRITE_TAC[ball; cball; sphere; EXTENSION; IN_UNION; IN_ELIM_THM] THEN
601 let SPHERE_UNION_BALL = prove
602 (`!a r. sphere(a,r) UNION ball(a,r) = cball(a,r)`,
603 REWRITE_TAC[ball; cball; sphere; EXTENSION; IN_UNION; IN_ELIM_THM] THEN
606 let CBALL_DIFF_SPHERE = prove
607 (`!a r. cball(a,r) DIFF sphere(a,r) = ball(a,r)`,
608 REWRITE_TAC[EXTENSION; IN_DIFF; IN_SPHERE; IN_BALL; IN_CBALL] THEN
611 let OPEN_BALL = prove
612 (`!x e. open(ball(x,e))`,
613 REWRITE_TAC[open_def; ball; IN_ELIM_THM] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
614 MESON_TAC[REAL_SUB_LT; REAL_LT_SUB_LADD; REAL_ADD_SYM; REAL_LET_TRANS;
615 DIST_TRIANGLE_ALT]);;
617 let CENTRE_IN_BALL = prove
618 (`!x e. x IN ball(x,e) <=> &0 < e`,
619 MESON_TAC[IN_BALL; DIST_REFL]);;
621 let OPEN_CONTAINS_BALL = prove
622 (`!s. open s <=> !x. x IN s ==> ?e. &0 < e /\ ball(x,e) SUBSET s`,
623 REWRITE_TAC[open_def; SUBSET; IN_BALL] THEN REWRITE_TAC[DIST_SYM]);;
625 let OPEN_CONTAINS_BALL_EQ = prove
626 (`!s. open s ==> (!x. x IN s <=> ?e. &0 < e /\ ball(x,e) SUBSET s)`,
627 MESON_TAC[OPEN_CONTAINS_BALL; SUBSET; CENTRE_IN_BALL]);;
629 let BALL_EQ_EMPTY = prove
630 (`!x e. (ball(x,e) = {}) <=> e <= &0`,
631 REWRITE_TAC[EXTENSION; IN_BALL; NOT_IN_EMPTY; REAL_NOT_LT] THEN
632 MESON_TAC[DIST_POS_LE; REAL_LE_TRANS; DIST_REFL]);;
634 let BALL_EMPTY = prove
635 (`!x e. e <= &0 ==> ball(x,e) = {}`,
636 REWRITE_TAC[BALL_EQ_EMPTY]);;
638 let OPEN_CONTAINS_CBALL = prove
639 (`!s. open s <=> !x. x IN s ==> ?e. &0 < e /\ cball(x,e) SUBSET s`,
640 GEN_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN EQ_TAC THENL
641 [ALL_TAC; ASM_MESON_TAC[SUBSET_TRANS; BALL_SUBSET_CBALL]] THEN
642 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
643 REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL] THEN
644 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
645 EXISTS_TAC `e / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN
646 SUBGOAL_THEN `e / &2 < e` (fun th -> ASM_MESON_TAC[th; REAL_LET_TRANS]) THEN
647 ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
648 UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC);;
650 let OPEN_CONTAINS_CBALL_EQ = prove
651 (`!s. open s ==> (!x. x IN s <=> ?e. &0 < e /\ cball(x,e) SUBSET s)`,
652 MESON_TAC[OPEN_CONTAINS_CBALL; SUBSET; REAL_LT_IMP_LE; CENTRE_IN_CBALL]);;
654 let SPHERE_EQ_EMPTY = prove
655 (`!a:real^N r. sphere(a,r) = {} <=> r < &0`,
656 REWRITE_TAC[sphere; EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN
657 REPEAT GEN_TAC THEN EQ_TAC THENL [ALL_TAC; CONV_TAC NORM_ARITH] THEN
658 MESON_TAC[VECTOR_CHOOSE_DIST; REAL_NOT_LE]);;
660 let SPHERE_EMPTY = prove
661 (`!a:real^N r. r < &0 ==> sphere(a,r) = {}`,
662 REWRITE_TAC[SPHERE_EQ_EMPTY]);;
664 let NEGATIONS_BALL = prove
665 (`!r. IMAGE (--) (ball(vec 0:real^N,r)) = ball(vec 0,r)`,
666 GEN_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
667 REWRITE_TAC[IN_BALL_0; NORM_NEG] THEN MESON_TAC[VECTOR_NEG_NEG]);;
669 let NEGATIONS_CBALL = prove
670 (`!r. IMAGE (--) (cball(vec 0:real^N,r)) = cball(vec 0,r)`,
671 GEN_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
672 REWRITE_TAC[IN_CBALL_0; NORM_NEG] THEN MESON_TAC[VECTOR_NEG_NEG]);;
674 let NEGATIONS_SPHERE = prove
675 (`!r. IMAGE (--) (sphere(vec 0:real^N,r)) = sphere(vec 0,r)`,
676 GEN_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
677 REWRITE_TAC[IN_SPHERE_0; NORM_NEG] THEN MESON_TAC[VECTOR_NEG_NEG]);;
679 let ORTHOGONAL_TRANSFORMATION_BALL = prove
680 (`!f:real^N->real^N r.
681 orthogonal_transformation f ==> IMAGE f (ball(vec 0,r)) = ball(vec 0,r)`,
682 REWRITE_TAC[EXTENSION; IN_IMAGE; IN_BALL_0] THEN
683 MESON_TAC[ORTHOGONAL_TRANSFORMATION_INVERSE; ORTHOGONAL_TRANSFORMATION]);;
685 let ORTHOGONAL_TRANSFORMATION_CBALL = prove
686 (`!f:real^N->real^N r.
687 orthogonal_transformation f ==> IMAGE f (cball(vec 0,r)) = cball(vec 0,r)`,
688 REWRITE_TAC[EXTENSION; IN_IMAGE; IN_CBALL_0] THEN
689 MESON_TAC[ORTHOGONAL_TRANSFORMATION_INVERSE; ORTHOGONAL_TRANSFORMATION]);;
691 let ORTHOGONAL_TRANSFORMATION_SPHERE = prove
692 (`!f:real^N->real^N r.
693 orthogonal_transformation f
694 ==> IMAGE f (sphere(vec 0,r)) = sphere(vec 0,r)`,
695 REWRITE_TAC[EXTENSION; IN_IMAGE; IN_SPHERE_0] THEN
696 MESON_TAC[ORTHOGONAL_TRANSFORMATION_INVERSE; ORTHOGONAL_TRANSFORMATION]);;
698 (* ------------------------------------------------------------------------- *)
699 (* Basic "localization" results are handy for connectedness. *)
700 (* ------------------------------------------------------------------------- *)
702 let OPEN_IN_OPEN = prove
704 open_in (subtopology euclidean u) s <=> ?t. open t /\ (s = u INTER t)`,
705 REPEAT STRIP_TAC THEN REWRITE_TAC[OPEN_IN_SUBTOPOLOGY; GSYM OPEN_IN] THEN
706 REWRITE_TAC[INTER_ACI]);;
708 let OPEN_IN_INTER_OPEN = prove
709 (`!s t u:real^N->bool.
710 open_in (subtopology euclidean u) s /\ open t
711 ==> open_in (subtopology euclidean u) (s INTER t)`,
712 REWRITE_TAC[OPEN_IN_OPEN] THEN REPEAT STRIP_TAC THEN
713 ASM_REWRITE_TAC[INTER_ASSOC] THEN ASM_MESON_TAC[OPEN_INTER]);;
715 let OPEN_IN_OPEN_INTER = prove
716 (`!u s. open s ==> open_in (subtopology euclidean u) (u INTER s)`,
717 REWRITE_TAC[OPEN_IN_OPEN] THEN MESON_TAC[]);;
719 let OPEN_OPEN_IN_TRANS = prove
720 (`!s t. open s /\ open t /\ t SUBSET s
721 ==> open_in (subtopology euclidean s) t`,
722 MESON_TAC[OPEN_IN_OPEN_INTER; SET_RULE `t SUBSET s ==> t = s INTER t`]);;
724 let OPEN_SUBSET = prove
726 s SUBSET t /\ open s ==> open_in (subtopology euclidean t) s`,
727 REPEAT STRIP_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN
728 EXISTS_TAC `s:real^N->bool` THEN ASM SET_TAC[]);;
730 let CLOSED_IN_CLOSED = prove
732 closed_in (subtopology euclidean u) s <=> ?t. closed t /\ (s = u INTER t)`,
733 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY; GSYM CLOSED_IN] THEN
734 REWRITE_TAC[INTER_ACI]);;
736 let CLOSED_SUBSET_EQ = prove
738 closed s ==> (closed_in (subtopology euclidean u) s <=> s SUBSET u)`,
739 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
740 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN
741 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY];
742 REWRITE_TAC[CLOSED_IN_CLOSED] THEN EXISTS_TAC `s:real^N->bool` THEN
745 let CLOSED_IN_INTER_CLOSED = prove
746 (`!s t u:real^N->bool.
747 closed_in (subtopology euclidean u) s /\ closed t
748 ==> closed_in (subtopology euclidean u) (s INTER t)`,
749 REWRITE_TAC[CLOSED_IN_CLOSED] THEN REPEAT STRIP_TAC THEN
750 ASM_REWRITE_TAC[INTER_ASSOC] THEN ASM_MESON_TAC[CLOSED_INTER]);;
752 let CLOSED_IN_CLOSED_INTER = prove
753 (`!u s. closed s ==> closed_in (subtopology euclidean u) (u INTER s)`,
754 REWRITE_TAC[CLOSED_IN_CLOSED] THEN MESON_TAC[]);;
756 let CLOSED_SUBSET = prove
758 s SUBSET t /\ closed s ==> closed_in (subtopology euclidean t) s`,
759 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN
760 EXISTS_TAC `s:real^N->bool` THEN ASM SET_TAC[]);;
762 let OPEN_IN_SUBSET_TRANS = prove
763 (`!s t u:real^N->bool.
764 open_in (subtopology euclidean u) s /\ s SUBSET t /\ t SUBSET u
765 ==> open_in (subtopology euclidean t) s`,
766 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN; LEFT_AND_EXISTS_THM] THEN
767 MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]);;
769 let CLOSED_IN_SUBSET_TRANS = prove
770 (`!s t u:real^N->bool.
771 closed_in (subtopology euclidean u) s /\ s SUBSET t /\ t SUBSET u
772 ==> closed_in (subtopology euclidean t) s`,
773 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED; LEFT_AND_EXISTS_THM] THEN
774 MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]);;
778 open_in (subtopology euclidean u) s <=>
780 !x. x IN s ==> ?e. &0 < e /\
781 !x'. x' IN u /\ dist(x',x) < e ==> x' IN s`,
783 REWRITE_TAC[OPEN_IN_SUBTOPOLOGY; GSYM OPEN_IN] THEN EQ_TAC THENL
784 [REWRITE_TAC[open_def] THEN ASM SET_TAC[INTER_SUBSET; IN_INTER];
786 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
787 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
788 REWRITE_TAC[SKOLEM_THM] THEN DISCH_THEN(X_CHOOSE_TAC `d:real^N->real`) THEN
789 EXISTS_TAC `UNIONS {b | ?x:real^N. (b = ball(x,d x)) /\ x IN s}` THEN
791 [MATCH_MP_TAC OPEN_UNIONS THEN
792 ASM_SIMP_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM; OPEN_BALL];
793 GEN_REWRITE_TAC I [EXTENSION] THEN
794 REWRITE_TAC[IN_INTER; IN_UNIONS; IN_ELIM_THM] THEN
795 ASM_MESON_TAC[SUBSET; DIST_REFL; DIST_SYM; IN_BALL]]);;
797 let OPEN_IN_CONTAINS_BALL = prove
799 open_in (subtopology euclidean t) s <=>
801 !x. x IN s ==> ?e. &0 < e /\ ball(x,e) INTER t SUBSET s`,
802 REWRITE_TAC[open_in; INTER; SUBSET; IN_ELIM_THM; IN_BALL] THEN
803 MESON_TAC[DIST_SYM]);;
805 let OPEN_IN_CONTAINS_CBALL = prove
807 open_in (subtopology euclidean t) s <=>
809 !x. x IN s ==> ?e. &0 < e /\ cball(x,e) INTER t SUBSET s`,
810 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_CONTAINS_BALL] THEN
811 AP_TERM_TAC THEN REWRITE_TAC[IN_BALL; IN_INTER; SUBSET; IN_CBALL] THEN
812 MESON_TAC[REAL_ARITH `&0 < e ==> &0 < e / &2 /\ (x <= e / &2 ==> x < e)`;
815 (* ------------------------------------------------------------------------- *)
816 (* These "transitivity" results are handy too. *)
817 (* ------------------------------------------------------------------------- *)
819 let OPEN_IN_TRANS = prove
820 (`!s t u. open_in (subtopology euclidean t) s /\
821 open_in (subtopology euclidean u) t
822 ==> open_in (subtopology euclidean u) s`,
823 ASM_MESON_TAC[OPEN_IN_OPEN; OPEN_IN; OPEN_INTER; INTER_ASSOC]);;
825 let OPEN_IN_TRANS_EQ = prove
827 (!u. open_in (subtopology euclidean t) u
828 ==> open_in (subtopology euclidean s) t)
829 <=> open_in (subtopology euclidean s) t`,
830 MESON_TAC[OPEN_IN_TRANS; OPEN_IN_REFL]);;
832 let OPEN_IN_OPEN_TRANS = prove
833 (`!s t. open_in (subtopology euclidean t) s /\ open t ==> open s`,
834 REWRITE_TAC[ONCE_REWRITE_RULE[GSYM SUBTOPOLOGY_UNIV] OPEN_IN] THEN
835 REWRITE_TAC[OPEN_IN_TRANS]);;
837 let CLOSED_IN_TRANS = prove
838 (`!s t u. closed_in (subtopology euclidean t) s /\
839 closed_in (subtopology euclidean u) t
840 ==> closed_in (subtopology euclidean u) s`,
841 ASM_MESON_TAC[CLOSED_IN_CLOSED; CLOSED_IN; CLOSED_INTER; INTER_ASSOC]);;
843 let CLOSED_IN_TRANS_EQ = prove
845 (!u. closed_in (subtopology euclidean t) u
846 ==> closed_in (subtopology euclidean s) t)
847 <=> closed_in (subtopology euclidean s) t`,
848 MESON_TAC[CLOSED_IN_TRANS; CLOSED_IN_REFL]);;
850 let CLOSED_IN_CLOSED_TRANS = prove
851 (`!s t. closed_in (subtopology euclidean t) s /\ closed t ==> closed s`,
852 REWRITE_TAC[ONCE_REWRITE_RULE[GSYM SUBTOPOLOGY_UNIV] CLOSED_IN] THEN
853 REWRITE_TAC[CLOSED_IN_TRANS]);;
855 let OPEN_IN_SUBTOPOLOGY_INTER_SUBSET = prove
856 (`!s u v. open_in (subtopology euclidean u) (u INTER s) /\ v SUBSET u
857 ==> open_in (subtopology euclidean v) (v INTER s)`,
858 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN; LEFT_AND_EXISTS_THM] THEN
859 MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]);;
861 let OPEN_IN_OPEN_EQ = prove
863 ==> (open_in (subtopology euclidean s) t <=> open t /\ t SUBSET s)`,
864 MESON_TAC[OPEN_OPEN_IN_TRANS; OPEN_IN_OPEN_TRANS; open_in]);;
866 let CLOSED_IN_CLOSED_EQ = prove
868 ==> (closed_in (subtopology euclidean s) t <=>
869 closed t /\ t SUBSET s)`,
870 MESON_TAC[CLOSED_SUBSET; CLOSED_IN_CLOSED_TRANS; closed_in;
871 TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]);;
873 (* ------------------------------------------------------------------------- *)
874 (* Also some invariance theorems for relative topology. *)
875 (* ------------------------------------------------------------------------- *)
877 let OPEN_IN_TRANSLATION_EQ = prove
878 (`!a s t. open_in (subtopology euclidean (IMAGE (\x. a + x) t))
879 (IMAGE (\x. a + x) s) <=>
880 open_in (subtopology euclidean t) s`,
881 REWRITE_TAC[open_in] THEN GEOM_TRANSLATE_TAC[]);;
883 add_translation_invariants [OPEN_IN_TRANSLATION_EQ];;
885 let CLOSED_IN_TRANSLATION_EQ = prove
886 (`!a s t. closed_in (subtopology euclidean (IMAGE (\x. a + x) t))
887 (IMAGE (\x. a + x) s) <=>
888 closed_in (subtopology euclidean t) s`,
889 REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
890 GEOM_TRANSLATE_TAC[]);;
892 add_translation_invariants [CLOSED_IN_TRANSLATION_EQ];;
894 let OPEN_IN_INJECTIVE_LINEAR_IMAGE = prove
895 (`!f:real^M->real^N s t.
896 linear f /\ (!x y. f x = f y ==> x = y)
897 ==> (open_in (subtopology euclidean (IMAGE f t)) (IMAGE f s) <=>
898 open_in (subtopology euclidean t) s)`,
899 REWRITE_TAC[open_in; FORALL_IN_IMAGE; IMP_CONJ; SUBSET] THEN
900 REPEAT STRIP_TAC THEN
901 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (SET_RULE
902 `(!x y. f x = f y ==> x = y) ==> (!x s. f x IN IMAGE f s <=> x IN s)`)) THEN
903 ASM_REWRITE_TAC[] THEN
904 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_BOUNDED_POS) THEN
905 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_BOUNDED_BELOW_POS) THEN
906 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
907 X_GEN_TAC `B2:real` THEN STRIP_TAC THEN
908 X_GEN_TAC `B1:real` THEN STRIP_TAC THEN
909 AP_TERM_TAC THEN AP_TERM_TAC THEN
910 GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `x:real^M` THEN
911 REWRITE_TAC[] THEN AP_TERM_TAC THEN
912 FIRST_ASSUM(ASSUME_TAC o GSYM o MATCH_MP LINEAR_SUB) THEN
913 ASM_REWRITE_TAC[dist; IMP_IMP] THEN EQ_TAC THEN
914 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THENL
915 [EXISTS_TAC `e / B1:real`; EXISTS_TAC `e * B2:real`] THEN
916 ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV] THEN
917 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THENL
918 [MATCH_MP_TAC(REAL_ARITH
919 `norm(f x) <= B1 * norm(x) /\ norm(x) * B1 < e ==> norm(f x) < e`) THEN
920 ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ];
921 MATCH_MP_TAC(REAL_ARITH
922 `norm x <= norm (f x :real^N) / B2 /\ norm(f x) / B2 < e
923 ==> norm x < e`) THEN
924 ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LT_LDIV_EQ]]);;
926 add_linear_invariants [OPEN_IN_INJECTIVE_LINEAR_IMAGE];;
928 let CLOSED_IN_INJECTIVE_LINEAR_IMAGE = prove
929 (`!f:real^M->real^N s t.
930 linear f /\ (!x y. f x = f y ==> x = y)
931 ==> (closed_in (subtopology euclidean (IMAGE f t)) (IMAGE f s) <=>
932 closed_in (subtopology euclidean t) s)`,
933 REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
934 GEOM_TRANSFORM_TAC[]);;
936 add_linear_invariants [CLOSED_IN_INJECTIVE_LINEAR_IMAGE];;
938 (* ------------------------------------------------------------------------- *)
940 (* ------------------------------------------------------------------------- *)
942 let connected = new_definition
944 ~(?e1 e2. open e1 /\ open e2 /\ s SUBSET (e1 UNION e2) /\
945 (e1 INTER e2 INTER s = {}) /\
946 ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))`;;
948 let CONNECTED_CLOSED = prove
951 ~(?e1 e2. closed e1 /\ closed e2 /\ s SUBSET (e1 UNION e2) /\
952 (e1 INTER e2 INTER s = {}) /\
953 ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))`,
954 GEN_TAC THEN REWRITE_TAC[connected] THEN AP_TERM_TAC THEN
955 EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
956 MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN STRIP_TAC THEN
957 MAP_EVERY EXISTS_TAC [`(:real^N) DIFF v`; `(:real^N) DIFF u`] THEN
958 ASM_REWRITE_TAC[GSYM closed; GSYM OPEN_CLOSED] THEN ASM SET_TAC[]);;
960 let CONNECTED_OPEN_IN = prove
961 (`!s. connected s <=>
963 open_in (subtopology euclidean s) e1 /\
964 open_in (subtopology euclidean s) e2 /\
965 s SUBSET e1 UNION e2 /\
969 GEN_TAC THEN REWRITE_TAC[connected; OPEN_IN_OPEN] THEN
970 REWRITE_TAC[LEFT_AND_EXISTS_THM; RIGHT_AND_EXISTS_THM] THEN
971 CONV_TAC(ONCE_DEPTH_CONV UNWIND_CONV) THEN
972 AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
975 let CONNECTED_OPEN_IN_EQ = prove
976 (`!s. connected s <=>
978 open_in (subtopology euclidean s) e1 /\
979 open_in (subtopology euclidean s) e2 /\
980 e1 UNION e2 = s /\ e1 INTER e2 = {} /\
981 ~(e1 = {}) /\ ~(e2 = {}))`,
982 GEN_TAC THEN REWRITE_TAC[CONNECTED_OPEN_IN] THEN
983 AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
984 EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN
985 RULE_ASSUM_TAC(REWRITE_RULE[OPEN_IN_CLOSED_IN_EQ;
986 TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]) THEN
989 let CONNECTED_CLOSED_IN = prove
990 (`!s. connected s <=>
992 closed_in (subtopology euclidean s) e1 /\
993 closed_in (subtopology euclidean s) e2 /\
994 s SUBSET e1 UNION e2 /\
998 GEN_TAC THEN REWRITE_TAC[CONNECTED_CLOSED; CLOSED_IN_CLOSED] THEN
999 REWRITE_TAC[LEFT_AND_EXISTS_THM; RIGHT_AND_EXISTS_THM] THEN
1000 CONV_TAC(ONCE_DEPTH_CONV UNWIND_CONV) THEN
1001 AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
1004 let CONNECTED_CLOSED_IN_EQ = prove
1005 (`!s. connected s <=>
1007 closed_in (subtopology euclidean s) e1 /\
1008 closed_in (subtopology euclidean s) e2 /\
1010 e1 UNION e2 = s /\ e1 INTER e2 = {} /\
1011 ~(e1 = {}) /\ ~(e2 = {}))`,
1012 GEN_TAC THEN REWRITE_TAC[CONNECTED_CLOSED_IN] THEN
1013 AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
1014 EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN
1015 RULE_ASSUM_TAC(REWRITE_RULE[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]) THEN
1018 let CONNECTED_CLOPEN = prove
1019 (`!s. connected s <=>
1020 !t. open_in (subtopology euclidean s) t /\
1021 closed_in (subtopology euclidean s) t ==> t = {} \/ t = s`,
1022 GEN_TAC THEN REWRITE_TAC[connected; OPEN_IN_OPEN; CLOSED_IN_CLOSED] THEN
1023 GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o BINDER_CONV) [GSYM EXISTS_DIFF] THEN
1024 ONCE_REWRITE_TAC[TAUT `(~a <=> b) <=> (a <=> ~b)`] THEN
1025 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; GSYM CONJ_ASSOC; DE_MORGAN_THM] THEN
1026 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> b /\ a /\ c /\ d`] THEN
1027 REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN REWRITE_TAC[GSYM closed] THEN
1028 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN AP_TERM_TAC THEN ABS_TAC THEN
1029 REWRITE_TAC[LEFT_AND_EXISTS_THM; RIGHT_AND_EXISTS_THM] THEN
1030 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN AP_TERM_TAC THEN ABS_TAC THEN
1031 REWRITE_TAC[TAUT `(a /\ b) /\ (c /\ d) /\ e <=> a /\ c /\ b /\ d /\ e`] THEN
1032 REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN
1033 AP_TERM_TAC THEN AP_TERM_TAC THEN SET_TAC[]);;
1035 let CONNECTED_CLOSED_SET = prove
1038 ==> (connected s <=>
1039 ~(?e1 e2. closed e1 /\ closed e2 /\ ~(e1 = {}) /\ ~(e2 = {}) /\
1040 e1 UNION e2 = s /\ e1 INTER e2 = {}))`,
1041 REPEAT STRIP_TAC THEN EQ_TAC THENL
1042 [REWRITE_TAC[CONNECTED_CLOSED; CONTRAPOS_THM] THEN
1043 REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
1044 SIMP_TAC[] THEN SET_TAC[];
1045 REWRITE_TAC[CONNECTED_CLOSED_IN; CONTRAPOS_THM; LEFT_IMP_EXISTS_THM] THEN
1046 REWRITE_TAC[CLOSED_IN_CLOSED; LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN
1047 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN REWRITE_TAC[IMP_IMP] THEN
1049 [`e1:real^N->bool`; `e2:real^N->bool`;
1050 `u:real^N->bool`; `v:real^N->bool`] THEN
1051 STRIP_TAC THEN MAP_EVERY (C UNDISCH_THEN SUBST_ALL_TAC)
1052 [`e1:real^N->bool = s INTER u`;
1053 `e2:real^N->bool = s INTER v`] THEN
1054 MAP_EVERY EXISTS_TAC
1055 [`s INTER u:real^N->bool`; `s INTER v:real^N->bool`] THEN
1056 ASM_SIMP_TAC[CLOSED_INTER] THEN ASM SET_TAC[]]);;
1058 let CONNECTED_OPEN_SET = prove
1061 ==> (connected s <=>
1062 ~(?e1 e2. open e1 /\ open e2 /\ ~(e1 = {}) /\ ~(e2 = {}) /\
1063 e1 UNION e2 = s /\ e1 INTER e2 = {}))`,
1064 REPEAT STRIP_TAC THEN EQ_TAC THENL
1065 [REWRITE_TAC[connected; CONTRAPOS_THM] THEN
1066 REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
1067 SIMP_TAC[] THEN SET_TAC[];
1068 REWRITE_TAC[CONNECTED_OPEN_IN; CONTRAPOS_THM; LEFT_IMP_EXISTS_THM] THEN
1069 REWRITE_TAC[OPEN_IN_OPEN; LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN
1070 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN REWRITE_TAC[IMP_IMP] THEN
1072 [`e1:real^N->bool`; `e2:real^N->bool`;
1073 `u:real^N->bool`; `v:real^N->bool`] THEN
1074 STRIP_TAC THEN MAP_EVERY (C UNDISCH_THEN SUBST_ALL_TAC)
1075 [`e1:real^N->bool = s INTER u`;
1076 `e2:real^N->bool = s INTER v`] THEN
1077 MAP_EVERY EXISTS_TAC
1078 [`s INTER u:real^N->bool`; `s INTER v:real^N->bool`] THEN
1079 ASM_SIMP_TAC[OPEN_INTER] THEN ASM SET_TAC[]]);;
1081 let CONNECTED_EMPTY = prove
1083 REWRITE_TAC[connected; INTER_EMPTY]);;
1085 let CONNECTED_SING = prove
1086 (`!a. connected{a}`,
1087 REWRITE_TAC[connected] THEN SET_TAC[]);;
1089 let CONNECTED_UNIONS = prove
1090 (`!P:(real^N->bool)->bool.
1091 (!s. s IN P ==> connected s) /\ ~(INTERS P = {})
1092 ==> connected(UNIONS P)`,
1093 GEN_TAC THEN REWRITE_TAC[connected; NOT_EXISTS_THM] THEN STRIP_TAC THEN
1094 MAP_EVERY X_GEN_TAC [`e1:real^N->bool`; `e2:real^N->bool`] THEN
1095 STRIP_TAC THEN UNDISCH_TAC `~(INTERS P :real^N->bool = {})` THEN
1096 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTERS] THEN
1097 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
1098 SUBGOAL_THEN `(a:real^N) IN e1 \/ a IN e2` STRIP_ASSUME_TAC THENL
1100 UNDISCH_TAC `~(e2 INTER UNIONS P:real^N->bool = {})`;
1101 UNDISCH_TAC `~(e1 INTER UNIONS P:real^N->bool = {})`] THEN
1102 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER; IN_UNIONS] THEN
1103 DISCH_THEN(X_CHOOSE_THEN `b:real^N`
1104 (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
1105 DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN
1106 UNDISCH_TAC `!t:real^N->bool. t IN P ==> a IN t` THEN
1107 DISCH_THEN(MP_TAC o SPEC `s:real^N->bool`) THEN
1108 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
1109 FIRST_X_ASSUM(MP_TAC o SPEC `s:real^N->bool`) THEN
1110 ASM_REWRITE_TAC[] THEN
1111 DISCH_THEN(MP_TAC o SPECL [`e1:real^N->bool`; `e2:real^N->bool`]) THEN
1114 let CONNECTED_UNION = prove
1115 (`!s t:real^N->bool.
1116 connected s /\ connected t /\ ~(s INTER t = {})
1117 ==> connected (s UNION t)`,
1118 REWRITE_TAC[GSYM UNIONS_2; GSYM INTERS_2] THEN
1119 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_UNIONS THEN
1122 let CONNECTED_DIFF_OPEN_FROM_CLOSED = prove
1123 (`!s t u:real^N->bool.
1124 s SUBSET t /\ t SUBSET u /\
1125 open s /\ closed t /\ connected u /\ connected(t DIFF s)
1126 ==> connected(u DIFF s)`,
1127 REPEAT STRIP_TAC THEN REWRITE_TAC[connected; NOT_EXISTS_THM] THEN
1128 MAP_EVERY X_GEN_TAC [`v:real^N->bool`; `w:real^N->bool`] THEN STRIP_TAC THEN
1129 UNDISCH_TAC `connected(t DIFF s:real^N->bool)` THEN SIMP_TAC[connected] THEN
1130 MAP_EVERY EXISTS_TAC [`v:real^N->bool`; `w:real^N->bool`] THEN
1131 ASM_REWRITE_TAC[] THEN
1132 REPLICATE_TAC 2 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
1133 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
1134 MAP_EVERY (fun t -> SPEC_TAC(t,t)) [`v:real^N->bool`; `w:real^N->bool`] THEN
1135 MATCH_MP_TAC(MESON[]
1136 `(!v w. P v w ==> P w v) /\ (!w v. P v w /\ Q w ==> F)
1137 ==> !w v. P v w ==> ~(Q v) /\ ~(Q w)`) THEN
1138 CONJ_TAC THENL [SIMP_TAC[CONJ_ACI; INTER_ACI; UNION_ACI]; ALL_TAC] THEN
1139 REPEAT STRIP_TAC THEN
1140 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [connected]) THEN SIMP_TAC[] THEN
1141 MAP_EVERY EXISTS_TAC [`v UNION s:real^N->bool`; `w DIFF t:real^N->bool`] THEN
1142 ASM_SIMP_TAC[OPEN_UNION; OPEN_DIFF] THEN ASM SET_TAC[]);;
1144 let CONNECTED_DISJOINT_UNIONS_OPEN_UNIQUE = prove
1145 (`!f:(real^N->bool)->bool f'.
1146 pairwise DISJOINT f /\ pairwise DISJOINT f' /\
1147 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\
1148 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\
1149 UNIONS f = UNIONS f'
1151 GEN_REWRITE_TAC (funpow 2 BINDER_CONV o RAND_CONV) [EXTENSION] THEN
1152 MATCH_MP_TAC(MESON[]
1153 `(!s t. P s t ==> P t s) /\ (!s t x. P s t /\ x IN s ==> x IN t)
1154 ==> (!s t. P s t ==> (!x. x IN s <=> x IN t))`) THEN
1155 CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
1156 GEN_TAC THEN GEN_TAC THEN X_GEN_TAC `s:real^N->bool` THEN STRIP_TAC THEN
1158 `?t a:real^N. t IN f' /\ a IN s /\ a IN t` STRIP_ASSUME_TAC
1159 THENL [ASM SET_TAC[]; ALL_TAC] THEN
1160 SUBGOAL_THEN `s:real^N->bool = t` (fun th -> ASM_REWRITE_TAC[th]) THEN
1161 REWRITE_TAC[EXTENSION] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
1162 MAP_EVERY (fun t -> SPEC_TAC(t,t))
1163 [`s:real^N->bool`; `t:real^N->bool`;
1164 `f:(real^N->bool)->bool`; `f':(real^N->bool)->bool`] THEN
1165 MATCH_MP_TAC(MESON[]
1166 `(!f f' s t. P f f' s t ==> P f' f t s) /\
1167 (!f f' s t x. P f f' s t /\ x IN s ==> x IN t)
1168 ==> (!f' f t s. P f f' s t ==> (!x. x IN s <=> x IN t))`) THEN
1169 CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
1170 REPLICATE_TAC 4 GEN_TAC THEN X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN
1172 `!s:real^N->bool. s IN f ==> open s /\ connected s /\ ~(s = {})` THEN
1173 DISCH_THEN(MP_TAC o SPEC `s:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
1174 STRIP_TAC THEN ASM_CASES_TAC `(b:real^N) IN t` THEN
1175 ASM_REWRITE_TAC[] THEN
1176 UNDISCH_TAC `connected(s:real^N->bool)` THEN
1177 REWRITE_TAC[connected] THEN
1178 MAP_EVERY EXISTS_TAC
1179 [`t:real^N->bool`; `UNIONS(f' DELETE (t:real^N->bool))`] THEN
1180 REPEAT STRIP_TAC THENL
1182 MATCH_MP_TAC OPEN_UNIONS THEN ASM_SIMP_TAC[IN_DELETE];
1183 REWRITE_TAC[GSYM UNIONS_INSERT] THEN ASM SET_TAC[];
1184 MATCH_MP_TAC(SET_RULE `t INTER u = {} ==> t INTER u INTER s = {}`) THEN
1185 REWRITE_TAC[INTER_UNIONS; EMPTY_UNIONS; FORALL_IN_GSPEC] THEN
1186 REWRITE_TAC[IN_DELETE; GSYM DISJOINT] THEN ASM_MESON_TAC[pairwise];
1190 let CONNECTED_FROM_CLOSED_UNION_AND_INTER = prove
1191 (`!s t:real^N->bool.
1192 closed s /\ closed t /\ connected(s UNION t) /\ connected(s INTER t)
1193 ==> connected s /\ connected t`,
1194 MATCH_MP_TAC(MESON[]
1195 `(!s t. P s t ==> P t s) /\ (!s t. P s t ==> Q s)
1196 ==> !s t. P s t ==> Q s /\ Q t`) THEN
1197 CONJ_TAC THENL [SIMP_TAC[UNION_COMM; INTER_COMM]; REPEAT STRIP_TAC] THEN
1198 ASM_SIMP_TAC[CONNECTED_CLOSED_SET] THEN
1199 REWRITE_TAC[NOT_EXISTS_THM] THEN
1200 MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN
1201 STRIP_TAC THEN ASM_CASES_TAC
1202 `~(s INTER t SUBSET (u:real^N->bool)) /\ ~(s INTER t SUBSET v)`
1204 [UNDISCH_TAC `connected(s INTER t:real^N->bool)` THEN
1205 ASM_SIMP_TAC[CONNECTED_CLOSED] THEN
1206 MAP_EVERY EXISTS_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN
1207 ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
1208 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DE_MORGAN_THM]) THEN
1209 REWRITE_TAC[] THEN STRIP_TAC THEN
1210 UNDISCH_TAC `connected(s UNION t:real^N->bool)` THEN
1211 ASM_SIMP_TAC[CONNECTED_CLOSED] THENL
1212 [MAP_EVERY EXISTS_TAC [`t UNION u:real^N->bool`; `v:real^N->bool`] THEN
1213 ASM_SIMP_TAC[CLOSED_UNION] THEN ASM SET_TAC[];
1214 MAP_EVERY EXISTS_TAC [`t UNION v:real^N->bool`; `u:real^N->bool`] THEN
1215 ASM_SIMP_TAC[CLOSED_UNION] THEN ASM SET_TAC[]]]);;
1217 let CONNECTED_FROM_OPEN_UNION_AND_INTER = prove
1218 (`!s t:real^N->bool.
1219 open s /\ open t /\ connected(s UNION t) /\ connected(s INTER t)
1220 ==> connected s /\ connected t`,
1221 MATCH_MP_TAC(MESON[]
1222 `(!s t. P s t ==> P t s) /\ (!s t. P s t ==> Q s)
1223 ==> !s t. P s t ==> Q s /\ Q t`) THEN
1224 CONJ_TAC THENL [SIMP_TAC[UNION_COMM; INTER_COMM]; REPEAT STRIP_TAC] THEN
1225 ASM_SIMP_TAC[CONNECTED_OPEN_SET] THEN
1226 REWRITE_TAC[NOT_EXISTS_THM] THEN
1227 MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN
1228 STRIP_TAC THEN ASM_CASES_TAC
1229 `~(s INTER t SUBSET (u:real^N->bool)) /\ ~(s INTER t SUBSET v)`
1231 [UNDISCH_TAC `connected(s INTER t:real^N->bool)` THEN
1232 ASM_SIMP_TAC[connected] THEN
1233 MAP_EVERY EXISTS_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN
1234 ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
1235 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DE_MORGAN_THM]) THEN
1236 REWRITE_TAC[] THEN STRIP_TAC THEN
1237 UNDISCH_TAC `connected(s UNION t:real^N->bool)` THEN
1238 ASM_SIMP_TAC[connected] THENL
1239 [MAP_EVERY EXISTS_TAC [`t UNION u:real^N->bool`; `v:real^N->bool`] THEN
1240 ASM_SIMP_TAC[OPEN_UNION] THEN ASM SET_TAC[];
1241 MAP_EVERY EXISTS_TAC [`t UNION v:real^N->bool`; `u:real^N->bool`] THEN
1242 ASM_SIMP_TAC[OPEN_UNION] THEN ASM SET_TAC[]]]);;
1244 (* ------------------------------------------------------------------------- *)
1245 (* Sort of induction principle for connected sets. *)
1246 (* ------------------------------------------------------------------------- *)
1248 let CONNECTED_INDUCTION = prove
1249 (`!P Q s:real^N->bool.
1251 (!t a. open_in (subtopology euclidean s) t /\ a IN t
1252 ==> ?z. z IN t /\ P z) /\
1254 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
1255 !x y. x IN t /\ y IN t /\ P x /\ P y /\ Q x ==> Q y)
1256 ==> !a b. a IN s /\ b IN s /\ P a /\ P b /\ Q a ==> Q b`,
1257 REPEAT STRIP_TAC THEN
1258 GEN_REWRITE_TAC I [TAUT `p <=> ~ ~p`] THEN DISCH_TAC THEN
1259 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONNECTED_OPEN_IN]) THEN
1260 REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC
1261 [`{b:real^N | ?t. open_in (subtopology euclidean s) t /\ b IN t /\
1262 !x. x IN t /\ P x ==> Q x}`;
1263 `{b:real^N | ?t. open_in (subtopology euclidean s) t /\ b IN t /\
1264 !x. x IN t /\ P x ==> ~(Q x)}`] THEN
1265 REPEAT CONJ_TAC THENL
1266 [ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN
1267 X_GEN_TAC `c:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN
1268 MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[];
1269 ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN
1270 X_GEN_TAC `c:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN
1271 MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[];
1272 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNION] THEN
1273 X_GEN_TAC `c:real^N` THEN DISCH_TAC THEN
1274 FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N`) THEN ASM SET_TAC[];
1275 REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY; IN_ELIM_THM] THEN
1276 X_GEN_TAC `c:real^N` THEN DISCH_THEN(CONJUNCTS_THEN2
1277 (X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC)
1278 (X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC)) THEN
1279 FIRST_X_ASSUM(MP_TAC o SPECL [`t INTER u:real^N->bool`; `c:real^N`]) THEN
1280 ASM_SIMP_TAC[OPEN_IN_INTER] THEN ASM SET_TAC[];
1284 let CONNECTED_EQUIVALENCE_RELATION_GEN = prove
1285 (`!P R s:real^N->bool.
1287 (!x y. R x y ==> R y x) /\
1288 (!x y z. R x y /\ R y z ==> R x z) /\
1289 (!t a. open_in (subtopology euclidean s) t /\ a IN t
1290 ==> ?z. z IN t /\ P z) /\
1292 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
1293 !x y. x IN t /\ y IN t /\ P x /\ P y ==> R x y)
1294 ==> !a b. a IN s /\ b IN s /\ P a /\ P b ==> R a b`,
1295 REPEAT GEN_TAC THEN STRIP_TAC THEN
1297 `!a:real^N. a IN s /\ P a
1298 ==> !b c. b IN s /\ c IN s /\ P b /\ P c /\ R a b ==> R a c`
1299 MP_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
1300 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONNECTED_INDUCTION THEN
1303 let CONNECTED_INDUCTION_SIMPLE = prove
1304 (`!P s:real^N->bool.
1307 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
1308 !x y. x IN t /\ y IN t /\ P x ==> P y)
1309 ==> !a b. a IN s /\ b IN s /\ P a ==> P b`,
1310 MP_TAC(ISPEC `\x:real^N. T` CONNECTED_INDUCTION) THEN
1312 REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN MESON_TAC[]);;
1314 let CONNECTED_EQUIVALENCE_RELATION = prove
1315 (`!R s:real^N->bool.
1317 (!x y. R x y ==> R y x) /\
1318 (!x y z. R x y /\ R y z ==> R x z) /\
1320 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
1321 !x. x IN t ==> R a x)
1322 ==> !a b. a IN s /\ b IN s ==> R a b`,
1323 REPEAT GEN_TAC THEN STRIP_TAC THEN
1325 `!a:real^N. a IN s ==> !b c. b IN s /\ c IN s /\ R a b ==> R a c`
1326 MP_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
1327 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONNECTED_INDUCTION_SIMPLE THEN
1330 (* ------------------------------------------------------------------------- *)
1332 (* ------------------------------------------------------------------------- *)
1334 parse_as_infix ("limit_point_of",(12,"right"));;
1336 let limit_point_of = new_definition
1337 `x limit_point_of s <=>
1338 !t. x IN t /\ open t ==> ?y. ~(y = x) /\ y IN s /\ y IN t`;;
1340 let LIMPT_SUBSET = prove
1341 (`!x s t. x limit_point_of s /\ s SUBSET t ==> x limit_point_of t`,
1342 REWRITE_TAC[limit_point_of; SUBSET] THEN MESON_TAC[]);;
1344 let LIMPT_APPROACHABLE = prove
1345 (`!x s. x limit_point_of s <=>
1346 !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ dist(x',x) < e`,
1347 REPEAT GEN_TAC THEN REWRITE_TAC[limit_point_of] THEN
1348 MESON_TAC[open_def; DIST_SYM; OPEN_BALL; CENTRE_IN_BALL; IN_BALL]);;
1350 let LIMPT_APPROACHABLE_LE = prove
1351 (`!x s. x limit_point_of s <=>
1352 !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ dist(x',x) <= e`,
1353 REPEAT GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
1354 MATCH_MP_TAC(TAUT `(~a <=> ~b) ==> (a <=> b)`) THEN
1355 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN
1356 REWRITE_TAC[TAUT `~(a /\ b /\ c) <=> c ==> ~(a /\ b)`; APPROACHABLE_LT_LE]);;
1358 let LIMPT_UNIV = prove
1359 (`!x:real^N. x limit_point_of UNIV`,
1360 GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE; IN_UNIV] THEN
1361 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1362 SUBGOAL_THEN `?c:real^N. norm(c) = e / &2` CHOOSE_TAC THENL
1363 [ASM_SIMP_TAC[VECTOR_CHOOSE_SIZE; REAL_HALF; REAL_LT_IMP_LE];
1365 EXISTS_TAC `x + c:real^N` THEN
1366 REWRITE_TAC[dist; VECTOR_EQ_ADDR] THEN ASM_REWRITE_TAC[VECTOR_ADD_SUB] THEN
1367 SUBGOAL_THEN `&0 < e / &2 /\ e / &2 < e`
1368 (fun th -> ASM_MESON_TAC[th; NORM_0; REAL_LT_REFL]) THEN
1369 SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
1370 UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC);;
1372 let CLOSED_LIMPT = prove
1373 (`!s. closed s <=> !x. x limit_point_of s ==> x IN s`,
1374 REWRITE_TAC[closed] THEN ONCE_REWRITE_TAC[OPEN_SUBOPEN] THEN
1375 REWRITE_TAC[limit_point_of; IN_DIFF; IN_UNIV; SUBSET] THEN MESON_TAC[]);;
1377 let LIMPT_EMPTY = prove
1378 (`!x. ~(x limit_point_of {})`,
1379 REWRITE_TAC[LIMPT_APPROACHABLE; NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]);;
1381 let NO_LIMIT_POINT_IMP_CLOSED = prove
1382 (`!s. ~(?x. x limit_point_of s) ==> closed s`,
1383 MESON_TAC[CLOSED_LIMPT]);;
1385 let CLOSED_POSITIVE_ORTHANT = prove
1386 (`closed {x:real^N | !i. 1 <= i /\ i <= dimindex(:N)
1388 REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE] THEN
1389 REWRITE_TAC[IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
1390 X_GEN_TAC `i:num` THEN STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
1391 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `--(x:real^N $ i)`) THEN
1392 ASM_REWRITE_TAC[REAL_LT_RNEG; REAL_ADD_LID; NOT_EXISTS_THM] THEN
1393 X_GEN_TAC `y:real^N` THEN
1394 MATCH_MP_TAC(TAUT `(a ==> ~c) ==> ~(a /\ b /\ c)`) THEN DISCH_TAC THEN
1395 MATCH_MP_TAC(REAL_ARITH `!b. abs x <= b /\ b <= a ==> ~(a + x < &0)`) THEN
1396 EXISTS_TAC `abs((y - x :real^N)$i)` THEN
1397 ASM_SIMP_TAC[dist; COMPONENT_LE_NORM] THEN
1398 ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; REAL_ARITH
1399 `x < &0 /\ &0 <= y ==> abs(x) <= abs(y - x)`]);;
1401 let FINITE_SET_AVOID = prove
1402 (`!a:real^N s. FINITE s
1403 ==> ?d. &0 < d /\ !x. x IN s /\ ~(x = a) ==> d <= dist(a,x)`,
1404 GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1405 REWRITE_TAC[NOT_IN_EMPTY] THEN
1406 CONJ_TAC THENL [MESON_TAC[REAL_LT_01]; ALL_TAC] THEN
1407 MAP_EVERY X_GEN_TAC [`x:real^N`; `s:real^N->bool`] THEN
1408 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
1409 FIRST_X_ASSUM(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
1410 ASM_CASES_TAC `x:real^N = a` THEN REWRITE_TAC[IN_INSERT] THENL
1411 [ASM_MESON_TAC[]; ALL_TAC] THEN
1412 EXISTS_TAC `min d (dist(a:real^N,x))` THEN
1413 ASM_REWRITE_TAC[REAL_LT_MIN; GSYM DIST_NZ; REAL_MIN_LE] THEN
1414 ASM_MESON_TAC[REAL_LE_REFL]);;
1416 let LIMIT_POINT_FINITE = prove
1417 (`!s a. FINITE s ==> ~(a limit_point_of s)`,
1418 REWRITE_TAC[LIMPT_APPROACHABLE; GSYM REAL_NOT_LE] THEN
1419 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM; REAL_NOT_LE;
1420 REAL_NOT_LT; TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN
1421 MESON_TAC[FINITE_SET_AVOID; DIST_SYM]);;
1423 let LIMPT_SING = prove
1424 (`!x y:real^N. ~(x limit_point_of {y})`,
1425 SIMP_TAC[LIMIT_POINT_FINITE; FINITE_SING]);;
1427 let LIMIT_POINT_UNION = prove
1428 (`!s t x:real^N. x limit_point_of (s UNION t) <=>
1429 x limit_point_of s \/ x limit_point_of t`,
1430 REPEAT GEN_TAC THEN EQ_TAC THENL
1431 [ALL_TAC; MESON_TAC[LIMPT_SUBSET; SUBSET_UNION]] THEN
1432 REWRITE_TAC[LIMPT_APPROACHABLE; IN_UNION] THEN DISCH_TAC THEN
1433 MATCH_MP_TAC(TAUT `(~a ==> b) ==> a \/ b`) THEN
1434 REWRITE_TAC[NOT_FORALL_THM; LEFT_IMP_EXISTS_THM; NOT_IMP] THEN
1435 X_GEN_TAC `e:real` THEN STRIP_TAC THEN X_GEN_TAC `d:real` THEN DISCH_TAC THEN
1436 FIRST_X_ASSUM(MP_TAC o SPEC `min d e`) THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
1439 let LIMPT_INSERT = prove
1440 (`!s x y:real^N. x limit_point_of (y INSERT s) <=> x limit_point_of s`,
1441 ONCE_REWRITE_TAC[SET_RULE `y INSERT s = {y} UNION s`] THEN
1442 REWRITE_TAC[LIMIT_POINT_UNION] THEN
1443 SIMP_TAC[FINITE_SING; LIMIT_POINT_FINITE]);;
1445 let LIMPT_OF_LIMPTS = prove
1447 x limit_point_of {y | y limit_point_of s} ==> x limit_point_of s`,
1448 REWRITE_TAC[LIMPT_APPROACHABLE; IN_ELIM_THM] THEN REPEAT GEN_TAC THEN
1449 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1450 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
1451 DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN
1452 FIRST_X_ASSUM(MP_TAC o SPEC `dist(y:real^N,x)`) THEN
1453 ASM_SIMP_TAC[DIST_POS_LT] THEN MATCH_MP_TAC MONO_EXISTS THEN
1454 GEN_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1455 REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC);;
1457 let CLOSED_LIMPTS = prove
1458 (`!s. closed {x:real^N | x limit_point_of s}`,
1459 REWRITE_TAC[CLOSED_LIMPT; IN_ELIM_THM; LIMPT_OF_LIMPTS]);;
1461 let DISCRETE_IMP_CLOSED = prove
1462 (`!s:real^N->bool e.
1464 (!x y. x IN s /\ y IN s /\ norm(y - x) < e ==> y = x)
1466 REPEAT STRIP_TAC THEN
1467 SUBGOAL_THEN `!x:real^N. ~(x limit_point_of s)`
1468 (fun th -> MESON_TAC[th; CLOSED_LIMPT]) THEN
1469 GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN DISCH_TAC THEN
1470 FIRST_ASSUM(MP_TAC o SPEC `e / &2`) THEN
1471 REWRITE_TAC[REAL_HALF; ASSUME `&0 < e`] THEN
1472 DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN
1473 FIRST_X_ASSUM(MP_TAC o SPEC `min (e / &2) (dist(x:real^N,y))`) THEN
1474 ASM_SIMP_TAC[REAL_LT_MIN; DIST_POS_LT; REAL_HALF] THEN
1475 DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
1476 FIRST_X_ASSUM(MP_TAC o SPECL [`y:real^N`; `z:real^N`]) THEN
1477 ASM_REWRITE_TAC[] THEN ASM_NORM_ARITH_TAC);;
1479 let LIMPT_OF_UNIV = prove
1480 (`!x. x limit_point_of (:real^N)`,
1481 GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE; IN_UNIV] THEN
1482 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1483 MP_TAC(ISPECL [`x:real^N`; `e / &2`] VECTOR_CHOOSE_DIST) THEN
1484 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN
1485 POP_ASSUM MP_TAC THEN CONV_TAC NORM_ARITH);;
1487 let LIMPT_OF_OPEN_IN = prove
1489 open_in (subtopology euclidean s) t /\ x limit_point_of s /\ x IN t
1490 ==> x limit_point_of t`,
1491 REWRITE_TAC[open_in; SUBSET; LIMPT_APPROACHABLE] THEN
1492 REPEAT GEN_TAC THEN STRIP_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1493 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
1494 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
1495 FIRST_X_ASSUM(MP_TAC o SPEC `min d e / &2`) THEN
1496 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN
1497 GEN_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THEN
1498 TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN ASM_REWRITE_TAC[] THEN
1499 ASM_REAL_ARITH_TAC);;
1501 let LIMPT_OF_OPEN = prove
1502 (`!s x:real^N. open s /\ x IN s ==> x limit_point_of s`,
1503 REWRITE_TAC[OPEN_IN] THEN ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN
1504 MESON_TAC[LIMPT_OF_OPEN_IN; LIMPT_OF_UNIV]);;
1506 let OPEN_IN_SING = prove
1507 (`!s a. open_in (subtopology euclidean s) {a} <=>
1508 a IN s /\ ~(a limit_point_of s)`,
1509 REWRITE_TAC[open_in; LIMPT_APPROACHABLE; SING_SUBSET; IN_SING] THEN
1510 REWRITE_TAC[FORALL_UNWIND_THM2] THEN MESON_TAC[]);;
1512 (* ------------------------------------------------------------------------- *)
1513 (* Interior of a set. *)
1514 (* ------------------------------------------------------------------------- *)
1516 let interior = new_definition
1517 `interior s = {x | ?t. open t /\ x IN t /\ t SUBSET s}`;;
1519 let INTERIOR_EQ = prove
1520 (`!s. (interior s = s) <=> open s`,
1521 GEN_TAC THEN REWRITE_TAC[EXTENSION; interior; IN_ELIM_THM] THEN
1522 GEN_REWRITE_TAC RAND_CONV [OPEN_SUBOPEN] THEN MESON_TAC[SUBSET]);;
1524 let INTERIOR_OPEN = prove
1525 (`!s. open s ==> (interior s = s)`,
1526 MESON_TAC[INTERIOR_EQ]);;
1528 let INTERIOR_EMPTY = prove
1529 (`interior {} = {}`,
1530 SIMP_TAC[INTERIOR_OPEN; OPEN_EMPTY]);;
1532 let INTERIOR_UNIV = prove
1533 (`interior(:real^N) = (:real^N)`,
1534 SIMP_TAC[INTERIOR_OPEN; OPEN_UNIV]);;
1536 let OPEN_INTERIOR = prove
1537 (`!s. open(interior s)`,
1538 GEN_TAC THEN REWRITE_TAC[interior] THEN GEN_REWRITE_TAC I [OPEN_SUBOPEN] THEN
1539 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN MESON_TAC[]);;
1541 let INTERIOR_INTERIOR = prove
1542 (`!s. interior(interior s) = interior s`,
1543 MESON_TAC[INTERIOR_EQ; OPEN_INTERIOR]);;
1545 let INTERIOR_SUBSET = prove
1546 (`!s. (interior s) SUBSET s`,
1547 REWRITE_TAC[SUBSET; interior; IN_ELIM_THM] THEN MESON_TAC[]);;
1549 let SUBSET_INTERIOR = prove
1550 (`!s t. s SUBSET t ==> (interior s) SUBSET (interior t)`,
1551 REWRITE_TAC[interior; SUBSET; IN_ELIM_THM] THEN MESON_TAC[]);;
1553 let INTERIOR_MAXIMAL = prove
1554 (`!s t. t SUBSET s /\ open t ==> t SUBSET (interior s)`,
1555 REWRITE_TAC[interior; SUBSET; IN_ELIM_THM] THEN MESON_TAC[]);;
1557 let INTERIOR_MAXIMAL_EQ = prove
1558 (`!s t:real^N->bool. open s ==> (s SUBSET interior t <=> s SUBSET t)`,
1559 MESON_TAC[INTERIOR_MAXIMAL; SUBSET_TRANS; INTERIOR_SUBSET]);;
1561 let INTERIOR_UNIQUE = prove
1562 (`!s t. t SUBSET s /\ open t /\ (!t'. t' SUBSET s /\ open t' ==> t' SUBSET t)
1563 ==> (interior s = t)`,
1564 MESON_TAC[SUBSET_ANTISYM; INTERIOR_MAXIMAL; INTERIOR_SUBSET;
1567 let IN_INTERIOR = prove
1568 (`!x s. x IN interior s <=> ?e. &0 < e /\ ball(x,e) SUBSET s`,
1569 REWRITE_TAC[interior; IN_ELIM_THM] THEN
1570 MESON_TAC[OPEN_CONTAINS_BALL; SUBSET_TRANS; CENTRE_IN_BALL; OPEN_BALL]);;
1572 let OPEN_SUBSET_INTERIOR = prove
1573 (`!s t. open s ==> (s SUBSET interior t <=> s SUBSET t)`,
1574 MESON_TAC[INTERIOR_MAXIMAL; INTERIOR_SUBSET; SUBSET_TRANS]);;
1576 let INTERIOR_INTER = prove
1577 (`!s t:real^N->bool. interior(s INTER t) = interior s INTER interior t`,
1578 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
1579 [REWRITE_TAC[SUBSET_INTER] THEN CONJ_TAC THEN
1580 MATCH_MP_TAC SUBSET_INTERIOR THEN REWRITE_TAC[INTER_SUBSET];
1581 MATCH_MP_TAC INTERIOR_MAXIMAL THEN SIMP_TAC[OPEN_INTER; OPEN_INTERIOR] THEN
1582 MATCH_MP_TAC(SET_RULE
1583 `s SUBSET s' /\ t SUBSET t' ==> s INTER t SUBSET s' INTER t'`) THEN
1584 REWRITE_TAC[INTERIOR_SUBSET]]);;
1586 let INTERIOR_FINITE_INTERS = prove
1587 (`!s:(real^N->bool)->bool.
1588 FINITE s ==> interior(INTERS s) = INTERS(IMAGE interior s)`,
1589 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1590 REWRITE_TAC[INTERS_0; INTERS_INSERT; INTERIOR_UNIV; IMAGE_CLAUSES] THEN
1591 SIMP_TAC[INTERIOR_INTER]);;
1593 let INTERIOR_INTERS_SUBSET = prove
1594 (`!f. interior(INTERS f) SUBSET INTERS (IMAGE interior f)`,
1595 REWRITE_TAC[SUBSET; IN_INTERIOR; IN_INTERS; FORALL_IN_IMAGE] THEN
1598 let UNION_INTERIOR_SUBSET = prove
1599 (`!s t:real^N->bool.
1600 interior s UNION interior t SUBSET interior(s UNION t)`,
1601 SIMP_TAC[INTERIOR_MAXIMAL_EQ; OPEN_UNION; OPEN_INTERIOR] THEN
1602 REPEAT GEN_TAC THEN MATCH_MP_TAC(SET_RULE
1603 `s SUBSET s' /\ t SUBSET t' ==> (s UNION t) SUBSET (s' UNION t')`) THEN
1604 REWRITE_TAC[INTERIOR_SUBSET]);;
1606 let INTERIOR_EQ_EMPTY = prove
1607 (`!s:real^N->bool. interior s = {} <=> !t. open t /\ t SUBSET s ==> t = {}`,
1608 MESON_TAC[INTERIOR_MAXIMAL_EQ; SUBSET_EMPTY;
1609 OPEN_INTERIOR; INTERIOR_SUBSET]);;
1611 let INTERIOR_EQ_EMPTY_ALT = prove
1614 !t. open t /\ ~(t = {}) ==> ~(t DIFF s = {})`,
1615 GEN_TAC THEN REWRITE_TAC[INTERIOR_EQ_EMPTY] THEN SET_TAC[]);;
1617 let INTERIOR_LIMIT_POINT = prove
1618 (`!s x:real^N. x IN interior s ==> x limit_point_of s`,
1620 REWRITE_TAC[IN_INTERIOR; IN_ELIM_THM; SUBSET; IN_BALL] THEN
1621 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
1622 REWRITE_TAC[LIMPT_APPROACHABLE] THEN X_GEN_TAC `d:real` THEN
1624 MP_TAC(ISPECL [`x:real^N`; `min d e / &2`] VECTOR_CHOOSE_DIST) THEN
1625 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
1626 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
1627 REPEAT CONJ_TAC THENL
1628 [FIRST_X_ASSUM MATCH_MP_TAC;
1629 CONV_TAC (RAND_CONV SYM_CONV) THEN REWRITE_TAC[GSYM DIST_EQ_0];
1630 ONCE_REWRITE_TAC[DIST_SYM]] THEN
1631 ASM_REAL_ARITH_TAC);;
1633 let INTERIOR_SING = prove
1634 (`!a:real^N. interior {a} = {}`,
1635 REWRITE_TAC[EXTENSION; NOT_IN_EMPTY] THEN
1636 MESON_TAC[INTERIOR_LIMIT_POINT; LIMPT_SING]);;
1638 let INTERIOR_CLOSED_UNION_EMPTY_INTERIOR = prove
1639 (`!s t:real^N->bool.
1640 closed(s) /\ interior(t) = {}
1641 ==> interior(s UNION t) = interior(s)`,
1642 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
1643 SIMP_TAC[SUBSET_INTERIOR; SUBSET_UNION] THEN
1644 REWRITE_TAC[SUBSET; IN_INTERIOR; IN_INTER; IN_UNION] THEN
1645 X_GEN_TAC `x:real^N` THEN MATCH_MP_TAC MONO_EXISTS THEN
1646 X_GEN_TAC `e:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1647 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
1648 SUBGOAL_THEN `(y:real^N) limit_point_of s`
1649 (fun th -> ASM_MESON_TAC[CLOSED_LIMPT; th]) THEN
1650 REWRITE_TAC[IN_INTERIOR; NOT_IN_EMPTY; LIMPT_APPROACHABLE] THEN
1651 X_GEN_TAC `d:real` THEN DISCH_TAC THEN
1653 `?z:real^N. ~(z IN t) /\ ~(z = y) /\ dist(z,y) < d /\ dist(x,z) < e`
1654 (fun th -> ASM_MESON_TAC[th; IN_BALL]) THEN
1655 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN
1656 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
1657 REWRITE_TAC[IN_INTERIOR; NOT_IN_EMPTY; NOT_EXISTS_THM] THEN
1658 ABBREV_TAC `k = min d (e - dist(x:real^N,y))` THEN
1659 SUBGOAL_THEN `&0 < k` ASSUME_TAC THENL
1660 [ASM_ARITH_TAC; ALL_TAC] THEN
1661 SUBGOAL_THEN `?w:real^N. dist(y,w) = k / &2` CHOOSE_TAC THENL
1662 [ASM_SIMP_TAC[VECTOR_CHOOSE_DIST; REAL_HALF; REAL_LT_IMP_LE]; ALL_TAC] THEN
1663 DISCH_THEN(MP_TAC o SPECL [`w:real^N`; `k / &4`]) THEN
1664 ASM_SIMP_TAC[SUBSET; NOT_FORALL_THM; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH;
1665 NOT_IMP; IN_BALL] THEN
1666 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:real^N` THEN
1667 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN ASM_REWRITE_TAC[] THEN
1668 ASM_NORM_ARITH_TAC);;
1670 let INTERIOR_UNION_EQ_EMPTY = prove
1671 (`!s t:real^N->bool.
1672 closed s \/ closed t
1673 ==> (interior(s UNION t) = {} <=>
1674 interior s = {} /\ interior t = {})`,
1675 REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THENL
1676 [ASM_MESON_TAC[SUBSET_UNION; SUBSET_INTERIOR; SUBSET_EMPTY];
1677 ASM_MESON_TAC[UNION_COMM; INTERIOR_CLOSED_UNION_EMPTY_INTERIOR]]);;
1679 let INTERIOR_UNIONS_OPEN_SUBSETS = prove
1680 (`!s:real^N->bool. UNIONS {t | open t /\ t SUBSET s} = interior s`,
1681 GEN_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN
1682 SIMP_TAC[OPEN_UNIONS; IN_ELIM_THM] THEN SET_TAC[]);;
1684 (* ------------------------------------------------------------------------- *)
1685 (* Closure of a set. *)
1686 (* ------------------------------------------------------------------------- *)
1688 let closure = new_definition
1689 `closure s = s UNION {x | x limit_point_of s}`;;
1691 let CLOSURE_INTERIOR = prove
1692 (`!s:real^N->bool. closure s = UNIV DIFF (interior (UNIV DIFF s))`,
1693 REWRITE_TAC[EXTENSION; closure; IN_UNION; IN_DIFF; IN_UNIV; interior;
1694 IN_ELIM_THM; limit_point_of; SUBSET] THEN
1697 let INTERIOR_CLOSURE = prove
1698 (`!s:real^N->bool. interior s = UNIV DIFF (closure (UNIV DIFF s))`,
1699 let lemma = prove(`!s t. UNIV DIFF (UNIV DIFF t) = t`,SET_TAC[]) in
1700 REWRITE_TAC[CLOSURE_INTERIOR; lemma]);;
1702 let CLOSED_CLOSURE = prove
1703 (`!s. closed(closure s)`,
1704 let lemma = prove(`UNIV DIFF (UNIV DIFF s) = s`,SET_TAC[]) in
1705 REWRITE_TAC[closed; CLOSURE_INTERIOR; lemma; OPEN_INTERIOR]);;
1707 let CLOSURE_HULL = prove
1708 (`!s. closure s = closed hull s`,
1709 GEN_TAC THEN MATCH_MP_TAC(GSYM HULL_UNIQUE) THEN
1710 REWRITE_TAC[CLOSED_CLOSURE; SUBSET] THEN
1711 REWRITE_TAC[closure; IN_UNION; IN_ELIM_THM; CLOSED_LIMPT] THEN
1712 MESON_TAC[limit_point_of]);;
1714 let CLOSURE_EQ = prove
1715 (`!s. (closure s = s) <=> closed s`,
1716 SIMP_TAC[CLOSURE_HULL; HULL_EQ; CLOSED_INTERS]);;
1718 let CLOSURE_CLOSED = prove
1719 (`!s. closed s ==> (closure s = s)`,
1720 MESON_TAC[CLOSURE_EQ]);;
1722 let CLOSURE_CLOSURE = prove
1723 (`!s. closure(closure s) = closure s`,
1724 REWRITE_TAC[CLOSURE_HULL; HULL_HULL]);;
1726 let CLOSURE_SUBSET = prove
1727 (`!s. s SUBSET (closure s)`,
1728 REWRITE_TAC[CLOSURE_HULL; HULL_SUBSET]);;
1730 let SUBSET_CLOSURE = prove
1731 (`!s t. s SUBSET t ==> (closure s) SUBSET (closure t)`,
1732 REWRITE_TAC[CLOSURE_HULL; HULL_MONO]);;
1734 let CLOSURE_UNION = prove
1735 (`!s t:real^N->bool. closure(s UNION t) = closure s UNION closure t`,
1736 REWRITE_TAC[LIMIT_POINT_UNION; closure] THEN SET_TAC[]);;
1738 let CLOSURE_INTER_SUBSET = prove
1739 (`!s t. closure(s INTER t) SUBSET closure(s) INTER closure(t)`,
1740 REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET_INTER] THEN
1741 CONJ_TAC THEN MATCH_MP_TAC SUBSET_CLOSURE THEN SET_TAC[]);;
1743 let CLOSURE_INTERS_SUBSET = prove
1744 (`!f. closure(INTERS f) SUBSET INTERS(IMAGE closure f)`,
1745 REWRITE_TAC[SET_RULE `s SUBSET INTERS f <=> !t. t IN f ==> s SUBSET t`] THEN
1746 REWRITE_TAC[FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN
1747 MATCH_MP_TAC SUBSET_CLOSURE THEN ASM SET_TAC[]);;
1749 let CLOSURE_MINIMAL = prove
1750 (`!s t. s SUBSET t /\ closed t ==> (closure s) SUBSET t`,
1751 REWRITE_TAC[HULL_MINIMAL; CLOSURE_HULL]);;
1753 let CLOSURE_MINIMAL_EQ = prove
1754 (`!s t:real^N->bool. closed t ==> (closure s SUBSET t <=> s SUBSET t)`,
1755 MESON_TAC[SUBSET_TRANS; CLOSURE_SUBSET; CLOSURE_MINIMAL]);;
1757 let CLOSURE_UNIQUE = prove
1758 (`!s t. s SUBSET t /\ closed t /\
1759 (!t'. s SUBSET t' /\ closed t' ==> t SUBSET t')
1760 ==> (closure s = t)`,
1761 REWRITE_TAC[CLOSURE_HULL; HULL_UNIQUE]);;
1763 let CLOSURE_EMPTY = prove
1765 SIMP_TAC[CLOSURE_CLOSED; CLOSED_EMPTY]);;
1767 let CLOSURE_UNIV = prove
1768 (`closure(:real^N) = (:real^N)`,
1769 SIMP_TAC[CLOSURE_CLOSED; CLOSED_UNIV]);;
1771 let CLOSURE_UNIONS = prove
1772 (`!f. FINITE f ==> closure(UNIONS f) = UNIONS {closure s | s IN f}`,
1773 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1774 REWRITE_TAC[UNIONS_0; UNIONS_INSERT; SET_RULE `{f x | x IN {}} = {}`;
1775 SET_RULE `{f x | x IN a INSERT s} = (f a) INSERT {f x | x IN s}`] THEN
1776 SIMP_TAC[CLOSURE_EMPTY; CLOSURE_UNION]);;
1778 let CLOSURE_EQ_EMPTY = prove
1779 (`!s. closure s = {} <=> s = {}`,
1780 GEN_TAC THEN EQ_TAC THEN SIMP_TAC[CLOSURE_EMPTY] THEN
1781 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> t = {} ==> s = {}`) THEN
1782 REWRITE_TAC[CLOSURE_SUBSET]);;
1784 let CLOSURE_SUBSET_EQ = prove
1785 (`!s:real^N->bool. closure s SUBSET s <=> closed s`,
1786 GEN_TAC THEN REWRITE_TAC[GSYM CLOSURE_EQ] THEN
1787 MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN SET_TAC[]);;
1789 let OPEN_INTER_CLOSURE_EQ_EMPTY = prove
1790 (`!s t:real^N->bool.
1791 open s ==> (s INTER (closure t) = {} <=> s INTER t = {})`,
1792 REPEAT STRIP_TAC THEN EQ_TAC THENL
1793 [MP_TAC(ISPEC `t:real^N->bool` CLOSURE_SUBSET) THEN SET_TAC[]; ALL_TAC] THEN
1794 DISCH_TAC THEN REWRITE_TAC[CLOSURE_INTERIOR] THEN
1795 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> s INTER (UNIV DIFF t) = {}`) THEN
1796 ASM_SIMP_TAC[OPEN_SUBSET_INTERIOR] THEN ASM SET_TAC[]);;
1798 let OPEN_INTER_CLOSURE_SUBSET = prove
1799 (`!s t:real^N->bool.
1800 open s ==> (s INTER (closure t)) SUBSET closure(s INTER t)`,
1801 REPEAT STRIP_TAC THEN
1802 SIMP_TAC[SUBSET; IN_INTER; closure; IN_UNION; IN_ELIM_THM] THEN
1803 X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1804 DISJ2_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
1805 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1806 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [open_def]) THEN
1807 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
1808 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
1809 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIMPT_APPROACHABLE]) THEN
1810 DISCH_THEN(MP_TAC o SPEC `min d e`) THEN
1811 ASM_REWRITE_TAC[REAL_LT_MIN; IN_INTER] THEN
1812 MATCH_MP_TAC MONO_EXISTS THEN ASM_MESON_TAC[]);;
1814 let CLOSURE_OPEN_INTER_SUPERSET = prove
1815 (`!s t:real^N->bool.
1816 open s /\ s SUBSET closure t ==> closure(s INTER t) = closure s`,
1817 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
1818 SIMP_TAC[SUBSET_CLOSURE; INTER_SUBSET] THEN
1819 MATCH_MP_TAC CLOSURE_MINIMAL THEN REWRITE_TAC[CLOSED_CLOSURE] THEN
1820 W(MP_TAC o PART_MATCH (rand o rand)
1821 OPEN_INTER_CLOSURE_SUBSET o rand o snd) THEN
1822 ASM_REWRITE_TAC[] THEN
1823 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] SUBSET_TRANS) THEN ASM SET_TAC[]);;
1825 let CLOSURE_COMPLEMENT = prove
1826 (`!s:real^N->bool. closure(UNIV DIFF s) = UNIV DIFF interior(s)`,
1827 REWRITE_TAC[SET_RULE `s = UNIV DIFF t <=> UNIV DIFF s = t`] THEN
1828 REWRITE_TAC[GSYM INTERIOR_CLOSURE]);;
1830 let INTERIOR_COMPLEMENT = prove
1831 (`!s:real^N->bool. interior(UNIV DIFF s) = UNIV DIFF closure(s)`,
1832 REWRITE_TAC[SET_RULE `s = UNIV DIFF t <=> UNIV DIFF s = t`] THEN
1833 REWRITE_TAC[GSYM CLOSURE_INTERIOR]);;
1835 let CONNECTED_INTERMEDIATE_CLOSURE = prove
1836 (`!s t:real^N->bool.
1837 connected s /\ s SUBSET t /\ t SUBSET closure s ==> connected t`,
1838 REPEAT GEN_TAC THEN REWRITE_TAC[connected; NOT_EXISTS_THM] THEN
1840 MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN STRIP_TAC THEN
1841 FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^N->bool`; `v:real^N->bool`]) THEN
1842 ASM_REWRITE_TAC[] THEN ASSUME_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN
1843 REPLICATE_TAC 2 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
1844 REWRITE_TAC[GSYM DE_MORGAN_THM] THEN STRIP_TAC THENL
1845 [SUBGOAL_THEN `(closure s) SUBSET ((:real^N) DIFF u)` MP_TAC THENL
1846 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_REWRITE_TAC[GSYM OPEN_CLOSED];
1848 SUBGOAL_THEN `(closure s) SUBSET ((:real^N) DIFF v)` MP_TAC THENL
1849 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_REWRITE_TAC[GSYM OPEN_CLOSED];
1853 let CONNECTED_CLOSURE = prove
1854 (`!s:real^N->bool. connected s ==> connected(closure s)`,
1855 MESON_TAC[CONNECTED_INTERMEDIATE_CLOSURE; CLOSURE_SUBSET; SUBSET_REFL]);;
1857 let CONNECTED_UNION_STRONG = prove
1858 (`!s t:real^N->bool.
1859 connected s /\ connected t /\ ~(closure s INTER t = {})
1860 ==> connected(s UNION t)`,
1861 REPEAT STRIP_TAC THEN
1862 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
1863 DISCH_THEN(X_CHOOSE_TAC `p:real^N`) THEN
1864 SUBGOAL_THEN `s UNION t = ((p:real^N) INSERT s) UNION t` SUBST1_TAC THENL
1865 [ASM SET_TAC[]; ALL_TAC] THEN
1866 MATCH_MP_TAC CONNECTED_UNION THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
1867 [MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN
1868 EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN
1869 MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[];
1872 let INTERIOR_DIFF = prove
1873 (`!s t. interior(s DIFF t) = interior(s) DIFF closure(t)`,
1874 ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN
1875 REWRITE_TAC[INTERIOR_INTER; CLOSURE_INTERIOR] THEN SET_TAC[]);;
1877 let LIMPT_OF_CLOSURE = prove
1878 (`!x:real^N s. x limit_point_of closure s <=> x limit_point_of s`,
1879 REWRITE_TAC[closure; IN_UNION; IN_ELIM_THM; LIMIT_POINT_UNION] THEN
1880 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT `(q ==> p) ==> (p \/ q <=> p)`) THEN
1881 REWRITE_TAC[LIMPT_OF_LIMPTS]);;
1883 let CLOSED_IN_LIMPT = prove
1884 (`!s t. closed_in (subtopology euclidean t) s <=>
1885 s SUBSET t /\ !x:real^N. x limit_point_of s /\ x IN t ==> x IN s`,
1886 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN EQ_TAC THENL
1887 [DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
1888 ASM_SIMP_TAC[IN_INTER] THEN
1889 ASM_MESON_TAC[CLOSED_LIMPT; LIMPT_SUBSET; INTER_SUBSET];
1890 STRIP_TAC THEN EXISTS_TAC `closure s :real^N->bool` THEN
1891 REWRITE_TAC[CLOSED_CLOSURE] THEN REWRITE_TAC[closure] THEN
1894 let CLOSED_IN_INTER_CLOSURE = prove
1895 (`!s t:real^N->bool.
1896 closed_in (subtopology euclidean s) t <=> s INTER closure t = t`,
1897 REWRITE_TAC[closure; CLOSED_IN_LIMPT] THEN SET_TAC[]);;
1899 let INTERIOR_CLOSURE_IDEMP = prove
1901 interior(closure(interior(closure s))) = interior(closure s)`,
1902 GEN_TAC THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN
1903 ASM_MESON_TAC[OPEN_INTERIOR; CLOSURE_SUBSET; CLOSURE_CLOSURE; SUBSET_TRANS;
1904 OPEN_SUBSET_INTERIOR;SUBSET_CLOSURE; INTERIOR_SUBSET]);;
1906 let CLOSURE_INTERIOR_IDEMP = prove
1908 closure(interior(closure(interior s))) = closure(interior s)`,
1910 ONCE_REWRITE_TAC[SET_RULE `s = t <=> UNIV DIFF s = UNIV DIFF t`] THEN
1911 REWRITE_TAC[GSYM INTERIOR_COMPLEMENT; GSYM CLOSURE_COMPLEMENT] THEN
1912 REWRITE_TAC[INTERIOR_CLOSURE_IDEMP]);;
1914 let NOWHERE_DENSE_UNION = prove
1915 (`!s t:real^N->bool.
1916 interior(closure(s UNION t)) = {} <=>
1917 interior(closure s) = {} /\ interior(closure t) = {}`,
1918 SIMP_TAC[CLOSURE_UNION; INTERIOR_UNION_EQ_EMPTY; CLOSED_CLOSURE]);;
1920 let NOWHERE_DENSE = prove
1922 interior(closure s) = {} <=>
1923 !t. open t /\ ~(t = {})
1924 ==> ?u. open u /\ ~(u = {}) /\ u SUBSET t /\ u INTER s = {}`,
1925 GEN_TAC THEN REWRITE_TAC[INTERIOR_EQ_EMPTY_ALT] THEN EQ_TAC THEN
1926 DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THENL
1927 [EXISTS_TAC `t DIFF closure s:real^N->bool` THEN
1928 ASM_SIMP_TAC[OPEN_DIFF; CLOSED_CLOSURE] THEN
1929 MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN SET_TAC[];
1930 FIRST_X_ASSUM(MP_TAC o SPEC `t:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
1931 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
1932 MP_TAC(ISPECL [`u:real^N->bool`; `s:real^N->bool`]
1933 OPEN_INTER_CLOSURE_EQ_EMPTY) THEN
1936 let INTERIOR_CLOSURE_INTER_OPEN = prove
1937 (`!s t:real^N->bool.
1939 ==> interior(closure(s INTER t)) =
1940 interior(closure s) INTER interior(closure t)`,
1941 REPEAT STRIP_TAC THEN REWRITE_TAC[SET_RULE
1942 `u = s INTER t <=> s INTER t SUBSET u /\ u SUBSET s /\ u SUBSET t`] THEN
1943 SIMP_TAC[SUBSET_INTERIOR; SUBSET_CLOSURE; INTER_SUBSET] THEN
1944 MATCH_MP_TAC INTERIOR_MAXIMAL THEN SIMP_TAC[OPEN_INTER; OPEN_INTERIOR] THEN
1945 REWRITE_TAC[SET_RULE `s SUBSET t <=> s INTER (UNIV DIFF t) = {}`;
1946 GSYM INTERIOR_COMPLEMENT] THEN
1947 REWRITE_TAC[GSYM INTERIOR_INTER] THEN
1948 REWRITE_TAC[INTERIOR_EQ_EMPTY] THEN
1949 X_GEN_TAC `u:real^N->bool` THEN STRIP_TAC THEN
1950 MP_TAC(ISPECL [`u INTER s:real^N->bool`; `t:real^N->bool`]
1951 OPEN_INTER_CLOSURE_EQ_EMPTY) THEN
1952 MP_TAC(ISPECL [`u:real^N->bool`; `s:real^N->bool`]
1953 OPEN_INTER_CLOSURE_EQ_EMPTY) THEN
1954 ASM_SIMP_TAC[OPEN_INTER] THEN ASM SET_TAC[]);;
1956 let CLOSURE_INTERIOR_UNION_CLOSED = prove
1957 (`!s t:real^N->bool.
1958 closed s /\ closed t
1959 ==> closure(interior(s UNION t)) =
1960 closure(interior s) UNION closure(interior t)`,
1961 REPEAT GEN_TAC THEN REWRITE_TAC[closed] THEN
1962 DISCH_THEN(MP_TAC o MATCH_MP INTERIOR_CLOSURE_INTER_OPEN) THEN
1963 REWRITE_TAC[CLOSURE_COMPLEMENT; INTERIOR_COMPLEMENT;
1964 SET_RULE `(UNIV DIFF s) INTER (UNIV DIFF t) =
1965 UNIV DIFF (s UNION t)`] THEN
1968 let REGULAR_OPEN_INTER = prove
1969 (`!s t:real^N->bool.
1970 interior(closure s) = s /\ interior(closure t) = t
1971 ==> interior(closure(s INTER t)) = s INTER t`,
1972 MESON_TAC[INTERIOR_CLOSURE_INTER_OPEN; OPEN_INTERIOR]);;
1974 let REGULAR_CLOSED_UNION = prove
1975 (`!s t:real^N->bool.
1976 closure(interior s) = s /\ closure(interior t) = t
1977 ==> closure(interior(s UNION t)) = s UNION t`,
1978 MESON_TAC[CLOSURE_INTERIOR_UNION_CLOSED; CLOSED_CLOSURE]);;
1980 let DIFF_CLOSURE_SUBSET = prove
1981 (`!s t:real^N->bool. closure(s) DIFF closure t SUBSET closure(s DIFF t)`,
1983 MP_TAC(ISPECL [`(:real^N) DIFF closure t`; `s:real^N->bool`]
1984 OPEN_INTER_CLOSURE_SUBSET) THEN
1985 REWRITE_TAC[SET_RULE `(UNIV DIFF t) INTER s = s DIFF t`] THEN
1986 REWRITE_TAC[GSYM closed; CLOSED_CLOSURE] THEN
1987 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUBSET_TRANS) THEN
1988 MATCH_MP_TAC SUBSET_CLOSURE THEN
1989 MATCH_MP_TAC(SET_RULE `t SUBSET u ==> s DIFF u SUBSET s DIFF t`) THEN
1990 REWRITE_TAC[CLOSURE_SUBSET]);;
1992 (* ------------------------------------------------------------------------- *)
1993 (* Frontier (aka boundary). *)
1994 (* ------------------------------------------------------------------------- *)
1996 let frontier = new_definition
1997 `frontier s = (closure s) DIFF (interior s)`;;
1999 let FRONTIER_CLOSED = prove
2000 (`!s. closed(frontier s)`,
2001 SIMP_TAC[frontier; CLOSED_DIFF; CLOSED_CLOSURE; OPEN_INTERIOR]);;
2003 let FRONTIER_CLOSURES = prove
2004 (`!s:real^N->bool. frontier s = (closure s) INTER (closure(UNIV DIFF s))`,
2005 let lemma = prove(`s DIFF (UNIV DIFF t) = s INTER t`,SET_TAC[]) in
2006 REWRITE_TAC[frontier; INTERIOR_CLOSURE; lemma]);;
2008 let FRONTIER_STRADDLE = prove
2011 !e. &0 < e ==> (?x. x IN s /\ dist(a,x) < e) /\
2012 (?x. ~(x IN s) /\ dist(a,x) < e)`,
2013 REPEAT GEN_TAC THEN REWRITE_TAC[FRONTIER_CLOSURES; IN_INTER] THEN
2014 REWRITE_TAC[closure; IN_UNION; IN_ELIM_THM; limit_point_of;
2015 IN_UNIV; IN_DIFF] THEN
2016 ASM_MESON_TAC[IN_BALL; SUBSET; OPEN_CONTAINS_BALL;
2017 CENTRE_IN_BALL; OPEN_BALL; DIST_REFL]);;
2019 let FRONTIER_SUBSET_CLOSED = prove
2020 (`!s. closed s ==> (frontier s) SUBSET s`,
2021 MESON_TAC[frontier; CLOSURE_CLOSED; SUBSET_DIFF]);;
2023 let FRONTIER_EMPTY = prove
2024 (`frontier {} = {}`,
2025 REWRITE_TAC[frontier; CLOSURE_EMPTY; EMPTY_DIFF]);;
2027 let FRONTIER_UNIV = prove
2028 (`frontier(:real^N) = {}`,
2029 REWRITE_TAC[frontier; CLOSURE_UNIV; INTERIOR_UNIV] THEN SET_TAC[]);;
2031 let FRONTIER_SUBSET_EQ = prove
2032 (`!s:real^N->bool. (frontier s) SUBSET s <=> closed s`,
2033 GEN_TAC THEN EQ_TAC THEN SIMP_TAC[FRONTIER_SUBSET_CLOSED] THEN
2034 REWRITE_TAC[frontier] THEN
2035 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
2036 `s DIFF t SUBSET u ==> t SUBSET u ==> s SUBSET u`)) THEN
2037 REWRITE_TAC[INTERIOR_SUBSET; CLOSURE_SUBSET_EQ]);;
2039 let FRONTIER_COMPLEMENT = prove
2040 (`!s:real^N->bool. frontier(UNIV DIFF s) = frontier s`,
2041 REWRITE_TAC[frontier; CLOSURE_COMPLEMENT; INTERIOR_COMPLEMENT] THEN
2044 let FRONTIER_DISJOINT_EQ = prove
2045 (`!s. (frontier s) INTER s = {} <=> open s`,
2046 ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT; OPEN_CLOSED] THEN
2047 REWRITE_TAC[GSYM FRONTIER_SUBSET_EQ] THEN SET_TAC[]);;
2049 let FRONTIER_INTER_SUBSET = prove
2050 (`!s t. frontier(s INTER t) SUBSET frontier(s) UNION frontier(t)`,
2051 REPEAT GEN_TAC THEN REWRITE_TAC[frontier; INTERIOR_INTER] THEN
2052 MATCH_MP_TAC(SET_RULE
2053 `cst SUBSET cs INTER ct
2054 ==> cst DIFF (s INTER t) SUBSET (cs DIFF s) UNION (ct DIFF t)`) THEN
2055 REWRITE_TAC[CLOSURE_INTER_SUBSET]);;
2057 let FRONTIER_UNION_SUBSET = prove
2058 (`!s t:real^N->bool. frontier(s UNION t) SUBSET frontier s UNION frontier t`,
2059 ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT] THEN
2060 REWRITE_TAC[SET_RULE `u DIFF (s UNION t) = (u DIFF s) INTER (u DIFF t)`] THEN
2061 REWRITE_TAC[FRONTIER_INTER_SUBSET]);;
2063 let FRONTIER_INTERIORS = prove
2064 (`!s. frontier s = (:real^N) DIFF interior(s) DIFF interior((:real^N) DIFF s)`,
2065 REWRITE_TAC[frontier; CLOSURE_INTERIOR] THEN SET_TAC[]);;
2067 let FRONTIER_FRONTIER_SUBSET = prove
2068 (`!s:real^N->bool. frontier(frontier s) SUBSET frontier s`,
2069 GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [frontier] THEN
2070 SIMP_TAC[CLOSURE_CLOSED; FRONTIER_CLOSED] THEN SET_TAC[]);;
2072 let INTERIOR_FRONTIER = prove
2074 interior(frontier s) = interior(closure s) DIFF closure(interior s)`,
2075 ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN
2076 REWRITE_TAC[GSYM INTERIOR_COMPLEMENT; GSYM INTERIOR_INTER; frontier] THEN
2077 GEN_TAC THEN AP_TERM_TAC THEN SET_TAC[]);;
2079 let INTERIOR_FRONTIER_EMPTY = prove
2080 (`!s:real^N->bool. open s \/ closed s ==> interior(frontier s) = {}`,
2081 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[INTERIOR_FRONTIER] THEN
2082 ASM_SIMP_TAC[CLOSURE_CLOSED; INTERIOR_OPEN] THEN
2083 REWRITE_TAC[SET_RULE `s DIFF t = {} <=> s SUBSET t`] THEN
2084 REWRITE_TAC[INTERIOR_SUBSET; CLOSURE_SUBSET]);;
2086 let FRONTIER_FRONTIER = prove
2087 (`!s:real^N->bool. open s \/ closed s ==> frontier(frontier s) = frontier s`,
2088 GEN_TAC THEN GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [frontier] THEN
2089 SIMP_TAC[INTERIOR_FRONTIER_EMPTY; CLOSURE_CLOSED; FRONTIER_CLOSED] THEN
2090 REWRITE_TAC[DIFF_EMPTY]);;
2092 let FRONTIER_FRONTIER_FRONTIER = prove
2093 (`!s:real^N->bool. frontier(frontier(frontier s)) = frontier(frontier s)`,
2094 SIMP_TAC[FRONTIER_FRONTIER; FRONTIER_CLOSED]);;
2096 let UNION_FRONTIER = prove
2097 (`!s t:real^N->bool.
2098 frontier(s) UNION frontier(t) =
2099 frontier(s UNION t) UNION
2100 frontier(s INTER t) UNION
2101 frontier(s) INTER frontier(t)`,
2103 (`!s t x. x IN frontier s /\ x IN interior t ==> x IN frontier(s INTER t)`,
2104 REWRITE_TAC[FRONTIER_STRADDLE; IN_INTER; IN_INTERIOR; SUBSET; IN_BALL] THEN
2106 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_TAC `d:real`)) THEN
2107 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2108 FIRST_X_ASSUM(MP_TAC o SPEC `min d e:real`) THEN
2109 ASM_REWRITE_TAC[REAL_LT_MIN] THEN ASM_MESON_TAC[]) in
2110 REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; UNION_SUBSET;
2111 FRONTIER_UNION_SUBSET; FRONTIER_INTER_SUBSET;
2112 SET_RULE `s INTER t SUBSET s UNION t`] THEN
2113 REWRITE_TAC[GSYM UNION_SUBSET] THEN REWRITE_TAC[SUBSET; IN_UNION] THEN
2114 MATCH_MP_TAC(MESON[]
2115 `(!s t x. P s x ==> R x s t) /\ (!s t x. R x s t <=> R x t s)
2116 ==> (!s t x. P s x \/ P t x ==> R x s t)`) THEN
2117 CONJ_TAC THENL [REPEAT STRIP_TAC; REWRITE_TAC[UNION_COMM; INTER_COMM]] THEN
2118 ASM_CASES_TAC `(x:real^N) IN frontier t` THEN ASM_REWRITE_TAC[IN_INTER] THEN
2119 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (RAND_CONV o RAND_CONV)
2120 [FRONTIER_INTERIORS]) THEN
2121 REWRITE_TAC[DE_MORGAN_THM; IN_DIFF; IN_UNIV] THEN
2122 GEN_REWRITE_TAC RAND_CONV [DISJ_SYM] THEN MATCH_MP_TAC MONO_OR THEN
2123 ASM_SIMP_TAC[lemma] THEN
2124 POP_ASSUM MP_TAC THEN ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT] THEN
2125 SIMP_TAC[lemma; SET_RULE
2126 `UNIV DIFF (s UNION t) = (UNIV DIFF s) INTER (UNIV DIFF t)`]);;
2128 let CONNECTED_INTER_FRONTIER = prove
2129 (`!s t:real^N->bool.
2130 connected s /\ ~(s INTER t = {}) /\ ~(s DIFF t = {})
2131 ==> ~(s INTER frontier t = {})`,
2132 REWRITE_TAC[FRONTIER_INTERIORS] THEN REPEAT STRIP_TAC THEN
2133 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONNECTED_OPEN_IN]) THEN
2134 REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC
2135 [`s INTER interior t:real^N->bool`;
2136 `s INTER (interior((:real^N) DIFF t))`] THEN
2137 SIMP_TAC[OPEN_IN_OPEN_INTER; OPEN_INTERIOR] THEN
2138 MAP_EVERY (MP_TAC o C ISPEC INTERIOR_SUBSET)
2139 [`t:real^N->bool`; `(:real^N) DIFF t`] THEN
2142 let INTERIOR_CLOSED_EQ_EMPTY_AS_FRONTIER = prove
2144 closed s /\ interior s = {} <=> ?t. open t /\ s = frontier t`,
2145 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THENL
2146 [EXISTS_TAC `(:real^N) DIFF s` THEN
2147 ASM_SIMP_TAC[OPEN_DIFF; OPEN_UNIV; FRONTIER_COMPLEMENT] THEN
2148 ASM_SIMP_TAC[frontier; CLOSURE_CLOSED; DIFF_EMPTY];
2149 ASM_SIMP_TAC[FRONTIER_CLOSED; INTERIOR_FRONTIER_EMPTY]]);;
2151 let FRONTIER_UNION = prove
2152 (`!s t:real^N->bool.
2153 closure s INTER closure t = {}
2154 ==> frontier(s UNION t) = frontier(s) UNION frontier(t)`,
2155 REPEAT STRIP_TAC THEN
2156 MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[FRONTIER_UNION_SUBSET] THEN
2157 GEN_REWRITE_TAC RAND_CONV [frontier] THEN
2158 REWRITE_TAC[CLOSURE_UNION] THEN MATCH_MP_TAC(SET_RULE
2159 `(fs SUBSET cs /\ ft SUBSET ct) /\ k INTER fs = {} /\ k INTER ft = {}
2160 ==> (fs UNION ft) SUBSET (cs UNION ct) DIFF k`) THEN
2161 CONJ_TAC THENL [REWRITE_TAC[frontier] THEN SET_TAC[]; ALL_TAC] THEN
2164 ONCE_REWRITE_TAC[UNION_COMM] THEN
2165 RULE_ASSUM_TAC(ONCE_REWRITE_RULE[INTER_COMM])] THEN
2166 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
2167 `s INTER t = {} ==> s' SUBSET s /\ s' INTER u INTER (UNIV DIFF t) = {}
2168 ==> u INTER s' = {}`)) THEN
2169 REWRITE_TAC[frontier; SUBSET_DIFF; GSYM INTERIOR_COMPLEMENT] THEN
2170 REWRITE_TAC[GSYM INTERIOR_INTER; SET_RULE
2171 `(s UNION t) INTER (UNIV DIFF t) = s DIFF t`] THEN
2172 MATCH_MP_TAC(SET_RULE
2173 `ti SUBSET si ==> (c DIFF si) INTER ti = {}`) THEN
2174 SIMP_TAC[SUBSET_INTERIOR; SUBSET_DIFF]);;
2176 let CLOSURE_UNION_FRONTIER = prove
2177 (`!s:real^N->bool. closure s = s UNION frontier s`,
2178 GEN_TAC THEN REWRITE_TAC[frontier] THEN
2179 MP_TAC(ISPEC `s:real^N->bool` INTERIOR_SUBSET) THEN
2180 MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN
2183 let FRONTIER_INTERIOR_SUBSET = prove
2184 (`!s:real^N->bool. frontier(interior s) SUBSET frontier s`,
2185 GEN_TAC THEN REWRITE_TAC[frontier; INTERIOR_INTERIOR] THEN
2186 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> s DIFF u SUBSET t DIFF u`) THEN
2187 SIMP_TAC[SUBSET_CLOSURE; INTERIOR_SUBSET]);;
2189 let FRONTIER_CLOSURE_SUBSET = prove
2190 (`!s:real^N->bool. frontier(closure s) SUBSET frontier s`,
2191 GEN_TAC THEN REWRITE_TAC[frontier; CLOSURE_CLOSURE] THEN
2192 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> u DIFF t SUBSET u DIFF s`) THEN
2193 SIMP_TAC[SUBSET_INTERIOR; CLOSURE_SUBSET]);;
2195 let SET_DIFF_FRONTIER = prove
2196 (`!s:real^N->bool. s DIFF frontier s = interior s`,
2197 GEN_TAC THEN REWRITE_TAC[frontier] THEN
2198 MP_TAC(ISPEC `s:real^N->bool` INTERIOR_SUBSET) THEN
2199 MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN
2202 let FRONTIER_INTER_SUBSET_INTER = prove
2203 (`!s t:real^N->bool.
2204 frontier(s INTER t) SUBSET closure s INTER frontier t UNION
2205 frontier s INTER closure t`,
2206 REPEAT GEN_TAC THEN REWRITE_TAC[frontier; INTERIOR_INTER] THEN
2207 MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`]
2208 CLOSURE_INTER_SUBSET) THEN
2211 (* ------------------------------------------------------------------------- *)
2212 (* A variant of nets (slightly non-standard but good for our purposes). *)
2213 (* ------------------------------------------------------------------------- *)
2215 let net_tybij = new_type_definition "net" ("mk_net","netord")
2217 (`?g:A->A->bool. !x y. (!z. g z x ==> g z y) \/ (!z. g z y ==> g z x)`,
2218 EXISTS_TAC `\x:A y:A. F` THEN REWRITE_TAC[]));;
2221 (`!n x y. (!z. netord n z x ==> netord n z y) \/
2222 (!z. netord n z y ==> netord n z x)`,
2223 REWRITE_TAC[net_tybij; ETA_AX]);;
2226 (`!n x y. netord n x x /\ netord n y y
2227 ==> ?z. netord n z z /\
2228 !w. netord n w z ==> netord n w x /\ netord n w y`,
2231 let NET_DILEMMA = prove
2232 (`!net. (?a. (?x. netord net x a) /\ (!x. netord net x a ==> P x)) /\
2233 (?b. (?x. netord net x b) /\ (!x. netord net x b ==> Q x))
2234 ==> ?c. (?x. netord net x c) /\ (!x. netord net x c ==> P x /\ Q x)`,
2237 (* ------------------------------------------------------------------------- *)
2238 (* Common nets and the "within" modifier for nets. *)
2239 (* ------------------------------------------------------------------------- *)
2241 parse_as_infix("within",(14,"right"));;
2242 parse_as_infix("in_direction",(14,"right"));;
2244 let at = new_definition
2245 `at a = mk_net(\x y. &0 < dist(x,a) /\ dist(x,a) <= dist(y,a))`;;
2247 let at_infinity = new_definition
2248 `at_infinity = mk_net(\x y. norm(x) >= norm(y))`;;
2250 let at_posinfinity = new_definition
2251 `at_posinfinity = mk_net(\x y:real. x >= y)`;;
2253 let at_neginfinity = new_definition
2254 `at_neginfinity = mk_net(\x y:real. x <= y)`;;
2256 let sequentially = new_definition
2257 `sequentially = mk_net(\m:num n. m >= n)`;;
2259 let within = new_definition
2260 `net within s = mk_net(\x y. netord net x y /\ x IN s)`;;
2262 let in_direction = new_definition
2263 `a in_direction v = (at a) within {b | ?c. &0 <= c /\ (b - a = c % v)}`;;
2265 (* ------------------------------------------------------------------------- *)
2266 (* Prove that they are all nets. *)
2267 (* ------------------------------------------------------------------------- *)
2269 let NET_PROVE_TAC[def] =
2270 REWRITE_TAC[GSYM FUN_EQ_THM; def] THEN
2271 REWRITE_TAC[ETA_AX] THEN
2272 ASM_SIMP_TAC[GSYM(CONJUNCT2 net_tybij)];;
2276 netord(at a) x y <=> &0 < dist(x,a) /\ dist(x,a) <= dist(y,a)`,
2277 GEN_TAC THEN NET_PROVE_TAC[at] THEN
2278 MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS; REAL_LET_TRANS]);;
2280 let AT_INFINITY = prove
2281 (`!x y. netord at_infinity x y <=> norm(x) >= norm(y)`,
2282 NET_PROVE_TAC[at_infinity] THEN
2283 REWRITE_TAC[real_ge; REAL_LE_REFL] THEN
2284 MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS]);;
2286 let AT_POSINFINITY = prove
2287 (`!x y. netord at_posinfinity x y <=> x >= y`,
2288 NET_PROVE_TAC[at_posinfinity] THEN
2289 REWRITE_TAC[real_ge; REAL_LE_REFL] THEN
2290 MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS]);;
2292 let AT_NEGINFINITY = prove
2293 (`!x y. netord at_neginfinity x y <=> x <= y`,
2294 NET_PROVE_TAC[at_neginfinity] THEN
2295 REWRITE_TAC[real_ge; REAL_LE_REFL] THEN
2296 MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS]);;
2298 let SEQUENTIALLY = prove
2299 (`!m n. netord sequentially m n <=> m >= n`,
2300 NET_PROVE_TAC[sequentially] THEN REWRITE_TAC[GE; LE_REFL] THEN
2301 MESON_TAC[LE_CASES; LE_REFL; LE_TRANS]);;
2304 (`!n s x y. netord(n within s) x y <=> netord n x y /\ x IN s`,
2305 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[within; GSYM FUN_EQ_THM] THEN
2306 REWRITE_TAC[GSYM(CONJUNCT2 net_tybij); ETA_AX] THEN
2309 let IN_DIRECTION = prove
2310 (`!a v x y. netord(a in_direction v) x y <=>
2311 &0 < dist(x,a) /\ dist(x,a) <= dist(y,a) /\
2312 ?c. &0 <= c /\ (x - a = c % v)`,
2313 REWRITE_TAC[WITHIN; AT; in_direction; IN_ELIM_THM; CONJ_ACI]);;
2315 let WITHIN_UNIV = prove
2316 (`!x:real^N. at x within UNIV = at x`,
2317 REWRITE_TAC[within; at; IN_UNIV] THEN REWRITE_TAC[ETA_AX; net_tybij]);;
2319 let WITHIN_WITHIN = prove
2320 (`!net s t. (net within s) within t = net within (s INTER t)`,
2321 ONCE_REWRITE_TAC[within] THEN
2322 REWRITE_TAC[WITHIN; IN_INTER; GSYM CONJ_ASSOC]);;
2324 (* ------------------------------------------------------------------------- *)
2325 (* Identify trivial limits, where we can't approach arbitrarily closely. *)
2326 (* ------------------------------------------------------------------------- *)
2328 let trivial_limit = new_definition
2329 `trivial_limit net <=>
2331 ?a:A b. ~(a = b) /\ !x. ~(netord(net) x a) /\ ~(netord(net) x b)`;;
2333 let TRIVIAL_LIMIT_WITHIN = prove
2334 (`!a:real^N. trivial_limit (at a within s) <=> ~(a limit_point_of s)`,
2335 REWRITE_TAC[trivial_limit; LIMPT_APPROACHABLE_LE; WITHIN; AT; DIST_NZ] THEN
2336 REPEAT GEN_TAC THEN EQ_TAC THENL
2337 [DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL
2338 [MESON_TAC[REAL_LT_01; REAL_LT_REFL; VECTOR_CHOOSE_DIST;
2339 DIST_REFL; REAL_LT_IMP_LE];
2340 DISCH_THEN(X_CHOOSE_THEN `b:real^N` (X_CHOOSE_THEN `c:real^N`
2341 STRIP_ASSUME_TAC)) THEN
2342 SUBGOAL_THEN `&0 < dist(a,b:real^N) \/ &0 < dist(a,c:real^N)` MP_TAC THEN
2343 ASM_MESON_TAC[DIST_TRIANGLE; DIST_SYM; GSYM DIST_NZ; GSYM DIST_EQ_0;
2344 REAL_ARITH `x <= &0 + &0 ==> ~(&0 < x)`]];
2345 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN
2346 X_GEN_TAC `e:real` THEN DISCH_TAC THEN DISJ2_TAC THEN
2347 EXISTS_TAC `a:real^N` THEN
2348 SUBGOAL_THEN `?b:real^N. dist(a,b) = e` MP_TAC THENL
2349 [ASM_SIMP_TAC[VECTOR_CHOOSE_DIST; REAL_LT_IMP_LE]; ALL_TAC] THEN
2350 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN
2351 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
2352 ASM_MESON_TAC[REAL_NOT_LE; DIST_REFL; DIST_NZ; DIST_SYM]]);;
2354 let TRIVIAL_LIMIT_AT = prove
2355 (`!a. ~(trivial_limit (at a))`,
2356 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
2357 REWRITE_TAC[TRIVIAL_LIMIT_WITHIN; LIMPT_UNIV]);;
2359 let TRIVIAL_LIMIT_AT_INFINITY = prove
2360 (`~(trivial_limit at_infinity)`,
2361 REWRITE_TAC[trivial_limit; AT_INFINITY; real_ge] THEN
2362 MESON_TAC[REAL_LE_REFL; VECTOR_CHOOSE_SIZE; REAL_LT_01; REAL_LT_LE]);;
2364 let TRIVIAL_LIMIT_AT_POSINFINITY = prove
2365 (`~(trivial_limit at_posinfinity)`,
2366 REWRITE_TAC[trivial_limit; AT_POSINFINITY; DE_MORGAN_THM] THEN
2368 [DISCH_THEN(MP_TAC o SPECL [`&0`; `&1`]) THEN REAL_ARITH_TAC; ALL_TAC] THEN
2369 REWRITE_TAC[DE_MORGAN_THM; NOT_EXISTS_THM; real_ge; REAL_NOT_LE] THEN
2370 MESON_TAC[REAL_LT_TOTAL; REAL_LT_ANTISYM]);;
2372 let TRIVIAL_LIMIT_AT_NEGINFINITY = prove
2373 (`~(trivial_limit at_neginfinity)`,
2374 REWRITE_TAC[trivial_limit; AT_NEGINFINITY; DE_MORGAN_THM] THEN
2376 [DISCH_THEN(MP_TAC o SPECL [`&0`; `&1`]) THEN REAL_ARITH_TAC; ALL_TAC] THEN
2377 REWRITE_TAC[DE_MORGAN_THM; NOT_EXISTS_THM; real_ge; REAL_NOT_LE] THEN
2378 MESON_TAC[REAL_LT_TOTAL; REAL_LT_ANTISYM]);;
2380 let TRIVIAL_LIMIT_SEQUENTIALLY = prove
2381 (`~(trivial_limit sequentially)`,
2382 REWRITE_TAC[trivial_limit; SEQUENTIALLY] THEN
2383 MESON_TAC[GE_REFL; NOT_SUC]);;
2385 let LIM_WITHIN_CLOSED_TRIVIAL = prove
2386 (`!a s. closed s /\ ~(a IN s) ==> trivial_limit (at a within s)`,
2387 REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN MESON_TAC[CLOSED_LIMPT]);;
2389 let NONTRIVIAL_LIMIT_WITHIN = prove
2390 (`!net s. trivial_limit net ==> trivial_limit(net within s)`,
2391 REWRITE_TAC[trivial_limit; WITHIN] THEN MESON_TAC[]);;
2393 (* ------------------------------------------------------------------------- *)
2394 (* Some property holds "sufficiently close" to the limit point. *)
2395 (* ------------------------------------------------------------------------- *)
2397 let eventually = new_definition
2398 `eventually p net <=>
2399 trivial_limit net \/
2400 ?y. (?x. netord net x y) /\ (!x. netord net x y ==> p x)`;;
2402 let EVENTUALLY_HAPPENS = prove
2403 (`!net p. eventually p net ==> trivial_limit net \/ ?x. p x`,
2404 REWRITE_TAC[eventually] THEN MESON_TAC[]);;
2406 let EVENTUALLY_WITHIN_LE = prove
2408 eventually p (at a within s) <=>
2409 ?d. &0 < d /\ !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d ==> p(x)`,
2410 REWRITE_TAC[eventually; AT; WITHIN; TRIVIAL_LIMIT_WITHIN] THEN
2411 REWRITE_TAC[LIMPT_APPROACHABLE_LE; DIST_NZ] THEN
2412 REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[REAL_LTE_TRANS]; ALL_TAC] THEN
2413 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
2414 MATCH_MP_TAC(TAUT `(a ==> b) ==> ~a \/ b`) THEN DISCH_TAC THEN
2415 SUBGOAL_THEN `?b:real^M. dist(a,b) = d` MP_TAC THENL
2416 [ASM_SIMP_TAC[VECTOR_CHOOSE_DIST; REAL_LT_IMP_LE]; ALL_TAC] THEN
2417 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^M` THEN
2418 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
2419 ASM_MESON_TAC[REAL_NOT_LE; DIST_REFL; DIST_NZ; DIST_SYM]);;
2421 let EVENTUALLY_WITHIN = prove
2423 eventually p (at a within s) <=>
2424 ?d. &0 < d /\ !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d ==> p(x)`,
2425 REWRITE_TAC[EVENTUALLY_WITHIN_LE] THEN
2426 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] THEN
2427 REWRITE_TAC[APPROACHABLE_LT_LE]);;
2429 let EVENTUALLY_AT = prove
2430 (`!a p. eventually p (at a) <=>
2431 ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d ==> p(x)`,
2432 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
2433 REWRITE_TAC[EVENTUALLY_WITHIN; IN_UNIV]);;
2435 let EVENTUALLY_SEQUENTIALLY = prove
2436 (`!p. eventually p sequentially <=> ?N. !n. N <= n ==> p n`,
2437 REWRITE_TAC[eventually; SEQUENTIALLY; GE; LE_REFL;
2438 TRIVIAL_LIMIT_SEQUENTIALLY] THEN MESON_TAC[LE_REFL]);;
2440 let EVENTUALLY_AT_INFINITY = prove
2441 (`!p. eventually p at_infinity <=> ?b. !x. norm(x) >= b ==> p x`,
2442 REWRITE_TAC[eventually; AT_INFINITY; TRIVIAL_LIMIT_AT_INFINITY] THEN
2443 REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[REAL_LE_REFL]; ALL_TAC] THEN
2444 MESON_TAC[real_ge; REAL_LE_REFL; VECTOR_CHOOSE_SIZE;
2445 REAL_ARITH `&0 <= b \/ (!x. x >= &0 ==> x >= b)`]);;
2447 let EVENTUALLY_AT_POSINFINITY = prove
2448 (`!p. eventually p at_posinfinity <=> ?b. !x. x >= b ==> p x`,
2449 REWRITE_TAC[eventually; TRIVIAL_LIMIT_AT_POSINFINITY; AT_POSINFINITY] THEN
2450 MESON_TAC[REAL_ARITH `x >= x`]);;
2452 let EVENTUALLY_AT_NEGINFINITY = prove
2453 (`!p. eventually p at_neginfinity <=> ?b. !x. x <= b ==> p x`,
2454 REWRITE_TAC[eventually; TRIVIAL_LIMIT_AT_NEGINFINITY; AT_NEGINFINITY] THEN
2455 MESON_TAC[REAL_LE_REFL]);;
2457 let EVENTUALLY_AT_INFINITY_POS = prove
2459 eventually p at_infinity <=> ?b. &0 < b /\ !x. norm x >= b ==> p x`,
2460 GEN_TAC THEN REWRITE_TAC[EVENTUALLY_AT_INFINITY; real_ge] THEN
2461 MESON_TAC[REAL_ARITH `&0 < abs b + &1 /\ (abs b + &1 <= x ==> b <= x)`]);;
2463 let ALWAYS_EVENTUALLY = prove
2464 (`(!x. p x) ==> eventually p net`,
2465 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[eventually; trivial_limit] THEN
2468 (* ------------------------------------------------------------------------- *)
2469 (* Combining theorems for "eventually". *)
2470 (* ------------------------------------------------------------------------- *)
2472 let EVENTUALLY_AND = prove
2474 eventually (\x. p x /\ q x) net <=>
2475 eventually p net /\ eventually q net`,
2476 REPEAT GEN_TAC THEN REWRITE_TAC[eventually] THEN
2477 ASM_CASES_TAC `trivial_limit(net:(A net))` THEN ASM_REWRITE_TAC[] THEN
2478 EQ_TAC THEN SIMP_TAC[NET_DILEMMA] THEN MESON_TAC[]);;
2480 let EVENTUALLY_MONO = prove
2482 (!x. p x ==> q x) /\ eventually p net
2483 ==> eventually q net`,
2484 REWRITE_TAC[eventually] THEN MESON_TAC[]);;
2486 let EVENTUALLY_MP = prove
2488 eventually (\x. p x ==> q x) net /\ eventually p net
2489 ==> eventually q net`,
2490 REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
2491 REWRITE_TAC[eventually] THEN MESON_TAC[]);;
2493 let EVENTUALLY_FALSE = prove
2494 (`!net. eventually (\x. F) net <=> trivial_limit net`,
2495 REWRITE_TAC[eventually] THEN MESON_TAC[]);;
2497 let EVENTUALLY_TRUE = prove
2498 (`!net. eventually (\x. T) net <=> T`,
2499 REWRITE_TAC[eventually; trivial_limit] THEN MESON_TAC[]);;
2501 let NOT_EVENTUALLY = prove
2502 (`!net p. (!x. ~(p x)) /\ ~(trivial_limit net) ==> ~(eventually p net)`,
2503 REWRITE_TAC[eventually] THEN MESON_TAC[]);;
2505 let EVENTUALLY_FORALL = prove
2506 (`!net:(A net) p s:B->bool.
2507 FINITE s /\ ~(s = {})
2508 ==> (eventually (\x. !a. a IN s ==> p a x) net <=>
2509 !a. a IN s ==> eventually (p a) net)`,
2510 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
2511 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2512 REWRITE_TAC[FORALL_IN_INSERT; EVENTUALLY_AND; ETA_AX] THEN
2513 MAP_EVERY X_GEN_TAC [`b:B`; `t:B->bool`] THEN
2514 ASM_CASES_TAC `t:B->bool = {}` THEN
2515 ASM_SIMP_TAC[NOT_IN_EMPTY; EVENTUALLY_TRUE]);;
2517 let FORALL_EVENTUALLY = prove
2518 (`!net:(A net) p s:B->bool.
2519 FINITE s /\ ~(s = {})
2520 ==> ((!a. a IN s ==> eventually (p a) net) <=>
2521 eventually (\x. !a. a IN s ==> p a x) net)`,
2522 SIMP_TAC[EVENTUALLY_FORALL]);;
2524 (* ------------------------------------------------------------------------- *)
2525 (* Limits, defined as vacuously true when the limit is trivial. *)
2526 (* ------------------------------------------------------------------------- *)
2528 parse_as_infix("-->",(12,"right"));;
2530 let tendsto = new_definition
2531 `(f --> l) net <=> !e. &0 < e ==> eventually (\x. dist(f(x),l) < e) net`;;
2533 let lim = new_definition
2534 `lim net f = @l. (f --> l) net`;;
2538 trivial_limit net \/
2539 !e. &0 < e ==> ?y. (?x. netord(net) x y) /\
2540 !x. netord(net) x y ==> dist(f(x),l) < e`,
2541 REWRITE_TAC[tendsto; eventually] THEN MESON_TAC[]);;
2543 (* ------------------------------------------------------------------------- *)
2544 (* Show that they yield usual definitions in the various cases. *)
2545 (* ------------------------------------------------------------------------- *)
2547 let LIM_WITHIN_LE = prove
2548 (`!f:real^M->real^N l a s.
2549 (f --> l)(at a within s) <=>
2550 !e. &0 < e ==> ?d. &0 < d /\
2551 !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d
2552 ==> dist(f(x),l) < e`,
2553 REWRITE_TAC[tendsto; EVENTUALLY_WITHIN_LE]);;
2555 let LIM_WITHIN = prove
2556 (`!f:real^M->real^N l a s.
2557 (f --> l) (at a within s) <=>
2560 !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d
2561 ==> dist(f(x),l) < e`,
2562 REWRITE_TAC[tendsto; EVENTUALLY_WITHIN] THEN MESON_TAC[]);;
2564 let LIM_AT_LE = prove
2565 (`!f l a. (f --> l) (at a) <=>
2568 !x. &0 < dist(x,a) /\ dist(x,a) <= d
2569 ==> dist (f x,l) < e`,
2570 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
2571 REWRITE_TAC[LIM_WITHIN_LE; IN_UNIV]);;
2574 (`!f l:real^N a:real^M.
2575 (f --> l) (at a) <=>
2577 ==> ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d
2578 ==> dist(f(x),l) < e`,
2579 REWRITE_TAC[tendsto; EVENTUALLY_AT] THEN MESON_TAC[]);;
2581 let LIM_AT_INFINITY = prove
2582 (`!f l. (f --> l) at_infinity <=>
2583 !e. &0 < e ==> ?b. !x. norm(x) >= b ==> dist(f(x),l) < e`,
2584 REWRITE_TAC[tendsto; EVENTUALLY_AT_INFINITY] THEN MESON_TAC[]);;
2586 let LIM_AT_INFINITY_POS = prove
2587 (`!f l. (f --> l) at_infinity <=>
2588 !e. &0 < e ==> ?b. &0 < b /\ !x. norm x >= b ==> dist(f x,l) < e`,
2589 REPEAT GEN_TAC THEN REWRITE_TAC[LIM_AT_INFINITY] THEN
2590 MESON_TAC[REAL_ARITH `&0 < abs b + &1 /\ (x >= abs b + &1 ==> x >= b)`]);;
2592 let LIM_AT_POSINFINITY = prove
2593 (`!f l. (f --> l) at_posinfinity <=>
2594 !e. &0 < e ==> ?b. !x. x >= b ==> dist(f(x),l) < e`,
2595 REWRITE_TAC[tendsto; EVENTUALLY_AT_POSINFINITY] THEN MESON_TAC[]);;
2597 let LIM_AT_NEGINFINITY = prove
2598 (`!f l. (f --> l) at_neginfinity <=>
2599 !e. &0 < e ==> ?b. !x. x <= b ==> dist(f(x),l) < e`,
2600 REWRITE_TAC[tendsto; EVENTUALLY_AT_NEGINFINITY] THEN MESON_TAC[]);;
2602 let LIM_SEQUENTIALLY = prove
2603 (`!s l. (s --> l) sequentially <=>
2604 !e. &0 < e ==> ?N. !n. N <= n ==> dist(s(n),l) < e`,
2605 REWRITE_TAC[tendsto; EVENTUALLY_SEQUENTIALLY] THEN MESON_TAC[]);;
2607 let LIM_EVENTUALLY = prove
2608 (`!net f l. eventually (\x. f x = l) net ==> (f --> l) net`,
2609 REWRITE_TAC[eventually; LIM] THEN MESON_TAC[DIST_REFL]);;
2611 let LIM_POSINFINITY_SEQUENTIALLY = prove
2612 (`!f l. (f --> l) at_posinfinity ==> ((\n. f(&n)) --> l) sequentially`,
2614 REWRITE_TAC[LIM_AT_POSINFINITY; LIM_SEQUENTIALLY] THEN
2615 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2616 FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
2617 DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN
2618 MP_TAC(ISPEC `B:real` REAL_ARCH_SIMPLE) THEN
2619 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
2620 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
2621 RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN ASM_REAL_ARITH_TAC);;
2623 let LIM_INFINITY_POSINFINITY_LIFT = prove
2624 (`!f l:real^N. (f --> l) at_infinity ==> ((f o lift) --> l) at_posinfinity`,
2625 REWRITE_TAC[LIM_AT_INFINITY; LIM_AT_POSINFINITY; o_THM] THEN
2626 REWRITE_TAC[FORALL_DROP; NORM_REAL; GSYM drop; LIFT_DROP] THEN
2627 MESON_TAC[REAL_ARITH `x >= b ==> abs(x) >= b`]);;
2629 (* ------------------------------------------------------------------------- *)
2630 (* The expected monotonicity property. *)
2631 (* ------------------------------------------------------------------------- *)
2633 let LIM_WITHIN_EMPTY = prove
2634 (`!f l x. (f --> l) (at x within {})`,
2635 REWRITE_TAC[LIM_WITHIN; NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]);;
2637 let LIM_WITHIN_SUBSET = prove
2639 (f --> l) (at a within s) /\ t SUBSET s ==> (f --> l) (at a within t)`,
2640 REWRITE_TAC[LIM_WITHIN; SUBSET] THEN MESON_TAC[]);;
2642 let LIM_UNION = prove
2644 (f --> l) (at x within s) /\ (f --> l) (at x within t)
2645 ==> (f --> l) (at x within (s UNION t))`,
2646 REPEAT GEN_TAC THEN REWRITE_TAC[LIM_WITHIN; IN_UNION] THEN
2647 REWRITE_TAC[AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN
2648 X_GEN_TAC `e:real` THEN ASM_CASES_TAC `&0 < e` THEN ASM_SIMP_TAC[] THEN
2649 DISCH_THEN(CONJUNCTS_THEN2
2650 (X_CHOOSE_TAC `d1:real`) (X_CHOOSE_TAC `d2:real`)) THEN
2651 EXISTS_TAC `min d1 d2` THEN ASM_MESON_TAC[REAL_LT_MIN]);;
2653 let LIM_UNION_UNIV = prove
2655 (f --> l) (at x within s) /\ (f --> l) (at x within t) /\
2656 s UNION t = (:real^N)
2657 ==> (f --> l) (at x)`,
2658 MESON_TAC[LIM_UNION; WITHIN_UNIV]);;
2660 (* ------------------------------------------------------------------------- *)
2661 (* Composition of limits. *)
2662 (* ------------------------------------------------------------------------- *)
2664 let LIM_COMPOSE_WITHIN = prove
2665 (`!net f:A->real^N g:real^N->real^P s y z.
2667 eventually (\w. f w IN s /\ (f w = y ==> g y = z)) net /\
2668 (g --> z) (at y within s)
2669 ==> ((g o f) --> z) net`,
2670 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto; CONJ_ASSOC] THEN
2671 ONCE_REWRITE_TAC[LEFT_AND_FORALL_THM] THEN
2672 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2673 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2674 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
2675 REWRITE_TAC[EVENTUALLY_WITHIN; GSYM DIST_NZ; o_DEF] THEN
2676 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
2677 FIRST_X_ASSUM(MP_TAC o SPEC `d:real`) THEN
2678 ASM_REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
2679 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
2680 ASM_MESON_TAC[DIST_REFL]);;
2682 let LIM_COMPOSE_AT = prove
2683 (`!net f:A->real^N g:real^N->real^P y z.
2685 eventually (\w. f w = y ==> g y = z) net /\
2687 ==> ((g o f) --> z) net`,
2688 REPEAT STRIP_TAC THEN
2689 MP_TAC(ISPECL [`net:(A)net`; `f:A->real^N`; `g:real^N->real^P`;
2690 `(:real^N)`; `y:real^N`; `z:real^P`]
2691 LIM_COMPOSE_WITHIN) THEN
2692 ASM_REWRITE_TAC[IN_UNIV; WITHIN_UNIV]);;
2694 (* ------------------------------------------------------------------------- *)
2695 (* Interrelations between restricted and unrestricted limits. *)
2696 (* ------------------------------------------------------------------------- *)
2698 let LIM_AT_WITHIN = prove
2699 (`!f l a s. (f --> l)(at a) ==> (f --> l)(at a within s)`,
2700 REWRITE_TAC[LIM_AT; LIM_WITHIN] THEN MESON_TAC[]);;
2702 let LIM_WITHIN_OPEN = prove
2704 a IN s /\ open s ==> ((f --> l)(at a within s) <=> (f --> l)(at a))`,
2705 REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[LIM_AT_WITHIN] THEN
2706 REWRITE_TAC[LIM_AT; LIM_WITHIN] THEN
2707 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2708 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
2709 DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN
2710 FIRST_X_ASSUM(MP_TAC o SPEC `a:real^M` o GEN_REWRITE_RULE I [open_def]) THEN
2711 ASM_REWRITE_TAC[] THEN
2712 DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN
2713 MP_TAC(SPECL [`d1:real`; `d2:real`] REAL_DOWN2) THEN ASM_REWRITE_TAC[] THEN
2714 ASM_MESON_TAC[REAL_LT_TRANS]);;
2716 (* ------------------------------------------------------------------------- *)
2717 (* More limit point characterizations. *)
2718 (* ------------------------------------------------------------------------- *)
2720 let LIMPT_SEQUENTIAL_INJ = prove
2722 x limit_point_of s <=>
2723 ?f. (!n. f(n) IN (s DELETE x)) /\
2724 (!m n. f m = f n <=> m = n) /\
2725 (f --> x) sequentially`,
2727 REWRITE_TAC[LIMPT_APPROACHABLE; LIM_SEQUENTIALLY; IN_DELETE] THEN
2728 EQ_TAC THENL [ALL_TAC; MESON_TAC[GE; LE_REFL]] THEN
2729 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
2730 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
2731 X_GEN_TAC `y:real->real^N` THEN DISCH_TAC THEN
2732 (STRIP_ASSUME_TAC o prove_recursive_functions_exist num_RECURSION)
2734 (!n. z (SUC n):real^N = y(min (inv(&2 pow (SUC n))) (dist(z n,x))))` THEN
2735 EXISTS_TAC `z:num->real^N` THEN
2737 `!n. z(n) IN s /\ ~(z n:real^N = x) /\ dist(z n,x) < inv(&2 pow n)`
2739 [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
2740 ASM_SIMP_TAC[REAL_LT_01] THEN FIRST_X_ASSUM(MP_TAC o SPEC
2741 `min (inv(&2 pow (SUC n))) (dist(z n:real^N,x))`) THEN
2742 ASM_SIMP_TAC[REAL_LT_MIN; REAL_LT_INV_EQ; REAL_LT_POW2; DIST_POS_LT];
2743 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
2744 [MATCH_MP_TAC WLOG_LT THEN REWRITE_TAC[EQ_SYM_EQ] THEN
2745 SUBGOAL_THEN `!m n:num. m < n ==> dist(z n:real^N,x) < dist(z m,x)`
2746 (fun th -> MESON_TAC[th; REAL_LT_REFL; LT_REFL]) THEN
2747 MATCH_MP_TAC TRANSITIVE_STEPWISE_LT THEN
2748 CONJ_TAC THENL [REAL_ARITH_TAC; GEN_TAC THEN ASM_REWRITE_TAC[]] THEN
2749 FIRST_X_ASSUM(MP_TAC o SPEC
2750 `min (inv(&2 pow (SUC n))) (dist(z n:real^N,x))`) THEN
2751 ASM_SIMP_TAC[REAL_LT_MIN; REAL_LT_INV_EQ; REAL_LT_POW2; DIST_POS_LT];
2752 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2753 MP_TAC(ISPECL [`inv(&2)`; `e:real`] REAL_ARCH_POW_INV) THEN
2754 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN
2755 X_GEN_TAC `N:num` THEN REWRITE_TAC[REAL_POW_INV] THEN DISCH_TAC THEN
2756 X_GEN_TAC `n:num` THEN DISCH_TAC THEN
2757 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
2758 REAL_LT_TRANS)) THEN
2759 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `inv(&2 pow n)` THEN
2760 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
2761 ASM_REWRITE_TAC[REAL_LT_POW2] THEN MATCH_MP_TAC REAL_POW_MONO THEN
2762 REWRITE_TAC[REAL_OF_NUM_LE] THEN ASM_ARITH_TAC]]);;
2764 let LIMPT_SEQUENTIAL = prove
2766 x limit_point_of s <=>
2767 ?f. (!n. f(n) IN (s DELETE x)) /\ (f --> x) sequentially`,
2768 REPEAT GEN_TAC THEN EQ_TAC THENL
2769 [REWRITE_TAC[LIMPT_SEQUENTIAL_INJ] THEN MESON_TAC[];
2770 REWRITE_TAC[LIMPT_APPROACHABLE; LIM_SEQUENTIALLY; IN_DELETE] THEN
2771 MESON_TAC[GE; LE_REFL]]);;
2773 let [LIMPT_INFINITE_OPEN; LIMPT_INFINITE_BALL; LIMPT_INFINITE_CBALL] =
2776 x limit_point_of s <=> !t. x IN t /\ open t ==> INFINITE(s INTER t)) /\
2778 x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER ball(x,e))) /\
2780 x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER cball(x,e)))`,
2781 REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
2782 `(q ==> p) /\ (r ==> s) /\ (s ==> q) /\ (p ==> r)
2783 ==> (p <=> q) /\ (p <=> r) /\ (p <=> s)`) THEN
2784 REPEAT CONJ_TAC THENL
2785 [REWRITE_TAC[limit_point_of; INFINITE; SET_RULE
2786 `(?y. ~(y = x) /\ y IN s /\ y IN t) <=> ~(s INTER t SUBSET {x})`] THEN
2787 MESON_TAC[FINITE_SUBSET; FINITE_SING];
2788 MESON_TAC[INFINITE_SUPERSET; BALL_SUBSET_CBALL;
2789 SET_RULE `t SUBSET u ==> s INTER t SUBSET s INTER u`];
2790 MESON_TAC[INFINITE_SUPERSET; OPEN_CONTAINS_CBALL;
2791 SET_RULE `t SUBSET u ==> s INTER t SUBSET s INTER u`];
2792 REWRITE_TAC[LIMPT_SEQUENTIAL_INJ; IN_DELETE; FORALL_AND_THM] THEN
2793 DISCH_THEN(X_CHOOSE_THEN `f:num->real^N` STRIP_ASSUME_TAC) THEN
2794 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2795 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
2796 DISCH_THEN(MP_TAC o SPEC `e:real`) THEN
2797 ASM_REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[DIST_SYM] IN_BALL)] THEN
2798 DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
2799 MATCH_MP_TAC INFINITE_SUPERSET THEN
2800 EXISTS_TAC `IMAGE (f:num->real^N) (from N)` THEN
2801 ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_FROM; IN_INTER] THEN
2802 ASM_MESON_TAC[INFINITE_IMAGE_INJ; INFINITE_FROM]]);;
2804 let INFINITE_OPEN_IN = prove
2805 (`!u s:real^N->bool.
2806 open_in (subtopology euclidean u) s /\ (?x. x IN s /\ x limit_point_of u)
2808 REPEAT STRIP_TAC THEN
2809 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN
2810 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
2811 FIRST_X_ASSUM(MP_TAC o SPEC `t:real^N->bool` o
2812 GEN_REWRITE_RULE I [LIMPT_INFINITE_OPEN]) THEN
2813 FIRST_X_ASSUM SUBST_ALL_TAC THEN ASM SET_TAC[]);;
2815 (* ------------------------------------------------------------------------- *)
2816 (* Condensation points. *)
2817 (* ------------------------------------------------------------------------- *)
2819 parse_as_infix ("condensation_point_of",(12,"right"));;
2821 let condensation_point_of = new_definition
2822 `x condensation_point_of s <=>
2823 !t. x IN t /\ open t ==> ~COUNTABLE(s INTER t)`;;
2825 let CONDENSATION_POINT_OF_SUBSET = prove
2827 x condensation_point_of s /\ s SUBSET t ==> x condensation_point_of t`,
2829 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
2830 REWRITE_TAC[condensation_point_of] THEN
2831 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
2832 REWRITE_TAC[CONTRAPOS_THM] THEN
2833 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] COUNTABLE_SUBSET) THEN
2836 let CONDENSATION_POINT_IMP_LIMPT = prove
2837 (`!x s. x condensation_point_of s ==> x limit_point_of s`,
2838 REWRITE_TAC[condensation_point_of; LIMPT_INFINITE_OPEN; INFINITE] THEN
2839 MESON_TAC[FINITE_IMP_COUNTABLE]);;
2841 let CONDENSATION_POINT_INFINITE_BALL,CONDENSATION_POINT_INFINITE_CBALL =
2844 x condensation_point_of s <=>
2845 !e. &0 < e ==> ~COUNTABLE(s INTER ball(x,e))) /\
2847 x condensation_point_of s <=>
2848 !e. &0 < e ==> ~COUNTABLE(s INTER cball(x,e)))`,
2849 REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
2850 `(p ==> q) /\ (q ==> r) /\ (r ==> p)
2851 ==> (p <=> q) /\ (p <=> r)`) THEN
2852 REWRITE_TAC[condensation_point_of] THEN REPEAT CONJ_TAC THENL
2853 [MESON_TAC[OPEN_BALL; CENTRE_IN_BALL];
2854 MESON_TAC[BALL_SUBSET_CBALL; COUNTABLE_SUBSET;
2855 SET_RULE `t SUBSET u ==> s INTER t SUBSET s INTER u`];
2856 MESON_TAC[COUNTABLE_SUBSET; OPEN_CONTAINS_CBALL;
2857 SET_RULE `t SUBSET u ==> s INTER t SUBSET s INTER u`]]);;
2859 (* ------------------------------------------------------------------------- *)
2860 (* Basic arithmetical combining theorems for limits. *)
2861 (* ------------------------------------------------------------------------- *)
2863 let LIM_LINEAR = prove
2864 (`!net:(A)net h f l.
2865 (f --> l) net /\ linear h ==> ((\x. h(f x)) --> h l) net`,
2866 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
2867 ASM_CASES_TAC `trivial_limit (net:(A)net)` THEN ASM_REWRITE_TAC[] THEN
2868 STRIP_TAC THEN FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o
2869 MATCH_MP LINEAR_BOUNDED_POS) THEN
2870 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2871 FIRST_X_ASSUM(MP_TAC o SPEC `e / B`) THEN
2872 ASM_SIMP_TAC[REAL_LT_DIV; dist; GSYM LINEAR_SUB; REAL_LT_RDIV_EQ] THEN
2873 ASM_MESON_TAC[REAL_LET_TRANS; REAL_MUL_SYM]);;
2875 let LIM_CONST = prove
2876 (`!net a:real^N. ((\x. a) --> a) net`,
2877 SIMP_TAC[LIM; DIST_REFL; trivial_limit] THEN MESON_TAC[]);;
2879 let LIM_CMUL = prove
2880 (`!f l c. (f --> l) net ==> ((\x. c % f x) --> c % l) net`,
2881 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_LINEAR THEN
2882 ASM_REWRITE_TAC[REWRITE_RULE[ETA_AX]
2883 (MATCH_MP LINEAR_COMPOSE_CMUL LINEAR_ID)]);;
2885 let LIM_CMUL_EQ = prove
2887 ~(c = &0) ==> (((\x. c % f x) --> c % l) net <=> (f --> l) net)`,
2888 REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[LIM_CMUL] THEN
2889 DISCH_THEN(MP_TAC o SPEC `inv c:real` o MATCH_MP LIM_CMUL) THEN
2890 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID; ETA_AX]);;
2893 (`!net f l:real^N. (f --> l) net ==> ((\x. --(f x)) --> --l) net`,
2894 REPEAT GEN_TAC THEN REWRITE_TAC[LIM; dist] THEN
2895 REWRITE_TAC[VECTOR_ARITH `--x - --y = --(x - y:real^N)`; NORM_NEG]);;
2897 let LIM_NEG_EQ = prove
2898 (`!net f l:real^N. ((\x. --(f x)) --> --l) net <=> (f --> l) net`,
2899 REPEAT GEN_TAC THEN EQ_TAC THEN
2900 DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG) THEN
2901 REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);;
2904 (`!net:(A)net f g l m.
2905 (f --> l) net /\ (g --> m) net ==> ((\x. f(x) + g(x)) --> l + m) net`,
2906 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
2907 ASM_CASES_TAC `trivial_limit (net:(A)net)` THEN
2908 ASM_REWRITE_TAC[AND_FORALL_THM] THEN
2909 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2910 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
2911 DISCH_THEN(MP_TAC o MATCH_MP NET_DILEMMA) THEN MATCH_MP_TAC MONO_EXISTS THEN
2912 MESON_TAC[REAL_HALF; DIST_TRIANGLE_ADD; REAL_LT_ADD2; REAL_LET_TRANS]);;
2915 (`!net:(A)net f:A->real^N l.
2917 ==> ((\x. lambda i. (abs(f(x)$i))) --> (lambda i. abs(l$i)):real^N) net`,
2918 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
2919 ASM_CASES_TAC `trivial_limit (net:(A)net)` THEN ASM_REWRITE_TAC[] THEN
2920 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
2921 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
2922 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
2923 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
2924 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
2925 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
2926 MATCH_MP_TAC(NORM_ARITH
2927 `norm(x - y) <= norm(a - b) ==> dist(a,b) < e ==> dist(x,y) < e`) THEN
2928 MATCH_MP_TAC NORM_LE_COMPONENTWISE THEN
2929 SIMP_TAC[LAMBDA_BETA; VECTOR_SUB_COMPONENT] THEN
2933 (`!net:(A)net f g l m.
2934 (f --> l) net /\ (g --> m) net ==> ((\x. f(x) - g(x)) --> l - m) net`,
2935 REWRITE_TAC[real_sub; VECTOR_SUB] THEN ASM_SIMP_TAC[LIM_ADD; LIM_NEG]);;
2938 (`!net:(A)net f g l:real^N m:real^N.
2939 (f --> l) net /\ (g --> m) net
2940 ==> ((\x. lambda i. max (f(x)$i) (g(x)$i))
2941 --> (lambda i. max (l$i) (m$i)):real^N) net`,
2942 REPEAT GEN_TAC THEN DISCH_TAC THEN
2943 FIRST_ASSUM(MP_TAC o MATCH_MP LIM_ADD) THEN
2944 FIRST_ASSUM(MP_TAC o MATCH_MP LIM_SUB) THEN
2945 DISCH_THEN(MP_TAC o MATCH_MP LIM_ABS) THEN
2946 REWRITE_TAC[IMP_IMP] THEN
2947 DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN
2948 DISCH_THEN(MP_TAC o SPEC `inv(&2)` o MATCH_MP LIM_CMUL) THEN
2949 MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THEN
2950 SIMP_TAC[FUN_EQ_THM; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
2951 VECTOR_SUB_COMPONENT; LAMBDA_BETA] THEN
2955 (`!net:(A)net f g l:real^N m:real^N.
2956 (f --> l) net /\ (g --> m) net
2957 ==> ((\x. lambda i. min (f(x)$i) (g(x)$i))
2958 --> (lambda i. min (l$i) (m$i)):real^N) net`,
2960 DISCH_THEN(CONJUNCTS_THEN(MP_TAC o MATCH_MP LIM_NEG)) THEN
2961 REWRITE_TAC[IMP_IMP] THEN
2962 DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG o MATCH_MP LIM_MAX) THEN
2963 MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THEN
2964 SIMP_TAC[FUN_EQ_THM; CART_EQ; LAMBDA_BETA; VECTOR_NEG_COMPONENT] THEN
2967 let LIM_NORM = prove
2968 (`!net f:A->real^N l.
2969 (f --> l) net ==> ((\x. lift(norm(f x))) --> lift(norm l)) net`,
2970 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto; DIST_LIFT] THEN
2971 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
2973 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
2974 REWRITE_TAC[] THEN NORM_ARITH_TAC);;
2976 let LIM_NULL = prove
2977 (`!net f l. (f --> l) net <=> ((\x. f(x) - l) --> vec 0) net`,
2978 REWRITE_TAC[LIM; dist; VECTOR_SUB_RZERO]);;
2980 let LIM_NULL_NORM = prove
2981 (`!net f. (f --> vec 0) net <=> ((\x. lift(norm(f x))) --> vec 0) net`,
2982 REWRITE_TAC[LIM; dist; VECTOR_SUB_RZERO; REAL_ABS_NORM; NORM_LIFT]);;
2984 let LIM_NULL_CMUL_EQ = prove
2986 ~(c = &0) ==> (((\x. c % f x) --> vec 0) net <=> (f --> vec 0) net)`,
2987 MESON_TAC[LIM_CMUL_EQ; VECTOR_MUL_RZERO]);;
2989 let LIM_NULL_CMUL = prove
2990 (`!net f c. (f --> vec 0) net ==> ((\x. c % f x) --> vec 0) net`,
2991 REPEAT GEN_TAC THEN ASM_CASES_TAC `c = &0` THEN
2992 ASM_SIMP_TAC[LIM_NULL_CMUL_EQ; VECTOR_MUL_LZERO; LIM_CONST]);;
2994 let LIM_NULL_ADD = prove
2995 (`!net f g:A->real^N.
2996 (f --> vec 0) net /\ (g --> vec 0) net
2997 ==> ((\x. f x + g x) --> vec 0) net`,
2999 DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN
3000 REWRITE_TAC[VECTOR_ADD_LID]);;
3002 let LIM_NULL_SUB = prove
3003 (`!net f g:A->real^N.
3004 (f --> vec 0) net /\ (g --> vec 0) net
3005 ==> ((\x. f x - g x) --> vec 0) net`,
3007 DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN
3008 REWRITE_TAC[VECTOR_SUB_RZERO]);;
3010 let LIM_NULL_COMPARISON = prove
3011 (`!net f g. eventually (\x. norm(f x) <= g x) net /\
3012 ((\x. lift(g x)) --> vec 0) net
3013 ==> (f --> vec 0) net`,
3014 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto; RIGHT_AND_FORALL_THM] THEN
3015 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
3016 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
3017 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
3018 REWRITE_TAC[dist; VECTOR_SUB_RZERO; NORM_LIFT] THEN REAL_ARITH_TAC);;
3020 let LIM_COMPONENT = prove
3021 (`!net f i l:real^N. (f --> l) net /\ 1 <= i /\ i <= dimindex(:N)
3022 ==> ((\a. lift(f(a)$i)) --> lift(l$i)) net`,
3023 REWRITE_TAC[LIM; dist; GSYM LIFT_SUB; NORM_LIFT] THEN
3024 SIMP_TAC[GSYM VECTOR_SUB_COMPONENT] THEN
3025 MESON_TAC[COMPONENT_LE_NORM; REAL_LET_TRANS]);;
3027 let LIM_TRANSFORM_BOUND = prove
3028 (`!f g. eventually (\n. norm(f n) <= norm(g n)) net /\ (g --> vec 0) net
3029 ==> (f --> vec 0) net`,
3031 REWRITE_TAC[tendsto; RIGHT_AND_FORALL_THM] THEN
3032 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
3033 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
3034 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
3035 REWRITE_TAC[dist; VECTOR_SUB_RZERO] THEN REAL_ARITH_TAC);;
3037 let LIM_NULL_CMUL_BOUNDED = prove
3039 eventually (\a. g a = vec 0 \/ abs(f a) <= B) net /\
3041 ==> ((\n. f n % g n) --> vec 0) net`,
3042 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto] THEN STRIP_TAC THEN
3043 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3044 FIRST_X_ASSUM(MP_TAC o SPEC `e / (abs B + &1)`) THEN
3045 ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < abs x + &1`] THEN
3046 UNDISCH_TAC `eventually (\a. g a:real^N = vec 0 \/ abs(f a) <= B)
3048 REWRITE_TAC[IMP_IMP; GSYM EVENTUALLY_AND] THEN
3049 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MP) THEN
3050 REWRITE_TAC[dist; VECTOR_SUB_RZERO; o_THM; NORM_LIFT; NORM_MUL] THEN
3051 MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `x:A` THEN REWRITE_TAC[] THEN
3052 ASM_CASES_TAC `(g:A->real^N) x = vec 0` THEN
3053 ASM_REWRITE_TAC[NORM_0; REAL_MUL_RZERO] THEN
3054 STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
3055 EXISTS_TAC `B * e / (abs B + &1)` THEN
3056 ASM_SIMP_TAC[REAL_LE_MUL2; REAL_ABS_POS; NORM_POS_LE; REAL_LT_IMP_LE] THEN
3057 REWRITE_TAC[REAL_ARITH `c * (a / b) = (c * a) / b`] THEN
3058 SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 < abs x + &1`] THEN
3059 MATCH_MP_TAC(REAL_ARITH
3060 `e * B <= e * abs B /\ &0 < e ==> B * e < e * (abs B + &1)`) THEN
3061 ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN REAL_ARITH_TAC);;
3063 let LIM_NULL_VMUL_BOUNDED = prove
3065 ((lift o f) --> vec 0) net /\
3066 eventually (\a. f a = &0 \/ norm(g a) <= B) net
3067 ==> ((\n. f n % g n) --> vec 0) net`,
3068 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto] THEN STRIP_TAC THEN
3069 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3070 FIRST_X_ASSUM(MP_TAC o SPEC `e / (abs B + &1)`) THEN
3071 ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < abs x + &1`] THEN
3072 UNDISCH_TAC `eventually(\a. f a = &0 \/ norm((g:A->real^N) a) <= B) net` THEN
3073 REWRITE_TAC[IMP_IMP; GSYM EVENTUALLY_AND] THEN
3074 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MP) THEN
3075 REWRITE_TAC[dist; VECTOR_SUB_RZERO; o_THM; NORM_LIFT; NORM_MUL] THEN
3076 MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `x:A` THEN REWRITE_TAC[] THEN
3077 ASM_CASES_TAC `(f:A->real) x = &0` THEN
3078 ASM_REWRITE_TAC[REAL_ABS_NUM; REAL_MUL_LZERO] THEN
3079 STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
3080 EXISTS_TAC `e / (abs B + &1) * B` THEN
3081 ASM_SIMP_TAC[REAL_LE_MUL2; REAL_ABS_POS; NORM_POS_LE; REAL_LT_IMP_LE] THEN
3082 REWRITE_TAC[REAL_ARITH `(a / b) * c = (a * c) / b`] THEN
3083 SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 < abs x + &1`] THEN
3084 MATCH_MP_TAC(REAL_ARITH
3085 `e * B <= e * abs B /\ &0 < e ==> e * B < e * (abs B + &1)`) THEN
3086 ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN REAL_ARITH_TAC);;
3088 let LIM_VSUM = prove
3089 (`!net f:A->B->real^N l s.
3090 FINITE s /\ (!i. i IN s ==> ((f i) --> (l i)) net)
3091 ==> ((\x. vsum s (\i. f i x)) --> vsum s l) net`,
3092 REPLICATE_TAC 3 GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
3093 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3094 SIMP_TAC[VSUM_CLAUSES; LIM_CONST; LIM_ADD; IN_INSERT; ETA_AX]);;
3096 (* ------------------------------------------------------------------------- *)
3097 (* Deducing things about the limit from the elements. *)
3098 (* ------------------------------------------------------------------------- *)
3100 let LIM_IN_CLOSED_SET = prove
3101 (`!net f:A->real^N s l.
3102 closed s /\ eventually (\x. f(x) IN s) net /\
3103 ~(trivial_limit net) /\ (f --> l) net
3105 REWRITE_TAC[closed] THEN REPEAT STRIP_TAC THEN
3106 MATCH_MP_TAC(SET_RULE `~(x IN (UNIV DIFF s)) ==> x IN s`) THEN
3108 FIRST_ASSUM(MP_TAC o SPEC `l:real^N` o GEN_REWRITE_RULE I
3109 [OPEN_CONTAINS_BALL]) THEN
3110 ASM_REWRITE_TAC[SUBSET; IN_BALL; IN_DIFF; IN_UNION] THEN
3111 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
3112 FIRST_X_ASSUM(MP_TAC o SPEC `e:real` o GEN_REWRITE_RULE I [tendsto]) THEN
3113 UNDISCH_TAC `eventually (\x. (f:A->real^N) x IN s) net` THEN
3114 ASM_REWRITE_TAC[GSYM EVENTUALLY_AND; TAUT `a ==> ~b <=> ~(a /\ b)`] THEN
3115 MATCH_MP_TAC NOT_EVENTUALLY THEN ASM_MESON_TAC[DIST_SYM]);;
3117 (* ------------------------------------------------------------------------- *)
3118 (* Need to prove closed(cball(x,e)) before deducing this as a corollary. *)
3119 (* ------------------------------------------------------------------------- *)
3121 let LIM_NORM_UBOUND = prove
3122 (`!net:(A)net f (l:real^N) b.
3123 ~(trivial_limit net) /\
3125 eventually (\x. norm(f x) <= b) net
3127 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3128 ASM_REWRITE_TAC[LIM] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3129 ASM_REWRITE_TAC[eventually] THEN
3130 STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
3131 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN
3133 `?x:A. dist(f(x):real^N,l) < norm(l:real^N) - b /\ norm(f x) <= b`
3134 (CHOOSE_THEN MP_TAC) THENL [ASM_MESON_TAC[NET]; ALL_TAC] THEN
3135 REWRITE_TAC[REAL_NOT_LT; REAL_LE_SUB_RADD; DE_MORGAN_THM; dist] THEN
3138 let LIM_NORM_LBOUND = prove
3139 (`!net:(A)net f (l:real^N) b.
3140 ~(trivial_limit net) /\ (f --> l) net /\
3141 eventually (\x. b <= norm(f x)) net
3143 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3144 ASM_REWRITE_TAC[LIM] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3145 ASM_REWRITE_TAC[eventually] THEN
3146 STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
3147 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN
3149 `?x:A. dist(f(x):real^N,l) < b - norm(l:real^N) /\ b <= norm(f x)`
3150 (CHOOSE_THEN MP_TAC) THENL [ASM_MESON_TAC[NET]; ALL_TAC] THEN
3151 REWRITE_TAC[REAL_NOT_LT; REAL_LE_SUB_RADD; DE_MORGAN_THM; dist] THEN
3154 (* ------------------------------------------------------------------------- *)
3155 (* Uniqueness of the limit, when nontrivial. *)
3156 (* ------------------------------------------------------------------------- *)
3158 let LIM_UNIQUE = prove
3159 (`!net:(A)net f l:real^N l'.
3160 ~(trivial_limit net) /\ (f --> l) net /\ (f --> l') net ==> (l = l')`,
3161 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3162 DISCH_THEN(ASSUME_TAC o REWRITE_RULE[VECTOR_SUB_REFL] o MATCH_MP LIM_SUB) THEN
3163 SUBGOAL_THEN `!e. &0 < e ==> norm(l:real^N - l') <= e` MP_TAC THENL
3164 [GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC LIM_NORM_UBOUND THEN
3165 MAP_EVERY EXISTS_TAC [`net:(A)net`; `\x:A. vec 0 : real^N`] THEN
3166 ASM_SIMP_TAC[NORM_0; REAL_LT_IMP_LE; eventually] THEN
3167 ASM_MESON_TAC[trivial_limit];
3168 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[DIST_NZ; dist] THEN
3169 DISCH_TAC THEN DISCH_THEN(MP_TAC o SPEC `norm(l - l':real^N) / &2`) THEN
3170 ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_LE_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
3171 UNDISCH_TAC `&0 < norm(l - l':real^N)` THEN REAL_ARITH_TAC]);;
3173 let TENDSTO_LIM = prove
3174 (`!net f l. ~(trivial_limit net) /\ (f --> l) net ==> lim net f = l`,
3175 REWRITE_TAC[lim] THEN MESON_TAC[LIM_UNIQUE]);;
3177 let LIM_CONST_EQ = prove
3178 (`!net:(A net) c d:real^N.
3179 ((\x. c) --> d) net <=> trivial_limit net \/ c = d`,
3181 ASM_CASES_TAC `trivial_limit (net:A net)` THEN ASM_REWRITE_TAC[] THENL
3182 [ASM_REWRITE_TAC[LIM]; ALL_TAC] THEN
3183 EQ_TAC THEN SIMP_TAC[LIM_CONST] THEN DISCH_TAC THEN
3184 MATCH_MP_TAC(SPEC `net:A net` LIM_UNIQUE) THEN
3185 EXISTS_TAC `(\x. c):A->real^N` THEN ASM_REWRITE_TAC[LIM_CONST]);;
3187 (* ------------------------------------------------------------------------- *)
3188 (* Some unwieldy but occasionally useful theorems about uniform limits. *)
3189 (* ------------------------------------------------------------------------- *)
3191 let UNIFORM_LIM_ADD = prove
3192 (`!net:(A)net P f g l m.
3194 ==> eventually (\x. !n:B. P n ==> norm(f n x - l n) < e) net) /\
3196 ==> eventually (\x. !n. P n ==> norm(g n x - m n) < e) net)
3200 ==> norm((f n x + g n x) - (l n + m n)) < e)
3202 REPEAT GEN_TAC THEN REWRITE_TAC[AND_FORALL_THM] THEN DISCH_TAC THEN
3203 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3204 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
3205 ASM_REWRITE_TAC[REAL_HALF; GSYM EVENTUALLY_AND] THEN
3206 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
3207 GEN_TAC THEN REWRITE_TAC[AND_FORALL_THM] THEN
3208 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:B` THEN
3209 ASM_CASES_TAC `(P:B->bool) n` THEN ASM_REWRITE_TAC[] THEN
3210 CONV_TAC NORM_ARITH);;
3212 let UNIFORM_LIM_SUB = prove
3213 (`!net:(A)net P f g l m.
3215 ==> eventually (\x. !n:B. P n ==> norm(f n x - l n) < e) net) /\
3217 ==> eventually (\x. !n. P n ==> norm(g n x - m n) < e) net)
3221 ==> norm((f n x - g n x) - (l n - m n)) < e)
3223 REPEAT GEN_TAC THEN REWRITE_TAC[AND_FORALL_THM] THEN DISCH_TAC THEN
3224 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3225 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
3226 ASM_REWRITE_TAC[REAL_HALF; GSYM EVENTUALLY_AND] THEN
3227 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
3228 GEN_TAC THEN REWRITE_TAC[AND_FORALL_THM] THEN
3229 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:B` THEN
3230 ASM_CASES_TAC `(P:B->bool) n` THEN ASM_REWRITE_TAC[] THEN
3231 CONV_TAC NORM_ARITH);;
3233 (* ------------------------------------------------------------------------- *)
3234 (* Limit under bilinear function, uniform version first. *)
3235 (* ------------------------------------------------------------------------- *)
3237 let UNIFORM_LIM_BILINEAR = prove
3238 (`!net:(A)net P (h:real^M->real^N->real^P) f g l m b1 b2.
3240 eventually (\x. !n. P n ==> norm(l n) <= b1) net /\
3241 eventually (\x. !n. P n ==> norm(m n) <= b2) net /\
3243 ==> eventually (\x. !n:B. P n ==> norm(f n x - l n) < e) net) /\
3245 ==> eventually (\x. !n. P n ==> norm(g n x - m n) < e) net)
3249 ==> norm(h (f n x) (g n x) - h (l n) (m n)) < e)
3252 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3253 FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o MATCH_MP
3254 BILINEAR_BOUNDED_POS) THEN
3255 REWRITE_TAC[AND_FORALL_THM; RIGHT_AND_FORALL_THM] THEN DISCH_TAC THEN
3256 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3257 FIRST_X_ASSUM(MP_TAC o SPEC
3258 `min (abs b2 + &1) (e / &2 / (B * (abs b1 + abs b2 + &2)))`) THEN
3259 ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; REAL_LT_MUL; REAL_LT_MIN;
3260 REAL_ARITH `&0 < abs x + &1`;
3261 REAL_ARITH `&0 < abs x + abs y + &2`] THEN
3262 REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
3263 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
3264 X_GEN_TAC `x:A` THEN REWRITE_TAC[AND_FORALL_THM] THEN
3265 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:B` THEN
3266 ASM_CASES_TAC `(P:B->bool) n` THEN ASM_REWRITE_TAC[] THEN
3268 ONCE_REWRITE_TAC[VECTOR_ARITH
3269 `h a b - h c d :real^N = (h a b - h a d) + (h a d - h c d)`] THEN
3270 ASM_SIMP_TAC[GSYM BILINEAR_LSUB; GSYM BILINEAR_RSUB] THEN
3271 MATCH_MP_TAC NORM_TRIANGLE_LT THEN
3272 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
3273 (MESON[REAL_LE_ADD2; REAL_LET_TRANS]
3274 `(!x y. norm(h x y:real^P) <= B * norm x * norm y)
3275 ==> B * norm a * norm b + B * norm c * norm d < e
3276 ==> norm(h a b) + norm(h c d) < e`)) THEN
3277 MATCH_MP_TAC(REAL_ARITH
3278 `x * B < e / &2 /\ y * B < e / &2 ==> B * x + B * y < e`) THEN
3279 CONJ_TAC THEN ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THENL
3280 [ONCE_REWRITE_TAC[REAL_MUL_SYM]; ALL_TAC] THEN
3281 MATCH_MP_TAC REAL_LET_TRANS THEN
3282 EXISTS_TAC `e / &2 / (B * (abs b1 + abs b2 + &2)) *
3283 (abs b1 + abs b2 + &1)` THEN
3285 [MATCH_MP_TAC REAL_LE_MUL2 THEN
3286 ASM_SIMP_TAC[NORM_POS_LE; REAL_LT_IMP_LE] THEN
3287 ASM_SIMP_TAC[REAL_ARITH `a <= b2 ==> a <= abs b1 + abs b2 + &1`] THEN
3288 ASM_MESON_TAC[NORM_ARITH
3289 `norm(f - l:real^P) < abs b2 + &1 /\ norm(l) <= b1
3290 ==> norm(f) <= abs b1 + abs b2 + &1`];
3291 ONCE_REWRITE_TAC[real_div] THEN
3292 ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_HALF; GSYM REAL_MUL_ASSOC;
3294 REWRITE_TAC[REAL_ARITH `B * inv x * y < B <=> B * y / x < B * &1`] THEN
3295 ASM_SIMP_TAC[REAL_LT_INV_EQ; REAL_LT_LMUL_EQ; REAL_LT_LDIV_EQ;
3296 REAL_ARITH `&0 < abs x + abs y + &2`] THEN
3299 let LIM_BILINEAR = prove
3300 (`!net:(A)net (h:real^M->real^N->real^P) f g l m.
3301 (f --> l) net /\ (g --> m) net /\ bilinear h
3302 ==> ((\x. h (f x) (g x)) --> (h l m)) net`,
3303 REPEAT STRIP_TAC THEN
3305 [`net:(A)net`; `\x:one. T`; `h:real^M->real^N->real^P`;
3306 `\n:one. (f:A->real^M)`; `\n:one. (g:A->real^N)`;
3307 `\n:one. (l:real^M)`; `\n:one. (m:real^N)`;
3308 `norm(l:real^M)`; `norm(m:real^N)`]
3309 UNIFORM_LIM_BILINEAR) THEN
3310 ASM_REWRITE_TAC[REAL_LE_REFL; EVENTUALLY_TRUE] THEN
3311 ASM_REWRITE_TAC[GSYM dist; GSYM tendsto]);;
3313 (* ------------------------------------------------------------------------- *)
3314 (* These are special for limits out of the same vector space. *)
3315 (* ------------------------------------------------------------------------- *)
3317 let LIM_WITHIN_ID = prove
3318 (`!a s. ((\x. x) --> a) (at a within s)`,
3319 REWRITE_TAC[LIM_WITHIN] THEN MESON_TAC[]);;
3321 let LIM_AT_ID = prove
3322 (`!a. ((\x. x) --> a) (at a)`,
3323 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN REWRITE_TAC[LIM_WITHIN_ID]);;
3325 let LIM_AT_ZERO = prove
3326 (`!f:real^M->real^N l a.
3327 (f --> l) (at a) <=> ((\x. f(a + x)) --> l) (at(vec 0))`,
3328 REPEAT GEN_TAC THEN REWRITE_TAC[LIM_AT] THEN
3329 AP_TERM_TAC THEN ABS_TAC THEN
3330 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
3331 AP_TERM_TAC THEN ABS_TAC THEN
3332 ASM_CASES_TAC `&0 < d` THEN ASM_REWRITE_TAC[] THEN
3333 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `x:real^M` THENL
3334 [FIRST_X_ASSUM(MP_TAC o SPEC `a + x:real^M`) THEN
3335 REWRITE_TAC[dist; VECTOR_ADD_SUB; VECTOR_SUB_RZERO];
3336 FIRST_X_ASSUM(MP_TAC o SPEC `x - a:real^M`) THEN
3337 REWRITE_TAC[dist; VECTOR_SUB_RZERO; VECTOR_SUB_ADD2]]);;
3339 (* ------------------------------------------------------------------------- *)
3340 (* It's also sometimes useful to extract the limit point from the net. *)
3341 (* ------------------------------------------------------------------------- *)
3343 let netlimit = new_definition
3344 `netlimit net = @a. !x. ~(netord net x a)`;;
3346 let NETLIMIT_WITHIN = prove
3347 (`!a:real^N s. ~(trivial_limit (at a within s))
3348 ==> (netlimit (at a within s) = a)`,
3349 REWRITE_TAC[trivial_limit; netlimit; AT; WITHIN; DE_MORGAN_THM] THEN
3350 REPEAT STRIP_TAC THEN MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN
3352 `!x:real^N. ~(&0 < dist(x,a) /\ dist(x,a) <= dist(a,a) /\ x IN s)`
3354 [ASM_MESON_TAC[DIST_REFL; REAL_NOT_LT]; ASM_MESON_TAC[]]);;
3356 let NETLIMIT_AT = prove
3357 (`!a. netlimit(at a) = a`,
3358 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
3359 MATCH_MP_TAC NETLIMIT_WITHIN THEN
3360 SIMP_TAC[TRIVIAL_LIMIT_AT; WITHIN_UNIV]);;
3362 (* ------------------------------------------------------------------------- *)
3363 (* Transformation of limit. *)
3364 (* ------------------------------------------------------------------------- *)
3366 let LIM_TRANSFORM = prove
3368 ((\x. f x - g x) --> vec 0) net /\ (f --> l) net ==> (g --> l) net`,
3369 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN
3370 DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG) THEN MATCH_MP_TAC EQ_IMP THEN
3371 AP_THM_TAC THEN BINOP_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN
3374 let LIM_TRANSFORM_EVENTUALLY = prove
3376 eventually (\x. f x = g x) net /\ (f --> l) net ==> (g --> l) net`,
3377 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
3378 DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o MATCH_MP LIM_EVENTUALLY) MP_TAC) THEN
3379 MESON_TAC[LIM_TRANSFORM]);;
3381 let LIM_TRANSFORM_WITHIN = prove
3384 (!x'. x' IN s /\ &0 < dist(x',x) /\ dist(x',x) < d ==> f(x') = g(x')) /\
3385 (f --> l) (at x within s)
3386 ==> (g --> l) (at x within s)`,
3387 REPEAT GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
3388 DISCH_TAC THEN DISCH_TAC THEN
3389 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM) THEN
3390 REWRITE_TAC[LIM_WITHIN] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `d:real` THEN
3391 ASM_SIMP_TAC[VECTOR_SUB_REFL; DIST_REFL]);;
3393 let LIM_TRANSFORM_AT = prove
3396 (!x'. &0 < dist(x',x) /\ dist(x',x) < d ==> f(x') = g(x')) /\
3398 ==> (g --> l) (at x)`,
3399 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN MESON_TAC[LIM_TRANSFORM_WITHIN]);;
3401 let LIM_TRANSFORM_EQ = prove
3402 (`!net f:A->real^N g l.
3403 ((\x. f x - g x) --> vec 0) net ==> ((f --> l) net <=> (g --> l) net)`,
3404 REPEAT STRIP_TAC THEN EQ_TAC THEN
3405 DISCH_TAC THEN MATCH_MP_TAC LIM_TRANSFORM THENL
3406 [EXISTS_TAC `f:A->real^N` THEN ASM_REWRITE_TAC[];
3407 EXISTS_TAC `g:A->real^N` THEN ASM_REWRITE_TAC[] THEN
3408 ONCE_REWRITE_TAC[GSYM LIM_NEG_EQ] THEN
3409 ASM_REWRITE_TAC[VECTOR_NEG_SUB; VECTOR_NEG_0]]);;
3411 let LIM_TRANSFORM_WITHIN_SET = prove
3413 eventually (\x. x IN s <=> x IN t) (at a)
3414 ==> ((f --> l) (at a within s) <=> (f --> l) (at a within t))`,
3415 REPEAT GEN_TAC THEN REWRITE_TAC[EVENTUALLY_AT; LIM_WITHIN] THEN
3416 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
3417 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3418 FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
3419 DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
3420 EXISTS_TAC `min d k:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
3423 (* ------------------------------------------------------------------------- *)
3424 (* Common case assuming being away from some crucial point like 0. *)
3425 (* ------------------------------------------------------------------------- *)
3427 let LIM_TRANSFORM_AWAY_WITHIN = prove
3428 (`!f:real^M->real^N g a b s.
3430 (!x. x IN s /\ ~(x = a) /\ ~(x = b) ==> f(x) = g(x)) /\
3431 (f --> l) (at a within s)
3432 ==> (g --> l) (at a within s)`,
3433 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN
3434 MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `dist(a:real^M,b)`] THEN
3435 ASM_REWRITE_TAC[GSYM DIST_NZ] THEN X_GEN_TAC `y:real^M` THEN
3436 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
3437 ASM_MESON_TAC[DIST_SYM; REAL_LT_REFL]);;
3439 let LIM_TRANSFORM_AWAY_AT = prove
3440 (`!f:real^M->real^N g a b.
3442 (!x. ~(x = a) /\ ~(x = b) ==> f(x) = g(x)) /\
3444 ==> (g --> l) (at a)`,
3445 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
3446 MESON_TAC[LIM_TRANSFORM_AWAY_WITHIN]);;
3448 (* ------------------------------------------------------------------------- *)
3449 (* Alternatively, within an open set. *)
3450 (* ------------------------------------------------------------------------- *)
3452 let LIM_TRANSFORM_WITHIN_OPEN = prove
3453 (`!f g:real^M->real^N s a l.
3455 (!x. x IN s /\ ~(x = a) ==> f x = g x) /\
3457 ==> (g --> l) (at a)`,
3458 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_AT THEN
3459 EXISTS_TAC `f:real^M->real^N` THEN ASM_REWRITE_TAC[] THEN
3460 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN
3461 DISCH_THEN(MP_TAC o SPEC `a:real^M`) THEN ASM_REWRITE_TAC[] THEN
3462 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[SUBSET; IN_BALL] THEN
3463 ASM_MESON_TAC[DIST_NZ; DIST_SYM]);;
3465 let LIM_TRANSFORM_WITHIN_OPEN_IN = prove
3466 (`!f g:real^M->real^N s t a l.
3467 open_in (subtopology euclidean t) s /\ a IN s /\
3468 (!x. x IN s /\ ~(x = a) ==> f x = g x) /\
3469 (f --> l) (at a within t)
3470 ==> (g --> l) (at a within t)`,
3471 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN
3472 EXISTS_TAC `f:real^M->real^N` THEN ASM_REWRITE_TAC[] THEN
3473 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_CONTAINS_BALL]) THEN
3474 DISCH_THEN(MP_TAC o SPEC `a:real^M` o CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN
3475 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[SUBSET; IN_INTER; IN_BALL] THEN
3476 ASM_MESON_TAC[DIST_NZ; DIST_SYM]);;
3478 (* ------------------------------------------------------------------------- *)
3479 (* Another quite common idiom of an explicit conditional in a sequence. *)
3480 (* ------------------------------------------------------------------------- *)
3482 let LIM_CASES_FINITE_SEQUENTIALLY = prove
3483 (`!f g l. FINITE {n | P n}
3484 ==> (((\n. if P n then f n else g n) --> l) sequentially <=>
3485 (g --> l) sequentially)`,
3486 REPEAT STRIP_TAC THEN EQ_TAC THEN
3487 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN
3488 FIRST_ASSUM(MP_TAC o SPEC `\n:num. n` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN
3489 REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
3490 X_GEN_TAC `N:num` THEN DISCH_TAC THEN SIMP_TAC[EVENTUALLY_SEQUENTIALLY] THEN
3491 EXISTS_TAC `N + 1` THEN
3492 ASM_MESON_TAC[ARITH_RULE `~(x <= n /\ n + 1 <= x)`]);;
3494 let LIM_CASES_COFINITE_SEQUENTIALLY = prove
3495 (`!f g l. FINITE {n | ~P n}
3496 ==> (((\n. if P n then f n else g n) --> l) sequentially <=>
3497 (f --> l) sequentially)`,
3498 ONCE_REWRITE_TAC[TAUT `(if p then x else y) = (if ~p then y else x)`] THEN
3499 REWRITE_TAC[LIM_CASES_FINITE_SEQUENTIALLY]);;
3501 let LIM_CASES_SEQUENTIALLY = prove
3502 (`!f g l m. (((\n. if m <= n then f n else g n) --> l) sequentially <=>
3503 (f --> l) sequentially) /\
3504 (((\n. if m < n then f n else g n) --> l) sequentially <=>
3505 (f --> l) sequentially) /\
3506 (((\n. if n <= m then f n else g n) --> l) sequentially <=>
3507 (g --> l) sequentially) /\
3508 (((\n. if n < m then f n else g n) --> l) sequentially <=>
3509 (g --> l) sequentially)`,
3510 SIMP_TAC[LIM_CASES_FINITE_SEQUENTIALLY; LIM_CASES_COFINITE_SEQUENTIALLY;
3511 NOT_LE; NOT_LT; FINITE_NUMSEG_LT; FINITE_NUMSEG_LE]);;
3513 (* ------------------------------------------------------------------------- *)
3514 (* A congruence rule allowing us to transform limits assuming not at point. *)
3515 (* ------------------------------------------------------------------------- *)
3517 let LIM_CONG_WITHIN = prove
3518 (`(!x. ~(x = a) ==> f x = g x)
3519 ==> (((\x. f x) --> l) (at a within s) <=> ((g --> l) (at a within s)))`,
3520 REWRITE_TAC[LIM_WITHIN; GSYM DIST_NZ] THEN SIMP_TAC[]);;
3522 let LIM_CONG_AT = prove
3523 (`(!x. ~(x = a) ==> f x = g x)
3524 ==> (((\x. f x) --> l) (at a) <=> ((g --> l) (at a)))`,
3525 REWRITE_TAC[LIM_AT; GSYM DIST_NZ] THEN SIMP_TAC[]);;
3527 extend_basic_congs [LIM_CONG_WITHIN; LIM_CONG_AT];;
3529 (* ------------------------------------------------------------------------- *)
3530 (* Useful lemmas on closure and set of possible sequential limits. *)
3531 (* ------------------------------------------------------------------------- *)
3533 let CLOSURE_SEQUENTIAL = prove
3535 l IN closure(s) <=> ?x. (!n. x(n) IN s) /\ (x --> l) sequentially`,
3536 REWRITE_TAC[closure; IN_UNION; LIMPT_SEQUENTIAL; IN_ELIM_THM; IN_DELETE] THEN
3537 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
3538 `((b ==> c) /\ (~a /\ c ==> b)) /\ (a ==> c) ==> (a \/ b <=> c)`) THEN
3539 CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN DISCH_TAC THEN
3540 EXISTS_TAC `\n:num. l:real^N` THEN
3541 ASM_REWRITE_TAC[LIM_CONST]);;
3543 let CLOSED_CONTAINS_SEQUENTIAL_LIMIT = prove
3545 closed s /\ (!n. x n IN s) /\ (x --> l) sequentially ==> l IN s`,
3546 MESON_TAC[CLOSURE_SEQUENTIAL; CLOSURE_CLOSED]);;
3548 let CLOSED_SEQUENTIAL_LIMITS = prove
3550 !x l. (!n. x(n) IN s) /\ (x --> l) sequentially ==> l IN s`,
3551 MESON_TAC[CLOSURE_SEQUENTIAL; CLOSURE_CLOSED;
3552 CLOSED_LIMPT; LIMPT_SEQUENTIAL; IN_DELETE]);;
3554 let CLOSURE_APPROACHABLE = prove
3555 (`!x s. x IN closure(s) <=> !e. &0 < e ==> ?y. y IN s /\ dist(y,x) < e`,
3556 REWRITE_TAC[closure; LIMPT_APPROACHABLE; IN_UNION; IN_ELIM_THM] THEN
3557 MESON_TAC[DIST_REFL]);;
3559 let CLOSED_APPROACHABLE = prove
3561 ==> ((!e. &0 < e ==> ?y. y IN s /\ dist(y,x) < e) <=> x IN s)`,
3562 MESON_TAC[CLOSURE_CLOSED; CLOSURE_APPROACHABLE]);;
3564 let IN_CLOSURE_DELETE = prove
3565 (`!s x:real^N. x IN closure(s DELETE x) <=> x limit_point_of s`,
3566 SIMP_TAC[CLOSURE_APPROACHABLE; LIMPT_APPROACHABLE; IN_DELETE; CONJ_ASSOC]);;
3568 (* ------------------------------------------------------------------------- *)
3569 (* Some other lemmas about sequences. *)
3570 (* ------------------------------------------------------------------------- *)
3572 let SEQ_OFFSET = prove
3573 (`!f l k. (f --> l) sequentially ==> ((\i. f(i + k)) --> l) sequentially`,
3574 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
3575 MESON_TAC[ARITH_RULE `N <= n ==> N <= n + k:num`]);;
3577 let SEQ_OFFSET_NEG = prove
3578 (`!f l k. (f --> l) sequentially ==> ((\i. f(i - k)) --> l) sequentially`,
3579 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
3580 MESON_TAC[ARITH_RULE `N + k <= n ==> N <= n - k:num`]);;
3582 let SEQ_OFFSET_REV = prove
3583 (`!f l k. ((\i. f(i + k)) --> l) sequentially ==> (f --> l) sequentially`,
3584 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
3585 MESON_TAC[ARITH_RULE `N + k <= n ==> N <= n - k /\ (n - k) + k = n:num`]);;
3587 let SEQ_HARMONIC = prove
3588 (`((\n. lift(inv(&n))) --> vec 0) sequentially`,
3589 REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3590 FIRST_ASSUM(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC o
3591 GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN
3592 EXISTS_TAC `N:num` THEN REPEAT STRIP_TAC THEN
3593 REWRITE_TAC[dist; VECTOR_SUB_RZERO; NORM_LIFT] THEN
3594 ASM_REWRITE_TAC[REAL_ABS_INV; REAL_ABS_NUM] THEN
3595 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN
3596 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
3597 ASM_REWRITE_TAC[REAL_OF_NUM_LT; REAL_OF_NUM_LE; LT_NZ]);;
3599 (* ------------------------------------------------------------------------- *)
3600 (* More properties of closed balls. *)
3601 (* ------------------------------------------------------------------------- *)
3603 let CLOSED_CBALL = prove
3604 (`!x:real^N e. closed(cball(x,e))`,
3605 REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS; IN_CBALL; dist] THEN
3606 GEN_TAC THEN GEN_TAC THEN X_GEN_TAC `s:num->real^N` THEN
3607 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
3608 MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN
3609 EXISTS_TAC `\n. x - (s:num->real^N) n` THEN
3610 REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
3611 ASM_SIMP_TAC[LIM_SUB; LIM_CONST; SEQUENTIALLY] THEN MESON_TAC[GE_REFL]);;
3613 let IN_INTERIOR_CBALL = prove
3614 (`!x s. x IN interior s <=> ?e. &0 < e /\ cball(x,e) SUBSET s`,
3615 REWRITE_TAC[interior; IN_ELIM_THM] THEN
3616 MESON_TAC[OPEN_CONTAINS_CBALL; SUBSET_TRANS;
3617 BALL_SUBSET_CBALL; CENTRE_IN_BALL; OPEN_BALL]);;
3619 let LIMPT_BALL = prove
3620 (`!x:real^N y e. y limit_point_of ball(x,e) <=> &0 < e /\ y IN cball(x,e)`,
3621 REPEAT GEN_TAC THEN ASM_CASES_TAC `&0 < e` THENL
3622 [ALL_TAC; ASM_MESON_TAC[LIMPT_EMPTY; REAL_NOT_LT; BALL_EQ_EMPTY]] THEN
3623 ASM_REWRITE_TAC[] THEN EQ_TAC THENL
3624 [MESON_TAC[CLOSED_CBALL; CLOSED_LIMPT; LIMPT_SUBSET; BALL_SUBSET_CBALL];
3625 REWRITE_TAC[IN_CBALL; LIMPT_APPROACHABLE; IN_BALL]] THEN
3626 DISCH_TAC THEN X_GEN_TAC `d:real` THEN DISCH_TAC THEN
3627 ASM_CASES_TAC `y:real^N = x` THEN ASM_REWRITE_TAC[DIST_NZ] THENL
3628 [MP_TAC(SPECL [`d:real`; `e:real`] REAL_DOWN2) THEN
3629 ASM_REWRITE_TAC[] THEN
3630 GEN_MESON_TAC 0 40 1 [VECTOR_CHOOSE_DIST; DIST_SYM; REAL_LT_IMP_LE];
3632 MP_TAC(SPECL [`norm(y:real^N - x)`; `d:real`] REAL_DOWN2) THEN
3633 RULE_ASSUM_TAC(REWRITE_RULE[DIST_NZ; dist]) THEN ASM_REWRITE_TAC[] THEN
3634 DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
3635 EXISTS_TAC `(y:real^N) - (k / dist(y,x)) % (y - x)` THEN
3636 REWRITE_TAC[dist; VECTOR_ARITH `(y - c % z) - y = --c % z`] THEN
3637 REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; REAL_ABS_NEG] THEN
3638 ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_LT_IMP_NZ] THEN
3639 REWRITE_TAC[VECTOR_ARITH `x - (y - k % (y - x)) = (&1 - k) % (x - y)`] THEN
3640 ASM_SIMP_TAC[REAL_ARITH `&0 < k ==> &0 < abs k`; NORM_MUL] THEN
3641 ASM_SIMP_TAC[REAL_ARITH `&0 < k /\ k < d ==> abs k < d`] THEN
3642 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `norm(x:real^N - y)` THEN
3643 ASM_REWRITE_TAC[] THEN GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN
3644 MATCH_MP_TAC REAL_LT_RMUL THEN CONJ_TAC THENL
3645 [ALL_TAC; ASM_MESON_TAC[NORM_SUB]] THEN
3646 MATCH_MP_TAC(REAL_ARITH `&0 < k /\ k < &1 ==> abs(&1 - k) < &1`) THEN
3647 ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_MUL_LZERO;
3650 let CLOSURE_BALL = prove
3651 (`!x:real^N e. &0 < e ==> (closure(ball(x,e)) = cball(x,e))`,
3652 SIMP_TAC[EXTENSION; closure; IN_ELIM_THM; IN_UNION; LIMPT_BALL] THEN
3653 REWRITE_TAC[IN_BALL; IN_CBALL] THEN REAL_ARITH_TAC);;
3655 let INTERIOR_BALL = prove
3656 (`!a r. interior(ball(a,r)) = ball(a,r)`,
3657 SIMP_TAC[INTERIOR_OPEN; OPEN_BALL]);;
3659 let INTERIOR_CBALL = prove
3660 (`!x:real^N e. interior(cball(x,e)) = ball(x,e)`,
3661 REPEAT GEN_TAC THEN ASM_CASES_TAC `&0 <= e` THENL
3663 SUBGOAL_THEN `cball(x:real^N,e) = {} /\ ball(x:real^N,e) = {}`
3664 (fun th -> REWRITE_TAC[th; INTERIOR_EMPTY]) THEN
3665 REWRITE_TAC[IN_BALL; IN_CBALL; EXTENSION; NOT_IN_EMPTY] THEN
3666 CONJ_TAC THEN X_GEN_TAC `y:real^N` THEN
3667 MP_TAC(ISPECL [`x:real^N`; `y:real^N`] DIST_POS_LE) THEN
3668 POP_ASSUM MP_TAC THEN REAL_ARITH_TAC] THEN
3669 MATCH_MP_TAC INTERIOR_UNIQUE THEN
3670 REWRITE_TAC[BALL_SUBSET_CBALL; OPEN_BALL] THEN
3671 X_GEN_TAC `t:real^N->bool` THEN
3672 SIMP_TAC[SUBSET; IN_CBALL; IN_BALL; REAL_LT_LE] THEN STRIP_TAC THEN
3673 X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
3674 FIRST_X_ASSUM(MP_TAC o SPEC `z:real^N` o GEN_REWRITE_RULE I [open_def]) THEN
3675 ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN `d:real` MP_TAC) THEN
3676 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3677 ASM_CASES_TAC `z:real^N = x` THENL
3678 [FIRST_X_ASSUM SUBST_ALL_TAC THEN
3679 FIRST_X_ASSUM(X_CHOOSE_TAC `k:real` o MATCH_MP REAL_DOWN) THEN
3680 SUBGOAL_THEN `?w:real^N. dist(w,x) = k` STRIP_ASSUME_TAC THENL
3681 [ASM_MESON_TAC[VECTOR_CHOOSE_DIST; DIST_SYM; REAL_LT_IMP_LE];
3682 ASM_MESON_TAC[REAL_NOT_LE; DIST_REFL; DIST_SYM]];
3683 RULE_ASSUM_TAC(REWRITE_RULE[DIST_NZ]) THEN
3684 DISCH_THEN(MP_TAC o SPEC `z + ((d / &2) / dist(z,x)) % (z - x:real^N)`) THEN
3685 REWRITE_TAC[dist; VECTOR_ADD_SUB; NORM_MUL; REAL_ABS_DIV;
3686 REAL_ABS_NORM; REAL_ABS_NUM] THEN
3687 ASM_SIMP_TAC[REAL_DIV_RMUL; GSYM dist; REAL_LT_IMP_NZ] THEN
3688 ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
3689 ASM_REWRITE_TAC[REAL_ARITH `abs d < d * &2 <=> &0 < d`] THEN
3690 DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN REWRITE_TAC[dist] THEN
3691 REWRITE_TAC[VECTOR_ARITH `x - (z + k % (z - x)) = (&1 + k) % (x - z)`] THEN
3692 REWRITE_TAC[REAL_NOT_LE; NORM_MUL] THEN
3693 GEN_REWRITE_TAC LAND_CONV [GSYM REAL_MUL_LID] THEN
3694 ONCE_REWRITE_TAC[NORM_SUB] THEN
3695 ASM_SIMP_TAC[REAL_LT_RMUL_EQ; GSYM dist] THEN
3696 MATCH_MP_TAC(REAL_ARITH `&0 < x ==> &1 < abs(&1 + x)`) THEN
3697 ONCE_REWRITE_TAC[DIST_SYM] THEN
3698 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH]]);;
3700 let FRONTIER_BALL = prove
3701 (`!a e. &0 < e ==> frontier(ball(a,e)) = sphere(a,e)`,
3702 SIMP_TAC[frontier; sphere; CLOSURE_BALL; INTERIOR_OPEN; OPEN_BALL;
3703 REAL_LT_IMP_LE] THEN
3704 REWRITE_TAC[EXTENSION; IN_DIFF; IN_ELIM_THM; IN_BALL; IN_CBALL] THEN
3707 let FRONTIER_CBALL = prove
3708 (`!a e. frontier(cball(a,e)) = sphere(a,e)`,
3709 SIMP_TAC[frontier; sphere; INTERIOR_CBALL; CLOSED_CBALL; CLOSURE_CLOSED;
3710 REAL_LT_IMP_LE] THEN
3711 REWRITE_TAC[EXTENSION; IN_DIFF; IN_ELIM_THM; IN_BALL; IN_CBALL] THEN
3714 let CBALL_EQ_EMPTY = prove
3715 (`!x e. (cball(x,e) = {}) <=> e < &0`,
3716 REWRITE_TAC[EXTENSION; IN_CBALL; NOT_IN_EMPTY; REAL_NOT_LE] THEN
3717 MESON_TAC[DIST_POS_LE; DIST_REFL; REAL_LTE_TRANS]);;
3719 let CBALL_EMPTY = prove
3720 (`!x e. e < &0 ==> cball(x,e) = {}`,
3721 REWRITE_TAC[CBALL_EQ_EMPTY]);;
3723 let CBALL_EQ_SING = prove
3724 (`!x:real^N e. (cball(x,e) = {x}) <=> e = &0`,
3725 REPEAT GEN_TAC THEN REWRITE_TAC[EXTENSION; IN_CBALL; IN_SING] THEN
3726 EQ_TAC THENL [ALL_TAC; MESON_TAC[DIST_LE_0]] THEN
3727 DISCH_THEN(fun th -> MP_TAC(SPEC `x + (e / &2) % basis 1:real^N` th) THEN
3728 MP_TAC(SPEC `x:real^N` th)) THEN
3729 REWRITE_TAC[dist; VECTOR_ARITH `x - (x + e):real^N = --e`;
3730 VECTOR_ARITH `x + e = x <=> e:real^N = vec 0`] THEN
3731 REWRITE_TAC[NORM_NEG; NORM_MUL; VECTOR_MUL_EQ_0; NORM_0; VECTOR_SUB_REFL] THEN
3732 SIMP_TAC[NORM_BASIS; BASIS_NONZERO; LE_REFL; DIMINDEX_GE_1] THEN
3735 let CBALL_SING = prove
3736 (`!x e. e = &0 ==> cball(x,e) = {x}`,
3737 REWRITE_TAC[CBALL_EQ_SING]);;
3739 let SPHERE_SING = prove
3740 (`!x e. e = &0 ==> sphere(x,e) = {x}`,
3741 SIMP_TAC[sphere; DIST_EQ_0; SING_GSPEC]);;
3743 let SPHERE_EQ_SING = prove
3744 (`!a:real^N r x. sphere(a,r) = {x} <=> x = a /\ r = &0`,
3745 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[SPHERE_SING] THEN
3746 ASM_CASES_TAC `r < &0` THEN ASM_SIMP_TAC[SPHERE_EMPTY; NOT_INSERT_EMPTY] THEN
3747 ASM_CASES_TAC `r = &0` THEN ASM_SIMP_TAC[SPHERE_SING] THENL
3748 [ASM SET_TAC[]; ALL_TAC] THEN
3749 MATCH_MP_TAC(SET_RULE
3750 `!y. (x IN s ==> y IN s /\ ~(y = x)) ==> ~(s = {x})`) THEN
3751 EXISTS_TAC `a - (x - a):real^N` THEN REWRITE_TAC[IN_SPHERE] THEN
3752 REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC NORM_ARITH);;
3754 (* ------------------------------------------------------------------------- *)
3755 (* For points in the interior, localization of limits makes no difference. *)
3756 (* ------------------------------------------------------------------------- *)
3758 let EVENTUALLY_WITHIN_INTERIOR = prove
3761 ==> (eventually p (at x within s) <=> eventually p (at x))`,
3762 REWRITE_TAC[EVENTUALLY_WITHIN; EVENTUALLY_AT; IN_INTERIOR] THEN
3763 REPEAT GEN_TAC THEN SIMP_TAC[SUBSET; IN_BALL; LEFT_IMP_FORALL_THM] THEN
3764 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
3765 EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
3766 EXISTS_TAC `min (d:real) e` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
3767 ASM_MESON_TAC[DIST_SYM]);;
3769 let LIM_WITHIN_INTERIOR = prove
3772 ==> ((f --> l) (at x within s) <=> (f --> l) (at x))`,
3773 SIMP_TAC[tendsto; EVENTUALLY_WITHIN_INTERIOR]);;
3775 let NETLIMIT_WITHIN_INTERIOR = prove
3776 (`!s x:real^N. x IN interior s ==> netlimit(at x within s) = x`,
3777 REPEAT STRIP_TAC THEN MATCH_MP_TAC NETLIMIT_WITHIN THEN
3778 REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN
3779 FIRST_ASSUM(MP_TAC o MATCH_MP(REWRITE_RULE[OPEN_CONTAINS_BALL]
3780 (SPEC_ALL OPEN_INTERIOR))) THEN
3781 ASM_MESON_TAC[LIMPT_SUBSET; LIMPT_BALL; CENTRE_IN_CBALL; REAL_LT_IMP_LE;
3782 SUBSET_TRANS; INTERIOR_SUBSET]);;
3784 (* ------------------------------------------------------------------------- *)
3785 (* A non-singleton connected set is perfect (i.e. has no isolated points). *)
3786 (* ------------------------------------------------------------------------- *)
3788 let CONNECTED_IMP_PERFECT = prove
3790 connected s /\ ~(?a. s = {a}) /\ x IN s ==> x limit_point_of s`,
3791 REPEAT STRIP_TAC THEN REWRITE_TAC[limit_point_of] THEN
3792 X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN
3793 MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN
3794 FIRST_ASSUM(MP_TAC o SPEC `x:real^N` o GEN_REWRITE_RULE I
3795 [OPEN_CONTAINS_CBALL]) THEN
3796 ASM_REWRITE_TAC[] THEN
3797 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
3798 FIRST_X_ASSUM(MP_TAC o SPEC `{x:real^N}` o
3799 GEN_REWRITE_RULE I [CONNECTED_CLOPEN]) THEN
3800 REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL
3801 [REWRITE_TAC[OPEN_IN_OPEN] THEN EXISTS_TAC `t:real^N->bool` THEN
3803 REWRITE_TAC[CLOSED_IN_CLOSED] THEN
3804 EXISTS_TAC `cball(x:real^N,e)` THEN REWRITE_TAC[CLOSED_CBALL] THEN
3805 REWRITE_TAC[EXTENSION; IN_INTER; IN_SING] THEN
3806 ASM_MESON_TAC[CENTRE_IN_CBALL; SUBSET; REAL_LT_IMP_LE];
3809 let CONNECTED_IMP_PERFECT_CLOSED = prove
3810 (`!s x. connected s /\ closed s /\ ~(?a. s = {a})
3811 ==> (x limit_point_of s <=> x IN s)`,
3812 MESON_TAC[CONNECTED_IMP_PERFECT; CLOSED_LIMPT]);;
3814 (* ------------------------------------------------------------------------- *)
3816 (* ------------------------------------------------------------------------- *)
3818 let bounded = new_definition
3819 `bounded s <=> ?a. !x:real^N. x IN s ==> norm(x) <= a`;;
3821 let BOUNDED_EMPTY = prove
3823 REWRITE_TAC[bounded; NOT_IN_EMPTY]);;
3825 let BOUNDED_SUBSET = prove
3826 (`!s t. bounded t /\ s SUBSET t ==> bounded s`,
3827 MESON_TAC[bounded; SUBSET]);;
3829 let BOUNDED_INTERIOR = prove
3830 (`!s:real^N->bool. bounded s ==> bounded(interior s)`,
3831 MESON_TAC[BOUNDED_SUBSET; INTERIOR_SUBSET]);;
3833 let BOUNDED_CLOSURE = prove
3834 (`!s:real^N->bool. bounded s ==> bounded(closure s)`,
3835 REWRITE_TAC[bounded; CLOSURE_SEQUENTIAL] THEN
3836 GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
3837 MESON_TAC[REWRITE_RULE[eventually] LIM_NORM_UBOUND;
3838 TRIVIAL_LIMIT_SEQUENTIALLY; trivial_limit]);;
3840 let BOUNDED_CLOSURE_EQ = prove
3841 (`!s:real^N->bool. bounded(closure s) <=> bounded s`,
3842 GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_CLOSURE] THEN
3843 MESON_TAC[BOUNDED_SUBSET; CLOSURE_SUBSET]);;
3845 let BOUNDED_CBALL = prove
3846 (`!x:real^N e. bounded(cball(x,e))`,
3847 REPEAT GEN_TAC THEN REWRITE_TAC[bounded] THEN
3848 EXISTS_TAC `norm(x:real^N) + e` THEN REWRITE_TAC[IN_CBALL; dist] THEN
3851 let BOUNDED_BALL = prove
3852 (`!x e. bounded(ball(x,e))`,
3853 MESON_TAC[BALL_SUBSET_CBALL; BOUNDED_CBALL; BOUNDED_SUBSET]);;
3855 let FINITE_IMP_BOUNDED = prove
3856 (`!s:real^N->bool. FINITE s ==> bounded s`,
3857 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[BOUNDED_EMPTY] THEN
3858 REWRITE_TAC[bounded; IN_INSERT] THEN X_GEN_TAC `x:real^N` THEN GEN_TAC THEN
3859 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `B:real`) STRIP_ASSUME_TAC) THEN
3860 EXISTS_TAC `norm(x:real^N) + abs B` THEN REPEAT STRIP_TAC THEN
3861 ASM_MESON_TAC[NORM_POS_LE; REAL_ARITH
3862 `(y <= b /\ &0 <= x ==> y <= x + abs b) /\ x <= x + abs b`]);;
3864 let BOUNDED_UNION = prove
3865 (`!s t. bounded (s UNION t) <=> bounded s /\ bounded t`,
3866 REWRITE_TAC[bounded; IN_UNION] THEN MESON_TAC[REAL_LE_MAX]);;
3868 let BOUNDED_UNIONS = prove
3869 (`!f. FINITE f /\ (!s. s IN f ==> bounded s) ==> bounded(UNIONS f)`,
3870 REWRITE_TAC[IMP_CONJ] THEN
3871 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3872 REWRITE_TAC[UNIONS_0; BOUNDED_EMPTY; IN_INSERT; UNIONS_INSERT] THEN
3873 MESON_TAC[BOUNDED_UNION]);;
3875 let BOUNDED_POS = prove
3876 (`!s. bounded s <=> ?b. &0 < b /\ !x. x IN s ==> norm(x) <= b`,
3877 REWRITE_TAC[bounded] THEN
3878 MESON_TAC[REAL_ARITH `&0 < &1 + abs(y) /\ (x <= y ==> x <= &1 + abs(y))`]);;
3880 let BOUNDED_POS_LT = prove
3881 (`!s. bounded s <=> ?b. &0 < b /\ !x. x IN s ==> norm(x) < b`,
3882 REWRITE_TAC[bounded] THEN
3883 MESON_TAC[REAL_LT_IMP_LE;
3884 REAL_ARITH `&0 < &1 + abs(y) /\ (x <= y ==> x < &1 + abs(y))`]);;
3886 let BOUNDED_INTER = prove
3887 (`!s t. bounded s \/ bounded t ==> bounded (s INTER t)`,
3888 MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET]);;
3890 let BOUNDED_DIFF = prove
3891 (`!s t. bounded s ==> bounded (s DIFF t)`,
3892 MESON_TAC[BOUNDED_SUBSET; SUBSET_DIFF]);;
3894 let BOUNDED_INSERT = prove
3895 (`!x s. bounded(x INSERT s) <=> bounded s`,
3896 ONCE_REWRITE_TAC[SET_RULE `x INSERT s = {x} UNION s`] THEN
3897 SIMP_TAC[BOUNDED_UNION; FINITE_IMP_BOUNDED; FINITE_RULES]);;
3899 let BOUNDED_SING = prove
3901 REWRITE_TAC[BOUNDED_INSERT; BOUNDED_EMPTY]);;
3903 let BOUNDED_INTERS = prove
3904 (`!f:(real^N->bool)->bool.
3905 (?s:real^N->bool. s IN f /\ bounded s) ==> bounded(INTERS f)`,
3906 REWRITE_TAC[LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN REPEAT GEN_TAC THEN
3907 DISCH_TAC THEN MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN
3910 let NOT_BOUNDED_UNIV = prove
3911 (`~(bounded (:real^N))`,
3912 REWRITE_TAC[BOUNDED_POS; NOT_FORALL_THM; NOT_EXISTS_THM; IN_UNIV;
3913 DE_MORGAN_THM; REAL_NOT_LE] THEN
3914 X_GEN_TAC `B:real` THEN ASM_CASES_TAC `&0 < B` THEN ASM_REWRITE_TAC[] THEN
3915 MP_TAC(SPEC `B + &1` VECTOR_CHOOSE_SIZE) THEN
3916 ASM_SIMP_TAC[REAL_ARITH `&0 < B ==> &0 <= B + &1`] THEN
3917 MATCH_MP_TAC MONO_EXISTS THEN REAL_ARITH_TAC);;
3919 let COBOUNDED_IMP_UNBOUNDED = prove
3920 (`!s. bounded((:real^N) DIFF s) ==> ~bounded s`,
3921 GEN_TAC THEN REWRITE_TAC[TAUT `a ==> ~b <=> ~(a /\ b)`] THEN
3922 REWRITE_TAC[GSYM BOUNDED_UNION; SET_RULE `UNIV DIFF s UNION s = UNIV`] THEN
3923 REWRITE_TAC[NOT_BOUNDED_UNIV]);;
3925 let BOUNDED_LINEAR_IMAGE = prove
3926 (`!f:real^M->real^N s. bounded s /\ linear f ==> bounded(IMAGE f s)`,
3927 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN
3928 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `B1:real`) MP_TAC) THEN
3929 DISCH_THEN(X_CHOOSE_TAC `B2:real` o MATCH_MP LINEAR_BOUNDED_POS) THEN
3930 EXISTS_TAC `B2 * B1` THEN ASM_SIMP_TAC[REAL_LT_MUL; FORALL_IN_IMAGE] THEN
3931 X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN
3932 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `B2 * norm(x:real^M)` THEN
3933 ASM_SIMP_TAC[REAL_LE_LMUL_EQ]);;
3935 let BOUNDED_LINEAR_IMAGE_EQ = prove
3936 (`!f s. linear f /\ (!x y. f x = f y ==> x = y)
3937 ==> (bounded (IMAGE f s) <=> bounded s)`,
3938 MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE BOUNDED_LINEAR_IMAGE));;
3940 add_linear_invariants [BOUNDED_LINEAR_IMAGE_EQ];;
3942 let BOUNDED_SCALING = prove
3943 (`!c s. bounded s ==> bounded (IMAGE (\x. c % x) s)`,
3944 REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_LINEAR_IMAGE THEN
3945 ASM_SIMP_TAC[LINEAR_COMPOSE_CMUL; LINEAR_ID]);;
3947 let BOUNDED_NEGATIONS = prove
3948 (`!s. bounded s ==> bounded (IMAGE (--) s)`,
3950 DISCH_THEN(MP_TAC o SPEC `-- &1` o MATCH_MP BOUNDED_SCALING) THEN
3951 REWRITE_TAC[bounded; IN_IMAGE; VECTOR_MUL_LNEG; VECTOR_MUL_LID]);;
3953 let BOUNDED_TRANSLATION = prove
3954 (`!a:real^N s. bounded s ==> bounded (IMAGE (\x. a + x) s)`,
3955 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN
3956 DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN
3957 EXISTS_TAC `B + norm(a:real^N)` THEN POP_ASSUM MP_TAC THEN
3958 MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL [NORM_ARITH_TAC; ALL_TAC] THEN
3959 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
3960 REWRITE_TAC[] THEN NORM_ARITH_TAC);;
3962 let BOUNDED_TRANSLATION_EQ = prove
3963 (`!a s. bounded (IMAGE (\x:real^N. a + x) s) <=> bounded s`,
3964 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_TRANSLATION] THEN
3965 DISCH_THEN(MP_TAC o SPEC `--a:real^N` o MATCH_MP BOUNDED_TRANSLATION) THEN
3966 REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID;
3967 VECTOR_ARITH `--a + a + x:real^N = x`]);;
3969 add_translation_invariants [BOUNDED_TRANSLATION_EQ];;
3971 let BOUNDED_DIFFS = prove
3972 (`!s t:real^N->bool.
3973 bounded s /\ bounded t ==> bounded {x - y | x IN s /\ y IN t}`,
3974 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN
3975 DISCH_THEN(CONJUNCTS_THEN2
3976 (X_CHOOSE_TAC `B:real`) (X_CHOOSE_TAC `C:real`)) THEN
3977 EXISTS_TAC `B + C:real` THEN REWRITE_TAC[IN_ELIM_THM] THEN
3978 CONJ_TAC THENL [ASM_REAL_ARITH_TAC; REPEAT STRIP_TAC] THEN
3979 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(NORM_ARITH
3980 `norm x <= a /\ norm y <= b ==> norm(x - y) <= a + b`) THEN
3983 let BOUNDED_SUMS = prove
3984 (`!s t:real^N->bool.
3985 bounded s /\ bounded t ==> bounded {x + y | x IN s /\ y IN t}`,
3986 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN
3987 DISCH_THEN(CONJUNCTS_THEN2
3988 (X_CHOOSE_TAC `B:real`) (X_CHOOSE_TAC `C:real`)) THEN
3989 EXISTS_TAC `B + C:real` THEN REWRITE_TAC[IN_ELIM_THM] THEN
3990 CONJ_TAC THENL [ASM_REAL_ARITH_TAC; REPEAT STRIP_TAC] THEN
3991 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(NORM_ARITH
3992 `norm x <= a /\ norm y <= b ==> norm(x + y) <= a + b`) THEN
3995 let BOUNDED_SUMS_IMAGE = prove
3996 (`!f g t. bounded {f x | x IN t} /\ bounded {g x | x IN t}
3997 ==> bounded {f x + g x | x IN t}`,
3998 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUMS) THEN
3999 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN
4002 let BOUNDED_SUMS_IMAGES = prove
4003 (`!f:A->B->real^N t s.
4005 (!a. a IN s ==> bounded {f x a | x IN t})
4006 ==> bounded { vsum s (f x) | x IN t}`,
4007 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
4008 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
4009 SIMP_TAC[VSUM_CLAUSES] THEN CONJ_TAC THENL
4010 [DISCH_THEN(K ALL_TAC) THEN MATCH_MP_TAC BOUNDED_SUBSET THEN
4011 EXISTS_TAC `{vec 0:real^N}` THEN
4012 SIMP_TAC[FINITE_IMP_BOUNDED; FINITE_RULES] THEN SET_TAC[];
4014 REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_SUMS_IMAGE THEN
4015 ASM_SIMP_TAC[IN_INSERT]);;
4017 let BOUNDED_SUBSET_BALL = prove
4018 (`!s x:real^N. bounded(s) ==> ?r. &0 < r /\ s SUBSET ball(x,r)`,
4019 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN
4020 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
4021 EXISTS_TAC `&2 * B + norm(x:real^N)` THEN
4022 ASM_SIMP_TAC[NORM_POS_LE; REAL_ARITH
4023 `&0 < B /\ &0 <= x ==> &0 < &2 * B + x`] THEN
4024 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
4025 FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[IN_BALL] THEN
4026 UNDISCH_TAC `&0 < B` THEN NORM_ARITH_TAC);;
4028 let BOUNDED_SUBSET_CBALL = prove
4029 (`!s x:real^N. bounded(s) ==> ?r. &0 < r /\ s SUBSET cball(x,r)`,
4030 MESON_TAC[BOUNDED_SUBSET_BALL; SUBSET_TRANS; BALL_SUBSET_CBALL]);;
4032 let UNBOUNDED_INTER_COBOUNDED = prove
4033 (`!s t. ~bounded s /\ bounded((:real^N) DIFF t) ==> ~(s INTER t = {})`,
4034 REWRITE_TAC[SET_RULE `s INTER t = {} <=> s SUBSET (:real^N) DIFF t`] THEN
4035 MESON_TAC[BOUNDED_SUBSET]);;
4037 let COBOUNDED_INTER_UNBOUNDED = prove
4038 (`!s t. bounded((:real^N) DIFF s) /\ ~bounded t ==> ~(s INTER t = {})`,
4039 REWRITE_TAC[SET_RULE `s INTER t = {} <=> t SUBSET (:real^N) DIFF s`] THEN
4040 MESON_TAC[BOUNDED_SUBSET]);;
4042 let SUBSPACE_BOUNDED_EQ_TRIVIAL = prove
4043 (`!s:real^N->bool. subspace s ==> (bounded s <=> s = {vec 0})`,
4044 REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[BOUNDED_SING] THEN
4045 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
4046 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
4047 `~(s = {a}) ==> a IN s ==> ?b. b IN s /\ ~(b = a)`)) THEN
4048 ASM_SIMP_TAC[SUBSPACE_0] THEN
4049 DISCH_THEN(X_CHOOSE_THEN `v:real^N` STRIP_ASSUME_TAC) THEN
4050 REWRITE_TAC[bounded; NOT_EXISTS_THM] THEN X_GEN_TAC `B:real` THEN
4051 DISCH_THEN(MP_TAC o SPEC `(B + &1) / norm v % v:real^N`) THEN
4052 ASM_SIMP_TAC[SUBSPACE_MUL; NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN
4053 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN REAL_ARITH_TAC);;
4055 let BOUNDED_COMPONENTWISE = prove
4057 bounded s <=> !i. 1 <= i /\ i <= dimindex(:N)
4058 ==> bounded (IMAGE (\x. lift(x$i)) s)`,
4059 GEN_TAC THEN REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; NORM_LIFT] THEN
4060 EQ_TAC THENL [ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS]; ALL_TAC] THEN
4061 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
4062 SIMP_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `b:num->real` THEN
4063 DISCH_TAC THEN EXISTS_TAC `sum(1..dimindex(:N)) b` THEN CONJ_TAC THENL
4064 [MATCH_MP_TAC REAL_LET_TRANS THEN
4065 EXISTS_TAC `sum(1..dimindex(:N)) (\i. &0)` THEN
4066 SIMP_TAC[SUM_POS_LE_NUMSEG; REAL_POS] THEN
4067 MATCH_MP_TAC SUM_LT_ALL THEN
4068 ASM_SIMP_TAC[IN_NUMSEG; FINITE_NUMSEG; NUMSEG_EMPTY] THEN
4069 REWRITE_TAC[NOT_LT; DIMINDEX_GE_1];
4070 REPEAT STRIP_TAC THEN
4071 W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN
4072 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
4073 MATCH_MP_TAC SUM_LE THEN ASM_SIMP_TAC[IN_NUMSEG; FINITE_NUMSEG]]);;
4075 (* ------------------------------------------------------------------------- *)
4076 (* Some theorems on sups and infs using the notion "bounded". *)
4077 (* ------------------------------------------------------------------------- *)
4079 let BOUNDED_LIFT = prove
4080 (`!s. bounded(IMAGE lift s) <=> ?a. !x. x IN s ==> abs(x) <= a`,
4081 REWRITE_TAC[bounded; FORALL_LIFT; NORM_LIFT; LIFT_IN_IMAGE_LIFT]);;
4083 let BOUNDED_HAS_SUP = prove
4084 (`!s. bounded(IMAGE lift s) /\ ~(s = {})
4085 ==> (!x. x IN s ==> x <= sup s) /\
4086 (!b. (!x. x IN s ==> x <= b) ==> sup s <= b)`,
4087 REWRITE_TAC[BOUNDED_LIFT; IMAGE_EQ_EMPTY] THEN
4088 MESON_TAC[SUP; REAL_ARITH `abs(x) <= a ==> x <= a`]);;
4090 let SUP_INSERT = prove
4091 (`!x s. bounded (IMAGE lift s)
4092 ==> sup(x INSERT s) = if s = {} then x else max x (sup s)`,
4093 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_UNIQUE THEN
4094 COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THENL
4095 [MESON_TAC[REAL_LE_REFL]; ALL_TAC] THEN
4096 REWRITE_TAC[REAL_LE_MAX; REAL_LT_MAX; IN_INSERT] THEN
4097 MP_TAC(ISPEC `s:real->bool` BOUNDED_HAS_SUP) THEN ASM_REWRITE_TAC[] THEN
4098 REPEAT STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_REFL; REAL_NOT_LT]);;
4100 let BOUNDED_HAS_INF = prove
4101 (`!s. bounded(IMAGE lift s) /\ ~(s = {})
4102 ==> (!x. x IN s ==> inf s <= x) /\
4103 (!b. (!x. x IN s ==> b <= x) ==> b <= inf s)`,
4104 REWRITE_TAC[BOUNDED_LIFT; IMAGE_EQ_EMPTY] THEN
4105 MESON_TAC[INF; REAL_ARITH `abs(x) <= a ==> --a <= x`]);;
4107 let INF_INSERT = prove
4108 (`!x s. bounded (IMAGE lift s)
4109 ==> inf(x INSERT s) = if s = {} then x else min x (inf s)`,
4110 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INF_UNIQUE THEN
4111 COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THENL
4112 [MESON_TAC[REAL_LE_REFL]; ALL_TAC] THEN
4113 REWRITE_TAC[REAL_MIN_LE; REAL_MIN_LT; IN_INSERT] THEN
4114 MP_TAC(ISPEC `s:real->bool` BOUNDED_HAS_INF) THEN ASM_REWRITE_TAC[] THEN
4115 REPEAT STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_REFL; REAL_NOT_LT]);;
4117 (* ------------------------------------------------------------------------- *)
4118 (* Subset and overlapping relations on balls. *)
4119 (* ------------------------------------------------------------------------- *)
4121 let SUBSET_BALLS = prove
4122 (`(!a a':real^N r r'.
4123 ball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r <= r' \/ r <= &0) /\
4125 ball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r <= &0) /\
4127 cball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r < r' \/ r < &0) /\
4129 cball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r < &0)`,
4132 cball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r < &0) /\
4134 cball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r < r' \/ r < &0)`,
4136 (GEOM_ORIGIN_TAC `a':real^N` THEN
4137 REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET; IN_CBALL; IN_BALL] THEN
4138 EQ_TAC THENL [REWRITE_TAC[DIST_0]; NORM_ARITH_TAC] THEN
4139 DISJ_CASES_TAC(REAL_ARITH `r < &0 \/ &0 <= r`) THEN
4140 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN DISJ1_TAC THEN
4141 ASM_CASES_TAC `a:real^N = vec 0` THENL
4142 [FIRST_X_ASSUM(MP_TAC o SPEC `r % basis 1:real^N`) THEN
4143 ASM_SIMP_TAC[DIST_0; NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL];
4144 FIRST_X_ASSUM(MP_TAC o SPEC `(&1 + r / norm(a)) % a:real^N`) THEN
4145 SIMP_TAC[dist; VECTOR_ARITH `a - (&1 + x) % a:real^N = --(x % a)`] THEN
4146 ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; NORM_NEG; REAL_POS;
4147 REAL_LE_DIV; NORM_POS_LE; REAL_ADD_RDISTRIB; REAL_DIV_RMUL;
4148 NORM_EQ_0; REAL_ARITH `&0 <= x ==> abs(&1 + x) = &1 + x`]] THEN
4149 UNDISCH_TAC `&0 <= r` THEN NORM_ARITH_TAC))
4150 and tac = DISCH_THEN(MP_TAC o MATCH_MP SUBSET_CLOSURE) THEN
4151 ASM_SIMP_TAC[CLOSED_CBALL; CLOSURE_CLOSED; CLOSURE_BALL] in
4152 REWRITE_TAC[AND_FORALL_THM] THEN GEOM_ORIGIN_TAC `a':real^N` THEN
4153 REPEAT STRIP_TAC THEN
4155 [ALL_TAC; REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL] THEN NORM_ARITH_TAC]) THEN
4156 MATCH_MP_TAC(SET_RULE
4157 `(s = {} <=> q) /\ (s SUBSET t /\ ~(s = {}) /\ ~(t = {}) ==> p)
4158 ==> s SUBSET t ==> p \/ q`) THEN
4159 REWRITE_TAC[BALL_EQ_EMPTY; CBALL_EQ_EMPTY; REAL_NOT_LE; REAL_NOT_LT] THEN
4160 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THENL
4161 [tac; tac; ALL_TAC; ALL_TAC] THEN REWRITE_TAC[lemma] THEN
4162 REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC);;
4164 let INTER_BALLS_EQ_EMPTY = prove
4165 (`(!a b:real^N r s. ball(a,r) INTER ball(b,s) = {} <=>
4166 r <= &0 \/ s <= &0 \/ r + s <= dist(a,b)) /\
4167 (!a b:real^N r s. ball(a,r) INTER cball(b,s) = {} <=>
4168 r <= &0 \/ s < &0 \/ r + s <= dist(a,b)) /\
4169 (!a b:real^N r s. cball(a,r) INTER ball(b,s) = {} <=>
4170 r < &0 \/ s <= &0 \/ r + s <= dist(a,b)) /\
4171 (!a b:real^N r s. cball(a,r) INTER cball(b,s) = {} <=>
4172 r < &0 \/ s < &0 \/ r + s < dist(a,b))`,
4173 REPEAT STRIP_TAC THEN GEOM_ORIGIN_TAC `a:real^N` THEN
4174 GEOM_BASIS_MULTIPLE_TAC 1 `b:real^N` THEN REPEAT STRIP_TAC THEN
4175 REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_INTER; IN_CBALL; IN_BALL] THEN
4178 SPEC_TAC(`b % basis 1:real^N`,`v:real^N`) THEN CONV_TAC NORM_ARITH]) THEN
4179 DISCH_THEN(MP_TAC o GEN `c:real` o SPEC `c % basis 1:real^N`) THEN
4180 SIMP_TAC[NORM_MUL; NORM_BASIS; LE_REFL; DIMINDEX_GE_1; dist; NORM_NEG;
4181 VECTOR_SUB_LZERO; GSYM VECTOR_SUB_RDISTRIB; REAL_MUL_RID] THEN
4182 ASM_REWRITE_TAC[real_abs] THEN REWRITE_TAC[GSYM real_abs] THEN
4183 DISCH_THEN(fun th ->
4184 MP_TAC(SPEC `min b r:real` th) THEN
4185 MP_TAC(SPEC `max (&0) (b - s:real)` th) THEN
4186 MP_TAC(SPEC `(r + (b - s)) / &2` th)) THEN
4187 ASM_REAL_ARITH_TAC);;
4189 (* ------------------------------------------------------------------------- *)
4190 (* Every closed set is a G_Delta. *)
4191 (* ------------------------------------------------------------------------- *)
4193 let CLOSED_AS_GDELTA = prove
4196 ==> ?g. COUNTABLE g /\
4197 (!u. u IN g ==> open u) /\
4199 REPEAT STRIP_TAC THEN EXISTS_TAC
4200 `{ UNIONS { ball(x:real^N,inv(&n + &1)) | x IN s} | n IN (:num)}` THEN
4201 SIMP_TAC[SIMPLE_IMAGE; COUNTABLE_IMAGE; NUM_COUNTABLE] THEN
4202 SIMP_TAC[FORALL_IN_IMAGE; OPEN_UNIONS; OPEN_BALL] THEN
4203 MATCH_MP_TAC(SET_RULE
4204 `closure s = s /\ s SUBSET t /\ t SUBSET closure s
4206 ASM_REWRITE_TAC[CLOSURE_EQ] THEN CONJ_TAC THENL
4207 [REWRITE_TAC[SUBSET_INTERS; FORALL_IN_IMAGE; IN_UNIV] THEN
4208 X_GEN_TAC `n:num` THEN REWRITE_TAC[UNIONS_IMAGE; SUBSET; IN_ELIM_THM] THEN
4209 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN EXISTS_TAC `x:real^N` THEN
4210 ASM_REWRITE_TAC[CENTRE_IN_BALL; REAL_LT_INV_EQ] THEN REAL_ARITH_TAC;
4211 REWRITE_TAC[SUBSET; CLOSURE_APPROACHABLE; INTERS_IMAGE; IN_UNIV] THEN
4212 X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_ELIM_THM; UNIONS_IMAGE] THEN
4213 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
4214 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN
4215 DISCH_THEN(X_CHOOSE_THEN `n:num` STRIP_ASSUME_TAC) THEN
4216 FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN REWRITE_TAC[IN_BALL] THEN
4217 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN
4218 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
4219 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LT_TRANS) THEN
4220 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
4221 REAL_LT_TRANS)) THEN
4222 MATCH_MP_TAC REAL_LT_INV2 THEN
4223 REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LT] THEN ASM_ARITH_TAC]);;
4225 (* ------------------------------------------------------------------------- *)
4226 (* Compactness (the definition is the one based on convegent subsequences). *)
4227 (* ------------------------------------------------------------------------- *)
4229 let compact = new_definition
4233 ==> ?l r. l IN s /\ (!m n:num. m < n ==> r(m) < r(n)) /\
4234 ((f o r) --> l) sequentially`;;
4236 let MONOTONE_BIGGER = prove
4237 (`!r. (!m n. m < n ==> r(m) < r(n)) ==> !n:num. n <= r(n)`,
4238 GEN_TAC THEN DISCH_TAC THEN INDUCT_TAC THEN
4239 ASM_MESON_TAC[LE_0; ARITH_RULE `n <= m /\ m < p ==> SUC n <= p`; LT]);;
4241 let LIM_SUBSEQUENCE = prove
4242 (`!s r l. (!m n. m < n ==> r(m) < r(n)) /\ (s --> l) sequentially
4243 ==> (s o r --> l) sequentially`,
4244 REWRITE_TAC[LIM_SEQUENTIALLY; o_THM] THEN
4245 MESON_TAC[MONOTONE_BIGGER; LE_TRANS]);;
4247 let MONOTONE_SUBSEQUENCE = prove
4248 (`!s:num->real. ?r:num->num.
4249 (!m n. m < n ==> r(m) < r(n)) /\
4250 ((!m n. m <= n ==> s(r(m)) <= s(r(n))) \/
4251 (!m n. m <= n ==> s(r(n)) <= s(r(m))))`,
4253 ASM_CASES_TAC `!n:num. ?p. n < p /\ !m. p <= m ==> s(m) <= s(p)` THEN
4254 POP_ASSUM MP_TAC THEN
4255 REWRITE_TAC[NOT_FORALL_THM; NOT_EXISTS_THM; NOT_IMP; DE_MORGAN_THM] THEN
4256 REWRITE_TAC[RIGHT_OR_EXISTS_THM; SKOLEM_THM; REAL_NOT_LE; REAL_NOT_LT] THENL
4257 [ABBREV_TAC `N = 0`; DISCH_THEN(X_CHOOSE_THEN `N:num` MP_TAC)] THEN
4258 DISCH_THEN(X_CHOOSE_THEN `next:num->num` STRIP_ASSUME_TAC) THEN
4259 (MP_TAC o prove_recursive_functions_exist num_RECURSION)
4260 `(r 0 = next(SUC N)) /\ (!n. r(SUC n) = next(r n))` THEN
4261 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN STRIP_TAC THENL
4262 [SUBGOAL_THEN `!m:num n:num. r n <= m ==> s(m) <= s(r n):real`
4263 ASSUME_TAC THEN TRY CONJ_TAC THEN TRY DISJ2_TAC THEN
4264 GEN_TAC THEN INDUCT_TAC THEN ASM_REWRITE_TAC[LT; LE] THEN
4265 ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL; LT_IMP_LE; LT_TRANS];
4266 SUBGOAL_THEN `!n. N < (r:num->num) n` ASSUME_TAC THEN
4267 TRY(CONJ_TAC THENL [GEN_TAC; DISJ1_TAC THEN GEN_TAC]) THEN
4268 INDUCT_TAC THEN ASM_REWRITE_TAC[LT; LE] THEN
4269 TRY STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4270 ASM_MESON_TAC[REAL_LT_REFL; LT_LE; LTE_TRANS; REAL_LE_REFL;
4271 REAL_LT_LE; REAL_LE_TRANS; LT]]);;
4273 let CONVERGENT_BOUNDED_INCREASING = prove
4274 (`!s:num->real b. (!m n. m <= n ==> s m <= s n) /\ (!n. abs(s n) <= b)
4275 ==> ?l. !e. &0 < e ==> ?N. !n. N <= n ==> abs(s n - l) < e`,
4276 REPEAT STRIP_TAC THEN
4277 MP_TAC(SPEC `\x. ?n. (s:num->real) n = x` REAL_COMPLETE) THEN
4278 REWRITE_TAC[] THEN ANTS_TAC THENL
4279 [ASM_MESON_TAC[REAL_ARITH `abs(x) <= b ==> x <= b`]; ALL_TAC] THEN
4280 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real` THEN STRIP_TAC THEN
4281 X_GEN_TAC `e:real` THEN STRIP_TAC THEN
4282 FIRST_X_ASSUM(MP_TAC o SPEC `l - e`) THEN
4283 ASM_MESON_TAC[REAL_ARITH `&0 < e ==> ~(l <= l - e)`;
4284 REAL_ARITH `x <= y /\ y <= l /\ ~(x <= l - e) ==> abs(y - l) < e`]);;
4286 let CONVERGENT_BOUNDED_MONOTONE = prove
4287 (`!s:num->real b. (!n. abs(s n) <= b) /\
4288 ((!m n. m <= n ==> s m <= s n) \/
4289 (!m n. m <= n ==> s n <= s m))
4290 ==> ?l. !e. &0 < e ==> ?N. !n. N <= n ==> abs(s n - l) < e`,
4291 REPEAT STRIP_TAC THENL
4292 [ASM_MESON_TAC[CONVERGENT_BOUNDED_INCREASING]; ALL_TAC] THEN
4293 MP_TAC(SPEC `\n. --((s:num->real) n)` CONVERGENT_BOUNDED_INCREASING) THEN
4294 ASM_REWRITE_TAC[REAL_LE_NEG2; REAL_ABS_NEG] THEN
4295 ASM_MESON_TAC[REAL_ARITH `abs(x - --l) = abs(--x - l)`]);;
4297 let COMPACT_REAL_LEMMA = prove
4298 (`!s b. (!n:num. abs(s n) <= b)
4299 ==> ?l r. (!m n:num. m < n ==> r(m) < r(n)) /\
4300 !e. &0 < e ==> ?N. !n. N <= n ==> abs(s(r n) - l) < e`,
4301 REPEAT GEN_TAC THEN DISCH_TAC THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
4302 MP_TAC(SPEC `s:num->real` MONOTONE_SUBSEQUENCE) THEN
4303 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN DISCH_TAC THEN ASM_SIMP_TAC[] THEN
4304 MATCH_MP_TAC CONVERGENT_BOUNDED_MONOTONE THEN ASM_MESON_TAC[]);;
4306 let COMPACT_LEMMA = prove
4307 (`!s. bounded s /\ (!n. (x:num->real^N) n IN s)
4308 ==> !d. d <= dimindex(:N)
4309 ==> ?l:real^N r. (!m n. m < n ==> r m < (r:num->num) n) /\
4311 ==> ?N. !n i. 1 <= i /\ i <= d
4313 ==> abs(x(r n)$i - l$i) < e`,
4314 GEN_TAC THEN REWRITE_TAC[bounded] THEN
4315 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `b:real`) ASSUME_TAC) THEN
4317 [REWRITE_TAC[ARITH_RULE `1 <= i /\ i <= 0 <=> F`; CONJ_ASSOC] THEN
4318 DISCH_TAC THEN EXISTS_TAC `\n:num. n` THEN REWRITE_TAC[];
4320 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN
4321 ASM_SIMP_TAC[ARITH_RULE `SUC d <= n ==> d <= n`] THEN STRIP_TAC THEN
4322 MP_TAC(SPECL [`\n:num. (x:num->real^N) (r n) $ (SUC d)`; `b:real`]
4323 COMPACT_REAL_LEMMA) THEN
4324 REWRITE_TAC[] THEN ANTS_TAC THENL
4325 [ASM_MESON_TAC[REAL_LE_TRANS; COMPONENT_LE_NORM; ARITH_RULE `1 <= SUC n`];
4327 DISCH_THEN(X_CHOOSE_THEN `y:real` (X_CHOOSE_THEN `s:num->num`
4328 STRIP_ASSUME_TAC)) THEN
4329 MAP_EVERY EXISTS_TAC
4330 [`(lambda k. if k = SUC d then y else (l:real^N)$k):real^N`;
4331 `(r:num->num) o (s:num->num)`] THEN
4332 ASM_SIMP_TAC[o_THM] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
4333 REPEAT(FIRST_ASSUM(C UNDISCH_THEN (MP_TAC o SPEC `e:real`) o concl)) THEN
4334 ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_TAC `N1:num`) THEN
4335 DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN EXISTS_TAC `N1 + N2:num` THEN
4336 FIRST_ASSUM(fun th -> SIMP_TAC[LAMBDA_BETA; MATCH_MP(ARITH_RULE
4337 `SUC d <= n ==> !i. 1 <= i /\ i <= SUC d ==> 1 <= i /\ i <= n`) th]) THEN
4338 REWRITE_TAC[LE] THEN REPEAT STRIP_TAC THEN
4339 ASM_REWRITE_TAC[] THEN TRY COND_CASES_TAC THEN
4340 ASM_MESON_TAC[MONOTONE_BIGGER; LE_TRANS;
4341 ARITH_RULE `N1 + N2 <= n ==> N2 <= n:num /\ N1 <= n`;
4342 ARITH_RULE `1 <= i /\ i <= d /\ SUC d <= n
4343 ==> ~(i = SUC d) /\ 1 <= SUC d /\ d <= n /\ i <= n`]);;
4345 let BOUNDED_CLOSED_IMP_COMPACT = prove
4346 (`!s:real^N->bool. bounded s /\ closed s ==> compact s`,
4347 REPEAT STRIP_TAC THEN REWRITE_TAC[compact] THEN
4348 X_GEN_TAC `x:num->real^N` THEN DISCH_TAC THEN
4349 MP_TAC(ISPEC `s:real^N->bool` COMPACT_LEMMA) THEN
4350 ASM_REWRITE_TAC[] THEN
4351 DISCH_THEN(MP_TAC o SPEC `dimindex(:N)`) THEN
4352 REWRITE_TAC[LE_REFL] THEN
4353 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real^N` THEN
4354 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `r:num->num` THEN ASM_SIMP_TAC[] THEN
4355 STRIP_TAC THEN MATCH_MP_TAC(TAUT `(b ==> a) /\ b ==> a /\ b`) THEN
4356 REPEAT STRIP_TAC THENL
4357 [FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CLOSED_SEQUENTIAL_LIMITS]) THEN
4358 EXISTS_TAC `(x:num->real^N) o (r:num->num)` THEN
4359 ASM_REWRITE_TAC[o_THM];
4361 REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
4362 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2 / &(dimindex(:N))`) THEN
4363 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; DIMINDEX_NONZERO;
4364 REAL_HALF; ARITH_RULE `0 < n <=> ~(n = 0)`] THEN
4365 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
4366 REWRITE_TAC[dist] THEN REPEAT STRIP_TAC THEN
4367 MATCH_MP_TAC(MATCH_MP (REAL_ARITH `a <= b ==> b < e ==> a < e`)
4368 (SPEC_ALL NORM_LE_L1)) THEN
4369 MATCH_MP_TAC REAL_LET_TRANS THEN
4370 EXISTS_TAC `sum (1..dimindex(:N))
4371 (\k. e / &2 / &(dimindex(:N)))` THEN
4373 [MATCH_MP_TAC SUM_LE_NUMSEG THEN
4374 SIMP_TAC[o_THM; LAMBDA_BETA; vector_sub] THEN
4375 ASM_MESON_TAC[REAL_LT_IMP_LE; LE_TRANS];
4376 ASM_SIMP_TAC[SUM_CONST_NUMSEG; ADD_SUB; REAL_DIV_LMUL; REAL_OF_NUM_EQ;
4377 DIMINDEX_NONZERO; REAL_LE_REFL; REAL_LT_LDIV_EQ; ARITH;
4378 REAL_OF_NUM_LT; REAL_ARITH `x < x * &2 <=> &0 < x`]]);;
4380 (* ------------------------------------------------------------------------- *)
4382 (* ------------------------------------------------------------------------- *)
4384 let cauchy = new_definition
4385 `cauchy (s:num->real^N) <=>
4386 !e. &0 < e ==> ?N. !m n. m >= N /\ n >= N ==> dist(s m,s n) < e`;;
4388 let complete = new_definition
4390 !f:num->real^N. (!n. f n IN s) /\ cauchy f
4391 ==> ?l. l IN s /\ (f --> l) sequentially`;;
4395 cauchy s <=> !e. &0 < e ==> ?N. !n. n >= N ==> dist(s n,s N) < e`,
4396 REPEAT GEN_TAC THEN REWRITE_TAC[cauchy; GE] THEN EQ_TAC THENL
4397 [MESON_TAC[LE_REFL]; DISCH_TAC] THEN
4398 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
4399 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
4400 MESON_TAC[DIST_TRIANGLE_HALF_L]);;
4402 let CONVERGENT_IMP_CAUCHY = prove
4403 (`!s l. (s --> l) sequentially ==> cauchy s`,
4404 REWRITE_TAC[LIM_SEQUENTIALLY; cauchy] THEN
4405 REPEAT GEN_TAC THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
4406 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
4407 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
4408 ASM_MESON_TAC[GE; LE_REFL; DIST_TRIANGLE_HALF_L]);;
4410 let CAUCHY_IMP_BOUNDED = prove
4411 (`!s:num->real^N. cauchy s ==> bounded {y | ?n. y = s n}`,
4412 REWRITE_TAC[cauchy; bounded; IN_ELIM_THM] THEN GEN_TAC THEN
4413 DISCH_THEN(MP_TAC o SPEC `&1`) THEN REWRITE_TAC[REAL_LT_01] THEN
4414 DISCH_THEN(X_CHOOSE_THEN `N:num` (MP_TAC o SPEC `N:num`)) THEN
4415 REWRITE_TAC[GE_REFL] THEN DISCH_TAC THEN
4416 SUBGOAL_THEN `!n:num. N <= n ==> norm(s n :real^N) <= norm(s N) + &1`
4418 [ASM_MESON_TAC[GE; dist; DIST_SYM; NORM_TRIANGLE_SUB;
4419 REAL_ARITH `a <= b + c /\ c < &1 ==> a <= b + &1`];
4420 MP_TAC(ISPECL [`\n:num. norm(s n :real^N)`; `0..N`]
4421 UPPER_BOUND_FINITE_SET_REAL) THEN
4422 SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; LE_0; LEFT_IMP_EXISTS_THM] THEN
4423 ASM_MESON_TAC[LE_CASES;
4424 REAL_ARITH `x <= a \/ x <= b ==> x <= abs a + abs b`]]);;
4426 let COMPACT_IMP_COMPLETE = prove
4427 (`!s:real^N->bool. compact s ==> complete s`,
4428 GEN_TAC THEN REWRITE_TAC[complete; compact] THEN
4429 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `f:num->real^N` THEN
4430 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
4431 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
4432 DISCH_THEN(X_CHOOSE_THEN `r:num->num` STRIP_ASSUME_TAC) THEN
4433 FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] LIM_ADD)) THEN
4434 DISCH_THEN(MP_TAC o SPEC `\n. (f:num->real^N)(n) - f(r n)`) THEN
4435 DISCH_THEN(MP_TAC o SPEC `vec 0: real^N`) THEN ASM_REWRITE_TAC[o_THM] THEN
4436 REWRITE_TAC[VECTOR_ADD_RID; VECTOR_SUB_ADD2; ETA_AX] THEN
4437 DISCH_THEN MATCH_MP_TAC THEN
4438 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [cauchy]) THEN
4439 REWRITE_TAC[GE; LIM; SEQUENTIALLY; dist; VECTOR_SUB_RZERO] THEN
4440 SUBGOAL_THEN `!n:num. n <= r(n)` MP_TAC THENL [INDUCT_TAC; ALL_TAC] THEN
4441 ASM_MESON_TAC[ LE_TRANS; LE_REFL; LT; LET_TRANS; LE_0; LE_SUC_LT]);;
4443 let COMPLETE_UNIV = prove
4444 (`complete(:real^N)`,
4445 REWRITE_TAC[complete; IN_UNIV] THEN X_GEN_TAC `x:num->real^N` THEN
4446 DISCH_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_IMP_BOUNDED) THEN
4447 DISCH_THEN(ASSUME_TAC o MATCH_MP BOUNDED_CLOSURE) THEN
4448 MP_TAC(ISPEC `closure {y:real^N | ?n:num. y = x n}`
4449 COMPACT_IMP_COMPLETE) THEN
4450 ASM_SIMP_TAC[BOUNDED_CLOSED_IMP_COMPACT; CLOSED_CLOSURE; complete] THEN
4451 DISCH_THEN(MP_TAC o SPEC `x:num->real^N`) THEN
4452 ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
4453 ASM_REWRITE_TAC[closure; IN_ELIM_THM; IN_UNION] THEN MESON_TAC[]);;
4455 let COMPLETE_EQ_CLOSED = prove
4456 (`!s:real^N->bool. complete s <=> closed s`,
4457 GEN_TAC THEN EQ_TAC THENL
4458 [REWRITE_TAC[complete; CLOSED_LIMPT; LIMPT_SEQUENTIAL] THEN
4459 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN GEN_TAC THEN
4460 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN MATCH_MP_TAC MONO_FORALL THEN
4461 MESON_TAC[CONVERGENT_IMP_CAUCHY; IN_DELETE; LIM_UNIQUE;
4462 TRIVIAL_LIMIT_SEQUENTIALLY];
4463 REWRITE_TAC[complete; CLOSED_SEQUENTIAL_LIMITS] THEN DISCH_TAC THEN
4464 X_GEN_TAC `f:num->real^N` THEN STRIP_TAC THEN
4465 MP_TAC(REWRITE_RULE[complete] COMPLETE_UNIV) THEN
4466 DISCH_THEN(MP_TAC o SPEC `f:num->real^N`) THEN
4467 ASM_REWRITE_TAC[IN_UNIV] THEN ASM_MESON_TAC[]]);;
4469 let CONVERGENT_EQ_CAUCHY = prove
4470 (`!s. (?l. (s --> l) sequentially) <=> cauchy s`,
4471 GEN_TAC THEN EQ_TAC THENL
4472 [REWRITE_TAC[LEFT_IMP_EXISTS_THM; CONVERGENT_IMP_CAUCHY];
4473 REWRITE_TAC[REWRITE_RULE[complete; IN_UNIV] COMPLETE_UNIV]]);;
4475 let CONVERGENT_IMP_BOUNDED = prove
4476 (`!s l. (s --> l) sequentially ==> bounded (IMAGE s (:num))`,
4477 REWRITE_TAC[LEFT_FORALL_IMP_THM; CONVERGENT_EQ_CAUCHY] THEN
4478 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CAUCHY_IMP_BOUNDED) THEN
4479 REWRITE_TAC[IMAGE; IN_UNIV]);;
4481 (* ------------------------------------------------------------------------- *)
4482 (* Total boundedness. *)
4483 (* ------------------------------------------------------------------------- *)
4485 let COMPACT_IMP_TOTALLY_BOUNDED = prove
4488 ==> !e. &0 < e ==> ?k. FINITE k /\ k SUBSET s /\
4489 s SUBSET (UNIONS(IMAGE (\x. ball(x,e)) k))`,
4490 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
4491 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN
4492 REWRITE_TAC[TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`; SUBSET] THEN
4493 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
4495 `?x:num->real^N. !n. x(n) IN s /\ !m. m < n ==> ~(dist(x(m),x(n)) < e)`
4499 !n. x(n) = @y. y IN s /\ !m. m < n ==> ~(dist(x(m),y) < e)`
4501 [MATCH_MP_TAC(MATCH_MP WF_REC WF_num) THEN SIMP_TAC[]; ALL_TAC] THEN
4502 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:num->real^N` THEN
4503 DISCH_TAC THEN MATCH_MP_TAC num_WF THEN X_GEN_TAC `n:num` THEN
4504 FIRST_X_ASSUM(SUBST1_TAC o SPEC `n:num`) THEN STRIP_TAC THEN
4505 CONV_TAC SELECT_CONV THEN
4506 FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (x:num->real^N) {m | m < n}`) THEN
4507 SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG_LT; NOT_FORALL_THM; NOT_IMP] THEN
4508 REWRITE_TAC[IN_UNIONS; IN_IMAGE; IN_ELIM_THM] THEN ASM_MESON_TAC[IN_BALL];
4510 REWRITE_TAC[compact; NOT_FORALL_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
4511 X_GEN_TAC `x:num->real^N` THEN REWRITE_TAC[NOT_IMP; FORALL_AND_THM] THEN
4512 STRIP_TAC THEN ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN REPEAT STRIP_TAC THEN
4513 FIRST_X_ASSUM(MP_TAC o MATCH_MP CONVERGENT_IMP_CAUCHY) THEN
4514 REWRITE_TAC[cauchy] THEN DISCH_THEN(MP_TAC o SPEC `e:real`) THEN
4515 ASM_REWRITE_TAC[o_THM; NOT_EXISTS_THM; NOT_IMP; NOT_FORALL_THM; NOT_IMP] THEN
4516 X_GEN_TAC `N:num` THEN MAP_EVERY EXISTS_TAC [`N:num`; `SUC N`] THEN
4517 CONJ_TAC THENL [ARITH_TAC; ASM_MESON_TAC[LT]]);;
4519 (* ------------------------------------------------------------------------- *)
4520 (* Heine-Borel theorem (following Burkill & Burkill vol. 2) *)
4521 (* ------------------------------------------------------------------------- *)
4523 let HEINE_BOREL_LEMMA = prove
4526 ==> !t. s SUBSET (UNIONS t) /\ (!b. b IN t ==> open b)
4528 !x. x IN s ==> ?b. b IN t /\ ball(x,e) SUBSET b`,
4529 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
4530 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN
4531 DISCH_THEN(CHOOSE_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
4532 DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `&1 / (&n + &1)`) THEN
4533 SIMP_TAC[REAL_LT_DIV; REAL_LT_01; REAL_ARITH `x <= y ==> x < y + &1`;
4534 FORALL_AND_THM; REAL_POS; NOT_FORALL_THM; NOT_IMP; SKOLEM_THM; compact] THEN
4535 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN REWRITE_TAC[NOT_EXISTS_THM] THEN
4536 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
4537 DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`l:real^N`; `r:num->num`] THEN
4539 SUBGOAL_THEN `?b:real^N->bool. l IN b /\ b IN t` STRIP_ASSUME_TAC THENL
4540 [ASM_MESON_TAC[SUBSET; IN_UNIONS]; ALL_TAC] THEN
4541 SUBGOAL_THEN `?e. &0 < e /\ !z:real^N. dist(z,l) < e ==> z IN b`
4542 STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[open_def]; ALL_TAC] THEN
4543 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
4544 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
4545 SUBGOAL_THEN `&0 < e / &2` (fun th ->
4546 REWRITE_TAC[th; o_THM] THEN MP_TAC(GEN_REWRITE_RULE I [REAL_ARCH_INV] th))
4547 THENL [ASM_REWRITE_TAC[REAL_HALF]; ALL_TAC] THEN
4548 DISCH_THEN(X_CHOOSE_THEN `N1:num` STRIP_ASSUME_TAC) THEN
4549 DISCH_THEN(X_CHOOSE_THEN `N2:num` STRIP_ASSUME_TAC) THEN
4550 FIRST_X_ASSUM(MP_TAC o SPECL
4551 [`(r:num->num)(N1 + N2)`; `b:real^N->bool`]) THEN
4552 ASM_REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
4553 FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC DIST_TRIANGLE_HALF_R THEN
4554 EXISTS_TAC `(f:num->real^N)(r(N1 + N2:num))` THEN CONJ_TAC THENL
4555 [ALL_TAC; FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC] THEN
4556 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN
4557 MATCH_MP_TAC(REAL_ARITH `a <= b ==> x < a ==> x < b`) THEN
4558 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `inv(&N1)` THEN
4559 ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN REWRITE_TAC[real_div; REAL_MUL_LID] THEN
4560 MATCH_MP_TAC REAL_LE_INV2 THEN
4561 REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
4562 ASM_MESON_TAC[ARITH_RULE `(~(n = 0) ==> 0 < n)`; LE_ADD; MONOTONE_BIGGER;
4563 LT_IMP_LE; LE_TRANS]);;
4565 let COMPACT_IMP_HEINE_BOREL = prove
4566 (`!s. compact (s:real^N->bool)
4567 ==> !f. (!t. t IN f ==> open t) /\ s SUBSET (UNIONS f)
4568 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (UNIONS f')`,
4569 REPEAT STRIP_TAC THEN
4570 FIRST_ASSUM(MP_TAC o SPEC `f:(real^N->bool)->bool` o
4571 MATCH_MP HEINE_BOREL_LEMMA) THEN ASM_REWRITE_TAC[] THEN
4572 DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
4573 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
4574 REWRITE_TAC[SKOLEM_THM; SUBSET; IN_BALL] THEN
4575 DISCH_THEN(X_CHOOSE_TAC `B:real^N->real^N->bool`) THEN
4576 FIRST_ASSUM(MP_TAC o SPEC `e:real` o
4577 MATCH_MP COMPACT_IMP_TOTALLY_BOUNDED) THEN
4578 ASM_REWRITE_TAC[UNIONS_IMAGE; SUBSET; IN_ELIM_THM] THEN
4579 REWRITE_TAC[IN_UNIONS; IN_BALL] THEN
4580 DISCH_THEN(X_CHOOSE_THEN `k:real^N->bool` STRIP_ASSUME_TAC) THEN
4581 EXISTS_TAC `IMAGE (B:real^N->real^N->bool) k` THEN
4582 ASM_SIMP_TAC[FINITE_IMAGE; SUBSET; IN_IMAGE; LEFT_IMP_EXISTS_THM] THEN
4583 ASM_MESON_TAC[IN_BALL]);;
4585 (* ------------------------------------------------------------------------- *)
4586 (* Bolzano-Weierstrass property. *)
4587 (* ------------------------------------------------------------------------- *)
4589 let HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS = prove
4591 (!f. (!t. t IN f ==> open t) /\ s SUBSET (UNIONS f)
4592 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (UNIONS f'))
4593 ==> !t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t`,
4594 REWRITE_TAC[RIGHT_IMP_FORALL_THM; limit_point_of] THEN REPEAT GEN_TAC THEN
4595 ONCE_REWRITE_TAC[TAUT `a ==> b /\ c ==> d <=> c ==> ~d ==> a ==> ~b`] THEN
4596 REWRITE_TAC[NOT_FORALL_THM; NOT_EXISTS_THM; RIGHT_AND_FORALL_THM] THEN
4597 DISCH_TAC THEN REWRITE_TAC[SKOLEM_THM] THEN
4598 DISCH_THEN(X_CHOOSE_TAC `f:real^N->real^N->bool`) THEN
4599 DISCH_THEN(MP_TAC o SPEC
4600 `{t:real^N->bool | ?x:real^N. x IN s /\ (t = f x)}`) THEN
4601 REWRITE_TAC[INFINITE; SUBSET; IN_ELIM_THM; IN_UNIONS; NOT_IMP] THEN
4602 ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
4603 DISCH_THEN(X_CHOOSE_THEN `g:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
4604 MATCH_MP_TAC FINITE_SUBSET THEN
4605 EXISTS_TAC `{x:real^N | x IN t /\ (f(x):real^N->bool) IN g}` THEN
4607 [MATCH_MP_TAC FINITE_IMAGE_INJ_GENERAL THEN ASM_MESON_TAC[SUBSET];
4608 SIMP_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `u:real^N` THEN
4609 DISCH_TAC THEN SUBGOAL_THEN `(u:real^N) IN s` ASSUME_TAC THEN
4610 ASM_MESON_TAC[SUBSET]]);;
4612 (* ------------------------------------------------------------------------- *)
4613 (* Complete the chain of compactness variants. *)
4614 (* ------------------------------------------------------------------------- *)
4616 let BOLZANO_WEIERSTRASS_IMP_BOUNDED = prove
4618 (!t. INFINITE t /\ t SUBSET s ==> ?x. x limit_point_of t)
4620 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
4621 SIMP_TAC[compact; bounded] THEN
4622 REWRITE_TAC[NOT_FORALL_THM; NOT_EXISTS_THM; SKOLEM_THM; NOT_IMP] THEN
4623 REWRITE_TAC[REAL_NOT_LE] THEN
4624 DISCH_THEN(X_CHOOSE_TAC `beyond:real->real^N`) THEN
4625 (MP_TAC o prove_recursive_functions_exist num_RECURSION)
4626 `(f(0) = beyond(&0)) /\
4627 (!n. f(SUC n) = beyond(norm(f n) + &1):real^N)` THEN
4628 DISCH_THEN(X_CHOOSE_THEN `x:num->real^N` STRIP_ASSUME_TAC) THEN
4629 EXISTS_TAC `IMAGE (x:num->real^N) UNIV` THEN
4631 `!m n. m < n ==> norm((x:num->real^N) m) + &1 < norm(x n)`
4633 [GEN_TAC THEN INDUCT_TAC THEN ASM_REWRITE_TAC[LT] THEN
4634 ASM_MESON_TAC[REAL_LT_TRANS; REAL_ARITH `b < b + &1`];
4636 SUBGOAL_THEN `!m n. ~(m = n) ==> &1 < dist((x:num->real^N) m,x n)`
4638 [REPEAT GEN_TAC THEN REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC
4639 (SPECL [`m:num`; `n:num`] LT_CASES) THEN
4640 ASM_MESON_TAC[dist; LT_CASES; NORM_TRIANGLE_SUB; NORM_SUB;
4641 REAL_ARITH `x + &1 < y /\ y <= x + d ==> &1 < d`];
4643 REPEAT CONJ_TAC THENL
4644 [ASM_MESON_TAC[INFINITE_IMAGE_INJ; num_INFINITE; DIST_REFL;
4645 REAL_ARITH `~(&1 < &0)`];
4646 REWRITE_TAC[SUBSET; IN_IMAGE; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN
4647 GEN_TAC THEN INDUCT_TAC THEN ASM_MESON_TAC[];
4649 X_GEN_TAC `l:real^N` THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
4650 REWRITE_TAC[IN_IMAGE; IN_UNIV; LEFT_AND_EXISTS_THM] THEN
4651 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2] THEN
4652 STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC `&1 / &2`) THEN
4653 CONV_TAC REAL_RAT_REDUCE_CONV THEN
4654 DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN
4655 FIRST_X_ASSUM(MP_TAC o SPEC `dist((x:num->real^N) k,l)`) THEN
4656 ASM_SIMP_TAC[DIST_POS_LT] THEN
4657 DISCH_THEN(X_CHOOSE_THEN `m:num` STRIP_ASSUME_TAC) THEN
4658 ASM_CASES_TAC `m:num = k` THEN
4659 ASM_MESON_TAC[DIST_TRIANGLE_HALF_L; REAL_LT_TRANS; REAL_LT_REFL]);;
4661 let SEQUENCE_INFINITE_LEMMA = prove
4662 (`!f l. (!n. ~(f(n) = l)) /\ (f --> l) sequentially
4663 ==> INFINITE {y:real^N | ?n. y = f n}`,
4664 REWRITE_TAC[INFINITE] THEN REPEAT STRIP_TAC THEN MP_TAC(ISPEC
4665 `IMAGE (\y:real^N. dist(y,l)) {y | ?n:num. y = f n}` INF_FINITE) THEN
4666 ASM_SIMP_TAC[GSYM MEMBER_NOT_EMPTY; IN_IMAGE; FINITE_IMAGE; IN_ELIM_THM] THEN
4667 ASM_MESON_TAC[LIM_SEQUENTIALLY; LE_REFL; REAL_NOT_LE; DIST_POS_LT]);;
4669 let LIMPT_OF_SEQUENCE_SUBSEQUENCE = prove
4671 l limit_point_of (IMAGE f (:num))
4672 ==> ?r. (!m n. m < n ==> r(m) < r(n)) /\ ((f o r) --> l) sequentially`,
4673 REPEAT STRIP_TAC THEN
4674 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIMPT_APPROACHABLE]) THEN
4675 DISCH_THEN(MP_TAC o GEN `n:num` o SPEC
4676 `inf((inv(&n + &1)) INSERT
4677 IMAGE (\k. dist((f:num->real^N) k,l))
4678 {k | k IN 0..n /\ ~(f k = l)})`) THEN
4679 SIMP_TAC[REAL_LT_INF_FINITE; FINITE_INSERT; NOT_INSERT_EMPTY;
4680 FINITE_RESTRICT; FINITE_NUMSEG; FINITE_IMAGE] THEN
4681 REWRITE_TAC[FORALL_IN_INSERT; EXISTS_IN_IMAGE; FORALL_IN_IMAGE; IN_UNIV] THEN
4682 REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
4683 SIMP_TAC[FORALL_AND_THM; FORALL_IN_GSPEC; GSYM DIST_NZ; SKOLEM_THM] THEN
4684 DISCH_THEN(X_CHOOSE_THEN `nn:num->num` STRIP_ASSUME_TAC) THEN
4685 (MP_TAC o prove_recursive_functions_exist num_RECURSION)
4686 `r 0 = nn 0 /\ (!n. r (SUC n) = nn(r n))` THEN
4687 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `r:num->num` THEN
4689 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
4690 [MATCH_MP_TAC TRANSITIVE_STEPWISE_LT THEN REWRITE_TAC[LT_TRANS] THEN
4691 X_GEN_TAC `n:num` THEN ASM_REWRITE_TAC[] THEN
4692 FIRST_X_ASSUM(MP_TAC o SPECL
4693 [`(r:num->num) n`; `(nn:num->num)(r(n:num))`]) THEN
4694 ASM_REWRITE_TAC[IN_NUMSEG; LE_0; REAL_LT_REFL] THEN ARITH_TAC;
4695 DISCH_THEN(ASSUME_TAC o MATCH_MP MONOTONE_BIGGER)] THEN
4696 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
4697 X_GEN_TAC `e:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_ARCH_INV] THEN
4698 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
4699 MATCH_MP_TAC num_INDUCTION THEN ASM_REWRITE_TAC[CONJUNCT1 LE] THEN
4700 X_GEN_TAC `n:num` THEN DISCH_THEN(K ALL_TAC) THEN DISCH_TAC THEN
4701 ASM_REWRITE_TAC[o_THM] THEN MATCH_MP_TAC REAL_LT_TRANS THEN
4702 EXISTS_TAC `inv(&((r:num->num) n) + &1)` THEN ASM_REWRITE_TAC[] THEN
4703 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN
4704 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
4705 ASM_SIMP_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_LT; LE_1; REAL_OF_NUM_ADD] THEN
4706 MATCH_MP_TAC(ARITH_RULE `N <= SUC n /\ n <= r n ==> N <= r n + 1`) THEN
4707 ASM_REWRITE_TAC[]);;
4709 let SEQUENCE_UNIQUE_LIMPT = prove
4711 (f --> l) sequentially /\ l' limit_point_of {y | ?n. y = f n}
4713 REWRITE_TAC[SET_RULE `{y | ?n. y = f n} = IMAGE f (:num)`] THEN
4714 REPEAT STRIP_TAC THEN
4715 FIRST_X_ASSUM(MP_TAC o MATCH_MP LIMPT_OF_SEQUENCE_SUBSEQUENCE) THEN
4716 DISCH_THEN(X_CHOOSE_THEN `r:num->num` STRIP_ASSUME_TAC) THEN
4717 MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
4718 EXISTS_TAC `(f:num->real^N) o (r:num->num)` THEN
4719 ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; LIM_SUBSEQUENCE]);;
4721 let BOLZANO_WEIERSTRASS_IMP_CLOSED = prove
4723 (!t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t)
4725 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS] THEN
4726 MAP_EVERY X_GEN_TAC [`f:num->real^N`; `l:real^N`] THEN
4728 MAP_EVERY (MP_TAC o ISPECL [`f:num->real^N`; `l:real^N`])
4729 [SEQUENCE_UNIQUE_LIMPT; SEQUENCE_INFINITE_LEMMA] THEN
4731 `(~d ==> a /\ ~(b /\ c)) ==> (a ==> b) ==> c ==> d`) THEN
4732 DISCH_TAC THEN CONJ_TAC THENL [ASM_MESON_TAC[]; STRIP_TAC] THEN
4733 FIRST_X_ASSUM(MP_TAC o SPEC `{y:real^N | ?n:num. y = f n}`) THEN
4734 ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL
4735 [REWRITE_TAC[SUBSET; IN_ELIM_THM];
4736 ABBREV_TAC `t = {y:real^N | ?n:num. y = f n}`] THEN
4739 (* ------------------------------------------------------------------------- *)
4740 (* Hence express everything as an equivalence. *)
4741 (* ------------------------------------------------------------------------- *)
4743 let COMPACT_EQ_HEINE_BOREL = prove
4746 !f. (!t. t IN f ==> open t) /\ s SUBSET (UNIONS f)
4747 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (UNIONS f')`,
4748 GEN_TAC THEN EQ_TAC THEN SIMP_TAC[COMPACT_IMP_HEINE_BOREL] THEN
4749 DISCH_THEN(MP_TAC o MATCH_MP HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS) THEN
4750 DISCH_TAC THEN MATCH_MP_TAC BOUNDED_CLOSED_IMP_COMPACT THEN
4751 ASM_MESON_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED;
4752 BOLZANO_WEIERSTRASS_IMP_CLOSED]);;
4754 let COMPACT_EQ_BOLZANO_WEIERSTRASS = prove
4757 !t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t`,
4758 GEN_TAC THEN EQ_TAC THENL
4759 [SIMP_TAC[COMPACT_EQ_HEINE_BOREL; HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS];
4760 MESON_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED; BOLZANO_WEIERSTRASS_IMP_CLOSED;
4761 BOUNDED_CLOSED_IMP_COMPACT]]);;
4763 let COMPACT_EQ_BOUNDED_CLOSED = prove
4764 (`!s:real^N->bool. compact s <=> bounded s /\ closed s`,
4765 GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_CLOSED_IMP_COMPACT] THEN
4766 MESON_TAC[COMPACT_EQ_BOLZANO_WEIERSTRASS; BOLZANO_WEIERSTRASS_IMP_BOUNDED;
4767 BOLZANO_WEIERSTRASS_IMP_CLOSED]);;
4769 let COMPACT_IMP_BOUNDED = prove
4770 (`!s. compact s ==> bounded s`,
4771 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED]);;
4773 let COMPACT_IMP_CLOSED = prove
4774 (`!s. compact s ==> closed s`,
4775 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED]);;
4777 let COMPACT_SEQUENCE_WITH_LIMIT = prove
4779 (f --> l) sequentially ==> compact (l INSERT IMAGE f (:num))`,
4780 REPEAT STRIP_TAC THEN REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
4781 REWRITE_TAC[BOUNDED_INSERT] THEN CONJ_TAC THENL
4782 [ASM_MESON_TAC[CONVERGENT_IMP_BOUNDED];
4783 SIMP_TAC[CLOSED_LIMPT; LIMPT_INSERT; IN_INSERT] THEN
4784 REWRITE_TAC[IMAGE; IN_UNIV] THEN REPEAT STRIP_TAC THEN DISJ1_TAC THEN
4785 MATCH_MP_TAC SEQUENCE_UNIQUE_LIMPT THEN ASM_MESON_TAC[]]);;
4787 let CLOSED_IN_COMPACT = prove
4788 (`!s t:real^N->bool.
4789 compact s /\ closed_in (subtopology euclidean s) t
4791 SIMP_TAC[IMP_CONJ; COMPACT_EQ_BOUNDED_CLOSED; CLOSED_IN_CLOSED_EQ] THEN
4792 MESON_TAC[BOUNDED_SUBSET]);;
4794 let CLOSED_IN_COMPACT_EQ = prove
4796 ==> (closed_in (subtopology euclidean s) t <=>
4797 compact t /\ t SUBSET s)`,
4798 MESON_TAC[CLOSED_IN_CLOSED_EQ; COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_SUBSET]);;
4800 (* ------------------------------------------------------------------------- *)
4801 (* A version of Heine-Borel for subtopology. *)
4802 (* ------------------------------------------------------------------------- *)
4804 let COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY = prove
4807 (!f. (!t. t IN f ==> open_in(subtopology euclidean s) t) /\
4809 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET UNIONS f')`,
4810 GEN_TAC THEN REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN EQ_TAC THEN
4811 DISCH_TAC THEN X_GEN_TAC `f:(real^N->bool)->bool` THENL
4812 [REWRITE_TAC[OPEN_IN_OPEN] THEN
4813 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
4814 REWRITE_TAC[SKOLEM_THM] THEN
4815 DISCH_THEN(CONJUNCTS_THEN2
4816 (X_CHOOSE_TAC `m:(real^N->bool)->(real^N->bool)`) ASSUME_TAC) THEN
4817 FIRST_X_ASSUM(MP_TAC o SPEC
4818 `IMAGE (m:(real^N->bool)->(real^N->bool)) f`) THEN
4819 ASM_SIMP_TAC[FORALL_IN_IMAGE] THEN
4820 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4821 DISCH_THEN(X_CHOOSE_THEN `f':(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
4822 EXISTS_TAC `IMAGE (\t:real^N->bool. s INTER t) f'` THEN
4823 ASM_SIMP_TAC[FINITE_IMAGE; UNIONS_IMAGE; SUBSET; FORALL_IN_IMAGE] THEN
4824 CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
4825 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET_IMAGE]) THEN
4826 STRIP_TAC THEN ASM_REWRITE_TAC[FORALL_IN_IMAGE] THEN ASM_MESON_TAC[SUBSET];
4828 FIRST_X_ASSUM(MP_TAC o SPEC `{s INTER t:real^N->bool | t IN f}`) THEN
4829 REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; OPEN_IN_OPEN; UNIONS_IMAGE] THEN
4830 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4831 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN
4832 REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE; UNIONS_IMAGE] THEN
4833 MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]]);;
4835 (* ------------------------------------------------------------------------- *)
4836 (* More easy lemmas. *)
4837 (* ------------------------------------------------------------------------- *)
4839 let COMPACT_CLOSURE = prove
4840 (`!s. compact(closure s) <=> bounded s`,
4841 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_CLOSURE; BOUNDED_CLOSURE_EQ]);;
4843 let BOLZANO_WEIERSTRASS_CONTRAPOS = prove
4844 (`!s t:real^N->bool.
4845 compact s /\ t SUBSET s /\
4846 (!x. x IN s ==> ~(x limit_point_of t))
4848 REWRITE_TAC[COMPACT_EQ_BOLZANO_WEIERSTRASS; INFINITE] THEN MESON_TAC[]);;
4850 let DISCRETE_BOUNDED_IMP_FINITE = prove
4851 (`!s:real^N->bool e.
4853 (!x y. x IN s /\ y IN s /\ norm(y - x) < e ==> y = x) /\
4856 REPEAT STRIP_TAC THEN
4857 SUBGOAL_THEN `compact(s:real^N->bool)` MP_TAC THENL
4858 [ASM_REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
4859 ASM_MESON_TAC[DISCRETE_IMP_CLOSED];
4860 DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_HEINE_BOREL)] THEN
4861 DISCH_THEN(MP_TAC o SPEC `IMAGE (\x:real^N. ball(x,e)) s`) THEN
4862 REWRITE_TAC[FORALL_IN_IMAGE; OPEN_BALL; UNIONS_IMAGE; IN_ELIM_THM] THEN
4864 [REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_MESON_TAC[CENTRE_IN_BALL];
4865 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`]] THEN
4866 REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE] THEN
4867 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
4868 SUBGOAL_THEN `s:real^N->bool = t` (fun th -> ASM_REWRITE_TAC[th]) THEN
4869 MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN
4870 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
4871 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [UNIONS_IMAGE]) THEN
4872 DISCH_THEN(MP_TAC o SPEC `x:real^N` o GEN_REWRITE_RULE I [SUBSET]) THEN
4873 ASM_REWRITE_TAC[IN_ELIM_THM; IN_BALL; dist] THEN ASM_MESON_TAC[SUBSET]);;
4875 let BOLZANO_WEIERSTRASS = prove
4876 (`!s:real^N->bool. bounded s /\ INFINITE s ==> ?x. x limit_point_of s`,
4877 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
4878 FIRST_ASSUM(ASSUME_TAC o MATCH_MP NO_LIMIT_POINT_IMP_CLOSED) THEN
4880 MP_TAC(ISPEC `s:real^N->bool` COMPACT_EQ_BOLZANO_WEIERSTRASS) THEN
4881 ASM_REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
4882 DISCH_THEN(MP_TAC o SPEC `s:real^N->bool`) THEN
4883 ASM_REWRITE_TAC[SUBSET_REFL] THEN ASM_MESON_TAC[]);;
4885 let BOUNDED_EQ_BOLZANO_WEIERSTRASS = prove
4887 bounded s <=> !t. t SUBSET s /\ INFINITE t ==> ?x. x limit_point_of t`,
4888 MESON_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED; BOLZANO_WEIERSTRASS;
4891 (* ------------------------------------------------------------------------- *)
4892 (* In particular, some common special cases. *)
4893 (* ------------------------------------------------------------------------- *)
4895 let COMPACT_EMPTY = prove
4897 REWRITE_TAC[compact; NOT_IN_EMPTY]);;
4899 let COMPACT_UNION = prove
4900 (`!s t. compact s /\ compact t ==> compact (s UNION t)`,
4901 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_UNION; CLOSED_UNION]);;
4903 let COMPACT_INTER = prove
4904 (`!s t. compact s /\ compact t ==> compact (s INTER t)`,
4905 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_INTER; CLOSED_INTER]);;
4907 let COMPACT_INTER_CLOSED = prove
4908 (`!s t. compact s /\ closed t ==> compact (s INTER t)`,
4909 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_INTER] THEN
4910 MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET]);;
4912 let CLOSED_INTER_COMPACT = prove
4913 (`!s t. closed s /\ compact t ==> compact (s INTER t)`,
4914 MESON_TAC[COMPACT_INTER_CLOSED; INTER_COMM]);;
4916 let COMPACT_INTERS = prove
4917 (`!f:(real^N->bool)->bool.
4918 (!s. s IN f ==> compact s) /\ ~(f = {})
4919 ==> compact(INTERS f)`,
4920 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_INTERS] THEN
4921 REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_INTERS THEN ASM SET_TAC[]);;
4923 let FINITE_IMP_CLOSED = prove
4924 (`!s. FINITE s ==> closed s`,
4925 MESON_TAC[BOLZANO_WEIERSTRASS_IMP_CLOSED; INFINITE; FINITE_SUBSET]);;
4927 let FINITE_IMP_CLOSED_IN = prove
4928 (`!s t. FINITE s /\ s SUBSET t ==> closed_in (subtopology euclidean t) s`,
4929 SIMP_TAC[CLOSED_SUBSET_EQ; FINITE_IMP_CLOSED]);;
4931 let FINITE_IMP_COMPACT = prove
4932 (`!s. FINITE s ==> compact s`,
4933 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; FINITE_IMP_CLOSED; FINITE_IMP_BOUNDED]);;
4935 let COMPACT_SING = prove
4937 SIMP_TAC[FINITE_IMP_COMPACT; FINITE_RULES]);;
4939 let COMPACT_INSERT = prove
4940 (`!a s. compact s ==> compact(a INSERT s)`,
4941 ONCE_REWRITE_TAC[SET_RULE `a INSERT s = {a} UNION s`] THEN
4942 SIMP_TAC[COMPACT_UNION; COMPACT_SING]);;
4944 let CLOSED_SING = prove
4946 MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; COMPACT_SING]);;
4948 let CLOSED_IN_SING = prove
4949 (`!u x:real^N. closed_in (subtopology euclidean u) {x} <=> x IN u`,
4950 SIMP_TAC[CLOSED_SUBSET_EQ; CLOSED_SING] THEN SET_TAC[]);;
4952 let CLOSURE_SING = prove
4953 (`!x:real^N. closure {x} = {x}`,
4954 SIMP_TAC[CLOSURE_CLOSED; CLOSED_SING]);;
4956 let CLOSED_INSERT = prove
4957 (`!a s. closed s ==> closed(a INSERT s)`,
4958 ONCE_REWRITE_TAC[SET_RULE `a INSERT s = {a} UNION s`] THEN
4959 SIMP_TAC[CLOSED_UNION; CLOSED_SING]);;
4961 let COMPACT_CBALL = prove
4962 (`!x e. compact(cball(x,e))`,
4963 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_CBALL; CLOSED_CBALL]);;
4965 let COMPACT_FRONTIER_BOUNDED = prove
4966 (`!s. bounded s ==> compact(frontier s)`,
4967 SIMP_TAC[frontier; COMPACT_EQ_BOUNDED_CLOSED;
4968 CLOSED_DIFF; OPEN_INTERIOR; CLOSED_CLOSURE] THEN
4969 MESON_TAC[SUBSET_DIFF; BOUNDED_SUBSET; BOUNDED_CLOSURE]);;
4971 let COMPACT_FRONTIER = prove
4972 (`!s. compact s ==> compact (frontier s)`,
4973 MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; COMPACT_FRONTIER_BOUNDED]);;
4975 let BOUNDED_FRONTIER = prove
4976 (`!s:real^N->bool. bounded s ==> bounded(frontier s)`,
4977 MESON_TAC[COMPACT_FRONTIER_BOUNDED; COMPACT_IMP_BOUNDED]);;
4979 let FRONTIER_SUBSET_COMPACT = prove
4980 (`!s. compact s ==> frontier s SUBSET s`,
4981 MESON_TAC[FRONTIER_SUBSET_CLOSED; COMPACT_EQ_BOUNDED_CLOSED]);;
4983 let OPEN_DELETE = prove
4984 (`!s x. open s ==> open(s DELETE x)`,
4985 let lemma = prove(`s DELETE x = s DIFF {x}`,SET_TAC[]) in
4986 SIMP_TAC[lemma; OPEN_DIFF; CLOSED_SING]);;
4988 let OPEN_IN_DELETE = prove
4990 open_in (subtopology euclidean u) s
4991 ==> open_in (subtopology euclidean u) (s DELETE a)`,
4992 REPEAT STRIP_TAC THEN ASM_CASES_TAC `(a:real^N) IN s` THENL
4993 [ONCE_REWRITE_TAC[SET_RULE `s DELETE a = s DIFF {a}`] THEN
4994 MATCH_MP_TAC OPEN_IN_DIFF THEN ASM_REWRITE_TAC[CLOSED_IN_SING] THEN
4995 FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN ASM SET_TAC[];
4996 ASM_SIMP_TAC[SET_RULE `~(a IN s) ==> s DELETE a = s`]]);;
4998 let CLOSED_INTERS_COMPACT = prove
5000 closed s <=> !e. compact(cball(vec 0,e) INTER s)`,
5001 GEN_TAC THEN EQ_TAC THENL
5002 [SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_INTER; CLOSED_CBALL;
5003 BOUNDED_INTER; BOUNDED_CBALL];
5005 STRIP_TAC THEN REWRITE_TAC[CLOSED_LIMPT] THEN
5006 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
5007 FIRST_X_ASSUM(MP_TAC o SPEC `norm(x:real^N) + &1`) THEN
5008 DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_CLOSED) THEN
5009 REWRITE_TAC[CLOSED_LIMPT] THEN DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
5010 REWRITE_TAC[IN_INTER] THEN ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
5011 POP_ASSUM MP_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
5012 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5013 FIRST_X_ASSUM(MP_TAC o SPEC `min e (&1 / &2)`) THEN
5014 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN
5015 X_GEN_TAC `y:real^N` THEN SIMP_TAC[IN_INTER; IN_CBALL] THEN NORM_ARITH_TAC);;
5017 let COMPACT_UNIONS = prove
5018 (`!s. FINITE s /\ (!t. t IN s ==> compact t) ==> compact(UNIONS s)`,
5019 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_UNIONS; BOUNDED_UNIONS]);;
5021 let COMPACT_DIFF = prove
5022 (`!s t. compact s /\ open t ==> compact(s DIFF t)`,
5023 ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN
5024 SIMP_TAC[COMPACT_INTER_CLOSED; GSYM OPEN_CLOSED]);;
5026 let COMPACT_SPHERE = prove
5027 (`!a:real^N r. compact(sphere(a,r))`,
5029 REWRITE_TAC[GSYM FRONTIER_CBALL] THEN MATCH_MP_TAC COMPACT_FRONTIER THEN
5030 REWRITE_TAC[COMPACT_CBALL]);;
5032 let BOUNDED_SPHERE = prove
5033 (`!a:real^N r. bounded(sphere(a,r))`,
5034 SIMP_TAC[COMPACT_SPHERE; COMPACT_IMP_BOUNDED]);;
5036 let CLOSED_SPHERE = prove
5037 (`!a r. closed(sphere(a,r))`,
5038 SIMP_TAC[COMPACT_SPHERE; COMPACT_IMP_CLOSED]);;
5040 let FRONTIER_SING = prove
5041 (`!a:real^N. frontier {a} = {a}`,
5042 REWRITE_TAC[frontier; CLOSURE_SING; INTERIOR_SING; DIFF_EMPTY]);;
5044 (* ------------------------------------------------------------------------- *)
5045 (* Finite intersection property. I could make it an equivalence in fact. *)
5046 (* ------------------------------------------------------------------------- *)
5048 let COMPACT_IMP_FIP = prove
5049 (`!s:real^N->bool f.
5051 (!t. t IN f ==> closed t) /\
5052 (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (INTERS f') = {}))
5053 ==> ~(s INTER (INTERS f) = {})`,
5054 let lemma = prove(`(s = UNIV DIFF t) <=> (UNIV DIFF s = t)`,SET_TAC[]) in
5055 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5056 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL]) THEN
5057 DISCH_THEN(MP_TAC o SPEC `IMAGE (\t:real^N->bool. UNIV DIFF t) f`) THEN
5058 ASM_SIMP_TAC[FORALL_IN_IMAGE] THEN
5059 DISCH_THEN(fun th -> REPEAT STRIP_TAC THEN MP_TAC th) THEN
5060 ASM_SIMP_TAC[OPEN_DIFF; CLOSED_DIFF; OPEN_UNIV; CLOSED_UNIV; NOT_IMP] THEN
5062 [UNDISCH_TAC `(s:real^N->bool) INTER INTERS f = {}` THEN
5063 ONCE_REWRITE_TAC[SUBSET; EXTENSION] THEN
5064 REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE] THEN SET_TAC[];
5065 DISCH_THEN(X_CHOOSE_THEN `g:(real^N->bool)->bool` MP_TAC) THEN
5066 FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (\t:real^N->bool. UNIV DIFF t) g`) THEN
5067 ASM_CASES_TAC `FINITE(g:(real^N->bool)->bool)` THEN
5068 ASM_SIMP_TAC[FINITE_IMAGE] THEN ONCE_REWRITE_TAC[SUBSET; EXTENSION] THEN
5069 REWRITE_TAC[FORALL_IN_IMAGE; IN_INTER; IN_INTERS; IN_IMAGE; IN_DIFF;
5070 IN_UNIV; NOT_IN_EMPTY; lemma; UNWIND_THM1; IN_UNIONS] THEN
5073 let CLOSED_IMP_FIP = prove
5074 (`!s:real^N->bool f.
5076 (!t. t IN f ==> closed t) /\ (?t. t IN f /\ bounded t) /\
5077 (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (INTERS f') = {}))
5078 ==> ~(s INTER (INTERS f) = {})`,
5079 REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC(SET_RULE
5080 `~((s INTER t) INTER u = {}) ==> ~(s INTER u = {})`) THEN
5081 MATCH_MP_TAC COMPACT_IMP_FIP THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
5082 [ASM_MESON_TAC[CLOSED_INTER_COMPACT; COMPACT_EQ_BOUNDED_CLOSED];
5083 REWRITE_TAC[INTER_ASSOC] THEN ONCE_REWRITE_TAC[GSYM INTERS_INSERT]] THEN
5084 GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
5085 ASM_SIMP_TAC[FINITE_INSERT; INSERT_SUBSET]);;
5087 let CLOSED_IMP_FIP_COMPACT = prove
5088 (`!s:real^N->bool f.
5089 closed s /\ (!t. t IN f ==> compact t) /\
5090 (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (INTERS f') = {}))
5091 ==> ~(s INTER (INTERS f) = {})`,
5093 ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN
5094 ASM_SIMP_TAC[SUBSET_EMPTY; INTERS_0; INTER_UNIV] THENL
5095 [MESON_TAC[FINITE_EMPTY]; ALL_TAC] THEN
5096 STRIP_TAC THEN MATCH_MP_TAC CLOSED_IMP_FIP THEN
5097 ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; MEMBER_NOT_EMPTY]);;
5099 let CLOSED_FIP = prove
5100 (`!f. (!t:real^N->bool. t IN f ==> closed t) /\ (?t. t IN f /\ bounded t) /\
5101 (!f'. FINITE f' /\ f' SUBSET f ==> ~(INTERS f' = {}))
5102 ==> ~(INTERS f = {})`,
5103 GEN_TAC THEN DISCH_TAC THEN
5104 ONCE_REWRITE_TAC[SET_RULE `s = {} <=> UNIV INTER s = {}`] THEN
5105 MATCH_MP_TAC CLOSED_IMP_FIP THEN ASM_REWRITE_TAC[CLOSED_UNIV; INTER_UNIV]);;
5107 let COMPACT_FIP = prove
5108 (`!f. (!t:real^N->bool. t IN f ==> compact t) /\
5109 (!f'. FINITE f' /\ f' SUBSET f ==> ~(INTERS f' = {}))
5110 ==> ~(INTERS f = {})`,
5111 GEN_TAC THEN DISCH_TAC THEN
5112 ONCE_REWRITE_TAC[SET_RULE `s = {} <=> UNIV INTER s = {}`] THEN
5113 MATCH_MP_TAC CLOSED_IMP_FIP_COMPACT THEN
5114 ASM_REWRITE_TAC[CLOSED_UNIV; INTER_UNIV]);;
5116 (* ------------------------------------------------------------------------- *)
5117 (* Bounded closed nest property (proof does not use Heine-Borel). *)
5118 (* ------------------------------------------------------------------------- *)
5120 let BOUNDED_CLOSED_NEST = prove
5121 (`!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\
5122 (!m n. m <= n ==> s(n) SUBSET s(m)) /\
5124 ==> ?a:real^N. !n:num. a IN s(n)`,
5125 GEN_TAC THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; SKOLEM_THM] THEN
5126 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5127 DISCH_THEN(CONJUNCTS_THEN2
5128 (X_CHOOSE_TAC `a:num->real^N`) STRIP_ASSUME_TAC) THEN
5129 SUBGOAL_THEN `compact(s 0:real^N->bool)` MP_TAC THENL
5130 [ASM_MESON_TAC[BOUNDED_CLOSED_IMP_COMPACT]; ALL_TAC] THEN
5131 REWRITE_TAC[compact] THEN
5132 DISCH_THEN(MP_TAC o SPEC `a:num->real^N`) THEN
5133 ANTS_TAC THENL [ASM_MESON_TAC[SUBSET; LE_0]; ALL_TAC] THEN
5134 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real^N` THEN
5135 REWRITE_TAC[LIM_SEQUENTIALLY; o_THM] THEN
5136 DISCH_THEN(X_CHOOSE_THEN `r:num->num` STRIP_ASSUME_TAC) THEN
5137 GEN_REWRITE_TAC I [TAUT `p <=> ~(~p)`] THEN
5138 GEN_REWRITE_TAC RAND_CONV [NOT_FORALL_THM] THEN
5139 DISCH_THEN(X_CHOOSE_THEN `N:num` MP_TAC) THEN
5140 MP_TAC(ISPECL [`l:real^N`; `(s:num->real^N->bool) N`]
5141 CLOSED_APPROACHABLE) THEN
5142 ASM_MESON_TAC[SUBSET; LE_REFL; LE_TRANS; LE_CASES; MONOTONE_BIGGER]);;
5144 (* ------------------------------------------------------------------------- *)
5145 (* Decreasing case does not even need compactness, just completeness. *)
5146 (* ------------------------------------------------------------------------- *)
5148 let DECREASING_CLOSED_NEST = prove
5149 (`!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\
5150 (!m n. m <= n ==> s(n) SUBSET s(m)) /\
5151 (!e. &0 < e ==> ?n. !x y. x IN s(n) /\ y IN s(n) ==> dist(x,y) < e)
5152 ==> ?a:real^N. !n:num. a IN s(n)`,
5153 GEN_TAC THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; SKOLEM_THM] THEN
5154 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5155 DISCH_THEN(CONJUNCTS_THEN2
5156 (X_CHOOSE_TAC `a:num->real^N`) STRIP_ASSUME_TAC) THEN
5157 SUBGOAL_THEN `?l:real^N. (a --> l) sequentially` MP_TAC THENL
5158 [ASM_MESON_TAC[cauchy; GE; SUBSET; LE_TRANS; LE_REFL;
5159 complete; COMPLETE_UNIV; IN_UNIV];
5160 ASM_MESON_TAC[LIM_SEQUENTIALLY; CLOSED_APPROACHABLE;
5161 SUBSET; LE_REFL; LE_TRANS; LE_CASES]]);;
5163 (* ------------------------------------------------------------------------- *)
5164 (* Strengthen it to the intersection actually being a singleton. *)
5165 (* ------------------------------------------------------------------------- *)
5167 let DECREASING_CLOSED_NEST_SING = prove
5168 (`!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\
5169 (!m n. m <= n ==> s(n) SUBSET s(m)) /\
5170 (!e. &0 < e ==> ?n. !x y. x IN s(n) /\ y IN s(n) ==> dist(x,y) < e)
5171 ==> ?a:real^N. INTERS {t | ?n:num. t = s n} = {a}`,
5172 GEN_TAC THEN DISCH_TAC THEN
5173 FIRST_ASSUM(MP_TAC o MATCH_MP DECREASING_CLOSED_NEST) THEN
5174 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN
5175 DISCH_TAC THEN REWRITE_TAC[EXTENSION; IN_INTERS; IN_SING; IN_ELIM_THM] THEN
5176 ASM_MESON_TAC[DIST_POS_LT; REAL_LT_REFL; SUBSET; LE_CASES]);;
5178 (* ------------------------------------------------------------------------- *)
5179 (* A version for a more general chain, not indexed by N. *)
5180 (* ------------------------------------------------------------------------- *)
5182 let BOUNDED_CLOSED_CHAIN = prove
5183 (`!f b:real^N->bool.
5184 (!s. s IN f ==> closed s /\ ~(s = {})) /\
5185 (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) /\
5187 ==> ~(INTERS f = {})`,
5188 REPEAT GEN_TAC THEN STRIP_TAC THEN
5189 SUBGOAL_THEN `~(b INTER (INTERS f):real^N->bool = {})` MP_TAC THENL
5190 [ALL_TAC; SET_TAC[]] THEN
5191 MATCH_MP_TAC COMPACT_IMP_FIP THEN
5192 ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
5193 X_GEN_TAC `u:(real^N->bool)->bool` THEN STRIP_TAC THEN
5194 SUBGOAL_THEN `?s:real^N->bool. s IN f /\ !t. t IN u ==> s SUBSET t`
5195 MP_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
5196 UNDISCH_TAC `(u:(real^N->bool)->bool) SUBSET f` THEN
5197 UNDISCH_TAC `FINITE(u:(real^N->bool)->bool)` THEN
5198 SPEC_TAC(`u:(real^N->bool)->bool`,`u:(real^N->bool)->bool`) THEN
5199 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
5200 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
5201 MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:(real^N->bool)->bool`] THEN
5202 REWRITE_TAC[INSERT_SUBSET] THEN
5203 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
5204 ASM_REWRITE_TAC[] THEN
5205 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
5206 DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN
5207 FIRST_X_ASSUM(MP_TAC o SPECL [`s:real^N->bool`; `t:real^N->bool`]) THEN
5210 (* ------------------------------------------------------------------------- *)
5211 (* Analogous things directly for compactness. *)
5212 (* ------------------------------------------------------------------------- *)
5214 let COMPACT_CHAIN = prove
5215 (`!f:(real^N->bool)->bool.
5216 (!s. s IN f ==> compact s /\ ~(s = {})) /\
5217 (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s)
5218 ==> ~(INTERS f = {})`,
5219 GEN_TAC THEN REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN STRIP_TAC THEN
5220 ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THENL
5221 [ASM_REWRITE_TAC[INTERS_0] THEN SET_TAC[];
5222 MATCH_MP_TAC BOUNDED_CLOSED_CHAIN THEN ASM SET_TAC[]]);;
5224 let COMPACT_NEST = prove
5225 (`!s. (!n. compact(s n) /\ ~(s n = {})) /\
5226 (!m n. m <= n ==> s n SUBSET s m)
5227 ==> ~(INTERS {s n | n IN (:num)} = {})`,
5228 GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC COMPACT_CHAIN THEN
5229 ASM_SIMP_TAC[FORALL_IN_GSPEC; IN_UNIV; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
5230 MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]);;
5232 (* ------------------------------------------------------------------------- *)
5233 (* Cauchy-type criteria for *uniform* convergence. *)
5234 (* ------------------------------------------------------------------------- *)
5236 let UNIFORMLY_CONVERGENT_EQ_CAUCHY = prove
5237 (`!P s:num->A->real^N.
5239 ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e) <=>
5241 ==> ?N. !m n x. N <= m /\ N <= n /\ P x
5242 ==> dist(s m x,s n x) < e)`,
5243 REPEAT GEN_TAC THEN EQ_TAC THENL
5244 [DISCH_THEN(X_CHOOSE_TAC `l:A->real^N`) THEN X_GEN_TAC `e:real` THEN
5245 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
5246 ASM_REWRITE_TAC[REAL_HALF] THEN MESON_TAC[DIST_TRIANGLE_HALF_L];
5249 SUBGOAL_THEN `!x:A. P x ==> cauchy (\n. s n x :real^N)` MP_TAC THENL
5250 [REWRITE_TAC[cauchy; GE] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
5251 REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY; LIM_SEQUENTIALLY] THEN
5252 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
5253 REWRITE_TAC[SKOLEM_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
5254 X_GEN_TAC `l:A->real^N` THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN
5255 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
5256 ASM_REWRITE_TAC[REAL_HALF] THEN MATCH_MP_TAC MONO_EXISTS THEN
5257 X_GEN_TAC `N:num` THEN STRIP_TAC THEN
5258 MAP_EVERY X_GEN_TAC [`n:num`; `x:A`] THEN STRIP_TAC THEN
5259 FIRST_X_ASSUM(MP_TAC o SPEC `x:A`) THEN ASM_REWRITE_TAC[] THEN
5260 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
5261 DISCH_THEN(X_CHOOSE_TAC `M:num`) THEN
5262 FIRST_X_ASSUM(MP_TAC o SPECL [`n:num`; `N + M:num`; `x:A`]) THEN
5263 ASM_REWRITE_TAC[LE_ADD] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN
5264 FIRST_X_ASSUM(MP_TAC o SPEC `M + N:num`) THEN REWRITE_TAC[LE_ADD] THEN
5265 ASM_MESON_TAC[DIST_TRIANGLE_HALF_L; DIST_SYM]);;
5267 let UNIFORMLY_CONVERGENT_EQ_CAUCHY_ALT = prove
5268 (`!P s:num->A->real^N.
5270 ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e) <=>
5272 ==> ?N. !m n x. N <= m /\ N <= n /\ m < n /\ P x
5273 ==> dist(s m x,s n x) < e)`,
5274 REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONVERGENT_EQ_CAUCHY] THEN
5275 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5276 FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
5277 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN
5278 ASM_SIMP_TAC[] THEN MATCH_MP_TAC WLOG_LT THEN
5279 ASM_SIMP_TAC[DIST_REFL] THEN MESON_TAC[DIST_SYM]);;
5281 let UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT = prove
5282 (`!P (s:num->A->real^N) l.
5284 ==> ?N. !m n x. N <= m /\ N <= n /\ P x ==> dist(s m x,s n x) < e) /\
5285 (!x. P x ==> !e. &0 < e ==> ?N. !n. N <= n ==> dist(s n x,l x) < e)
5286 ==> (!e. &0 < e ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e)`,
5287 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM UNIFORMLY_CONVERGENT_EQ_CAUCHY] THEN
5288 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `l':A->real^N`) ASSUME_TAC) THEN
5289 SUBGOAL_THEN `!x. P x ==> (l:A->real^N) x = l' x` MP_TAC THENL
5290 [ALL_TAC; ASM_MESON_TAC[]] THEN
5291 REPEAT STRIP_TAC THEN MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
5292 EXISTS_TAC `\n. (s:num->A->real^N) n x` THEN
5293 REWRITE_TAC[LIM_SEQUENTIALLY; TRIVIAL_LIMIT_SEQUENTIALLY] THEN
5296 (* ------------------------------------------------------------------------- *)
5297 (* Define continuity over a net to take in restrictions of the set. *)
5298 (* ------------------------------------------------------------------------- *)
5300 parse_as_infix ("continuous",(12,"right"));;
5302 let continuous = new_definition
5303 `f continuous net <=> (f --> f(netlimit net)) net`;;
5305 let CONTINUOUS_TRIVIAL_LIMIT = prove
5306 (`!f net. trivial_limit net ==> f continuous net`,
5307 SIMP_TAC[continuous; LIM]);;
5309 let CONTINUOUS_WITHIN = prove
5310 (`!f x:real^M. f continuous (at x within s) <=> (f --> f(x)) (at x within s)`,
5311 REPEAT GEN_TAC THEN REWRITE_TAC[continuous] THEN
5312 ASM_CASES_TAC `trivial_limit(at (x:real^M) within s)` THENL
5313 [ASM_REWRITE_TAC[LIM]; ASM_SIMP_TAC[NETLIMIT_WITHIN]]);;
5315 let CONTINUOUS_AT = prove
5316 (`!f (x:real^N). f continuous (at x) <=> (f --> f(x)) (at x)`,
5317 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
5318 REWRITE_TAC[CONTINUOUS_WITHIN; IN_UNIV]);;
5320 let CONTINUOUS_AT_WITHIN = prove
5321 (`!f:real^M->real^N x s.
5322 f continuous (at x) ==> f continuous (at x within s)`,
5323 SIMP_TAC[LIM_AT_WITHIN; CONTINUOUS_AT; CONTINUOUS_WITHIN]);;
5325 let CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL = prove
5326 (`!a s. closed s /\ ~(a IN s) ==> f continuous (at a within s)`,
5327 ASM_SIMP_TAC[continuous; LIM; LIM_WITHIN_CLOSED_TRIVIAL]);;
5329 let CONTINUOUS_TRANSFORM_WITHIN = prove
5330 (`!f g:real^M->real^N s x d.
5332 (!x'. x' IN s /\ dist(x',x) < d ==> f(x') = g(x')) /\
5333 f continuous (at x within s)
5334 ==> g continuous (at x within s)`,
5335 REWRITE_TAC[CONTINUOUS_WITHIN] THEN
5336 MESON_TAC[LIM_TRANSFORM_WITHIN; DIST_REFL]);;
5338 let CONTINUOUS_TRANSFORM_AT = prove
5339 (`!f g:real^M->real^N x d.
5340 &0 < d /\ (!x'. dist(x',x) < d ==> f(x') = g(x')) /\
5342 ==> g continuous (at x)`,
5343 REWRITE_TAC[CONTINUOUS_AT] THEN
5344 MESON_TAC[LIM_TRANSFORM_AT; DIST_REFL]);;
5346 let CONTINUOUS_TRANSFORM_WITHIN_OPEN = prove
5347 (`!f g:real^M->real^N s a.
5349 (!x. x IN s ==> f x = g x) /\
5351 ==> g continuous at a`,
5352 MESON_TAC[CONTINUOUS_AT; LIM_TRANSFORM_WITHIN_OPEN]);;
5354 let CONTINUOUS_TRANSFORM_WITHIN_OPEN_IN = prove
5355 (`!f g:real^M->real^N s t a.
5356 open_in (subtopology euclidean t) s /\ a IN s /\
5357 (!x. x IN s ==> f x = g x) /\
5358 f continuous (at a within t)
5359 ==> g continuous (at a within t)`,
5360 MESON_TAC[CONTINUOUS_WITHIN; LIM_TRANSFORM_WITHIN_OPEN_IN]);;
5362 (* ------------------------------------------------------------------------- *)
5363 (* Derive the epsilon-delta forms, which we often use as "definitions" *)
5364 (* ------------------------------------------------------------------------- *)
5366 let continuous_within = prove
5367 (`f continuous (at x within s) <=>
5370 !x'. x' IN s /\ dist(x',x) < d ==> dist(f(x'),f(x)) < e`,
5371 REWRITE_TAC[CONTINUOUS_WITHIN; LIM_WITHIN] THEN
5372 REWRITE_TAC[GSYM DIST_NZ] THEN MESON_TAC[DIST_REFL]);;
5374 let continuous_at = prove
5375 (`f continuous (at x) <=>
5376 !e. &0 < e ==> ?d. &0 < d /\
5377 !x'. dist(x',x) < d ==> dist(f(x'),f(x)) < e`,
5378 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
5379 REWRITE_TAC[continuous_within; IN_UNIV]);;
5381 (* ------------------------------------------------------------------------- *)
5382 (* Versions in terms of open balls. *)
5383 (* ------------------------------------------------------------------------- *)
5385 let CONTINUOUS_WITHIN_BALL = prove
5386 (`!f s x. f continuous (at x within s) <=>
5389 IMAGE f (ball(x,d) INTER s) SUBSET ball(f x,e)`,
5390 SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_BALL; continuous_within; IN_INTER] THEN
5391 MESON_TAC[DIST_SYM]);;
5393 let CONTINUOUS_AT_BALL = prove
5394 (`!f x. f continuous (at x) <=>
5397 IMAGE f (ball(x,d)) SUBSET ball(f x,e)`,
5398 SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_BALL; continuous_at] THEN
5399 MESON_TAC[DIST_SYM]);;
5401 (* ------------------------------------------------------------------------- *)
5402 (* For setwise continuity, just start from the epsilon-delta definitions. *)
5403 (* ------------------------------------------------------------------------- *)
5405 parse_as_infix ("continuous_on",(12,"right"));;
5406 parse_as_infix ("uniformly_continuous_on",(12,"right"));;
5408 let continuous_on = new_definition
5409 `f continuous_on s <=>
5410 !x. x IN s ==> !e. &0 < e
5412 !x'. x' IN s /\ dist(x',x) < d
5413 ==> dist(f(x'),f(x)) < e`;;
5415 let uniformly_continuous_on = new_definition
5416 `f uniformly_continuous_on s <=>
5419 !x x'. x IN s /\ x' IN s /\ dist(x',x) < d
5420 ==> dist(f(x'),f(x)) < e`;;
5422 (* ------------------------------------------------------------------------- *)
5423 (* Some simple consequential lemmas. *)
5424 (* ------------------------------------------------------------------------- *)
5426 let UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS = prove
5427 (`!f s. f uniformly_continuous_on s ==> f continuous_on s`,
5428 REWRITE_TAC[uniformly_continuous_on; continuous_on] THEN MESON_TAC[]);;
5430 let CONTINUOUS_AT_IMP_CONTINUOUS_ON = prove
5431 (`!f s. (!x. x IN s ==> f continuous (at x)) ==> f continuous_on s`,
5432 REWRITE_TAC[continuous_at; continuous_on] THEN MESON_TAC[]);;
5434 let CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN = prove
5435 (`!f s. f continuous_on s <=> !x. x IN s ==> f continuous (at x within s)`,
5436 REWRITE_TAC[continuous_on; continuous_within]);;
5438 let CONTINUOUS_ON = prove
5439 (`!f (s:real^N->bool).
5440 f continuous_on s <=> !x. x IN s ==> (f --> f(x)) (at x within s)`,
5441 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_WITHIN]);;
5443 let CONTINUOUS_ON_EQ_CONTINUOUS_AT = prove
5444 (`!f:real^M->real^N s.
5445 open s ==> (f continuous_on s <=> (!x. x IN s ==> f continuous (at x)))`,
5446 SIMP_TAC[CONTINUOUS_ON; CONTINUOUS_AT; LIM_WITHIN_OPEN]);;
5448 let CONTINUOUS_WITHIN_SUBSET = prove
5449 (`!f s t x. f continuous (at x within s) /\ t SUBSET s
5450 ==> f continuous (at x within t)`,
5451 REWRITE_TAC[CONTINUOUS_WITHIN] THEN MESON_TAC[LIM_WITHIN_SUBSET]);;
5453 let CONTINUOUS_ON_SUBSET = prove
5454 (`!f s t. f continuous_on s /\ t SUBSET s ==> f continuous_on t`,
5455 REWRITE_TAC[CONTINUOUS_ON] THEN MESON_TAC[SUBSET; LIM_WITHIN_SUBSET]);;
5457 let UNIFORMLY_CONTINUOUS_ON_SUBSET = prove
5458 (`!f s t. f uniformly_continuous_on s /\ t SUBSET s
5459 ==> f uniformly_continuous_on t`,
5460 REWRITE_TAC[uniformly_continuous_on] THEN
5461 MESON_TAC[SUBSET; LIM_WITHIN_SUBSET]);;
5463 let CONTINUOUS_ON_INTERIOR = prove
5464 (`!f:real^M->real^N s x.
5465 f continuous_on s /\ x IN interior(s) ==> f continuous at x`,
5466 REWRITE_TAC[interior; IN_ELIM_THM] THEN
5467 MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; CONTINUOUS_ON_SUBSET]);;
5469 let CONTINUOUS_ON_EQ = prove
5470 (`!f g s. (!x. x IN s ==> f(x) = g(x)) /\ f continuous_on s
5471 ==> g continuous_on s`,
5472 SIMP_TAC[continuous_on; IMP_CONJ]);;
5474 let UNIFORMLY_CONTINUOUS_ON_EQ = prove
5476 (!x. x IN s ==> f x = g x) /\ f uniformly_continuous_on s
5477 ==> g uniformly_continuous_on s`,
5478 SIMP_TAC[uniformly_continuous_on; IMP_CONJ]);;
5480 let CONTINUOUS_ON_SING = prove
5481 (`!f:real^M->real^N a. f continuous_on {a}`,
5482 SIMP_TAC[continuous_on; IN_SING; FORALL_UNWIND_THM2; DIST_REFL] THEN
5485 let CONTINUOUS_ON_EMPTY = prove
5486 (`!f:real^M->real^N. f continuous_on {}`,
5487 MESON_TAC[CONTINUOUS_ON_SING; EMPTY_SUBSET; CONTINUOUS_ON_SUBSET]);;
5489 let CONTINUOUS_ON_NO_LIMPT = prove
5490 (`!f:real^M->real^N s.
5491 ~(?x. x limit_point_of s) ==> f continuous_on s`,
5492 REWRITE_TAC[continuous_on; LIMPT_APPROACHABLE] THEN MESON_TAC[DIST_REFL]);;
5494 let CONTINUOUS_ON_FINITE = prove
5495 (`!f:real^M->real^N s. FINITE s ==> f continuous_on s`,
5496 MESON_TAC[CONTINUOUS_ON_NO_LIMPT; LIMIT_POINT_FINITE]);;
5498 let CONTRACTION_IMP_CONTINUOUS_ON = prove
5499 (`!f:real^M->real^N.
5500 (!x y. x IN s /\ y IN s ==> dist(f x,f y) <= dist(x,y))
5501 ==> f continuous_on s`,
5502 SIMP_TAC[continuous_on] THEN MESON_TAC[REAL_LET_TRANS]);;
5504 let ISOMETRY_ON_IMP_CONTINUOUS_ON = prove
5505 (`!f:real^M->real^N.
5506 (!x y. x IN s /\ y IN s ==> dist(f x,f y) = dist(x,y))
5507 ==> f continuous_on s`,
5508 SIMP_TAC[CONTRACTION_IMP_CONTINUOUS_ON; REAL_LE_REFL]);;
5510 (* ------------------------------------------------------------------------- *)
5511 (* Characterization of various kinds of continuity in terms of sequences. *)
5512 (* ------------------------------------------------------------------------- *)
5514 let CONTINUOUS_WITHIN_SEQUENTIALLY = prove
5516 f continuous (at a within s) <=>
5517 !x. (!n. x(n) IN s) /\ (x --> a) sequentially
5518 ==> ((f o x) --> f(a)) sequentially`,
5519 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within] THEN EQ_TAC THENL
5520 [REWRITE_TAC[LIM_SEQUENTIALLY; o_THM] THEN MESON_TAC[]; ALL_TAC] THEN
5521 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
5522 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN
5523 DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5524 DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `&1 / (&n + &1)`) THEN
5525 SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; REAL_OF_NUM_LE; REAL_POS; ARITH;
5526 REAL_ARITH `&0 <= n ==> &0 < n + &1`; NOT_FORALL_THM; SKOLEM_THM] THEN
5527 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[NOT_IMP; FORALL_AND_THM] THEN
5528 X_GEN_TAC `y:num->real^N` THEN REWRITE_TAC[LIM_SEQUENTIALLY; o_THM] THEN
5529 STRIP_TAC THEN CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LE_REFL]] THEN
5530 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC FORALL_POS_MONO_1 THEN
5531 CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_TRANS]; ALL_TAC] THEN
5532 X_GEN_TAC `n:num` THEN EXISTS_TAC `n:num` THEN X_GEN_TAC `m:num` THEN
5533 DISCH_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN
5534 EXISTS_TAC `&1 / (&m + &1)` THEN ASM_REWRITE_TAC[] THEN
5535 ASM_SIMP_TAC[REAL_LE_INV2; real_div; REAL_ARITH `&0 <= x ==> &0 < x + &1`;
5536 REAL_POS; REAL_MUL_LID; REAL_LE_RADD; REAL_OF_NUM_LE]);;
5538 let CONTINUOUS_AT_SEQUENTIALLY = prove
5540 f continuous (at a) <=>
5541 !x. (x --> a) sequentially
5542 ==> ((f o x) --> f(a)) sequentially`,
5543 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
5544 REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY; IN_UNIV]);;
5546 let CONTINUOUS_ON_SEQUENTIALLY = prove
5547 (`!f s:real^N->bool.
5548 f continuous_on s <=>
5549 !x a. a IN s /\ (!n. x(n) IN s) /\ (x --> a) sequentially
5550 ==> ((f o x) --> f(a)) sequentially`,
5551 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
5552 CONTINUOUS_WITHIN_SEQUENTIALLY] THEN MESON_TAC[]);;
5554 let UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY = prove
5555 (`!f s:real^N->bool.
5556 f uniformly_continuous_on s <=>
5557 !x y. (!n. x(n) IN s) /\ (!n. y(n) IN s) /\
5558 ((\n. x(n) - y(n)) --> vec 0) sequentially
5559 ==> ((\n. f(x(n)) - f(y(n))) --> vec 0) sequentially`,
5560 REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on] THEN
5561 REWRITE_TAC[LIM_SEQUENTIALLY; dist; VECTOR_SUB_RZERO] THEN
5562 EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
5563 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
5564 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN
5565 DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5566 DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `&1 / (&n + &1)`) THEN
5567 SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; REAL_OF_NUM_LE; REAL_POS; ARITH;
5568 REAL_ARITH `&0 <= n ==> &0 < n + &1`; NOT_FORALL_THM; SKOLEM_THM] THEN
5569 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:num->real^N` THEN
5570 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:num->real^N` THEN
5571 REWRITE_TAC[NOT_IMP; FORALL_AND_THM] THEN STRIP_TAC THEN
5572 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[NORM_SUB] THEN CONJ_TAC THENL
5573 [MATCH_MP_TAC FORALL_POS_MONO_1 THEN
5574 CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_TRANS]; ALL_TAC] THEN
5575 X_GEN_TAC `n:num` THEN EXISTS_TAC `n:num` THEN X_GEN_TAC `m:num` THEN
5576 DISCH_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN
5577 EXISTS_TAC `&1 / (&m + &1)` THEN ASM_REWRITE_TAC[] THEN
5578 ASM_SIMP_TAC[REAL_LE_INV2; real_div; REAL_ARITH `&0 <= x ==> &0 < x + &1`;
5579 REAL_POS; REAL_MUL_LID; REAL_LE_RADD; REAL_OF_NUM_LE];
5580 EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN
5581 EXISTS_TAC `\x:num. x` THEN ASM_REWRITE_TAC[LE_REFL]]);;
5583 let LIM_CONTINUOUS_FUNCTION = prove
5585 f continuous (at l) /\ (g --> l) net ==> ((\x. f(g x)) --> f l) net`,
5586 REWRITE_TAC[tendsto; continuous_at; eventually] THEN MESON_TAC[]);;
5588 (* ------------------------------------------------------------------------- *)
5589 (* Combination results for pointwise continuity. *)
5590 (* ------------------------------------------------------------------------- *)
5592 let CONTINUOUS_CONST = prove
5593 (`!net c. (\x. c) continuous net`,
5594 REWRITE_TAC[continuous; LIM_CONST]);;
5596 let CONTINUOUS_CMUL = prove
5597 (`!f c net. f continuous net ==> (\x. c % f(x)) continuous net`,
5598 REWRITE_TAC[continuous; LIM_CMUL]);;
5600 let CONTINUOUS_NEG = prove
5601 (`!f net. f continuous net ==> (\x. --(f x)) continuous net`,
5602 REWRITE_TAC[continuous; LIM_NEG]);;
5604 let CONTINUOUS_ADD = prove
5605 (`!f g net. f continuous net /\ g continuous net
5606 ==> (\x. f(x) + g(x)) continuous net`,
5607 REWRITE_TAC[continuous; LIM_ADD]);;
5609 let CONTINUOUS_SUB = prove
5610 (`!f g net. f continuous net /\ g continuous net
5611 ==> (\x. f(x) - g(x)) continuous net`,
5612 REWRITE_TAC[continuous; LIM_SUB]);;
5614 let CONTINUOUS_ABS = prove
5615 (`!(f:A->real^N) net.
5617 ==> (\x. (lambda i. abs(f(x)$i)):real^N) continuous net`,
5618 REWRITE_TAC[continuous; LIM_ABS]);;
5620 let CONTINUOUS_MAX = prove
5621 (`!(f:A->real^N) (g:A->real^N) net.
5622 f continuous net /\ g continuous net
5623 ==> (\x. (lambda i. max (f(x)$i) (g(x)$i)):real^N) continuous net`,
5624 REWRITE_TAC[continuous; LIM_MAX]);;
5626 let CONTINUOUS_MIN = prove
5627 (`!(f:A->real^N) (g:A->real^N) net.
5628 f continuous net /\ g continuous net
5629 ==> (\x. (lambda i. min (f(x)$i) (g(x)$i)):real^N) continuous net`,
5630 REWRITE_TAC[continuous; LIM_MIN]);;
5632 let CONTINUOUS_VSUM = prove
5633 (`!net f s. FINITE s /\ (!a. a IN s ==> (f a) continuous net)
5634 ==> (\x. vsum s (\a. f a x)) continuous net`,
5635 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
5636 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
5637 SIMP_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY; VSUM_CLAUSES;
5638 CONTINUOUS_CONST; CONTINUOUS_ADD; ETA_AX]);;
5640 (* ------------------------------------------------------------------------- *)
5641 (* Same thing for setwise continuity. *)
5642 (* ------------------------------------------------------------------------- *)
5644 let CONTINUOUS_ON_CONST = prove
5645 (`!s c. (\x. c) continuous_on s`,
5646 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_CONST]);;
5648 let CONTINUOUS_ON_CMUL = prove
5649 (`!f c s. f continuous_on s ==> (\x. c % f(x)) continuous_on s`,
5650 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_CMUL]);;
5652 let CONTINUOUS_ON_NEG = prove
5653 (`!f s. f continuous_on s
5654 ==> (\x. --(f x)) continuous_on s`,
5655 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_NEG]);;
5657 let CONTINUOUS_ON_ADD = prove
5658 (`!f g s. f continuous_on s /\ g continuous_on s
5659 ==> (\x. f(x) + g(x)) continuous_on s`,
5660 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_ADD]);;
5662 let CONTINUOUS_ON_SUB = prove
5663 (`!f g s. f continuous_on s /\ g continuous_on s
5664 ==> (\x. f(x) - g(x)) continuous_on s`,
5665 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_SUB]);;
5667 let CONTINUOUS_ON_ABS = prove
5668 (`!f:real^M->real^N s.
5670 ==> (\x. (lambda i. abs(f(x)$i)):real^N) continuous_on s`,
5671 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_ABS]);;
5673 let CONTINUOUS_ON_MAX = prove
5674 (`!f:real^M->real^N g:real^M->real^N s.
5675 f continuous_on s /\ g continuous_on s
5676 ==> (\x. (lambda i. max (f(x)$i) (g(x)$i)):real^N)
5678 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_MAX]);;
5680 let CONTINUOUS_ON_MIN = prove
5681 (`!f:real^M->real^N g:real^M->real^N s.
5682 f continuous_on s /\ g continuous_on s
5683 ==> (\x. (lambda i. min (f(x)$i) (g(x)$i)):real^N)
5685 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_MIN]);;
5687 let CONTINUOUS_ON_VSUM = prove
5688 (`!t f s. FINITE s /\ (!a. a IN s ==> (f a) continuous_on t)
5689 ==> (\x. vsum s (\a. f a x)) continuous_on t`,
5690 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_VSUM]);;
5692 (* ------------------------------------------------------------------------- *)
5693 (* Same thing for uniform continuity, using sequential formulations. *)
5694 (* ------------------------------------------------------------------------- *)
5696 let UNIFORMLY_CONTINUOUS_ON_CONST = prove
5697 (`!s c. (\x. c) uniformly_continuous_on s`,
5698 REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY; o_DEF;
5699 VECTOR_SUB_REFL; LIM_CONST]);;
5701 let LINEAR_UNIFORMLY_CONTINUOUS_ON = prove
5702 (`!f:real^M->real^N s. linear f ==> f uniformly_continuous_on s`,
5703 REPEAT STRIP_TAC THEN
5704 ASM_SIMP_TAC[uniformly_continuous_on; dist; GSYM LINEAR_SUB] THEN
5705 FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o
5706 MATCH_MP LINEAR_BOUNDED_POS) THEN
5707 X_GEN_TAC `e:real` THEN DISCH_TAC THEN EXISTS_TAC `e / B:real` THEN
5708 ASM_SIMP_TAC[REAL_LT_DIV] THEN
5709 MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN
5710 MATCH_MP_TAC REAL_LET_TRANS THEN
5711 EXISTS_TAC `B * norm(y - x:real^M)` THEN ASM_REWRITE_TAC[] THEN
5712 ASM_MESON_TAC[REAL_LT_RDIV_EQ; REAL_MUL_SYM]);;
5714 let UNIFORMLY_CONTINUOUS_ON_COMPOSE = prove
5715 (`!f g s. f uniformly_continuous_on s /\
5716 g uniformly_continuous_on (IMAGE f s)
5717 ==> (g o f) uniformly_continuous_on s`,
5719 (`(!y. ((?x. (y = f x) /\ P x) /\ Q y ==> R y)) <=>
5720 (!x. P x /\ Q (f x) ==> R (f x))`,
5723 REWRITE_TAC[uniformly_continuous_on; o_THM; IN_IMAGE] THEN
5724 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN REWRITE_TAC[lemma] THEN
5725 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN
5726 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN REWRITE_TAC[lemma] THEN
5727 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5728 MATCH_MP_TAC MONO_FORALL THEN
5729 X_GEN_TAC `e:real` THEN ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
5732 let BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE = prove
5733 (`!f:real^M->real^N g (h:real^N->real^P->real^Q) s.
5734 f uniformly_continuous_on s /\ g uniformly_continuous_on s /\
5735 bilinear h /\ bounded(IMAGE f s) /\ bounded(IMAGE g s)
5736 ==> (\x. h (f x) (g x)) uniformly_continuous_on s`,
5737 REPEAT STRIP_TAC THEN REWRITE_TAC[uniformly_continuous_on; dist] THEN
5738 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5740 `!a b c d. (h:real^N->real^P->real^Q) a b - h c d =
5741 h (a - c) b + h c (b - d)`
5742 (fun th -> ONCE_REWRITE_TAC[th])
5744 [FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP BILINEAR_LSUB th]) THEN
5745 FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP BILINEAR_RSUB th]) THEN
5748 FIRST_X_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o
5749 MATCH_MP BILINEAR_BOUNDED_POS) THEN
5750 UNDISCH_TAC `bounded(IMAGE (g:real^M->real^P) s)` THEN
5751 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
5752 REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN
5753 DISCH_THEN(X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) THEN
5754 DISCH_THEN(X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC) THEN
5755 UNDISCH_TAC `(g:real^M->real^P) uniformly_continuous_on s` THEN
5756 UNDISCH_TAC `(f:real^M->real^N) uniformly_continuous_on s` THEN
5757 REWRITE_TAC[uniformly_continuous_on] THEN
5758 DISCH_THEN(MP_TAC o SPEC `e / &2 / &2 / B / B2`) THEN
5759 ASM_SIMP_TAC[REAL_LT_DIV; REAL_HALF; dist] THEN
5760 DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN
5761 DISCH_THEN(MP_TAC o SPEC `e / &2 / &2 / B / B1`) THEN
5762 ASM_SIMP_TAC[REAL_LT_DIV; REAL_HALF; dist] THEN
5763 DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN
5764 EXISTS_TAC `min d1 d2` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
5765 MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN
5766 REPEAT(FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `y:real^M`])) THEN
5767 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
5768 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC
5769 `B * e / &2 / &2 / B / B2 * B2 + B * B1 * e / &2 / &2 / B / B1` THEN
5771 [MATCH_MP_TAC(NORM_ARITH
5772 `norm(x) <= a /\ norm(y) <= b ==> norm(x + y:real^N) <= a + b`) THEN
5774 FIRST_X_ASSUM(fun th -> W(MP_TAC o PART_MATCH lhand th o lhand o snd)) THEN
5775 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
5776 MATCH_MP_TAC REAL_LE_LMUL THEN ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN
5777 MATCH_MP_TAC REAL_LE_MUL2 THEN
5778 ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_POS_LE];
5779 ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN
5780 ASM_REAL_ARITH_TAC]);;
5782 let UNIFORMLY_CONTINUOUS_ON_MUL = prove
5783 (`!f g:real^M->real^N s.
5784 (lift o f) uniformly_continuous_on s /\ g uniformly_continuous_on s /\
5785 bounded(IMAGE (lift o f) s) /\ bounded(IMAGE g s)
5786 ==> (\x. f x % g x) uniformly_continuous_on s`,
5787 REPEAT STRIP_TAC THEN
5789 [`lift o (f:real^M->real)`; `g:real^M->real^N`;
5790 `\c (v:real^N). drop c % v`; `s:real^M->bool`]
5791 BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE) THEN
5792 ASM_REWRITE_TAC[o_THM; LIFT_DROP] THEN DISCH_THEN MATCH_MP_TAC THEN
5793 REWRITE_TAC[bilinear; linear; DROP_ADD; DROP_CMUL] THEN VECTOR_ARITH_TAC);;
5795 let UNIFORMLY_CONTINUOUS_ON_CMUL = prove
5796 (`!f c s. f uniformly_continuous_on s
5797 ==> (\x. c % f(x)) uniformly_continuous_on s`,
5798 REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY] THEN
5799 REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
5800 DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
5801 ASM_REWRITE_TAC[] THEN
5802 DISCH_THEN(MP_TAC o MATCH_MP LIM_CMUL) THEN
5803 ASM_SIMP_TAC[VECTOR_SUB_LDISTRIB; VECTOR_MUL_RZERO]);;
5805 let UNIFORMLY_CONTINUOUS_ON_VMUL = prove
5806 (`!s:real^M->bool c v:real^N.
5807 (lift o c) uniformly_continuous_on s
5808 ==> (\x. c x % v) uniformly_continuous_on s`,
5810 DISCH_THEN(MP_TAC o ISPEC `\x. (drop x % v:real^N)` o MATCH_MP
5811 (REWRITE_RULE[IMP_CONJ] UNIFORMLY_CONTINUOUS_ON_COMPOSE)) THEN
5812 REWRITE_TAC[o_DEF; LIFT_DROP] THEN DISCH_THEN MATCH_MP_TAC THEN
5813 MATCH_MP_TAC LINEAR_UNIFORMLY_CONTINUOUS_ON THEN
5814 MATCH_MP_TAC LINEAR_VMUL_DROP THEN REWRITE_TAC[LINEAR_ID]);;
5816 let UNIFORMLY_CONTINUOUS_ON_NEG = prove
5817 (`!f s. f uniformly_continuous_on s
5818 ==> (\x. --(f x)) uniformly_continuous_on s`,
5819 ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN
5820 REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_CMUL]);;
5822 let UNIFORMLY_CONTINUOUS_ON_ADD = prove
5823 (`!f g s. f uniformly_continuous_on s /\ g uniformly_continuous_on s
5824 ==> (\x. f(x) + g(x)) uniformly_continuous_on s`,
5825 REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY] THEN
5826 REWRITE_TAC[AND_FORALL_THM] THEN
5827 REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
5828 DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
5829 ASM_REWRITE_TAC[o_DEF] THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN
5830 MATCH_MP_TAC EQ_IMP THEN
5831 REWRITE_TAC[VECTOR_ADD_LID] THEN AP_THM_TAC THEN BINOP_TAC THEN
5832 REWRITE_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC);;
5834 let UNIFORMLY_CONTINUOUS_ON_SUB = prove
5835 (`!f g s. f uniformly_continuous_on s /\ g uniformly_continuous_on s
5836 ==> (\x. f(x) - g(x)) uniformly_continuous_on s`,
5837 REWRITE_TAC[VECTOR_SUB] THEN
5838 SIMP_TAC[UNIFORMLY_CONTINUOUS_ON_NEG; UNIFORMLY_CONTINUOUS_ON_ADD]);;
5840 let UNIFORMLY_CONTINUOUS_ON_VSUM = prove
5841 (`!t f s. FINITE s /\ (!a. a IN s ==> (f a) uniformly_continuous_on t)
5842 ==> (\x. vsum s (\a. f a x)) uniformly_continuous_on t`,
5843 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
5844 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
5845 SIMP_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY; VSUM_CLAUSES;
5846 UNIFORMLY_CONTINUOUS_ON_CONST; UNIFORMLY_CONTINUOUS_ON_ADD; ETA_AX]);;
5848 (* ------------------------------------------------------------------------- *)
5849 (* Identity function is continuous in every sense. *)
5850 (* ------------------------------------------------------------------------- *)
5852 let CONTINUOUS_WITHIN_ID = prove
5853 (`!a s. (\x. x) continuous (at a within s)`,
5854 REWRITE_TAC[continuous_within] THEN MESON_TAC[]);;
5856 let CONTINUOUS_AT_ID = prove
5857 (`!a. (\x. x) continuous (at a)`,
5858 REWRITE_TAC[continuous_at] THEN MESON_TAC[]);;
5860 let CONTINUOUS_ON_ID = prove
5861 (`!s. (\x. x) continuous_on s`,
5862 REWRITE_TAC[continuous_on] THEN MESON_TAC[]);;
5864 let UNIFORMLY_CONTINUOUS_ON_ID = prove
5865 (`!s. (\x. x) uniformly_continuous_on s`,
5866 REWRITE_TAC[uniformly_continuous_on] THEN MESON_TAC[]);;
5868 (* ------------------------------------------------------------------------- *)
5869 (* Continuity of all kinds is preserved under composition. *)
5870 (* ------------------------------------------------------------------------- *)
5872 let CONTINUOUS_WITHIN_COMPOSE = prove
5873 (`!f g x s. f continuous (at x within s) /\
5874 g continuous (at (f x) within IMAGE f s)
5875 ==> (g o f) continuous (at x within s)`,
5876 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within; o_THM; IN_IMAGE] THEN
5877 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5878 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
5881 let CONTINUOUS_AT_COMPOSE = prove
5882 (`!f g x. f continuous (at x) /\ g continuous (at (f x))
5883 ==> (g o f) continuous (at x)`,
5884 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
5885 MESON_TAC[CONTINUOUS_WITHIN_COMPOSE; IN_IMAGE; CONTINUOUS_WITHIN_SUBSET;
5886 SUBSET_UNIV; IN_UNIV]);;
5888 let CONTINUOUS_ON_COMPOSE = prove
5889 (`!f g s. f continuous_on s /\ g continuous_on (IMAGE f s)
5890 ==> (g o f) continuous_on s`,
5891 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
5892 MESON_TAC[IN_IMAGE; CONTINUOUS_WITHIN_COMPOSE]);;
5894 (* ------------------------------------------------------------------------- *)
5895 (* Continuity in terms of open preimages. *)
5896 (* ------------------------------------------------------------------------- *)
5898 let CONTINUOUS_WITHIN_OPEN = prove
5899 (`!f:real^M->real^N x u.
5900 f continuous (at x within u) <=>
5901 !t. open t /\ f(x) IN t
5902 ==> ?s. open s /\ x IN s /\
5903 !x'. x' IN s /\ x' IN u ==> f(x') IN t`,
5904 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within] THEN EQ_TAC THENL
5905 [DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN
5906 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
5907 GEN_REWRITE_TAC LAND_CONV [open_def] THEN
5908 DISCH_THEN(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN
5909 ASM_MESON_TAC[IN_BALL; DIST_SYM; OPEN_BALL; CENTRE_IN_BALL; DIST_SYM];
5910 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5911 FIRST_X_ASSUM(MP_TAC o SPEC `ball((f:real^M->real^N) x,e)`) THEN
5912 ASM_SIMP_TAC[OPEN_BALL; CENTRE_IN_BALL] THEN
5913 MESON_TAC[open_def; IN_BALL; REAL_LT_TRANS; DIST_SYM]]);;
5915 let CONTINUOUS_AT_OPEN = prove
5916 (`!f:real^M->real^N x.
5917 f continuous (at x) <=>
5918 !t. open t /\ f(x) IN t
5919 ==> ?s. open s /\ x IN s /\
5920 !x'. x' IN s ==> f(x') IN t`,
5921 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_at] THEN EQ_TAC THENL
5922 [DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN
5923 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
5924 GEN_REWRITE_TAC LAND_CONV [open_def] THEN
5925 DISCH_THEN(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN
5926 ASM_MESON_TAC[IN_BALL; DIST_SYM; OPEN_BALL; CENTRE_IN_BALL];
5927 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5928 FIRST_X_ASSUM(MP_TAC o SPEC `ball((f:real^M->real^N) x,e)`) THEN
5929 ASM_SIMP_TAC[OPEN_BALL; CENTRE_IN_BALL] THEN
5930 MESON_TAC[open_def; IN_BALL; REAL_LT_TRANS; DIST_SYM]]);;
5932 let CONTINUOUS_ON_OPEN_GEN = prove
5933 (`!f:real^M->real^N s t.
5935 ==> (f continuous_on s <=>
5936 !u. open_in (subtopology euclidean t) u
5937 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN u})`,
5938 REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_on] THEN EQ_TAC THENL
5939 [REWRITE_TAC[open_in; SUBSET; IN_ELIM_THM] THEN
5940 DISCH_TAC THEN X_GEN_TAC `u:real^N->bool` THEN STRIP_TAC THEN
5941 CONJ_TAC THENL [ASM_MESON_TAC[DIST_REFL]; ALL_TAC] THEN
5942 X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN
5943 FIRST_X_ASSUM(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN ASM SET_TAC[];
5944 DISCH_TAC THEN X_GEN_TAC `x:real^M` THEN
5945 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5946 FIRST_X_ASSUM(MP_TAC o
5947 SPEC `ball((f:real^M->real^N) x,e) INTER t`) THEN
5949 [ASM_MESON_TAC[OPEN_IN_OPEN; INTER_COMM; OPEN_BALL]; ALL_TAC] THEN
5950 REWRITE_TAC[open_in; SUBSET; IN_INTER; IN_ELIM_THM; IN_BALL; IN_IMAGE] THEN
5951 REWRITE_TAC[AND_FORALL_THM] THEN DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN
5952 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE]) THEN
5953 ASM_MESON_TAC[DIST_REFL; DIST_SYM]]);;
5955 let CONTINUOUS_ON_OPEN = prove
5956 (`!f:real^M->real^N s.
5957 f continuous_on s <=>
5958 !t. open_in (subtopology euclidean (IMAGE f s)) t
5959 ==> open_in (subtopology euclidean s) {x | x IN s /\ f(x) IN t}`,
5960 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_OPEN_GEN THEN
5961 REWRITE_TAC[SUBSET_REFL]);;
5963 let CONTINUOUS_OPEN_IN_PREIMAGE_GEN = prove
5964 (`!f:real^M->real^N s t u.
5965 f continuous_on s /\ IMAGE f s SUBSET t /\
5966 open_in (subtopology euclidean t) u
5967 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN u}`,
5968 MESON_TAC[CONTINUOUS_ON_OPEN_GEN]);;
5970 let CONTINUOUS_ON_IMP_OPEN_IN = prove
5971 (`!f:real^M->real^N s t.
5972 f continuous_on s /\
5973 open_in (subtopology euclidean (IMAGE f s)) t
5974 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`,
5975 MESON_TAC[CONTINUOUS_ON_OPEN]);;
5977 (* ------------------------------------------------------------------------- *)
5978 (* Similarly in terms of closed sets. *)
5979 (* ------------------------------------------------------------------------- *)
5981 let CONTINUOUS_ON_CLOSED_GEN = prove
5982 (`!f:real^M->real^N s t.
5984 ==> (f continuous_on s <=>
5985 !u. closed_in (subtopology euclidean t) u
5986 ==> closed_in (subtopology euclidean s)
5987 {x | x IN s /\ f x IN u})`,
5988 REPEAT STRIP_TAC THEN FIRST_ASSUM(fun th ->
5989 ONCE_REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THEN
5990 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `u:real^N->bool` THEN
5991 FIRST_X_ASSUM(MP_TAC o SPEC `t DIFF u:real^N->bool`) THENL
5992 [REWRITE_TAC[closed_in]; REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ]] THEN
5993 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
5994 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
5995 ASM_REWRITE_TAC[SUBSET_RESTRICT] THEN
5996 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]);;
5998 let CONTINUOUS_ON_CLOSED = prove
5999 (`!f:real^M->real^N s.
6000 f continuous_on s <=>
6001 !t. closed_in (subtopology euclidean (IMAGE f s)) t
6002 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f(x) IN t}`,
6003 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CLOSED_GEN THEN
6004 REWRITE_TAC[SUBSET_REFL]);;
6006 let CONTINUOUS_CLOSED_IN_PREIMAGE_GEN = prove
6007 (`!f:real^M->real^N s t u.
6008 f continuous_on s /\ IMAGE f s SUBSET t /\
6009 closed_in (subtopology euclidean t) u
6010 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN u}`,
6011 MESON_TAC[CONTINUOUS_ON_CLOSED_GEN]);;
6013 let CONTINUOUS_ON_IMP_CLOSED_IN = prove
6014 (`!f:real^M->real^N s t.
6015 f continuous_on s /\
6016 closed_in (subtopology euclidean (IMAGE f s)) t
6017 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`,
6018 MESON_TAC[CONTINUOUS_ON_CLOSED]);;
6020 (* ------------------------------------------------------------------------- *)
6021 (* Half-global and completely global cases. *)
6022 (* ------------------------------------------------------------------------- *)
6024 let CONTINUOUS_OPEN_IN_PREIMAGE = prove
6026 f continuous_on s /\ open t
6027 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`,
6028 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE
6029 `x IN s /\ f x IN t <=> x IN s /\ f x IN (t INTER IMAGE f s)`] THEN
6030 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CONTINUOUS_ON_OPEN]) THEN
6031 ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN
6032 ASM_REWRITE_TAC[]);;
6034 let CONTINUOUS_CLOSED_IN_PREIMAGE = prove
6036 f continuous_on s /\ closed t
6037 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`,
6038 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE
6039 `x IN s /\ f x IN t <=> x IN s /\ f x IN (t INTER IMAGE f s)`] THEN
6040 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CONTINUOUS_ON_CLOSED]) THEN
6041 ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC CLOSED_IN_CLOSED_INTER THEN
6042 ASM_REWRITE_TAC[]);;
6044 let CONTINUOUS_OPEN_PREIMAGE = prove
6045 (`!f:real^M->real^N s t.
6046 f continuous_on s /\ open s /\ open t
6047 ==> open {x | x IN s /\ f(x) IN t}`,
6048 REPEAT STRIP_TAC THEN
6049 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_ON_OPEN]) THEN
6050 REWRITE_TAC [OPEN_IN_OPEN] THEN
6051 DISCH_THEN(MP_TAC o SPEC `IMAGE (f:real^M->real^N) s INTER t`) THEN
6053 [EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC [];
6055 SUBGOAL_THEN `{x | x IN s /\ (f:real^M->real^N) x IN t} =
6056 s INTER t'` SUBST1_TAC THENL
6057 [ASM SET_TAC []; ASM_MESON_TAC [OPEN_INTER]]]);;
6059 let CONTINUOUS_CLOSED_PREIMAGE = prove
6060 (`!f:real^M->real^N s t.
6061 f continuous_on s /\ closed s /\ closed t
6062 ==> closed {x | x IN s /\ f(x) IN t}`,
6063 REPEAT STRIP_TAC THEN
6064 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_ON_CLOSED]) THEN
6065 REWRITE_TAC [CLOSED_IN_CLOSED] THEN
6066 DISCH_THEN(MP_TAC o SPEC `IMAGE (f:real^M->real^N) s INTER t`) THEN
6068 [EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC [];
6070 SUBGOAL_THEN `{x | x IN s /\ (f:real^M->real^N) x IN t} =
6071 s INTER t'` SUBST1_TAC THENL
6072 [ASM SET_TAC []; ASM_MESON_TAC [CLOSED_INTER]]]);;
6074 let CONTINUOUS_OPEN_PREIMAGE_UNIV = prove
6075 (`!f:real^M->real^N s.
6076 (!x. f continuous (at x)) /\ open s ==> open {x | f(x) IN s}`,
6077 REPEAT STRIP_TAC THEN
6078 MP_TAC(SPECL [`f:real^M->real^N`; `(:real^M)`; `s:real^N->bool`]
6079 CONTINUOUS_OPEN_PREIMAGE) THEN
6080 ASM_SIMP_TAC[OPEN_UNIV; IN_UNIV; CONTINUOUS_AT_IMP_CONTINUOUS_ON]);;
6082 let CONTINUOUS_CLOSED_PREIMAGE_UNIV = prove
6083 (`!f:real^M->real^N s.
6084 (!x. f continuous (at x)) /\ closed s ==> closed {x | f(x) IN s}`,
6085 REPEAT STRIP_TAC THEN
6086 MP_TAC(SPECL [`f:real^M->real^N`; `(:real^M)`; `s:real^N->bool`]
6087 CONTINUOUS_CLOSED_PREIMAGE) THEN
6088 ASM_SIMP_TAC[CLOSED_UNIV; IN_UNIV; CONTINUOUS_AT_IMP_CONTINUOUS_ON]);;
6090 let CONTINUOUS_OPEN_IN_PREIMAGE_EQ = prove
6091 (`!f:real^M->real^N s.
6092 f continuous_on s <=>
6093 !t. open t ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`,
6094 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[CONTINUOUS_OPEN_IN_PREIMAGE] THEN
6095 REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN DISCH_TAC THEN
6096 X_GEN_TAC `t:real^N->bool` THEN GEN_REWRITE_TAC LAND_CONV [OPEN_IN_OPEN] THEN
6097 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
6098 FIRST_X_ASSUM(MP_TAC o SPEC `u:real^N->bool`) THEN
6099 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[]);;
6101 let CONTINUOUS_CLOSED_IN_PREIMAGE_EQ = prove
6102 (`!f:real^M->real^N s.
6103 f continuous_on s <=>
6105 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`,
6106 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE] THEN
6107 REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN DISCH_TAC THEN
6108 X_GEN_TAC `t:real^N->bool` THEN
6109 GEN_REWRITE_TAC LAND_CONV [CLOSED_IN_CLOSED] THEN
6110 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
6111 FIRST_X_ASSUM(MP_TAC o SPEC `u:real^N->bool`) THEN
6112 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[]);;
6114 (* ------------------------------------------------------------------------- *)
6115 (* Linear functions are (uniformly) continuous on any set. *)
6116 (* ------------------------------------------------------------------------- *)
6118 let LINEAR_LIM_0 = prove
6119 (`!f. linear f ==> (f --> vec 0) (at (vec 0))`,
6120 REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_AT] THEN
6121 FIRST_X_ASSUM(MP_TAC o MATCH_MP LINEAR_BOUNDED_POS) THEN
6122 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
6123 X_GEN_TAC `e:real` THEN DISCH_TAC THEN EXISTS_TAC `e / B` THEN
6124 ASM_SIMP_TAC[REAL_LT_DIV] THEN REWRITE_TAC[dist; VECTOR_SUB_RZERO] THEN
6125 ASM_MESON_TAC[REAL_MUL_SYM; REAL_LET_TRANS; REAL_LT_RDIV_EQ]);;
6127 let LINEAR_CONTINUOUS_AT = prove
6128 (`!f:real^M->real^N a. linear f ==> f continuous (at a)`,
6129 REPEAT STRIP_TAC THEN
6130 MP_TAC(ISPEC `\x. (f:real^M->real^N) (a + x) - f(a)` LINEAR_LIM_0) THEN
6132 [POP_ASSUM MP_TAC THEN SIMP_TAC[linear] THEN
6133 REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC;
6135 REWRITE_TAC[GSYM LIM_NULL; CONTINUOUS_AT] THEN
6136 GEN_REWRITE_TAC RAND_CONV [LIM_AT_ZERO] THEN SIMP_TAC[]);;
6138 let LINEAR_CONTINUOUS_WITHIN = prove
6139 (`!f:real^M->real^N s x. linear f ==> f continuous (at x within s)`,
6140 SIMP_TAC[CONTINUOUS_AT_WITHIN; LINEAR_CONTINUOUS_AT]);;
6142 let LINEAR_CONTINUOUS_ON = prove
6143 (`!f:real^M->real^N s. linear f ==> f continuous_on s`,
6144 MESON_TAC[LINEAR_CONTINUOUS_AT; CONTINUOUS_AT_IMP_CONTINUOUS_ON]);;
6146 let LINEAR_CONTINUOUS_COMPOSE = prove
6147 (`!net f:A->real^N g:real^N->real^P.
6148 f continuous net /\ linear g ==> (\x. g(f x)) continuous net`,
6149 REWRITE_TAC[continuous; LIM_LINEAR]);;
6151 let LINEAR_CONTINUOUS_ON_COMPOSE = prove
6152 (`!f:real^M->real^N g:real^N->real^P s.
6153 f continuous_on s /\ linear g ==> (\x. g(f x)) continuous_on s`,
6154 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
6155 LINEAR_CONTINUOUS_COMPOSE]);;
6157 let CONTINUOUS_LIFT_COMPONENT_COMPOSE = prove
6158 (`!net f:A->real^N i. f continuous net ==> (\x. lift(f x$i)) continuous net`,
6160 SUBGOAL_THEN `linear(\x:real^N. lift (x$i))` MP_TAC THENL
6161 [REWRITE_TAC[LINEAR_LIFT_COMPONENT]; REWRITE_TAC[GSYM IMP_CONJ_ALT]] THEN
6162 REWRITE_TAC[LINEAR_CONTINUOUS_COMPOSE]);;
6164 let CONTINUOUS_ON_LIFT_COMPONENT_COMPOSE = prove
6165 (`!f:real^M->real^N s.
6167 ==> (\x. lift (f x$i)) continuous_on s`,
6168 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
6169 CONTINUOUS_LIFT_COMPONENT_COMPOSE]);;
6171 (* ------------------------------------------------------------------------- *)
6172 (* Also bilinear functions, in composition form. *)
6173 (* ------------------------------------------------------------------------- *)
6175 let BILINEAR_CONTINUOUS_COMPOSE = prove
6176 (`!net f:A->real^M g:A->real^N h:real^M->real^N->real^P.
6177 f continuous net /\ g continuous net /\ bilinear h
6178 ==> (\x. h (f x) (g x)) continuous net`,
6179 REWRITE_TAC[continuous; LIM_BILINEAR]);;
6181 let BILINEAR_CONTINUOUS_ON_COMPOSE = prove
6182 (`!f g h s. f continuous_on s /\ g continuous_on s /\ bilinear h
6183 ==> (\x. h (f x) (g x)) continuous_on s`,
6184 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
6185 BILINEAR_CONTINUOUS_COMPOSE]);;
6187 let BILINEAR_DOT = prove
6188 (`bilinear (\x y:real^N. lift(x dot y))`,
6189 REWRITE_TAC[bilinear; linear; DOT_LADD; DOT_RADD; DOT_LMUL; DOT_RMUL] THEN
6190 REWRITE_TAC[LIFT_ADD; LIFT_CMUL]);;
6192 let CONTINUOUS_LIFT_DOT2 = prove
6193 (`!net f g:A->real^N.
6194 f continuous net /\ g continuous net
6195 ==> (\x. lift(f x dot g x)) continuous net`,
6196 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE
6197 [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`]
6198 BILINEAR_CONTINUOUS_COMPOSE) BILINEAR_DOT)) THEN REWRITE_TAC[]);;
6200 let CONTINUOUS_ON_LIFT_DOT2 = prove
6201 (`!f:real^M->real^N g s.
6202 f continuous_on s /\ g continuous_on s
6203 ==> (\x. lift(f x dot g x)) continuous_on s`,
6204 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE
6205 [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`]
6206 BILINEAR_CONTINUOUS_ON_COMPOSE) BILINEAR_DOT)) THEN REWRITE_TAC[]);;
6208 (* ------------------------------------------------------------------------- *)
6209 (* Preservation of compactness and connectedness under continuous function. *)
6210 (* ------------------------------------------------------------------------- *)
6212 let COMPACT_CONTINUOUS_IMAGE = prove
6213 (`!f:real^M->real^N s.
6214 f continuous_on s /\ compact s ==> compact(IMAGE f s)`,
6215 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on; compact] THEN
6216 STRIP_TAC THEN X_GEN_TAC `y:num->real^N` THEN
6217 REWRITE_TAC[IN_IMAGE; SKOLEM_THM; FORALL_AND_THM] THEN
6218 DISCH_THEN(X_CHOOSE_THEN `x:num->real^M` STRIP_ASSUME_TAC) THEN
6219 FIRST_X_ASSUM(MP_TAC o SPEC `x:num->real^M`) THEN ASM_REWRITE_TAC[] THEN
6220 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
6221 X_GEN_TAC `r:num->num` THEN
6222 DISCH_THEN(X_CHOOSE_THEN `l:real^M` STRIP_ASSUME_TAC) THEN
6223 EXISTS_TAC `(f:real^M->real^N) l` THEN ASM_REWRITE_TAC[] THEN
6224 CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
6225 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
6226 FIRST_X_ASSUM(MP_TAC o SPEC `l:real^M`) THEN
6227 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
6228 DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
6229 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
6230 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
6231 DISCH_THEN(MP_TAC o SPEC `d:real`) THEN ASM_REWRITE_TAC[o_THM] THEN
6234 let COMPACT_TRANSLATION = prove
6235 (`!s a:real^N. compact s ==> compact (IMAGE (\x. a + x) s)`,
6236 SIMP_TAC[COMPACT_CONTINUOUS_IMAGE; CONTINUOUS_ON_ADD;
6237 CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]);;
6239 let COMPACT_TRANSLATION_EQ = prove
6240 (`!a s. compact (IMAGE (\x:real^N. a + x) s) <=> compact s`,
6241 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[COMPACT_TRANSLATION] THEN
6242 DISCH_THEN(MP_TAC o ISPEC `--a:real^N` o MATCH_MP COMPACT_TRANSLATION) THEN
6243 REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID;
6244 VECTOR_ARITH `--a + a + x:real^N = x`]);;
6246 add_translation_invariants [COMPACT_TRANSLATION_EQ];;
6248 let COMPACT_LINEAR_IMAGE = prove
6249 (`!f:real^M->real^N s. compact s /\ linear f ==> compact(IMAGE f s)`,
6250 SIMP_TAC[LINEAR_CONTINUOUS_ON; COMPACT_CONTINUOUS_IMAGE]);;
6252 let COMPACT_LINEAR_IMAGE_EQ = prove
6253 (`!f s. linear f /\ (!x y. f x = f y ==> x = y)
6254 ==> (compact (IMAGE f s) <=> compact s)`,
6255 MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE COMPACT_LINEAR_IMAGE));;
6257 add_linear_invariants [COMPACT_LINEAR_IMAGE_EQ];;
6259 let CONNECTED_CONTINUOUS_IMAGE = prove
6260 (`!f:real^M->real^N s.
6261 f continuous_on s /\ connected s ==> connected(IMAGE f s)`,
6262 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN
6263 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6264 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
6265 REWRITE_TAC[CONNECTED_CLOPEN; NOT_FORALL_THM; NOT_IMP; DE_MORGAN_THM] THEN
6266 REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
6267 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
6268 FIRST_X_ASSUM(fun th -> MP_TAC(SPEC `t:real^N->bool` th) THEN
6269 MP_TAC(SPEC `IMAGE (f:real^M->real^N) s DIFF t` th)) THEN
6270 ASM_REWRITE_TAC[] THEN
6271 SUBGOAL_THEN `{x | x IN s /\ (f:real^M->real^N) x IN IMAGE f s DIFF t} =
6272 s DIFF {x | x IN s /\ f x IN t}`
6274 [UNDISCH_TAC `t SUBSET IMAGE (f:real^M->real^N) s` THEN
6275 REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DIFF; IN_ELIM_THM; SUBSET] THEN
6277 REPEAT STRIP_TAC THEN
6278 EXISTS_TAC `{x | x IN s /\ (f:real^M->real^N) x IN t}` THEN
6279 ASM_REWRITE_TAC[] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
6280 REWRITE_TAC[IN_IMAGE; SUBSET; IN_ELIM_THM; NOT_IN_EMPTY; EXTENSION] THEN
6283 let CONNECTED_TRANSLATION = prove
6284 (`!a s. connected s ==> connected (IMAGE (\x:real^N. a + x) s)`,
6285 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN
6286 ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST]);;
6288 let CONNECTED_TRANSLATION_EQ = prove
6289 (`!a s. connected (IMAGE (\x:real^N. a + x) s) <=> connected s`,
6290 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[CONNECTED_TRANSLATION] THEN
6291 DISCH_THEN(MP_TAC o ISPEC `--a:real^N` o MATCH_MP CONNECTED_TRANSLATION) THEN
6292 REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID;
6293 VECTOR_ARITH `--a + a + x:real^N = x`]);;
6295 add_translation_invariants [CONNECTED_TRANSLATION_EQ];;
6297 let CONNECTED_LINEAR_IMAGE = prove
6298 (`!f:real^M->real^N s. connected s /\ linear f ==> connected(IMAGE f s)`,
6299 SIMP_TAC[LINEAR_CONTINUOUS_ON; CONNECTED_CONTINUOUS_IMAGE]);;
6301 let CONNECTED_LINEAR_IMAGE_EQ = prove
6302 (`!f s. linear f /\ (!x y. f x = f y ==> x = y)
6303 ==> (connected (IMAGE f s) <=> connected s)`,
6304 MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE CONNECTED_LINEAR_IMAGE));;
6306 add_linear_invariants [CONNECTED_LINEAR_IMAGE_EQ];;
6308 (* ------------------------------------------------------------------------- *)
6309 (* Preservation properties for pasted sets (Cartesian products). *)
6310 (* ------------------------------------------------------------------------- *)
6312 let BOUNDED_PCROSS_EQ = prove
6313 (`!s:real^M->bool t:real^N->bool.
6314 bounded (s PCROSS t) <=>
6315 s = {} \/ t = {} \/ bounded s /\ bounded t`,
6316 REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN
6317 ASM_CASES_TAC `s:real^M->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
6318 ASM_CASES_TAC `t:real^N->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
6319 REWRITE_TAC[SET_RULE `{f x y |x,y| F} = {}`; BOUNDED_EMPTY] THEN
6320 RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN
6321 REWRITE_TAC[bounded; FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN
6322 ASM_MESON_TAC[NORM_LE_PASTECART; REAL_LE_TRANS; NORM_PASTECART_LE;
6325 let BOUNDED_PCROSS = prove
6326 (`!s:real^M->bool t:real^N->bool.
6327 bounded s /\ bounded t ==> bounded (s PCROSS t)`,
6328 SIMP_TAC[BOUNDED_PCROSS_EQ]);;
6330 let CLOSED_PCROSS_EQ = prove
6331 (`!s:real^M->bool t:real^N->bool.
6332 closed (s PCROSS t) <=>
6333 s = {} \/ t = {} \/ closed s /\ closed t`,
6334 REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN MAP_EVERY ASM_CASES_TAC
6335 [`s:real^M->bool = {}`; `t:real^N->bool = {}`] THEN
6336 ASM_REWRITE_TAC[NOT_IN_EMPTY; CLOSED_EMPTY; SET_RULE
6337 `{f x y |x,y| F} = {}`] THEN
6338 REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS; LIM_SEQUENTIALLY] THEN
6339 REWRITE_TAC[FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN
6340 REWRITE_TAC[IN_ELIM_THM; SKOLEM_THM; FORALL_AND_THM] THEN
6341 ONCE_REWRITE_TAC[GSYM FUN_EQ_THM] THEN
6342 REWRITE_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN
6343 SIMP_TAC[TAUT `((p /\ q) /\ r) /\ s ==> t <=> r ==> p /\ q /\ s ==> t`] THEN
6344 ONCE_REWRITE_TAC[MESON[]
6345 `(!a b c d e. P a b c d e) <=> (!d e b c a. P a b c d e)`] THEN
6346 REWRITE_TAC[FORALL_UNWIND_THM2] THEN
6347 RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN EQ_TAC THENL
6348 [GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV)
6349 [TAUT `p ==> q /\ r <=> (p ==> q) /\ (p ==> r)`; FORALL_AND_THM] THEN
6350 MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
6351 [ALL_TAC; GEN_REWRITE_TAC LAND_CONV [SWAP_FORALL_THM]] THEN
6352 MATCH_MP_TAC MONO_FORALL THEN REPEAT STRIP_TAC THEN
6353 FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC(MESON[]
6354 `(?x. P x (\n. x)) ==> (?s x. P x s)`) THEN
6355 ASM_MESON_TAC[DIST_PASTECART_CANCEL];
6356 ONCE_REWRITE_TAC[MESON[]
6357 `(!x l. P x l) /\ (!y m. Q y m) <=> (!x y l m. P x l /\ Q y m)`] THEN
6358 REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
6359 REWRITE_TAC[dist; PASTECART_SUB] THEN
6360 ASM_MESON_TAC[NORM_LE_PASTECART; REAL_LET_TRANS]]);;
6362 let CLOSED_PCROSS = prove
6363 (`!s:real^M->bool t:real^N->bool.
6364 closed s /\ closed t ==> closed (s PCROSS t)`,
6365 SIMP_TAC[CLOSED_PCROSS_EQ]);;
6367 let COMPACT_PCROSS_EQ = prove
6368 (`!s:real^M->bool t:real^N->bool.
6369 compact (s PCROSS t) <=>
6370 s = {} \/ t = {} \/ compact s /\ compact t`,
6371 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_PCROSS_EQ;
6372 BOUNDED_PCROSS_EQ] THEN
6375 let COMPACT_PCROSS = prove
6376 (`!s:real^M->bool t:real^N->bool.
6377 compact s /\ compact t ==> compact (s PCROSS t)`,
6378 SIMP_TAC[COMPACT_PCROSS_EQ]);;
6380 let OPEN_PCROSS_EQ = prove
6381 (`!s:real^M->bool t:real^N->bool.
6382 open (s PCROSS t) <=>
6383 s = {} \/ t = {} \/ open s /\ open t`,
6384 REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN
6385 ASM_CASES_TAC `s:real^M->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
6386 ASM_CASES_TAC `t:real^N->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
6387 REWRITE_TAC[SET_RULE `{f x y |x,y| F} = {}`; OPEN_EMPTY] THEN
6388 RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN
6390 [REWRITE_TAC[open_def; FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN
6391 ASM_MESON_TAC[DIST_PASTECART_CANCEL];
6392 REWRITE_TAC[OPEN_CLOSED] THEN STRIP_TAC THEN
6394 `UNIV DIFF {pastecart x y | x IN s /\ y IN t} =
6395 {pastecart x y | x IN ((:real^M) DIFF s) /\ y IN (:real^N)} UNION
6396 {pastecart x y | x IN (:real^M) /\ y IN ((:real^N) DIFF t)}`
6398 [REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNION; FORALL_PASTECART; IN_UNIV] THEN
6399 REWRITE_TAC[IN_ELIM_THM; PASTECART_EQ; FSTCART_PASTECART;
6400 SNDCART_PASTECART] THEN MESON_TAC[];
6401 SIMP_TAC[GSYM PCROSS] THEN MATCH_MP_TAC CLOSED_UNION THEN CONJ_TAC THEN
6402 MATCH_MP_TAC CLOSED_PCROSS THEN ASM_REWRITE_TAC[CLOSED_UNIV]]]);;
6404 let OPEN_PCROSS = prove
6405 (`!s:real^M->bool t:real^N->bool.
6406 open s /\ open t ==> open (s PCROSS t)`,
6407 SIMP_TAC[OPEN_PCROSS_EQ]);;
6409 let OPEN_IN_PCROSS = prove
6410 (`!s s':real^M->bool t t':real^N->bool.
6411 open_in (subtopology euclidean s) s' /\
6412 open_in (subtopology euclidean t) t'
6413 ==> open_in (subtopology euclidean (s PCROSS t)) (s' PCROSS t')`,
6414 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_THEN(CONJUNCTS_THEN2
6415 (X_CHOOSE_THEN `s'':real^M->bool` STRIP_ASSUME_TAC)
6416 (X_CHOOSE_THEN `t'':real^N->bool` STRIP_ASSUME_TAC)) THEN
6417 EXISTS_TAC `(s'':real^M->bool) PCROSS (t'':real^N->bool)` THEN
6418 ASM_SIMP_TAC[OPEN_PCROSS; EXTENSION; FORALL_PASTECART] THEN
6419 REWRITE_TAC[IN_INTER; PASTECART_IN_PCROSS] THEN ASM SET_TAC[]);;
6421 let PASTECART_IN_INTERIOR_SUBTOPOLOGY = prove
6422 (`!s t u x:real^M y:real^N.
6423 pastecart x y IN u /\ open_in (subtopology euclidean (s PCROSS t)) u
6424 ==> ?v w. open_in (subtopology euclidean s) v /\ x IN v /\
6425 open_in (subtopology euclidean t) w /\ y IN w /\
6426 (v PCROSS w) SUBSET u`,
6427 REWRITE_TAC[open_in; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN
6428 REPEAT STRIP_TAC THEN
6429 FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `y:real^N`]) THEN
6430 ASM_REWRITE_TAC[] THEN
6431 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
6432 EXISTS_TAC `ball(x:real^M,e / &2) INTER s` THEN
6433 EXISTS_TAC `ball(y:real^N,e / &2) INTER t` THEN
6434 SUBGOAL_THEN `(x:real^M) IN s /\ (y:real^N) IN t` STRIP_ASSUME_TAC THENL
6435 [ASM_MESON_TAC[SUBSET; PASTECART_IN_PCROSS]; ALL_TAC] THEN
6436 ASM_SIMP_TAC[INTER_SUBSET; IN_INTER; CENTRE_IN_BALL; REAL_HALF] THEN
6437 REWRITE_TAC[IN_BALL] THEN REPEAT(CONJ_TAC THENL
6438 [MESON_TAC[REAL_SUB_LT; NORM_ARITH
6439 `dist(x,y) < e /\ dist(z,y) < e - dist(x,y)
6440 ==> dist(x:real^N,z) < e`];
6442 REWRITE_TAC[SUBSET; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN
6443 REWRITE_TAC[IN_BALL; IN_INTER] THEN REPEAT STRIP_TAC THEN
6444 FIRST_X_ASSUM MATCH_MP_TAC THEN
6445 ASM_REWRITE_TAC[dist; PASTECART_SUB] THEN
6446 W(MP_TAC o PART_MATCH lhand NORM_PASTECART_LE o lhand o snd) THEN
6447 REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[DIST_SYM] dist)] THEN
6448 ASM_REAL_ARITH_TAC);;
6450 let OPEN_IN_PCROSS_EQ = prove
6451 (`!s s':real^M->bool t t':real^N->bool.
6452 open_in (subtopology euclidean (s PCROSS t)) (s' PCROSS t') <=>
6453 s' = {} \/ t' = {} \/
6454 open_in (subtopology euclidean s) s' /\
6455 open_in (subtopology euclidean t) t'`,
6457 ASM_CASES_TAC `s':real^M->bool = {}` THEN
6458 ASM_REWRITE_TAC[PCROSS_EMPTY; OPEN_IN_EMPTY] THEN
6459 ASM_CASES_TAC `t':real^N->bool = {}` THEN
6460 ASM_REWRITE_TAC[PCROSS_EMPTY; OPEN_IN_EMPTY] THEN
6461 EQ_TAC THEN REWRITE_TAC[OPEN_IN_PCROSS] THEN REPEAT STRIP_TAC THENL
6462 [ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN
6463 X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
6464 UNDISCH_TAC `~(t':real^N->bool = {})` THEN
6465 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
6466 DISCH_THEN(X_CHOOSE_TAC `y:real^N`);
6467 ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN
6468 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
6469 UNDISCH_TAC `~(s':real^M->bool = {})` THEN
6470 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
6471 DISCH_THEN(X_CHOOSE_TAC `x:real^M`)] THEN
6473 [`s:real^M->bool`; `t:real^N->bool`;
6474 `(s':real^M->bool) PCROSS (t':real^N->bool)`;
6475 `x:real^M`; `y:real^N`] PASTECART_IN_INTERIOR_SUBTOPOLOGY) THEN
6476 ASM_REWRITE_TAC[SUBSET; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN
6479 let INTERIOR_PCROSS = prove
6480 (`!s:real^M->bool t:real^N->bool.
6481 interior (s PCROSS t) = (interior s) PCROSS (interior t)`,
6482 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
6483 [REWRITE_TAC[SUBSET; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN
6484 MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^N`] THEN DISCH_TAC THEN
6485 MP_TAC(ISPECL [`(:real^M)`; `(:real^N)`;
6486 `interior((s:real^M->bool) PCROSS (t:real^N->bool))`;
6487 `x:real^M`; `y:real^N`] PASTECART_IN_INTERIOR_SUBTOPOLOGY) THEN
6488 REWRITE_TAC[UNIV_PCROSS_UNIV; SUBTOPOLOGY_UNIV; GSYM OPEN_IN] THEN
6489 ASM_REWRITE_TAC[OPEN_INTERIOR] THEN STRIP_TAC THEN
6490 FIRST_ASSUM(MP_TAC o MATCH_MP (MESON[INTERIOR_SUBSET; SUBSET_TRANS]
6491 `s SUBSET interior t ==> s SUBSET t`)) THEN
6492 REWRITE_TAC[SUBSET_PCROSS] THEN
6493 ASM_MESON_TAC[NOT_IN_EMPTY; INTERIOR_MAXIMAL; SUBSET];
6494 MATCH_MP_TAC INTERIOR_MAXIMAL THEN
6495 SIMP_TAC[OPEN_PCROSS; OPEN_INTERIOR; PCROSS_MONO; INTERIOR_SUBSET]]);;
6497 (* ------------------------------------------------------------------------- *)
6498 (* Quotient maps are occasionally useful. *)
6499 (* ------------------------------------------------------------------------- *)
6501 let QUASICOMPACT_OPEN_CLOSED = prove
6502 (`!f:real^M->real^N s t.
6504 ==> ((!u. u SUBSET t
6505 ==> (open_in (subtopology euclidean s)
6506 {x | x IN s /\ f x IN u}
6507 ==> open_in (subtopology euclidean t) u)) <=>
6509 ==> (closed_in (subtopology euclidean s)
6510 {x | x IN s /\ f x IN u}
6511 ==> closed_in (subtopology euclidean t) u)))`,
6512 SIMP_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
6513 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
6514 X_GEN_TAC `u:real^N->bool` THEN
6515 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `t DIFF u:real^N->bool`) THEN
6516 ASM_SIMP_TAC[SET_RULE `u SUBSET t ==> t DIFF (t DIFF u) = u`] THEN
6517 (ANTS_TAC THENL [SET_TAC[]; REPEAT STRIP_TAC]) THEN
6518 FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[SUBSET_RESTRICT] THEN
6519 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[]
6520 `open_in top x ==> x = y ==> open_in top y`)) THEN
6523 let QUOTIENT_MAP_IMP_CONTINUOUS_OPEN = prove
6524 (`!f:real^M->real^N s t.
6525 IMAGE f s SUBSET t /\
6527 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
6528 open_in (subtopology euclidean t) u))
6529 ==> f continuous_on s`,
6530 MESON_TAC[OPEN_IN_IMP_SUBSET; CONTINUOUS_ON_OPEN_GEN]);;
6532 let QUOTIENT_MAP_IMP_CONTINUOUS_CLOSED = prove
6533 (`!f:real^M->real^N s t.
6534 IMAGE f s SUBSET t /\
6536 ==> (closed_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
6537 closed_in (subtopology euclidean t) u))
6538 ==> f continuous_on s`,
6539 MESON_TAC[CLOSED_IN_IMP_SUBSET; CONTINUOUS_ON_CLOSED_GEN]);;
6541 let OPEN_MAP_IMP_QUOTIENT_MAP = prove
6542 (`!f:real^M->real^N s.
6543 f continuous_on s /\
6544 (!t. open_in (subtopology euclidean s) t
6545 ==> open_in (subtopology euclidean (IMAGE f s)) (IMAGE f t))
6546 ==> !t. t SUBSET IMAGE f s
6547 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=>
6548 open_in (subtopology euclidean (IMAGE f s)) t)`,
6549 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
6551 `t = IMAGE f {x | x IN s /\ (f:real^M->real^N) x IN t}`
6552 SUBST1_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[]];
6553 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_ON_OPEN]) THEN
6556 let CLOSED_MAP_IMP_QUOTIENT_MAP = prove
6557 (`!f:real^M->real^N s.
6558 f continuous_on s /\
6559 (!t. closed_in (subtopology euclidean s) t
6560 ==> closed_in (subtopology euclidean (IMAGE f s)) (IMAGE f t))
6561 ==> !t. t SUBSET IMAGE f s
6562 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=>
6563 open_in (subtopology euclidean (IMAGE f s)) t)`,
6564 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
6565 [FIRST_X_ASSUM(MP_TAC o SPEC
6566 `s DIFF {x | x IN s /\ (f:real^M->real^N) x IN t}`) THEN
6568 [MATCH_MP_TAC CLOSED_IN_DIFF THEN
6569 ASM_SIMP_TAC[CLOSED_IN_SUBTOPOLOGY_REFL;
6570 TOPSPACE_EUCLIDEAN; SUBSET_UNIV];
6571 REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
6572 DISCH_THEN(MP_TAC o CONJUNCT2) THEN MATCH_MP_TAC EQ_IMP THEN
6573 AP_TERM_TAC THEN ASM SET_TAC[]];
6574 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_ON_OPEN]) THEN
6577 let CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP = prove
6578 (`!f:real^M->real^N g s t.
6579 f continuous_on s /\ IMAGE f s SUBSET t /\
6580 g continuous_on t /\ IMAGE g t SUBSET s /\
6581 (!y. y IN t ==> f(g y) = y)
6583 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
6584 open_in (subtopology euclidean t) u))`,
6585 REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN REPEAT STRIP_TAC THEN EQ_TAC THENL
6586 [DISCH_TAC THEN FIRST_ASSUM(MP_TAC o SPEC `(IMAGE (g:real^N->real^M) t)
6588 {x | x IN s /\ (f:real^M->real^N) x IN u}`) THEN
6590 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN
6591 REWRITE_TAC[OPEN_IN_OPEN] THEN MATCH_MP_TAC MONO_EXISTS THEN
6593 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]];
6594 DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
6595 SUBGOAL_THEN `IMAGE (f:real^M->real^N) s = t`
6596 (fun th -> ASM_REWRITE_TAC[th]) THEN
6599 let CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP = prove
6600 (`!f:real^M->real^N g s.
6601 f continuous_on s /\ g continuous_on (IMAGE f s) /\
6602 (!x. x IN s ==> g(f x) = x)
6603 ==> (!u. u SUBSET (IMAGE f s)
6604 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
6605 open_in (subtopology euclidean (IMAGE f s)) u))`,
6606 REPEAT GEN_TAC THEN STRIP_TAC THEN
6607 MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN
6608 EXISTS_TAC `g:real^N->real^M` THEN
6609 ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);;
6611 let QUOTIENT_MAP_OPEN_CLOSED = prove
6612 (`!f:real^M->real^N s t.
6614 ==> ((!u. u SUBSET t
6615 ==> (open_in (subtopology euclidean s)
6616 {x | x IN s /\ f x IN u} <=>
6617 open_in (subtopology euclidean t) u)) <=>
6619 ==> (closed_in (subtopology euclidean s)
6620 {x | x IN s /\ f x IN u} <=>
6621 closed_in (subtopology euclidean t) u)))`,
6622 SIMP_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
6623 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
6624 X_GEN_TAC `u:real^N->bool` THEN
6625 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `t DIFF u:real^N->bool`) THEN
6626 ASM_SIMP_TAC[SET_RULE `u SUBSET t ==> t DIFF (t DIFF u) = u`] THEN
6627 (ANTS_TAC THENL [SET_TAC[]; DISCH_THEN(SUBST1_TAC o SYM)]) THEN
6628 REWRITE_TAC[SUBSET_RESTRICT] THEN AP_TERM_TAC THEN ASM SET_TAC[]);;
6630 let CONTINUOUS_ON_COMPOSE_QUOTIENT = prove
6631 (`!f:real^M->real^N g:real^N->real^P s t u.
6632 IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\
6634 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN v} <=>
6635 open_in (subtopology euclidean t) v)) /\
6636 (g o f) continuous_on s
6637 ==> g continuous_on t`,
6639 REPLICATE_TAC 3 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
6640 FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THEN
6642 `IMAGE ((g:real^N->real^P) o (f:real^M->real^N)) s SUBSET u`
6643 (fun th -> REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th])
6644 THENL [REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[]; DISCH_TAC] THEN
6645 X_GEN_TAC `v:real^P->bool` THEN DISCH_TAC THEN
6646 FIRST_X_ASSUM(MP_TAC o SPEC `v:real^P->bool`) THEN
6647 ASM_REWRITE_TAC[o_THM] THEN DISCH_TAC THEN
6648 FIRST_X_ASSUM(MP_TAC o SPEC `{x | x IN t /\ (g:real^N->real^P) x IN v}`) THEN
6649 ASM_REWRITE_TAC[SUBSET_RESTRICT] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
6650 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[]
6651 `open_in top s ==> s = t ==> open_in top t`)) THEN
6654 let LIFT_TO_QUOTIENT_SPACE = prove
6655 (`!f:real^M->real^N h:real^M->real^P s t u.
6658 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN v} <=>
6659 open_in (subtopology euclidean t) v)) /\
6660 h continuous_on s /\ IMAGE h s = u /\
6661 (!x y. x IN s /\ y IN s /\ f x = f y ==> h x = h y)
6662 ==> ?g. g continuous_on t /\ IMAGE g t = u /\
6663 !x. x IN s ==> h(x) = g(f x)`,
6665 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
6666 REWRITE_TAC[FUNCTION_FACTORS_LEFT_GEN] THEN
6667 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^P` THEN
6668 DISCH_TAC THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
6669 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE_QUOTIENT THEN MAP_EVERY EXISTS_TAC
6670 [`f:real^M->real^N`; `s:real^M->bool`; `u:real^P->bool`] THEN
6671 ASM_SIMP_TAC[SUBSET_REFL] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
6672 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
6673 CONTINUOUS_ON_EQ)) THEN
6674 ASM_REWRITE_TAC[o_THM]);;
6676 let QUOTIENT_MAP_COMPOSE = prove
6677 (`!f:real^M->real^N g:real^N->real^P s t u.
6678 IMAGE f s SUBSET t /\
6680 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN v} <=>
6681 open_in (subtopology euclidean t) v)) /\
6683 ==> (open_in (subtopology euclidean t) {x | x IN t /\ g x IN v} <=>
6684 open_in (subtopology euclidean u) v))
6686 ==> (open_in (subtopology euclidean s)
6687 {x | x IN s /\ (g o f) x IN v} <=>
6688 open_in (subtopology euclidean u) v)`,
6689 REPEAT STRIP_TAC THEN REWRITE_TAC[o_THM] THEN
6691 `{x | x IN s /\ (g:real^N->real^P) ((f:real^M->real^N) x) IN v} =
6692 {x | x IN s /\ f x IN {x | x IN t /\ g x IN v}}`
6693 SUBST1_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[SUBSET_RESTRICT]]);;
6695 let QUOTIENT_MAP_FROM_COMPOSITION = prove
6696 (`!f:real^M->real^N g:real^N->real^P s t u.
6697 f continuous_on s /\ IMAGE f s SUBSET t /\
6698 g continuous_on t /\ IMAGE g t SUBSET u /\
6700 ==> (open_in (subtopology euclidean s)
6701 {x | x IN s /\ (g o f) x IN v} <=>
6702 open_in (subtopology euclidean u) v))
6704 ==> (open_in (subtopology euclidean t)
6705 {x | x IN t /\ g x IN v} <=>
6706 open_in (subtopology euclidean u) v)`,
6707 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THENL
6708 [FIRST_X_ASSUM(MP_TAC o SPEC `v:real^P->bool`) THEN
6709 ASM_REWRITE_TAC[o_THM] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
6711 `{x | x IN s /\ (g:real^N->real^P) ((f:real^M->real^N) x) IN v} =
6712 {x | x IN s /\ f x IN {x | x IN t /\ g x IN v}}`
6713 SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
6714 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN
6715 EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[];
6716 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN
6717 EXISTS_TAC `u:real^P->bool` THEN ASM_REWRITE_TAC[]]);;
6719 let QUOTIENT_MAP_FROM_SUBSET = prove
6720 (`!f:real^M->real^N s t u.
6721 f continuous_on t /\ IMAGE f t SUBSET u /\
6722 s SUBSET t /\ IMAGE f s = u /\
6724 ==> (open_in (subtopology euclidean s)
6725 {x | x IN s /\ f x IN v} <=>
6726 open_in (subtopology euclidean u) v))
6728 ==> (open_in (subtopology euclidean t)
6729 {x | x IN t /\ f x IN v} <=>
6730 open_in (subtopology euclidean u) v)`,
6731 REPEAT GEN_TAC THEN STRIP_TAC THEN
6732 MATCH_MP_TAC QUOTIENT_MAP_FROM_COMPOSITION THEN
6733 MAP_EVERY EXISTS_TAC [`\x:real^M. x`; `s:real^M->bool`] THEN
6734 ASM_REWRITE_TAC[CONTINUOUS_ON_ID; IMAGE_ID; o_THM]);;
6736 let QUOTIENT_MAP_RESTRICT = prove
6737 (`!f:real^M->real^N s t c.
6738 IMAGE f s SUBSET t /\
6740 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
6741 open_in (subtopology euclidean t) u)) /\
6742 (open_in (subtopology euclidean t) c \/
6743 closed_in (subtopology euclidean t) c)
6745 ==> (open_in (subtopology euclidean {x | x IN s /\ f x IN c})
6746 {x | x IN {x | x IN s /\ f x IN c} /\ f x IN u} <=>
6747 open_in (subtopology euclidean c) u)`,
6749 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6750 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
6751 DISCH_THEN(fun th -> MP_TAC th THEN MP_TAC (MATCH_MP
6752 (REWRITE_RULE[IMP_CONJ_ALT] QUOTIENT_MAP_IMP_CONTINUOUS_OPEN) th)) THEN
6753 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
6754 SUBGOAL_THEN `IMAGE (f:real^M->real^N) {x | x IN s /\ f x IN c} SUBSET c`
6755 ASSUME_TAC THENL [SET_TAC[]; ALL_TAC] THEN
6756 FIRST_X_ASSUM DISJ_CASES_TAC THENL
6757 [FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET);
6758 ASM_SIMP_TAC[QUOTIENT_MAP_OPEN_CLOSED] THEN
6759 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET)] THEN
6760 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `u:real^N->bool` THEN
6761 DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
6762 (ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
6763 (MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THENL
6764 [MATCH_MP_TAC(MESON[] `t = s /\ (P s <=> Q s) ==> (P s <=> Q t)`) THEN
6765 CONJ_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[IN_ELIM_THM]];
6768 [MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] OPEN_IN_SUBSET_TRANS) ORELSE
6769 MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ_ALT] CLOSED_IN_SUBSET_TRANS);
6770 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] OPEN_IN_TRANS) ORELSE
6771 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CLOSED_IN_TRANS)]) THEN
6772 (MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN ORELSE
6773 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN ORELSE ASM_SIMP_TAC[]) THEN
6776 let CONNECTED_MONOTONE_QUOTIENT_PREIMAGE = prove
6777 (`!f:real^M->real^N s t.
6778 f continuous_on s /\ IMAGE f s = t /\
6780 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
6781 open_in (subtopology euclidean t) u)) /\
6782 (!y. y IN t ==> connected {x | x IN s /\ f x = y}) /\
6785 REPEAT STRIP_TAC THEN REWRITE_TAC[connected; NOT_EXISTS_THM] THEN
6786 MAP_EVERY X_GEN_TAC [`u:real^M->bool`; `v:real^M->bool`] THEN STRIP_TAC THEN
6787 UNDISCH_TAC `connected(t:real^N->bool)` THEN SIMP_TAC[CONNECTED_OPEN_IN] THEN
6788 MAP_EVERY EXISTS_TAC
6789 [`IMAGE (f:real^M->real^N) (s INTER u)`;
6790 `IMAGE (f:real^M->real^N) (s INTER v)`] THEN
6791 ASM_REWRITE_TAC[IMAGE_EQ_EMPTY] THEN
6793 `IMAGE (f:real^M->real^N) (s INTER u) INTER IMAGE f (s INTER v) = {}`
6795 [REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN
6796 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
6797 FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN
6798 ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[connected]] THEN
6799 MAP_EVERY EXISTS_TAC [`u:real^M->bool`; `v:real^M->bool`] THEN
6802 ONCE_REWRITE_TAC[CONJ_ASSOC] THEN
6803 CONJ_TAC THENL [CONJ_TAC; ASM SET_TAC[]] THEN
6804 FIRST_X_ASSUM(fun th ->
6805 W(MP_TAC o PART_MATCH (rand o rand) th o snd)) THEN
6806 (ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN(SUBST1_TAC o SYM)]) THEN
6807 MATCH_MP_TAC(MESON[]
6808 `{x | x IN s /\ f x IN IMAGE f u} = u /\ open_in top u
6809 ==> open_in top {x | x IN s /\ f x IN IMAGE f u}`) THEN
6810 ASM_SIMP_TAC[OPEN_IN_OPEN_INTER] THEN ASM SET_TAC[]);;
6812 let CONNECTED_MONOTONE_QUOTIENT_PREIMAGE_GEN = prove
6813 (`!f:real^M->real^N s t c.
6816 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
6817 open_in (subtopology euclidean t) u)) /\
6818 (!y. y IN t ==> connected {x | x IN s /\ f x = y}) /\
6819 (open_in (subtopology euclidean t) c \/
6820 closed_in (subtopology euclidean t) c) /\
6822 ==> connected {x | x IN s /\ f x IN c}`,
6824 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
6825 MATCH_MP_TAC(ONCE_REWRITE_RULE[IMP_CONJ]
6826 (REWRITE_RULE[CONJ_ASSOC] CONNECTED_MONOTONE_QUOTIENT_PREIMAGE)) THEN
6827 SUBGOAL_THEN `(c:real^N->bool) SUBSET t` ASSUME_TAC THENL
6828 [ASM_MESON_TAC[OPEN_IN_IMP_SUBSET; CLOSED_IN_IMP_SUBSET]; ALL_TAC] THEN
6829 EXISTS_TAC `f:real^M->real^N` THEN REPEAT CONJ_TAC THENL
6830 [FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
6831 QUOTIENT_MAP_IMP_CONTINUOUS_OPEN)) THEN
6832 ASM_REWRITE_TAC[SUBSET_REFL] THEN
6833 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] CONTINUOUS_ON_SUBSET) THEN
6834 REWRITE_TAC[SUBSET_RESTRICT];
6836 MATCH_MP_TAC QUOTIENT_MAP_RESTRICT THEN
6837 ASM_MESON_TAC[SUBSET_REFL];
6838 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
6839 FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN
6840 ANTS_TAC THENL [ASM SET_TAC[]; MATCH_MP_TAC EQ_IMP] THEN
6841 AP_TERM_TAC THEN ASM SET_TAC[]]);;
6843 (* ------------------------------------------------------------------------- *)
6844 (* More properties of open and closed maps. *)
6845 (* ------------------------------------------------------------------------- *)
6847 let OPEN_MAP_RESTRICT = prove
6848 (`!f:real^M->real^N s t t'.
6849 (!u. open_in (subtopology euclidean s) u
6850 ==> open_in (subtopology euclidean t) (IMAGE f u)) /\
6852 ==> !u. open_in (subtopology euclidean {x | x IN s /\ f x IN t'}) u
6853 ==> open_in (subtopology euclidean t') (IMAGE f u)`,
6854 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN
6855 REWRITE_TAC[LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN
6856 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
6857 REWRITE_TAC[RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN
6858 REPEAT DISCH_TAC THEN X_GEN_TAC `c:real^M->bool` THEN
6859 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `c:real^M->bool`) THEN
6860 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[]);;
6862 let CLOSED_MAP_RESTRICT = prove
6863 (`!f:real^M->real^N s t t'.
6864 (!u. closed_in (subtopology euclidean s) u
6865 ==> closed_in (subtopology euclidean t) (IMAGE f u)) /\
6867 ==> !u. closed_in (subtopology euclidean {x | x IN s /\ f x IN t'}) u
6868 ==> closed_in (subtopology euclidean t') (IMAGE f u)`,
6869 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN
6870 REWRITE_TAC[LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN
6871 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
6872 REWRITE_TAC[RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN
6873 REPEAT DISCH_TAC THEN X_GEN_TAC `c:real^M->bool` THEN
6874 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `c:real^M->bool`) THEN
6875 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[]);;
6877 let QUOTIENT_MAP_OPEN_MAP_EQ = prove
6878 (`!f:real^M->real^N s t.
6879 IMAGE f s SUBSET t /\
6881 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
6882 open_in (subtopology euclidean t) u))
6883 ==> ((!k. open_in (subtopology euclidean s) k
6884 ==> open_in (subtopology euclidean t) (IMAGE f k)) <=>
6885 (!k. open_in (subtopology euclidean s) k
6886 ==> open_in (subtopology euclidean s)
6887 {x | x IN s /\ f x IN IMAGE f k}))`,
6888 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
6889 X_GEN_TAC `k:real^M->bool` THEN STRIP_TAC THEN
6890 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
6891 FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (f:real^M->real^N) k`) THEN
6892 ASM_SIMP_TAC[IMAGE_SUBSET] THEN DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[]);;
6894 let QUOTIENT_MAP_CLOSED_MAP_EQ = prove
6895 (`!f:real^M->real^N s t.
6896 IMAGE f s SUBSET t /\
6898 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
6899 open_in (subtopology euclidean t) u))
6900 ==> ((!k. closed_in (subtopology euclidean s) k
6901 ==> closed_in (subtopology euclidean t) (IMAGE f k)) <=>
6902 (!k. closed_in (subtopology euclidean s) k
6903 ==> closed_in (subtopology euclidean s)
6904 {x | x IN s /\ f x IN IMAGE f k}))`,
6905 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6906 ASM_SIMP_TAC[QUOTIENT_MAP_OPEN_CLOSED] THEN
6907 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
6908 X_GEN_TAC `k:real^M->bool` THEN STRIP_TAC THEN
6909 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
6910 FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (f:real^M->real^N) k`) THEN
6911 ASM_SIMP_TAC[IMAGE_SUBSET] THEN DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[]);;
6913 let CLOSED_MAP_IMP_OPEN_MAP = prove
6914 (`!f:real^M->real^N s t.
6916 (!u. closed_in (subtopology euclidean s) u
6917 ==> closed_in (subtopology euclidean t) (IMAGE f u)) /\
6918 (!u. open_in (subtopology euclidean s) u
6919 ==> open_in (subtopology euclidean s)
6920 {x | x IN s /\ f x IN IMAGE f u})
6921 ==> (!u. open_in (subtopology euclidean s) u
6922 ==> open_in (subtopology euclidean t) (IMAGE f u))`,
6923 REPEAT STRIP_TAC THEN
6925 `IMAGE (f:real^M->real^N) u =
6926 t DIFF IMAGE f (s DIFF {x | x IN s /\ f x IN IMAGE f u})`
6928 [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN ASM SET_TAC[];
6929 MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN
6930 FIRST_X_ASSUM MATCH_MP_TAC THEN
6931 MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN
6932 ASM_SIMP_TAC[CLOSED_IN_REFL]]);;
6934 let OPEN_MAP_IMP_CLOSED_MAP = prove
6935 (`!f:real^M->real^N s t.
6937 (!u. open_in (subtopology euclidean s) u
6938 ==> open_in (subtopology euclidean t) (IMAGE f u)) /\
6939 (!u. closed_in (subtopology euclidean s) u
6940 ==> closed_in (subtopology euclidean s)
6941 {x | x IN s /\ f x IN IMAGE f u})
6942 ==> (!u. closed_in (subtopology euclidean s) u
6943 ==> closed_in (subtopology euclidean t) (IMAGE f u))`,
6944 REPEAT STRIP_TAC THEN
6946 `IMAGE (f:real^M->real^N) u =
6947 t DIFF IMAGE f (s DIFF {x | x IN s /\ f x IN IMAGE f u})`
6949 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN ASM SET_TAC[];
6950 MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN
6951 FIRST_X_ASSUM MATCH_MP_TAC THEN
6952 MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN
6953 ASM_SIMP_TAC[OPEN_IN_REFL]]);;
6955 let OPEN_MAP_FROM_COMPOSITION_SURJECTIVE = prove
6956 (`!f:real^M->real^N g:real^N->real^P s t u.
6957 f continuous_on s /\ IMAGE f s = t /\ IMAGE g t SUBSET u /\
6958 (!k. open_in (subtopology euclidean s) k
6959 ==> open_in (subtopology euclidean u) (IMAGE (g o f) k))
6960 ==> (!k. open_in (subtopology euclidean t) k
6961 ==> open_in (subtopology euclidean u) (IMAGE g k))`,
6962 REPEAT STRIP_TAC THEN SUBGOAL_THEN
6963 `IMAGE g k = IMAGE ((g:real^N->real^P) o (f:real^M->real^N))
6964 {x | x IN s /\ f(x) IN k}`
6966 [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
6967 REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[];
6968 FIRST_X_ASSUM MATCH_MP_TAC THEN
6969 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN
6970 EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL]]);;
6972 let CLOSED_MAP_FROM_COMPOSITION_SURJECTIVE = prove
6973 (`!f:real^M->real^N g:real^N->real^P s t u.
6974 f continuous_on s /\ IMAGE f s = t /\ IMAGE g t SUBSET u /\
6975 (!k. closed_in (subtopology euclidean s) k
6976 ==> closed_in (subtopology euclidean u) (IMAGE (g o f) k))
6977 ==> (!k. closed_in (subtopology euclidean t) k
6978 ==> closed_in (subtopology euclidean u) (IMAGE g k))`,
6979 REPEAT STRIP_TAC THEN SUBGOAL_THEN
6980 `IMAGE g k = IMAGE ((g:real^N->real^P) o (f:real^M->real^N))
6981 {x | x IN s /\ f(x) IN k}`
6983 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
6984 REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[];
6985 FIRST_X_ASSUM MATCH_MP_TAC THEN
6986 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN
6987 EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL]]);;
6989 let OPEN_MAP_FROM_COMPOSITION_INJECTIVE = prove
6990 (`!f:real^M->real^N g:real^N->real^P s t u.
6991 IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\
6992 g continuous_on t /\ (!x y. x IN t /\ y IN t /\ g x = g y ==> x = y) /\
6993 (!k. open_in (subtopology euclidean s) k
6994 ==> open_in (subtopology euclidean u) (IMAGE (g o f) k))
6995 ==> (!k. open_in (subtopology euclidean s) k
6996 ==> open_in (subtopology euclidean t) (IMAGE f k))`,
6997 REPEAT STRIP_TAC THEN SUBGOAL_THEN
6998 `IMAGE f k = {x | x IN t /\
6999 g(x) IN IMAGE ((g:real^N->real^P) o (f:real^M->real^N)) k}`
7001 [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
7002 REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[];
7003 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN
7004 EXISTS_TAC `u:real^P->bool` THEN ASM_SIMP_TAC[]]);;
7006 let CLOSED_MAP_FROM_COMPOSITION_INJECTIVE = prove
7007 (`!f:real^M->real^N g:real^N->real^P s t u.
7008 IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\
7009 g continuous_on t /\ (!x y. x IN t /\ y IN t /\ g x = g y ==> x = y) /\
7010 (!k. closed_in (subtopology euclidean s) k
7011 ==> closed_in (subtopology euclidean u) (IMAGE (g o f) k))
7012 ==> (!k. closed_in (subtopology euclidean s) k
7013 ==> closed_in (subtopology euclidean t) (IMAGE f k))`,
7014 REPEAT STRIP_TAC THEN SUBGOAL_THEN
7015 `IMAGE f k = {x | x IN t /\
7016 g(x) IN IMAGE ((g:real^N->real^P) o (f:real^M->real^N)) k}`
7018 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
7019 REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[];
7020 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN
7021 EXISTS_TAC `u:real^P->bool` THEN ASM_SIMP_TAC[]]);;
7023 let OPEN_MAP_CLOSED_SUPERSET_PREIMAGE = prove
7024 (`!f:real^M->real^N s t u w.
7025 (!k. open_in (subtopology euclidean s) k
7026 ==> open_in (subtopology euclidean t) (IMAGE f k)) /\
7027 closed_in (subtopology euclidean s) u /\
7028 w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u
7029 ==> ?v. closed_in (subtopology euclidean t) v /\
7031 {x | x IN s /\ f(x) IN v} SUBSET u`,
7032 REPEAT STRIP_TAC THEN
7033 EXISTS_TAC `t DIFF IMAGE (f:real^M->real^N) (s DIFF u)` THEN
7034 CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
7035 MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN
7036 FIRST_X_ASSUM MATCH_MP_TAC THEN
7037 ASM_SIMP_TAC[OPEN_IN_DIFF; OPEN_IN_REFL]);;
7039 let OPEN_MAP_CLOSED_SUPERSET_PREIMAGE_EQ = prove
7040 (`!f:real^M->real^N s t.
7042 ==> ((!k. open_in (subtopology euclidean s) k
7043 ==> open_in (subtopology euclidean t) (IMAGE f k)) <=>
7044 (!u w. closed_in (subtopology euclidean s) u /\
7045 w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u
7046 ==> ?v. closed_in (subtopology euclidean t) v /\
7047 w SUBSET v /\ {x | x IN s /\ f(x) IN v} SUBSET u))`,
7048 REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN
7049 ASM_SIMP_TAC[OPEN_MAP_CLOSED_SUPERSET_PREIMAGE] THEN
7050 FIRST_X_ASSUM(MP_TAC o SPECL
7051 [`s DIFF k:real^M->bool`; `t DIFF IMAGE (f:real^M->real^N) k`]) THEN
7052 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
7053 ASM_SIMP_TAC[CLOSED_IN_DIFF; CLOSED_IN_REFL] THEN
7054 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7055 DISCH_THEN(X_CHOOSE_THEN `v:real^N->bool` STRIP_ASSUME_TAC) THEN
7056 SUBGOAL_THEN `IMAGE (f:real^M->real^N) k = t DIFF v` SUBST1_TAC THENL
7057 [ASM SET_TAC[]; ASM_SIMP_TAC[OPEN_IN_DIFF; OPEN_IN_REFL]]);;
7059 let CLOSED_MAP_OPEN_SUPERSET_PREIMAGE = prove
7060 (`!f:real^M->real^N s t u w.
7061 (!k. closed_in (subtopology euclidean s) k
7062 ==> closed_in (subtopology euclidean t) (IMAGE f k)) /\
7063 open_in (subtopology euclidean s) u /\
7064 w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u
7065 ==> ?v. open_in (subtopology euclidean t) v /\
7067 {x | x IN s /\ f(x) IN v} SUBSET u`,
7068 REPEAT STRIP_TAC THEN
7069 EXISTS_TAC `t DIFF IMAGE (f:real^M->real^N) (s DIFF u)` THEN
7070 CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
7071 MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN
7072 FIRST_X_ASSUM MATCH_MP_TAC THEN
7073 ASM_SIMP_TAC[CLOSED_IN_DIFF; CLOSED_IN_REFL]);;
7075 let CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_EQ = prove
7076 (`!f:real^M->real^N s t.
7078 ==> ((!k. closed_in (subtopology euclidean s) k
7079 ==> closed_in (subtopology euclidean t) (IMAGE f k)) <=>
7080 (!u w. open_in (subtopology euclidean s) u /\
7081 w SUBSET t /\ {x | x IN s /\ f(x) IN w} SUBSET u
7082 ==> ?v. open_in (subtopology euclidean t) v /\
7083 w SUBSET v /\ {x | x IN s /\ f(x) IN v} SUBSET u))`,
7084 REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN
7085 ASM_SIMP_TAC[CLOSED_MAP_OPEN_SUPERSET_PREIMAGE] THEN
7086 FIRST_X_ASSUM(MP_TAC o SPECL
7087 [`s DIFF k:real^M->bool`; `t DIFF IMAGE (f:real^M->real^N) k`]) THEN
7088 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
7089 ASM_SIMP_TAC[OPEN_IN_DIFF; OPEN_IN_REFL] THEN
7090 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7091 DISCH_THEN(X_CHOOSE_THEN `v:real^N->bool` STRIP_ASSUME_TAC) THEN
7092 SUBGOAL_THEN `IMAGE (f:real^M->real^N) k = t DIFF v` SUBST1_TAC THENL
7093 [ASM SET_TAC[]; ASM_SIMP_TAC[CLOSED_IN_DIFF; CLOSED_IN_REFL]]);;
7095 let CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_POINT = prove
7096 (`!f:real^M->real^N s t.
7098 ==> ((!k. closed_in (subtopology euclidean s) k
7099 ==> closed_in (subtopology euclidean t) (IMAGE f k)) <=>
7100 (!u y. open_in (subtopology euclidean s) u /\
7101 y IN t /\ {x | x IN s /\ f(x) = y} SUBSET u
7102 ==> ?v. open_in (subtopology euclidean t) v /\
7103 y IN v /\ {x | x IN s /\ f(x) IN v} SUBSET u))`,
7104 REPEAT STRIP_TAC THEN ASM_SIMP_TAC[CLOSED_MAP_OPEN_SUPERSET_PREIMAGE_EQ] THEN
7105 EQ_TAC THEN DISCH_TAC THENL
7106 [MAP_EVERY X_GEN_TAC [`u:real^M->bool`; `y:real^N`] THEN
7108 FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^M->bool`; `{y:real^N}`]) THEN
7109 ASM_REWRITE_TAC[SING_SUBSET; IN_SING];
7110 MAP_EVERY X_GEN_TAC [`u:real^M->bool`; `w:real^N->bool`] THEN
7111 STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M->bool`) THEN
7112 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
7113 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
7114 X_GEN_TAC `vv:real^N->real^N->bool` THEN DISCH_TAC THEN
7115 EXISTS_TAC `UNIONS {(vv:real^N->real^N->bool) y | y IN w}` THEN
7117 [MATCH_MP_TAC OPEN_IN_UNIONS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN
7119 REWRITE_TAC[UNIONS_GSPEC] THEN
7120 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7121 REWRITE_TAC[SUBSET; IN_ELIM_THM; RIGHT_AND_EXISTS_THM;
7122 LEFT_IMP_EXISTS_THM] THEN
7123 MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^N`] THEN STRIP_TAC THEN
7124 FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN ASM SET_TAC[]]]);;
7126 let CONNECTED_OPEN_MONOTONE_PREIMAGE = prove
7127 (`!f:real^M->real^N s t.
7128 f continuous_on s /\ IMAGE f s = t /\
7129 (!c. open_in (subtopology euclidean s) c
7130 ==> open_in (subtopology euclidean t) (IMAGE f c)) /\
7131 (!y. y IN t ==> connected {x | x IN s /\ f x = y})
7132 ==> !c. connected c /\ c SUBSET t
7133 ==> connected {x | x IN s /\ f x IN c}`,
7134 REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC `c:real^N->bool` o MATCH_MP
7135 (ONCE_REWRITE_RULE[IMP_CONJ] OPEN_MAP_RESTRICT)) THEN
7136 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC(ISPECL
7137 [`f:real^M->real^N`; `{x | x IN s /\ (f:real^M->real^N) x IN c}`]
7138 OPEN_MAP_IMP_QUOTIENT_MAP) THEN
7139 SUBGOAL_THEN `IMAGE f {x | x IN s /\ (f:real^M->real^N) x IN c} = c`
7140 ASSUME_TAC THENL [ASM SET_TAC[]; ASM_REWRITE_TAC[]] THEN ANTS_TAC THENL
7141 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
7142 CONTINUOUS_ON_SUBSET)) THEN SET_TAC[];
7144 MATCH_MP_TAC CONNECTED_MONOTONE_QUOTIENT_PREIMAGE THEN
7145 MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `c:real^N->bool`] THEN
7146 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
7147 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
7148 CONTINUOUS_ON_SUBSET)) THEN SET_TAC[];
7150 `y IN c ==> {x | x IN {x | x IN s /\ f x IN c} /\ f x = y} =
7151 {x | x IN s /\ f x = y}`] THEN
7154 let CONNECTED_CLOSED_MONOTONE_PREIMAGE = prove
7155 (`!f:real^M->real^N s t.
7156 f continuous_on s /\ IMAGE f s = t /\
7157 (!c. closed_in (subtopology euclidean s) c
7158 ==> closed_in (subtopology euclidean t) (IMAGE f c)) /\
7159 (!y. y IN t ==> connected {x | x IN s /\ f x = y})
7160 ==> !c. connected c /\ c SUBSET t
7161 ==> connected {x | x IN s /\ f x IN c}`,
7162 REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC `c:real^N->bool` o MATCH_MP
7163 (ONCE_REWRITE_RULE[IMP_CONJ] CLOSED_MAP_RESTRICT)) THEN
7164 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN MP_TAC(ISPECL
7165 [`f:real^M->real^N`; `{x | x IN s /\ (f:real^M->real^N) x IN c}`]
7166 CLOSED_MAP_IMP_QUOTIENT_MAP) THEN
7167 SUBGOAL_THEN `IMAGE f {x | x IN s /\ (f:real^M->real^N) x IN c} = c`
7168 ASSUME_TAC THENL [ASM SET_TAC[]; ASM_REWRITE_TAC[]] THEN ANTS_TAC THENL
7169 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
7170 CONTINUOUS_ON_SUBSET)) THEN SET_TAC[];
7172 MATCH_MP_TAC CONNECTED_MONOTONE_QUOTIENT_PREIMAGE THEN
7173 MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `c:real^N->bool`] THEN
7174 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
7175 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
7176 CONTINUOUS_ON_SUBSET)) THEN SET_TAC[];
7178 `y IN c ==> {x | x IN {x | x IN s /\ f x IN c} /\ f x = y} =
7179 {x | x IN s /\ f x = y}`] THEN
7182 (* ------------------------------------------------------------------------- *)
7183 (* Proper maps, including projections out of compact sets. *)
7184 (* ------------------------------------------------------------------------- *)
7186 let PROPER_MAP = prove
7187 (`!f:real^M->real^N s t.
7189 ==> ((!k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}) <=>
7190 (!k. closed_in (subtopology euclidean s) k
7191 ==> closed_in (subtopology euclidean t) (IMAGE f k)) /\
7192 (!a. a IN t ==> compact {x | x IN s /\ f x = a}))`,
7193 REPEAT STRIP_TAC THEN EQ_TAC THENL
7194 [REPEAT STRIP_TAC THENL
7196 ONCE_REWRITE_TAC[SET_RULE `x = a <=> x IN {a}`] THEN
7197 FIRST_X_ASSUM MATCH_MP_TAC THEN
7198 ASM_REWRITE_TAC[SING_SUBSET; COMPACT_SING]] THEN
7199 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
7200 REWRITE_TAC[CLOSED_IN_LIMPT] THEN
7201 CONJ_TAC THENL [ASM SET_TAC[]; X_GEN_TAC `y:real^N`] THEN
7202 REWRITE_TAC[LIMPT_SEQUENTIAL_INJ; IN_DELETE] THEN
7203 REWRITE_TAC[IN_IMAGE; LEFT_AND_EXISTS_THM; SKOLEM_THM] THEN
7204 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
7205 REWRITE_TAC[GSYM CONJ_ASSOC; FORALL_AND_THM] THEN
7206 ONCE_REWRITE_TAC[GSYM FUN_EQ_THM] THEN
7207 REWRITE_TAC[UNWIND_THM2; FUN_EQ_THM] THEN
7208 DISCH_THEN(X_CHOOSE_THEN `x:num->real^M` STRIP_ASSUME_TAC) THEN
7210 `~(INTERS {{a | a IN k /\
7211 (f:real^M->real^N) a IN
7212 (y INSERT IMAGE (\i. f(x(n + i))) (:num))} |
7215 [MATCH_MP_TAC COMPACT_FIP THEN CONJ_TAC THENL
7216 [REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV] THEN X_GEN_TAC `n:num` THEN
7217 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CLOSED_IN_CLOSED]) THEN
7218 DISCH_THEN(X_CHOOSE_THEN `c:real^M->bool` STRIP_ASSUME_TAC) THEN
7219 ASM_REWRITE_TAC[SET_RULE
7220 `{x | x IN s INTER k /\ P x} = k INTER {x | x IN s /\ P x}`] THEN
7221 MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN
7222 FIRST_X_ASSUM MATCH_MP_TAC THEN
7223 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7224 MATCH_MP_TAC COMPACT_SEQUENCE_WITH_LIMIT THEN
7225 FIRST_ASSUM(MP_TAC o SPEC `n:num` o MATCH_MP SEQ_OFFSET) THEN
7226 REWRITE_TAC[ADD_SYM];
7227 REWRITE_TAC[SIMPLE_IMAGE; FORALL_FINITE_SUBSET_IMAGE] THEN
7228 X_GEN_TAC `i:num->bool` THEN STRIP_TAC THEN
7229 FIRST_ASSUM(MP_TAC o ISPEC `\n:num. n` o MATCH_MP
7230 UPPER_BOUND_FINITE_SET) THEN
7231 REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_TAC `m:num`) THEN
7232 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; INTERS_IMAGE; IN_ELIM_THM] THEN
7233 EXISTS_TAC `(x:num->real^M) m` THEN
7234 X_GEN_TAC `p:num` THEN DISCH_TAC THEN
7235 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7236 REWRITE_TAC[IN_INSERT; IN_IMAGE; IN_UNIV] THEN DISJ2_TAC THEN
7237 EXISTS_TAC `m - p:num` THEN
7238 ASM_MESON_TAC[ARITH_RULE `p <= m ==> p + m - p:num = m`]];
7239 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN MATCH_MP_TAC MONO_EXISTS THEN
7240 X_GEN_TAC `x:real^M` THEN
7241 REWRITE_TAC[INTERS_GSPEC; IN_ELIM_THM; IN_UNIV] THEN
7242 DISCH_THEN(fun th -> LABEL_TAC "*" th THEN MP_TAC(SPEC `0` th)) THEN
7243 REWRITE_TAC[ADD_CLAUSES; IN_INSERT; IN_IMAGE; IN_UNIV] THEN
7244 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (DISJ_CASES_THEN MP_TAC)) THEN
7245 ASM_SIMP_TAC[] THEN DISCH_THEN(X_CHOOSE_TAC `i:num`) THEN
7246 REMOVE_THEN "*" (MP_TAC o SPEC `i + 1`) THEN
7247 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
7248 ASM_REWRITE_TAC[IN_INSERT; IN_IMAGE; IN_UNIV] THEN ARITH_TAC];
7249 STRIP_TAC THEN X_GEN_TAC `k:real^N->bool` THEN STRIP_TAC THEN
7250 REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN
7251 X_GEN_TAC `c:(real^M->bool)->bool` THEN STRIP_TAC THEN
7254 ==> ?g. g SUBSET c /\ FINITE g /\
7255 {x | x IN s /\ (f:real^M->real^N) x = a} SUBSET UNIONS g`
7257 [X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN UNDISCH_THEN
7258 `!a. a IN t ==> compact {x | x IN s /\ (f:real^M->real^N) x = a}`
7259 (MP_TAC o SPEC `a:real^N`) THEN
7260 ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[COMPACT_EQ_HEINE_BOREL]] THEN
7261 DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
7262 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
7263 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
7264 X_GEN_TAC `uu:real^N->(real^M->bool)->bool` THEN
7265 DISCH_THEN(LABEL_TAC "*")] THEN
7268 ==> ?v. open v /\ a IN v /\
7269 {x | x IN s /\ (f:real^M->real^N) x IN v} SUBSET UNIONS(uu a)`
7271 [REPEAT STRIP_TAC THEN
7273 `!k. closed_in (subtopology euclidean s) k
7274 ==> closed_in (subtopology euclidean t)
7275 (IMAGE (f:real^M->real^N) k)`
7276 (MP_TAC o SPEC `(s:real^M->bool) DIFF UNIONS(uu(a:real^N))`) THEN
7277 SIMP_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ANTS_TAC THENL
7278 [CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
7279 REWRITE_TAC[SET_RULE `s DIFF (s DIFF t) = s INTER t`] THEN
7280 MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN
7281 MATCH_MP_TAC OPEN_UNIONS THEN ASM SET_TAC[];
7282 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
7283 REWRITE_TAC[OPEN_IN_OPEN] THEN MATCH_MP_TAC MONO_EXISTS THEN
7284 X_GEN_TAC `v:real^N->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
7285 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `a:real^N`)) THEN
7286 ASM_REWRITE_TAC[] THEN REPEAT
7287 ((ANTS_TAC THENL [ASM SET_TAC[]; DISCH_TAC]) ORELSE STRIP_TAC)
7288 THENL [ALL_TAC; ASM SET_TAC[]] THEN
7289 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
7290 DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN ASM SET_TAC[]];
7291 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
7292 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
7293 X_GEN_TAC `vv:real^N->(real^N->bool)` THEN
7294 DISCH_THEN(LABEL_TAC "+")] THEN
7295 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL]) THEN
7296 DISCH_THEN(MP_TAC o SPEC `IMAGE (vv:real^N->(real^N->bool)) k`) THEN
7297 ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN
7298 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r ==> s <=> q /\ p ==> r ==> s`] THEN
7299 REWRITE_TAC[FORALL_FINITE_SUBSET_IMAGE] THEN
7300 X_GEN_TAC `j:real^N->bool` THEN REPEAT STRIP_TAC THEN
7301 EXISTS_TAC `UNIONS(IMAGE (uu:real^N->(real^M->bool)->bool) j)` THEN
7302 REPEAT CONJ_TAC THENL
7304 ASM_SIMP_TAC[FINITE_UNIONS; FORALL_IN_IMAGE; FINITE_IMAGE] THEN
7306 REWRITE_TAC[UNIONS_IMAGE; SUBSET; IN_UNIONS; IN_ELIM_THM] THEN
7309 let COMPACT_CONTINUOUS_IMAGE_EQ = prove
7310 (`!f:real^M->real^N s.
7311 (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y)
7312 ==> (f continuous_on s <=>
7313 !t. compact t /\ t SUBSET s ==> compact(IMAGE f t))`,
7314 REPEAT STRIP_TAC THEN EQ_TAC THENL
7315 [MESON_TAC[COMPACT_CONTINUOUS_IMAGE; CONTINUOUS_ON_SUBSET]; DISCH_TAC] THEN
7316 FIRST_X_ASSUM(X_CHOOSE_TAC `g:real^N->real^M` o
7317 GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN
7318 REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN
7319 X_GEN_TAC `u:real^N->bool` THEN DISCH_TAC THEN
7320 MP_TAC(ISPECL [`g:real^N->real^M`; `IMAGE (f:real^M->real^N) s`;
7321 `s:real^M->bool`] PROPER_MAP) THEN
7322 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7323 MATCH_MP_TAC(TAUT `(q ==> s) /\ p ==> (p <=> q /\ r) ==> s`) THEN
7324 REPEAT STRIP_TAC THENL
7326 `{x | x IN s /\ (f:real^M->real^N) x IN u} = IMAGE g u`
7327 (fun th -> ASM_MESON_TAC[th]);
7329 `{x | x IN IMAGE f s /\ (g:real^N->real^M) x IN k} = IMAGE f k`
7330 (fun th -> ASM_SIMP_TAC[th])] THEN
7331 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN ASM SET_TAC[]);;
7333 let PROPER_MAP_FROM_COMPACT = prove
7334 (`!f:real^M->real^N s k.
7335 f continuous_on s /\ IMAGE f s SUBSET t /\ compact s /\
7336 closed_in (subtopology euclidean t) k
7337 ==> compact {x | x IN s /\ f x IN k}`,
7338 REPEAT STRIP_TAC THEN
7339 MATCH_MP_TAC CLOSED_IN_COMPACT THEN EXISTS_TAC `s:real^M->bool` THEN
7340 ASM_MESON_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_GEN]);;
7342 let PROPER_MAP_COMPOSE = prove
7343 (`!f:real^M->real^N g:real^N->real^P s t u.
7344 IMAGE f s SUBSET t /\
7345 (!k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}) /\
7346 (!k. k SUBSET u /\ compact k ==> compact {x | x IN t /\ g x IN k})
7347 ==> !k. k SUBSET u /\ compact k
7348 ==> compact {x | x IN s /\ (g o f) x IN k}`,
7349 REPEAT STRIP_TAC THEN REWRITE_TAC[o_THM] THEN
7350 FIRST_X_ASSUM(MP_TAC o SPEC `k:real^P->bool`) THEN
7351 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
7352 FIRST_X_ASSUM(MP_TAC o SPEC `{x | x IN t /\ (g:real^N->real^P) x IN k}`) THEN
7353 ANTS_TAC THENL [ASM SET_TAC[]; MATCH_MP_TAC EQ_IMP] THEN
7354 AP_TERM_TAC THEN ASM SET_TAC[]);;
7356 let PROPER_MAP_FROM_COMPOSITION_LEFT = prove
7357 (`!f:real^M->real^N g:real^N->real^P s t u.
7358 f continuous_on s /\ IMAGE f s = t /\
7359 g continuous_on t /\ IMAGE g t SUBSET u /\
7360 (!k. k SUBSET u /\ compact k
7361 ==> compact {x | x IN s /\ (g o f) x IN k})
7362 ==> !k. k SUBSET u /\ compact k ==> compact {x | x IN t /\ g x IN k}`,
7363 REWRITE_TAC[o_THM] THEN REPEAT STRIP_TAC THEN
7364 FIRST_X_ASSUM(MP_TAC o SPEC `k:real^P->bool`) THEN ASM_REWRITE_TAC[] THEN
7365 DISCH_THEN(MP_TAC o ISPEC `f:real^M->real^N` o MATCH_MP
7366 (REWRITE_RULE[IMP_CONJ_ALT] COMPACT_CONTINUOUS_IMAGE)) THEN
7368 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
7369 CONTINUOUS_ON_SUBSET)) THEN SET_TAC[];
7370 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]]);;
7372 let PROPER_MAP_FROM_COMPOSITION_RIGHT = prove
7373 (`!f:real^M->real^N g:real^N->real^P s t u.
7374 f continuous_on s /\ IMAGE f s SUBSET t /\
7375 g continuous_on t /\ IMAGE g t SUBSET u /\
7376 (!k. k SUBSET u /\ compact k
7377 ==> compact {x | x IN s /\ (g o f) x IN k})
7378 ==> !k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}`,
7380 (`!s t. closed_in (subtopology euclidean s) t ==> compact s ==> compact t`,
7381 MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_SUBSET;
7382 CLOSED_IN_CLOSED_EQ]) in
7383 REWRITE_TAC[o_THM] THEN REPEAT STRIP_TAC THEN
7384 FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (g:real^N->real^P) k`) THEN
7386 [CONJ_TAC THENL [ASM SET_TAC[]; MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE] THEN
7387 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET];
7388 MATCH_MP_TAC lemma THEN
7389 MATCH_MP_TAC CLOSED_IN_SUBSET_TRANS THEN
7390 EXISTS_TAC `s:real^M->bool` THEN
7391 CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
7392 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN
7393 EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[] THEN
7394 MATCH_MP_TAC CLOSED_SUBSET THEN ASM_SIMP_TAC[COMPACT_IMP_CLOSED]]);;
7396 let PROPER_MAP_FSTCART = prove
7397 (`!s:real^M->bool t:real^N->bool k.
7398 compact t /\ k SUBSET s /\ compact k
7399 ==> compact {z | z IN s PCROSS t /\ fstcart z IN k}`,
7400 REPEAT STRIP_TAC THEN SUBGOAL_THEN
7401 `{z | z IN s PCROSS t /\ fstcart z IN k} =
7402 (k:real^M->bool) PCROSS (t:real^N->bool)`
7403 (fun th -> ASM_SIMP_TAC[th; COMPACT_PCROSS]) THEN
7404 REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_THM;
7405 PASTECART_IN_PCROSS; FSTCART_PASTECART] THEN
7408 let CLOSED_MAP_FSTCART = prove
7409 (`!s:real^M->bool t:real^N->bool c.
7410 compact t /\ closed_in (subtopology euclidean (s PCROSS t)) c
7411 ==> closed_in (subtopology euclidean s) (IMAGE fstcart c)`,
7412 REPEAT STRIP_TAC THEN
7413 MP_TAC(ISPECL [`fstcart:real^(M,N)finite_sum->real^M`;
7414 `(s:real^M->bool) PCROSS (t:real^N->bool)`;
7417 ASM_SIMP_TAC[PROPER_MAP_FSTCART; IMAGE_FSTCART_PCROSS] THEN
7420 let PROPER_MAP_SNDCART = prove
7421 (`!s:real^M->bool t:real^N->bool k.
7422 compact s /\ k SUBSET t /\ compact k
7423 ==> compact {z | z IN s PCROSS t /\ sndcart z IN k}`,
7424 REPEAT STRIP_TAC THEN SUBGOAL_THEN
7425 `{z | z IN s PCROSS t /\ sndcart z IN k} =
7426 (s:real^M->bool) PCROSS (k:real^N->bool)`
7427 (fun th -> ASM_SIMP_TAC[th; COMPACT_PCROSS]) THEN
7428 REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_THM;
7429 PASTECART_IN_PCROSS; SNDCART_PASTECART] THEN
7432 let CLOSED_MAP_SNDCART = prove
7433 (`!s:real^M->bool t:real^N->bool c.
7434 compact s /\ closed_in (subtopology euclidean (s PCROSS t)) c
7435 ==> closed_in (subtopology euclidean t) (IMAGE sndcart c)`,
7436 REPEAT STRIP_TAC THEN
7437 MP_TAC(ISPECL [`sndcart:real^(M,N)finite_sum->real^N`;
7438 `(s:real^M->bool) PCROSS (t:real^N->bool)`;
7441 ASM_SIMP_TAC[PROPER_MAP_SNDCART; IMAGE_SNDCART_PCROSS] THEN
7444 let CLOSED_IN_COMPACT_PROJECTION = prove
7445 (`!s:real^M->bool t:real^N->bool u.
7446 compact s /\ closed_in (subtopology euclidean (s PCROSS t)) u
7447 ==> closed_in (subtopology euclidean t)
7448 {y | ?x. x IN s /\ pastecart x y IN u}`,
7449 REPEAT GEN_TAC THEN DISCH_TAC THEN
7450 FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_MAP_SNDCART) THEN
7451 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
7452 FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET o CONJUNCT2) THEN
7453 REWRITE_TAC[EXTENSION; SUBSET; IN_IMAGE; FORALL_PASTECART; EXISTS_PASTECART;
7454 PASTECART_IN_PCROSS; IN_ELIM_THM; SNDCART_PASTECART] THEN
7457 let CLOSED_COMPACT_PROJECTION = prove
7458 (`!s:real^M->bool t:real^(M,N)finite_sum->bool.
7459 compact s /\ closed t ==> closed {y | ?x. x IN s /\ pastecart x y IN t}`,
7460 REPEAT STRIP_TAC THEN
7462 `{y | ?x:real^M. x IN s /\ pastecart x y IN t} =
7463 {y | ?x. x IN s /\ pastecart x y IN ((s PCROSS (:real^N)) INTER t)}`
7465 [REWRITE_TAC[PASTECART_IN_PCROSS; IN_UNIV; IN_INTER] THEN SET_TAC[];
7466 MATCH_MP_TAC CLOSED_IN_CLOSED_TRANS THEN
7467 EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[CLOSED_UNIV] THEN
7468 MATCH_MP_TAC CLOSED_IN_COMPACT_PROJECTION THEN
7469 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CLOSED_SUBSET THEN
7470 ASM_SIMP_TAC[CLOSED_INTER; CLOSED_UNIV; CLOSED_PCROSS; COMPACT_IMP_CLOSED;
7473 let TUBE_LEMMA = prove
7474 (`!s:real^M->bool t:real^N->bool u a.
7475 compact s /\ ~(s = {}) /\ {pastecart x a | x IN s} SUBSET u /\
7476 open_in(subtopology euclidean (s PCROSS t)) u
7477 ==> ?v. open_in (subtopology euclidean t) v /\ a IN v /\
7478 (s PCROSS v) SUBSET u`,
7479 REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN
7480 REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ] THEN
7481 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
7482 REPEAT STRIP_TAC THEN
7483 FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT; PCROSS]
7484 CLOSED_IN_COMPACT_PROJECTION)) THEN
7485 ASM_REWRITE_TAC[IN_ELIM_PASTECART_THM; IN_DIFF] THEN
7486 REWRITE_TAC[GSYM CONJ_ASSOC] THEN MATCH_MP_TAC(MESON[]
7487 `(closed_in top t ==> s DIFF (s DIFF t) = t) /\
7488 s DIFF t SUBSET s /\ P(s DIFF t)
7490 ==> ?v. v SUBSET s /\ closed_in top (s DIFF v) /\ P v`) THEN
7491 REWRITE_TAC[SET_RULE `s DIFF (s DIFF t) = t <=> t SUBSET s`] THEN
7492 REWRITE_TAC[SUBSET_DIFF] THEN
7493 SIMP_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
7494 REWRITE_TAC[IN_DIFF; IN_ELIM_THM] THEN
7495 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN
7496 CONJ_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
7497 REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET])) THEN
7498 REWRITE_TAC[FORALL_IN_GSPEC; IN_SING; FORALL_PASTECART] THEN
7499 REWRITE_TAC[IN_ELIM_PASTECART_THM] THEN ASM_MESON_TAC[MEMBER_NOT_EMPTY]);;
7501 let TUBE_LEMMA_GEN = prove
7502 (`!s t t' u:real^(M,N)finite_sum->bool.
7503 compact s /\ ~(s = {}) /\ t SUBSET t' /\
7504 s PCROSS t SUBSET u /\
7505 open_in (subtopology euclidean (s PCROSS t')) u
7506 ==> ?v. open_in (subtopology euclidean t') v /\
7508 s PCROSS v SUBSET u`,
7509 REPEAT STRIP_TAC THEN
7511 `!a. a IN t ==> ?v. open_in (subtopology euclidean t') v /\ a IN v /\
7512 (s:real^M->bool) PCROSS (v:real^N->bool) SUBSET u`
7514 [REPEAT STRIP_TAC THEN MATCH_MP_TAC TUBE_LEMMA THEN
7515 ASM_REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN REPEAT STRIP_TAC THEN
7516 REPEAT STRIP_TAC THEN
7517 FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[SUBSET]) THEN
7518 ASM_REWRITE_TAC[PASTECART_IN_PCROSS];
7519 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
7520 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
7521 X_GEN_TAC `vv:real^N->real^N->bool` THEN DISCH_TAC THEN
7522 EXISTS_TAC `UNIONS (IMAGE (vv:real^N->real^N->bool) t)` THEN
7523 ASM_SIMP_TAC[OPEN_IN_UNIONS; FORALL_IN_IMAGE] THEN
7524 REWRITE_TAC[SUBSET; UNIONS_IMAGE; IN_ELIM_THM; FORALL_IN_PCROSS] THEN
7525 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7526 MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^N`] THEN
7527 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_TAC `c:real^N`)) THEN
7528 FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N`) THEN
7529 ASM_REWRITE_TAC[SUBSET; FORALL_IN_PCROSS] THEN ASM SET_TAC[]]);;
7531 (* ------------------------------------------------------------------------- *)
7532 (* Pasting functions together on open sets. *)
7533 (* ------------------------------------------------------------------------- *)
7535 let PASTING_LEMMA = prove
7536 (`!f:A->real^M->real^N g t s k.
7538 ==> open_in (subtopology euclidean s) (t i) /\
7539 (f i) continuous_on (t i)) /\
7540 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j
7541 ==> f i x = f j x) /\
7542 (!x. x IN s ==> ?j. j IN k /\ x IN t j /\ g x = f j x)
7543 ==> g continuous_on s`,
7544 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_OPEN_IN_PREIMAGE_EQ] THEN
7545 STRIP_TAC THEN X_GEN_TAC `u:real^N->bool` THEN DISCH_TAC THEN
7547 `{x | x IN s /\ g x IN u} =
7548 UNIONS {{x | x IN (t i) /\ ((f:A->real^M->real^N) i x) IN u} |
7551 [SUBGOAL_THEN `!i. i IN k ==> ((t:A->real^M->bool) i) SUBSET s`
7553 [ASM_MESON_TAC[OPEN_IN_SUBSET; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY];
7554 REWRITE_TAC[UNIONS_GSPEC] THEN ASM SET_TAC[]];
7555 MATCH_MP_TAC OPEN_IN_UNIONS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN
7556 ASM_MESON_TAC[OPEN_IN_TRANS]]);;
7558 let PASTING_LEMMA_EXISTS = prove
7559 (`!f:A->real^M->real^N t s k.
7560 s SUBSET UNIONS {t i | i IN k} /\
7562 ==> open_in (subtopology euclidean s) (t i) /\
7563 (f i) continuous_on (t i)) /\
7564 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j
7566 ==> ?g. g continuous_on s /\
7567 (!x i. i IN k /\ x IN s INTER t i ==> g x = f i x)`,
7568 REPEAT STRIP_TAC THEN
7569 EXISTS_TAC `\x. (f:A->real^M->real^N)(@i. i IN k /\ x IN t i) x` THEN
7570 CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN MATCH_MP_TAC PASTING_LEMMA THEN
7571 MAP_EVERY EXISTS_TAC
7572 [`f:A->real^M->real^N`; `t:A->real^M->bool`; `k:A->bool`] THEN
7575 let CONTINUOUS_ON_UNION_LOCAL_OPEN = prove
7576 (`!f:real^M->real^N s.
7577 open_in (subtopology euclidean (s UNION t)) s /\
7578 open_in (subtopology euclidean (s UNION t)) t /\
7579 f continuous_on s /\ f continuous_on t
7580 ==> f continuous_on (s UNION t)`,
7581 REPEAT STRIP_TAC THEN MP_TAC(ISPECL
7582 [`\i:(real^M->bool). (f:real^M->real^N)`; `f:real^M->real^N`;
7583 `\i:(real^M->bool). i`; `s UNION t:real^M->bool`; `{s:real^M->bool,t}`]
7584 PASTING_LEMMA) THEN DISCH_THEN MATCH_MP_TAC THEN
7585 ASM_REWRITE_TAC[FORALL_IN_INSERT; EXISTS_IN_INSERT; NOT_IN_EMPTY] THEN
7586 REWRITE_TAC[IN_UNION]);;
7588 let CONTINUOUS_ON_UNION_OPEN = prove
7589 (`!f s t. open s /\ open t /\ f continuous_on s /\ f continuous_on t
7590 ==> f continuous_on (s UNION t)`,
7591 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL_OPEN THEN
7592 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN
7593 ASM_SIMP_TAC[OPEN_UNION] THEN SET_TAC[]);;
7595 let CONTINUOUS_ON_CASES_LOCAL_OPEN = prove
7596 (`!P f g:real^M->real^N s t.
7597 open_in (subtopology euclidean (s UNION t)) s /\
7598 open_in (subtopology euclidean (s UNION t)) t /\
7599 f continuous_on s /\ g continuous_on t /\
7600 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x)
7601 ==> (\x. if P x then f x else g x) continuous_on (s UNION t)`,
7602 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL_OPEN THEN
7603 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL
7604 [EXISTS_TAC `f:real^M->real^N`; EXISTS_TAC `g:real^M->real^N`] THEN
7605 ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;
7607 let CONTINUOUS_ON_CASES_OPEN = prove
7611 f continuous_on s /\
7612 g continuous_on t /\
7613 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x)
7614 ==> (\x. if P x then f x else g x) continuous_on s UNION t`,
7615 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL_OPEN THEN
7616 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN
7617 ASM_SIMP_TAC[OPEN_UNION] THEN SET_TAC[]);;
7619 (* ------------------------------------------------------------------------- *)
7620 (* Likewise on closed sets, with a finiteness assumption. *)
7621 (* ------------------------------------------------------------------------- *)
7623 let PASTING_LEMMA_CLOSED = prove
7624 (`!f:A->real^M->real^N g t s k.
7627 ==> closed_in (subtopology euclidean s) (t i) /\
7628 (f i) continuous_on (t i)) /\
7629 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j
7630 ==> f i x = f j x) /\
7631 (!x. x IN s ==> ?j. j IN k /\ x IN t j /\ g x = f j x)
7632 ==> g continuous_on s`,
7633 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN
7634 STRIP_TAC THEN X_GEN_TAC `u:real^N->bool` THEN DISCH_TAC THEN
7636 `{x | x IN s /\ g x IN u} =
7637 UNIONS {{x | x IN (t i) /\ ((f:A->real^M->real^N) i x) IN u} |
7640 [SUBGOAL_THEN `!i. i IN k ==> ((t:A->real^M->bool) i) SUBSET s`
7642 [ASM_MESON_TAC[CLOSED_IN_SUBSET; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY];
7643 REWRITE_TAC[UNIONS_GSPEC] THEN ASM SET_TAC[]];
7644 MATCH_MP_TAC CLOSED_IN_UNIONS THEN
7645 ASM_SIMP_TAC[SIMPLE_IMAGE; FINITE_IMAGE; FORALL_IN_IMAGE] THEN
7646 ASM_MESON_TAC[CLOSED_IN_TRANS]]);;
7648 let PASTING_LEMMA_EXISTS_CLOSED = prove
7649 (`!f:A->real^M->real^N t s k.
7651 s SUBSET UNIONS {t i | i IN k} /\
7653 ==> closed_in (subtopology euclidean s) (t i) /\
7654 (f i) continuous_on (t i)) /\
7655 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j
7657 ==> ?g. g continuous_on s /\
7658 (!x i. i IN k /\ x IN s INTER t i ==> g x = f i x)`,
7659 REPEAT STRIP_TAC THEN
7660 EXISTS_TAC `\x. (f:A->real^M->real^N)(@i. i IN k /\ x IN t i) x` THEN
7661 CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
7662 MATCH_MP_TAC PASTING_LEMMA_CLOSED THEN
7663 MAP_EVERY EXISTS_TAC
7664 [`f:A->real^M->real^N`; `t:A->real^M->bool`; `k:A->bool`] THEN
7667 (* ------------------------------------------------------------------------- *)
7668 (* Closure of halflines, halfspaces and hyperplanes. *)
7669 (* ------------------------------------------------------------------------- *)
7671 let LIM_LIFT_DOT = prove
7672 (`!f:real^M->real^N a.
7673 (f --> l) net ==> ((lift o (\y. a dot f(y))) --> lift(a dot l)) net`,
7674 REPEAT GEN_TAC THEN ASM_CASES_TAC `a = vec 0:real^N` THENL
7675 [ASM_REWRITE_TAC[DOT_LZERO; LIFT_NUM; o_DEF; LIM_CONST]; ALL_TAC] THEN
7676 REWRITE_TAC[LIM] THEN MATCH_MP_TAC MONO_OR THEN REWRITE_TAC[] THEN
7677 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
7678 FIRST_X_ASSUM(MP_TAC o SPEC `e / norm(a:real^N)`) THEN
7679 ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; REAL_LT_RDIV_EQ] THEN
7680 REWRITE_TAC[dist; o_THM; GSYM LIFT_SUB; GSYM DOT_RSUB; NORM_LIFT] THEN
7681 ONCE_REWRITE_TAC[DOT_SYM] THEN
7682 MESON_TAC[NORM_CAUCHY_SCHWARZ_ABS; REAL_MUL_SYM; REAL_LET_TRANS]);;
7684 let CONTINUOUS_AT_LIFT_DOT = prove
7685 (`!a:real^N x. (lift o (\y. a dot y)) continuous at x`,
7686 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_AT; o_THM] THEN
7687 MATCH_MP_TAC LIM_LIFT_DOT THEN REWRITE_TAC[LIM_AT] THEN MESON_TAC[]);;
7689 let CONTINUOUS_ON_LIFT_DOT = prove
7690 (`!s. (lift o (\y. a dot y)) continuous_on s`,
7691 SIMP_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_LIFT_DOT]);;
7693 let CLOSED_INTERVAL_LEFT = prove
7695 closed {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> x$i <= b$i}`,
7696 REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE; IN_ELIM_THM] THEN
7697 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
7698 FIRST_X_ASSUM(MP_TAC o SPEC `(x:real^N)$i - (b:real^N)$i`) THEN
7699 ASM_REWRITE_TAC[REAL_SUB_LT] THEN
7700 DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN
7701 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
7702 REWRITE_TAC[dist; REAL_NOT_LT] THEN
7703 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((z - x :real^N)$i)` THEN
7704 ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
7705 ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
7706 ASM_SIMP_TAC[REAL_ARITH `z <= b /\ b < x ==> x - b <= abs(z - x)`]);;
7708 let CLOSED_INTERVAL_RIGHT = prove
7710 closed {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= x$i}`,
7711 REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE; IN_ELIM_THM] THEN
7712 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
7713 FIRST_X_ASSUM(MP_TAC o SPEC `(a:real^N)$i - (x:real^N)$i`) THEN
7714 ASM_REWRITE_TAC[REAL_SUB_LT] THEN
7715 DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN
7716 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
7717 REWRITE_TAC[dist; REAL_NOT_LT] THEN
7718 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((z - x :real^N)$i)` THEN
7719 ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
7720 ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
7721 ASM_SIMP_TAC[REAL_ARITH `x < a /\ a <= z ==> a - x <= abs(z - x)`]);;
7723 let CLOSED_HALFSPACE_LE = prove
7724 (`!a:real^N b. closed {x | a dot x <= b}`,
7726 MP_TAC(ISPEC `(:real^N)` CONTINUOUS_ON_LIFT_DOT) THEN
7727 REWRITE_TAC[CONTINUOUS_ON_CLOSED; GSYM CLOSED_IN; SUBTOPOLOGY_UNIV] THEN
7728 DISCH_THEN(MP_TAC o SPEC
7729 `IMAGE lift {r | ?x:real^N. (a dot x = r) /\ r <= b}`) THEN
7732 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
7733 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; IN_UNIV] THEN
7734 REWRITE_TAC[o_DEF] THEN MESON_TAC[LIFT_DROP]] THEN
7735 REWRITE_TAC[CLOSED_IN_CLOSED] THEN
7736 EXISTS_TAC `{x | !i. 1 <= i /\ i <= dimindex(:1)
7737 ==> (x:real^1)$i <= (lift b)$i}` THEN
7738 REWRITE_TAC[CLOSED_INTERVAL_LEFT] THEN
7739 SIMP_TAC[EXTENSION; IN_IMAGE; IN_UNIV; IN_ELIM_THM; IN_INTER;
7740 VEC_COMPONENT; DIMINDEX_1; LAMBDA_BETA; o_THM] THEN
7741 SIMP_TAC[ARITH_RULE `1 <= i /\ i <= 1 <=> (i = 1)`] THEN
7742 REWRITE_TAC[GSYM drop; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
7743 MESON_TAC[LIFT_DROP]);;
7745 let CLOSED_HALFSPACE_GE = prove
7746 (`!a:real^N b. closed {x | a dot x >= b}`,
7747 REWRITE_TAC[REAL_ARITH `a >= b <=> --a <= --b`] THEN
7748 REWRITE_TAC[GSYM DOT_LNEG; CLOSED_HALFSPACE_LE]);;
7750 let CLOSED_HYPERPLANE = prove
7751 (`!a b. closed {x | a dot x = b}`,
7752 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
7753 REWRITE_TAC[REAL_ARITH `b <= a dot x <=> a dot x >= b`] THEN
7754 REWRITE_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN
7755 SIMP_TAC[CLOSED_INTER; CLOSED_HALFSPACE_LE; CLOSED_HALFSPACE_GE]);;
7757 let CLOSED_STANDARD_HYPERPLANE = prove
7758 (`!k a. closed {x:real^N | x$k = a}`,
7760 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
7762 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
7763 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSED_HYPERPLANE) THEN
7764 ASM_SIMP_TAC[DOT_BASIS]);;
7766 let CLOSED_HALFSPACE_COMPONENT_LE = prove
7767 (`!a k. closed {x:real^N | x$k <= a}`,
7769 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
7771 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
7772 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSED_HALFSPACE_LE) THEN
7773 ASM_SIMP_TAC[DOT_BASIS]);;
7775 let CLOSED_HALFSPACE_COMPONENT_GE = prove
7776 (`!a k. closed {x:real^N | x$k >= a}`,
7778 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
7780 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
7781 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSED_HALFSPACE_GE) THEN
7782 ASM_SIMP_TAC[DOT_BASIS]);;
7784 (* ------------------------------------------------------------------------- *)
7785 (* Openness of halfspaces. *)
7786 (* ------------------------------------------------------------------------- *)
7788 let OPEN_HALFSPACE_LT = prove
7789 (`!a b. open {x | a dot x < b}`,
7790 REWRITE_TAC[GSYM REAL_NOT_LE] THEN
7791 REWRITE_TAC[SET_RULE `{x | ~p x} = UNIV DIFF {x | p x}`] THEN
7792 REWRITE_TAC[GSYM closed; GSYM real_ge; CLOSED_HALFSPACE_GE]);;
7794 let OPEN_HALFSPACE_COMPONENT_LT = prove
7795 (`!a k. open {x:real^N | x$k < a}`,
7797 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
7799 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
7800 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] OPEN_HALFSPACE_LT) THEN
7801 ASM_SIMP_TAC[DOT_BASIS]);;
7803 let OPEN_HALFSPACE_GT = prove
7804 (`!a b. open {x | a dot x > b}`,
7805 REWRITE_TAC[REAL_ARITH `x > y <=> ~(x <= y)`] THEN
7806 REWRITE_TAC[SET_RULE `{x | ~p x} = UNIV DIFF {x | p x}`] THEN
7807 REWRITE_TAC[GSYM closed; CLOSED_HALFSPACE_LE]);;
7809 let OPEN_HALFSPACE_COMPONENT_GT = prove
7810 (`!a k. open {x:real^N | x$k > a}`,
7812 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
7814 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
7815 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] OPEN_HALFSPACE_GT) THEN
7816 ASM_SIMP_TAC[DOT_BASIS]);;
7818 let OPEN_POSITIVE_MULTIPLES = prove
7819 (`!s:real^N->bool. open s ==> open {c % x | &0 < c /\ x IN s}`,
7820 REWRITE_TAC[open_def; FORALL_IN_GSPEC] THEN GEN_TAC THEN DISCH_TAC THEN
7821 MAP_EVERY X_GEN_TAC [`c:real`; `x:real^N`] THEN STRIP_TAC THEN
7822 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
7823 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
7824 EXISTS_TAC `c * e:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN
7825 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
7826 FIRST_X_ASSUM(MP_TAC o SPEC `inv(c) % y:real^N`) THEN ANTS_TAC THENL
7827 [SUBGOAL_THEN `x:real^N = inv c % c % x` SUBST1_TAC THENL
7828 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID;
7830 ASM_SIMP_TAC[DIST_MUL; real_abs; REAL_LT_INV_EQ; REAL_LT_IMP_LE] THEN
7831 ONCE_REWRITE_TAC[REAL_ARITH `inv c * x:real = x / c`] THEN
7832 ASM_MESON_TAC[REAL_LT_LDIV_EQ; REAL_MUL_SYM]];
7833 DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
7834 EXISTS_TAC `c:real` THEN EXISTS_TAC `inv(c) % y:real^N` THEN
7835 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; REAL_LT_IMP_NZ] THEN
7836 VECTOR_ARITH_TAC]);;
7838 let OPEN_INTERVAL_LEFT = prove
7839 (`!b:real^N. open {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> x$i < b$i}`,
7842 `{x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> x$i < b$i} =
7843 INTERS{{x | x$i < (b:real^N)$i} | i IN 1..dimindex(:N)}`
7845 [REWRITE_TAC[INTERS_GSPEC; IN_NUMSEG] THEN SET_TAC[];
7846 MATCH_MP_TAC OPEN_INTERS THEN
7847 SIMP_TAC[SIMPLE_IMAGE; FINITE_IMAGE; FINITE_NUMSEG] THEN
7848 REWRITE_TAC[FORALL_IN_IMAGE; OPEN_HALFSPACE_COMPONENT_LT]]);;
7850 let OPEN_INTERVAL_RIGHT = prove
7851 (`!a:real^N. open {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> a$i < x$i}`,
7854 `{x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> a$i < x$i} =
7855 INTERS{{x | (a:real^N)$i < x$i} | i IN 1..dimindex(:N)}`
7857 [REWRITE_TAC[INTERS_GSPEC; IN_NUMSEG] THEN SET_TAC[];
7858 MATCH_MP_TAC OPEN_INTERS THEN
7859 SIMP_TAC[SIMPLE_IMAGE; FINITE_IMAGE; FINITE_NUMSEG] THEN
7860 REWRITE_TAC[FORALL_IN_IMAGE; GSYM real_gt; OPEN_HALFSPACE_COMPONENT_GT]]);;
7862 let OPEN_POSITIVE_ORTHANT = prove
7863 (`open {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> &0 < x$i}`,
7864 MP_TAC(ISPEC `vec 0:real^N` OPEN_INTERVAL_RIGHT) THEN
7865 REWRITE_TAC[VEC_COMPONENT]);;
7867 (* ------------------------------------------------------------------------- *)
7868 (* Closures and interiors of halfspaces. *)
7869 (* ------------------------------------------------------------------------- *)
7871 let INTERIOR_HALFSPACE_LE = prove
7873 ~(a = vec 0) ==> interior {x | a dot x <= b} = {x | a dot x < b}`,
7874 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN
7875 SIMP_TAC[OPEN_HALFSPACE_LT; SUBSET; IN_ELIM_THM; REAL_LT_IMP_LE] THEN
7876 X_GEN_TAC `s:real^N->bool` THEN STRIP_TAC THEN
7877 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN ASM_SIMP_TAC[REAL_LT_LE] THEN
7879 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN
7880 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
7881 DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
7882 REWRITE_TAC[SUBSET; IN_CBALL] THEN
7883 DISCH_THEN(MP_TAC o SPEC `x + e / norm(a) % a:real^N`) THEN
7884 REWRITE_TAC[NORM_ARITH `dist(x:real^N,x + y) = norm y`] THEN
7885 ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; REAL_DIV_RMUL;
7886 NORM_EQ_0; REAL_ARITH `&0 < x ==> abs x <= x`] THEN
7888 FIRST_X_ASSUM(MP_TAC o SPEC `x + e / norm(a) % a:real^N`) THEN
7889 ASM_REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN
7890 MATCH_MP_TAC(REAL_ARITH `&0 < e ==> ~(b + e <= b)`) THEN
7891 ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; NORM_POS_LT; DOT_POS_LT]);;
7893 let INTERIOR_HALFSPACE_GE = prove
7895 ~(a = vec 0) ==> interior {x | a dot x >= b} = {x | a dot x > b}`,
7896 REPEAT STRIP_TAC THEN
7897 ONCE_REWRITE_TAC[REAL_ARITH `a >= b <=> --a <= --b`;
7898 REAL_ARITH `a > b <=> --a < --b`] THEN
7899 ASM_SIMP_TAC[GSYM DOT_LNEG; INTERIOR_HALFSPACE_LE; VECTOR_NEG_EQ_0]);;
7901 let INTERIOR_HALFSPACE_COMPONENT_LE = prove
7902 (`!a k. interior {x:real^N | x$k <= a} = {x | x$k < a}`,
7904 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
7906 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
7907 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] INTERIOR_HALFSPACE_LE) THEN
7908 ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);;
7910 let INTERIOR_HALFSPACE_COMPONENT_GE = prove
7911 (`!a k. interior {x:real^N | x$k >= a} = {x | x$k > a}`,
7913 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
7915 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
7916 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] INTERIOR_HALFSPACE_GE) THEN
7917 ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);;
7919 let CLOSURE_HALFSPACE_LT = prove
7921 ~(a = vec 0) ==> closure {x | a dot x < b} = {x | a dot x <= b}`,
7922 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSURE_INTERIOR] THEN
7923 REWRITE_TAC[SET_RULE `UNIV DIFF {x | P x} = {x | ~P x}`] THEN
7924 ASM_SIMP_TAC[REAL_ARITH `~(x < b) <=> x >= b`; INTERIOR_HALFSPACE_GE] THEN
7925 REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNIV; IN_ELIM_THM] THEN REAL_ARITH_TAC);;
7927 let CLOSURE_HALFSPACE_GT = prove
7929 ~(a = vec 0) ==> closure {x | a dot x > b} = {x | a dot x >= b}`,
7930 REPEAT STRIP_TAC THEN
7931 ONCE_REWRITE_TAC[REAL_ARITH `a >= b <=> --a <= --b`;
7932 REAL_ARITH `a > b <=> --a < --b`] THEN
7933 ASM_SIMP_TAC[GSYM DOT_LNEG; CLOSURE_HALFSPACE_LT; VECTOR_NEG_EQ_0]);;
7935 let CLOSURE_HALFSPACE_COMPONENT_LT = prove
7936 (`!a k. closure {x:real^N | x$k < a} = {x | x$k <= a}`,
7938 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
7940 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
7941 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSURE_HALFSPACE_LT) THEN
7942 ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);;
7944 let CLOSURE_HALFSPACE_COMPONENT_GT = prove
7945 (`!a k. closure {x:real^N | x$k > a} = {x | x$k >= a}`,
7947 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
7949 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
7950 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSURE_HALFSPACE_GT) THEN
7951 ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);;
7953 let INTERIOR_HYPERPLANE = prove
7954 (`!a b. ~(a = vec 0) ==> interior {x | a dot x = b} = {}`,
7955 REWRITE_TAC[REAL_ARITH `x = y <=> x <= y /\ x >= y`] THEN
7956 REWRITE_TAC[SET_RULE `{x | p x /\ q x} = {x | p x} INTER {x | q x}`] THEN
7957 REWRITE_TAC[INTERIOR_INTER] THEN
7958 ASM_SIMP_TAC[INTERIOR_HALFSPACE_LE; INTERIOR_HALFSPACE_GE] THEN
7959 REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM; NOT_IN_EMPTY] THEN
7962 let FRONTIER_HALFSPACE_LE = prove
7963 (`!a:real^N b. ~(a = vec 0 /\ b = &0)
7964 ==> frontier {x | a dot x <= b} = {x | a dot x = b}`,
7965 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN
7966 ASM_SIMP_TAC[DOT_LZERO] THENL
7967 [ASM_CASES_TAC `&0 <= b` THEN
7968 ASM_REWRITE_TAC[UNIV_GSPEC; FRONTIER_UNIV; EMPTY_GSPEC; FRONTIER_EMPTY];
7969 ASM_SIMP_TAC[frontier; INTERIOR_HALFSPACE_LE; CLOSURE_CLOSED;
7970 CLOSED_HALFSPACE_LE] THEN
7971 REWRITE_TAC[EXTENSION; IN_DIFF; IN_ELIM_THM] THEN REAL_ARITH_TAC]);;
7973 let FRONTIER_HALFSPACE_GE = prove
7974 (`!a:real^N b. ~(a = vec 0 /\ b = &0)
7975 ==> frontier {x | a dot x >= b} = {x | a dot x = b}`,
7976 REPEAT STRIP_TAC THEN
7977 MP_TAC(ISPECL [`--a:real^N`; `--b:real`] FRONTIER_HALFSPACE_LE) THEN
7978 ASM_REWRITE_TAC[VECTOR_NEG_EQ_0; REAL_NEG_EQ_0; DOT_LNEG] THEN
7979 REWRITE_TAC[REAL_LE_NEG2; REAL_EQ_NEG2; real_ge]);;
7981 let FRONTIER_HALFSPACE_LT = prove
7982 (`!a:real^N b. ~(a = vec 0 /\ b = &0)
7983 ==> frontier {x | a dot x < b} = {x | a dot x = b}`,
7984 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN
7985 ASM_SIMP_TAC[DOT_LZERO] THENL
7986 [ASM_CASES_TAC `&0 < b` THEN
7987 ASM_REWRITE_TAC[UNIV_GSPEC; FRONTIER_UNIV; EMPTY_GSPEC; FRONTIER_EMPTY];
7988 ASM_SIMP_TAC[frontier; CLOSURE_HALFSPACE_LT; INTERIOR_OPEN;
7989 OPEN_HALFSPACE_LT] THEN
7990 REWRITE_TAC[EXTENSION; IN_DIFF; IN_ELIM_THM] THEN REAL_ARITH_TAC]);;
7992 let FRONTIER_HALFSPACE_GT = prove
7993 (`!a:real^N b. ~(a = vec 0 /\ b = &0)
7994 ==> frontier {x | a dot x > b} = {x | a dot x = b}`,
7995 REPEAT STRIP_TAC THEN
7996 MP_TAC(ISPECL [`--a:real^N`; `--b:real`] FRONTIER_HALFSPACE_LT) THEN
7997 ASM_REWRITE_TAC[VECTOR_NEG_EQ_0; REAL_NEG_EQ_0; DOT_LNEG] THEN
7998 REWRITE_TAC[REAL_LT_NEG2; REAL_EQ_NEG2; real_gt]);;
8000 let INTERIOR_STANDARD_HYPERPLANE = prove
8001 (`!k a. interior {x:real^N | x$k = a} = {}`,
8003 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
8005 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
8006 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] INTERIOR_HYPERPLANE) THEN
8007 ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);;
8009 let EMPTY_INTERIOR_LOWDIM = prove
8010 (`!s:real^N->bool. dim(s) < dimindex(:N) ==> interior s = {}`,
8011 GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP LOWDIM_SUBSET_HYPERPLANE) THEN
8012 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
8013 MATCH_MP_TAC(SET_RULE
8014 `!t u. s SUBSET t /\ t SUBSET u /\ u = {} ==> s = {}`) THEN
8015 MAP_EVERY EXISTS_TAC
8016 [`interior(span(s):real^N->bool)`;
8017 `interior({x:real^N | a dot x = &0})`] THEN
8018 ASM_SIMP_TAC[SUBSET_INTERIOR; SPAN_INC; INTERIOR_HYPERPLANE]);;
8020 (* ------------------------------------------------------------------------- *)
8021 (* Unboundedness of halfspaces. *)
8022 (* ------------------------------------------------------------------------- *)
8024 let UNBOUNDED_HALFSPACE_COMPONENT_LE = prove
8025 (`!a k. ~bounded {x:real^N | x$k <= a}`,
8027 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !z:real^N. z$k = z$i`
8028 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
8029 ASM_REWRITE_TAC[bounded; FORALL_IN_GSPEC] THEN
8030 DISCH_THEN(X_CHOOSE_THEN `B:real` MP_TAC) THEN
8031 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
8032 EXISTS_TAC `--(&1 + max (abs B) (abs a)) % basis i:real^N` THEN
8033 ASM_SIMP_TAC[NORM_MUL; NORM_BASIS; BASIS_COMPONENT;
8034 VECTOR_MUL_COMPONENT] THEN
8037 let UNBOUNDED_HALFSPACE_COMPONENT_GE = prove
8038 (`!a k. ~bounded {x:real^N | x$k >= a}`,
8039 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_NEGATIONS) THEN
8040 MP_TAC(SPECL [`--a:real`; `k:num`] UNBOUNDED_HALFSPACE_COMPONENT_LE) THEN
8041 REWRITE_TAC[CONTRAPOS_THM] THEN MATCH_MP_TAC EQ_IMP THEN
8042 AP_TERM_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN CONJ_TAC THENL
8043 [MESON_TAC[VECTOR_NEG_NEG];
8044 REWRITE_TAC[IN_ELIM_THM; VECTOR_NEG_COMPONENT] THEN REAL_ARITH_TAC]);;
8046 let UNBOUNDED_HALFSPACE_COMPONENT_LT = prove
8047 (`!a k. ~bounded {x:real^N | x$k < a}`,
8048 ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN
8049 REWRITE_TAC[CLOSURE_HALFSPACE_COMPONENT_LT;
8050 UNBOUNDED_HALFSPACE_COMPONENT_LE]);;
8052 let UNBOUNDED_HALFSPACE_COMPONENT_GT = prove
8053 (`!a k. ~bounded {x:real^N | x$k > a}`,
8054 ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN
8055 REWRITE_TAC[CLOSURE_HALFSPACE_COMPONENT_GT;
8056 UNBOUNDED_HALFSPACE_COMPONENT_GE]);;
8058 let BOUNDED_HALFSPACE_LE = prove
8059 (`!a:real^N b. bounded {x | a dot x <= b} <=> a = vec 0 /\ b < &0`,
8060 GEOM_BASIS_MULTIPLE_TAC 1 `a:real^N` THEN
8061 SIMP_TAC[DOT_LMUL; DOT_BASIS; VECTOR_MUL_EQ_0; DIMINDEX_GE_1; LE_REFL;
8063 X_GEN_TAC `a:real` THEN ASM_CASES_TAC `a = &0` THEN ASM_REWRITE_TAC[] THEN
8064 DISCH_TAC THEN X_GEN_TAC `b:real` THENL
8065 [REWRITE_TAC[REAL_MUL_LZERO; DOT_LZERO; GSYM REAL_NOT_LE] THEN
8066 ASM_CASES_TAC `&0 <= b` THEN
8067 ASM_REWRITE_TAC[BOUNDED_EMPTY; NOT_BOUNDED_UNIV;
8068 SET_RULE `{x | T} = UNIV`; EMPTY_GSPEC];
8069 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
8070 ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_LT_LE;
8071 UNBOUNDED_HALFSPACE_COMPONENT_LE]]);;
8073 let BOUNDED_HALFSPACE_GE = prove
8074 (`!a:real^N b. bounded {x | a dot x >= b} <=> a = vec 0 /\ &0 < b`,
8075 REWRITE_TAC[REAL_ARITH `a >= b <=> --a <= --b`] THEN
8076 REWRITE_TAC[GSYM DOT_LNEG; BOUNDED_HALFSPACE_LE] THEN
8077 REWRITE_TAC[VECTOR_NEG_EQ_0; REAL_ARITH `--b < &0 <=> &0 < b`]);;
8079 let BOUNDED_HALFSPACE_LT = prove
8080 (`!a:real^N b. bounded {x | a dot x < b} <=> a = vec 0 /\ b <= &0`,
8081 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN
8082 ASM_REWRITE_TAC[] THENL
8083 [REWRITE_TAC[DOT_LZERO; GSYM REAL_NOT_LE] THEN ASM_CASES_TAC `b <= &0` THEN
8084 ASM_REWRITE_TAC[BOUNDED_EMPTY; NOT_BOUNDED_UNIV;
8085 SET_RULE `{x | T} = UNIV`; EMPTY_GSPEC];
8086 ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN
8087 ASM_SIMP_TAC[CLOSURE_HALFSPACE_LT; BOUNDED_HALFSPACE_LE]]);;
8089 let BOUNDED_HALFSPACE_GT = prove
8090 (`!a:real^N b. bounded {x | a dot x > b} <=> a = vec 0 /\ &0 <= b`,
8091 REWRITE_TAC[REAL_ARITH `a > b <=> --a < --b`] THEN
8092 REWRITE_TAC[GSYM DOT_LNEG; BOUNDED_HALFSPACE_LT] THEN
8093 REWRITE_TAC[VECTOR_NEG_EQ_0; REAL_ARITH `--b <= &0 <=> &0 <= b`]);;
8095 (* ------------------------------------------------------------------------- *)
8096 (* Equality of continuous functions on closure and related results. *)
8097 (* ------------------------------------------------------------------------- *)
8099 let FORALL_IN_CLOSURE = prove
8100 (`!f:real^M->real^N s t.
8101 closed t /\ f continuous_on (closure s) /\
8102 (!x. x IN s ==> f x IN t)
8103 ==> (!x. x IN closure s ==> f x IN t)`,
8104 REWRITE_TAC[SET_RULE `(!x. x IN s ==> f x IN t) <=>
8105 s SUBSET {x | x IN s /\ f x IN t}`] THEN
8106 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN
8107 ASM_REWRITE_TAC[CLOSED_CLOSURE] THEN CONJ_TAC THENL
8108 [MP_TAC(ISPEC `s:real^M->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[];
8109 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN
8110 ASM_REWRITE_TAC[CLOSED_CLOSURE]]);;
8112 let FORALL_IN_CLOSURE_EQ = prove
8114 closed t /\ f continuous_on closure s
8115 ==> ((!x. x IN closure s ==> f x IN t) <=>
8116 (!x. x IN s ==> f x IN t))`,
8117 MESON_TAC[FORALL_IN_CLOSURE; CLOSURE_SUBSET; SUBSET]);;
8119 let SUP_CLOSURE = prove
8120 (`!s. sup(IMAGE drop (closure s)) = sup(IMAGE drop s)`,
8121 GEN_TAC THEN MATCH_MP_TAC SUP_EQ THEN
8122 REWRITE_TAC[FORALL_IN_IMAGE] THEN GEN_TAC THEN
8123 ONCE_REWRITE_TAC[SET_RULE `drop x <= b <=> x IN {x | drop x <= b}`] THEN
8124 MATCH_MP_TAC FORALL_IN_CLOSURE_EQ THEN
8125 REWRITE_TAC[CONTINUOUS_ON_ID; drop; CLOSED_HALFSPACE_COMPONENT_LE]);;
8127 let INF_CLOSURE = prove
8128 (`!s. inf(IMAGE drop (closure s)) = inf(IMAGE drop s)`,
8129 GEN_TAC THEN MATCH_MP_TAC INF_EQ THEN
8130 REWRITE_TAC[FORALL_IN_IMAGE] THEN GEN_TAC THEN
8131 ONCE_REWRITE_TAC[SET_RULE `b <= drop x <=> x IN {x | b <= drop x}`] THEN
8132 MATCH_MP_TAC FORALL_IN_CLOSURE_EQ THEN
8133 REWRITE_TAC[CONTINUOUS_ON_ID; drop; CLOSED_HALFSPACE_COMPONENT_GE;
8136 let CONTINUOUS_LE_ON_CLOSURE = prove
8137 (`!f:real^M->real s a.
8138 (lift o f) continuous_on closure(s) /\ (!x. x IN s ==> f(x) <= a)
8139 ==> !x. x IN closure(s) ==> f(x) <= a`,
8141 (`x IN s ==> f x <= a <=> x IN s ==> (lift o f) x IN {y | y$1 <= a}`,
8142 REWRITE_TAC[IN_ELIM_THM; o_THM; GSYM drop; LIFT_DROP]) in
8143 REWRITE_TAC[lemma] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
8144 MATCH_MP_TAC FORALL_IN_CLOSURE THEN
8145 ASM_REWRITE_TAC[ETA_AX; CLOSED_HALFSPACE_COMPONENT_LE]);;
8147 let CONTINUOUS_GE_ON_CLOSURE = prove
8148 (`!f:real^M->real s a.
8149 (lift o f) continuous_on closure(s) /\ (!x. x IN s ==> a <= f(x))
8150 ==> !x. x IN closure(s) ==> a <= f(x)`,
8152 (`x IN s ==> a <= f x <=> x IN s ==> (lift o f) x IN {y | y$1 >= a}`,
8153 REWRITE_TAC[IN_ELIM_THM; o_THM; GSYM drop; real_ge; LIFT_DROP]) in
8154 REWRITE_TAC[lemma] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
8155 MATCH_MP_TAC FORALL_IN_CLOSURE THEN
8156 ASM_REWRITE_TAC[ETA_AX; CLOSED_HALFSPACE_COMPONENT_GE]);;
8158 let CONTINUOUS_CONSTANT_ON_CLOSURE = prove
8159 (`!f:real^M->real^N s a.
8160 f continuous_on closure(s) /\ (!x. x IN s ==> f(x) = a)
8161 ==> !x. x IN closure(s) ==> f(x) = a`,
8162 REWRITE_TAC[SET_RULE
8163 `x IN s ==> f x = a <=> x IN s ==> f x IN {a}`] THEN
8164 REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC FORALL_IN_CLOSURE THEN
8165 ASM_REWRITE_TAC[CLOSED_SING]);;
8167 let CONTINUOUS_AGREE_ON_CLOSURE = prove
8168 (`!g h:real^M->real^N.
8169 g continuous_on closure s /\ h continuous_on closure s /\
8170 (!x. x IN s ==> g x = h x)
8171 ==> !x. x IN closure s ==> g x = h x`,
8172 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN STRIP_TAC THEN
8173 MATCH_MP_TAC CONTINUOUS_CONSTANT_ON_CLOSURE THEN
8174 ASM_SIMP_TAC[CONTINUOUS_ON_SUB]);;
8176 let CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT = prove
8177 (`!f:real^M->real^N s a.
8179 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x = a}`,
8180 REPEAT STRIP_TAC THEN
8181 ONCE_REWRITE_TAC[SET_RULE
8182 `{x | x IN s /\ f(x) = a} = {x | x IN s /\ f(x) IN {a}}`] THEN
8183 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN
8184 ASM_REWRITE_TAC[CLOSED_SING]);;
8186 let CONTINUOUS_CLOSED_PREIMAGE_CONSTANT = prove
8187 (`!f:real^M->real^N s.
8188 f continuous_on s /\ closed s ==> closed {x | x IN s /\ f(x) = a}`,
8189 REPEAT STRIP_TAC THEN
8190 ASM_CASES_TAC `{x | x IN s /\ (f:real^M->real^N)(x) = a} = {}` THEN
8191 ASM_REWRITE_TAC[CLOSED_EMPTY] THEN ONCE_REWRITE_TAC[SET_RULE
8192 `{x | x IN s /\ f(x) = a} = {x | x IN s /\ f(x) IN {a}}`] THEN
8193 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN
8194 ASM_REWRITE_TAC[CLOSED_SING] THEN ASM SET_TAC[]);;
8196 (* ------------------------------------------------------------------------- *)
8197 (* Theorems relating continuity and uniform continuity to closures. *)
8198 (* ------------------------------------------------------------------------- *)
8200 let CONTINUOUS_ON_CLOSURE = prove
8201 (`!f:real^M->real^N s.
8202 f continuous_on closure s <=>
8203 !x e. x IN closure s /\ &0 < e
8205 !y. y IN s /\ dist(y,x) < d ==> dist(f y,f x) < e`,
8206 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on] THEN
8207 EQ_TAC THENL [MESON_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET]; ALL_TAC] THEN
8208 DISCH_TAC THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
8209 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8210 FIRST_ASSUM(MP_TAC o SPECL [`x:real^M`; `e / &2`]) THEN
8211 ANTS_TAC THENL [ASM_REWRITE_TAC[REAL_HALF]; ALL_TAC] THEN
8212 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
8213 EXISTS_TAC `d / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN
8214 X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN
8215 FIRST_X_ASSUM(MP_TAC o SPECL [`y:real^M`; `e / &2`]) THEN
8216 ASM_REWRITE_TAC[REAL_HALF] THEN
8217 DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
8218 MP_TAC(ISPECL [`y:real^M`; `s:real^M->bool`] CLOSURE_APPROACHABLE) THEN
8219 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `min k (d / &2)`) THEN
8220 ASM_REWRITE_TAC[REAL_HALF; REAL_LT_MIN] THEN
8221 ASM_MESON_TAC[DIST_SYM; NORM_ARITH
8222 `dist(a,b) < e / &2 /\ dist(b,c) < e / &2 ==> dist(a,c) < e`]);;
8224 let CONTINUOUS_ON_CLOSURE_SEQUENTIALLY = prove
8225 (`!f:real^M->real^N s.
8226 f continuous_on closure s <=>
8227 !x a. a IN closure s /\ (!n. x n IN s) /\ (x --> a) sequentially
8228 ==> ((f o x) --> f a) sequentially`,
8229 REWRITE_TAC[CONTINUOUS_ON_CLOSURE] THEN
8230 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
8231 REWRITE_TAC[IMP_IMP; GSYM continuous_within] THEN
8232 REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY] THEN MESON_TAC[]);;
8234 let UNIFORMLY_CONTINUOUS_ON_CLOSURE = prove
8235 (`!f:real^M->real^N s.
8236 f uniformly_continuous_on s /\ f continuous_on closure s
8237 ==> f uniformly_continuous_on closure s`,
8239 REWRITE_TAC[uniformly_continuous_on] THEN STRIP_TAC THEN
8240 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8241 FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN
8242 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
8243 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
8244 EXISTS_TAC `d / &3` THEN CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
8245 MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN
8246 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [continuous_on]) THEN
8247 DISCH_THEN(fun th ->
8248 MP_TAC(SPEC `y:real^M` th) THEN MP_TAC(SPEC `x:real^M` th)) THEN
8249 ASM_REWRITE_TAC[] THEN
8250 DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
8251 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
8252 DISCH_THEN(X_CHOOSE_THEN `d1:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
8253 MP_TAC(ISPECL [`x:real^M`; `s:real^M->bool`] CLOSURE_APPROACHABLE) THEN
8254 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `min d1 (d / &3)`) THEN
8255 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[REAL_LT_MIN]] THEN
8256 DISCH_THEN(X_CHOOSE_THEN `x':real^M` STRIP_ASSUME_TAC) THEN
8257 DISCH_THEN(MP_TAC o SPEC `x':real^M`) THEN
8258 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN DISCH_TAC THEN
8259 DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
8260 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
8261 DISCH_THEN(X_CHOOSE_THEN `d2:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
8262 MP_TAC(ISPECL [`y:real^M`; `s:real^M->bool`] CLOSURE_APPROACHABLE) THEN
8263 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `min d2 (d / &3)`) THEN
8264 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[REAL_LT_MIN]] THEN
8265 DISCH_THEN(X_CHOOSE_THEN `y':real^M` STRIP_ASSUME_TAC) THEN
8266 DISCH_THEN(MP_TAC o SPEC `y':real^M`) THEN
8267 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN DISCH_TAC THEN
8268 FIRST_X_ASSUM(MP_TAC o SPECL [`x':real^M`; `y':real^M`]) THEN
8269 ASM_MESON_TAC[DIST_SYM; NORM_ARITH
8270 `dist(y,x) < d / &3 /\ dist(x',x) < d / &3 /\ dist(y',y) < d / &3
8271 ==> dist(y',x') < d`]);;
8273 (* ------------------------------------------------------------------------- *)
8274 (* Continuity properties for square roots. We get other forms of this *)
8275 (* later (transcendentals.ml and realanalysis.ml) but it's nice to have *)
8276 (* them around earlier. *)
8277 (* ------------------------------------------------------------------------- *)
8279 let CONTINUOUS_AT_SQRT = prove
8280 (`!a s. &0 < drop a ==> (lift o sqrt o drop) continuous (at a)`,
8281 REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_at; o_THM; DIST_LIFT] THEN
8282 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8283 EXISTS_TAC `min (drop a) (e * sqrt(drop a))` THEN
8284 ASM_SIMP_TAC[REAL_LT_MIN; SQRT_POS_LT; REAL_LT_MUL; DIST_REAL] THEN
8285 X_GEN_TAC `b:real^1` THEN REWRITE_TAC[GSYM drop] THEN STRIP_TAC THEN
8286 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_ARITH
8287 `abs(b - a) < a ==> &0 < b`)) THEN
8289 `sqrt(drop b) - sqrt(drop a) =
8290 (drop b - drop a) / (sqrt(drop a) + sqrt(drop b))`
8292 [MATCH_MP_TAC(REAL_FIELD
8293 `sa pow 2 = a /\ sb pow 2 = b /\ &0 < sa /\ &0 < sb
8294 ==> sb - sa = (b - a) / (sa + sb)`) THEN
8295 ASM_SIMP_TAC[SQRT_POS_LT; SQRT_POW_2; REAL_LT_IMP_LE];
8296 ASM_SIMP_TAC[REAL_ABS_DIV; SQRT_POS_LT; REAL_LT_ADD; REAL_LT_LDIV_EQ;
8297 REAL_ARITH `&0 < x ==> abs x = x`] THEN
8298 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
8299 REAL_LTE_TRANS)) THEN
8300 ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LE_ADDR; SQRT_POS_LE;
8303 let CONTINUOUS_WITHIN_LIFT_SQRT = prove
8304 (`!a s. (!x. x IN s ==> &0 <= drop x)
8305 ==> (lift o sqrt o drop) continuous (at a within s)`,
8306 REPEAT STRIP_TAC THEN
8307 REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC
8308 (REAL_ARITH `drop a < &0 \/ drop a = &0 \/ &0 < drop a`)
8310 [MATCH_MP_TAC CONTINUOUS_WITHIN_SUBSET THEN
8311 EXISTS_TAC `{x | &0 <= drop x}` THEN
8312 ASM_SIMP_TAC[SUBSET; IN_ELIM_THM] THEN
8313 MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN
8314 ASM_REWRITE_TAC[IN_ELIM_THM; REAL_NOT_LE] THEN
8315 REWRITE_TAC[drop; REWRITE_RULE[real_ge] CLOSED_HALFSPACE_COMPONENT_GE];
8316 RULE_ASSUM_TAC(REWRITE_RULE[GSYM LIFT_EQ; LIFT_DROP; LIFT_NUM]) THEN
8317 ASM_REWRITE_TAC[continuous_within; o_THM; DROP_VEC; SQRT_0; LIFT_NUM] THEN
8318 REWRITE_TAC[DIST_0; NORM_LIFT; NORM_REAL; GSYM drop] THEN
8319 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8320 EXISTS_TAC `(e:real) pow 2` THEN ASM_SIMP_TAC[REAL_POW_LT] THEN
8321 X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN
8322 ASM_SIMP_TAC[real_abs; SQRT_POS_LE] THEN
8323 SUBGOAL_THEN `e = sqrt(e pow 2)` SUBST1_TAC THENL
8324 [ASM_SIMP_TAC[POW_2_SQRT; REAL_LT_IMP_LE];
8325 MATCH_MP_TAC SQRT_MONO_LT THEN ASM_SIMP_TAC[] THEN ASM_REAL_ARITH_TAC];
8326 MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN
8327 MATCH_MP_TAC CONTINUOUS_AT_SQRT THEN ASM_REWRITE_TAC[]]);;
8329 let CONTINUOUS_WITHIN_SQRT_COMPOSE = prove
8331 (\x. lift(f x)) continuous (at a within s) /\
8332 (&0 < f a \/ !x. x IN s ==> &0 <= f x)
8333 ==> (\x. lift(sqrt(f x))) continuous (at a within s)`,
8336 `(\x:real^N. lift(sqrt(f x))) = (lift o sqrt o drop) o (lift o f)`
8337 SUBST1_TAC THENL [REWRITE_TAC[o_DEF; LIFT_DROP]; ALL_TAC] THEN
8338 REPEAT STRIP_TAC THEN
8339 (MATCH_MP_TAC CONTINUOUS_WITHIN_COMPOSE THEN
8340 CONJ_TAC THENL [ASM_REWRITE_TAC[o_DEF]; ALL_TAC])
8342 [MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN
8343 MATCH_MP_TAC CONTINUOUS_AT_SQRT THEN ASM_REWRITE_TAC[o_DEF; LIFT_DROP];
8344 MATCH_MP_TAC CONTINUOUS_WITHIN_LIFT_SQRT THEN
8345 ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_DEF; LIFT_DROP]]);;
8347 let CONTINUOUS_AT_SQRT_COMPOSE = prove
8349 (\x. lift(f x)) continuous (at a) /\ (&0 < f a \/ !x. &0 <= f x)
8350 ==> (\x. lift(sqrt(f x))) continuous (at a)`,
8352 MP_TAC(ISPECL [`f:real^N->real`; `(:real^N)`; `a:real^N`]
8353 CONTINUOUS_WITHIN_SQRT_COMPOSE) THEN
8354 REWRITE_TAC[WITHIN_UNIV; IN_UNIV]);;
8356 let CONTINUOUS_ON_LIFT_SQRT = prove
8357 (`!s. (!x. x IN s ==> &0 <= drop x)
8358 ==> (lift o sqrt o drop) continuous_on s`,
8359 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_WITHIN_LIFT_SQRT]);;
8361 let CONTINUOUS_ON_LIFT_SQRT_COMPOSE = prove
8362 (`!f:real^N->real s.
8363 (lift o f) continuous_on s /\ (!x. x IN s ==> &0 <= f x)
8364 ==> (\x. lift(sqrt(f x))) continuous_on s`,
8365 REPEAT STRIP_TAC THEN
8367 `(\x:real^N. lift(sqrt(f x))) = (lift o sqrt o drop) o (lift o f)`
8369 [REWRITE_TAC[o_DEF; LIFT_DROP];
8370 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN
8371 MATCH_MP_TAC CONTINUOUS_ON_LIFT_SQRT THEN
8372 ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP]]);;
8374 (* ------------------------------------------------------------------------- *)
8375 (* Cauchy continuity, and the extension of functions to closures. *)
8376 (* ------------------------------------------------------------------------- *)
8378 let UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS = prove
8379 (`!f:real^M->real^N s.
8380 f uniformly_continuous_on s
8381 ==> (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))`,
8382 REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on; cauchy; o_DEF] THEN
8385 let CONTINUOUS_CLOSED_IMP_CAUCHY_CONTINUOUS = prove
8386 (`!f:real^M->real^N s.
8387 f continuous_on s /\ closed s
8388 ==> (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))`,
8389 REWRITE_TAC[GSYM COMPLETE_EQ_CLOSED; CONTINUOUS_ON_SEQUENTIALLY] THEN
8390 REWRITE_TAC[complete] THEN MESON_TAC[CONVERGENT_IMP_CAUCHY]);;
8392 let CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA = prove
8393 (`!f:real^M->real^N s.
8394 (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))
8395 ==> !a x. (!n. (x n) IN s) /\ (x --> a) sequentially
8396 ==> ?l. ((f o x) --> l) sequentially /\
8397 !y. (!n. (y n) IN s) /\ (y --> a) sequentially
8398 ==> ((f o y) --> l) sequentially`,
8399 REPEAT STRIP_TAC THEN
8400 FIRST_ASSUM(MP_TAC o SPEC `x:num->real^M`) THEN
8401 ANTS_TAC THENL [ASM_MESON_TAC[CONVERGENT_IMP_CAUCHY]; ALL_TAC] THEN
8402 REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN MATCH_MP_TAC MONO_EXISTS THEN
8403 X_GEN_TAC `l:real^N` THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
8404 X_GEN_TAC `y:num->real^M` THEN STRIP_TAC THEN
8405 FIRST_ASSUM(MP_TAC o SPEC `y:num->real^M`) THEN
8406 ANTS_TAC THENL [ASM_MESON_TAC[CONVERGENT_IMP_CAUCHY]; ALL_TAC] THEN
8407 REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN
8408 DISCH_THEN(X_CHOOSE_THEN `m:real^N` STRIP_ASSUME_TAC) THEN
8409 SUBGOAL_THEN `l:real^N = m` (fun th -> ASM_REWRITE_TAC[th]) THEN
8410 ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
8411 MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
8412 EXISTS_TAC `\n:num. (f:real^M->real^N)(x n) - f(y n)` THEN
8413 RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN
8414 ASM_SIMP_TAC[LIM_SUB; TRIVIAL_LIMIT_SEQUENTIALLY] THEN
8415 FIRST_X_ASSUM(MP_TAC o SPEC
8416 `\n. if EVEN n then x(n DIV 2):real^M else y(n DIV 2)`) THEN
8417 REWRITE_TAC[cauchy; o_THM; LIM_SEQUENTIALLY] THEN ANTS_TAC THENL
8418 [CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
8419 X_GEN_TAC `e:real` THEN DISCH_TAC THEN MAP_EVERY UNDISCH_TAC
8420 [`((y:num->real^M) --> a) sequentially`;
8421 `((x:num->real^M) --> a) sequentially`] THEN
8422 REPEAT(FIRST_X_ASSUM(K ALL_TAC o check (is_forall o concl))) THEN
8423 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
8424 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
8425 DISCH_THEN(X_CHOOSE_TAC `N1:num`) THEN
8426 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
8427 DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN
8428 EXISTS_TAC `2 * (N1 + N2)` THEN
8429 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN
8430 REPEAT(FIRST_X_ASSUM(fun th ->
8431 MP_TAC(SPEC `m DIV 2` th) THEN MP_TAC(SPEC `n DIV 2` th))) THEN
8432 REPEAT(ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_TAC]) THEN
8433 REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN
8434 REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_NOT_LE])) THEN
8435 CONV_TAC NORM_ARITH;
8436 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
8437 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
8438 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN
8439 X_GEN_TAC `n:num` THEN DISCH_TAC THEN
8440 FIRST_X_ASSUM(MP_TAC o SPECL [`2 * n`; `2 * n + 1`]) THEN
8441 ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
8442 REWRITE_TAC[EVEN_ADD; EVEN_MULT; ARITH_EVEN] THEN
8443 REWRITE_TAC[ARITH_RULE `(2 * n) DIV 2 = n /\ (2 * n + 1) DIV 2 = n`] THEN
8444 REWRITE_TAC[dist; VECTOR_SUB_RZERO]]);;
8446 let CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE = prove
8447 (`!f:real^M->real^N s.
8448 (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))
8449 ==> ?g. g continuous_on closure s /\ (!x. x IN s ==> g x = f x)`,
8450 REPEAT STRIP_TAC THEN
8453 a IN closure s ==> (!n. x n IN s) /\ (x --> a) sequentially`
8454 MP_TAC THENL [MESON_TAC[CLOSURE_SEQUENTIAL]; ALL_TAC] THEN
8455 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
8456 X_GEN_TAC `X:real^M->num->real^M` THEN DISCH_TAC THEN
8457 FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA) THEN
8458 DISCH_THEN(MP_TAC o GEN `a:real^M` o
8459 SPECL [`a:real^M`; `(X:real^M->num->real^M) a`]) THEN
8460 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[]
8461 `(!a. P a ==> Q a) ==> ((!a. P a ==> R a) ==> p)
8462 ==> ((!a. Q a ==> R a) ==> p)`)) THEN
8463 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
8464 REWRITE_TAC[SKOLEM_THM] THEN
8465 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^M->real^N` THEN
8467 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
8468 [X_GEN_TAC `a:real^M` THEN DISCH_TAC THEN
8469 FIRST_X_ASSUM(MP_TAC o SPEC `a:real^M`) THEN
8470 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN
8471 DISCH_THEN(MP_TAC o SPEC `(\n. a):num->real^M` o CONJUNCT2) THEN
8472 ASM_SIMP_TAC[LIM_CONST_EQ; o_DEF; TRIVIAL_LIMIT_SEQUENTIALLY];
8474 ASM_SIMP_TAC[CONTINUOUS_ON_CLOSURE_SEQUENTIALLY] THEN
8475 MAP_EVERY X_GEN_TAC [`x:num->real^M`; `a:real^M`] THEN STRIP_TAC THEN
8476 MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
8477 EXISTS_TAC `(f:real^M->real^N) o (x:num->real^M)` THEN ASM_SIMP_TAC[] THEN
8478 MATCH_MP_TAC ALWAYS_EVENTUALLY THEN ASM_SIMP_TAC[o_THM]);;
8480 let UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE = prove
8481 (`!f:real^M->real^N s.
8482 f uniformly_continuous_on s
8483 ==> ?g. g uniformly_continuous_on closure s /\ (!x. x IN s ==> g x = f x) /\
8484 !h. h continuous_on closure s /\ (!x. x IN s ==> h x = f x)
8485 ==> !x. x IN closure s ==> h x = g x`,
8486 REPEAT STRIP_TAC THEN
8487 FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE o
8488 MATCH_MP UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS) THEN
8489 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^M->real^N` THEN
8490 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
8491 [ASM_MESON_TAC[UNIFORMLY_CONTINUOUS_ON_CLOSURE; UNIFORMLY_CONTINUOUS_ON_EQ];
8492 ASM_MESON_TAC[CONTINUOUS_AGREE_ON_CLOSURE]]);;
8494 let CAUCHY_CONTINUOUS_IMP_CONTINUOUS = prove
8495 (`!f:real^M->real^N s.
8496 (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))
8497 ==> f continuous_on s`,
8498 REPEAT STRIP_TAC THEN
8499 FIRST_ASSUM(CHOOSE_TAC o MATCH_MP CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE) THEN
8500 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; CLOSURE_SUBSET; CONTINUOUS_ON_EQ]);;
8502 let BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE = prove
8503 (`!f:real^M->real^N s.
8504 f uniformly_continuous_on s /\ bounded s ==> bounded(IMAGE f s)`,
8505 REPEAT STRIP_TAC THEN FIRST_ASSUM
8506 (MP_TAC o MATCH_MP UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE) THEN
8507 DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN
8508 MATCH_MP_TAC BOUNDED_SUBSET THEN
8509 EXISTS_TAC `IMAGE (g:real^M->real^N) (closure s)` THEN CONJ_TAC THENL
8510 [ASM_MESON_TAC[COMPACT_CLOSURE; UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS;
8511 COMPACT_IMP_BOUNDED; COMPACT_CONTINUOUS_IMAGE];
8512 MP_TAC(ISPEC `s:real^M->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]]);;
8514 (* ------------------------------------------------------------------------- *)
8515 (* Occasionally useful invariance properties. *)
8516 (* ------------------------------------------------------------------------- *)
8518 let CONTINUOUS_AT_COMPOSE_EQ = prove
8519 (`!f:real^M->real^N g:real^M->real^M h:real^M->real^M.
8520 g continuous at x /\ h continuous at (g x) /\
8521 (!y. g(h y) = y) /\ h(g x) = x
8522 ==> (f continuous at (g x) <=> (\x. f(g x)) continuous at x)`,
8523 REPEAT STRIP_TAC THEN EQ_TAC THEN
8524 ASM_SIMP_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_AT_COMPOSE] THEN
8527 `((f:real^M->real^N) o (g:real^M->real^M) o (h:real^M->real^M))
8528 continuous at (g(x:real^M))`
8530 [REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN
8531 ASM_REWRITE_TAC[o_DEF];
8533 ASM_REWRITE_TAC[o_DEF; ETA_AX]]);;
8535 let CONTINUOUS_AT_TRANSLATION = prove
8536 (`!a z f:real^M->real^N.
8537 f continuous at (a + z) <=> (\x. f(a + x)) continuous at z`,
8538 REPEAT GEN_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE_EQ THEN
8539 EXISTS_TAC `\x:real^M. x - a` THEN
8540 SIMP_TAC[CONTINUOUS_ADD; CONTINUOUS_SUB;
8541 CONTINUOUS_AT_ID; CONTINUOUS_CONST] THEN
8544 add_translation_invariants [CONTINUOUS_AT_TRANSLATION];;
8546 let CONTINUOUS_AT_LINEAR_IMAGE = prove
8547 (`!h:real^M->real^M z f:real^M->real^N.
8548 linear h /\ (!x. norm(h x) = norm x)
8549 ==> (f continuous at (h z) <=> (\x. f(h x)) continuous at z)`,
8550 REPEAT GEN_TAC THEN DISCH_TAC THEN
8551 FIRST_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I
8552 [GSYM ORTHOGONAL_TRANSFORMATION]) THEN
8553 FIRST_ASSUM(X_CHOOSE_TAC `g:real^M->real^M` o MATCH_MP
8554 ORTHOGONAL_TRANSFORMATION_INVERSE) THEN
8555 MATCH_MP_TAC CONTINUOUS_AT_COMPOSE_EQ THEN
8556 EXISTS_TAC `g:real^M->real^M` THEN
8557 RULE_ASSUM_TAC(REWRITE_RULE[ORTHOGONAL_TRANSFORMATION]) THEN
8558 ASM_SIMP_TAC[LINEAR_CONTINUOUS_AT]);;
8560 add_linear_invariants [CONTINUOUS_AT_LINEAR_IMAGE];;
8562 (* ------------------------------------------------------------------------- *)
8563 (* Interior of an injective image. *)
8564 (* ------------------------------------------------------------------------- *)
8566 let INTERIOR_IMAGE_SUBSET = prove
8567 (`!f:real^M->real^N s.
8568 (!x. f continuous at x) /\ (!x y. f x = f y ==> x = y)
8569 ==> interior(IMAGE f s) SUBSET IMAGE f (interior s)`,
8570 REPEAT STRIP_TAC THEN REWRITE_TAC[SUBSET] THEN
8571 REWRITE_TAC[interior; IN_ELIM_THM] THEN
8572 X_GEN_TAC `y:real^N` THEN
8573 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
8574 REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN
8575 SUBGOAL_THEN `y IN IMAGE (f:real^M->real^N) s` MP_TAC THENL
8576 [ASM SET_TAC[]; ALL_TAC] THEN
8577 REWRITE_TAC[IN_IMAGE] THEN
8578 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN
8579 ASM_REWRITE_TAC[IN_ELIM_THM] THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN
8580 EXISTS_TAC `{x | (f:real^M->real^N)(x) IN t}` THEN
8581 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN CONJ_TAC THENL
8582 [MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE_UNIV THEN ASM_MESON_TAC[];
8585 (* ------------------------------------------------------------------------- *)
8586 (* Making a continuous function avoid some value in a neighbourhood. *)
8587 (* ------------------------------------------------------------------------- *)
8589 let CONTINUOUS_WITHIN_AVOID = prove
8590 (`!f:real^M->real^N x s a.
8591 f continuous (at x within s) /\ x IN s /\ ~(f x = a)
8592 ==> ?e. &0 < e /\ !y. y IN s /\ dist(x,y) < e ==> ~(f y = a)`,
8593 REPEAT STRIP_TAC THEN
8594 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [continuous_within]) THEN
8595 DISCH_THEN(MP_TAC o SPEC `norm((f:real^M->real^N) x - a)`) THEN
8596 ASM_REWRITE_TAC[NORM_POS_LT; VECTOR_SUB_EQ] THEN
8597 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN MATCH_MP_TAC MONO_AND THEN
8598 REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN
8599 GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN SIMP_TAC[] THEN NORM_ARITH_TAC);;
8601 let CONTINUOUS_AT_AVOID = prove
8602 (`!f:real^M->real^N x a.
8603 f continuous (at x) /\ ~(f x = a)
8604 ==> ?e. &0 < e /\ !y. dist(x,y) < e ==> ~(f y = a)`,
8605 MP_TAC CONTINUOUS_WITHIN_AVOID THEN
8606 REPLICATE_TAC 2 (MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
8607 DISCH_THEN(MP_TAC o SPEC `(:real^M)`) THEN
8608 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
8609 REWRITE_TAC[WITHIN_UNIV; IN_UNIV]);;
8611 let CONTINUOUS_ON_AVOID = prove
8612 (`!f:real^M->real^N x s a.
8613 f continuous_on s /\ x IN s /\ ~(f x = a)
8614 ==> ?e. &0 < e /\ !y. y IN s /\ dist(x,y) < e ==> ~(f y = a)`,
8615 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
8616 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_WITHIN_AVOID THEN
8619 let CONTINUOUS_ON_OPEN_AVOID = prove
8620 (`!f:real^M->real^N x s a.
8621 f continuous_on s /\ open s /\ x IN s /\ ~(f x = a)
8622 ==> ?e. &0 < e /\ !y. dist(x,y) < e ==> ~(f y = a)`,
8623 REPEAT GEN_TAC THEN ASM_CASES_TAC `open(s:real^M->bool)` THEN
8624 ASM_SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT] THEN
8625 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_AVOID THEN
8628 (* ------------------------------------------------------------------------- *)
8629 (* Proving a function is constant by proving open-ness of level set. *)
8630 (* ------------------------------------------------------------------------- *)
8632 let CONTINUOUS_LEVELSET_OPEN_IN_CASES = prove
8633 (`!f:real^M->real^N s a.
8635 f continuous_on s /\
8636 open_in (subtopology euclidean s) {x | x IN s /\ f x = a}
8637 ==> (!x. x IN s ==> ~(f x = a)) \/ (!x. x IN s ==> f x = a)`,
8638 REWRITE_TAC[SET_RULE `(!x. x IN s ==> ~(f x = a)) <=>
8639 {x | x IN s /\ f x = a} = {}`;
8640 SET_RULE `(!x. x IN s ==> f x = a) <=>
8641 {x | x IN s /\ f x = a} = s`] THEN
8642 REWRITE_TAC[CONNECTED_CLOPEN] THEN REPEAT STRIP_TAC THEN
8643 FIRST_X_ASSUM MATCH_MP_TAC THEN
8644 ASM_SIMP_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT]);;
8646 let CONTINUOUS_LEVELSET_OPEN_IN = prove
8647 (`!f:real^M->real^N s a.
8649 f continuous_on s /\
8650 open_in (subtopology euclidean s) {x | x IN s /\ f x = a} /\
8651 (?x. x IN s /\ f x = a)
8652 ==> (!x. x IN s ==> f x = a)`,
8653 MESON_TAC[CONTINUOUS_LEVELSET_OPEN_IN_CASES]);;
8655 let CONTINUOUS_LEVELSET_OPEN = prove
8656 (`!f:real^M->real^N s a.
8658 f continuous_on s /\
8659 open {x | x IN s /\ f x = a} /\
8660 (?x. x IN s /\ f x = a)
8661 ==> (!x. x IN s ==> f x = a)`,
8662 REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
8663 MATCH_MP_TAC CONTINUOUS_LEVELSET_OPEN_IN THEN
8664 ASM_REWRITE_TAC[OPEN_IN_OPEN] THEN
8665 EXISTS_TAC `{x | x IN s /\ (f:real^M->real^N) x = a}` THEN
8666 ASM_REWRITE_TAC[] THEN SET_TAC[]);;
8668 (* ------------------------------------------------------------------------- *)
8669 (* Some arithmetical combinations (more to prove). *)
8670 (* ------------------------------------------------------------------------- *)
8672 let OPEN_SCALING = prove
8673 (`!s:real^N->bool c. ~(c = &0) /\ open s ==> open(IMAGE (\x. c % x) s)`,
8674 REPEAT GEN_TAC THEN REWRITE_TAC[open_def; FORALL_IN_IMAGE] THEN
8675 STRIP_TAC THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
8676 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
8677 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
8678 EXISTS_TAC `e * abs(c)` THEN ASM_SIMP_TAC[REAL_LT_MUL; GSYM REAL_ABS_NZ] THEN
8679 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_IMAGE] THEN
8680 EXISTS_TAC `inv(c) % y:real^N` THEN
8681 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; VECTOR_MUL_LID] THEN
8682 FIRST_X_ASSUM MATCH_MP_TAC THEN
8683 SUBGOAL_THEN `x = inv(c) % c % x:real^N` SUBST1_TAC THENL
8684 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID];
8685 REWRITE_TAC[dist; GSYM VECTOR_SUB_LDISTRIB; NORM_MUL] THEN
8686 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[REAL_ABS_INV] THEN
8687 ASM_SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ; GSYM REAL_ABS_NZ] THEN
8688 ASM_REWRITE_TAC[GSYM dist]]);;
8690 let OPEN_NEGATIONS = prove
8691 (`!s:real^N->bool. open s ==> open (IMAGE (--) s)`,
8692 SUBGOAL_THEN `(--) = \x:real^N. --(&1) % x`
8693 (fun th -> SIMP_TAC[th; OPEN_SCALING; REAL_ARITH `~(--(&1) = &0)`]) THEN
8694 REWRITE_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC);;
8696 let OPEN_TRANSLATION = prove
8697 (`!s a:real^N. open s ==> open(IMAGE (\x. a + x) s)`,
8698 REPEAT STRIP_TAC THEN
8699 MP_TAC(ISPECL [`\x:real^N. x - a`; `s:real^N->bool`]
8700 CONTINUOUS_OPEN_PREIMAGE_UNIV) THEN
8701 ASM_SIMP_TAC[CONTINUOUS_SUB; CONTINUOUS_AT_ID; CONTINUOUS_CONST] THEN
8702 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
8703 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; IN_UNIV] THEN
8704 ASM_MESON_TAC[VECTOR_ARITH `(a + x) - a = x:real^N`;
8705 VECTOR_ARITH `a + (x - a) = x:real^N`]);;
8707 let OPEN_TRANSLATION_EQ = prove
8708 (`!a s. open (IMAGE (\x:real^N. a + x) s) <=> open s`,
8709 REWRITE_TAC[open_def] THEN GEOM_TRANSLATE_TAC[]);;
8711 add_translation_invariants [OPEN_TRANSLATION_EQ];;
8713 let OPEN_AFFINITY = prove
8715 open s /\ ~(c = &0) ==> open (IMAGE (\x. a + c % x) s)`,
8716 REPEAT STRIP_TAC THEN
8717 SUBGOAL_THEN `(\x:real^N. a + c % x) = (\x. a + x) o (\x. c % x)`
8718 SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
8719 ASM_SIMP_TAC[IMAGE_o; OPEN_TRANSLATION; OPEN_SCALING]);;
8721 let INTERIOR_TRANSLATION = prove
8723 interior (IMAGE (\x. a + x) s) = IMAGE (\x. a + x) (interior s)`,
8724 REWRITE_TAC[interior] THEN GEOM_TRANSLATE_TAC[]);;
8726 add_translation_invariants [INTERIOR_TRANSLATION];;
8728 let OPEN_SUMS = prove
8729 (`!s t:real^N->bool.
8730 open s \/ open t ==> open {x + y | x IN s /\ y IN t}`,
8731 REPEAT GEN_TAC THEN REWRITE_TAC[open_def] THEN STRIP_TAC THEN
8732 REWRITE_TAC[FORALL_IN_GSPEC] THEN
8733 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THENL
8734 [FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`);
8735 FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`)] THEN
8736 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN
8737 X_GEN_TAC `e:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
8738 X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
8739 ASM_MESON_TAC[VECTOR_ADD_SYM; VECTOR_ARITH `(z - y) + y:real^N = z`;
8740 NORM_ARITH `dist(z:real^N,x + y) < e ==> dist(z - y,x) < e`]);;
8742 (* ------------------------------------------------------------------------- *)
8743 (* Upper and lower hemicontinuous functions, relation in the case of *)
8744 (* preimage map to open and closed maps, and fact that upper and lower *)
8745 (* hemicontinuity together imply continuity in the sense of the Hausdorff *)
8746 (* metric (at points where the function gives a bounded and nonempty set). *)
8747 (* ------------------------------------------------------------------------- *)
8749 let UPPER_HEMICONTINUOUS = prove
8750 (`!f:real^M->real^N->bool t s.
8751 (!x. x IN s ==> f(x) SUBSET t)
8752 ==> ((!u. open_in (subtopology euclidean t) u
8753 ==> open_in (subtopology euclidean s)
8754 {x | x IN s /\ f(x) SUBSET u}) <=>
8755 (!u. closed_in (subtopology euclidean t) u
8756 ==> closed_in (subtopology euclidean s)
8757 {x | x IN s /\ ~(f(x) INTER u = {})}))`,
8758 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN
8759 FIRST_X_ASSUM(MP_TAC o SPEC `t DIFF u:real^N->bool`) THEN
8760 MATCH_MP_TAC MONO_IMP THEN
8761 SIMP_TAC[OPEN_IN_DIFF; CLOSED_IN_DIFF; OPEN_IN_REFL; CLOSED_IN_REFL] THENL
8762 [REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ]; REWRITE_TAC[closed_in]] THEN
8763 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY; SUBSET_RESTRICT] THEN
8764 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]);;
8766 let LOWER_HEMICONTINUOUS = prove
8767 (`!f:real^M->real^N->bool t s.
8768 (!x. x IN s ==> f(x) SUBSET t)
8769 ==> ((!u. closed_in (subtopology euclidean t) u
8770 ==> closed_in (subtopology euclidean s)
8771 {x | x IN s /\ f(x) SUBSET u}) <=>
8772 (!u. open_in (subtopology euclidean t) u
8773 ==> open_in (subtopology euclidean s)
8774 {x | x IN s /\ ~(f(x) INTER u = {})}))`,
8775 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN GEN_TAC THEN
8776 FIRST_X_ASSUM(MP_TAC o SPEC `t DIFF u:real^N->bool`) THEN
8777 MATCH_MP_TAC MONO_IMP THEN
8778 SIMP_TAC[OPEN_IN_DIFF; CLOSED_IN_DIFF; OPEN_IN_REFL; CLOSED_IN_REFL] THENL
8779 [REWRITE_TAC[closed_in]; REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ]] THEN
8780 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY; SUBSET_RESTRICT] THEN
8781 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]);;
8783 let OPEN_MAP_IFF_LOWER_HEMICONTINUOUS_PREIMAGE = prove
8784 (`!f:real^M->real^N s t.
8786 ==> ((!u. open_in (subtopology euclidean s) u
8787 ==> open_in (subtopology euclidean t) (IMAGE f u)) <=>
8788 (!u. closed_in (subtopology euclidean s) u
8789 ==> closed_in (subtopology euclidean t)
8791 {x | x IN s /\ f x = y} SUBSET u}))`,
8792 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
8793 [X_GEN_TAC `v:real^M->bool` THEN DISCH_TAC THEN
8794 FIRST_X_ASSUM(MP_TAC o SPEC `s DIFF v:real^M->bool`) THEN
8795 ASM_SIMP_TAC[OPEN_IN_DIFF; OPEN_IN_REFL] THEN
8796 REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
8797 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
8798 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
8799 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[];
8800 X_GEN_TAC `v:real^M->bool` THEN DISCH_TAC THEN
8801 FIRST_X_ASSUM(MP_TAC o SPEC `s DIFF v:real^M->bool`) THEN
8802 ASM_SIMP_TAC[CLOSED_IN_DIFF; CLOSED_IN_REFL] THEN
8803 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
8804 REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
8805 DISCH_THEN(fun th -> CONJ_TAC THENL [ASM SET_TAC[]; MP_TAC th]) THEN
8806 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]]);;
8808 let CLOSED_MAP_IFF_UPPER_HEMICONTINUOUS_PREIMAGE = prove
8809 (`!f:real^M->real^N s t.
8811 ==> ((!u. closed_in (subtopology euclidean s) u
8812 ==> closed_in (subtopology euclidean t) (IMAGE f u)) <=>
8813 (!u. open_in (subtopology euclidean s) u
8814 ==> open_in (subtopology euclidean t)
8816 {x | x IN s /\ f x = y} SUBSET u}))`,
8817 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
8818 [X_GEN_TAC `v:real^M->bool` THEN DISCH_TAC THEN
8819 FIRST_X_ASSUM(MP_TAC o SPEC `s DIFF v:real^M->bool`) THEN
8820 ASM_SIMP_TAC[CLOSED_IN_DIFF; CLOSED_IN_REFL] THEN
8821 REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
8822 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
8823 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
8824 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[];
8825 X_GEN_TAC `v:real^M->bool` THEN DISCH_TAC THEN
8826 FIRST_X_ASSUM(MP_TAC o SPEC `s DIFF v:real^M->bool`) THEN
8827 ASM_SIMP_TAC[OPEN_IN_DIFF; OPEN_IN_REFL] THEN
8828 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
8829 REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
8830 DISCH_THEN(fun th -> CONJ_TAC THENL [ASM SET_TAC[]; MP_TAC th]) THEN
8831 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]]);;
8833 let UPPER_LOWER_HEMICONTINUOUS_EXPLICIT = prove
8834 (`!f:real^M->real^N->bool t s.
8835 (!x. x IN s ==> f(x) SUBSET t) /\
8836 (!u. open_in (subtopology euclidean t) u
8837 ==> open_in (subtopology euclidean s)
8838 {x | x IN s /\ f(x) SUBSET u}) /\
8839 (!u. closed_in (subtopology euclidean t) u
8840 ==> closed_in (subtopology euclidean s)
8841 {x | x IN s /\ f(x) SUBSET u})
8842 ==> !x e. x IN s /\ &0 < e /\ bounded(f x) /\ ~(f x = {})
8844 !x'. x' IN s /\ dist(x,x') < d
8846 ==> ?y'. y' IN f x' /\ dist(y,y') < e) /\
8848 ==> ?y. y IN f x /\ dist(y',y) < e)`,
8849 REPEAT STRIP_TAC THEN
8851 `!u. open_in (subtopology euclidean t) u
8852 ==> open_in (subtopology euclidean s)
8853 {x | x IN s /\ (f:real^M->real^N->bool)(x) SUBSET u}` THEN
8854 DISCH_THEN(MP_TAC o SPEC
8856 {a + b | a IN (f:real^M->real^N->bool) x /\ b IN ball(vec 0,e)}`) THEN
8857 SIMP_TAC[OPEN_SUMS; OPEN_BALL; OPEN_IN_OPEN_INTER] THEN
8858 REWRITE_TAC[open_in; SUBSET_RESTRICT] THEN
8859 DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN
8860 ASM_SIMP_TAC[IN_ELIM_THM; SUBSET_INTER] THEN ANTS_TAC THENL
8861 [REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
8862 ASM_MESON_TAC[CENTRE_IN_BALL; VECTOR_ADD_RID];
8863 DISCH_THEN(X_CHOOSE_THEN `d1:real`
8864 (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "1")))] THEN
8866 `!u. closed_in (subtopology euclidean t) u
8867 ==> closed_in (subtopology euclidean s)
8868 {x | x IN s /\ (f:real^M->real^N->bool)(x) SUBSET u}` THEN
8869 ASM_SIMP_TAC[LOWER_HEMICONTINUOUS] THEN DISCH_THEN(MP_TAC o
8870 GEN `a:real^N` o SPEC `t INTER ball(a:real^N,e / &2)`) THEN
8871 SIMP_TAC[OPEN_BALL; OPEN_IN_OPEN_INTER] THEN
8873 MP_TAC(SPEC `closure((f:real^M->real^N->bool) x)`
8874 COMPACT_EQ_HEINE_BOREL) THEN
8875 ASM_REWRITE_TAC[COMPACT_CLOSURE] THEN DISCH_THEN(MP_TAC o SPEC
8876 `{ball(a:real^N,e / &2) | a IN (f:real^M->real^N->bool) x}`) THEN
8877 REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; OPEN_BALL] THEN
8878 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
8879 REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE] THEN ANTS_TAC THENL
8880 [REWRITE_TAC[CLOSURE_APPROACHABLE; SUBSET; UNIONS_IMAGE; IN_ELIM_THM] THEN
8881 REWRITE_TAC[IN_BALL] THEN ASM_SIMP_TAC[REAL_HALF];
8883 DISCH_THEN(X_CHOOSE_THEN `c:real^N->bool` STRIP_ASSUME_TAC) THEN
8884 DISCH_TAC THEN FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP
8885 (MESON[CLOSURE_SUBSET; SUBSET_TRANS]
8886 `closure s SUBSET t ==> s SUBSET t`)) THEN
8888 `open_in (subtopology euclidean s)
8889 (INTERS {{x | x IN s /\
8890 ~((f:real^M->real^N->bool) x INTER t INTER ball(a,e / &2) = {})} |
8893 [MATCH_MP_TAC OPEN_IN_INTERS THEN
8894 ASM_SIMP_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; FINITE_IMAGE] THEN
8895 ASM_REWRITE_TAC[IMAGE_EQ_EMPTY] THEN ASM SET_TAC[];
8897 REWRITE_TAC[open_in] THEN
8898 DISCH_THEN(MP_TAC o SPEC `x:real^M` o CONJUNCT2) THEN ANTS_TAC THENL
8899 [REWRITE_TAC[INTERS_GSPEC; IN_ELIM_THM] THEN
8900 X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN
8901 ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
8902 EXISTS_TAC `a:real^N` THEN
8903 ASM_REWRITE_TAC[IN_INTER; CENTRE_IN_BALL; REAL_HALF] THEN
8905 DISCH_THEN(X_CHOOSE_THEN `d2:real`
8906 (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "2")))] THEN
8907 EXISTS_TAC `min d1 d2:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
8908 X_GEN_TAC `x':real^M` THEN STRIP_TAC THEN CONJ_TAC THENL
8910 REMOVE_THEN "1" (MP_TAC o SPEC `x':real^M`) THEN
8911 ASM_REWRITE_TAC[] THEN
8912 ANTS_TAC THENL [ASM_MESON_TAC[DIST_SYM]; ALL_TAC] THEN
8913 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_BALL] THEN
8914 REWRITE_TAC[VECTOR_ARITH `x:real^N = a + b <=> x - a = b`;
8915 DIST_0; ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN
8916 REWRITE_TAC[dist]] THEN
8917 REMOVE_THEN "2" (MP_TAC o SPEC `x':real^M`) THEN
8918 ASM_REWRITE_TAC[INTERS_GSPEC; IN_ELIM_THM] THEN
8919 ANTS_TAC THENL [ASM_MESON_TAC[DIST_SYM]; ALL_TAC] THEN
8920 DISCH_THEN(LABEL_TAC "3") THEN
8921 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
8922 UNDISCH_TAC `(f:real^M->real^N->bool) x SUBSET
8923 UNIONS (IMAGE (\a. ball (a,e / &2)) c)` THEN
8924 REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `y:real^N`) THEN
8925 ASM_REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM; IN_BALL] THEN
8926 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
8927 REMOVE_THEN "3" (MP_TAC o SPEC `a:real^N`) THEN
8928 ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER; IN_BALL] THEN
8929 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:real^N` THEN
8930 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
8931 ASM_MESON_TAC[DIST_TRIANGLE_HALF_L; DIST_SYM]);;
8933 (* ------------------------------------------------------------------------- *)
8934 (* Connected components, considered as a "connectedness" relation or a set. *)
8935 (* ------------------------------------------------------------------------- *)
8937 let connected_component = new_definition
8938 `connected_component s x y <=>
8939 ?t. connected t /\ t SUBSET s /\ x IN t /\ y IN t`;;
8941 let CONNECTED_COMPONENT_IN = prove
8942 (`!s x y. connected_component s x y ==> x IN s /\ y IN s`,
8943 REWRITE_TAC[connected_component] THEN SET_TAC[]);;
8945 let CONNECTED_COMPONENT_REFL = prove
8946 (`!s x:real^N. x IN s ==> connected_component s x x`,
8947 REWRITE_TAC[connected_component] THEN REPEAT STRIP_TAC THEN
8948 EXISTS_TAC `{x:real^N}` THEN REWRITE_TAC[CONNECTED_SING] THEN
8951 let CONNECTED_COMPONENT_REFL_EQ = prove
8952 (`!s x:real^N. connected_component s x x <=> x IN s`,
8953 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[CONNECTED_COMPONENT_REFL] THEN
8954 REWRITE_TAC[connected_component] THEN SET_TAC[]);;
8956 let CONNECTED_COMPONENT_SYM = prove
8957 (`!s x y:real^N. connected_component s x y ==> connected_component s y x`,
8958 REWRITE_TAC[connected_component] THEN MESON_TAC[]);;
8960 let CONNECTED_COMPONENT_TRANS = prove
8962 connected_component s x y /\ connected_component s y z
8963 ==> connected_component s x z`,
8964 REPEAT GEN_TAC THEN REWRITE_TAC[connected_component] THEN
8965 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `t:real^N->bool`)
8966 (X_CHOOSE_TAC `u:real^N->bool`)) THEN
8967 EXISTS_TAC `t UNION u:real^N->bool` THEN
8968 ASM_REWRITE_TAC[IN_UNION; UNION_SUBSET] THEN
8969 MATCH_MP_TAC CONNECTED_UNION THEN ASM SET_TAC[]);;
8971 let CONNECTED_COMPONENT_OF_SUBSET = prove
8972 (`!s t x. s SUBSET t /\ connected_component s x y
8973 ==> connected_component t x y`,
8974 REWRITE_TAC[connected_component] THEN SET_TAC[]);;
8976 let CONNECTED_COMPONENT_SET = prove
8977 (`!s x. connected_component s x =
8978 { y | ?t. connected t /\ t SUBSET s /\ x IN t /\ y IN t}`,
8979 REWRITE_TAC[IN_ELIM_THM; EXTENSION] THEN
8980 REWRITE_TAC[IN; connected_component] THEN MESON_TAC[]);;
8982 let CONNECTED_COMPONENT_UNIONS = prove
8983 (`!s x. connected_component s x =
8984 UNIONS {t | connected t /\ x IN t /\ t SUBSET s}`,
8985 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);;
8987 let CONNECTED_COMPONENT_SUBSET = prove
8988 (`!s x. (connected_component s x) SUBSET s`,
8989 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);;
8991 let CONNECTED_CONNECTED_COMPONENT_SET = prove
8992 (`!s. connected s <=> !x:real^N. x IN s ==> connected_component s x = s`,
8993 GEN_TAC THEN REWRITE_TAC[CONNECTED_COMPONENT_UNIONS] THEN EQ_TAC THENL
8994 [SET_TAC[]; ALL_TAC] THEN
8995 ASM_CASES_TAC `s:real^N->bool = {}` THEN
8996 ASM_REWRITE_TAC[CONNECTED_EMPTY] THEN
8997 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
8998 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
8999 DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN ASM_REWRITE_TAC[] THEN
9000 DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC CONNECTED_UNIONS THEN
9003 let CONNECTED_COMPONENT_EQ_SELF = prove
9004 (`!s x. connected s /\ x IN s ==> connected_component s x = s`,
9005 MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET]);;
9007 let CONNECTED_IFF_CONNECTED_COMPONENT = prove
9008 (`!s. connected s <=>
9009 !x y. x IN s /\ y IN s ==> connected_component s x y`,
9010 REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT_SET] THEN
9011 REWRITE_TAC[EXTENSION] THEN MESON_TAC[IN; CONNECTED_COMPONENT_IN]);;
9013 let CONNECTED_COMPONENT_MAXIMAL = prove
9015 x IN t /\ connected t /\ t SUBSET s
9016 ==> t SUBSET (connected_component s x)`,
9017 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);;
9019 let CONNECTED_COMPONENT_MONO = prove
9020 (`!s t x. s SUBSET t
9021 ==> (connected_component s x) SUBSET (connected_component t x)`,
9022 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);;
9024 let CONNECTED_CONNECTED_COMPONENT = prove
9025 (`!s x. connected(connected_component s x)`,
9026 REWRITE_TAC[CONNECTED_COMPONENT_UNIONS] THEN
9027 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_UNIONS THEN SET_TAC[]);;
9029 let CONNECTED_COMPONENT_EQ_EMPTY = prove
9030 (`!s x:real^N. connected_component s x = {} <=> ~(x IN s)`,
9031 REPEAT GEN_TAC THEN EQ_TAC THENL
9032 [REWRITE_TAC[EXTENSION; NOT_IN_EMPTY] THEN
9033 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
9034 REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ];
9035 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]]);;
9037 let CONNECTED_COMPONENT_EMPTY = prove
9038 (`!x. connected_component {} x = {}`,
9039 REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY; NOT_IN_EMPTY]);;
9041 let CONNECTED_COMPONENT_EQ = prove
9042 (`!s x y. y IN connected_component s x
9043 ==> (connected_component s y = connected_component s x)`,
9044 REWRITE_TAC[EXTENSION; IN] THEN
9045 MESON_TAC[CONNECTED_COMPONENT_SYM; CONNECTED_COMPONENT_TRANS]);;
9047 let CLOSED_CONNECTED_COMPONENT = prove
9048 (`!s x:real^N. closed s ==> closed(connected_component s x)`,
9049 REPEAT STRIP_TAC THEN
9050 ASM_CASES_TAC `(x:real^N) IN s` THENL
9051 [ALL_TAC; ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY; CLOSED_EMPTY]] THEN
9052 REWRITE_TAC[GSYM CLOSURE_EQ] THEN
9053 MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[CLOSURE_SUBSET] THEN
9054 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
9055 SIMP_TAC[CONNECTED_CLOSURE; CONNECTED_CONNECTED_COMPONENT] THEN
9057 [MATCH_MP_TAC(REWRITE_RULE[SUBSET] CLOSURE_SUBSET) THEN
9058 ASM_REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ];
9059 MATCH_MP_TAC CLOSURE_MINIMAL THEN
9060 ASM_REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]]);;
9062 let CONNECTED_COMPONENT_DISJOINT = prove
9063 (`!s a b. DISJOINT (connected_component s a) (connected_component s b) <=>
9064 ~(a IN connected_component s b)`,
9065 REWRITE_TAC[DISJOINT; EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN
9066 REWRITE_TAC[IN] THEN
9067 MESON_TAC[CONNECTED_COMPONENT_SYM; CONNECTED_COMPONENT_TRANS]);;
9069 let CONNECTED_COMPONENT_NONOVERLAP = prove
9071 (connected_component s a) INTER (connected_component s b) = {} <=>
9072 ~(a IN s) \/ ~(b IN s) \/
9073 ~(connected_component s a = connected_component s b)`,
9075 ASM_CASES_TAC `(a:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN
9076 RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN
9077 ASM_REWRITE_TAC[INTER_EMPTY] THEN
9078 ASM_CASES_TAC `(b:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN
9079 RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN
9080 ASM_REWRITE_TAC[INTER_EMPTY] THEN ASM_CASES_TAC
9081 `connected_component s (a:real^N) = connected_component s b` THEN
9082 ASM_REWRITE_TAC[INTER_IDEMPOT; CONNECTED_COMPONENT_EQ_EMPTY] THEN
9083 FIRST_X_ASSUM(MP_TAC o check(is_neg o concl)) THEN
9084 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
9085 REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN
9086 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [GSYM DISJOINT]) THEN
9087 REWRITE_TAC[CONNECTED_COMPONENT_DISJOINT]);;
9089 let CONNECTED_COMPONENT_OVERLAP = prove
9091 ~((connected_component s a) INTER (connected_component s b) = {}) <=>
9093 connected_component s a = connected_component s b`,
9094 REWRITE_TAC[CONNECTED_COMPONENT_NONOVERLAP; DE_MORGAN_THM]);;
9096 let CONNECTED_COMPONENT_SYM_EQ = prove
9097 (`!s x y. connected_component s x y <=> connected_component s y x`,
9098 MESON_TAC[CONNECTED_COMPONENT_SYM]);;
9100 let CONNECTED_COMPONENT_EQ_EQ = prove
9102 connected_component s x = connected_component s y <=>
9103 ~(x IN s) /\ ~(y IN s) \/
9104 x IN s /\ y IN s /\ connected_component s x y`,
9105 REPEAT GEN_TAC THEN ASM_CASES_TAC `(y:real^N) IN s` THENL
9106 [ASM_CASES_TAC `(x:real^N) IN s` THEN ASM_REWRITE_TAC[] THENL
9107 [REWRITE_TAC[FUN_EQ_THM] THEN
9108 ASM_MESON_TAC[CONNECTED_COMPONENT_TRANS; CONNECTED_COMPONENT_REFL;
9109 CONNECTED_COMPONENT_SYM];
9110 ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]];
9111 RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN
9112 ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY] THEN
9113 ONCE_REWRITE_TAC[CONNECTED_COMPONENT_SYM_EQ] THEN
9114 ASM_REWRITE_TAC[EMPTY] THEN ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]]);;
9116 let CONNECTED_EQ_CONNECTED_COMPONENT_EQ = prove
9117 (`!s. connected s <=>
9118 !x y. x IN s /\ y IN s
9119 ==> connected_component s x = connected_component s y`,
9120 SIMP_TAC[CONNECTED_COMPONENT_EQ_EQ] THEN
9121 REWRITE_TAC[CONNECTED_IFF_CONNECTED_COMPONENT]);;
9123 let CONNECTED_COMPONENT_IDEMP = prove
9124 (`!s x:real^N. connected_component (connected_component s x) x =
9125 connected_component s x`,
9126 REWRITE_TAC[FUN_EQ_THM; connected_component] THEN
9127 REPEAT GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN EQ_TAC THEN
9128 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9129 ASM_MESON_TAC[CONNECTED_COMPONENT_MAXIMAL; SUBSET_TRANS;
9130 CONNECTED_COMPONENT_SUBSET]);;
9132 let CONNECTED_COMPONENT_UNIQUE = prove
9134 x IN c /\ c SUBSET s /\ connected c /\
9135 (!c'. x IN c' /\ c' SUBSET s /\ connected c'
9137 ==> connected_component s x = c`,
9138 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
9139 [FIRST_X_ASSUM MATCH_MP_TAC THEN
9140 REWRITE_TAC[CONNECTED_COMPONENT_SUBSET; CONNECTED_CONNECTED_COMPONENT] THEN
9141 REWRITE_TAC[IN] THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN
9143 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN ASM_REWRITE_TAC[]]);;
9145 let JOINABLE_CONNECTED_COMPONENT_EQ = prove
9147 connected t /\ t SUBSET s /\
9148 ~(connected_component s x INTER t = {}) /\
9149 ~(connected_component s y INTER t = {})
9150 ==> connected_component s x = connected_component s y`,
9152 REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
9153 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN DISCH_THEN(CONJUNCTS_THEN2
9154 (X_CHOOSE_THEN `w:real^N` STRIP_ASSUME_TAC)
9155 (X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC)) THEN
9156 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN
9157 REWRITE_TAC[IN] THEN
9158 MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN
9159 EXISTS_TAC `z:real^N` THEN CONJ_TAC THENL [ASM_MESON_TAC[IN]; ALL_TAC] THEN
9160 MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN
9161 EXISTS_TAC `w:real^N` THEN CONJ_TAC THENL
9162 [REWRITE_TAC[connected_component] THEN
9163 EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[];
9164 ASM_MESON_TAC[IN; CONNECTED_COMPONENT_SYM]]);;
9166 let CONNECTED_COMPONENT_TRANSLATION = prove
9167 (`!a s x. connected_component (IMAGE (\x. a + x) s) (a + x) =
9168 IMAGE (\x. a + x) (connected_component s x)`,
9169 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN GEOM_TRANSLATE_TAC[]);;
9171 add_translation_invariants [CONNECTED_COMPONENT_TRANSLATION];;
9173 let CONNECTED_COMPONENT_LINEAR_IMAGE = prove
9174 (`!f s x. linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
9175 ==> connected_component (IMAGE f s) (f x) =
9176 IMAGE f (connected_component s x)`,
9177 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN
9178 GEOM_TRANSFORM_TAC[]);;
9180 add_linear_invariants [CONNECTED_COMPONENT_LINEAR_IMAGE];;
9182 let UNIONS_CONNECTED_COMPONENT = prove
9183 (`!s:real^N->bool. UNIONS {connected_component s x |x| x IN s} = s`,
9184 GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
9185 REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC; CONNECTED_COMPONENT_SUBSET] THEN
9186 REWRITE_TAC[SUBSET; UNIONS_GSPEC; IN_ELIM_THM] THEN
9187 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN EXISTS_TAC `x:real^N` THEN
9188 ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN] THEN
9189 ASM_REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ]);;
9191 let COMPLEMENT_CONNECTED_COMPONENT_UNIONS = prove
9193 s DIFF connected_component s x =
9194 UNIONS({connected_component s y | y | y IN s} DELETE
9195 (connected_component s x))`,
9197 GEN_REWRITE_TAC (LAND_CONV o LAND_CONV)
9198 [GSYM UNIONS_CONNECTED_COMPONENT] THEN
9199 MATCH_MP_TAC(SET_RULE
9200 `(!x. x IN s DELETE a ==> DISJOINT a x)
9201 ==> UNIONS s DIFF a = UNIONS (s DELETE a)`) THEN
9202 REWRITE_TAC[IMP_CONJ; FORALL_IN_GSPEC; IN_DELETE] THEN
9203 SIMP_TAC[CONNECTED_COMPONENT_DISJOINT; CONNECTED_COMPONENT_EQ_EQ] THEN
9204 MESON_TAC[IN; SUBSET; CONNECTED_COMPONENT_SUBSET]);;
9206 let CLOSED_IN_CONNECTED_COMPONENT = prove
9207 (`!s x:real^N. closed_in (subtopology euclidean s) (connected_component s x)`,
9209 ASM_CASES_TAC `connected_component s (x:real^N) = {}` THEN
9210 ASM_REWRITE_TAC[CLOSED_IN_EMPTY] THEN
9211 RULE_ASSUM_TAC(REWRITE_RULE[CONNECTED_COMPONENT_EQ_EMPTY]) THEN
9212 REWRITE_TAC[CLOSED_IN_CLOSED] THEN
9213 EXISTS_TAC `closure(connected_component s x):real^N->bool` THEN
9214 REWRITE_TAC[CLOSED_CLOSURE] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
9215 REWRITE_TAC[SUBSET_INTER; CONNECTED_COMPONENT_SUBSET; CLOSURE_SUBSET] THEN
9216 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN REWRITE_TAC[INTER_SUBSET] THEN
9218 [ASM_REWRITE_TAC[IN_INTER] THEN
9219 MATCH_MP_TAC(REWRITE_RULE[SUBSET] CLOSURE_SUBSET) THEN
9220 ASM_REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ];
9221 MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN
9222 EXISTS_TAC `connected_component s (x:real^N)` THEN
9223 REWRITE_TAC[INTER_SUBSET; CONNECTED_CONNECTED_COMPONENT;
9224 SUBSET_INTER; CONNECTED_COMPONENT_SUBSET; CLOSURE_SUBSET]]);;
9226 let OPEN_IN_CONNECTED_COMPONENT = prove
9228 FINITE {connected_component s x |x| x IN s}
9229 ==> open_in (subtopology euclidean s) (connected_component s x)`,
9230 REPEAT STRIP_TAC THEN
9232 `connected_component s (x:real^N) =
9233 s DIFF (UNIONS {connected_component s y |y| y IN s} DIFF
9234 connected_component s x)`
9236 [REWRITE_TAC[UNIONS_CONNECTED_COMPONENT] THEN
9237 MATCH_MP_TAC(SET_RULE `t SUBSET s ==> t = s DIFF (s DIFF t)`) THEN
9238 REWRITE_TAC[CONNECTED_COMPONENT_SUBSET];
9239 MATCH_MP_TAC OPEN_IN_DIFF THEN
9240 REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL; TOPSPACE_EUCLIDEAN; SUBSET_UNIV] THEN
9241 REWRITE_TAC[UNIONS_DIFF] THEN
9242 MATCH_MP_TAC CLOSED_IN_UNIONS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN
9243 ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN
9244 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
9246 `connected_component s y DIFF connected_component s x =
9247 connected_component s y \/
9248 connected_component s (y:real^N) DIFF connected_component s x = {}`
9249 (DISJ_CASES_THEN SUBST1_TAC)
9251 [MATCH_MP_TAC(SET_RULE
9252 `(~(s INTER t = {}) ==> s = t) ==> s DIFF t = s \/ s DIFF t = {}`) THEN
9253 SIMP_TAC[CONNECTED_COMPONENT_OVERLAP];
9254 REWRITE_TAC[CLOSED_IN_CONNECTED_COMPONENT];
9255 REWRITE_TAC[CLOSED_IN_EMPTY]]]);;
9257 let CONNECTED_COMPONENT_EQUIVALENCE_RELATION = prove
9258 (`!R s:real^N->bool.
9259 (!x y. R x y ==> R y x) /\
9260 (!x y z. R x y /\ R y z ==> R x z) /\
9262 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
9263 !x. x IN t ==> R a x)
9264 ==> !a b. connected_component s a b ==> R a b`,
9265 REPEAT STRIP_TAC THEN
9266 MP_TAC(ISPECL [`R:real^N->real^N->bool`; `connected_component s (a:real^N)`]
9267 CONNECTED_EQUIVALENCE_RELATION) THEN
9268 ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN ANTS_TAC THENL
9269 [X_GEN_TAC `c:real^N` THEN DISCH_TAC THEN
9270 FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N`) THEN ANTS_TAC THENL
9271 [ASM_MESON_TAC[CONNECTED_COMPONENT_SUBSET; SUBSET]; ALL_TAC] THEN
9272 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
9273 EXISTS_TAC `t INTER connected_component s (a:real^N)` THEN
9274 ASM_SIMP_TAC[IN_INTER; OPEN_IN_OPEN] THEN
9275 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN
9276 MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN
9277 MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`]
9278 CONNECTED_COMPONENT_SUBSET) THEN
9280 DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN] THEN
9281 REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN
9282 ASM_MESON_TAC[CONNECTED_COMPONENT_IN]]);;
9284 let CONNECTED_COMPONENT_INTERMEDIATE_SUBSET = prove
9286 connected_component u a SUBSET t /\ t SUBSET u
9287 ==> connected_component t a = connected_component u a`,
9288 REPEAT GEN_TAC THEN ASM_CASES_TAC `(a:real^N) IN u` THENL
9289 [REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_UNIQUE THEN
9290 ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN
9291 CONJ_TAC THENL [ASM_MESON_TAC[CONNECTED_COMPONENT_REFL; IN]; ALL_TAC] THEN
9292 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
9294 ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY; SUBSET]]);;
9296 (* ------------------------------------------------------------------------- *)
9297 (* The set of connected components of a set. *)
9298 (* ------------------------------------------------------------------------- *)
9300 let components = new_definition
9301 `components s = {connected_component s x | x | x:real^N IN s}`;;
9303 let COMPONENTS_TRANSLATION = prove
9304 (`!a s. components(IMAGE (\x. a + x) s) =
9305 IMAGE (IMAGE (\x. a + x)) (components s)`,
9306 REWRITE_TAC[components] THEN GEOM_TRANSLATE_TAC[] THEN SET_TAC[]);;
9308 add_translation_invariants [COMPONENTS_TRANSLATION];;
9310 let COMPONENTS_LINEAR_IMAGE = prove
9311 (`!f s. linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
9312 ==> components(IMAGE f s) = IMAGE (IMAGE f) (components s)`,
9313 REWRITE_TAC[components] THEN GEOM_TRANSFORM_TAC[] THEN SET_TAC[]);;
9315 add_linear_invariants [COMPONENTS_LINEAR_IMAGE];;
9317 let IN_COMPONENTS = prove
9318 (`!u:real^N->bool s. s IN components u
9319 <=> ?x. x IN u /\ s = connected_component u x`,
9320 REPEAT GEN_TAC THEN REWRITE_TAC[components] THEN EQ_TAC
9321 THENL [SET_TAC[];STRIP_TAC THEN ASM_SIMP_TAC[] THEN
9322 UNDISCH_TAC `x:real^N IN u` THEN SET_TAC[]]);;
9324 let UNIONS_COMPONENTS = prove
9325 (`!u:real^N->bool. u = UNIONS (components u)`,
9326 REWRITE_TAC[EXTENSION] THEN REPEAT GEN_TAC THEN EQ_TAC
9327 THENL[DISCH_TAC THEN REWRITE_TAC[IN_UNIONS] THEN
9328 EXISTS_TAC `connected_component (u:real^N->bool) x` THEN CONJ_TAC THENL
9329 [REWRITE_TAC[components] THEN SET_TAC[ASSUME `x:real^N IN u`];
9330 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SUBGOAL_THEN
9331 `?s:real^N->bool. connected s /\ s SUBSET u /\ x IN s` MP_TAC
9332 THENL[EXISTS_TAC `{x:real^N}` THEN ASM_REWRITE_TAC[CONNECTED_SING] THEN
9333 POP_ASSUM MP_TAC THEN SET_TAC[]; SET_TAC[]]];
9334 REWRITE_TAC[IN_UNIONS] THEN STRIP_TAC THEN
9335 MATCH_MP_TAC (SET_RULE `!x:real^N s u. x IN s /\ s SUBSET u ==> x IN u`) THEN
9336 EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[] THEN STRIP_ASSUME_TAC
9337 (MESON[IN_COMPONENTS;ASSUME `t:real^N->bool IN components u`]
9338 `?y. t:real^N->bool = connected_component u y`) THEN
9339 ASM_REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]]);;
9341 let PAIRWISE_DISJOINT_COMPONENTS = prove
9342 (`!u:real^N->bool. pairwise DISJOINT (components u)`,
9343 GEN_TAC THEN REWRITE_TAC[pairwise;DISJOINT] THEN
9344 MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `t:real^N->bool`] THEN STRIP_TAC THEN
9345 ASSERT_TAC `(?a. s:real^N->bool = connected_component u a) /\
9346 ?b. t:real^N->bool = connected_component u b`
9347 THENL [ASM_MESON_TAC[IN_COMPONENTS];
9348 ASM_MESON_TAC[CONNECTED_COMPONENT_NONOVERLAP]]);;
9350 let IN_COMPONENTS_NONEMPTY = prove
9351 (`!s c. c IN components s ==> ~(c = {})`,
9352 REPEAT GEN_TAC THEN REWRITE_TAC[components; IN_ELIM_THM] THEN
9353 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY]);;
9355 let IN_COMPONENTS_SUBSET = prove
9356 (`!s c. c IN components s ==> c SUBSET s`,
9357 REPEAT GEN_TAC THEN REWRITE_TAC[components; IN_ELIM_THM] THEN
9358 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]);;
9360 let IN_COMPONENTS_CONNECTED = prove
9361 (`!s c. c IN components s ==> connected c`,
9362 REPEAT GEN_TAC THEN REWRITE_TAC[components; IN_ELIM_THM] THEN
9363 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT]);;
9365 let IN_COMPONENTS_MAXIMAL = prove
9366 (`!s c:real^N->bool.
9367 c IN components s <=>
9368 ~(c = {}) /\ c SUBSET s /\ connected c /\
9369 !c'. ~(c' = {}) /\ c SUBSET c' /\ c' SUBSET s /\ connected c'
9371 REPEAT GEN_TAC THEN REWRITE_TAC[components; IN_ELIM_THM] THEN EQ_TAC THENL
9372 [DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN
9373 ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY; CONNECTED_COMPONENT_SUBSET;
9374 CONNECTED_CONNECTED_COMPONENT] THEN
9375 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
9376 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
9377 ASM_MESON_TAC[CONNECTED_COMPONENT_REFL; IN; SUBSET];
9379 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
9380 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN
9381 DISCH_TAC THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
9382 MATCH_MP_TAC(GSYM CONNECTED_COMPONENT_UNIQUE) THEN
9383 ASM_REWRITE_TAC[] THEN X_GEN_TAC `c':real^N->bool` THEN STRIP_TAC THEN
9384 REWRITE_TAC[SET_RULE `c' SUBSET c <=> c' UNION c = c`] THEN
9385 FIRST_X_ASSUM MATCH_MP_TAC THEN
9386 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
9387 MATCH_MP_TAC CONNECTED_UNION THEN ASM SET_TAC[]]);;
9389 let JOINABLE_COMPONENTS_EQ = prove
9391 connected t /\ t SUBSET s /\
9392 c1 IN components s /\ c2 IN components s /\
9393 ~(c1 INTER t = {}) /\ ~(c2 INTER t = {})
9395 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; components; FORALL_IN_GSPEC] THEN
9396 MESON_TAC[JOINABLE_CONNECTED_COMPONENT_EQ]);;
9398 let CLOSED_IN_COMPONENT = prove
9399 (`!s c:real^N->bool.
9400 c IN components s ==> closed_in (subtopology euclidean s) c`,
9401 REWRITE_TAC[components; FORALL_IN_GSPEC; CLOSED_IN_CONNECTED_COMPONENT]);;
9403 let CLOSED_COMPONENTS = prove
9404 (`!s c. closed s /\ c IN components s ==> closed c`,
9405 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; components; FORALL_IN_GSPEC] THEN
9406 SIMP_TAC[CLOSED_CONNECTED_COMPONENT]);;
9408 let COMPACT_COMPONENTS = prove
9409 (`!s c:real^N->bool. compact s /\ c IN components s ==> compact c`,
9410 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
9411 MESON_TAC[CLOSED_COMPONENTS; IN_COMPONENTS_SUBSET; BOUNDED_SUBSET]);;
9413 let CONTINUOUS_ON_COMPONENTS_GEN = prove
9414 (`!f:real^M->real^N s.
9415 (!c. c IN components s
9416 ==> open_in (subtopology euclidean s) c /\ f continuous_on c)
9417 ==> f continuous_on s`,
9418 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_OPEN_IN_PREIMAGE_EQ] THEN
9419 DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN DISCH_TAC THEN
9421 `{x | x IN s /\ (f:real^M->real^N) x IN t} =
9422 UNIONS {{x | x IN c /\ f x IN t} | c IN components s}`
9424 [CONV_TAC(LAND_CONV(SUBS_CONV
9425 [ISPEC `s:real^M->bool` UNIONS_COMPONENTS])) THEN
9426 REWRITE_TAC[UNIONS_GSPEC; IN_UNIONS] THEN SET_TAC[];
9427 MATCH_MP_TAC OPEN_IN_UNIONS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN
9428 ASM_MESON_TAC[OPEN_IN_TRANS]]);;
9430 let CONTINUOUS_ON_COMPONENTS_FINITE = prove
9431 (`!f:real^M->real^N s.
9432 FINITE(components s) /\
9433 (!c. c IN components s ==> f continuous_on c)
9434 ==> f continuous_on s`,
9435 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN
9436 DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN DISCH_TAC THEN
9438 `{x | x IN s /\ (f:real^M->real^N) x IN t} =
9439 UNIONS {{x | x IN c /\ f x IN t} | c IN components s}`
9441 [CONV_TAC(LAND_CONV(SUBS_CONV
9442 [ISPEC `s:real^M->bool` UNIONS_COMPONENTS])) THEN
9443 REWRITE_TAC[UNIONS_GSPEC; IN_UNIONS] THEN SET_TAC[];
9444 MATCH_MP_TAC CLOSED_IN_UNIONS THEN
9445 ASM_SIMP_TAC[SIMPLE_IMAGE; FINITE_IMAGE; FORALL_IN_IMAGE] THEN
9446 ASM_MESON_TAC[CLOSED_IN_TRANS; CLOSED_IN_COMPONENT]]);;
9448 let COMPONENTS_NONOVERLAP = prove
9449 (`!s c c'. c IN components s /\ c' IN components s
9450 ==> (c INTER c' = {} <=> ~(c = c'))`,
9451 REWRITE_TAC[components; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
9452 ASM_SIMP_TAC[CONNECTED_COMPONENT_NONOVERLAP]);;
9454 let COMPONENTS_EQ = prove
9455 (`!s c c'. c IN components s /\ c' IN components s
9456 ==> (c = c' <=> ~(c INTER c' = {}))`,
9457 MESON_TAC[COMPONENTS_NONOVERLAP]);;
9459 let COMPONENTS_EQ_EMPTY = prove
9460 (`!s. components s = {} <=> s = {}`,
9461 GEN_TAC THEN REWRITE_TAC[EXTENSION] THEN
9462 REWRITE_TAC[components; connected_component; IN_ELIM_THM] THEN
9465 let COMPONENTS_EMPTY = prove
9466 (`components {} = {}`,
9467 REWRITE_TAC[COMPONENTS_EQ_EMPTY]);;
9469 let CONNECTED_EQ_CONNECTED_COMPONENTS_EQ = prove
9470 (`!s. connected s <=>
9471 !c c'. c IN components s /\ c' IN components s ==> c = c'`,
9472 REWRITE_TAC[components; IN_ELIM_THM] THEN
9473 MESON_TAC[CONNECTED_EQ_CONNECTED_COMPONENT_EQ]);;
9475 let COMPONENTS_EQ_SING,COMPONENTS_EQ_SING_EXISTS = (CONJ_PAIR o prove)
9476 (`(!s:real^N->bool. components s = {s} <=> connected s /\ ~(s = {})) /\
9477 (!s:real^N->bool. (?a. components s = {a}) <=> connected s /\ ~(s = {}))`,
9478 REWRITE_TAC[AND_FORALL_THM] THEN X_GEN_TAC `s:real^N->bool` THEN
9479 MATCH_MP_TAC(TAUT `(p ==> q) /\ (q ==> r) /\ (r ==> p)
9480 ==> (p <=> r) /\ (q <=> r)`) THEN
9481 REPEAT CONJ_TAC THENL
9483 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_EQ_CONNECTED_COMPONENTS_EQ] THEN
9484 ASM_MESON_TAC[IN_SING; COMPONENTS_EQ_EMPTY; NOT_INSERT_EMPTY];
9485 STRIP_TAC THEN ONCE_REWRITE_TAC[EXTENSION] THEN
9486 REWRITE_TAC[IN_SING] THEN
9487 REWRITE_TAC[components; IN_ELIM_THM] THEN
9488 ASM_MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET; MEMBER_NOT_EMPTY]]);;
9490 let CONNECTED_EQ_COMPONENTS_SUBSET_SING = prove
9491 (`!s:real^N->bool. connected s <=> components s SUBSET {s}`,
9492 GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN
9493 ASM_REWRITE_TAC[COMPONENTS_EMPTY; CONNECTED_EMPTY; EMPTY_SUBSET] THEN
9494 REWRITE_TAC[SET_RULE `s SUBSET {a} <=> s = {} \/ s = {a}`] THEN
9495 ASM_REWRITE_TAC[COMPONENTS_EQ_EMPTY; COMPONENTS_EQ_SING]);;
9497 let CONNECTED_EQ_COMPONENTS_SUBSET_SING_EXISTS = prove
9498 (`!s:real^N->bool. connected s <=> ?a. components s SUBSET {a}`,
9499 GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN
9500 ASM_REWRITE_TAC[COMPONENTS_EMPTY; CONNECTED_EMPTY; EMPTY_SUBSET] THEN
9501 REWRITE_TAC[SET_RULE `s SUBSET {a} <=> s = {} \/ s = {a}`] THEN
9502 ASM_REWRITE_TAC[COMPONENTS_EQ_EMPTY; COMPONENTS_EQ_SING_EXISTS]);;
9504 let IN_COMPONENTS_SELF = prove
9505 (`!s:real^N->bool. s IN components s <=> connected s /\ ~(s = {})`,
9506 GEN_TAC THEN EQ_TAC THENL
9507 [MESON_TAC[IN_COMPONENTS_NONEMPTY; IN_COMPONENTS_CONNECTED];
9508 SIMP_TAC[GSYM COMPONENTS_EQ_SING; IN_SING]]);;
9510 let COMPONENTS_MAXIMAL = prove
9511 (`!s t c:real^N->bool.
9512 c IN components s /\ connected t /\ t SUBSET s /\ ~(c INTER t = {})
9514 REWRITE_TAC[IMP_CONJ; components; FORALL_IN_GSPEC] THEN
9515 REPEAT STRIP_TAC THEN
9516 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
9517 REWRITE_TAC[IN_INTER; LEFT_IMP_EXISTS_THM] THEN
9518 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
9519 FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP CONNECTED_COMPONENT_EQ) THEN
9520 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN ASM_REWRITE_TAC[]);;
9522 let COMPONENTS_UNIQUE = prove
9523 (`!s:real^N->bool k.
9526 ==> connected c /\ ~(c = {}) /\
9527 !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> c' = c)
9528 ==> components s = k`,
9529 REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN
9530 X_GEN_TAC `c:real^N->bool` THEN REWRITE_TAC[IN_COMPONENTS] THEN
9532 [DISCH_THEN(X_CHOOSE_THEN `x:real^N`
9533 (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN
9534 FIRST_ASSUM(MP_TAC o SPEC `x:real^N` o GEN_REWRITE_RULE I [EXTENSION]) THEN
9535 REWRITE_TAC[IN_UNIONS] THEN ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
9536 X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN
9537 SUBGOAL_THEN `connected_component s (x:real^N) = c`
9538 (fun th -> ASM_REWRITE_TAC[th]) THEN
9539 MATCH_MP_TAC CONNECTED_COMPONENT_UNIQUE THEN
9540 FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N->bool`) THEN
9541 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9542 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
9543 X_GEN_TAC `c':real^N->bool` THEN STRIP_TAC THEN
9544 REWRITE_TAC[SET_RULE `c' SUBSET c <=> c' UNION c = c`] THEN
9545 FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL
9546 [MATCH_MP_TAC CONNECTED_UNION; ASM SET_TAC[]] THEN
9548 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N->bool`) THEN
9549 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
9550 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
9551 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN
9552 CONJ_TAC THENL [ASM SET_TAC[]; CONV_TAC SYM_CONV] THEN
9553 FIRST_X_ASSUM MATCH_MP_TAC THEN
9554 REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT; CONNECTED_COMPONENT_SUBSET] THEN
9555 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
9556 ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]);;
9558 let COMPONENTS_UNIQUE_EQ = prove
9559 (`!s:real^N->bool k.
9560 components s = k <=>
9563 ==> connected c /\ ~(c = {}) /\
9564 !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> c' = c)`,
9565 REPEAT GEN_TAC THEN EQ_TAC THENL
9566 [DISCH_THEN(SUBST1_TAC o SYM); REWRITE_TAC[COMPONENTS_UNIQUE]] THEN
9567 REWRITE_TAC[GSYM UNIONS_COMPONENTS] THEN
9568 X_GEN_TAC `c:real^N->bool` THEN DISCH_TAC THEN REPEAT CONJ_TAC THENL
9569 [ASM_MESON_TAC[IN_COMPONENTS_CONNECTED];
9570 ASM_MESON_TAC[IN_COMPONENTS_NONEMPTY];
9571 RULE_ASSUM_TAC(REWRITE_RULE[IN_COMPONENTS_MAXIMAL]) THEN
9572 ASM_MESON_TAC[SUBSET_EMPTY]]);;
9574 let EXISTS_COMPONENT_SUPERSET = prove
9575 (`!s t:real^N->bool.
9576 t SUBSET s /\ ~(s = {}) /\ connected t
9577 ==> ?c. c IN components s /\ t SUBSET c`,
9578 REPEAT STRIP_TAC THEN ASM_CASES_TAC `t:real^N->bool = {}` THENL
9579 [ASM_REWRITE_TAC[EMPTY_SUBSET] THEN
9580 ASM_MESON_TAC[COMPONENTS_EQ_EMPTY; MEMBER_NOT_EMPTY];
9581 FIRST_X_ASSUM(X_CHOOSE_TAC `a:real^N` o
9582 GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
9583 EXISTS_TAC `connected_component s (a:real^N)` THEN
9584 REWRITE_TAC[IN_COMPONENTS] THEN CONJ_TAC THENL
9585 [ASM SET_TAC[]; ASM_MESON_TAC[CONNECTED_COMPONENT_MAXIMAL]]]);;
9587 let COMPONENTS_INTERMEDIATE_SUBSET = prove
9588 (`!s t u:real^N->bool.
9589 s IN components u /\ s SUBSET t /\ t SUBSET u
9590 ==> s IN components t`,
9591 REPEAT GEN_TAC THEN REWRITE_TAC[IN_COMPONENTS; LEFT_AND_EXISTS_THM] THEN
9592 MESON_TAC[CONNECTED_COMPONENT_INTERMEDIATE_SUBSET; SUBSET;
9593 CONNECTED_COMPONENT_REFL; IN; CONNECTED_COMPONENT_SUBSET]);;
9595 let IN_COMPONENTS_UNIONS_COMPLEMENT = prove
9596 (`!s c:real^N->bool.
9598 ==> s DIFF c = UNIONS(components s DELETE c)`,
9599 REWRITE_TAC[components; FORALL_IN_GSPEC;
9600 COMPLEMENT_CONNECTED_COMPONENT_UNIONS]);;
9602 let CONNECTED_SUBSET_CLOPEN = prove
9603 (`!u s c:real^N->bool.
9604 closed_in (subtopology euclidean u) s /\
9605 open_in (subtopology euclidean u) s /\
9606 connected c /\ c SUBSET u /\ ~(c INTER s = {})
9608 REPEAT STRIP_TAC THEN
9609 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONNECTED_CLOSED_IN]) THEN
9610 REWRITE_TAC[NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o
9611 SPECL [`c INTER s:real^N->bool`; `c DIFF s:real^N->bool`]) THEN
9612 ASM_REWRITE_TAC[CONJ_ASSOC; SET_RULE `c DIFF s = {} <=> c SUBSET s`] THEN
9613 MATCH_MP_TAC(TAUT `p ==> ~(p /\ ~q) ==> q`) THEN
9614 REPLICATE_TAC 2 (CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]]) THEN
9616 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CLOSED_IN_CLOSED]);
9617 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN])] THEN
9618 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
9619 REWRITE_TAC[OPEN_IN_OPEN; CLOSED_IN_CLOSED] THENL
9620 [EXISTS_TAC `t:real^N->bool`; EXISTS_TAC `(:real^N) DIFF t`] THEN
9621 ASM_REWRITE_TAC[GSYM OPEN_CLOSED] THEN ASM SET_TAC[]);;
9623 let CLOPEN_UNIONS_COMPONENTS = prove
9624 (`!u s:real^N->bool.
9625 closed_in (subtopology euclidean u) s /\
9626 open_in (subtopology euclidean u) s
9627 ==> ?k. k SUBSET components u /\ s = UNIONS k`,
9628 REPEAT STRIP_TAC THEN
9629 EXISTS_TAC `{c:real^N->bool | c IN components u /\ ~(c INTER s = {})}` THEN
9630 REWRITE_TAC[SUBSET_RESTRICT] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
9632 [MP_TAC(ISPEC `u:real^N->bool` UNIONS_COMPONENTS) THEN
9633 FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN SET_TAC[];
9634 REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC] THEN
9635 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_SUBSET_CLOPEN THEN
9636 EXISTS_TAC `u:real^N->bool` THEN
9637 ASM_MESON_TAC[IN_COMPONENTS_CONNECTED; IN_COMPONENTS_SUBSET]]);;
9639 let CLOPEN_IN_COMPONENTS = prove
9640 (`!u s:real^N->bool.
9641 closed_in (subtopology euclidean u) s /\
9642 open_in (subtopology euclidean u) s /\
9643 connected s /\ ~(s = {})
9644 ==> s IN components u`,
9645 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[CONJ_ASSOC] THEN
9646 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
9647 FIRST_ASSUM(MP_TAC o MATCH_MP CLOPEN_UNIONS_COMPONENTS) THEN
9648 DISCH_THEN(X_CHOOSE_THEN `k:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
9649 ASM_CASES_TAC `k:(real^N->bool)->bool = {}` THEN
9650 ASM_REWRITE_TAC[UNIONS_0] THEN
9651 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
9652 DISCH_THEN(X_CHOOSE_TAC `c:real^N->bool`) THEN
9653 ASM_CASES_TAC `k = {c:real^N->bool}` THENL
9654 [ASM_MESON_TAC[UNIONS_1; GSYM SING_SUBSET]; ALL_TAC] THEN
9655 MATCH_MP_TAC(TAUT `~p ==> p /\ q ==> r`) THEN
9656 SUBGOAL_THEN `?c':real^N->bool. c' IN k /\ ~(c = c')` STRIP_ASSUME_TAC THENL
9657 [ASM_MESON_TAC[SET_RULE
9658 `a IN s /\ ~(s = {a}) ==> ?b. b IN s /\ ~(b = a)`];
9659 REWRITE_TAC[CONNECTED_EQ_CONNECTED_COMPONENTS_EQ] THEN
9660 DISCH_THEN(MP_TAC o SPECL [`c:real^N->bool`; `c':real^N->bool`]) THEN
9661 ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THEN
9662 MATCH_MP_TAC COMPONENTS_INTERMEDIATE_SUBSET THEN
9663 EXISTS_TAC `u:real^N->bool` THEN
9664 MP_TAC(ISPEC `u:real^N->bool` UNIONS_COMPONENTS) THEN ASM SET_TAC[]]);;
9666 (* ------------------------------------------------------------------------- *)
9667 (* Continuity implies uniform continuity on a compact domain. *)
9668 (* ------------------------------------------------------------------------- *)
9670 let COMPACT_UNIFORMLY_EQUICONTINUOUS = prove
9671 (`!(fs:(real^M->real^N)->bool) s.
9672 (!x e. x IN s /\ &0 < e
9674 (!f x'. f IN fs /\ x' IN s /\ dist (x',x) < d
9675 ==> dist (f x',f x) < e)) /\
9679 !f x x'. f IN fs /\ x IN s /\ x' IN s /\ dist (x',x) < d
9680 ==> dist(f x',f x) < e`,
9681 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
9682 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
9683 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
9684 X_GEN_TAC `d:real^M->real->real` THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN
9685 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP HEINE_BOREL_LEMMA) THEN
9686 DISCH_THEN(MP_TAC o SPEC
9687 `{ ball(x:real^M,d x (e / &2)) | x IN s}`) THEN
9688 SIMP_TAC[FORALL_IN_GSPEC; OPEN_BALL; UNIONS_GSPEC; SUBSET; IN_ELIM_THM] THEN
9689 ANTS_TAC THENL [ASM_MESON_TAC[CENTRE_IN_BALL; REAL_HALF]; ALL_TAC] THEN
9690 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real` THEN STRIP_TAC THEN
9691 ASM_REWRITE_TAC[] THEN
9692 MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `u:real^M`; `v:real^M`] THEN
9693 STRIP_TAC THEN FIRST_X_ASSUM(fun th -> MP_TAC(SPEC `v:real^M` th) THEN
9694 ASM_REWRITE_TAC[] THEN DISCH_THEN(CHOOSE_THEN MP_TAC)) THEN
9695 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
9696 DISCH_THEN(fun th ->
9697 MP_TAC(SPEC `u:real^M` th) THEN MP_TAC(SPEC `v:real^M` th)) THEN
9698 ASM_REWRITE_TAC[DIST_REFL] THEN
9699 FIRST_X_ASSUM(X_CHOOSE_THEN `w:real^M` (CONJUNCTS_THEN2 ASSUME_TAC
9700 SUBST_ALL_TAC)) THEN
9701 ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN ASM_REWRITE_TAC[IN_BALL] THEN
9702 ONCE_REWRITE_TAC[DIST_SYM] THEN REPEAT STRIP_TAC THEN
9703 FIRST_X_ASSUM(MP_TAC o SPECL [`w:real^M`; `e / &2`]) THEN
9704 ASM_REWRITE_TAC[REAL_HALF] THEN
9705 DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o CONJUNCT2) THEN
9706 DISCH_THEN(fun th -> MP_TAC(SPEC `u:real^M` th) THEN
9707 MP_TAC(SPEC `v:real^M` th)) THEN
9708 ASM_REWRITE_TAC[] THEN CONV_TAC NORM_ARITH);;
9710 let COMPACT_UNIFORMLY_CONTINUOUS = prove
9711 (`!f:real^M->real^N s.
9712 f continuous_on s /\ compact s ==> f uniformly_continuous_on s`,
9713 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on; uniformly_continuous_on] THEN
9715 MP_TAC(ISPECL [`{f:real^M->real^N}`; `s:real^M->bool`]
9716 COMPACT_UNIFORMLY_EQUICONTINUOUS) THEN
9717 REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; IN_SING; FORALL_UNWIND_THM2] THEN
9720 (* ------------------------------------------------------------------------- *)
9721 (* A uniformly convergent limit of continuous functions is continuous. *)
9722 (* ------------------------------------------------------------------------- *)
9724 let CONTINUOUS_UNIFORM_LIMIT = prove
9725 (`!net f:A->real^M->real^N g s.
9726 ~(trivial_limit net) /\
9727 eventually (\n. (f n) continuous_on s) net /\
9729 ==> eventually (\n. !x. x IN s ==> norm(f n x - g x) < e) net)
9730 ==> g continuous_on s`,
9731 REWRITE_TAC[continuous_on] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
9732 X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN
9733 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
9734 FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN
9735 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
9736 FIRST_X_ASSUM(fun th -> MP_TAC th THEN REWRITE_TAC[IMP_IMP] THEN
9737 GEN_REWRITE_TAC LAND_CONV [GSYM EVENTUALLY_AND]) THEN
9738 DISCH_THEN(MP_TAC o MATCH_MP EVENTUALLY_HAPPENS) THEN
9739 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `a:A` THEN
9740 DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `x:real^M`) ASSUME_TAC) THEN
9741 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
9742 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
9743 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN
9744 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
9745 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `y:real^M` THEN
9746 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
9747 FIRST_X_ASSUM(fun th ->
9748 MP_TAC(SPEC `x:real^M` th) THEN MP_TAC(SPEC `y:real^M` th)) THEN
9749 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
9751 ==> x < e / &3 ==> y < e / &3 ==> z < e / &3 ==> w < e`) THEN
9752 REWRITE_TAC[dist] THEN
9753 SUBST1_TAC(VECTOR_ARITH
9754 `(g:real^M->real^N) y - g x =
9755 --(f (a:A) y - g y) + (f a x - g x) + (f a y - f a x)`) THEN
9756 MATCH_MP_TAC NORM_TRIANGLE_LE THEN REWRITE_TAC[NORM_NEG; REAL_LE_LADD] THEN
9757 MATCH_MP_TAC NORM_TRIANGLE_LE THEN REWRITE_TAC[NORM_NEG; REAL_LE_REFL]);;
9759 (* ------------------------------------------------------------------------- *)
9760 (* Topological stuff lifted from and dropped to R *)
9761 (* ------------------------------------------------------------------------- *)
9763 let OPEN_LIFT = prove
9764 (`!s. open(IMAGE lift s) <=>
9765 !x. x IN s ==> ?e. &0 < e /\ !x'. abs(x' - x) < e ==> x' IN s`,
9766 REWRITE_TAC[open_def; FORALL_LIFT; LIFT_IN_IMAGE_LIFT; DIST_LIFT]);;
9768 let LIMPT_APPROACHABLE_LIFT = prove
9769 (`!x s. (lift x) limit_point_of (IMAGE lift s) <=>
9770 !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ abs(x' - x) < e`,
9771 REWRITE_TAC[LIMPT_APPROACHABLE; EXISTS_LIFT; LIFT_IN_IMAGE_LIFT;
9772 LIFT_EQ; DIST_LIFT]);;
9774 let CLOSED_LIFT = prove
9775 (`!s. closed (IMAGE lift s) <=>
9776 !x. (!e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ abs(x' - x) < e)
9778 GEN_TAC THEN REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE] THEN
9779 ONCE_REWRITE_TAC[FORALL_LIFT] THEN
9780 REWRITE_TAC[LIMPT_APPROACHABLE_LIFT; LIFT_EQ; DIST_LIFT;
9781 EXISTS_LIFT; LIFT_IN_IMAGE_LIFT]);;
9783 let CONTINUOUS_AT_LIFT_RANGE = prove
9784 (`!f x. (lift o f) continuous (at x) <=>
9787 (!x'. norm(x' - x) < d
9788 ==> abs(f x' - f x) < e)`,
9789 REWRITE_TAC[continuous_at; o_THM; DIST_LIFT] THEN REWRITE_TAC[dist]);;
9791 let CONTINUOUS_ON_LIFT_RANGE = prove
9792 (`!f s. (lift o f) continuous_on s <=>
9796 (!x'. x' IN s /\ norm(x' - x) < d
9797 ==> abs(f x' - f x) < e)`,
9798 REWRITE_TAC[continuous_on; o_THM; DIST_LIFT] THEN REWRITE_TAC[dist]);;
9800 let CONTINUOUS_LIFT_NORM_COMPOSE = prove
9803 ==> (\x. lift(norm(f x))) continuous net`,
9804 REPEAT GEN_TAC THEN REWRITE_TAC[continuous; tendsto] THEN
9805 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
9807 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
9808 REWRITE_TAC[DIST_REAL; GSYM drop; LIFT_DROP] THEN
9811 let CONTINUOUS_ON_LIFT_NORM_COMPOSE = prove
9812 (`!f:real^M->real^N s.
9814 ==> (\x. lift(norm(f x))) continuous_on s`,
9815 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_LIFT_NORM_COMPOSE]);;
9817 let CONTINUOUS_AT_LIFT_NORM = prove
9818 (`!x. (lift o norm) continuous (at x)`,
9819 REWRITE_TAC[CONTINUOUS_AT_LIFT_RANGE; NORM_LIFT] THEN
9820 MESON_TAC[REAL_ABS_SUB_NORM; REAL_LET_TRANS]);;
9822 let CONTINUOUS_ON_LIFT_NORM = prove
9823 (`!s. (lift o norm) continuous_on s`,
9824 REWRITE_TAC[CONTINUOUS_ON_LIFT_RANGE; NORM_LIFT] THEN
9825 MESON_TAC[REAL_ABS_SUB_NORM; REAL_LET_TRANS]);;
9827 let CONTINUOUS_AT_LIFT_COMPONENT = prove
9828 (`!i a. 1 <= i /\ i <= dimindex(:N)
9829 ==> (\x:real^N. lift(x$i)) continuous (at a)`,
9830 SIMP_TAC[continuous_at; DIST_LIFT; GSYM VECTOR_SUB_COMPONENT] THEN
9831 MESON_TAC[dist; REAL_LET_TRANS; COMPONENT_LE_NORM]);;
9833 let CONTINUOUS_ON_LIFT_COMPONENT = prove
9834 (`!i s. 1 <= i /\ i <= dimindex(:N)
9835 ==> (\x:real^N. lift(x$i)) continuous_on s`,
9836 SIMP_TAC[continuous_on; DIST_LIFT; GSYM VECTOR_SUB_COMPONENT] THEN
9837 MESON_TAC[dist; REAL_LET_TRANS; COMPONENT_LE_NORM]);;
9839 let CONTINUOUS_AT_LIFT_INFNORM = prove
9840 (`!x:real^N. (lift o infnorm) continuous (at x)`,
9841 REWRITE_TAC[CONTINUOUS_AT; LIM_AT; o_THM; DIST_LIFT] THEN
9842 MESON_TAC[REAL_LET_TRANS; dist; REAL_ABS_SUB_INFNORM; INFNORM_LE_NORM]);;
9844 let CONTINUOUS_AT_LIFT_DIST = prove
9845 (`!a:real^N x. (lift o (\x. dist(a,x))) continuous (at x)`,
9846 REWRITE_TAC[CONTINUOUS_AT_LIFT_RANGE] THEN
9847 MESON_TAC[NORM_ARITH `abs(dist(a:real^N,x) - dist(a,y)) <= norm(x - y)`;
9850 let CONTINUOUS_ON_LIFT_DIST = prove
9851 (`!a s. (lift o (\x. dist(a,x))) continuous_on s`,
9852 REWRITE_TAC[CONTINUOUS_ON_LIFT_RANGE] THEN
9853 MESON_TAC[NORM_ARITH `abs(dist(a:real^N,x) - dist(a,y)) <= norm(x - y)`;
9856 (* ------------------------------------------------------------------------- *)
9857 (* Hence some handy theorems on distance, diameter etc. of/from a set. *)
9858 (* ------------------------------------------------------------------------- *)
9860 let COMPACT_ATTAINS_SUP = prove
9861 (`!s. compact (IMAGE lift s) /\ ~(s = {})
9862 ==> ?x. x IN s /\ !y. y IN s ==> y <= x`,
9863 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN REPEAT STRIP_TAC THEN
9864 MP_TAC(SPEC `s:real->bool` BOUNDED_HAS_SUP) THEN ASM_REWRITE_TAC[] THEN
9865 STRIP_TAC THEN EXISTS_TAC `sup s` THEN ASM_REWRITE_TAC[] THEN
9866 ASM_MESON_TAC[CLOSED_LIFT; REAL_ARITH `s <= s - e <=> ~(&0 < e)`;
9867 REAL_ARITH `x <= s /\ ~(x <= s - e) ==> abs(x - s) < e`]);;
9869 let COMPACT_ATTAINS_INF = prove
9870 (`!s. compact (IMAGE lift s) /\ ~(s = {})
9871 ==> ?x. x IN s /\ !y. y IN s ==> x <= y`,
9872 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN REPEAT STRIP_TAC THEN
9873 MP_TAC(SPEC `s:real->bool` BOUNDED_HAS_INF) THEN ASM_REWRITE_TAC[] THEN
9874 STRIP_TAC THEN EXISTS_TAC `inf s` THEN ASM_REWRITE_TAC[] THEN
9875 ASM_MESON_TAC[CLOSED_LIFT; REAL_ARITH `s + e <= s <=> ~(&0 < e)`;
9876 REAL_ARITH `s <= x /\ ~(s + e <= x) ==> abs(x - s) < e`]);;
9878 let CONTINUOUS_ATTAINS_SUP = prove
9879 (`!f:real^N->real s.
9880 compact s /\ ~(s = {}) /\ (lift o f) continuous_on s
9881 ==> ?x. x IN s /\ !y. y IN s ==> f(y) <= f(x)`,
9882 REPEAT STRIP_TAC THEN
9883 MP_TAC(SPEC `IMAGE (f:real^N->real) s` COMPACT_ATTAINS_SUP) THEN
9884 ASM_SIMP_TAC[GSYM IMAGE_o; COMPACT_CONTINUOUS_IMAGE; IMAGE_EQ_EMPTY] THEN
9885 MESON_TAC[IN_IMAGE]);;
9887 let CONTINUOUS_ATTAINS_INF = prove
9888 (`!f:real^N->real s.
9889 compact s /\ ~(s = {}) /\ (lift o f) continuous_on s
9890 ==> ?x. x IN s /\ !y. y IN s ==> f(x) <= f(y)`,
9891 REPEAT STRIP_TAC THEN
9892 MP_TAC(SPEC `IMAGE (f:real^N->real) s` COMPACT_ATTAINS_INF) THEN
9893 ASM_SIMP_TAC[GSYM IMAGE_o; COMPACT_CONTINUOUS_IMAGE; IMAGE_EQ_EMPTY] THEN
9894 MESON_TAC[IN_IMAGE]);;
9896 let DISTANCE_ATTAINS_SUP = prove
9897 (`!s a. compact s /\ ~(s = {})
9898 ==> ?x. x IN s /\ !y. y IN s ==> dist(a,y) <= dist(a,x)`,
9899 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ATTAINS_SUP THEN
9900 ASM_REWRITE_TAC[CONTINUOUS_ON_LIFT_RANGE] THEN REWRITE_TAC[dist] THEN
9901 ASM_MESON_TAC[REAL_LET_TRANS; REAL_ABS_SUB_NORM; NORM_NEG;
9902 VECTOR_ARITH `(a - x) - (a - y) = --(x - y):real^N`]);;
9904 (* ------------------------------------------------------------------------- *)
9905 (* For *minimal* distance, we only need closure, not compactness. *)
9906 (* ------------------------------------------------------------------------- *)
9908 let DISTANCE_ATTAINS_INF = prove
9910 closed s /\ ~(s = {})
9911 ==> ?x. x IN s /\ !y. y IN s ==> dist(a,x) <= dist(a,y)`,
9912 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
9913 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
9914 DISCH_THEN(X_CHOOSE_TAC `b:real^N`) THEN
9915 MP_TAC(ISPECL [`\x:real^N. dist(a,x)`; `cball(a:real^N,dist(b,a)) INTER s`]
9916 CONTINUOUS_ATTAINS_INF) THEN
9918 [ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_INTER; BOUNDED_INTER;
9919 BOUNDED_CBALL; CLOSED_CBALL; GSYM MEMBER_NOT_EMPTY] THEN
9920 REWRITE_TAC[dist; CONTINUOUS_ON_LIFT_RANGE; IN_INTER; IN_CBALL] THEN
9921 ASM_MESON_TAC[REAL_LET_TRANS; REAL_ABS_SUB_NORM; NORM_NEG; REAL_LE_REFL;
9922 NORM_SUB; VECTOR_ARITH `(a - x) - (a - y) = --(x - y):real^N`];
9923 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[IN_INTER; IN_CBALL] THEN
9924 ASM_MESON_TAC[DIST_SYM; REAL_LE_TOTAL; REAL_LE_TRANS]]);;
9926 (* ------------------------------------------------------------------------- *)
9927 (* We can now extend limit compositions to consider the scalar multiplier. *)
9928 (* ------------------------------------------------------------------------- *)
9931 (`!net:(A)net f l:real^N c d.
9932 ((lift o c) --> lift d) net /\ (f --> l) net
9933 ==> ((\x. c(x) % f(x)) --> (d % l)) net`,
9934 REPEAT STRIP_TAC THEN
9935 MP_TAC(ISPECL [`net:(A)net`; `\x (y:real^N). drop x % y`;
9936 `lift o (c:A->real)`; `f:A->real^N`; `lift d`; `l:real^N`] LIM_BILINEAR) THEN
9937 ASM_REWRITE_TAC[LIFT_DROP; o_THM] THEN DISCH_THEN MATCH_MP_TAC THEN
9938 REWRITE_TAC[bilinear; linear; DROP_ADD; DROP_CMUL] THEN
9939 REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
9941 let LIM_VMUL = prove
9942 (`!net:(A)net c d v:real^N.
9943 ((lift o c) --> lift d) net ==> ((\x. c(x) % v) --> d % v) net`,
9944 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_MUL THEN ASM_REWRITE_TAC[LIM_CONST]);;
9946 let CONTINUOUS_VMUL = prove
9947 (`!net c v. (lift o c) continuous net ==> (\x. c(x) % v) continuous net`,
9948 REWRITE_TAC[continuous; LIM_VMUL; o_THM]);;
9950 let CONTINUOUS_MUL = prove
9951 (`!net f c. (lift o c) continuous net /\ f continuous net
9952 ==> (\x. c(x) % f(x)) continuous net`,
9953 REWRITE_TAC[continuous; LIM_MUL; o_THM]);;
9955 let CONTINUOUS_ON_VMUL = prove
9956 (`!s c v. (lift o c) continuous_on s ==> (\x. c(x) % v) continuous_on s`,
9957 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
9958 SIMP_TAC[CONTINUOUS_VMUL]);;
9960 let CONTINUOUS_ON_MUL = prove
9961 (`!s c f. (lift o c) continuous_on s /\ f continuous_on s
9962 ==> (\x. c(x) % f(x)) continuous_on s`,
9963 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
9964 SIMP_TAC[CONTINUOUS_MUL]);;
9966 let CONTINUOUS_LIFT_POW = prove
9968 (\x. lift(f x)) continuous net
9969 ==> (\x. lift(f x pow n)) continuous net`,
9970 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
9971 INDUCT_TAC THEN ASM_REWRITE_TAC[LIFT_CMUL; real_pow; CONTINUOUS_CONST] THEN
9972 MATCH_MP_TAC CONTINUOUS_MUL THEN ASM_REWRITE_TAC[o_DEF]);;
9974 let CONTINUOUS_ON_LIFT_POW = prove
9975 (`!f:real^N->real s n.
9976 (\x. lift(f x)) continuous_on s
9977 ==> (\x. lift(f x pow n)) continuous_on s`,
9978 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN
9979 DISCH_TAC THEN INDUCT_TAC THEN
9980 ASM_REWRITE_TAC[LIFT_CMUL; real_pow; CONTINUOUS_ON_CONST] THEN
9981 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN ASM_REWRITE_TAC[o_DEF]);;
9983 let CONTINUOUS_LIFT_PRODUCT = prove
9984 (`!net:(A)net f (t:B->bool).
9986 (!i. i IN t ==> (\x. lift(f x i)) continuous net)
9987 ==> (\x. lift(product t (f x))) continuous net`,
9988 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
9989 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN SIMP_TAC[PRODUCT_CLAUSES] THEN
9990 REWRITE_TAC[CONTINUOUS_CONST; LIFT_CMUL; FORALL_IN_INSERT] THEN
9991 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_MUL THEN
9992 ASM_SIMP_TAC[o_DEF]);;
9994 let CONTINUOUS_ON_LIFT_PRODUCT = prove
9995 (`!f:real^N->A->real s t.
9998 (!i. i IN t ==> (\x. lift(f x i)) continuous_on s)
9999 ==> (\x. lift(product t (f x))) continuous_on s`,
10000 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_LIFT_PRODUCT]);;
10002 (* ------------------------------------------------------------------------- *)
10003 (* And so we have continuity of inverse. *)
10004 (* ------------------------------------------------------------------------- *)
10006 let LIM_INV = prove
10008 ((lift o f) --> lift l) net /\ ~(l = &0)
10009 ==> ((lift o inv o f) --> lift(inv l)) net`,
10010 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
10011 ASM_CASES_TAC `trivial_limit(net:(A)net)` THEN ASM_REWRITE_TAC[] THEN
10012 REWRITE_TAC[o_THM; DIST_LIFT] THEN STRIP_TAC THEN
10013 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10014 FIRST_X_ASSUM(MP_TAC o SPEC `min (abs(l) / &2) ((l pow 2 * e) / &2)`) THEN
10015 REWRITE_TAC[REAL_LT_MIN] THEN ANTS_TAC THENL
10016 [ASM_SIMP_TAC[GSYM REAL_ABS_NZ; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
10017 MATCH_MP_TAC REAL_LT_DIV THEN REWRITE_TAC[REAL_OF_NUM_LT; ARITH] THEN
10018 ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN
10019 ASM_SIMP_TAC[REAL_LT_MUL; GSYM REAL_ABS_NZ; REAL_POW_LT];
10021 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:A` THEN
10022 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
10023 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `b:A` THEN
10024 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
10025 SIMP_TAC[REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN STRIP_TAC THEN
10026 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_ARITH
10027 `abs(x - l) * &2 < abs l ==> ~(x = &0)`)) THEN
10028 ASM_SIMP_TAC[REAL_SUB_INV; REAL_ABS_DIV; REAL_LT_LDIV_EQ;
10029 GSYM REAL_ABS_NZ; REAL_ENTIRE] THEN
10030 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
10031 `abs(x - y) * &2 < b * c ==> c * b <= d * &2 ==> abs(y - x) < d`)) THEN
10032 ASM_SIMP_TAC[GSYM REAL_MUL_ASSOC; REAL_LE_LMUL_EQ] THEN
10033 ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
10034 ASM_SIMP_TAC[REAL_ABS_MUL; REAL_POW_2; REAL_MUL_ASSOC; GSYM REAL_ABS_NZ;
10035 REAL_LE_RMUL_EQ] THEN
10036 ASM_SIMP_TAC[REAL_ARITH `abs(x - y) * &2 < abs y ==> abs y <= &2 * abs x`]);;
10038 let CONTINUOUS_INV = prove
10039 (`!net f. (lift o f) continuous net /\ ~(f(netlimit net) = &0)
10040 ==> (lift o inv o f) continuous net`,
10041 REWRITE_TAC[continuous; LIM_INV; o_THM]);;
10043 let CONTINUOUS_AT_WITHIN_INV = prove
10045 (lift o f) continuous (at a within s) /\ ~(f a = &0)
10046 ==> (lift o inv o f) continuous (at a within s)`,
10047 REPEAT GEN_TAC THEN
10048 ASM_CASES_TAC `trivial_limit (at (a:real^N) within s)` THENL
10049 [ASM_REWRITE_TAC[continuous; LIM];
10050 ASM_SIMP_TAC[NETLIMIT_WITHIN; CONTINUOUS_INV]]);;
10052 let CONTINUOUS_AT_INV = prove
10053 (`!f a. (lift o f) continuous at a /\ ~(f a = &0)
10054 ==> (lift o inv o f) continuous at a`,
10055 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
10056 REWRITE_TAC[CONTINUOUS_AT_WITHIN_INV]);;
10058 let CONTINUOUS_ON_INV = prove
10059 (`!f s. (lift o f) continuous_on s /\ (!x. x IN s ==> ~(f x = &0))
10060 ==> (lift o inv o f) continuous_on s`,
10061 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_AT_WITHIN_INV]);;
10063 (* ------------------------------------------------------------------------- *)
10064 (* More preservation properties for pasted sets (Cartesian products). *)
10065 (* ------------------------------------------------------------------------- *)
10067 let LIM_PASTECART = prove
10068 (`!net f:A->real^M g:A->real^N.
10069 (f --> a) net /\ (g --> b) net
10070 ==> ((\x. pastecart (f x) (g x)) --> pastecart a b) net`,
10071 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
10072 ASM_CASES_TAC `trivial_limit(net:(A)net)` THEN ASM_REWRITE_TAC[] THEN
10073 REWRITE_TAC[AND_FORALL_THM] THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN
10074 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
10075 ASM_REWRITE_TAC[REAL_HALF] THEN
10076 DISCH_THEN(MP_TAC o MATCH_MP NET_DILEMMA) THEN
10077 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN MATCH_MP_TAC MONO_AND THEN
10078 REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
10079 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
10080 REWRITE_TAC[dist; PASTECART_SUB] THEN
10081 MATCH_MP_TAC(REAL_ARITH
10082 `z <= x + y ==> x < e / &2 /\ y < e / &2 ==> z < e`) THEN
10083 REWRITE_TAC[NORM_PASTECART_LE]);;
10085 let LIM_PASTECART_EQ = prove
10086 (`!net f:A->real^M g:A->real^N.
10087 ((\x. pastecart (f x) (g x)) --> pastecart a b) net <=>
10088 (f --> a) net /\ (g --> b) net`,
10089 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[LIM_PASTECART] THEN
10090 REPEAT STRIP_TAC THENL
10091 [FIRST_ASSUM(MP_TAC o ISPEC `fstcart:real^(M,N)finite_sum->real^M` o
10092 MATCH_MP (REWRITE_RULE[IMP_CONJ] LIM_LINEAR)) THEN
10093 REWRITE_TAC[LINEAR_FSTCART; FSTCART_PASTECART; ETA_AX];
10094 FIRST_ASSUM(MP_TAC o ISPEC `sndcart:real^(M,N)finite_sum->real^N` o
10095 MATCH_MP (REWRITE_RULE[IMP_CONJ] LIM_LINEAR)) THEN
10096 REWRITE_TAC[LINEAR_SNDCART; SNDCART_PASTECART; ETA_AX]]);;
10098 let CONTINUOUS_PASTECART = prove
10099 (`!net f:A->real^M g:A->real^N.
10100 f continuous net /\ g continuous net
10101 ==> (\x. pastecart (f x) (g x)) continuous net`,
10102 REWRITE_TAC[continuous; LIM_PASTECART]);;
10104 let CONTINUOUS_ON_PASTECART = prove
10105 (`!f:real^M->real^N g:real^M->real^P s.
10106 f continuous_on s /\ g continuous_on s
10107 ==> (\x. pastecart (f x) (g x)) continuous_on s`,
10108 SIMP_TAC[CONTINUOUS_ON; LIM_PASTECART]);;
10110 let CONNECTED_PCROSS = prove
10111 (`!s:real^M->bool t:real^N->bool.
10112 connected s /\ connected t
10113 ==> connected (s PCROSS t)`,
10114 REPEAT GEN_TAC THEN
10115 REWRITE_TAC[PCROSS; CONNECTED_IFF_CONNECTED_COMPONENT] THEN
10116 DISCH_TAC THEN REWRITE_TAC[FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN
10117 MAP_EVERY X_GEN_TAC [`x1:real^M`; `y1:real^N`; `x2:real^M`; `y2:real^N`] THEN
10118 STRIP_TAC THEN FIRST_X_ASSUM(CONJUNCTS_THEN2
10119 (MP_TAC o SPECL [`x1:real^M`; `x2:real^M`])
10120 (MP_TAC o SPECL [`y1:real^N`; `y2:real^N`])) THEN
10121 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; connected_component] THEN
10122 X_GEN_TAC `c2:real^N->bool` THEN STRIP_TAC THEN
10123 X_GEN_TAC `c1:real^M->bool` THEN STRIP_TAC THEN
10125 `IMAGE (\x:real^M. pastecart x y1) c1 UNION
10126 IMAGE (\y:real^N. pastecart x2 y) c2` THEN
10127 REWRITE_TAC[IN_UNION] THEN REPEAT CONJ_TAC THENL
10128 [MATCH_MP_TAC CONNECTED_UNION THEN
10129 ASM_SIMP_TAC[CONNECTED_CONTINUOUS_IMAGE; CONTINUOUS_ON_PASTECART;
10130 CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN
10131 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER; EXISTS_IN_IMAGE] THEN
10132 EXISTS_TAC `x2:real^M` THEN ASM SET_TAC[];
10133 REWRITE_TAC[SUBSET; IN_UNION; FORALL_AND_THM; FORALL_IN_IMAGE;
10134 TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
10139 let CONNECTED_PCROSS_EQ = prove
10140 (`!s:real^M->bool t:real^N->bool.
10141 connected (s PCROSS t) <=>
10142 s = {} \/ t = {} \/ connected s /\ connected t`,
10143 REPEAT GEN_TAC THEN
10144 ASM_CASES_TAC `s:real^M->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
10145 ASM_CASES_TAC `t:real^N->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
10146 REWRITE_TAC[PCROSS_EMPTY; CONNECTED_EMPTY] THEN
10147 EQ_TAC THEN SIMP_TAC[CONNECTED_PCROSS] THEN
10148 REWRITE_TAC[PCROSS] THEN REPEAT STRIP_TAC THENL
10149 [SUBGOAL_THEN `connected (IMAGE fstcart
10150 {pastecart (x:real^M) (y:real^N) | x IN s /\ y IN t})`
10151 MP_TAC THENL [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE; ALL_TAC];
10152 SUBGOAL_THEN `connected (IMAGE sndcart
10153 {pastecart (x:real^M) (y:real^N) | x IN s /\ y IN t})`
10154 MP_TAC THENL [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE; ALL_TAC]] THEN
10155 ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART] THEN
10156 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
10157 REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; IN_ELIM_PASTECART_THM;
10158 FSTCART_PASTECART; SNDCART_PASTECART] THEN
10161 let CLOSURE_PCROSS = prove
10162 (`!s:real^M->bool t:real^N->bool.
10163 closure (s PCROSS t) = (closure s) PCROSS (closure t)`,
10164 REWRITE_TAC[EXTENSION; PCROSS; FORALL_PASTECART] THEN REPEAT GEN_TAC THEN
10165 REWRITE_TAC[CLOSURE_APPROACHABLE; EXISTS_PASTECART; FORALL_PASTECART] THEN
10166 REWRITE_TAC[IN_ELIM_PASTECART_THM; PASTECART_INJ] THEN
10167 REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN
10168 REWRITE_TAC[dist; PASTECART_SUB] THEN EQ_TAC THENL
10169 [MESON_TAC[NORM_LE_PASTECART; REAL_LET_TRANS]; DISCH_TAC] THEN
10170 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10171 FIRST_X_ASSUM(CONJUNCTS_THEN (MP_TAC o SPEC `e / &2`)) THEN
10172 ASM_MESON_TAC[REAL_HALF; NORM_PASTECART_LE; REAL_ARITH
10173 `z <= x + y /\ x < e / &2 /\ y < e / &2 ==> z < e`]);;
10175 let LIMPT_PCROSS = prove
10176 (`!s:real^M->bool t:real^N->bool x y.
10177 x limit_point_of s /\ y limit_point_of t
10178 ==> (pastecart x y) limit_point_of (s PCROSS t)`,
10179 REPEAT GEN_TAC THEN
10180 REWRITE_TAC[PCROSS; LIMPT_APPROACHABLE; EXISTS_PASTECART] THEN
10181 REWRITE_TAC[IN_ELIM_PASTECART_THM; PASTECART_INJ; dist; PASTECART_SUB] THEN
10182 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10183 FIRST_X_ASSUM(CONJUNCTS_THEN (MP_TAC o SPEC `e / &2`)) THEN
10184 ASM_MESON_TAC[REAL_HALF; NORM_PASTECART_LE; REAL_ARITH
10185 `z <= x + y /\ x < e / &2 /\ y < e / &2 ==> z < e`]);;
10187 let CLOSED_IN_PCROSS = prove
10188 (`!s:real^M->bool s' t:real^N->bool t'.
10189 closed_in (subtopology euclidean s) s' /\
10190 closed_in (subtopology euclidean t) t'
10191 ==> closed_in (subtopology euclidean (s PCROSS t)) (s' PCROSS t')`,
10192 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN
10193 DISCH_THEN(CONJUNCTS_THEN2
10194 (X_CHOOSE_THEN `s'':real^M->bool` STRIP_ASSUME_TAC)
10195 (X_CHOOSE_THEN `t'':real^N->bool` STRIP_ASSUME_TAC)) THEN
10196 EXISTS_TAC `(s'':real^M->bool) PCROSS (t'':real^N->bool)` THEN
10197 ASM_SIMP_TAC[CLOSED_PCROSS; EXTENSION; FORALL_PASTECART] THEN
10198 REWRITE_TAC[IN_INTER; PASTECART_IN_PCROSS] THEN ASM SET_TAC[]);;
10200 let CLOSED_IN_PCROSS_EQ = prove
10201 (`!s s':real^M->bool t t':real^N->bool.
10202 closed_in (subtopology euclidean (s PCROSS t)) (s' PCROSS t') <=>
10203 s' = {} \/ t' = {} \/
10204 closed_in (subtopology euclidean s) s' /\
10205 closed_in (subtopology euclidean t) t'`,
10206 REPEAT GEN_TAC THEN
10207 ASM_CASES_TAC `s':real^M->bool = {}` THEN
10208 ASM_REWRITE_TAC[PCROSS_EMPTY; CLOSED_IN_EMPTY] THEN
10209 ASM_CASES_TAC `t':real^N->bool = {}` THEN
10210 ASM_REWRITE_TAC[PCROSS_EMPTY; CLOSED_IN_EMPTY] THEN
10211 EQ_TAC THEN REWRITE_TAC[CLOSED_IN_PCROSS] THEN
10212 ASM_REWRITE_TAC[CLOSED_IN_INTER_CLOSURE; CLOSURE_PCROSS; INTER_PCROSS;
10213 PCROSS_EQ; PCROSS_EQ_EMPTY]);;
10215 let FRONTIER_PCROSS = prove
10216 (`!s:real^M->bool t:real^N->bool.
10217 frontier(s PCROSS t) = frontier s PCROSS closure t UNION
10218 closure s PCROSS frontier t`,
10219 REPEAT GEN_TAC THEN
10220 REWRITE_TAC[frontier; CLOSURE_PCROSS; INTERIOR_PCROSS; PCROSS_DIFF] THEN
10221 REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_DIFF; IN_UNION;
10222 PASTECART_IN_PCROSS] THEN
10225 (* ------------------------------------------------------------------------- *)
10226 (* Hence some useful properties follow quite easily. *)
10227 (* ------------------------------------------------------------------------- *)
10229 let CONNECTED_SCALING = prove
10230 (`!s:real^N->bool c. connected s ==> connected (IMAGE (\x. c % x) s)`,
10231 REPEAT STRIP_TAC THEN
10232 MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
10233 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
10234 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
10235 REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
10237 let CONNECTED_NEGATIONS = prove
10238 (`!s:real^N->bool. connected s ==> connected (IMAGE (--) s)`,
10239 REPEAT STRIP_TAC THEN
10240 MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
10241 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
10242 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
10243 REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
10245 let CONNECTED_SUMS = prove
10246 (`!s t:real^N->bool.
10247 connected s /\ connected t ==> connected {x + y | x IN s /\ y IN t}`,
10248 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CONNECTED_PCROSS) THEN
10249 DISCH_THEN(MP_TAC o ISPEC
10250 `\z. (fstcart z + sndcart z:real^N)` o
10251 MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] CONNECTED_CONTINUOUS_IMAGE)) THEN
10252 SIMP_TAC[CONTINUOUS_ON_ADD; LINEAR_CONTINUOUS_ON; LINEAR_FSTCART;
10253 LINEAR_SNDCART; PCROSS] THEN
10254 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
10255 REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM; EXISTS_PASTECART] THEN
10256 REWRITE_TAC[PASTECART_INJ; FSTCART_PASTECART; SNDCART_PASTECART] THEN
10259 let COMPACT_SCALING = prove
10260 (`!s:real^N->bool c. compact s ==> compact (IMAGE (\x. c % x) s)`,
10261 REPEAT STRIP_TAC THEN
10262 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
10263 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
10264 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
10265 REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
10267 let COMPACT_NEGATIONS = prove
10268 (`!s:real^N->bool. compact s ==> compact (IMAGE (--) s)`,
10269 REPEAT STRIP_TAC THEN
10270 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
10271 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
10272 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
10273 REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
10275 let COMPACT_SUMS = prove
10276 (`!s:real^N->bool t.
10277 compact s /\ compact t ==> compact {x + y | x IN s /\ y IN t}`,
10278 REPEAT STRIP_TAC THEN
10279 SUBGOAL_THEN `{x + y | x IN s /\ y IN t} =
10280 IMAGE (\z. fstcart z + sndcart z :real^N) (s PCROSS t)`
10282 [REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; PCROSS] THEN
10283 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
10284 ASM_MESON_TAC[FSTCART_PASTECART; SNDCART_PASTECART; PASTECART_FST_SND];
10286 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
10287 ASM_SIMP_TAC[COMPACT_PCROSS] THEN
10288 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
10289 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
10290 REWRITE_TAC[linear; FSTCART_ADD; FSTCART_CMUL; SNDCART_ADD;
10292 CONJ_TAC THEN VECTOR_ARITH_TAC);;
10294 let COMPACT_DIFFERENCES = prove
10295 (`!s:real^N->bool t.
10296 compact s /\ compact t ==> compact {x - y | x IN s /\ y IN t}`,
10297 REPEAT STRIP_TAC THEN
10298 SUBGOAL_THEN `{x - y | x:real^N IN s /\ y IN t} =
10299 {x + y | x IN s /\ y IN (IMAGE (--) t)}`
10300 (fun th -> ASM_SIMP_TAC[th; COMPACT_SUMS; COMPACT_NEGATIONS]) THEN
10301 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE] THEN
10302 ONCE_REWRITE_TAC[VECTOR_ARITH `(x:real^N = --y) <=> (y = --x)`] THEN
10303 SIMP_TAC[VECTOR_SUB; GSYM CONJ_ASSOC; UNWIND_THM2] THEN
10304 MESON_TAC[VECTOR_NEG_NEG]);;
10306 let COMPACT_AFFINITY = prove
10308 compact s ==> compact (IMAGE (\x. a + c % x) s)`,
10309 REPEAT STRIP_TAC THEN
10310 SUBGOAL_THEN `(\x:real^N. a + c % x) = (\x. a + x) o (\x. c % x)`
10311 SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
10312 ASM_SIMP_TAC[IMAGE_o; COMPACT_TRANSLATION; COMPACT_SCALING]);;
10314 (* ------------------------------------------------------------------------- *)
10315 (* Hence we get the following. *)
10316 (* ------------------------------------------------------------------------- *)
10318 let COMPACT_SUP_MAXDISTANCE = prove
10320 compact s /\ ~(s = {})
10321 ==> ?x y. x IN s /\ y IN s /\
10322 !u v. u IN s /\ v IN s ==> norm(u - v) <= norm(x - y)`,
10323 REPEAT STRIP_TAC THEN
10324 MP_TAC(ISPECL [`{x - y:real^N | x IN s /\ y IN s}`; `vec 0:real^N`]
10325 DISTANCE_ATTAINS_SUP) THEN
10327 [ASM_SIMP_TAC[COMPACT_DIFFERENCES] THEN
10328 REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN
10329 ASM_MESON_TAC[MEMBER_NOT_EMPTY];
10330 REWRITE_TAC[IN_ELIM_THM; dist; VECTOR_SUB_RZERO; VECTOR_SUB_LZERO;
10334 (* ------------------------------------------------------------------------- *)
10335 (* We can state this in terms of diameter of a set. *)
10336 (* ------------------------------------------------------------------------- *)
10338 let diameter = new_definition
10341 else sup {norm(x - y) | x IN s /\ y IN s}`;;
10343 let DIAMETER_BOUNDED = prove
10345 ==> (!x:real^N y. x IN s /\ y IN s ==> norm(x - y) <= diameter s) /\
10346 (!d. &0 <= d /\ d < diameter s
10347 ==> ?x y. x IN s /\ y IN s /\ norm(x - y) > d)`,
10348 GEN_TAC THEN DISCH_TAC THEN
10349 ASM_CASES_TAC `s:real^N->bool = {}` THEN
10350 ASM_REWRITE_TAC[diameter; NOT_IN_EMPTY; REAL_LET_ANTISYM] THEN
10351 MP_TAC(SPEC `{norm(x - y:real^N) | x IN s /\ y IN s}` SUP) THEN
10352 ABBREV_TAC `b = sup {norm(x - y:real^N) | x IN s /\ y IN s}` THEN
10353 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
10354 REWRITE_TAC[NOT_IN_EMPTY; real_gt] THEN ANTS_TAC THENL
10355 [CONJ_TAC THENL [ASM_MESON_TAC[MEMBER_NOT_EMPTY]; ALL_TAC];
10356 MESON_TAC[REAL_NOT_LE]] THEN
10357 SIMP_TAC[VECTOR_SUB; LEFT_IMP_EXISTS_THM] THEN
10358 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
10359 MESON_TAC[REAL_ARITH `x <= y + z /\ y <= b /\ z<= b ==> x <= b + b`;
10360 NORM_TRIANGLE; NORM_NEG]);;
10362 let DIAMETER_BOUNDED_BOUND = prove
10363 (`!s x y. bounded s /\ x IN s /\ y IN s ==> norm(x - y) <= diameter s`,
10364 MESON_TAC[DIAMETER_BOUNDED]);;
10366 let DIAMETER_COMPACT_ATTAINED = prove
10368 compact s /\ ~(s = {})
10369 ==> ?x y. x IN s /\ y IN s /\ (norm(x - y) = diameter s)`,
10370 GEN_TAC THEN DISCH_TAC THEN
10371 FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_SUP_MAXDISTANCE) THEN
10372 REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
10373 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
10374 MP_TAC(SPEC `s:real^N->bool` DIAMETER_BOUNDED) THEN
10375 RULE_ASSUM_TAC(REWRITE_RULE[COMPACT_EQ_BOUNDED_CLOSED]) THEN
10376 ASM_REWRITE_TAC[real_gt] THEN STRIP_TAC THEN
10377 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
10378 ASM_MESON_TAC[NORM_POS_LE; REAL_NOT_LT]);;
10380 let DIAMETER_TRANSLATION = prove
10381 (`!a s. diameter (IMAGE (\x. a + x) s) = diameter s`,
10382 REWRITE_TAC[diameter] THEN GEOM_TRANSLATE_TAC[]);;
10384 add_translation_invariants [DIAMETER_TRANSLATION];;
10386 let DIAMETER_LINEAR_IMAGE = prove
10387 (`!f:real^M->real^N s.
10388 linear f /\ (!x. norm(f x) = norm x)
10389 ==> diameter(IMAGE f s) = diameter s`,
10390 REWRITE_TAC[diameter] THEN
10391 REPEAT STRIP_TAC THEN REWRITE_TAC[diameter; IMAGE_EQ_EMPTY] THEN
10392 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN
10393 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
10394 REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM; EXISTS_IN_IMAGE] THEN
10395 ASM_MESON_TAC[LINEAR_SUB]);;
10397 add_linear_invariants [DIAMETER_LINEAR_IMAGE];;
10399 let DIAMETER_EMPTY = prove
10400 (`diameter {} = &0`,
10401 REWRITE_TAC[diameter]);;
10403 let DIAMETER_SING = prove
10404 (`!a. diameter {a} = &0`,
10405 REWRITE_TAC[diameter; NOT_INSERT_EMPTY; IN_SING] THEN
10406 REWRITE_TAC[SET_RULE `{f x y | x = a /\ y = a} = {f a a }`] THEN
10407 REWRITE_TAC[SUP_SING; VECTOR_SUB_REFL; NORM_0]);;
10409 let DIAMETER_POS_LE = prove
10410 (`!s:real^N->bool. bounded s ==> &0 <= diameter s`,
10411 REPEAT STRIP_TAC THEN REWRITE_TAC[diameter] THEN
10412 COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN
10413 MP_TAC(SPEC `{norm(x - y:real^N) | x IN s /\ y IN s}` SUP) THEN
10414 REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL
10415 [CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
10416 FIRST_X_ASSUM(X_CHOOSE_TAC `B:real` o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
10417 EXISTS_TAC `&2 * B` THEN
10418 ASM_SIMP_TAC[NORM_ARITH
10419 `norm x <= B /\ norm y <= B ==> norm(x - y) <= &2 * B`];
10420 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
10421 DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN
10422 DISCH_THEN(MP_TAC o SPECL [`a:real^N`; `a:real^N`] o CONJUNCT1) THEN
10423 ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0]]);;
10425 let DIAMETER_SUBSET = prove
10426 (`!s t:real^N->bool. s SUBSET t /\ bounded t ==> diameter s <= diameter t`,
10427 REPEAT STRIP_TAC THEN
10428 ASM_CASES_TAC `s:real^N->bool = {}` THEN
10429 ASM_SIMP_TAC[DIAMETER_EMPTY; DIAMETER_POS_LE] THEN
10430 ASM_REWRITE_TAC[diameter] THEN
10431 COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
10432 MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN
10433 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
10434 REWRITE_TAC[FORALL_IN_GSPEC] THEN
10435 FIRST_X_ASSUM(X_CHOOSE_TAC `B:real` o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
10436 EXISTS_TAC `&2 * B` THEN
10437 ASM_SIMP_TAC[NORM_ARITH
10438 `norm x <= B /\ norm y <= B ==> norm(x - y) <= &2 * B`]);;
10440 let DIAMETER_CLOSURE = prove
10441 (`!s:real^N->bool. bounded s ==> diameter(closure s) = diameter s`,
10442 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN REPEAT STRIP_TAC THEN
10443 ASM_SIMP_TAC[DIAMETER_SUBSET; BOUNDED_CLOSURE; CLOSURE_SUBSET] THEN
10444 REWRITE_TAC[GSYM REAL_NOT_LT] THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN
10445 DISCH_TAC THEN MP_TAC(ISPEC `closure s:real^N->bool` DIAMETER_BOUNDED) THEN
10446 ABBREV_TAC `d = diameter(closure s) - diameter(s:real^N->bool)` THEN
10447 ASM_SIMP_TAC[BOUNDED_CLOSURE] THEN DISCH_THEN(MP_TAC o
10448 SPEC `diameter(closure(s:real^N->bool)) - d / &2` o CONJUNCT2) THEN
10449 REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC; NOT_EXISTS_THM] THEN
10450 FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIAMETER_POS_LE) THEN
10451 REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
10452 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN
10453 REWRITE_TAC[CLOSURE_APPROACHABLE; CONJ_ASSOC; AND_FORALL_THM] THEN
10454 DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `d / &4`) ASSUME_TAC) THEN
10455 ASM_REWRITE_TAC[REAL_ARITH `&0 < d / &4 <=> &0 < d`] THEN
10456 DISCH_THEN(CONJUNCTS_THEN2
10457 (X_CHOOSE_THEN `u:real^N` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC))
10458 (X_CHOOSE_THEN `v:real^N` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC))) THEN
10459 FIRST_ASSUM(MP_TAC o MATCH_MP DIAMETER_BOUNDED) THEN
10460 DISCH_THEN(MP_TAC o SPECL [`u:real^N`; `v:real^N`] o CONJUNCT1) THEN
10461 ASM_REWRITE_TAC[] THEN REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC);;
10463 let DIAMETER_SUBSET_CBALL_NONEMPTY = prove
10465 bounded s /\ ~(s = {}) ==> ?z. z IN s /\ s SUBSET cball(z,diameter s)`,
10466 REPEAT STRIP_TAC THEN
10467 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
10468 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN
10469 DISCH_TAC THEN ASM_REWRITE_TAC[SUBSET] THEN X_GEN_TAC `b:real^N` THEN
10470 DISCH_TAC THEN REWRITE_TAC[IN_CBALL; dist] THEN
10471 ASM_MESON_TAC[DIAMETER_BOUNDED]);;
10473 let DIAMETER_SUBSET_CBALL = prove
10474 (`!s:real^N->bool. bounded s ==> ?z. s SUBSET cball(z,diameter s)`,
10475 REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN
10476 ASM_MESON_TAC[DIAMETER_SUBSET_CBALL_NONEMPTY; EMPTY_SUBSET]);;
10478 let DIAMETER_EQ_0 = prove
10480 bounded s ==> (diameter s = &0 <=> s = {} \/ ?a. s = {a})`,
10481 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THEN
10482 ASM_REWRITE_TAC[DIAMETER_EMPTY; DIAMETER_SING] THEN
10483 REWRITE_TAC[SET_RULE
10484 `s = {} \/ (?a. s = {a}) <=> !a b. a IN s /\ b IN s ==> a = b`] THEN
10485 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN STRIP_TAC THEN
10486 MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`; `b:real^N`]
10487 DIAMETER_BOUNDED_BOUND) THEN
10488 ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);;
10490 let DIAMETER_LE = prove
10492 (~(s = {}) \/ &0 <= d) /\
10493 (!x y. x IN s /\ y IN s ==> norm(x - y) <= d) ==> diameter s <= d`,
10494 GEN_TAC THEN REWRITE_TAC[diameter] THEN
10495 COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN
10496 STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_LE THEN
10497 CONJ_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[FORALL_IN_GSPEC]]);;
10499 let DIAMETER_CBALL = prove
10500 (`!a:real^N r. diameter(cball(a,r)) = if r < &0 then &0 else &2 * r`,
10501 REPEAT GEN_TAC THEN COND_CASES_TAC THENL
10502 [ASM_MESON_TAC[CBALL_EQ_EMPTY; DIAMETER_EMPTY]; ALL_TAC] THEN
10503 RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LT]) THEN
10504 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
10505 [MATCH_MP_TAC DIAMETER_LE THEN
10506 ASM_SIMP_TAC[CBALL_EQ_EMPTY; REAL_LE_MUL; REAL_POS; REAL_NOT_LT] THEN
10507 REWRITE_TAC[IN_CBALL] THEN NORM_ARITH_TAC;
10508 MATCH_MP_TAC REAL_LE_TRANS THEN
10509 EXISTS_TAC `norm((a + r % basis 1) - (a - r % basis 1):real^N)` THEN
10511 [REWRITE_TAC[VECTOR_ARITH `(a + r % b) - (a - r % b:real^N) =
10512 (&2 * r) % b`] THEN
10513 SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN
10514 ASM_REAL_ARITH_TAC;
10515 MATCH_MP_TAC DIAMETER_BOUNDED_BOUND THEN
10516 REWRITE_TAC[BOUNDED_CBALL; IN_CBALL] THEN
10517 REWRITE_TAC[NORM_ARITH
10518 `dist(a:real^N,a + b) = norm b /\ dist(a,a - b) = norm b`] THEN
10519 SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN
10520 ASM_REAL_ARITH_TAC]]);;
10522 let DIAMETER_BALL = prove
10523 (`!a:real^N r. diameter(ball(a,r)) = if r < &0 then &0 else &2 * r`,
10524 REPEAT GEN_TAC THEN COND_CASES_TAC THENL
10525 [ASM_SIMP_TAC[BALL_EMPTY; REAL_LT_IMP_LE; DIAMETER_EMPTY]; ALL_TAC] THEN
10526 ASM_CASES_TAC `r = &0` THEN
10527 ASM_SIMP_TAC[BALL_EMPTY; REAL_LE_REFL; DIAMETER_EMPTY; REAL_MUL_RZERO] THEN
10528 MATCH_MP_TAC EQ_TRANS THEN
10529 EXISTS_TAC `diameter(cball(a:real^N,r))` THEN CONJ_TAC THENL
10530 [SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
10531 ASM_SIMP_TAC[GSYM CLOSURE_BALL; DIAMETER_CLOSURE; BOUNDED_BALL];
10532 ASM_SIMP_TAC[DIAMETER_CBALL]]);;
10534 let DIAMETER_SUMS = prove
10535 (`!s t:real^N->bool.
10536 bounded s /\ bounded t
10537 ==> diameter {x + y | x IN s /\ y IN t} <= diameter s + diameter t`,
10538 REPEAT STRIP_TAC THEN
10539 ASM_CASES_TAC `s:real^N->bool = {}` THEN
10540 ASM_SIMP_TAC[NOT_IN_EMPTY; SET_RULE `{f x y |x,y| F} = {}`;
10541 DIAMETER_EMPTY; REAL_ADD_LID; DIAMETER_POS_LE] THEN
10542 ASM_CASES_TAC `t:real^N->bool = {}` THEN
10543 ASM_SIMP_TAC[NOT_IN_EMPTY; SET_RULE `{f x y |x,y| F} = {}`;
10544 DIAMETER_EMPTY; REAL_ADD_RID; DIAMETER_POS_LE] THEN
10545 MATCH_MP_TAC DIAMETER_LE THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
10546 REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_GSPEC] THEN
10547 REPEAT STRIP_TAC THEN MATCH_MP_TAC(NORM_ARITH
10548 `norm(x - x') <= s /\ norm(y - y') <= t
10549 ==> norm((x + y) - (x' + y'):real^N) <= s + t`) THEN
10550 ASM_SIMP_TAC[DIAMETER_BOUNDED_BOUND]);;
10552 let LEBESGUE_COVERING_LEMMA = prove
10553 (`!s:real^N->bool c.
10554 compact s /\ ~(c = {}) /\ s SUBSET UNIONS c /\ (!b. b IN c ==> open b)
10556 !t. t SUBSET s /\ diameter t <= d
10557 ==> ?b. b IN c /\ t SUBSET b`,
10558 REPEAT STRIP_TAC THEN
10559 FIRST_ASSUM(MP_TAC o MATCH_MP HEINE_BOREL_LEMMA) THEN
10560 DISCH_THEN(MP_TAC o SPEC `c:(real^N->bool)->bool`) THEN ASM_SIMP_TAC[] THEN
10561 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `e:real` THEN
10562 STRIP_TAC THEN EXISTS_TAC `e / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN
10563 X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN
10564 ASM_CASES_TAC `t:real^N->bool = {}` THENL [ASM SET_TAC[]; ALL_TAC] THEN
10565 MP_TAC(ISPEC `t:real^N->bool` DIAMETER_SUBSET_CBALL_NONEMPTY) THEN
10567 [ASM_MESON_TAC[BOUNDED_SUBSET; COMPACT_IMP_BOUNDED]; ALL_TAC] THEN
10568 DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN
10569 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
10570 ANTS_TAC THENL [ASM SET_TAC[]; MATCH_MP_TAC MONO_EXISTS] THEN
10571 X_GEN_TAC `b:real^N->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
10572 MATCH_MP_TAC SUBSET_TRANS THEN
10573 EXISTS_TAC `cball(x:real^N,diameter(t:real^N->bool))` THEN
10574 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN
10575 EXISTS_TAC `ball(x:real^N,e)` THEN ASM_REWRITE_TAC[] THEN
10576 REWRITE_TAC[SUBSET; IN_CBALL; IN_BALL] THEN
10577 MAP_EVERY UNDISCH_TAC [`&0 < e`; `diameter(t:real^N->bool) <= e / &2`] THEN
10580 (* ------------------------------------------------------------------------- *)
10581 (* Related results with closure as the conclusion. *)
10582 (* ------------------------------------------------------------------------- *)
10584 let CLOSED_SCALING = prove
10585 (`!s:real^N->bool c. closed s ==> closed (IMAGE (\x. c % x) s)`,
10586 REPEAT GEN_TAC THEN
10587 ASM_CASES_TAC `s :real^N->bool = {}` THEN
10588 ASM_REWRITE_TAC[CLOSED_EMPTY; IMAGE_CLAUSES] THEN
10589 ASM_CASES_TAC `c = &0` THENL
10590 [SUBGOAL_THEN `IMAGE (\x:real^N. c % x) s = {(vec 0)}`
10591 (fun th -> REWRITE_TAC[th; CLOSED_SING]) THEN
10592 ASM_REWRITE_TAC[EXTENSION; IN_IMAGE; IN_SING; VECTOR_MUL_LZERO] THEN
10593 ASM_MESON_TAC[MEMBER_NOT_EMPTY];
10595 REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS; IN_IMAGE; SKOLEM_THM] THEN
10596 STRIP_TAC THEN X_GEN_TAC `x:num->real^N` THEN X_GEN_TAC `l:real^N` THEN
10597 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
10598 DISCH_THEN(X_CHOOSE_THEN `y:num->real^N` MP_TAC) THEN
10599 REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN
10600 EXISTS_TAC `inv(c) % l :real^N` THEN
10601 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; VECTOR_MUL_LID] THEN
10602 FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `\n:num. inv(c) % x n:real^N` THEN
10603 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
10604 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID];
10605 MATCH_MP_TAC LIM_CMUL THEN
10606 FIRST_ASSUM(fun th -> REWRITE_TAC[SYM(SPEC_ALL th)]) THEN
10607 ASM_REWRITE_TAC[ETA_AX]]);;
10609 let CLOSED_NEGATIONS = prove
10610 (`!s:real^N->bool. closed s ==> closed (IMAGE (--) s)`,
10611 REPEAT GEN_TAC THEN
10612 SUBGOAL_THEN `IMAGE (--) s = IMAGE (\x:real^N. --(&1) % x) s`
10613 SUBST1_TAC THEN SIMP_TAC[CLOSED_SCALING] THEN
10614 REWRITE_TAC[VECTOR_ARITH `--(&1) % x = --x`] THEN REWRITE_TAC[ETA_AX]);;
10616 let COMPACT_CLOSED_SUMS = prove
10617 (`!s:real^N->bool t.
10618 compact s /\ closed t ==> closed {x + y | x IN s /\ y IN t}`,
10619 REPEAT GEN_TAC THEN
10620 REWRITE_TAC[compact; IN_ELIM_THM; CLOSED_SEQUENTIAL_LIMITS] THEN
10621 STRIP_TAC THEN X_GEN_TAC `f:num->real^N` THEN X_GEN_TAC `l:real^N` THEN
10622 REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM] THEN
10623 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
10624 DISCH_THEN(X_CHOOSE_THEN `a:num->real^N` MP_TAC) THEN
10625 DISCH_THEN(X_CHOOSE_THEN `b:num->real^N` STRIP_ASSUME_TAC) THEN
10626 FIRST_X_ASSUM(MP_TAC o check(is_imp o concl) o SPEC `a:num->real^N`) THEN
10627 ASM_REWRITE_TAC[] THEN
10628 DISCH_THEN(X_CHOOSE_THEN `la:real^N` (X_CHOOSE_THEN `sub:num->num`
10629 STRIP_ASSUME_TAC)) THEN
10630 MAP_EVERY EXISTS_TAC [`la:real^N`; `l - la:real^N`] THEN
10631 ASM_REWRITE_TAC[VECTOR_ARITH `a + (b - a) = b:real^N`] THEN
10632 FIRST_X_ASSUM MATCH_MP_TAC THEN
10633 EXISTS_TAC `\n. (f o (sub:num->num)) n - (a o sub) n:real^N` THEN
10634 CONJ_TAC THENL [ASM_REWRITE_TAC[VECTOR_ADD_SUB; o_THM]; ALL_TAC] THEN
10635 MATCH_MP_TAC LIM_SUB THEN ASM_SIMP_TAC[LIM_SUBSEQUENCE; ETA_AX]);;
10637 let CLOSED_COMPACT_SUMS = prove
10638 (`!s:real^N->bool t.
10639 closed s /\ compact t ==> closed {x + y | x IN s /\ y IN t}`,
10640 REPEAT GEN_TAC THEN
10641 SUBGOAL_THEN `{x + y:real^N | x IN s /\ y IN t} = {y + x | y IN t /\ x IN s}`
10642 SUBST1_TAC THEN SIMP_TAC[COMPACT_CLOSED_SUMS] THEN
10643 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN MESON_TAC[VECTOR_ADD_SYM]);;
10645 let CLOSURE_SUMS = prove
10646 (`!s t:real^N->bool.
10647 bounded s \/ bounded t
10648 ==> closure {x + y | x IN s /\ y IN t} =
10649 {x + y | x IN closure s /\ y IN closure t}`,
10650 REWRITE_TAC[TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN
10651 REWRITE_TAC[FORALL_AND_THM] THEN
10652 GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SUMS_SYM] THEN
10653 MATCH_MP_TAC(TAUT `(p ==> q) /\ p ==> p /\ q`) THEN
10655 REPEAT STRIP_TAC THEN REWRITE_TAC[EXTENSION; CLOSURE_SEQUENTIAL] THEN
10656 X_GEN_TAC `z:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN EQ_TAC THENL
10657 [REWRITE_TAC[IN_ELIM_THM; IN_DELETE; SKOLEM_THM; LEFT_AND_EXISTS_THM] THEN
10658 REWRITE_TAC[FORALL_AND_THM] THEN
10659 ONCE_REWRITE_TAC[TAUT `(p /\ q) /\ r <=> q /\ p /\ r`] THEN
10660 ONCE_REWRITE_TAC[MESON[] `(?f x y. P f x y) <=> (?x y f. P f x y)`] THEN
10661 ONCE_REWRITE_TAC[GSYM FUN_EQ_THM] THEN
10662 REWRITE_TAC[ETA_AX; UNWIND_THM2] THEN
10663 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
10664 MAP_EVERY X_GEN_TAC [`a:num->real^N`; `b:num->real^N`] THEN
10666 MP_TAC(ISPEC `closure s:real^N->bool` compact) THEN
10667 ASM_REWRITE_TAC[COMPACT_CLOSURE] THEN
10668 DISCH_THEN(MP_TAC o SPEC `a:num->real^N`) THEN
10669 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET; LEFT_IMP_EXISTS_THM] THEN
10670 MAP_EVERY X_GEN_TAC [`u:real^N`; `r:num->num`] THEN STRIP_TAC THEN
10671 EXISTS_TAC `z - u:real^N` THEN
10672 EXISTS_TAC `(a:num->real^N) o (r:num->num)` THEN EXISTS_TAC `u:real^N` THEN
10673 ASM_REWRITE_TAC[o_THM] THEN
10674 CONJ_TAC THENL [ALL_TAC; VECTOR_ARITH_TAC] THEN
10675 EXISTS_TAC `(\n. ((\n. a n + b n) o (r:num->num)) n - (a o r) n)
10678 [ASM_REWRITE_TAC[o_DEF; VECTOR_ARITH `(a + b) - a:real^N = b`];
10679 MATCH_MP_TAC LIM_SUB THEN ASM_REWRITE_TAC[ETA_AX] THEN
10680 MATCH_MP_TAC LIM_SUBSEQUENCE THEN ASM_REWRITE_TAC[]];
10681 REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN
10682 REWRITE_TAC[LEFT_IMP_EXISTS_THM; LEFT_AND_EXISTS_THM;
10683 RIGHT_AND_EXISTS_THM] THEN
10684 MAP_EVERY X_GEN_TAC
10685 [`x:real^N`; `y:real^N`; `a:num->real^N`; `b:num->real^N`] THEN
10686 STRIP_TAC THEN EXISTS_TAC `(\n. a n + b n):num->real^N` THEN
10687 ASM_SIMP_TAC[LIM_ADD] THEN ASM_MESON_TAC[]]);;
10689 let COMPACT_CLOSED_DIFFERENCES = prove
10690 (`!s:real^N->bool t.
10691 compact s /\ closed t ==> closed {x - y | x IN s /\ y IN t}`,
10692 REPEAT STRIP_TAC THEN
10693 SUBGOAL_THEN `{x - y | x:real^N IN s /\ y IN t} =
10694 {x + y | x IN s /\ y IN (IMAGE (--) t)}`
10695 (fun th -> ASM_SIMP_TAC[th; COMPACT_CLOSED_SUMS; CLOSED_NEGATIONS]) THEN
10696 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE] THEN
10697 ONCE_REWRITE_TAC[VECTOR_ARITH `(x:real^N = --y) <=> (y = --x)`] THEN
10698 SIMP_TAC[VECTOR_SUB; GSYM CONJ_ASSOC; UNWIND_THM2] THEN
10699 MESON_TAC[VECTOR_NEG_NEG]);;
10701 let CLOSED_COMPACT_DIFFERENCES = prove
10702 (`!s:real^N->bool t.
10703 closed s /\ compact t ==> closed {x - y | x IN s /\ y IN t}`,
10704 REPEAT STRIP_TAC THEN
10705 SUBGOAL_THEN `{x - y | x:real^N IN s /\ y IN t} =
10706 {x + y | x IN s /\ y IN (IMAGE (--) t)}`
10707 (fun th -> ASM_SIMP_TAC[th; CLOSED_COMPACT_SUMS; COMPACT_NEGATIONS]) THEN
10708 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE] THEN
10709 ONCE_REWRITE_TAC[VECTOR_ARITH `(x:real^N = --y) <=> (y = --x)`] THEN
10710 SIMP_TAC[VECTOR_SUB; GSYM CONJ_ASSOC; UNWIND_THM2] THEN
10711 MESON_TAC[VECTOR_NEG_NEG]);;
10713 let CLOSED_TRANSLATION_EQ = prove
10714 (`!a s. closed (IMAGE (\x:real^N. a + x) s) <=> closed s`,
10715 REWRITE_TAC[closed] THEN GEOM_TRANSLATE_TAC[]);;
10717 let CLOSED_TRANSLATION = prove
10718 (`!s a:real^N. closed s ==> closed (IMAGE (\x. a + x) s)`,
10719 REWRITE_TAC[CLOSED_TRANSLATION_EQ]);;
10721 add_translation_invariants [CLOSED_TRANSLATION_EQ];;
10723 let COMPLETE_TRANSLATION_EQ = prove
10724 (`!a s. complete(IMAGE (\x:real^N. a + x) s) <=> complete s`,
10725 REWRITE_TAC[COMPLETE_EQ_CLOSED; CLOSED_TRANSLATION_EQ]);;
10727 add_translation_invariants [COMPLETE_TRANSLATION_EQ];;
10729 let TRANSLATION_UNIV = prove
10730 (`!a. IMAGE (\x. a + x) (:real^N) = (:real^N)`,
10731 CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN GEOM_TRANSLATE_TAC[]);;
10733 let TRANSLATION_DIFF = prove
10734 (`!s t:real^N->bool.
10735 IMAGE (\x. a + x) (s DIFF t) =
10736 (IMAGE (\x. a + x) s) DIFF (IMAGE (\x. a + x) t)`,
10737 REWRITE_TAC[EXTENSION; IN_DIFF; IN_IMAGE] THEN
10738 ONCE_REWRITE_TAC[VECTOR_ARITH `x:real^N = a + y <=> y = x - a`] THEN
10739 REWRITE_TAC[UNWIND_THM2]);;
10741 let CLOSURE_TRANSLATION = prove
10742 (`!a s. closure(IMAGE (\x:real^N. a + x) s) = IMAGE (\x. a + x) (closure s)`,
10743 REWRITE_TAC[CLOSURE_INTERIOR] THEN GEOM_TRANSLATE_TAC[]);;
10745 add_translation_invariants [CLOSURE_TRANSLATION];;
10747 let FRONTIER_TRANSLATION = prove
10748 (`!a s. frontier(IMAGE (\x:real^N. a + x) s) = IMAGE (\x. a + x) (frontier s)`,
10749 REWRITE_TAC[frontier] THEN GEOM_TRANSLATE_TAC[]);;
10751 add_translation_invariants [FRONTIER_TRANSLATION];;
10753 (* ------------------------------------------------------------------------- *)
10754 (* Separation between points and sets. *)
10755 (* ------------------------------------------------------------------------- *)
10757 let SEPARATE_POINT_CLOSED = prove
10759 closed s /\ ~(a IN s)
10760 ==> ?d. &0 < d /\ !x. x IN s ==> d <= dist(a,x)`,
10761 REPEAT STRIP_TAC THEN
10762 ASM_CASES_TAC `s:real^N->bool = {}` THENL
10763 [EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY; REAL_LT_01];
10765 MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`] DISTANCE_ATTAINS_INF) THEN
10766 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `b:real^N` THEN
10767 STRIP_TAC THEN EXISTS_TAC `dist(a:real^N,b)` THEN
10768 ASM_MESON_TAC[DIST_POS_LT]);;
10770 let SEPARATE_COMPACT_CLOSED = prove
10771 (`!s t:real^N->bool.
10772 compact s /\ closed t /\ s INTER t = {}
10773 ==> ?d. &0 < d /\ !x y. x IN s /\ y IN t ==> d <= dist(x,y)`,
10774 REPEAT STRIP_TAC THEN
10775 MP_TAC(ISPECL [`{x - y:real^N | x IN s /\ y IN t}`; `vec 0:real^N`]
10776 SEPARATE_POINT_CLOSED) THEN
10777 ASM_SIMP_TAC[COMPACT_CLOSED_DIFFERENCES; IN_ELIM_THM] THEN
10778 REWRITE_TAC[VECTOR_ARITH `vec 0 = x - y <=> x = y`] THEN
10779 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
10780 MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[LEFT_IMP_EXISTS_THM] THEN
10781 MESON_TAC[NORM_ARITH `dist(vec 0,x - y) = dist(x,y)`]);;
10783 let SEPARATE_CLOSED_COMPACT = prove
10784 (`!s t:real^N->bool.
10785 closed s /\ compact t /\ s INTER t = {}
10786 ==> ?d. &0 < d /\ !x y. x IN s /\ y IN t ==> d <= dist(x,y)`,
10787 ONCE_REWRITE_TAC[DIST_SYM; INTER_COMM] THEN
10788 MESON_TAC[SEPARATE_COMPACT_CLOSED]);;
10790 (* ------------------------------------------------------------------------- *)
10791 (* Representing sets as the union of a chain of compact sets. *)
10792 (* ------------------------------------------------------------------------- *)
10794 let CLOSED_UNION_COMPACT_SUBSETS = prove
10796 ==> ?f:num->real^N->bool.
10797 (!n. compact(f n)) /\
10798 (!n. (f n) SUBSET s) /\
10799 (!n. (f n) SUBSET f(n + 1)) /\
10800 UNIONS {f n | n IN (:num)} = s /\
10801 (!k. compact k /\ k SUBSET s
10802 ==> ?N. !n. n >= N ==> k SUBSET (f n))`,
10803 REPEAT STRIP_TAC THEN
10804 EXISTS_TAC `\n. s INTER cball(vec 0:real^N,&n)` THEN
10805 ASM_SIMP_TAC[INTER_SUBSET; COMPACT_CBALL; CLOSED_INTER_COMPACT] THEN
10806 REPEAT CONJ_TAC THENL
10807 [GEN_TAC THEN MATCH_MP_TAC(SET_RULE
10808 `t SUBSET u ==> s INTER t SUBSET s INTER u`) THEN
10809 REWRITE_TAC[SUBSET_BALLS; DIST_REFL; GSYM REAL_OF_NUM_ADD] THEN
10811 REWRITE_TAC[EXTENSION; UNIONS_GSPEC; IN_ELIM_THM; IN_UNIV; IN_INTER] THEN
10812 X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_CBALL_0] THEN
10813 MESON_TAC[REAL_ARCH_SIMPLE];
10814 X_GEN_TAC `k:real^N->bool` THEN SIMP_TAC[SUBSET_INTER] THEN
10815 REPEAT STRIP_TAC THEN
10816 FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN DISCH_THEN
10817 (MP_TAC o SPEC `vec 0:real^N` o MATCH_MP BOUNDED_SUBSET_CBALL) THEN
10818 DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN
10819 MP_TAC(ISPEC `r:real` REAL_ARCH_SIMPLE) THEN MATCH_MP_TAC MONO_EXISTS THEN
10820 X_GEN_TAC `N:num` THEN REWRITE_TAC[GSYM REAL_OF_NUM_GE] THEN
10822 REPEAT STRIP_TAC THEN
10823 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
10824 SUBSET_TRANS)) THEN
10825 REWRITE_TAC[SUBSET_BALLS; DIST_REFL] THEN ASM_REAL_ARITH_TAC]);;
10827 let OPEN_UNION_COMPACT_SUBSETS = prove
10829 ==> ?f:num->real^N->bool.
10830 (!n. compact(f n)) /\
10831 (!n. (f n) SUBSET s) /\
10832 (!n. (f n) SUBSET interior(f(n + 1))) /\
10833 UNIONS {f n | n IN (:num)} = s /\
10834 (!k. compact k /\ k SUBSET s
10835 ==> ?N. !n. n >= N ==> k SUBSET (f n))`,
10836 GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL
10837 [DISCH_TAC THEN EXISTS_TAC `(\n. {}):num->real^N->bool` THEN
10838 ASM_SIMP_TAC[EMPTY_SUBSET; SUBSET_EMPTY; COMPACT_EMPTY] THEN
10839 REWRITE_TAC[EXTENSION; UNIONS_GSPEC; IN_ELIM_THM; NOT_IN_EMPTY];
10840 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
10841 DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN STRIP_TAC] THEN
10842 MATCH_MP_TAC(MESON[]
10843 `(!f. p1 f /\ p3 f /\ p4 f ==> p5 f) /\
10844 (?f. p1 f /\ p2 f /\ p3 f /\ (p2 f ==> p4 f))
10845 ==> ?f. p1 f /\ p2 f /\ p3 f /\ p4 f /\ p5 f`) THEN
10847 [X_GEN_TAC `f:num->real^N->bool` THEN STRIP_TAC THEN
10848 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
10849 X_GEN_TAC `k:real^N->bool` THEN STRIP_TAC THEN
10850 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL]) THEN
10851 DISCH_THEN(MP_TAC o SPEC `{interior(f n):real^N->bool | n IN (:num)}`) THEN
10852 REWRITE_TAC[FORALL_IN_GSPEC; OPEN_INTERIOR] THEN ANTS_TAC THENL
10853 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
10854 SUBSET_TRANS)) THEN
10855 REWRITE_TAC[SUBSET; UNIONS_GSPEC; IN_ELIM_THM] THEN ASM SET_TAC[];
10856 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
10857 REWRITE_TAC[SIMPLE_IMAGE; EXISTS_FINITE_SUBSET_IMAGE] THEN
10858 REWRITE_TAC[SUBSET_UNIV] THEN
10859 DISCH_THEN(X_CHOOSE_THEN `i:num->bool` STRIP_ASSUME_TAC) THEN
10860 FIRST_ASSUM(MP_TAC o SPEC `\n:num. n` o
10861 MATCH_MP UPPER_BOUND_FINITE_SET) THEN
10862 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
10863 REWRITE_TAC[GE] THEN DISCH_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10864 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
10865 SUBSET_TRANS)) THEN
10866 REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_IMAGE] THEN
10867 X_GEN_TAC `m:num` THEN DISCH_TAC THEN MATCH_MP_TAC SUBSET_TRANS THEN
10868 EXISTS_TAC `(f:num->real^N->bool) m` THEN
10869 REWRITE_TAC[INTERIOR_SUBSET] THEN
10870 SUBGOAL_THEN `!m n. m <= n ==> (f:num->real^N->bool) m SUBSET f n`
10871 (fun th -> ASM_MESON_TAC[th; LE_TRANS]) THEN
10872 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
10873 ASM_MESON_TAC[SUBSET; ADD1; INTERIOR_SUBSET]];
10875 `\n. cball(a,&n) DIFF
10876 {x + e | x IN (:real^N) DIFF s /\ e IN ball(vec 0,inv(&n + &1))}` THEN
10877 REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
10878 [X_GEN_TAC `n:num` THEN MATCH_MP_TAC COMPACT_DIFF THEN
10879 SIMP_TAC[COMPACT_CBALL; OPEN_SUMS; OPEN_BALL];
10880 GEN_TAC THEN MATCH_MP_TAC(SET_RULE
10881 `(UNIV DIFF s) SUBSET t ==> c DIFF t SUBSET s`) THEN
10882 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
10883 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
10884 MAP_EVERY EXISTS_TAC [`x:real^N`; `vec 0:real^N`] THEN
10885 ASM_REWRITE_TAC[VECTOR_ADD_RID; CENTRE_IN_BALL; REAL_LT_INV_EQ] THEN
10887 GEN_TAC THEN REWRITE_TAC[INTERIOR_DIFF] THEN MATCH_MP_TAC(SET_RULE
10888 `s SUBSET s' /\ t' SUBSET t ==> (s DIFF t) SUBSET (s' DIFF t')`) THEN
10890 [REWRITE_TAC[INTERIOR_CBALL; SUBSET; IN_BALL; IN_CBALL] THEN
10891 REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC;
10892 MATCH_MP_TAC SUBSET_TRANS THEN
10893 EXISTS_TAC `{x + e | x IN (:real^N) DIFF s /\
10894 e IN cball(vec 0,inv(&n + &2))}` THEN
10896 [MATCH_MP_TAC CLOSURE_MINIMAL THEN
10897 ASM_SIMP_TAC[CLOSED_COMPACT_SUMS; COMPACT_CBALL;
10898 GSYM OPEN_CLOSED] THEN
10899 MATCH_MP_TAC(SET_RULE
10901 ==> {f x y | x IN s /\ y IN t} SUBSET
10902 {f x y | x IN s /\ y IN t'}`) THEN
10903 REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL; GSYM REAL_OF_NUM_ADD] THEN
10905 MATCH_MP_TAC(SET_RULE
10907 ==> {f x y | x IN s /\ y IN t} SUBSET
10908 {f x y | x IN s /\ y IN t'}`) THEN
10909 REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL; GSYM REAL_OF_NUM_ADD] THEN
10910 GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH
10911 `a < b ==> x <= a ==> x < b`) THEN
10912 MATCH_MP_TAC REAL_LT_INV2 THEN REAL_ARITH_TAC]];
10913 DISCH_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
10914 ASM_REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC] THEN
10915 REWRITE_TAC[SUBSET; UNIONS_GSPEC; IN_UNIV; IN_ELIM_THM] THEN
10916 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_DIFF] THEN
10917 REWRITE_TAC[IN_ELIM_THM; IN_UNIV; IN_BALL_0] THEN
10918 REWRITE_TAC[VECTOR_ARITH `x:real^N = y + e <=> e = x - y`] THEN
10919 REWRITE_TAC[TAUT `(p /\ q) /\ r <=> r /\ p /\ q`; UNWIND_THM2] THEN
10920 REWRITE_TAC[MESON[] `~(?x. ~P x /\ Q x) <=> !x. Q x ==> P x`] THEN
10921 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN
10922 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
10923 ASM_REWRITE_TAC[SUBSET; IN_BALL; dist] THEN
10924 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
10925 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN
10926 DISCH_THEN(X_CHOOSE_THEN `N1:num` STRIP_ASSUME_TAC) THEN
10927 MP_TAC(ISPEC `norm(x - a:real^N)` REAL_ARCH_SIMPLE) THEN
10928 DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN EXISTS_TAC `N1 + N2:num` THEN
10930 [REWRITE_TAC[IN_CBALL] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
10931 UNDISCH_TAC `norm(x - a:real^N) <= &N2` THEN
10932 REWRITE_TAC[dist; GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC;
10933 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
10934 SUBGOAL_THEN `inv(&(N1 + N2) + &1) <= inv(&N1)` MP_TAC THENL
10935 [MATCH_MP_TAC REAL_LE_INV2 THEN
10936 ASM_SIMP_TAC[REAL_OF_NUM_LT; LE_1] THEN
10937 REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC;
10938 ASM_REAL_ARITH_TAC]]]]);;
10940 (* ------------------------------------------------------------------------- *)
10941 (* Closed-graph characterization of continuity. *)
10942 (* ------------------------------------------------------------------------- *)
10944 let CONTINUOUS_CLOSED_GRAPH_GEN = prove
10945 (`!f:real^M->real^N s t.
10946 f continuous_on s /\ IMAGE f s SUBSET t
10947 ==> closed_in (subtopology euclidean (s PCROSS t))
10948 {pastecart x (f x) | x IN s}`,
10949 REPEAT STRIP_TAC THEN
10951 `{pastecart (x:real^M) (f x:real^N) | x IN s} =
10952 {z | z IN s PCROSS t /\ f(fstcart z) - sndcart z IN {vec 0}}`
10954 [REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_THM; IN_SING;
10955 PASTECART_IN_PCROSS; FSTCART_PASTECART; SNDCART_PASTECART;
10956 PASTECART_INJ; VECTOR_SUB_EQ] THEN
10958 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN
10959 REWRITE_TAC[CLOSED_SING] THEN MATCH_MP_TAC CONTINUOUS_ON_SUB THEN
10960 SIMP_TAC[GSYM o_DEF; LINEAR_CONTINUOUS_ON; LINEAR_SNDCART] THEN
10961 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
10962 SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; IMAGE_FSTCART_PCROSS] THEN
10963 ASM_MESON_TAC[CONTINUOUS_ON_EMPTY]]);;
10965 let CONTINUOUS_CLOSED_GRAPH_EQ = prove
10966 (`!f:real^M->real^N s t.
10967 compact t /\ IMAGE f s SUBSET t
10968 ==> (f continuous_on s <=>
10969 closed_in (subtopology euclidean (s PCROSS t))
10970 {pastecart x (f x) | x IN s})`,
10971 REPEAT STRIP_TAC THEN EQ_TAC THEN
10972 ASM_SIMP_TAC[CONTINUOUS_CLOSED_GRAPH_GEN] THEN DISCH_TAC THEN
10973 FIRST_ASSUM(fun th ->
10974 REWRITE_TAC[MATCH_MP CONTINUOUS_ON_CLOSED_GEN th]) THEN
10975 X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN
10977 `{x | x IN s /\ (f:real^M->real^N) x IN c} =
10978 IMAGE fstcart ({pastecart x (f x) | x IN s} INTER
10981 [REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM; EXISTS_PASTECART;
10982 FSTCART_PASTECART; IN_INTER; IN_ELIM_PASTECART_THM;
10983 PASTECART_IN_PCROSS; PASTECART_INJ] THEN
10985 MATCH_MP_TAC CLOSED_MAP_FSTCART THEN EXISTS_TAC `t:real^N->bool` THEN
10986 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CLOSED_IN_INTER THEN
10987 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CLOSED_IN_PCROSS THEN
10988 ASM_REWRITE_TAC[CLOSED_IN_REFL]]);;
10990 let CONTINUOUS_CLOSED_GRAPH = prove
10991 (`!f:real^M->real^N s.
10992 closed s /\ f continuous_on s ==> closed {pastecart x (f x) | x IN s}`,
10993 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSED_IN_CLOSED_TRANS THEN
10994 EXISTS_TAC `(s:real^M->bool) PCROSS (:real^N)` THEN
10995 ASM_SIMP_TAC[CLOSED_PCROSS; CLOSED_UNIV] THEN
10996 MATCH_MP_TAC CONTINUOUS_CLOSED_GRAPH_GEN THEN
10997 ASM_REWRITE_TAC[SUBSET_UNIV]);;
10999 let CONTINUOUS_FROM_CLOSED_GRAPH = prove
11000 (`!f:real^M->real^N s t.
11001 compact t /\ IMAGE f s SUBSET t /\
11002 closed {pastecart x (f x) | x IN s}
11003 ==> f continuous_on s`,
11004 REPEAT GEN_TAC THEN REWRITE_TAC[CONJ_ASSOC] THEN
11005 DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
11006 FIRST_ASSUM(SUBST1_TAC o MATCH_MP CONTINUOUS_CLOSED_GRAPH_EQ) THEN
11007 MATCH_MP_TAC CLOSED_SUBSET THEN ASM_REWRITE_TAC[] THEN
11008 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; PASTECART_IN_PCROSS] THEN
11011 (* ------------------------------------------------------------------------- *)
11012 (* A cute way of denoting open and closed intervals using overloading. *)
11013 (* ------------------------------------------------------------------------- *)
11015 let open_interval = new_definition
11016 `open_interval(a:real^N,b:real^N) =
11017 {x:real^N | !i. 1 <= i /\ i <= dimindex(:N)
11018 ==> a$i < x$i /\ x$i < b$i}`;;
11020 let closed_interval = new_definition
11021 `closed_interval(l:(real^N#real^N)list) =
11022 {x:real^N | !i. 1 <= i /\ i <= dimindex(:N)
11023 ==> FST(HD l)$i <= x$i /\ x$i <= SND(HD l)$i}`;;
11025 make_overloadable "interval" `:A`;;
11027 overload_interface("interval",`open_interval`);;
11028 overload_interface("interval",`closed_interval`);;
11030 let interval = prove
11031 (`(interval (a,b) = {x:real^N | !i. 1 <= i /\ i <= dimindex(:N)
11032 ==> a$i < x$i /\ x$i < b$i}) /\
11033 (interval [a,b] = {x:real^N | !i. 1 <= i /\ i <= dimindex(:N)
11034 ==> a$i <= x$i /\ x$i <= b$i})`,
11035 REWRITE_TAC[open_interval; closed_interval; HD; FST; SND]);;
11037 let IN_INTERVAL = prove
11039 x IN interval (a,b) <=>
11040 !i. 1 <= i /\ i <= dimindex(:N)
11041 ==> a$i < x$i /\ x$i < b$i) /\
11043 x IN interval [a,b] <=>
11044 !i. 1 <= i /\ i <= dimindex(:N)
11045 ==> a$i <= x$i /\ x$i <= b$i)`,
11046 REWRITE_TAC[interval; IN_ELIM_THM]);;
11048 let IN_INTERVAL_REFLECT = prove
11049 (`(!a b x. (--x) IN interval[--b,--a] <=> x IN interval[a,b]) /\
11050 (!a b x. (--x) IN interval(--b,--a) <=> x IN interval(a,b))`,
11051 SIMP_TAC[IN_INTERVAL; REAL_LT_NEG2; REAL_LE_NEG2; VECTOR_NEG_COMPONENT] THEN
11054 let REFLECT_INTERVAL = prove
11055 (`(!a b:real^N. IMAGE (--) (interval[a,b]) = interval[--b,--a]) /\
11056 (!a b:real^N. IMAGE (--) (interval(a,b)) = interval(--b,--a))`,
11057 REPEAT STRIP_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
11058 REWRITE_TAC[IN_INTERVAL_REFLECT] THEN MESON_TAC[VECTOR_NEG_NEG]);;
11060 let INTERVAL_EQ_EMPTY = prove
11061 (`((interval [a:real^N,b] = {}) <=>
11062 ?i. 1 <= i /\ i <= dimindex(:N) /\ b$i < a$i) /\
11063 ((interval (a:real^N,b) = {}) <=>
11064 ?i. 1 <= i /\ i <= dimindex(:N) /\ b$i <= a$i)`,
11065 REWRITE_TAC[EXTENSION; IN_INTERVAL; NOT_IN_EMPTY] THEN
11066 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; GSYM CONJ_ASSOC] THEN
11067 CONJ_TAC THEN EQ_TAC THENL
11068 [MESON_TAC[REAL_LE_REFL; REAL_NOT_LE];
11069 MESON_TAC[REAL_LE_TRANS; REAL_NOT_LE];
11071 MESON_TAC[REAL_LT_TRANS; REAL_NOT_LT]] THEN
11072 SUBGOAL_THEN `!a b. ?c. a < b ==> a < c /\ c < b`
11073 (MP_TAC o REWRITE_RULE[SKOLEM_THM]) THENL
11074 [MESON_TAC[REAL_LT_BETWEEN]; ALL_TAC] THEN
11075 DISCH_THEN(X_CHOOSE_TAC `mid:real->real->real`) THEN
11076 DISCH_THEN(MP_TAC o SPEC
11077 `(lambda i. mid ((a:real^N)$i) ((b:real^N)$i)):real^N`) THEN
11078 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> ~(a /\ b ==> ~c)`] THEN
11079 SIMP_TAC[LAMBDA_BETA] THEN ASM_MESON_TAC[REAL_NOT_LT]);;
11081 let INTERVAL_NE_EMPTY = prove
11082 (`(~(interval [a:real^N,b] = {}) <=>
11083 !i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= b$i) /\
11084 (~(interval (a:real^N,b) = {}) <=>
11085 !i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i)`,
11086 REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN MESON_TAC[REAL_NOT_LE]);;
11088 let SUBSET_INTERVAL_IMP = prove
11089 (`((!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i)
11090 ==> interval[c,d] SUBSET interval[a:real^N,b]) /\
11091 ((!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < c$i /\ d$i < b$i)
11092 ==> interval[c,d] SUBSET interval(a:real^N,b)) /\
11093 ((!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i)
11094 ==> interval(c,d) SUBSET interval[a:real^N,b]) /\
11095 ((!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i)
11096 ==> interval(c,d) SUBSET interval(a:real^N,b))`,
11097 REWRITE_TAC[SUBSET; IN_INTERVAL] THEN REPEAT CONJ_TAC THEN
11098 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM MP_TAC THEN
11099 REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN
11100 GEN_TAC THEN DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
11101 ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;
11103 let INTERVAL_SING = prove
11104 (`interval[a,a] = {a} /\ interval(a,a) = {}`,
11105 REWRITE_TAC[EXTENSION; IN_SING; NOT_IN_EMPTY; IN_INTERVAL] THEN
11106 REWRITE_TAC[REAL_LE_ANTISYM; REAL_LT_ANTISYM; CART_EQ; EQ_SYM_EQ] THEN
11107 MESON_TAC[DIMINDEX_GE_1; LE_REFL]);;
11109 let SUBSET_INTERVAL = prove
11110 (`(interval[c,d] SUBSET interval[a:real^N,b] <=>
11111 (!i. 1 <= i /\ i <= dimindex(:N) ==> c$i <= d$i)
11112 ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i)) /\
11113 (interval[c,d] SUBSET interval(a:real^N,b) <=>
11114 (!i. 1 <= i /\ i <= dimindex(:N) ==> c$i <= d$i)
11115 ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < c$i /\ d$i < b$i)) /\
11116 (interval(c,d) SUBSET interval[a:real^N,b] <=>
11117 (!i. 1 <= i /\ i <= dimindex(:N) ==> c$i < d$i)
11118 ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i)) /\
11119 (interval(c,d) SUBSET interval(a:real^N,b) <=>
11120 (!i. 1 <= i /\ i <= dimindex(:N) ==> c$i < d$i)
11121 ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i))`,
11123 (`(!x:real^N. (!i. 1 <= i /\ i <= dimindex(:N) ==> Q i (x$i))
11124 ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> R i (x$i)))
11125 ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> ?y. Q i y)
11126 ==> !i y. 1 <= i /\ i <= dimindex(:N) /\ Q i y ==> R i y`,
11127 DISCH_TAC THEN REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
11128 DISCH_THEN(X_CHOOSE_THEN `f:num->real` STRIP_ASSUME_TAC) THEN
11129 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o
11130 SPEC `(lambda j. if j = i then y else f j):real^N`) THEN
11131 SIMP_TAC[LAMBDA_BETA] THEN ASM_MESON_TAC[]) in
11132 REPEAT STRIP_TAC THEN
11134 `(~q ==> p) /\ (q ==> (p <=> r)) ==> (p <=> q ==> r)`) THEN
11136 [DISCH_TAC THEN MATCH_MP_TAC(SET_RULE `s = {} ==> s SUBSET t`) THEN
11137 REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN ASM_MESON_TAC[REAL_NOT_LT];
11139 DISCH_TAC THEN EQ_TAC THEN REWRITE_TAC[SUBSET_INTERVAL_IMP] THEN
11140 REWRITE_TAC[SUBSET; IN_INTERVAL] THEN
11141 DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN ANTS_TAC THENL
11142 [ASM_MESON_TAC[REAL_LT_BETWEEN; REAL_LE_BETWEEN]; ALL_TAC] THEN
11143 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN
11144 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
11145 FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
11146 ASM_REWRITE_TAC[] THEN POP_ASSUM_LIST(K ALL_TAC) THEN STRIP_TAC)
11148 [ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL];
11149 ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL];
11150 ALL_TAC; ALL_TAC] THEN
11151 (REPEAT STRIP_TAC THENL
11152 [FIRST_X_ASSUM(MP_TAC o SPEC
11153 `((c:real^N)$i + min ((a:real^N)$i) ((d:real^N)$i)) / &2`) THEN
11154 POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
11155 FIRST_X_ASSUM(MP_TAC o SPEC
11156 `(max ((b:real^N)$i) ((c:real^N)$i) + (d:real^N)$i) / &2`) THEN
11157 POP_ASSUM MP_TAC THEN REAL_ARITH_TAC]));;
11159 let DISJOINT_INTERVAL = prove
11161 (interval[a,b] INTER interval[c,d] = {} <=>
11162 ?i. 1 <= i /\ i <= dimindex(:N) /\
11163 (b$i < a$i \/ d$i < c$i \/ b$i < c$i \/ d$i < a$i)) /\
11164 (interval[a,b] INTER interval(c,d) = {} <=>
11165 ?i. 1 <= i /\ i <= dimindex(:N) /\
11166 (b$i < a$i \/ d$i <= c$i \/ b$i <= c$i \/ d$i <= a$i)) /\
11167 (interval(a,b) INTER interval[c,d] = {} <=>
11168 ?i. 1 <= i /\ i <= dimindex(:N) /\
11169 (b$i <= a$i \/ d$i < c$i \/ b$i <= c$i \/ d$i <= a$i)) /\
11170 (interval(a,b) INTER interval(c,d) = {} <=>
11171 ?i. 1 <= i /\ i <= dimindex(:N) /\
11172 (b$i <= a$i \/ d$i <= c$i \/ b$i <= c$i \/ d$i <= a$i))`,
11173 REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL; NOT_IN_EMPTY] THEN
11174 REWRITE_TAC[AND_FORALL_THM; NOT_FORALL_THM] THEN
11175 REWRITE_TAC[TAUT `~((p ==> q) /\ (p ==> r)) <=> p /\ (~q \/ ~r)`] THEN
11176 REWRITE_TAC[DE_MORGAN_THM] THEN REPEAT STRIP_TAC THEN
11178 [DISCH_THEN(MP_TAC o SPEC
11179 `(lambda i. (max ((a:real^N)$i) ((c:real^N)$i) +
11180 min ((b:real^N)$i) ((d:real^N)$i)) / &2):real^N`) THEN
11181 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
11182 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
11183 ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC;
11184 DISCH_THEN(fun th -> GEN_TAC THEN MP_TAC th) THEN
11185 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN SIMP_TAC[] THEN
11186 REAL_ARITH_TAC]));;
11188 let ENDS_IN_INTERVAL = prove
11189 (`(!a b. a IN interval[a,b] <=> ~(interval[a,b] = {})) /\
11190 (!a b. b IN interval[a,b] <=> ~(interval[a,b] = {})) /\
11191 (!a b. ~(a IN interval(a,b))) /\
11192 (!a b. ~(b IN interval(a,b)))`,
11193 REWRITE_TAC[IN_INTERVAL; INTERVAL_NE_EMPTY] THEN
11194 REWRITE_TAC[REAL_LE_REFL; REAL_LT_REFL] THEN
11195 MESON_TAC[DIMINDEX_GE_1; LE_REFL]);;
11197 let ENDS_IN_UNIT_INTERVAL = prove
11198 (`vec 0 IN interval[vec 0,vec 1] /\
11199 vec 1 IN interval[vec 0,vec 1] /\
11200 ~(vec 0 IN interval(vec 0,vec 1)) /\
11201 ~(vec 1 IN interval(vec 0,vec 1))`,
11202 REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY; VEC_COMPONENT] THEN
11203 REWRITE_TAC[REAL_POS]);;
11205 let INTER_INTERVAL = prove
11206 (`interval[a,b] INTER interval[c,d] =
11207 interval[(lambda i. max (a$i) (c$i)),(lambda i. min (b$i) (d$i))]`,
11208 REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL] THEN
11209 SIMP_TAC[LAMBDA_BETA; REAL_MAX_LE; REAL_LE_MIN] THEN MESON_TAC[]);;
11211 let INTERVAL_OPEN_SUBSET_CLOSED = prove
11212 (`!a b. interval(a,b) SUBSET interval[a,b]`,
11213 REWRITE_TAC[SUBSET; IN_INTERVAL] THEN MESON_TAC[REAL_LT_IMP_LE]);;
11215 let OPEN_INTERVAL_LEMMA = prove
11216 (`!a b x. a < x /\ x < b
11217 ==> ?d. &0 < d /\ !x'. abs(x' - x) < d ==> a < x' /\ x' < b`,
11218 REPEAT STRIP_TAC THEN
11219 EXISTS_TAC `min (x - a) (b - x)` THEN REWRITE_TAC[REAL_LT_MIN] THEN
11220 ASM_REAL_ARITH_TAC);;
11222 let OPEN_INTERVAL = prove
11223 (`!a:real^N b. open(interval (a,b))`,
11224 REPEAT GEN_TAC THEN REWRITE_TAC[open_def; interval; IN_ELIM_THM] THEN
11225 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
11226 SUBGOAL_THEN `!i. 1 <= i /\ i <= dimindex(:N)
11228 !x'. abs(x' - (x:real^N)$i) < d
11229 ==> (a:real^N)$i < x' /\ x' < (b:real^N)$i`
11230 MP_TAC THENL [ASM_SIMP_TAC[OPEN_INTERVAL_LEMMA]; ALL_TAC] THEN
11231 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
11232 REWRITE_TAC[SKOLEM_THM] THEN
11233 DISCH_THEN(X_CHOOSE_THEN `d:num->real` STRIP_ASSUME_TAC) THEN
11234 EXISTS_TAC `inf (IMAGE d (1..dimindex(:N)))` THEN
11235 SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; FINITE_NUMSEG;
11236 IMAGE_EQ_EMPTY; NOT_INSERT_EMPTY; NUMSEG_EMPTY;
11237 ARITH_RULE `n < 1 <=> (n = 0)`; DIMINDEX_NONZERO] THEN
11238 REWRITE_TAC[FORALL_IN_IMAGE; IN_NUMSEG; dist] THEN
11239 ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LET_TRANS; VECTOR_SUB_COMPONENT]);;
11241 let CLOSED_INTERVAL = prove
11242 (`!a:real^N b. closed(interval [a,b])`,
11243 REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE; IN_INTERVAL] THEN
11244 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THENL
11245 [FIRST_X_ASSUM(MP_TAC o SPEC `(a:real^N)$i - (x:real^N)$i`);
11246 FIRST_X_ASSUM(MP_TAC o SPEC `(x:real^N)$i - (b:real^N)$i`)] THEN
11247 ASM_REWRITE_TAC[REAL_SUB_LT] THEN
11248 DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN
11249 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
11250 REWRITE_TAC[dist; REAL_NOT_LT] THEN
11251 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((z - x :real^N)$i)` THEN
11252 ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
11253 ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
11254 ASM_SIMP_TAC[REAL_ARITH `x < a /\ a <= z ==> a - x <= abs(z - x)`;
11255 REAL_ARITH `z <= b /\ b < x ==> x - b <= abs(z - x)`]);;
11257 let INTERIOR_CLOSED_INTERVAL = prove
11258 (`!a:real^N b. interior(interval [a,b]) = interval (a,b)`,
11259 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
11261 MATCH_MP_TAC INTERIOR_MAXIMAL THEN
11262 REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED; OPEN_INTERVAL]] THEN
11263 REWRITE_TAC[interior; SUBSET; IN_INTERVAL; IN_ELIM_THM] THEN
11264 X_GEN_TAC `x:real^N` THEN
11265 DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN
11266 X_GEN_TAC `i:num` THEN STRIP_TAC THEN
11267 ASM_SIMP_TAC[REAL_LT_LE] THEN REPEAT STRIP_TAC THEN
11268 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [open_def]) THEN
11269 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
11270 DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THENL
11271 [(let t = `x - (e / &2) % basis i :real^N` in
11272 DISCH_THEN(MP_TAC o SPEC t) THEN FIRST_X_ASSUM(MP_TAC o SPEC t));
11273 (let t = `x + (e / &2) % basis i :real^N` in
11274 DISCH_THEN(MP_TAC o SPEC t) THEN FIRST_X_ASSUM(MP_TAC o SPEC t))] THEN
11275 REWRITE_TAC[dist; VECTOR_ADD_SUB; VECTOR_ARITH `x - y - x = --y:real^N`] THEN
11276 ASM_SIMP_TAC[NORM_MUL; NORM_BASIS; NORM_NEG; REAL_MUL_RID;
11277 REAL_ARITH `&0 < e ==> abs(e / &2) < e`] THEN
11278 MATCH_MP_TAC(TAUT `~b ==> (a ==> b) ==> ~a`) THEN
11279 REWRITE_TAC[NOT_FORALL_THM] THEN EXISTS_TAC `i:num` THEN
11280 ASM_SIMP_TAC[DE_MORGAN_THM; VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT] THENL
11281 [DISJ1_TAC THEN REWRITE_TAC[REAL_ARITH `a <= a - b <=> ~(&0 < b)`];
11282 DISJ2_TAC THEN REWRITE_TAC[REAL_ARITH `a + b <= a <=> ~(&0 < b)`]] THEN
11283 ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; basis; LAMBDA_BETA; REAL_MUL_RID] THEN
11284 ASM_REWRITE_TAC[REAL_HALF]);;
11286 let INTERIOR_INTERVAL = prove
11287 (`(!a b. interior(interval[a,b]) = interval(a,b)) /\
11288 (!a b. interior(interval(a,b)) = interval(a,b))`,
11289 SIMP_TAC[INTERIOR_CLOSED_INTERVAL; INTERIOR_OPEN; OPEN_INTERVAL]);;
11291 let BOUNDED_CLOSED_INTERVAL = prove
11292 (`!a b:real^N. bounded (interval [a,b])`,
11293 REPEAT STRIP_TAC THEN REWRITE_TAC[bounded; interval] THEN
11294 EXISTS_TAC `sum(1..dimindex(:N))
11295 (\i. abs((a:real^N)$i) + abs((b:real^N)$i))` THEN
11296 X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN
11297 STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
11298 EXISTS_TAC `sum(1..dimindex(:N)) (\i. abs((x:real^N)$i))` THEN
11299 REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_LE THEN
11300 ASM_SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; REAL_ARITH
11301 `a <= x /\ x <= b ==> abs(x) <= abs(a) + abs(b)`]);;
11303 let BOUNDED_INTERVAL = prove
11304 (`(!a b. bounded (interval [a,b])) /\ (!a b. bounded (interval (a,b)))`,
11305 MESON_TAC[BOUNDED_CLOSED_INTERVAL; BOUNDED_SUBSET;
11306 INTERVAL_OPEN_SUBSET_CLOSED]);;
11308 let NOT_INTERVAL_UNIV = prove
11309 (`(!a b. ~(interval[a,b] = UNIV)) /\
11310 (!a b. ~(interval(a,b) = UNIV))`,
11311 MESON_TAC[BOUNDED_INTERVAL; NOT_BOUNDED_UNIV]);;
11313 let COMPACT_INTERVAL = prove
11314 (`!a b. compact (interval [a,b])`,
11315 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_INTERVAL; CLOSED_INTERVAL]);;
11317 let OPEN_INTERVAL_MIDPOINT = prove
11319 ~(interval(a,b) = {}) ==> (inv(&2) % (a + b)) IN interval(a,b)`,
11320 REWRITE_TAC[INTERVAL_NE_EMPTY; IN_INTERVAL] THEN
11321 SIMP_TAC[VECTOR_MUL_COMPONENT; VECTOR_ADD_COMPONENT] THEN
11322 REPEAT GEN_TAC THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
11323 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN REAL_ARITH_TAC);;
11325 let OPEN_CLOSED_INTERVAL_CONVEX = prove
11326 (`!a b x y:real^N e.
11327 x IN interval(a,b) /\ y IN interval[a,b] /\ &0 < e /\ e <= &1
11328 ==> (e % x + (&1 - e) % y) IN interval(a,b)`,
11329 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
11330 `(c /\ d ==> a /\ b ==> e) ==> a /\ b /\ c /\ d ==> e`) THEN
11331 STRIP_TAC THEN REWRITE_TAC[IN_INTERVAL; AND_FORALL_THM] THEN
11332 SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
11333 MATCH_MP_TAC MONO_FORALL THEN
11334 GEN_TAC THEN DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
11335 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
11336 SUBST1_TAC(REAL_ARITH `(a:real^N)$i = e * a$i + (&1 - e) * a$i`) THEN
11337 SUBST1_TAC(REAL_ARITH `(b:real^N)$i = e * b$i + (&1 - e) * b$i`) THEN
11338 CONJ_TAC THEN MATCH_MP_TAC REAL_LTE_ADD2 THEN
11339 ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_LE_LMUL; REAL_SUB_LE]);;
11341 let CLOSURE_OPEN_INTERVAL = prove
11343 ~(interval(a,b) = {}) ==> closure(interval(a,b)) = interval[a,b]`,
11344 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
11345 [MATCH_MP_TAC CLOSURE_MINIMAL THEN
11346 REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED; CLOSED_INTERVAL];
11348 REWRITE_TAC[SUBSET; closure; IN_UNION] THEN X_GEN_TAC `x:real^N` THEN
11349 DISCH_TAC THEN MATCH_MP_TAC(TAUT `(~b ==> c) ==> b \/ c`) THEN DISCH_TAC THEN
11350 REWRITE_TAC[IN_ELIM_THM; LIMPT_SEQUENTIAL] THEN
11351 ABBREV_TAC `(c:real^N) = inv(&2) % (a + b)` THEN
11352 EXISTS_TAC `\n. (x:real^N) + inv(&n + &1) % (c - x)` THEN CONJ_TAC THENL
11353 [X_GEN_TAC `n:num` THEN REWRITE_TAC[IN_DELETE] THEN
11354 REWRITE_TAC[VECTOR_ARITH `x + a = x <=> a = vec 0`] THEN
11355 REWRITE_TAC[VECTOR_MUL_EQ_0; REAL_INV_EQ_0] THEN
11356 REWRITE_TAC[VECTOR_SUB_EQ; REAL_ARITH `~(&n + &1 = &0)`] THEN
11357 CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[OPEN_INTERVAL_MIDPOINT]] THEN
11358 REWRITE_TAC[VECTOR_ARITH `x + a % (y - x) = a % y + (&1 - a) % x`] THEN
11359 MATCH_MP_TAC OPEN_CLOSED_INTERVAL_CONVEX THEN
11360 CONJ_TAC THENL [ASM_MESON_TAC[OPEN_INTERVAL_MIDPOINT]; ALL_TAC] THEN
11361 ASM_REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
11362 MATCH_MP_TAC REAL_INV_LE_1 THEN REAL_ARITH_TAC;
11364 GEN_REWRITE_TAC LAND_CONV [VECTOR_ARITH `x:real^N = x + &0 % (c - x)`] THEN
11365 MATCH_MP_TAC LIM_ADD THEN REWRITE_TAC[LIM_CONST] THEN
11366 MATCH_MP_TAC LIM_VMUL THEN REWRITE_TAC[LIM_CONST] THEN
11367 REWRITE_TAC[LIM_SEQUENTIALLY; o_THM; DIST_LIFT; REAL_SUB_RZERO] THEN
11368 X_GEN_TAC `e:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_ARCH_INV] THEN
11369 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
11370 STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
11371 REWRITE_TAC[REAL_ABS_INV] THEN MATCH_MP_TAC REAL_LET_TRANS THEN
11372 EXISTS_TAC `inv(&N)` THEN ASM_REWRITE_TAC[] THEN
11373 MATCH_MP_TAC REAL_LE_INV2 THEN UNDISCH_TAC `N:num <= n` THEN
11374 UNDISCH_TAC `~(N = 0)` THEN
11375 REWRITE_TAC[GSYM LT_NZ; GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_LT] THEN
11378 let CLOSURE_INTERVAL = prove
11379 (`(!a b. closure(interval[a,b]) = interval[a,b]) /\
11380 (!a b. closure(interval(a,b)) =
11381 if interval(a,b) = {} then {} else interval[a,b])`,
11382 SIMP_TAC[CLOSURE_CLOSED; CLOSED_INTERVAL] THEN REPEAT GEN_TAC THEN
11383 COND_CASES_TAC THEN ASM_SIMP_TAC[CLOSURE_OPEN_INTERVAL; CLOSURE_EMPTY]);;
11385 let BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC = prove
11386 (`!s:real^N->bool. bounded s ==> ?a. s SUBSET interval(--a,a)`,
11387 REWRITE_TAC[BOUNDED_POS; LEFT_IMP_EXISTS_THM] THEN
11388 MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `B:real`] THEN STRIP_TAC THEN
11389 EXISTS_TAC `(lambda i. B + &1):real^N` THEN
11390 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
11391 SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; REAL_BOUNDS_LT; VECTOR_NEG_COMPONENT] THEN
11392 ASM_MESON_TAC[COMPONENT_LE_NORM;
11393 REAL_ARITH `x <= y ==> a <= x ==> a < y + &1`]);;
11395 let BOUNDED_SUBSET_OPEN_INTERVAL = prove
11396 (`!s:real^N->bool. bounded s ==> ?a b. s SUBSET interval(a,b)`,
11397 MESON_TAC[BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC]);;
11399 let BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC = prove
11400 (`!s:real^N->bool. bounded s ==> ?a. s SUBSET interval[--a,a]`,
11402 DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC) THEN
11403 MATCH_MP_TAC MONO_EXISTS THEN
11404 SIMP_TAC[IN_BALL; IN_INTERVAL; SUBSET; REAL_LT_IMP_LE]);;
11406 let BOUNDED_SUBSET_CLOSED_INTERVAL = prove
11407 (`!s:real^N->bool. bounded s ==> ?a b. s SUBSET interval[a,b]`,
11408 MESON_TAC[BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC]);;
11410 let FRONTIER_CLOSED_INTERVAL = prove
11411 (`!a b. frontier(interval[a,b]) = interval[a,b] DIFF interval(a,b)`,
11412 SIMP_TAC[frontier; INTERIOR_CLOSED_INTERVAL; CLOSURE_CLOSED;
11413 CLOSED_INTERVAL]);;
11415 let FRONTIER_OPEN_INTERVAL = prove
11416 (`!a b. frontier(interval(a,b)) =
11417 if interval(a,b) = {} then {}
11418 else interval[a,b] DIFF interval(a,b)`,
11419 REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[FRONTIER_EMPTY] THEN
11420 ASM_SIMP_TAC[frontier; CLOSURE_OPEN_INTERVAL; INTERIOR_OPEN;
11423 let INTER_INTERVAL_MIXED_EQ_EMPTY = prove
11425 ~(interval(c,d) = {})
11426 ==> (interval(a,b) INTER interval[c,d] = {} <=>
11427 interval(a,b) INTER interval(c,d) = {})`,
11428 SIMP_TAC[GSYM CLOSURE_OPEN_INTERVAL; OPEN_INTER_CLOSURE_EQ_EMPTY;
11431 let INTERVAL_TRANSLATION = prove
11432 (`(!c a b. interval[c + a,c + b] = IMAGE (\x. c + x) (interval[a,b])) /\
11433 (!c a b. interval(c + a,c + b) = IMAGE (\x. c + x) (interval(a,b)))`,
11434 REWRITE_TAC[interval] THEN CONJ_TAC THEN GEOM_TRANSLATE_TAC[] THEN
11435 REWRITE_TAC[VECTOR_ADD_COMPONENT; REAL_LT_LADD; REAL_LE_LADD]);;
11437 add_translation_invariants
11438 [CONJUNCT1 INTERVAL_TRANSLATION; CONJUNCT2 INTERVAL_TRANSLATION];;
11440 let EMPTY_AS_INTERVAL = prove
11441 (`{} = interval[vec 1,vec 0]`,
11442 SIMP_TAC[EXTENSION; NOT_IN_EMPTY; IN_INTERVAL; VEC_COMPONENT] THEN
11443 GEN_TAC THEN DISCH_THEN(MP_TAC o SPEC `1`) THEN
11444 REWRITE_TAC[LE_REFL; DIMINDEX_GE_1] THEN REAL_ARITH_TAC);;
11446 let UNIT_INTERVAL_NONEMPTY = prove
11447 (`~(interval[vec 0:real^N,vec 1] = {}) /\
11448 ~(interval(vec 0:real^N,vec 1) = {})`,
11449 SIMP_TAC[INTERVAL_NE_EMPTY; VEC_COMPONENT; REAL_LT_01; REAL_POS]);;
11451 let IMAGE_STRETCH_INTERVAL = prove
11453 IMAGE (\x. lambda k. m(k) * x$k) (interval[a,b]) =
11454 if interval[a,b] = {} then {}
11455 else interval[(lambda k. min (m(k) * a$k) (m(k) * b$k)):real^N,
11456 (lambda k. max (m(k) * a$k) (m(k) * b$k))]`,
11457 REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[IMAGE_CLAUSES] THEN
11458 ASM_SIMP_TAC[EXTENSION; IN_IMAGE; CART_EQ; IN_INTERVAL; AND_FORALL_THM;
11459 TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`;
11460 LAMBDA_BETA; GSYM LAMBDA_SKOLEM] THEN
11461 X_GEN_TAC `x:real^N` THEN MATCH_MP_TAC(MESON[]
11462 `(!x. p x ==> (q x <=> r x))
11463 ==> ((!x. p x ==> q x) <=> (!x. p x ==> r x))`) THEN
11464 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INTERVAL_NE_EMPTY]) THEN
11465 MATCH_MP_TAC MONO_FORALL THEN
11466 X_GEN_TAC `k:num` THEN ASM_CASES_TAC `1 <= k /\ k <= dimindex(:N)` THEN
11467 ASM_REWRITE_TAC[] THEN ASM_CASES_TAC `(m:num->real) k = &0` THENL
11468 [ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MAX_ACI; REAL_MIN_ACI] THEN
11469 ASM_MESON_TAC[REAL_LE_ANTISYM; REAL_LE_REFL];
11471 ASM_SIMP_TAC[REAL_FIELD `~(m = &0) ==> (x = m * y <=> y = x / m)`] THEN
11472 REWRITE_TAC[UNWIND_THM2] THEN FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP
11473 (REAL_ARITH `~(z = &0) ==> &0 < z \/ &0 < --z`))
11476 ONCE_REWRITE_TAC[GSYM REAL_LE_NEG2] THEN
11477 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
11478 REWRITE_TAC[REAL_ARITH `--(max a b) = min (--a) (--b)`;
11479 REAL_ARITH `--(min a b) = max (--a) (--b)`; real_div;
11480 GSYM REAL_MUL_RNEG; GSYM REAL_INV_NEG] THEN
11481 REWRITE_TAC[GSYM real_div]] THEN
11482 ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ] THEN
11483 ASM_SIMP_TAC[real_min; real_max; REAL_LE_LMUL_EQ; REAL_LE_RMUL_EQ] THEN
11486 let INTERVAL_IMAGE_STRETCH_INTERVAL = prove
11487 (`!a b:real^N m. ?u v:real^N.
11488 IMAGE (\x. lambda k. m k * x$k) (interval[a,b]) = interval[u,v]`,
11489 REWRITE_TAC[IMAGE_STRETCH_INTERVAL] THEN MESON_TAC[EMPTY_AS_INTERVAL]);;
11491 let CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL = prove
11493 ~(interval[a,b] = {})
11494 ==> interval[a,b] = IMAGE (\x:real^N. a + x)
11495 (IMAGE (\x. (lambda i. (b$i - a$i) * x$i))
11496 (interval[vec 0:real^N,vec 1]))`,
11497 REWRITE_TAC[INTERVAL_NE_EMPTY] THEN REPEAT STRIP_TAC THEN
11498 REWRITE_TAC[IMAGE_STRETCH_INTERVAL; UNIT_INTERVAL_NONEMPTY] THEN
11499 REWRITE_TAC[GSYM INTERVAL_TRANSLATION] THEN
11500 REWRITE_TAC[EXTENSION; IN_INTERVAL] THEN
11501 SIMP_TAC[LAMBDA_BETA; VECTOR_ADD_COMPONENT; VEC_COMPONENT] THEN
11502 GEN_TAC THEN REWRITE_TAC[REAL_MUL_RZERO; REAL_MUL_RID] THEN
11503 MATCH_MP_TAC(MESON[] `(!x. P x <=> Q x) ==> ((!x. P x) <=> (!x. Q x))`) THEN
11504 POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN
11505 ASM_CASES_TAC `1 <= i /\ i <= dimindex(:N)` THEN ASM_REWRITE_TAC[] THEN
11508 let SUMS_INTERVALS = prove
11509 (`(!a b c d:real^N.
11510 ~(interval[a,b] = {}) /\ ~(interval[c,d] = {})
11511 ==> {x + y | x IN interval[a,b] /\ y IN interval[c,d]} =
11512 interval[a+c,b+d]) /\
11514 ~(interval(a,b) = {}) /\ ~(interval(c,d) = {})
11515 ==> {x + y | x IN interval(a,b) /\ y IN interval(c,d)} =
11516 interval(a+c,b+d))`,
11517 CONJ_TAC THEN REPEAT GEN_TAC THEN REWRITE_TAC[INTERVAL_NE_EMPTY] THEN
11518 STRIP_TAC THEN REWRITE_TAC[EXTENSION; IN_INTERVAL; IN_ELIM_THM] THEN
11519 REWRITE_TAC[TAUT `(a /\ b) /\ c <=> c /\ a /\ b`] THEN
11520 REWRITE_TAC[VECTOR_ARITH `x:real^N = y + z <=> z = x - y`] THEN
11521 REWRITE_TAC[UNWIND_THM2; VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT] THEN
11522 (X_GEN_TAC `x:real^N` THEN EQ_TAC THENL
11523 [DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC);
11525 REWRITE_TAC[AND_FORALL_THM; GSYM LAMBDA_SKOLEM;
11526 TAUT `(p ==> q) /\ (p ==> r) <=> p ==> q /\ r`] THEN
11527 REWRITE_TAC[REAL_ARITH
11528 `((a <= y /\ y <= b) /\ c <= x - y /\ x - y <= d <=>
11529 max a (x - d) <= y /\ y <= min b (x - c)) /\
11530 ((a < y /\ y < b) /\ c < x - y /\ x - y < d <=>
11531 max a (x - d) < y /\ y < min b (x - c))`] THEN
11532 REWRITE_TAC[GSYM REAL_LE_BETWEEN; GSYM REAL_LT_BETWEEN]] THEN
11533 X_GEN_TAC `i:num` THEN STRIP_TAC THEN
11534 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN
11535 ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC));;
11537 let PCROSS_INTERVAL = prove
11538 (`!a b:real^M c d:real^N.
11539 interval[a,b] PCROSS interval[c,d] =
11540 interval[pastecart a c,pastecart b d]`,
11541 REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN
11542 REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN
11543 SIMP_TAC[IN_INTERVAL; pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM] THEN
11544 MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^N`] THEN EQ_TAC THEN STRIP_TAC THENL
11545 [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
11546 COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN
11547 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC;
11548 CONJ_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THENL
11549 [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
11550 DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC;
11551 FIRST_X_ASSUM(MP_TAC o SPEC `i + dimindex(:M)`) THEN
11552 COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD_SUB] THENL
11554 DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC]]]);;
11556 let OPEN_CONTAINS_INTERVAL,OPEN_CONTAINS_OPEN_INTERVAL = (CONJ_PAIR o prove)
11557 (`(!s:real^N->bool.
11559 !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval[a,b] SUBSET s) /\
11562 !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval(a,b) SUBSET s)`,
11563 REWRITE_TAC[AND_FORALL_THM] THEN GEN_TAC THEN
11565 `(q ==> r) /\ (r ==> p) /\ (p ==> q) ==> (p <=> q) /\ (p <=> r)`) THEN
11566 REPEAT CONJ_TAC THENL
11567 [MESON_TAC[SUBSET_TRANS; INTERVAL_OPEN_SUBSET_CLOSED];
11568 DISCH_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN
11569 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
11570 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
11571 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
11572 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN STRIP_TAC THEN
11573 MP_TAC(ISPEC `interval(a:real^N,b)` OPEN_CONTAINS_BALL) THEN
11574 REWRITE_TAC[OPEN_INTERVAL] THEN
11575 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
11576 MATCH_MP_TAC MONO_EXISTS THEN
11577 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
11578 ASM_MESON_TAC[SUBSET_TRANS; INTERVAL_OPEN_SUBSET_CLOSED];
11579 DISCH_TAC THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
11580 FIRST_ASSUM(MP_TAC o SPEC `x:real^N` o
11581 GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN
11582 ASM_REWRITE_TAC[] THEN
11583 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
11584 EXISTS_TAC `x - e / &(dimindex(:N)) % vec 1:real^N` THEN
11585 EXISTS_TAC `x + e / &(dimindex(:N)) % vec 1:real^N` THEN
11586 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
11587 `b SUBSET s ==> x IN i /\ j SUBSET b ==> x IN i /\ j SUBSET s`)) THEN
11588 SIMP_TAC[IN_INTERVAL; VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; IN_CBALL;
11589 VEC_COMPONENT; VECTOR_ADD_COMPONENT; SUBSET; REAL_MUL_RID] THEN
11590 REWRITE_TAC[REAL_ARITH `x - e < x /\ x < x + e <=> &0 < e`;
11591 REAL_ARITH `x - e <= y /\ y <= x + e <=> abs(x - y) <= e`] THEN
11592 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1] THEN
11593 X_GEN_TAC `y:real^N` THEN REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT] THEN
11594 DISCH_TAC THEN REWRITE_TAC[dist] THEN
11595 MATCH_MP_TAC REAL_LE_TRANS THEN
11596 EXISTS_TAC `sum(1..dimindex(:N)) (\i. abs((x - y:real^N)$i))` THEN
11597 REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_BOUND_GEN THEN
11598 ASM_SIMP_TAC[CARD_NUMSEG_1; IN_NUMSEG; FINITE_NUMSEG] THEN
11599 REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1]]);;
11601 let DIAMETER_INTERVAL = prove
11603 diameter(interval[a,b]) =
11604 if interval[a,b] = {} then &0 else norm(b - a)) /\
11606 diameter(interval(a,b)) =
11607 if interval(a,b) = {} then &0 else norm(b - a))`,
11608 REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN
11609 ASM_CASES_TAC `interval[a:real^N,b] = {}` THENL
11610 [ASM_MESON_TAC[INTERVAL_OPEN_SUBSET_CLOSED; SUBSET_EMPTY; DIAMETER_EMPTY];
11611 ASM_REWRITE_TAC[]] THEN
11612 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
11613 [REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
11614 ASM_SIMP_TAC[DIAMETER_BOUNDED_BOUND;
11615 ENDS_IN_INTERVAL; BOUNDED_INTERVAL] THEN
11616 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
11617 `diameter(cball(inv(&2) % (a + b):real^N,norm(b - a) / &2))` THEN
11619 [MATCH_MP_TAC DIAMETER_SUBSET THEN REWRITE_TAC[BOUNDED_CBALL] THEN
11620 REWRITE_TAC[SUBSET; IN_INTERVAL; IN_CBALL] THEN
11621 GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[dist] THEN
11622 REWRITE_TAC[GSYM NORM_MUL; REAL_ARITH `x / &2 = abs(inv(&2)) * x`] THEN
11623 MATCH_MP_TAC NORM_LE_COMPONENTWISE THEN
11624 X_GEN_TAC `i:num` THEN DISCH_TAC THEN
11625 FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
11626 ASM_REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT;
11627 VECTOR_MUL_COMPONENT] THEN
11629 REWRITE_TAC[DIAMETER_CBALL] THEN NORM_ARITH_TAC];
11630 DISCH_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[DIAMETER_EMPTY] THEN
11631 SUBGOAL_THEN `interval[a:real^N,b] = closure(interval(a,b))`
11632 SUBST_ALL_TAC THEN ASM_REWRITE_TAC[CLOSURE_INTERVAL] THEN
11633 ASM_MESON_TAC[DIAMETER_CLOSURE; BOUNDED_INTERVAL]]);;
11635 let IMAGE_TWIZZLE_INTERVAL = prove
11636 (`!p a b. dimindex(:M) = dimindex(:N) /\ p permutes 1..dimindex(:N)
11637 ==> IMAGE ((\x. lambda i. x$(p i)):real^M->real^N) (interval[a,b]) =
11638 interval[(lambda i. a$(p i)),(lambda i. b$(p i))]`,
11639 REPEAT STRIP_TAC THEN
11640 MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
11641 SIMP_TAC[IN_INTERVAL; CART_EQ; LAMBDA_BETA] THEN CONJ_TAC THENL
11642 [X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
11643 EXISTS_TAC `(lambda i. (y:real^N)$(inverse p i)):real^M` THEN
11644 IMP_REWRITE_TAC[LAMBDA_BETA] THEN
11645 ASM_REWRITE_TAC[GSYM IN_NUMSEG] THEN
11646 ASM_MESON_TAC[PERMUTES_INVERSE_EQ; PERMUTES_IN_IMAGE];
11647 REWRITE_TAC[GSYM IN_NUMSEG] THEN
11648 ASM_MESON_TAC[PERMUTES_INVERSES; PERMUTES_IN_IMAGE]]);;
11650 (* ------------------------------------------------------------------------- *)
11651 (* Some special cases for intervals in R^1. *)
11652 (* ------------------------------------------------------------------------- *)
11654 let INTERVAL_CASES_1 = prove
11655 (`!x:real^1. x IN interval[a,b] ==> x IN interval(a,b) \/ (x = a) \/ (x = b)`,
11656 REWRITE_TAC[CART_EQ; IN_INTERVAL; FORALL_DIMINDEX_1] THEN REAL_ARITH_TAC);;
11658 let IN_INTERVAL_1 = prove
11660 (x IN interval[a,b] <=> drop a <= drop x /\ drop x <= drop b) /\
11661 (x IN interval(a,b) <=> drop a < drop x /\ drop x < drop b)`,
11662 REWRITE_TAC[IN_INTERVAL; drop; CONJ_ASSOC; DIMINDEX_1; LE_ANTISYM] THEN
11665 let INTERVAL_EQ_EMPTY_1 = prove
11667 (interval[a,b] = {} <=> drop b < drop a) /\
11668 (interval(a,b) = {} <=> drop b <= drop a)`,
11669 REWRITE_TAC[INTERVAL_EQ_EMPTY; drop; CONJ_ASSOC; DIMINDEX_1; LE_ANTISYM] THEN
11672 let INTERVAL_NE_EMPTY_1 = prove
11673 (`(!a b:real^1. ~(interval[a,b] = {}) <=> drop a <= drop b) /\
11674 (!a b:real^1. ~(interval(a,b) = {}) <=> drop a < drop b)`,
11675 REWRITE_TAC[INTERVAL_EQ_EMPTY_1] THEN REAL_ARITH_TAC);;
11677 let SUBSET_INTERVAL_1 = prove
11679 (interval[a,b] SUBSET interval[c,d] <=>
11681 drop c <= drop a /\ drop a <= drop b /\ drop b <= drop d) /\
11682 (interval[a,b] SUBSET interval(c,d) <=>
11684 drop c < drop a /\ drop a <= drop b /\ drop b < drop d) /\
11685 (interval(a,b) SUBSET interval[c,d] <=>
11686 drop b <= drop a \/
11687 drop c <= drop a /\ drop a < drop b /\ drop b <= drop d) /\
11688 (interval(a,b) SUBSET interval(c,d) <=>
11689 drop b <= drop a \/
11690 drop c <= drop a /\ drop a < drop b /\ drop b <= drop d)`,
11691 REWRITE_TAC[SUBSET_INTERVAL; FORALL_1; DIMINDEX_1; drop] THEN
11694 let EQ_INTERVAL_1 = prove
11696 (interval[a,b] = interval[c,d] <=>
11697 drop b < drop a /\ drop d < drop c \/
11698 drop a = drop c /\ drop b = drop d)`,
11699 REWRITE_TAC[SET_RULE `s = t <=> s SUBSET t /\ t SUBSET s`] THEN
11700 REWRITE_TAC[SUBSET_INTERVAL_1] THEN REAL_ARITH_TAC);;
11702 let DISJOINT_INTERVAL_1 = prove
11704 (interval[a,b] INTER interval[c,d] = {} <=>
11705 drop b < drop a \/ drop d < drop c \/
11706 drop b < drop c \/ drop d < drop a) /\
11707 (interval[a,b] INTER interval(c,d) = {} <=>
11708 drop b < drop a \/ drop d <= drop c \/
11709 drop b <= drop c \/ drop d <= drop a) /\
11710 (interval(a,b) INTER interval[c,d] = {} <=>
11711 drop b <= drop a \/ drop d < drop c \/
11712 drop b <= drop c \/ drop d <= drop a) /\
11713 (interval(a,b) INTER interval(c,d) = {} <=>
11714 drop b <= drop a \/ drop d <= drop c \/
11715 drop b <= drop c \/ drop d <= drop a)`,
11716 REWRITE_TAC[DISJOINT_INTERVAL; CONJ_ASSOC; DIMINDEX_1; LE_ANTISYM;
11717 UNWIND_THM1; drop]);;
11719 let OPEN_CLOSED_INTERVAL_1 = prove
11720 (`!a b:real^1. interval(a,b) = interval[a,b] DIFF {a,b}`,
11721 REWRITE_TAC[EXTENSION; IN_INTERVAL_1; IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN
11722 REWRITE_TAC[GSYM DROP_EQ] THEN REAL_ARITH_TAC);;
11724 let CLOSED_OPEN_INTERVAL_1 = prove
11725 (`!a b:real^1. drop a <= drop b ==> interval[a,b] = interval(a,b) UNION {a,b}`,
11726 REWRITE_TAC[EXTENSION; IN_INTERVAL_1; IN_UNION; IN_INSERT; NOT_IN_EMPTY] THEN
11727 REWRITE_TAC[GSYM DROP_EQ] THEN REAL_ARITH_TAC);;
11730 (`!x:real^1 r. cball(x,r) = interval[x - lift r,x + lift r] /\
11731 ball(x,r) = interval(x - lift r,x + lift r)`,
11732 REWRITE_TAC[EXTENSION; IN_BALL; IN_CBALL; IN_INTERVAL_1] THEN
11733 REWRITE_TAC[dist; NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP; DROP_ADD] THEN
11736 let SPHERE_1 = prove
11737 (`!a:real^1 r. sphere(a,r) = if r < &0 then {} else {a - lift r,a + lift r}`,
11738 REPEAT GEN_TAC THEN REWRITE_TAC[sphere] THEN COND_CASES_TAC THEN
11739 REWRITE_TAC[DIST_REAL; GSYM drop; FORALL_DROP] THEN
11740 REWRITE_TAC[EXTENSION; IN_INSERT; NOT_IN_EMPTY; IN_ELIM_THM] THEN
11741 REWRITE_TAC[GSYM DROP_EQ; DROP_ADD; DROP_SUB; LIFT_DROP] THEN
11742 ASM_REAL_ARITH_TAC);;
11744 let FINITE_SPHERE_1 = prove
11745 (`!a:real^1 r. FINITE(sphere(a,r))`,
11746 REPEAT GEN_TAC THEN REWRITE_TAC[SPHERE_1] THEN
11747 MESON_TAC[FINITE_INSERT; FINITE_EMPTY]);;
11749 let FINITE_INTERVAL_1 = prove
11750 (`(!a b. FINITE(interval[a,b]) <=> drop b <= drop a) /\
11751 (!a b. FINITE(interval(a,b)) <=> drop b <= drop a)`,
11752 REWRITE_TAC[OPEN_CLOSED_INTERVAL_1] THEN
11753 REWRITE_TAC[SET_RULE `s DIFF {a,b} = s DELETE a DELETE b`] THEN
11754 REWRITE_TAC[FINITE_DELETE] THEN REPEAT GEN_TAC THEN
11755 SUBGOAL_THEN `interval[a,b] = IMAGE lift {x | drop a <= x /\ x <= drop b}`
11757 [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
11758 CONJ_TAC THENL [MESON_TAC[LIFT_DROP]; ALL_TAC] THEN
11759 REWRITE_TAC[IN_INTERVAL_1; IN_ELIM_THM; LIFT_DROP];
11760 SIMP_TAC[FINITE_IMAGE_INJ_EQ; LIFT_EQ; FINITE_REAL_INTERVAL]]);;
11762 let BALL_INTERVAL = prove
11763 (`!x:real^1 e. ball(x,e) = interval(x - lift e,x + lift e)`,
11764 REWRITE_TAC[EXTENSION; IN_BALL; IN_INTERVAL_1; DIST_REAL] THEN
11765 REWRITE_TAC[GSYM drop; DROP_SUB; DROP_ADD; LIFT_DROP] THEN REAL_ARITH_TAC);;
11767 let CBALL_INTERVAL = prove
11768 (`!x:real^1 e. cball(x,e) = interval[x - lift e,x + lift e]`,
11769 REWRITE_TAC[EXTENSION; IN_CBALL; IN_INTERVAL_1; DIST_REAL] THEN
11770 REWRITE_TAC[GSYM drop; DROP_SUB; DROP_ADD; LIFT_DROP] THEN REAL_ARITH_TAC);;
11772 let BALL_INTERVAL_0 = prove
11773 (`!e. ball(vec 0:real^1,e) = interval(--lift e,lift e)`,
11774 GEN_TAC THEN REWRITE_TAC[BALL_INTERVAL] THEN AP_TERM_TAC THEN
11775 BINOP_TAC THEN VECTOR_ARITH_TAC);;
11777 let CBALL_INTERVAL_0 = prove
11778 (`!e. cball(vec 0:real^1,e) = interval[--lift e,lift e]`,
11779 GEN_TAC THEN REWRITE_TAC[CBALL_INTERVAL] THEN AP_TERM_TAC THEN
11780 AP_THM_TAC THEN AP_TERM_TAC THEN BINOP_TAC THEN VECTOR_ARITH_TAC);;
11782 let INTER_INTERVAL_1 = prove
11784 interval[a,b] INTER interval[c,d] =
11785 interval[lift(max (drop a) (drop c)),lift(min (drop b) (drop d))]`,
11786 REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL_1; real_max; real_min] THEN
11787 REPEAT GEN_TAC THEN
11788 REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[LIFT_DROP]) THEN
11789 ASM_REAL_ARITH_TAC);;
11791 let CLOSED_DIFF_OPEN_INTERVAL_1 = prove
11793 interval[a,b] DIFF interval(a,b) =
11794 if interval[a,b] = {} then {} else {a,b}`,
11795 REWRITE_TAC[EXTENSION; IN_DIFF; INTERVAL_EQ_EMPTY_1; IN_INTERVAL_1] THEN
11796 REPEAT GEN_TAC THEN COND_CASES_TAC THEN
11797 ASM_REWRITE_TAC[NOT_IN_EMPTY; IN_INSERT; NOT_IN_EMPTY] THEN
11798 REWRITE_TAC[GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC);;
11800 (* ------------------------------------------------------------------------- *)
11801 (* Intervals in general, including infinite and mixtures of open and closed. *)
11802 (* ------------------------------------------------------------------------- *)
11804 let is_interval = new_definition
11805 `is_interval(s:real^N->bool) <=>
11806 !a b x. a IN s /\ b IN s /\
11807 (!i. 1 <= i /\ i <= dimindex(:N)
11808 ==> (a$i <= x$i /\ x$i <= b$i) \/
11809 (b$i <= x$i /\ x$i <= a$i))
11812 let IS_INTERVAL_INTERVAL = prove
11813 (`!a:real^N b. is_interval(interval (a,b)) /\ is_interval(interval [a,b])`,
11814 REWRITE_TAC[is_interval; IN_INTERVAL] THEN
11815 MESON_TAC[REAL_LT_TRANS; REAL_LE_TRANS; REAL_LET_TRANS; REAL_LTE_TRANS]);;
11817 let IS_INTERVAL_EMPTY = prove
11819 REWRITE_TAC[is_interval; NOT_IN_EMPTY]);;
11821 let IS_INTERVAL_UNIV = prove
11822 (`is_interval(UNIV:real^N->bool)`,
11823 REWRITE_TAC[is_interval; IN_UNIV]);;
11825 let IS_INTERVAL_TRANSLATION_EQ = prove
11826 (`!a:real^N s. is_interval(IMAGE (\x. a + x) s) <=> is_interval s`,
11827 REWRITE_TAC[is_interval] THEN GEOM_TRANSLATE_TAC[] THEN
11828 REWRITE_TAC[VECTOR_ADD_COMPONENT; REAL_LT_LADD; REAL_LE_LADD]);;
11830 add_translation_invariants [IS_INTERVAL_TRANSLATION_EQ];;
11832 let IS_INTERVAL_TRANSLATION = prove
11833 (`!s a:real^N. is_interval s ==> is_interval(IMAGE (\x. a + x) s)`,
11834 REWRITE_TAC[IS_INTERVAL_TRANSLATION_EQ]);;
11836 let IS_INTERVAL_POINTWISE = prove
11837 (`!s:real^N->bool x.
11839 (!i. 1 <= i /\ i <= dimindex(:N) ==> ?a. a IN s /\ a$i = x$i)
11841 REWRITE_TAC[is_interval] THEN REPEAT STRIP_TAC THEN
11843 `!n. ?y:real^N. (!i. 1 <= i /\ i <= n ==> y$i = (x:real^N)$i) /\ y IN s`
11845 [INDUCT_TAC THEN REWRITE_TAC[ARITH_RULE `~(1 <= i /\ i <= 0)`] THENL
11846 [ASM_MESON_TAC[DIMINDEX_GE_1; LE_REFL]; ALL_TAC] THEN
11847 FIRST_X_ASSUM(X_CHOOSE_TAC `y:real^N`) THEN
11848 ASM_CASES_TAC `SUC n <= dimindex(:N)` THENL
11849 [FIRST_X_ASSUM(MP_TAC o SPEC `SUC n`) THEN
11850 ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
11851 DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
11853 `(lambda i. if i <= n then (y:real^N)$i else (z:real^N)$i):real^N` THEN
11855 [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
11856 SUBGOAL_THEN `i <= dimindex(:N)` ASSUME_TAC THENL
11857 [ASM_ARITH_TAC; ASM_SIMP_TAC[LAMBDA_BETA]] THEN
11858 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
11859 SUBGOAL_THEN `i = SUC n` (fun th -> ASM_REWRITE_TAC[th]) THEN
11861 FIRST_X_ASSUM(ASSUME_TAC o CONJUNCT2) THEN
11862 FIRST_X_ASSUM MATCH_MP_TAC THEN
11863 MAP_EVERY EXISTS_TAC [`y:real^N`; `z:real^N`] THEN
11864 ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC];
11865 EXISTS_TAC `y:real^N` THEN ASM_REWRITE_TAC[] THEN
11866 SUBGOAL_THEN `y:real^N = x` (fun th -> REWRITE_TAC[th]) THEN
11867 REWRITE_TAC[CART_EQ] THEN
11868 ASM_MESON_TAC[ARITH_RULE `i <= N /\ ~(SUC n <= N) ==> i <= n`]];
11869 DISCH_THEN(MP_TAC o SPEC `dimindex(:N)`) THEN
11870 REWRITE_TAC[GSYM CART_EQ] THEN MESON_TAC[]]);;
11872 let IS_INTERVAL_COMPACT = prove
11873 (`!s:real^N->bool. is_interval s /\ compact s <=> ?a b. s = interval[a,b]`,
11874 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN
11875 ASM_SIMP_TAC[IS_INTERVAL_INTERVAL; COMPACT_INTERVAL] THEN
11876 ASM_CASES_TAC `s:real^N->bool = {}` THENL
11877 [ASM_MESON_TAC[EMPTY_AS_INTERVAL]; ALL_TAC] THEN
11878 EXISTS_TAC `(lambda i. inf { (x:real^N)$i | x IN s}):real^N` THEN
11879 EXISTS_TAC `(lambda i. sup { (x:real^N)$i | x IN s}):real^N` THEN
11880 SIMP_TAC[EXTENSION; IN_INTERVAL; LAMBDA_BETA] THEN X_GEN_TAC `x:real^N` THEN
11882 [DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
11883 MP_TAC(ISPEC `{ (x:real^N)$i | x IN s}` INF) THEN
11884 MP_TAC(ISPEC `{ (x:real^N)$i | x IN s}` SUP) THEN
11885 ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
11886 ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN
11887 FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN
11888 REWRITE_TAC[bounded] THEN
11889 ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS; MEMBER_NOT_EMPTY;
11890 REAL_ARITH `abs(x) <= B ==> --B <= x /\ x <= B`];
11891 DISCH_TAC THEN MATCH_MP_TAC IS_INTERVAL_POINTWISE THEN
11892 ASM_REWRITE_TAC[] THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
11894 `?a b:real^N. a IN s /\ b IN s /\ a$i <= (x:real^N)$i /\ x$i <= b$i`
11895 STRIP_ASSUME_TAC THENL
11896 [MP_TAC(ISPECL [`\x:real^N. x$i`; `s:real^N->bool`]
11897 CONTINUOUS_ATTAINS_INF) THEN
11898 ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; o_DEF] THEN
11899 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN
11900 MP_TAC(ISPECL [`\x:real^N. x$i`; `s:real^N->bool`]
11901 CONTINUOUS_ATTAINS_SUP) THEN
11902 ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; o_DEF] THEN
11903 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN
11904 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THENL
11905 [EXISTS_TAC `inf {(x:real^N)$i | x IN s}` THEN ASM_SIMP_TAC[] THEN
11906 MATCH_MP_TAC REAL_LE_INF THEN ASM SET_TAC[];
11907 EXISTS_TAC `sup {(x:real^N)$i | x IN s}` THEN ASM_SIMP_TAC[] THEN
11908 MATCH_MP_TAC REAL_SUP_LE THEN ASM SET_TAC[]];
11910 `(lambda j. if j = i then (x:real^N)$i else (a:real^N)$j):real^N` THEN
11911 ASM_SIMP_TAC[LAMBDA_BETA] THEN
11912 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[is_interval]) THEN
11913 MAP_EVERY EXISTS_TAC
11915 `(lambda j. if j = i then (b:real^N)$i else (a:real^N)$j):real^N`] THEN
11916 ASM_SIMP_TAC[LAMBDA_BETA] THEN CONJ_TAC THENL
11917 [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[is_interval]) THEN
11918 MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real^N`] THEN
11919 ASM_SIMP_TAC[LAMBDA_BETA];
11921 GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
11922 ASM_REAL_ARITH_TAC]]);;
11924 let IS_INTERVAL_1 = prove
11927 !a b x. a IN s /\ b IN s /\ drop a <= drop x /\ drop x <= drop b
11929 REWRITE_TAC[is_interval; DIMINDEX_1; FORALL_1; GSYM drop] THEN
11930 REWRITE_TAC[FORALL_LIFT; LIFT_DROP] THEN MESON_TAC[]);;
11932 let IS_INTERVAL_1_CASES = prove
11937 (?a. s = {x | a < drop x}) \/
11938 (?a. s = {x | a <= drop x}) \/
11939 (?b. s = {x | drop x <= b}) \/
11940 (?b. s = {x | drop x < b}) \/
11941 (?a b. s = {x | a < drop x /\ drop x < b}) \/
11942 (?a b. s = {x | a < drop x /\ drop x <= b}) \/
11943 (?a b. s = {x | a <= drop x /\ drop x < b}) \/
11944 (?a b. s = {x | a <= drop x /\ drop x <= b})`,
11945 GEN_TAC THEN REWRITE_TAC[IS_INTERVAL_1] THEN EQ_TAC THENL
11947 STRIP_TAC THEN ASM_REWRITE_TAC[IN_ELIM_THM; IN_UNIV; NOT_IN_EMPTY] THEN
11948 REAL_ARITH_TAC] THEN
11949 ASM_CASES_TAC `s:real^1->bool = {}` THEN ASM_REWRITE_TAC[] THEN
11950 MP_TAC(ISPEC `IMAGE drop s` SUP) THEN
11951 MP_TAC(ISPEC `IMAGE drop s` INF) THEN
11952 ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN
11953 ASM_CASES_TAC `?a. !x. x IN s ==> a <= drop x` THEN
11954 ASM_CASES_TAC `?b. !x. x IN s ==> drop x <= b` THEN
11955 ASM_REWRITE_TAC[] THENL
11956 [STRIP_TAC THEN STRIP_TAC THEN
11957 MAP_EVERY ASM_CASES_TAC
11958 [`inf(IMAGE drop s) IN IMAGE drop s`; `sup(IMAGE drop s) IN IMAGE drop s`]
11960 [REPLICATE_TAC 8 DISJ2_TAC;
11961 REPLICATE_TAC 7 DISJ2_TAC THEN DISJ1_TAC;
11962 REPLICATE_TAC 6 DISJ2_TAC THEN DISJ1_TAC;
11963 REPLICATE_TAC 5 DISJ2_TAC THEN DISJ1_TAC] THEN
11964 MAP_EVERY EXISTS_TAC [`inf(IMAGE drop s)`; `sup(IMAGE drop s)`];
11965 STRIP_TAC THEN ASM_CASES_TAC `inf(IMAGE drop s) IN IMAGE drop s` THENL
11966 [REPLICATE_TAC 2 DISJ2_TAC THEN DISJ1_TAC;
11967 DISJ2_TAC THEN DISJ1_TAC] THEN
11968 EXISTS_TAC `inf(IMAGE drop s)`;
11969 STRIP_TAC THEN ASM_CASES_TAC `sup(IMAGE drop s) IN IMAGE drop s` THENL
11970 [REPLICATE_TAC 3 DISJ2_TAC THEN DISJ1_TAC;
11971 REPLICATE_TAC 4 DISJ2_TAC THEN DISJ1_TAC] THEN
11972 EXISTS_TAC `sup(IMAGE drop s)`;
11974 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_UNIV] THEN
11975 RULE_ASSUM_TAC(REWRITE_RULE[IN_IMAGE]) THEN
11976 REWRITE_TAC[GSYM REAL_NOT_LE] THEN
11977 ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL; REAL_LE_ANTISYM]);;
11979 let IS_INTERVAL_PCROSS = prove
11980 (`!s:real^M->bool t:real^N->bool.
11981 is_interval s /\ is_interval t ==> is_interval(s PCROSS t)`,
11982 REWRITE_TAC[is_interval; DIMINDEX_FINITE_SUM] THEN
11983 REWRITE_TAC[FORALL_PASTECART; PASTECART_IN_PCROSS] THEN
11984 REPEAT GEN_TAC THEN
11985 MATCH_MP_TAC(MESON[]
11986 `(!a b a' b' x x'. P a b x /\ Q a' b' x' ==> R a b x a' b' x')
11987 ==> (!a b x. P a b x) /\ (!a' b' x'. Q a' b' x')
11988 ==> (!a a' b b' x x'. R a b x a' b' x')`) THEN
11989 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
11990 ASM_REWRITE_TAC[] THEN X_GEN_TAC `i:num` THEN STRIP_TAC THENL
11991 [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
11992 ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM;
11993 ARITH_RULE `x:num <= m ==> x <= m + n`];
11994 FIRST_X_ASSUM(MP_TAC o SPEC `dimindex(:M) + i`) THEN
11995 ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM;
11996 ARITH_RULE `x:num <= n ==> m + x <= m + n`;
11997 ARITH_RULE `1 <= x ==> 1 <= m + x`] THEN
11998 COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD_SUB2] THEN ASM_ARITH_TAC]);;
12000 let IS_INTERVAL_PCROSS_EQ = prove
12001 (`!s:real^M->bool t:real^N->bool.
12002 is_interval(s PCROSS t) <=>
12003 s = {} \/ t = {} \/ is_interval s /\ is_interval t`,
12004 REPEAT GEN_TAC THEN
12005 ASM_CASES_TAC `s:real^M->bool = {}` THEN
12006 ASM_REWRITE_TAC[PCROSS_EMPTY; IS_INTERVAL_EMPTY] THEN
12007 ASM_CASES_TAC `t:real^N->bool = {}` THEN
12008 ASM_REWRITE_TAC[PCROSS_EMPTY; IS_INTERVAL_EMPTY] THEN
12009 EQ_TAC THEN REWRITE_TAC[IS_INTERVAL_PCROSS] THEN
12010 REWRITE_TAC[is_interval] THEN
12011 REWRITE_TAC[FORALL_PASTECART; PASTECART_IN_PCROSS] THEN
12012 STRIP_TAC THEN CONJ_TAC THENL
12013 [MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `x:real^M`] THEN
12014 STRIP_TAC THEN UNDISCH_TAC `~(t:real^N->bool = {})` THEN
12015 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
12016 DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN
12017 FIRST_X_ASSUM(MP_TAC o SPECL
12018 [`a:real^M`; `y:real^N`; `b:real^M`;
12019 `y:real^N`; `x:real^M`; `y:real^N`]);
12020 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `x:real^N`] THEN
12021 STRIP_TAC THEN UNDISCH_TAC `~(s:real^M->bool = {})` THEN
12022 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
12023 DISCH_THEN(X_CHOOSE_TAC `w:real^M`) THEN
12024 FIRST_X_ASSUM(MP_TAC o SPECL
12025 [`w:real^M`; `a:real^N`; `w:real^M`;
12026 `b:real^N`; `w:real^M`; `x:real^N`])] THEN
12027 ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN
12028 SIMP_TAC[pastecart; LAMBDA_BETA] THEN
12029 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN
12030 ASM_MESON_TAC[DIMINDEX_FINITE_SUM; ARITH_RULE
12031 `1 <= i /\ i <= m + n /\ ~(i <= m) ==> 1 <= i - m /\ i - m <= n`]);;
12033 let IS_INTERVAL_INTER = prove
12034 (`!s t:real^N->bool.
12035 is_interval s /\ is_interval t ==> is_interval(s INTER t)`,
12036 REWRITE_TAC[is_interval; IN_INTER] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
12037 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `x:real^N`] THEN
12038 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
12039 MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real^N`] THEN ASM_REWRITE_TAC[]);;
12041 let INTERVAL_SUBSET_IS_INTERVAL = prove
12044 ==> (interval[a,b] SUBSET s <=> interval[a,b] = {} \/ a IN s /\ b IN s)`,
12045 REWRITE_TAC[is_interval] THEN REPEAT STRIP_TAC THEN
12046 ASM_CASES_TAC `interval[a:real^N,b] = {}` THEN
12047 ASM_REWRITE_TAC[EMPTY_SUBSET] THEN
12048 EQ_TAC THENL [ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET]; ALL_TAC] THEN
12049 REWRITE_TAC[SUBSET; IN_INTERVAL] THEN ASM_MESON_TAC[]);;
12051 let INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD = prove
12053 is_interval s /\ x IN s
12054 ==> ?a b d. &0 < d /\ x IN interval[a,b] /\
12055 interval[a,b] SUBSET s /\
12056 ball(x,d) INTER s SUBSET interval[a,b]`,
12057 REPEAT STRIP_TAC THEN ASM_SIMP_TAC[INTERVAL_SUBSET_IS_INTERVAL] THEN
12059 `!i. 1 <= i /\ i <= dimindex(:N)
12060 ==> ?a. (?y. y IN s /\ y$i = a) /\
12061 (a < x$i \/ a = (x:real^N)$i /\
12062 !y:real^N. y IN s ==> a <= y$i)`
12063 MP_TAC THENL [ASM_MESON_TAC[REAL_NOT_LT]; REWRITE_TAC[LAMBDA_SKOLEM]] THEN
12064 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN
12066 `!i. 1 <= i /\ i <= dimindex(:N)
12067 ==> ?b. (?y. y IN s /\ y$i = b) /\
12068 (x$i < b \/ b = (x:real^N)$i /\
12069 !y:real^N. y IN s ==> y$i <= b)`
12070 MP_TAC THENL [ASM_MESON_TAC[REAL_NOT_LT]; REWRITE_TAC[LAMBDA_SKOLEM]] THEN
12071 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN
12072 EXISTS_TAC `min (inf (IMAGE (\i. if a$i < x$i
12073 then (x:real^N)$i - (a:real^N)$i else &1)
12074 (1..dimindex(:N))))
12075 (inf (IMAGE (\i. if x$i < b$i
12076 then (b:real^N)$i - x$i else &1)
12077 (1..dimindex(:N))))` THEN
12078 REWRITE_TAC[REAL_LT_MIN; SUBSET; IN_BALL; IN_INTER] THEN
12079 SIMP_TAC[REAL_LT_INF_FINITE; IMAGE_EQ_EMPTY; FINITE_IMAGE;
12080 FINITE_NUMSEG; NUMSEG_EMPTY; GSYM NOT_LE; DIMINDEX_GE_1] THEN
12081 REWRITE_TAC[FORALL_IN_IMAGE; IN_INTERVAL] THEN REPEAT CONJ_TAC THENL
12082 [MESON_TAC[REAL_SUB_LT; REAL_LT_01];
12083 MESON_TAC[REAL_SUB_LT; REAL_LT_01];
12084 ASM_MESON_TAC[REAL_LE_LT];
12085 DISJ2_TAC THEN CONJ_TAC THEN MATCH_MP_TAC IS_INTERVAL_POINTWISE THEN
12087 X_GEN_TAC `y:real^N` THEN
12088 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
12089 REWRITE_TAC[AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN
12090 X_GEN_TAC `i:num` THEN DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
12091 ASM_REWRITE_TAC[IN_NUMSEG] THEN MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN
12092 (COND_CASES_TAC THENL [REWRITE_TAC[dist]; ASM_MESON_TAC[]]) THEN
12093 DISCH_TAC THEN MP_TAC(ISPECL [`x - y:real^N`; `i:num`]
12094 COMPONENT_LE_NORM) THEN
12095 ASM_REWRITE_TAC[VECTOR_SUB_COMPONENT] THEN ASM_REAL_ARITH_TAC]);;
12097 let IS_INTERVAL_SUMS = prove
12098 (`!s t:real^N->bool.
12099 is_interval s /\ is_interval t
12100 ==> is_interval {x + y | x IN s /\ y IN t}`,
12101 REPEAT GEN_TAC THEN REWRITE_TAC[is_interval] THEN
12102 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
12103 REWRITE_TAC[FORALL_IN_GSPEC] THEN
12104 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
12105 REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
12106 MAP_EVERY X_GEN_TAC
12107 [`a:real^N`; `a':real^N`; `b:real^N`; `b':real^N`; `y:real^N`] THEN
12108 DISCH_THEN(CONJUNCTS_THEN2
12109 (MP_TAC o SPECL [`a:real^N`; `b:real^N`]) MP_TAC) THEN
12110 DISCH_THEN(CONJUNCTS_THEN2
12111 (MP_TAC o SPECL [`a':real^N`; `b':real^N`]) STRIP_ASSUME_TAC) THEN
12112 ASM_REWRITE_TAC[IMP_IMP; IN_ELIM_THM] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
12113 ONCE_REWRITE_TAC[VECTOR_ARITH `z:real^N = x + y <=> y = z - x`] THEN
12114 REWRITE_TAC[UNWIND_THM2] THEN MATCH_MP_TAC(MESON[]
12115 `(?x. P x /\ Q(f x))
12116 ==> (!x. P x ==> x IN s) /\ (!x. Q x ==> x IN t)
12117 ==> ?x. x IN s /\ f x IN t`) THEN
12118 REWRITE_TAC[VECTOR_SUB_COMPONENT; AND_FORALL_THM;
12119 TAUT `(p ==> q) /\ (p ==> r) <=> p ==> q /\ r`] THEN
12120 REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN
12121 X_GEN_TAC `i:num` THEN STRIP_TAC THEN
12122 FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
12123 ASM_REWRITE_TAC[VECTOR_ADD_COMPONENT] THEN
12124 REWRITE_TAC[REAL_ARITH
12125 `c <= y - x /\ y - x <= d <=> y - d <= x /\ x <= y - c`] THEN
12126 REWRITE_TAC[REAL_ARITH
12127 `a <= x /\ x <= b \/ b <= x /\ x <= a <=> min a b <= x /\ x <= max a b`] THEN
12128 ONCE_REWRITE_TAC[TAUT `(p /\ q) /\ (r /\ s) <=> (p /\ r) /\ (q /\ s)`] THEN
12129 REWRITE_TAC[GSYM REAL_LE_MIN; GSYM REAL_MAX_LE] THEN
12130 REWRITE_TAC[GSYM REAL_LE_BETWEEN] THEN REAL_ARITH_TAC);;
12132 let IS_INTERVAL_SING = prove
12133 (`!a:real^N. is_interval {a}`,
12134 SIMP_TAC[is_interval; IN_SING; IMP_CONJ; CART_EQ; REAL_LE_ANTISYM]);;
12136 let IS_INTERVAL_SCALING = prove
12137 (`!s:real^N->bool c. is_interval s ==> is_interval(IMAGE (\x. c % x) s)`,
12138 REPEAT GEN_TAC THEN ASM_CASES_TAC `c = &0` THENL
12139 [ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN
12140 SUBGOAL_THEN `IMAGE ((\x. vec 0):real^N->real^N) s = {} \/
12141 IMAGE ((\x. vec 0):real^N->real^N) s = {vec 0}`
12142 STRIP_ASSUME_TAC THENL
12144 ASM_REWRITE_TAC[IS_INTERVAL_EMPTY];
12145 ASM_REWRITE_TAC[IS_INTERVAL_SING]];
12146 REWRITE_TAC[is_interval; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
12147 REWRITE_TAC[FORALL_IN_IMAGE] THEN
12148 GEN_REWRITE_TAC (BINOP_CONV o REDEPTH_CONV) [RIGHT_IMP_FORALL_THM] THEN
12149 REWRITE_TAC[IMP_IMP; VECTOR_MUL_COMPONENT] THEN
12150 MAP_EVERY (fun t -> MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC t)
12151 [`a:real^N`; `b:real^N`] THEN
12152 DISCH_THEN(fun th -> X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN
12153 MP_TAC(SPEC `inv(c) % x:real^N` th)) THEN
12154 ASM_REWRITE_TAC[VECTOR_MUL_COMPONENT; IN_IMAGE] THEN ANTS_TAC THENL
12155 [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
12156 FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
12157 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN
12158 FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH
12159 `~(c = &0) ==> &0 < c \/ &0 < --c`)) THEN
12160 ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ] THEN
12161 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_LE_NEG2] THEN
12162 ASM_SIMP_TAC[GSYM REAL_MUL_RNEG; GSYM REAL_LE_RDIV_EQ; GSYM
12163 REAL_LE_LDIV_EQ] THEN
12164 REWRITE_TAC[real_div; REAL_INV_NEG] THEN REAL_ARITH_TAC;
12165 DISCH_TAC THEN EXISTS_TAC `inv c % x:real^N` THEN
12166 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; VECTOR_MUL_LID]]]);;
12168 let IS_INTERVAL_SCALING_EQ = prove
12169 (`!s:real^N->bool c.
12170 is_interval(IMAGE (\x. c % x) s) <=> c = &0 \/ is_interval s`,
12171 REPEAT GEN_TAC THEN ASM_CASES_TAC `c = &0` THENL
12172 [ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN
12173 SUBGOAL_THEN `IMAGE ((\x. vec 0):real^N->real^N) s = {} \/
12174 IMAGE ((\x. vec 0):real^N->real^N) s = {vec 0}`
12175 STRIP_ASSUME_TAC THENL
12177 ASM_REWRITE_TAC[IS_INTERVAL_EMPTY];
12178 ASM_REWRITE_TAC[IS_INTERVAL_SING]];
12179 ASM_REWRITE_TAC[] THEN EQ_TAC THEN REWRITE_TAC[IS_INTERVAL_SCALING] THEN
12180 DISCH_THEN(MP_TAC o SPEC `inv c:real` o MATCH_MP IS_INTERVAL_SCALING) THEN
12181 ASM_SIMP_TAC[GSYM IMAGE_o; VECTOR_MUL_ASSOC; o_DEF; REAL_MUL_LINV;
12182 VECTOR_MUL_LID; IMAGE_ID]]);;
12186 ==> !s:real^N->bool. is_interval(IMAGE (\x. c % x) s) <=>
12188 SIMP_TAC[IS_INTERVAL_SCALING_EQ; REAL_LT_IMP_NZ]) in
12189 add_scaling_theorems [lemma];;
12191 (* ------------------------------------------------------------------------- *)
12192 (* Line segments, with same open/closed overloading as for intervals. *)
12193 (* ------------------------------------------------------------------------- *)
12195 let closed_segment = define
12196 `closed_segment[a,b] = {(&1 - u) % a + u % b | &0 <= u /\ u <= &1}`;;
12198 let open_segment = new_definition
12199 `open_segment(a,b) = closed_segment[a,b] DIFF {a,b}`;;
12201 let OPEN_SEGMENT_ALT = prove
12204 ==> open_segment(a,b) = {(&1 - u) % a + u % b | &0 < u /\ u < &1}`,
12205 REPEAT STRIP_TAC THEN REWRITE_TAC[open_segment; closed_segment] THEN
12206 REWRITE_TAC[EXTENSION; IN_DIFF; IN_INSERT; NOT_IN_EMPTY; IN_ELIM_THM] THEN
12207 X_GEN_TAC `x:real^N` THEN REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN
12208 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN
12209 X_GEN_TAC `u:real` THEN ASM_CASES_TAC `x:real^N = (&1 - u) % a + u % b` THEN
12210 ASM_REWRITE_TAC[REAL_LE_LT;
12211 VECTOR_ARITH `(&1 - u) % a + u % b = a <=> u % (b - a) = vec 0`;
12212 VECTOR_ARITH `(&1 - u) % a + u % b = b <=> (&1 - u) % (b - a) = vec 0`;
12213 VECTOR_MUL_EQ_0; REAL_SUB_0; VECTOR_SUB_EQ] THEN
12216 make_overloadable "segment" `:A`;;
12218 overload_interface("segment",`open_segment`);;
12219 overload_interface("segment",`closed_segment`);;
12221 let segment = prove
12222 (`segment[a,b] = {(&1 - u) % a + u % b | &0 <= u /\ u <= &1} /\
12223 segment(a,b) = segment[a,b] DIFF {a,b}`,
12224 REWRITE_TAC[open_segment; closed_segment]);;
12226 let SEGMENT_REFL = prove
12227 (`(!a. segment[a,a] = {a}) /\
12228 (!a. segment(a,a) = {})`,
12229 REWRITE_TAC[segment; VECTOR_ARITH `(&1 - u) % a + u % a = a`] THEN
12230 SET_TAC[REAL_POS]);;
12232 let IN_SEGMENT = prove
12234 (x IN segment[a,b] <=>
12235 ?u. &0 <= u /\ u <= &1 /\ x = (&1 - u) % a + u % b) /\
12236 (x IN segment(a,b) <=>
12237 ~(a = b) /\ ?u. &0 < u /\ u < &1 /\ x = (&1 - u) % a + u % b)`,
12238 REPEAT STRIP_TAC THENL
12239 [REWRITE_TAC[segment; IN_ELIM_THM; CONJ_ASSOC]; ALL_TAC] THEN
12240 ASM_CASES_TAC `a:real^N = b` THEN
12241 ASM_REWRITE_TAC[SEGMENT_REFL; NOT_IN_EMPTY] THEN
12242 ASM_SIMP_TAC[OPEN_SEGMENT_ALT; IN_ELIM_THM; CONJ_ASSOC]);;
12244 let SEGMENT_SYM = prove
12245 (`(!a b:real^N. segment[a,b] = segment[b,a]) /\
12246 (!a b:real^N. segment(a,b) = segment(b,a))`,
12247 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN
12248 SIMP_TAC[open_segment] THEN
12249 CONJ_TAC THENL [ALL_TAC; SIMP_TAC[INSERT_AC]] THEN
12250 REWRITE_TAC[EXTENSION; IN_SEGMENT] THEN REPEAT GEN_TAC THEN EQ_TAC THEN
12251 DISCH_THEN(X_CHOOSE_TAC `u:real`) THEN EXISTS_TAC `&1 - u` THEN
12252 ASM_REWRITE_TAC[] THEN
12253 REPEAT CONJ_TAC THEN TRY ASM_ARITH_TAC THEN VECTOR_ARITH_TAC);;
12255 let ENDS_IN_SEGMENT = prove
12256 (`!a b. a IN segment[a,b] /\ b IN segment[a,b]`,
12257 REPEAT STRIP_TAC THEN REWRITE_TAC[segment; IN_ELIM_THM] THENL
12258 [EXISTS_TAC `&0`; EXISTS_TAC `&1`] THEN
12259 (CONJ_TAC THENL [REAL_ARITH_TAC; VECTOR_ARITH_TAC]));;
12261 let ENDS_NOT_IN_SEGMENT = prove
12262 (`!a b. ~(a IN segment(a,b)) /\ ~(b IN segment(a,b))`,
12263 REWRITE_TAC[open_segment] THEN SET_TAC[]);;
12265 let SEGMENT_CLOSED_OPEN = prove
12266 (`!a b. segment[a,b] = segment(a,b) UNION {a,b}`,
12267 REPEAT GEN_TAC THEN REWRITE_TAC[open_segment] THEN MATCH_MP_TAC(SET_RULE
12268 `a IN s /\ b IN s ==> s = (s DIFF {a,b}) UNION {a,b}`) THEN
12269 REWRITE_TAC[ENDS_IN_SEGMENT]);;
12271 let MIDPOINT_IN_SEGMENT = prove
12272 (`(!a b:real^N. midpoint(a,b) IN segment[a,b]) /\
12273 (!a b:real^N. midpoint(a,b) IN segment(a,b) <=> ~(a = b))`,
12274 REWRITE_TAC[IN_SEGMENT] THEN REPEAT STRIP_TAC THENL
12275 [ALL_TAC; ASM_CASES_TAC `a:real^N = b` THEN ASM_REWRITE_TAC[]] THEN
12276 EXISTS_TAC `&1 / &2` THEN REWRITE_TAC[midpoint] THEN
12277 CONV_TAC REAL_RAT_REDUCE_CONV THEN VECTOR_ARITH_TAC);;
12279 let BETWEEN_IN_SEGMENT = prove
12280 (`!x a b:real^N. between x (a,b) <=> x IN segment[a,b]`,
12281 REPEAT GEN_TAC THEN REWRITE_TAC[between] THEN
12282 ASM_CASES_TAC `a:real^N = b` THEN
12283 ASM_REWRITE_TAC[SEGMENT_REFL; IN_SING] THENL [NORM_ARITH_TAC; ALL_TAC] THEN
12284 REWRITE_TAC[segment; IN_ELIM_THM] THEN EQ_TAC THENL
12285 [DISCH_THEN(ASSUME_TAC o SYM) THEN
12286 EXISTS_TAC `dist(a:real^N,x) / dist(a,b)` THEN
12287 ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; DIST_POS_LT] THEN CONJ_TAC
12288 THENL [FIRST_ASSUM(SUBST1_TAC o SYM) THEN NORM_ARITH_TAC; ALL_TAC] THEN
12289 MATCH_MP_TAC VECTOR_MUL_LCANCEL_IMP THEN EXISTS_TAC `dist(a:real^N,b)` THEN
12290 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; VECTOR_ADD_LDISTRIB; REAL_SUB_LDISTRIB;
12291 REAL_DIV_LMUL; DIST_EQ_0] THEN
12292 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DIST_TRIANGLE_EQ] o SYM) THEN
12293 FIRST_ASSUM(SUBST1_TAC o SYM) THEN
12294 REWRITE_TAC[dist; REAL_ARITH `(a + b) * &1 - a = b`] THEN
12296 STRIP_TAC THEN ASM_REWRITE_TAC[dist] THEN
12297 REWRITE_TAC[VECTOR_ARITH `a - ((&1 - u) % a + u % b) = u % (a - b)`;
12298 VECTOR_ARITH `((&1 - u) % a + u % b) - b = (&1 - u) % (a - b)`;
12299 NORM_MUL; GSYM REAL_ADD_LDISTRIB] THEN
12300 REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD]);;
12302 let IN_SEGMENT_COMPONENT = prove
12304 x IN segment[a,b] /\ 1 <= i /\ i <= dimindex(:N)
12305 ==> min (a$i) (b$i) <= x$i /\ x$i <= max (a$i) (b$i)`,
12306 REPEAT STRIP_TAC THEN
12307 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT]) THEN
12308 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
12309 FIRST_X_ASSUM(X_CHOOSE_THEN `t:real` STRIP_ASSUME_TAC) THEN
12310 ASM_REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
12311 SIMP_TAC[REAL_ARITH `c <= u * a + t * b <=> u * --a + t * --b <= --c`] THEN
12312 MATCH_MP_TAC REAL_CONVEX_BOUND_LE THEN ASM_REAL_ARITH_TAC);;
12314 let SEGMENT_1 = prove
12315 (`(!a b. segment[a,b] =
12316 if drop a <= drop b then interval[a,b] else interval[b,a]) /\
12317 (!a b. segment(a,b) =
12318 if drop a <= drop b then interval(a,b) else interval(b,a))`,
12319 CONJ_TAC THEN REPEAT GEN_TAC THEN REWRITE_TAC[open_segment] THEN
12320 COND_CASES_TAC THEN
12321 REWRITE_TAC[IN_DIFF; IN_INSERT; NOT_IN_EMPTY;
12322 EXTENSION; GSYM BETWEEN_IN_SEGMENT; between; IN_INTERVAL_1] THEN
12323 REWRITE_TAC[GSYM DROP_EQ; DIST_REAL; GSYM drop] THEN ASM_REAL_ARITH_TAC);;
12325 let OPEN_SEGMENT_1 = prove
12326 (`!a b:real^1. open(segment(a,b))`,
12327 REPEAT GEN_TAC THEN REWRITE_TAC[SEGMENT_1] THEN
12328 COND_CASES_TAC THEN REWRITE_TAC[OPEN_INTERVAL]);;
12330 let SEGMENT_TRANSLATION = prove
12331 (`(!c a b. segment[c + a,c + b] = IMAGE (\x. c + x) (segment[a,b])) /\
12332 (!c a b. segment(c + a,c + b) = IMAGE (\x. c + x) (segment(a,b)))`,
12333 REWRITE_TAC[EXTENSION; IN_SEGMENT; IN_IMAGE] THEN
12334 REWRITE_TAC[VECTOR_ARITH `(&1 - u) % (c + a) + u % (c + b) =
12335 c + (&1 - u) % a + u % b`] THEN
12336 REWRITE_TAC[VECTOR_ARITH `c + a:real^N = c + b <=> a = b`] THEN
12339 add_translation_invariants
12340 [CONJUNCT1 SEGMENT_TRANSLATION; CONJUNCT2 SEGMENT_TRANSLATION];;
12342 let CLOSED_SEGMENT_LINEAR_IMAGE = prove
12344 ==> segment[f a,f b] = IMAGE f (segment[a,b])`,
12345 REPEAT STRIP_TAC THEN REWRITE_TAC[EXTENSION; IN_IMAGE; IN_SEGMENT] THEN
12346 FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_CMUL th)]) THEN
12347 FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_ADD th)]) THEN
12350 add_linear_invariants [CLOSED_SEGMENT_LINEAR_IMAGE];;
12352 let OPEN_SEGMENT_LINEAR_IMAGE = prove
12353 (`!f:real^M->real^N a b.
12354 linear f /\ (!x y. f x = f y ==> x = y)
12355 ==> segment(f a,f b) = IMAGE f (segment(a,b))`,
12356 REWRITE_TAC[open_segment] THEN GEOM_TRANSFORM_TAC[]);;
12358 add_linear_invariants [OPEN_SEGMENT_LINEAR_IMAGE];;
12360 let IN_OPEN_SEGMENT = prove
12362 x IN segment(a,b) <=> x IN segment[a,b] /\ ~(x = a) /\ ~(x = b)`,
12363 REPEAT GEN_TAC THEN REWRITE_TAC[open_segment; IN_DIFF] THEN SET_TAC[]);;
12365 let IN_OPEN_SEGMENT_ALT = prove
12367 x IN segment(a,b) <=>
12368 x IN segment[a,b] /\ ~(x = a) /\ ~(x = b) /\ ~(a = b)`,
12369 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = b` THEN
12370 ASM_REWRITE_TAC[SEGMENT_REFL; IN_SING; NOT_IN_EMPTY] THEN
12371 ASM_MESON_TAC[IN_OPEN_SEGMENT]);;
12373 let COLLINEAR_DIST_IN_CLOSED_SEGMENT = prove
12374 (`!a b x. collinear {x,a,b} /\
12375 dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)
12376 ==> x IN segment[a,b]`,
12377 REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT; COLLINEAR_DIST_BETWEEN]);;
12379 let COLLINEAR_DIST_IN_OPEN_SEGMENT = prove
12380 (`!a b x. collinear {x,a,b} /\
12381 dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b)
12382 ==> x IN segment(a,b)`,
12383 REWRITE_TAC[IN_OPEN_SEGMENT] THEN
12384 MESON_TAC[COLLINEAR_DIST_IN_CLOSED_SEGMENT; REAL_LT_LE; DIST_SYM]);;
12386 let SEGMENT_SCALAR_MULTIPLE = prove
12387 (`(!a b v. segment[a % v,b % v] =
12388 {x % v:real^N | a <= x /\ x <= b \/ b <= x /\ x <= a}) /\
12389 (!a b v. ~(v = vec 0)
12390 ==> segment(a % v,b % v) =
12391 {x % v:real^N | a < x /\ x < b \/ b < x /\ x < a})`,
12392 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN REPEAT STRIP_TAC THENL
12393 [REPEAT GEN_TAC THEN
12394 MP_TAC(SPECL [`a % basis 1:real^1`; `b % basis 1:real^1`]
12395 (CONJUNCT1 SEGMENT_1)) THEN
12396 REWRITE_TAC[segment; VECTOR_MUL_ASSOC; GSYM VECTOR_ADD_RDISTRIB] THEN
12397 REWRITE_TAC[SET_RULE `{f x % b | p x} = IMAGE (\a. a % b) {f x | p x}`] THEN
12398 DISCH_TAC THEN AP_TERM_TAC THEN
12399 FIRST_X_ASSUM(MP_TAC o AP_TERM `IMAGE drop`) THEN
12400 REWRITE_TAC[GSYM IMAGE_o; o_DEF; DROP_CMUL] THEN
12401 SIMP_TAC[drop; BASIS_COMPONENT; DIMINDEX_GE_1; LE_REFL] THEN
12402 REWRITE_TAC[REAL_MUL_RID; IMAGE_ID] THEN DISCH_THEN SUBST1_TAC THEN
12403 MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
12404 CONJ_TAC THENL [MESON_TAC[LIFT_DROP]; ALL_TAC] THEN
12405 REWRITE_TAC[FORALL_LIFT; LIFT_DROP] THEN GEN_TAC THEN
12406 COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP] THEN
12407 SIMP_TAC[drop; VECTOR_MUL_COMPONENT; BASIS_COMPONENT; DIMINDEX_GE_1;
12408 LE_REFL; IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC;
12409 ASM_REWRITE_TAC[open_segment] THEN
12410 ASM_SIMP_TAC[VECTOR_MUL_RCANCEL; SET_RULE
12411 `(!x y. x % v = y % v <=> x = y)
12412 ==> {x % v | P x} DIFF {a % v,b % v} =
12413 {x % v | P x /\ ~(x = a) /\ ~(x = b)}`] THEN
12414 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN AP_TERM_TAC THEN
12415 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN REAL_ARITH_TAC]);;
12417 let FINITE_INTER_COLLINEAR_OPEN_SEGMENTS = prove
12420 ==> (FINITE(segment(a,b) INTER segment(c,d)) <=>
12421 segment(a,b) INTER segment(c,d) = {})`,
12422 REPEAT GEN_TAC THEN ABBREV_TAC `m:real^N = b - a` THEN POP_ASSUM MP_TAC THEN
12423 GEOM_NORMALIZE_TAC `m:real^N` THEN
12424 SIMP_TAC[VECTOR_SUB_EQ; SEGMENT_REFL; INTER_EMPTY; FINITE_EMPTY] THEN
12425 X_GEN_TAC `m:real^N` THEN DISCH_TAC THEN REPEAT GEN_TAC THEN
12426 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN POP_ASSUM MP_TAC THEN
12427 GEOM_ORIGIN_TAC `a:real^N` THEN GEOM_BASIS_MULTIPLE_TAC 1 `b:real^N` THEN
12428 X_GEN_TAC `b:real` THEN DISCH_TAC THEN
12429 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN
12430 SIMP_TAC[VECTOR_SUB_RZERO; NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN
12431 ASM_REWRITE_TAC[real_abs; REAL_MUL_RID] THEN DISCH_THEN SUBST_ALL_TAC THEN
12432 POP_ASSUM(K ALL_TAC) THEN
12433 ASM_CASES_TAC `collinear{vec 0:real^N,&1 % basis 1,y}` THENL
12434 [POP_ASSUM MP_TAC THEN
12435 SIMP_TAC[COLLINEAR_LEMMA_ALT; BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL] THEN
12437 `~a /\ (b ==> c ==> d) ==> a \/ b ==> a \/ c ==> d`) THEN
12439 [SIMP_TAC[VECTOR_MUL_LID; BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL];
12440 REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN
12441 X_GEN_TAC `b:real` THEN DISCH_THEN SUBST_ALL_TAC THEN
12442 X_GEN_TAC `a:real` THEN DISCH_THEN SUBST_ALL_TAC THEN
12443 REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RID] THEN
12444 SUBST1_TAC(VECTOR_ARITH `vec 0:real^N = &0 % basis 1`) THEN
12445 SIMP_TAC[SEGMENT_SCALAR_MULTIPLE; BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL;
12446 VECTOR_MUL_RCANCEL; IMAGE_EQ_EMPTY; FINITE_IMAGE_INJ_EQ; SET_RULE
12447 `(!x y. x % v = y % v <=> x = y)
12448 ==> {x % v | P x} INTER {x % v | Q x} =
12449 IMAGE (\x. x % v) {x | P x /\ Q x}`] THEN
12450 REWRITE_TAC[REAL_ARITH `(&0 < x /\ x < &1 \/ &1 < x /\ x < &0) /\
12451 (b < x /\ x < a \/ a < x /\ x < b) <=>
12452 max (&0) (min a b) < x /\ x < min (&1) (max a b)`] THEN
12453 SIMP_TAC[FINITE_REAL_INTERVAL; EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM] THEN
12454 SIMP_TAC[GSYM REAL_LT_BETWEEN; GSYM NOT_EXISTS_THM] THEN REAL_ARITH_TAC;
12455 DISCH_TAC THEN ASM_CASES_TAC
12456 `segment(vec 0:real^N,&1 % basis 1) INTER segment (x,y) = {}` THEN
12457 ASM_REWRITE_TAC[FINITE_EMPTY] THEN DISCH_THEN(K ALL_TAC) THEN
12458 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
12459 REWRITE_TAC[open_segment; IN_DIFF; NOT_IN_EMPTY;
12460 DE_MORGAN_THM; IN_INTER; IN_INSERT] THEN
12461 DISCH_THEN(X_CHOOSE_THEN `p:real^N` STRIP_ASSUME_TAC) THEN
12462 UNDISCH_TAC `~collinear{vec 0:real^N,&1 % basis 1, y}` THEN
12463 RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_MUL_LID]) THEN
12464 REWRITE_TAC[VECTOR_MUL_LID] THEN
12465 MATCH_MP_TAC COLLINEAR_SUBSET THEN
12466 EXISTS_TAC `{p,x:real^N, y, vec 0, basis 1}` THEN
12467 CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN
12468 MP_TAC(ISPECL [`{y:real^N,vec 0,basis 1}`; `p:real^N`; `x:real^N`]
12469 COLLINEAR_TRIPLES) THEN
12470 ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN
12471 REWRITE_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY] THEN CONJ_TAC THENL
12472 [ONCE_REWRITE_TAC[SET_RULE `{p,x,y} = {x,p,y}`] THEN
12473 MATCH_MP_TAC BETWEEN_IMP_COLLINEAR THEN
12474 ASM_REWRITE_TAC[BETWEEN_IN_SEGMENT];
12476 ASM_SIMP_TAC[GSYM COLLINEAR_4_3] THEN
12477 ONCE_REWRITE_TAC[SET_RULE `{p,x,z,w} = {w,z,p,x}`] THEN
12478 SIMP_TAC[COLLINEAR_4_3; BASIS_NONZERO; DIMINDEX_GE_1; ARITH] THEN
12479 REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP BETWEEN_IMP_COLLINEAR o
12480 GEN_REWRITE_RULE I [GSYM BETWEEN_IN_SEGMENT])) THEN
12481 REPEAT(POP_ASSUM MP_TAC) THEN SIMP_TAC[INSERT_AC]]);;
12483 let DIST_IN_CLOSED_SEGMENT,DIST_IN_OPEN_SEGMENT = (CONJ_PAIR o prove)
12485 x IN segment[a,b] ==> dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)) /\
12487 x IN segment(a,b) ==> dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b))`,
12488 SIMP_TAC[IN_SEGMENT; RIGHT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM; dist;
12490 `((&1 - u) % a + u % b) - a:real^N = u % (b - a) /\
12491 ((&1 - u) % a + u % b) - b = --(&1 - u) % (b - a)`] THEN
12492 REWRITE_TAC[NORM_MUL; REAL_ABS_NEG; NORM_SUB] THEN CONJ_TAC THEN
12493 REPEAT GEN_TAC THEN STRIP_TAC THENL
12494 [REWRITE_TAC[REAL_ARITH `x * y <= y <=> x * y <= &1 * y`] THEN
12495 CONJ_TAC THEN MATCH_MP_TAC REAL_LE_RMUL THEN
12496 REWRITE_TAC[NORM_POS_LE] THEN ASM_REAL_ARITH_TAC;
12497 REWRITE_TAC[REAL_ARITH `x * y < y <=> x * y < &1 * y`] THEN
12498 ASM_SIMP_TAC[REAL_LT_RMUL_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN
12499 ASM_REAL_ARITH_TAC]);;
12501 let DIST_DECREASES_OPEN_SEGMENT = prove
12503 x IN segment(a,b) ==> dist(c,x) < dist(c,a) \/ dist(c,x) < dist(c,b)`,
12504 GEOM_ORIGIN_TAC `a:real^N` THEN GEOM_NORMALIZE_TAC `b:real^N` THEN
12505 REWRITE_TAC[SEGMENT_REFL; NOT_IN_EMPTY] THEN X_GEN_TAC `b:real^N` THEN
12506 GEOM_BASIS_MULTIPLE_TAC 1 `b:real^N` THEN X_GEN_TAC `b:real` THEN
12507 SIMP_TAC[NORM_MUL; NORM_BASIS; real_abs; DIMINDEX_GE_1; LE_REFL;
12508 REAL_MUL_RID; VECTOR_MUL_LID] THEN
12509 REPEAT(DISCH_THEN(K ALL_TAC)) THEN REPEAT GEN_TAC THEN
12510 REWRITE_TAC[IN_SEGMENT; dist] THEN STRIP_TAC THEN
12511 ASM_REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN
12513 `norm((c$1 - u) % basis 1:real^N) < norm((c:real^N)$1 % basis 1:real^N) \/
12514 norm((c$1 - u) % basis 1:real^N) < norm((c$1 - &1) % basis 1:real^N)`
12516 [SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN
12517 ASM_REAL_ARITH_TAC;
12518 ASM_SIMP_TAC[NORM_LT; DOT_LMUL; DOT_RMUL; DOT_BASIS; DIMINDEX_GE_1;
12519 DOT_LSUB; DOT_RSUB; LE_REFL; VECTOR_MUL_COMPONENT; VEC_COMPONENT;
12520 BASIS_COMPONENT; DOT_LZERO; DOT_RZERO; VECTOR_SUB_COMPONENT] THEN
12521 ASM_REAL_ARITH_TAC]);;
12523 let DIST_DECREASES_CLOSED_SEGMENT = prove
12525 x IN segment[a,b] ==> dist(c,x) <= dist(c,a) \/ dist(c,x) <= dist(c,b)`,
12526 REWRITE_TAC[SEGMENT_CLOSED_OPEN; IN_UNION; IN_INSERT; NOT_IN_EMPTY] THEN
12527 ASM_MESON_TAC[DIST_DECREASES_OPEN_SEGMENT; REAL_LE_REFL; REAL_LT_IMP_LE]);;
12529 (* ------------------------------------------------------------------------- *)
12530 (* Limit component bounds. *)
12531 (* ------------------------------------------------------------------------- *)
12533 let LIM_COMPONENT_UBOUND = prove
12534 (`!net:(A)net f (l:real^N) b k.
12535 ~(trivial_limit net) /\ (f --> l) net /\
12536 eventually (\x. (f x)$k <= b) net /\
12537 1 <= k /\ k <= dimindex(:N)
12539 REPEAT STRIP_TAC THEN MP_TAC(ISPECL
12540 [`net:(A)net`; `f:A->real^N`; `{y:real^N | basis k dot y <= b}`; `l:real^N`]
12541 LIM_IN_CLOSED_SET) THEN
12542 ASM_SIMP_TAC[CLOSED_HALFSPACE_LE; IN_ELIM_THM; DOT_BASIS]);;
12544 let LIM_COMPONENT_LBOUND = prove
12545 (`!net:(A)net f (l:real^N) b k.
12546 ~(trivial_limit net) /\ (f --> l) net /\
12547 eventually (\x. b <= (f x)$k) net /\
12548 1 <= k /\ k <= dimindex(:N)
12550 REPEAT STRIP_TAC THEN MP_TAC(ISPECL
12551 [`net:(A)net`; `f:A->real^N`; `{y:real^N | b <= basis k dot y}`; `l:real^N`]
12552 LIM_IN_CLOSED_SET) THEN
12553 ASM_SIMP_TAC[REWRITE_RULE[real_ge] CLOSED_HALFSPACE_GE;
12554 IN_ELIM_THM; DOT_BASIS]);;
12556 let LIM_COMPONENT_EQ = prove
12557 (`!net f:A->real^N i l b.
12558 (f --> l) net /\ 1 <= i /\ i <= dimindex(:N) /\
12559 ~(trivial_limit net) /\ eventually (\x. f(x)$i = b) net
12561 REWRITE_TAC[GSYM REAL_LE_ANTISYM; EVENTUALLY_AND] THEN
12562 MESON_TAC[LIM_COMPONENT_UBOUND; LIM_COMPONENT_LBOUND]);;
12564 let LIM_COMPONENT_LE = prove
12565 (`!net:(A)net f:A->real^N g:A->real^N k l m.
12566 ~(trivial_limit net) /\ (f --> l) net /\ (g --> m) net /\
12567 eventually (\x. (f x)$k <= (g x)$k) net /\
12568 1 <= k /\ k <= dimindex(:N)
12570 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LE] THEN
12571 REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT; LIM_COMPONENT_LBOUND] THEN
12572 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
12573 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> b /\ a ==> c ==> d`] THEN
12574 DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN POP_ASSUM MP_TAC THEN
12575 REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; LIM_COMPONENT_LBOUND]);;
12577 let LIM_DROP_LE = prove
12578 (`!net:(A)net f g l m.
12579 ~(trivial_limit net) /\ (f --> l) net /\ (g --> m) net /\
12580 eventually (\x. drop(f x) <= drop(g x)) net
12581 ==> drop l <= drop m`,
12582 REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN
12583 MATCH_MP_TAC(ISPEC `net:(A)net` LIM_COMPONENT_LE) THEN
12584 MAP_EVERY EXISTS_TAC [`f:A->real^1`; `g:A->real^1`] THEN
12585 ASM_REWRITE_TAC[DIMINDEX_1; LE_REFL]);;
12587 let LIM_DROP_UBOUND = prove
12588 (`!net f:A->real^1 l b.
12590 ~(trivial_limit net) /\ eventually (\x. drop(f x) <= b) net
12592 SIMP_TAC[drop] THEN REPEAT STRIP_TAC THEN
12593 MATCH_MP_TAC LIM_COMPONENT_UBOUND THEN
12594 REWRITE_TAC[LE_REFL; DIMINDEX_1] THEN ASM_MESON_TAC[]);;
12596 let LIM_DROP_LBOUND = prove
12597 (`!net f:A->real^1 l b.
12599 ~(trivial_limit net) /\ eventually (\x. b <= drop(f x)) net
12601 SIMP_TAC[drop] THEN REPEAT STRIP_TAC THEN
12602 MATCH_MP_TAC LIM_COMPONENT_LBOUND THEN
12603 REWRITE_TAC[LE_REFL; DIMINDEX_1] THEN ASM_MESON_TAC[]);;
12605 (* ------------------------------------------------------------------------- *)
12606 (* Also extending closed bounds to closures. *)
12607 (* ------------------------------------------------------------------------- *)
12609 let IMAGE_CLOSURE_SUBSET = prove
12610 (`!f (s:real^N->bool) (t:real^M->bool).
12611 f continuous_on closure s /\ closed t /\ IMAGE f s SUBSET t
12612 ==> IMAGE f (closure s) SUBSET t`,
12613 REPEAT STRIP_TAC THEN
12614 SUBGOAL_THEN `closure s SUBSET {x | (f:real^N->real^M) x IN t}` MP_TAC
12615 THENL [MATCH_MP_TAC SUBSET_TRANS; SET_TAC []] THEN
12616 EXISTS_TAC `{x | x IN closure s /\ (f:real^N->real^M) x IN t}` THEN
12618 [MATCH_MP_TAC CLOSURE_MINIMAL; SET_TAC[]] THEN
12619 ASM_SIMP_TAC[CONTINUOUS_CLOSED_PREIMAGE; CLOSED_CLOSURE] THEN
12620 MP_TAC (ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]);;
12622 let CLOSURE_IMAGE_CLOSURE = prove
12623 (`!f:real^M->real^N s.
12624 f continuous_on closure s
12625 ==> closure(IMAGE f (closure s)) = closure(IMAGE f s)`,
12626 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN
12627 SIMP_TAC[SUBSET_CLOSURE; IMAGE_SUBSET; CLOSURE_SUBSET] THEN
12628 SIMP_TAC[CLOSURE_MINIMAL_EQ; CLOSED_CLOSURE] THEN
12629 MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN
12630 ASM_REWRITE_TAC[CLOSED_CLOSURE; CLOSURE_SUBSET]);;
12632 let CLOSURE_IMAGE_BOUNDED = prove
12633 (`!f:real^M->real^N s.
12634 f continuous_on closure s /\ bounded s
12635 ==> closure(IMAGE f s) = IMAGE f (closure s)`,
12636 REPEAT STRIP_TAC THEN
12637 TRANS_TAC EQ_TRANS `closure(IMAGE (f:real^M->real^N) (closure s))` THEN
12638 CONJ_TAC THENL [ASM_MESON_TAC[CLOSURE_IMAGE_CLOSURE]; ALL_TAC] THEN
12639 MATCH_MP_TAC CLOSURE_CLOSED THEN MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
12640 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
12641 ASM_REWRITE_TAC[COMPACT_CLOSURE]);;
12643 let CONTINUOUS_ON_CLOSURE_NORM_LE = prove
12644 (`!f:real^N->real^M s x b.
12645 f continuous_on (closure s) /\
12646 (!y. y IN s ==> norm(f y) <= b) /\
12648 ==> norm(f x) <= b`,
12649 REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN
12650 SUBGOAL_THEN `IMAGE (f:real^N->real^M) (closure s) SUBSET cball(vec 0,b)`
12652 [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET; ASM SET_TAC []] THEN
12653 ASM_REWRITE_TAC [CLOSED_CBALL] THEN ASM SET_TAC []);;
12655 let CONTINUOUS_ON_CLOSURE_COMPONENT_LE = prove
12656 (`!f:real^N->real^M s x b k.
12657 f continuous_on (closure s) /\
12658 (!y. y IN s ==> (f y)$k <= b) /\
12661 REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN
12662 SUBGOAL_THEN `IMAGE (f:real^N->real^M) (closure s) SUBSET {x | x$k <= b}`
12664 [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET; ASM SET_TAC []] THEN
12665 ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE] THEN ASM SET_TAC[]);;
12667 let CONTINUOUS_ON_CLOSURE_COMPONENT_GE = prove
12668 (`!f:real^N->real^M s x b k.
12669 f continuous_on (closure s) /\
12670 (!y. y IN s ==> b <= (f y)$k) /\
12673 REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN
12674 SUBGOAL_THEN `IMAGE (f:real^N->real^M) (closure s) SUBSET {x | x$k >= b}`
12676 [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET; ASM SET_TAC [real_ge]] THEN
12677 ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_GE] THEN ASM SET_TAC[real_ge]);;
12679 (* ------------------------------------------------------------------------- *)
12680 (* Limits relative to a union. *)
12681 (* ------------------------------------------------------------------------- *)
12683 let LIM_WITHIN_UNION = prove
12684 (`(f --> l) (at x within (s UNION t)) <=>
12685 (f --> l) (at x within s) /\ (f --> l) (at x within t)`,
12686 REWRITE_TAC[LIM_WITHIN; IN_UNION; AND_FORALL_THM] THEN
12687 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN
12688 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
12689 EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN DISCH_THEN
12690 (CONJUNCTS_THEN2 (X_CHOOSE_TAC `d:real`) (X_CHOOSE_TAC `k:real`)) THEN
12691 EXISTS_TAC `min d k` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
12694 let CONTINUOUS_ON_UNION = prove
12695 (`!f s t. closed s /\ closed t /\ f continuous_on s /\ f continuous_on t
12696 ==> f continuous_on (s UNION t)`,
12697 REWRITE_TAC[CONTINUOUS_ON; CLOSED_LIMPT; IN_UNION; LIM_WITHIN_UNION] THEN
12698 MESON_TAC[LIM; TRIVIAL_LIMIT_WITHIN]);;
12700 let CONTINUOUS_ON_CASES = prove
12701 (`!P f g:real^M->real^N s t.
12702 closed s /\ closed t /\ f continuous_on s /\ g continuous_on t /\
12703 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x)
12704 ==> (\x. if P x then f x else g x) continuous_on (s UNION t)`,
12705 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION THEN
12706 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL
12707 [EXISTS_TAC `f:real^M->real^N`; EXISTS_TAC `g:real^M->real^N`] THEN
12708 ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;
12710 let CONTINUOUS_ON_UNION_LOCAL = prove
12711 (`!f:real^M->real^N s.
12712 closed_in (subtopology euclidean (s UNION t)) s /\
12713 closed_in (subtopology euclidean (s UNION t)) t /\
12714 f continuous_on s /\ f continuous_on t
12715 ==> f continuous_on (s UNION t)`,
12716 REWRITE_TAC[CONTINUOUS_ON; CLOSED_IN_LIMPT; IN_UNION; LIM_WITHIN_UNION] THEN
12717 MESON_TAC[LIM; TRIVIAL_LIMIT_WITHIN]);;
12719 let CONTINUOUS_ON_CASES_LOCAL = prove
12720 (`!P f g:real^M->real^N s t.
12721 closed_in (subtopology euclidean (s UNION t)) s /\
12722 closed_in (subtopology euclidean (s UNION t)) t /\
12723 f continuous_on s /\ g continuous_on t /\
12724 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x)
12725 ==> (\x. if P x then f x else g x) continuous_on (s UNION t)`,
12726 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL THEN
12727 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL
12728 [EXISTS_TAC `f:real^M->real^N`; EXISTS_TAC `g:real^M->real^N`] THEN
12729 ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;
12731 let CONTINUOUS_ON_CASES_LE = prove
12732 (`!f g:real^M->real^N h s a.
12733 f continuous_on {t | t IN s /\ h t <= a} /\
12734 g continuous_on {t | t IN s /\ a <= h t} /\
12735 (lift o h) continuous_on s /\
12736 (!t. t IN s /\ h t = a ==> f t = g t)
12737 ==> (\t. if h t <= a then f(t) else g(t)) continuous_on s`,
12738 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC
12739 `{t | t IN s /\ (h:real^M->real) t <= a} UNION
12740 {t | t IN s /\ a <= h t}` THEN
12742 [ALL_TAC; SIMP_TAC[SUBSET; IN_UNION; IN_ELIM_THM; REAL_LE_TOTAL]] THEN
12743 MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN ASM_REWRITE_TAC[] THEN
12744 REWRITE_TAC[IN_ELIM_THM; GSYM CONJ_ASSOC; REAL_LE_ANTISYM] THEN
12745 REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL
12746 [ALL_TAC; ASM_MESON_TAC[]] THEN
12749 `{t | t IN s /\ (h:real^M->real) t <= a} =
12750 {t | t IN ({t | t IN s /\ h t <= a} UNION {t | t IN s /\ a <= h t}) /\
12751 (lift o h) t IN {x | x$1 <= a}}`
12752 (fun th -> GEN_REWRITE_TAC RAND_CONV [th])
12754 [REWRITE_TAC[GSYM drop; o_THM; IN_ELIM_THM; LIFT_DROP; EXTENSION;
12756 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
12757 ASM_REAL_ARITH_TAC;
12758 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN
12759 ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE; ETA_AX] THEN
12760 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
12761 CONTINUOUS_ON_SUBSET)) THEN
12764 `{t | t IN s /\ a <= (h:real^M->real) t} =
12765 {t | t IN ({t | t IN s /\ h t <= a} UNION {t | t IN s /\ a <= h t}) /\
12766 (lift o h) t IN {x | x$1 >= a}}`
12767 (fun th -> GEN_REWRITE_TAC RAND_CONV [th])
12769 [REWRITE_TAC[GSYM drop; o_THM; IN_ELIM_THM; LIFT_DROP; EXTENSION;
12771 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
12772 ASM_REAL_ARITH_TAC;
12773 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN
12774 ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_GE; ETA_AX] THEN
12775 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
12776 CONTINUOUS_ON_SUBSET)) THEN
12779 let CONTINUOUS_ON_CASES_1 = prove
12780 (`!f g:real^1->real^N s a.
12781 f continuous_on {t | t IN s /\ drop t <= a} /\
12782 g continuous_on {t | t IN s /\ a <= drop t} /\
12783 (lift a IN s ==> f(lift a) = g(lift a))
12784 ==> (\t. if drop t <= a then f(t) else g(t)) continuous_on s`,
12785 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LE THEN
12786 ASM_REWRITE_TAC[o_DEF; LIFT_DROP; CONTINUOUS_ON_ID] THEN
12787 REWRITE_TAC[GSYM LIFT_EQ; LIFT_DROP] THEN ASM_MESON_TAC[]);;
12789 let EXTENSION_FROM_CLOPEN = prove
12790 (`!f:real^M->real^N s t u.
12791 open_in (subtopology euclidean s) t /\
12792 closed_in (subtopology euclidean s) t /\
12793 f continuous_on t /\ IMAGE f t SUBSET u /\ (u = {} ==> s = {})
12794 ==> ?g. g continuous_on s /\ IMAGE g s SUBSET u /\
12795 !x. x IN t ==> g x = f x`,
12796 REPEAT GEN_TAC THEN ASM_CASES_TAC `u:real^N->bool = {}` THEN
12797 ASM_SIMP_TAC[CONTINUOUS_ON_EMPTY; IMAGE_CLAUSES; SUBSET_EMPTY;
12798 IMAGE_EQ_EMPTY; NOT_IN_EMPTY] THEN
12800 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
12801 DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN
12802 EXISTS_TAC `\x. if x IN t then (f:real^M->real^N) x else a` THEN
12803 SIMP_TAC[SUBSET; FORALL_IN_IMAGE] THEN
12804 CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
12805 FIRST_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
12806 SUBGOAL_THEN `s:real^M->bool = t UNION (s DIFF t)` SUBST1_TAC THENL
12807 [ASM SET_TAC[]; MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL] THEN
12808 ASM_SIMP_TAC[SET_RULE `t SUBSET s ==> t UNION (s DIFF t) = s`] THEN
12809 REWRITE_TAC[CONTINUOUS_ON_CONST; IN_DIFF] THEN
12810 CONJ_TAC THENL [MATCH_MP_TAC CLOSED_IN_DIFF; MESON_TAC[]] THEN
12811 ASM_REWRITE_TAC[CLOSED_IN_REFL]);;
12813 (* ------------------------------------------------------------------------- *)
12814 (* Componentwise limits and continuity. *)
12815 (* ------------------------------------------------------------------------- *)
12817 let LIM_COMPONENTWISE_LIFT = prove
12818 (`!net f:A->real^N.
12820 !i. 1 <= i /\ i <= dimindex(:N)
12821 ==> ((\x. lift((f x)$i)) --> lift(l$i)) net`,
12822 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto] THEN EQ_TAC THENL
12823 [DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
12824 X_GEN_TAC `e:real` THEN
12825 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN
12826 ASM_SIMP_TAC[GSYM VECTOR_SUB_COMPONENT] THEN
12827 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
12828 GEN_TAC THEN REWRITE_TAC[dist] THEN MATCH_MP_TAC(REAL_ARITH
12829 `y <= x ==> x < e ==> y < e`) THEN
12830 ASM_SIMP_TAC[COMPONENT_LE_NORM; GSYM LIFT_SUB; NORM_LIFT;
12831 GSYM VECTOR_SUB_COMPONENT];
12832 GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [RIGHT_IMP_FORALL_THM] THEN
12833 ONCE_REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[IMP_CONJ_ALT] THEN
12834 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
12835 REWRITE_TAC[GSYM IN_NUMSEG; RIGHT_FORALL_IMP_THM] THEN
12836 SIMP_TAC[FORALL_EVENTUALLY; FINITE_NUMSEG; NUMSEG_EMPTY;
12837 GSYM NOT_LE; DIMINDEX_GE_1] THEN
12838 REWRITE_TAC[DIST_LIFT; GSYM VECTOR_SUB_COMPONENT] THEN
12839 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
12840 FIRST_X_ASSUM(MP_TAC o SPEC `e / &(dimindex(:N))`) THEN
12841 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1] THEN
12842 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
12843 X_GEN_TAC `x:A` THEN SIMP_TAC[GSYM VECTOR_SUB_COMPONENT; dist] THEN
12844 DISCH_TAC THEN W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN
12845 MATCH_MP_TAC(REAL_ARITH `s < e ==> n <= s ==> n < e`) THEN
12846 MATCH_MP_TAC SUM_BOUND_LT_GEN THEN
12847 ASM_SIMP_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; GSYM NOT_LE; DIMINDEX_GE_1;
12848 CARD_NUMSEG_1; GSYM IN_NUMSEG]]);;
12850 let CONTINUOUS_COMPONENTWISE_LIFT = prove
12851 (`!net f:A->real^N.
12852 f continuous net <=>
12853 !i. 1 <= i /\ i <= dimindex(:N)
12854 ==> (\x. lift((f x)$i)) continuous net`,
12855 REWRITE_TAC[continuous; GSYM LIM_COMPONENTWISE_LIFT]);;
12857 let CONTINUOUS_ON_COMPONENTWISE_LIFT = prove
12858 (`!f:real^M->real^N s.
12859 f continuous_on s <=>
12860 !i. 1 <= i /\ i <= dimindex(:N)
12861 ==> (\x. lift((f x)$i)) continuous_on s`,
12862 REPEAT GEN_TAC THEN
12863 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
12864 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
12865 [CONTINUOUS_COMPONENTWISE_LIFT] THEN
12868 (* ------------------------------------------------------------------------- *)
12869 (* Some more convenient intermediate-value theorem formulations. *)
12870 (* ------------------------------------------------------------------------- *)
12872 let CONNECTED_IVT_HYPERPLANE = prove
12873 (`!s x y:real^N a b.
12875 x IN s /\ y IN s /\ a dot x <= b /\ b <= a dot y
12876 ==> ?z. z IN s /\ a dot z = b`,
12877 REPEAT STRIP_TAC THEN
12878 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [connected]) THEN
12879 REWRITE_TAC[NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o SPECL
12880 [`{x:real^N | a dot x < b}`; `{x:real^N | a dot x > b}`]) THEN
12881 REWRITE_TAC[OPEN_HALFSPACE_LT; OPEN_HALFSPACE_GT] THEN
12882 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN STRIP_TAC THEN
12883 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; NOT_IN_EMPTY; SUBSET;
12884 IN_UNION; REAL_LT_LE; real_gt] THEN
12885 ASM_MESON_TAC[REAL_LE_TOTAL; REAL_LE_ANTISYM]);;
12887 let CONNECTED_IVT_COMPONENT = prove
12888 (`!s x y:real^N a k.
12889 connected s /\ x IN s /\ y IN s /\
12890 1 <= k /\ k <= dimindex(:N) /\ x$k <= a /\ a <= y$k
12891 ==> ?z. z IN s /\ z$k = a`,
12892 REPEAT STRIP_TAC THEN MP_TAC(ISPECL
12893 [`s:real^N->bool`; `x:real^N`; `y:real^N`; `(basis k):real^N`;
12894 `a:real`] CONNECTED_IVT_HYPERPLANE) THEN
12895 ASM_SIMP_TAC[DOT_BASIS]);;
12897 (* ------------------------------------------------------------------------- *)
12898 (* Rather trivial observation that we can map any connected set on segment. *)
12899 (* ------------------------------------------------------------------------- *)
12901 let MAPPING_CONNECTED_ONTO_SEGMENT = prove
12902 (`!s:real^M->bool a b:real^N.
12903 connected s /\ ~(?a. s SUBSET {a})
12904 ==> ?f. f continuous_on s /\ IMAGE f s = segment[a,b]`,
12905 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE
12906 `~(?a. s SUBSET {a}) ==> ?a b. a IN s /\ b IN s /\ ~(a = b)`)) THEN
12907 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
12908 MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN STRIP_TAC THEN EXISTS_TAC
12909 `\x:real^M. a + dist(u,x) / (dist(u,x) + dist(v,x)) % (b - a:real^N)` THEN
12911 [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
12912 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN SIMP_TAC[o_DEF; CONTINUOUS_ON_CONST];
12913 REWRITE_TAC[segment; VECTOR_ARITH
12914 `(&1 - u) % a + u % b:real^N = a + u % (b - a)`] THEN
12915 MATCH_MP_TAC(SET_RULE
12916 `IMAGE f s = {x | P x}
12917 ==> IMAGE (\x. a + f x % b) s = {a + u % b:real^N | P u}`) THEN
12918 REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET; FORALL_IN_IMAGE] THEN
12919 ASM_SIMP_TAC[IN_ELIM_THM; REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ;
12920 NORM_ARITH `~(u:real^N = v) ==> &0 < dist(u,x) + dist(v,x)`] THEN
12921 CONJ_TAC THENL [CONV_TAC NORM_ARITH; REWRITE_TAC[IN_IMAGE]] THEN
12922 X_GEN_TAC `t:real` THEN STRIP_TAC THEN
12924 [`IMAGE (\x:real^M. lift(dist(u,x) / (dist(u,x) + dist(v,x)))) s`;
12925 `vec 0:real^1`; `vec 1:real^1`; `t:real`; `1`]
12926 CONNECTED_IVT_COMPONENT) THEN
12927 ASM_SIMP_TAC[VEC_COMPONENT; DIMINDEX_1; ARITH_LE] THEN
12928 REWRITE_TAC[EXISTS_IN_IMAGE; GSYM drop; LIFT_DROP] THEN
12929 ANTS_TAC THENL [REWRITE_TAC[IN_IMAGE]; MESON_TAC[]] THEN
12930 REPEAT CONJ_TAC THENL
12931 [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[];
12932 EXISTS_TAC `u:real^M` THEN ASM_REWRITE_TAC[DIST_REFL; real_div] THEN
12933 REWRITE_TAC[GSYM LIFT_NUM; LIFT_EQ] THEN REAL_ARITH_TAC;
12934 EXISTS_TAC `v:real^M` THEN ASM_REWRITE_TAC[DIST_REFL] THEN
12935 ASM_SIMP_TAC[REAL_DIV_REFL; DIST_EQ_0; REAL_ADD_RID] THEN
12936 REWRITE_TAC[GSYM LIFT_NUM; LIFT_EQ]]] THEN
12937 REWRITE_TAC[real_div; LIFT_CMUL] THEN
12938 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN
12939 REWRITE_TAC[CONTINUOUS_ON_LIFT_DIST] THEN
12940 MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN
12941 ASM_SIMP_TAC[LIFT_ADD; NORM_ARITH
12942 `~(u:real^N = v) ==> ~(dist(u,x) + dist(v,x) = &0)`] THEN
12943 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN
12944 REWRITE_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_ON_LIFT_DIST]);;
12946 (* ------------------------------------------------------------------------- *)
12947 (* Also more convenient formulations of monotone convergence. *)
12948 (* ------------------------------------------------------------------------- *)
12950 let BOUNDED_INCREASING_CONVERGENT = prove
12952 bounded {s n | n IN (:num)} /\ (!n. drop(s n) <= drop(s(SUC n)))
12953 ==> ?l. (s --> l) sequentially`,
12955 REWRITE_TAC[bounded; IN_ELIM_THM; ABS_DROP; LIM_SEQUENTIALLY; dist;
12956 DROP_SUB; IN_UNIV; GSYM EXISTS_DROP] THEN
12957 DISCH_TAC THEN MATCH_MP_TAC CONVERGENT_BOUNDED_MONOTONE THEN
12958 REWRITE_TAC[LEFT_EXISTS_AND_THM] THEN
12959 CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
12960 DISJ1_TAC THEN MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
12961 ASM_REWRITE_TAC[REAL_LE_TRANS; REAL_LE_REFL]);;
12963 let BOUNDED_DECREASING_CONVERGENT = prove
12965 bounded {s n | n IN (:num)} /\ (!n. drop(s(SUC n)) <= drop(s(n)))
12966 ==> ?l. (s --> l) sequentially`,
12967 GEN_TAC THEN REWRITE_TAC[bounded; FORALL_IN_GSPEC] THEN
12968 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
12969 MP_TAC(ISPEC `\n. --((s:num->real^1) n)` BOUNDED_INCREASING_CONVERGENT) THEN
12970 ASM_SIMP_TAC[bounded; FORALL_IN_GSPEC; NORM_NEG; DROP_NEG; REAL_LE_NEG2] THEN
12971 GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [GSYM LIM_NEG_EQ] THEN
12972 REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX] THEN MESON_TAC[]);;
12974 (* ------------------------------------------------------------------------- *)
12975 (* Since we'll use some cardinality reasoning, add invariance theorems. *)
12976 (* ------------------------------------------------------------------------- *)
12978 let card_translation_invariants = (CONJUNCTS o prove)
12979 (`(!a (s:real^N->bool) (t:A->bool).
12980 IMAGE (\x. a + x) s =_c t <=> s =_c t) /\
12981 (!a (s:A->bool) (t:real^N->bool).
12982 s =_c IMAGE (\x. a + x) t <=> s =_c t) /\
12983 (!a (s:real^N->bool) (t:A->bool).
12984 IMAGE (\x. a + x) s <_c t <=> s <_c t) /\
12985 (!a (s:A->bool) (t:real^N->bool).
12986 s <_c IMAGE (\x. a + x) t <=> s <_c t) /\
12987 (!a (s:real^N->bool) (t:A->bool).
12988 IMAGE (\x. a + x) s <=_c t <=> s <=_c t) /\
12989 (!a (s:A->bool) (t:real^N->bool).
12990 s <=_c IMAGE (\x. a + x) t <=> s <=_c t) /\
12991 (!a (s:real^N->bool) (t:A->bool).
12992 IMAGE (\x. a + x) s >_c t <=> s >_c t) /\
12993 (!a (s:A->bool) (t:real^N->bool).
12994 s >_c IMAGE (\x. a + x) t <=> s >_c t) /\
12995 (!a (s:real^N->bool) (t:A->bool).
12996 IMAGE (\x. a + x) s >=_c t <=> s >=_c t) /\
12997 (!a (s:A->bool) (t:real^N->bool).
12998 s >=_c IMAGE (\x. a + x) t <=> s >=_c t)`,
12999 REWRITE_TAC[gt_c; ge_c] THEN REPEAT STRIP_TAC THENL
13000 [MATCH_MP_TAC CARD_EQ_CONG;
13001 MATCH_MP_TAC CARD_EQ_CONG;
13002 MATCH_MP_TAC CARD_LT_CONG;
13003 MATCH_MP_TAC CARD_LT_CONG;
13004 MATCH_MP_TAC CARD_LE_CONG;
13005 MATCH_MP_TAC CARD_LE_CONG;
13006 MATCH_MP_TAC CARD_LT_CONG;
13007 MATCH_MP_TAC CARD_LT_CONG;
13008 MATCH_MP_TAC CARD_LE_CONG;
13009 MATCH_MP_TAC CARD_LE_CONG] THEN
13010 REWRITE_TAC[CARD_EQ_REFL] THEN MATCH_MP_TAC CARD_EQ_IMAGE THEN
13011 SIMP_TAC[VECTOR_ARITH `a + x:real^N = a + y <=> x = y`]) in
13012 add_translation_invariants card_translation_invariants;;
13014 let card_linear_invariants = (CONJUNCTS o prove)
13015 (`(!(f:real^M->real^N) s (t:A->bool).
13016 linear f /\ (!x y. f x = f y ==> x = y)
13017 ==> (IMAGE f s =_c t <=> s =_c t)) /\
13018 (!(f:real^M->real^N) (s:A->bool) t.
13019 linear f /\ (!x y. f x = f y ==> x = y)
13020 ==> (s =_c IMAGE f t <=> s =_c t)) /\
13021 (!(f:real^M->real^N) s (t:A->bool).
13022 linear f /\ (!x y. f x = f y ==> x = y)
13023 ==> (IMAGE f s <_c t <=> s <_c t)) /\
13024 (!(f:real^M->real^N) (s:A->bool) t.
13025 linear f /\ (!x y. f x = f y ==> x = y)
13026 ==> (s <_c IMAGE f t <=> s <_c t)) /\
13027 (!(f:real^M->real^N) s (t:A->bool).
13028 linear f /\ (!x y. f x = f y ==> x = y)
13029 ==> (IMAGE f s <=_c t <=> s <=_c t)) /\
13030 (!(f:real^M->real^N) (s:A->bool) t.
13031 linear f /\ (!x y. f x = f y ==> x = y)
13032 ==> (s <=_c IMAGE f t <=> s <=_c t)) /\
13033 (!(f:real^M->real^N) s (t:A->bool).
13034 linear f /\ (!x y. f x = f y ==> x = y)
13035 ==> (IMAGE f s >_c t <=> s >_c t)) /\
13036 (!(f:real^M->real^N) (s:A->bool) t.
13037 linear f /\ (!x y. f x = f y ==> x = y)
13038 ==> (s >_c IMAGE f t <=> s >_c t)) /\
13039 (!(f:real^M->real^N) s (t:A->bool).
13040 linear f /\ (!x y. f x = f y ==> x = y)
13041 ==> (IMAGE f s >=_c t <=> s >=_c t)) /\
13042 (!(f:real^M->real^N) (s:A->bool) t.
13043 linear f /\ (!x y. f x = f y ==> x = y)
13044 ==> (s >=_c IMAGE f t <=> s >=_c t))`,
13045 REWRITE_TAC[gt_c; ge_c] THEN REPEAT STRIP_TAC THENL
13046 [MATCH_MP_TAC CARD_EQ_CONG;
13047 MATCH_MP_TAC CARD_EQ_CONG;
13048 MATCH_MP_TAC CARD_LT_CONG;
13049 MATCH_MP_TAC CARD_LT_CONG;
13050 MATCH_MP_TAC CARD_LE_CONG;
13051 MATCH_MP_TAC CARD_LE_CONG;
13052 MATCH_MP_TAC CARD_LT_CONG;
13053 MATCH_MP_TAC CARD_LT_CONG;
13054 MATCH_MP_TAC CARD_LE_CONG;
13055 MATCH_MP_TAC CARD_LE_CONG] THEN
13056 REWRITE_TAC[CARD_EQ_REFL] THEN MATCH_MP_TAC CARD_EQ_IMAGE THEN
13057 ASM_MESON_TAC[]) in
13058 add_linear_invariants card_linear_invariants;;
13060 (* ------------------------------------------------------------------------- *)
13061 (* Basic homeomorphism definitions. *)
13062 (* ------------------------------------------------------------------------- *)
13064 let homeomorphism = new_definition
13065 `homeomorphism (s,t) (f,g) <=>
13066 (!x. x IN s ==> (g(f(x)) = x)) /\ (IMAGE f s = t) /\ f continuous_on s /\
13067 (!y. y IN t ==> (f(g(y)) = y)) /\ (IMAGE g t = s) /\ g continuous_on t`;;
13069 parse_as_infix("homeomorphic",(12,"right"));;
13071 let homeomorphic = new_definition
13072 `s homeomorphic t <=> ?f g. homeomorphism (s,t) (f,g)`;;
13074 let HOMEOMORPHISM = prove
13075 (`!s:real^M->bool t:real^N->bool f g.
13076 homeomorphism (s,t) (f,g) <=>
13077 f continuous_on s /\ IMAGE f s SUBSET t /\
13078 g continuous_on t /\ IMAGE g t SUBSET s /\
13079 (!x. x IN s ==> g (f x) = x) /\
13080 (!y. y IN t ==> f (g y) = y)`,
13081 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphism] THEN
13082 EQ_TAC THEN SIMP_TAC[] THEN SET_TAC[]);;
13084 let HOMEOMORPHISM_OF_SUBSETS = prove
13086 homeomorphism (s,t) (f,g) /\ s' SUBSET s /\ t' SUBSET t /\ IMAGE f s' = t'
13087 ==> homeomorphism (s',t') (f,g)`,
13088 REWRITE_TAC[homeomorphism] THEN
13089 REPEAT STRIP_TAC THEN
13090 TRY(MATCH_MP_TAC CONTINUOUS_ON_SUBSET) THEN ASM SET_TAC[]);;
13092 let HOMEOMORPHISM_ID = prove
13093 (`!s:real^N->bool. homeomorphism (s,s) ((\x. x),(\x. x))`,
13094 REWRITE_TAC[homeomorphism; IMAGE_ID; CONTINUOUS_ON_ID]);;
13096 let HOMEOMORPHISM_I = prove
13097 (`!s:real^N->bool. homeomorphism (s,s) (I,I)`,
13098 REWRITE_TAC[I_DEF; HOMEOMORPHISM_ID]);;
13100 let HOMEOMORPHIC_REFL = prove
13101 (`!s:real^N->bool. s homeomorphic s`,
13102 REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_I]);;
13104 let HOMEOMORPHISM_SYM = prove
13105 (`!f:real^M->real^N g s t.
13106 homeomorphism (s,t) (f,g) <=> homeomorphism (t,s) (g,f)`,
13107 REWRITE_TAC[homeomorphism] THEN MESON_TAC[]);;
13109 let HOMEOMORPHIC_SYM = prove
13110 (`!s t. s homeomorphic t <=> t homeomorphic s`,
13111 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; homeomorphism] THEN
13112 GEN_REWRITE_TAC RAND_CONV [SWAP_EXISTS_THM] THEN
13113 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN CONV_TAC TAUT);;
13115 let HOMEOMORPHISM_COMPOSE = prove
13116 (`!f:real^M->real^N g h:real^N->real^P k s t u.
13117 homeomorphism (s,t) (f,g) /\ homeomorphism (t,u) (h,k)
13118 ==> homeomorphism (s,u) (h o f,g o k)`,
13119 SIMP_TAC[homeomorphism; CONTINUOUS_ON_COMPOSE; IMAGE_o; o_THM] THEN
13122 let HOMEOMORPHIC_TRANS = prove
13123 (`!s:real^M->bool t:real^N->bool u:real^P->bool.
13124 s homeomorphic t /\ t homeomorphic u ==> s homeomorphic u`,
13125 REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_COMPOSE]);;
13127 let HOMEOMORPHIC_IMP_CARD_EQ = prove
13128 (`!s:real^M->bool t:real^N->bool. s homeomorphic t ==> s =_c t`,
13129 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; homeomorphism; eq_c] THEN
13130 MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]);;
13132 let HOMEOMORPHIC_EMPTY = prove
13133 (`(!s. (s:real^N->bool) homeomorphic ({}:real^M->bool) <=> s = {}) /\
13134 (!s. ({}:real^M->bool) homeomorphic (s:real^N->bool) <=> s = {})`,
13135 REWRITE_TAC[homeomorphic; homeomorphism; IMAGE_CLAUSES; IMAGE_EQ_EMPTY] THEN
13136 REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN
13137 ASM_REWRITE_TAC[continuous_on; NOT_IN_EMPTY]);;
13139 let HOMEOMORPHIC_MINIMAL = prove
13140 (`!s t. s homeomorphic t <=>
13141 ?f g. (!x. x IN s ==> f(x) IN t /\ (g(f(x)) = x)) /\
13142 (!y. y IN t ==> g(y) IN s /\ (f(g(y)) = y)) /\
13143 f continuous_on s /\ g continuous_on t`,
13144 REWRITE_TAC[homeomorphic; homeomorphism; EXTENSION; IN_IMAGE] THEN
13145 REPEAT GEN_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN MESON_TAC[]);;
13147 let HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF = prove
13148 (`!f:real^M->real^N s.
13149 linear f /\ (!x y. f x = f y ==> x = y)
13150 ==> (IMAGE f s) homeomorphic s`,
13151 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
13152 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_LEFT_INVERSE]) THEN
13153 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN DISCH_TAC THEN
13154 EXISTS_TAC `f:real^M->real^N` THEN
13155 ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON; FORALL_IN_IMAGE; FUN_IN_IMAGE] THEN
13156 ASM_SIMP_TAC[continuous_on; IMP_CONJ; FORALL_IN_IMAGE] THEN
13157 X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
13158 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
13159 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_BOUNDED_BELOW_POS) THEN
13160 ASM_REWRITE_TAC[] THEN
13161 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
13162 EXISTS_TAC `e * B:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN
13163 X_GEN_TAC `y:real^M` THEN ASM_SIMP_TAC[dist; GSYM LINEAR_SUB] THEN
13164 DISCH_TAC THEN ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ] THEN
13165 MATCH_MP_TAC(REAL_ARITH `a <= b ==> b < x ==> a < x`) THEN
13166 ASM_SIMP_TAC[REAL_LE_RDIV_EQ]);;
13168 let HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ = prove
13169 (`!f:real^M->real^N s t.
13170 linear f /\ (!x y. f x = f y ==> x = y)
13171 ==> ((IMAGE f s) homeomorphic t <=> s homeomorphic t)`,
13172 REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o SPEC `s:real^M->bool` o
13173 MATCH_MP HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF) THEN
13175 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HOMEOMORPHIC_SYM]);
13176 POP_ASSUM MP_TAC] THEN
13177 REWRITE_TAC[IMP_IMP; HOMEOMORPHIC_TRANS]);;
13179 let HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ = prove
13180 (`!f:real^M->real^N s t.
13181 linear f /\ (!x y. f x = f y ==> x = y)
13182 ==> (s homeomorphic (IMAGE f t) <=> s homeomorphic t)`,
13183 ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN
13184 REWRITE_TAC[HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ]);;
13186 add_linear_invariants
13187 [HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ;
13188 HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ];;
13190 let HOMEOMORPHIC_TRANSLATION_SELF = prove
13191 (`!a:real^N s. (IMAGE (\x. a + x) s) homeomorphic s`,
13192 REPEAT GEN_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
13193 EXISTS_TAC `\x:real^N. x - a` THEN
13194 EXISTS_TAC `\x:real^N. a + x` THEN
13195 SIMP_TAC[FORALL_IN_IMAGE; CONTINUOUS_ON_SUB; CONTINUOUS_ON_ID;
13196 CONTINUOUS_ON_CONST; CONTINUOUS_ON_ADD; VECTOR_ADD_SUB] THEN
13197 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[]);;
13199 let HOMEOMORPHIC_TRANSLATION_LEFT_EQ = prove
13201 (IMAGE (\x. a + x) s) homeomorphic t <=> s homeomorphic t`,
13202 MESON_TAC[HOMEOMORPHIC_TRANSLATION_SELF;
13203 HOMEOMORPHIC_SYM; HOMEOMORPHIC_TRANS]);;
13205 let HOMEOMORPHIC_TRANSLATION_RIGHT_EQ = prove
13207 s homeomorphic (IMAGE (\x. a + x) t) <=> s homeomorphic t`,
13208 ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN
13209 REWRITE_TAC[HOMEOMORPHIC_TRANSLATION_LEFT_EQ]);;
13211 add_translation_invariants
13212 [HOMEOMORPHIC_TRANSLATION_LEFT_EQ;
13213 HOMEOMORPHIC_TRANSLATION_RIGHT_EQ];;
13215 let HOMEOMORPHISM_IMP_QUOTIENT_MAP = prove
13216 (`!f:real^M->real^N g s t.
13217 homeomorphism (s,t) (f,g)
13219 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
13220 open_in (subtopology euclidean t) u)`,
13221 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphism] THEN
13222 STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN
13223 EXISTS_TAC `g:real^N->real^M` THEN ASM_REWRITE_TAC[SUBSET_REFL]);;
13225 let HOMEOMORPHIC_PCROSS = prove
13226 (`!s:real^M->bool t:real^N->bool s':real^P->bool t':real^Q->bool.
13227 s homeomorphic s' /\ t homeomorphic t'
13228 ==> (s PCROSS t) homeomorphic (s' PCROSS t')`,
13229 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN
13230 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
13231 DISCH_THEN(CONJUNCTS_THEN2
13232 (X_CHOOSE_THEN `f:real^M->real^P`
13233 (X_CHOOSE_THEN `f':real^P->real^M` STRIP_ASSUME_TAC))
13234 (X_CHOOSE_THEN `g:real^N->real^Q`
13235 (X_CHOOSE_THEN `g':real^Q->real^N` STRIP_ASSUME_TAC))) THEN
13236 MAP_EVERY EXISTS_TAC
13237 [`(\z. pastecart (f(fstcart z)) (g(sndcart z)))
13238 :real^(M,N)finite_sum->real^(P,Q)finite_sum`;
13239 `(\z. pastecart (f'(fstcart z)) (g'(sndcart z)))
13240 :real^(P,Q)finite_sum->real^(M,N)finite_sum`] THEN
13241 ASM_SIMP_TAC[FORALL_IN_PCROSS; FSTCART_PASTECART; SNDCART_PASTECART;
13242 SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS] THEN
13243 CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN
13244 CONJ_TAC THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN
13245 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
13246 SIMP_TAC[LINEAR_FSTCART; LINEAR_SNDCART; LINEAR_CONTINUOUS_ON] THEN
13247 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
13248 CONTINUOUS_ON_SUBSET)) THEN
13249 REWRITE_TAC[FORALL_IN_IMAGE; FORALL_IN_PCROSS; SUBSET] THEN
13250 SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART]);;
13252 let HOMEOMORPHIC_PCROSS_SYM = prove
13253 (`!s:real^M->bool t:real^N->bool. (s PCROSS t) homeomorphic (t PCROSS s)`,
13254 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; homeomorphism] THEN
13255 EXISTS_TAC `(\z. pastecart (sndcart z) (fstcart z))
13256 :real^(M,N)finite_sum->real^(N,M)finite_sum` THEN
13257 EXISTS_TAC `(\z. pastecart (sndcart z) (fstcart z))
13258 :real^(N,M)finite_sum->real^(M,N)finite_sum` THEN
13259 REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET; FORALL_IN_IMAGE] THEN
13260 SIMP_TAC[CONTINUOUS_ON_PASTECART; LINEAR_CONTINUOUS_ON;
13261 LINEAR_FSTCART; LINEAR_SNDCART] THEN
13262 REWRITE_TAC[FORALL_IN_PCROSS; FSTCART_PASTECART; SNDCART_PASTECART;
13263 IN_IMAGE; EXISTS_PASTECART; PASTECART_INJ; PASTECART_IN_PCROSS] THEN
13266 let HOMEOMORPHIC_PCROSS_ASSOC = prove
13267 (`!s:real^M->bool t:real^N->bool u:real^P->bool.
13268 (s PCROSS (t PCROSS u)) homeomorphic ((s PCROSS t) PCROSS u)`,
13269 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN
13270 MAP_EVERY EXISTS_TAC
13271 [`\z:real^(M,(N,P)finite_sum)finite_sum.
13272 pastecart (pastecart (fstcart z) (fstcart(sndcart z)))
13273 (sndcart(sndcart z))`;
13274 `\z:real^((M,N)finite_sum,P)finite_sum.
13275 pastecart (fstcart(fstcart z))
13276 (pastecart (sndcart(fstcart z)) (sndcart z))`] THEN
13277 REWRITE_TAC[FORALL_IN_PCROSS; SUBSET; FORALL_IN_IMAGE;
13278 RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN
13279 SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART; PASTECART_IN_PCROSS] THEN
13280 CONJ_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN
13281 REPEAT(MATCH_MP_TAC LINEAR_PASTECART THEN CONJ_TAC) THEN
13282 TRY(GEN_REWRITE_TAC RAND_CONV [GSYM o_DEF] THEN
13283 MATCH_MP_TAC LINEAR_COMPOSE) THEN
13284 REWRITE_TAC[LINEAR_FSTCART; LINEAR_SNDCART]);;
13286 let HOMEOMORPHIC_SCALING_LEFT = prove
13288 ==> !s t. (IMAGE (\x. c % x) s) homeomorphic t <=> s homeomorphic t`,
13289 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
13290 MATCH_MP_TAC HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ THEN
13291 ASM_SIMP_TAC[VECTOR_MUL_LCANCEL; REAL_LT_IMP_NZ; LINEAR_SCALING]);;
13293 let HOMEOMORPHIC_SCALING_RIGHT = prove
13295 ==> !s t. s homeomorphic (IMAGE (\x. c % x) t) <=> s homeomorphic t`,
13296 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
13297 MATCH_MP_TAC HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ THEN
13298 ASM_SIMP_TAC[VECTOR_MUL_LCANCEL; REAL_LT_IMP_NZ; LINEAR_SCALING]);;
13300 let HOMEOMORPHIC_SUBSPACES = prove
13301 (`!s:real^M->bool t:real^N->bool.
13302 subspace s /\ subspace t /\ dim s = dim t ==> s homeomorphic t`,
13303 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN
13304 DISCH_THEN(MP_TAC o MATCH_MP ISOMETRIES_SUBSPACES) THEN
13305 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN
13306 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN
13307 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTER; IN_CBALL_0] THEN
13308 SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN ASM SET_TAC[]);;
13310 let HOMEOMORPHIC_FINITE = prove
13311 (`!s:real^M->bool t:real^N->bool.
13312 FINITE s /\ FINITE t ==> (s homeomorphic t <=> CARD s = CARD t)`,
13313 REPEAT STRIP_TAC THEN EQ_TAC THENL
13314 [DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN
13315 ASM_SIMP_TAC[CARD_EQ_CARD];
13316 STRIP_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN
13317 MP_TAC(ISPECL [`s:real^M->bool`; `t:real^N->bool`]
13318 CARD_EQ_BIJECTIONS) THEN
13319 ASM_REWRITE_TAC[] THEN
13320 REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
13321 ASM_SIMP_TAC[CONTINUOUS_ON_FINITE] THEN ASM SET_TAC[]]);;
13323 let HOMEOMORPHIC_FINITE_STRONG = prove
13324 (`!s:real^M->bool t:real^N->bool.
13325 FINITE s \/ FINITE t
13326 ==> (s homeomorphic t <=> FINITE s /\ FINITE t /\ CARD s = CARD t)`,
13327 REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THEN
13328 SIMP_TAC[HOMEOMORPHIC_FINITE] THEN DISCH_TAC THEN
13329 FIRST_ASSUM(MP_TAC o MATCH_MP CARD_FINITE_CONG o MATCH_MP
13330 HOMEOMORPHIC_IMP_CARD_EQ) THEN
13331 FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
13332 ASM_MESON_TAC[HOMEOMORPHIC_FINITE]);;
13334 let HOMEOMORPHIC_SING = prove
13335 (`!a:real^M b:real^N. {a} homeomorphic {b}`,
13336 SIMP_TAC[HOMEOMORPHIC_FINITE; FINITE_SING; CARD_SING]);;
13338 let HOMEOMORPHIC_PCROSS_SING = prove
13339 (`(!s:real^M->bool a:real^N. s homeomorphic (s PCROSS {a})) /\
13340 (!s:real^M->bool a:real^N. s homeomorphic ({a} PCROSS s))`,
13341 MATCH_MP_TAC(TAUT `(p ==> q) /\ p ==> p /\ q`) THEN CONJ_TAC THENL
13342 [MESON_TAC[HOMEOMORPHIC_PCROSS_SYM; HOMEOMORPHIC_TRANS]; ALL_TAC] THEN
13343 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN
13344 EXISTS_TAC `\x. (pastecart x a:real^(M,N)finite_sum)` THEN
13345 EXISTS_TAC `fstcart:real^(M,N)finite_sum->real^M` THEN
13346 SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN
13347 SIMP_TAC[LINEAR_FSTCART; LINEAR_CONTINUOUS_ON; SUBSET; FORALL_IN_IMAGE] THEN
13348 REWRITE_TAC[FORALL_IN_PCROSS; PASTECART_IN_PCROSS; IN_SING] THEN
13349 SIMP_TAC[FSTCART_PASTECART]);;
13351 (* ------------------------------------------------------------------------- *)
13352 (* Inverse function property for open/closed maps. *)
13353 (* ------------------------------------------------------------------------- *)
13355 let CONTINUOUS_ON_INVERSE_OPEN_MAP = prove
13356 (`!f:real^M->real^N g s t.
13357 f continuous_on s /\ IMAGE f s = t /\ (!x. x IN s ==> g(f x) = x) /\
13358 (!u. open_in (subtopology euclidean s) u
13359 ==> open_in (subtopology euclidean t) (IMAGE f u))
13360 ==> g continuous_on t`,
13361 REPEAT STRIP_TAC THEN
13362 MP_TAC(ISPECL [`g:real^N->real^M`; `t:real^N->bool`; `s:real^M->bool`]
13363 CONTINUOUS_ON_OPEN_GEN) THEN
13364 ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN SUBST1_TAC] THEN
13365 X_GEN_TAC `u:real^M->bool` THEN DISCH_TAC THEN
13366 FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M->bool`) THEN ASM_REWRITE_TAC[] THEN
13367 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
13368 FIRST_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [open_in]) THEN
13371 let CONTINUOUS_ON_INVERSE_CLOSED_MAP = prove
13372 (`!f:real^M->real^N g s t.
13373 f continuous_on s /\ IMAGE f s = t /\ (!x. x IN s ==> g(f x) = x) /\
13374 (!u. closed_in (subtopology euclidean s) u
13375 ==> closed_in (subtopology euclidean t) (IMAGE f u))
13376 ==> g continuous_on t`,
13377 REPEAT STRIP_TAC THEN
13378 MP_TAC(ISPECL [`g:real^N->real^M`; `t:real^N->bool`; `s:real^M->bool`]
13379 CONTINUOUS_ON_CLOSED_GEN) THEN
13380 ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN SUBST1_TAC] THEN
13381 X_GEN_TAC `u:real^M->bool` THEN DISCH_TAC THEN
13382 FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M->bool`) THEN ASM_REWRITE_TAC[] THEN
13383 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
13384 FIRST_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [closed_in]) THEN
13385 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM SET_TAC[]);;
13387 let HOMEOMORPHISM_INJECTIVE_OPEN_MAP = prove
13388 (`!f:real^M->real^N s t.
13389 f continuous_on s /\ IMAGE f s = t /\
13390 (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\
13391 (!u. open_in (subtopology euclidean s) u
13392 ==> open_in (subtopology euclidean t) (IMAGE f u))
13393 ==> ?g. homeomorphism (s,t) (f,g)`,
13394 REPEAT STRIP_TAC THEN
13395 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN
13396 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN
13397 DISCH_TAC THEN ASM_SIMP_TAC[homeomorphism] THEN
13398 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
13399 MATCH_MP_TAC CONTINUOUS_ON_INVERSE_OPEN_MAP THEN ASM_MESON_TAC[]);;
13401 let HOMEOMORPHISM_INJECTIVE_CLOSED_MAP = prove
13402 (`!f:real^M->real^N s t.
13403 f continuous_on s /\ IMAGE f s = t /\
13404 (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\
13405 (!u. closed_in (subtopology euclidean s) u
13406 ==> closed_in (subtopology euclidean t) (IMAGE f u))
13407 ==> ?g. homeomorphism (s,t) (f,g)`,
13408 REPEAT STRIP_TAC THEN
13409 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN
13410 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN
13411 DISCH_TAC THEN ASM_SIMP_TAC[homeomorphism] THEN
13412 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
13413 MATCH_MP_TAC CONTINUOUS_ON_INVERSE_CLOSED_MAP THEN ASM_MESON_TAC[]);;
13415 let HOMEOMORPHISM_IMP_OPEN_MAP = prove
13416 (`!f:real^M->real^N g s t u.
13417 homeomorphism (s,t) (f,g) /\ open_in (subtopology euclidean s) u
13418 ==> open_in (subtopology euclidean t) (IMAGE f u)`,
13419 REWRITE_TAC[homeomorphism] THEN REPEAT STRIP_TAC THEN
13420 SUBGOAL_THEN `IMAGE (f:real^M->real^N) u =
13421 {y | y IN t /\ g(y) IN u}`
13423 [FIRST_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [open_in]) THEN
13425 MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]]);;
13427 let HOMEOMORPHISM_IMP_CLOSED_MAP = prove
13428 (`!f:real^M->real^N g s t u.
13429 homeomorphism (s,t) (f,g) /\ closed_in (subtopology euclidean s) u
13430 ==> closed_in (subtopology euclidean t) (IMAGE f u)`,
13431 REWRITE_TAC[homeomorphism] THEN REPEAT STRIP_TAC THEN
13432 SUBGOAL_THEN `IMAGE (f:real^M->real^N) u =
13433 {y | y IN t /\ g(y) IN u}`
13435 [FIRST_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [closed_in]) THEN
13436 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM SET_TAC[];
13437 MATCH_MP_TAC CONTINUOUS_ON_IMP_CLOSED_IN THEN ASM_REWRITE_TAC[]]);;
13439 let HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ = prove
13440 (`!f:real^M->real^N s t.
13441 f continuous_on s /\ IMAGE f s = t /\
13442 (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y)
13443 ==> ((?g. homeomorphism (s,t) (f,g)) <=>
13444 !u. open_in (subtopology euclidean s) u
13445 ==> open_in (subtopology euclidean t) (IMAGE f u))`,
13446 REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
13447 [MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN ASM_MESON_TAC[];
13448 MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN
13449 ASM_REWRITE_TAC[]]);;
13451 let HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ = prove
13452 (`!f:real^M->real^N s t.
13453 f continuous_on s /\ IMAGE f s = t /\
13454 (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y)
13455 ==> ((?g. homeomorphism (s,t) (f,g)) <=>
13456 !u. closed_in (subtopology euclidean s) u
13457 ==> closed_in (subtopology euclidean t) (IMAGE f u))`,
13458 REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
13459 [MATCH_MP_TAC HOMEOMORPHISM_IMP_CLOSED_MAP THEN ASM_MESON_TAC[];
13460 MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_CLOSED_MAP THEN
13461 ASM_REWRITE_TAC[]]);;
13463 let INJECTIVE_MAP_OPEN_IFF_CLOSED = prove
13464 (`!f:real^M->real^N s t.
13465 f continuous_on s /\ IMAGE f s = t /\
13466 (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y)
13467 ==> ((!u. open_in (subtopology euclidean s) u
13468 ==> open_in (subtopology euclidean t) (IMAGE f u)) <=>
13469 (!u. closed_in (subtopology euclidean s) u
13470 ==> closed_in (subtopology euclidean t) (IMAGE f u)))`,
13471 REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
13472 EXISTS_TAC `?g:real^N->real^M. homeomorphism (s,t) (f,g)` THEN
13474 [CONV_TAC SYM_CONV THEN MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ;
13475 MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ] THEN
13476 ASM_REWRITE_TAC[]);;
13478 (* ------------------------------------------------------------------------- *)
13479 (* Relatively weak hypotheses if the domain of the function is compact. *)
13480 (* ------------------------------------------------------------------------- *)
13482 let CONTINUOUS_IMP_CLOSED_MAP = prove
13483 (`!f:real^M->real^N s t.
13484 f continuous_on s /\ IMAGE f s = t /\ compact s
13485 ==> !u. closed_in (subtopology euclidean s) u
13486 ==> closed_in (subtopology euclidean t) (IMAGE f u)`,
13487 SIMP_TAC[CLOSED_IN_CLOSED_EQ; COMPACT_IMP_CLOSED] THEN
13488 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSED_SUBSET THEN
13489 EXPAND_TAC "t" THEN ASM_SIMP_TAC[IMAGE_SUBSET] THEN
13490 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
13491 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
13492 ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_IN_CLOSED_TRANS;
13493 BOUNDED_SUBSET; CONTINUOUS_ON_SUBSET]);;
13495 let CONTINUOUS_IMP_QUOTIENT_MAP = prove
13496 (`!f:real^M->real^N s t.
13497 f continuous_on s /\ IMAGE f s = t /\ compact s
13499 ==> (open_in (subtopology euclidean s)
13500 {x | x IN s /\ f x IN u} <=>
13501 open_in (subtopology euclidean t) u)`,
13502 REPEAT GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
13503 MATCH_MP_TAC CLOSED_MAP_IMP_QUOTIENT_MAP THEN
13504 ASM_REWRITE_TAC[] THEN
13505 MATCH_MP_TAC CONTINUOUS_IMP_CLOSED_MAP THEN
13506 ASM_REWRITE_TAC[]);;
13508 let CONTINUOUS_ON_INVERSE = prove
13509 (`!f:real^M->real^N g s.
13510 f continuous_on s /\ compact s /\ (!x. x IN s ==> (g(f(x)) = x))
13511 ==> g continuous_on (IMAGE f s)`,
13512 REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN
13513 SUBGOAL_THEN `IMAGE g (IMAGE (f:real^M->real^N) s) = s` SUBST1_TAC THENL
13514 [REWRITE_TAC[EXTENSION; IN_IMAGE] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
13515 X_GEN_TAC `t:real^M->bool` THEN DISCH_TAC THEN
13516 REWRITE_TAC[CLOSED_IN_CLOSED] THEN
13517 EXISTS_TAC `IMAGE (f:real^M->real^N) t` THEN CONJ_TAC THENL
13518 [MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
13519 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
13520 FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN
13521 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
13522 ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_IN_CLOSED_TRANS;
13523 BOUNDED_SUBSET; CONTINUOUS_ON_SUBSET];
13524 REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM; IN_IMAGE] THEN
13525 ASM_MESON_TAC[CLOSED_IN_SUBSET; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY; SUBSET]]);;
13527 let HOMEOMORPHISM_COMPACT = prove
13528 (`!s f t. compact s /\ f continuous_on s /\ (IMAGE f s = t) /\
13529 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y))
13530 ==> ?g. homeomorphism(s,t) (f,g)`,
13531 REWRITE_TAC[INJECTIVE_ON_LEFT_INVERSE] THEN REPEAT GEN_TAC THEN
13532 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
13533 MATCH_MP_TAC MONO_EXISTS THEN ASM_SIMP_TAC[EXTENSION; homeomorphism] THEN
13534 FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
13535 ASM_MESON_TAC[CONTINUOUS_ON_INVERSE; IN_IMAGE]);;
13537 let HOMEOMORPHIC_COMPACT = prove
13538 (`!s f t. compact s /\ f continuous_on s /\ (IMAGE f s = t) /\
13539 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y))
13540 ==> s homeomorphic t`,
13541 REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_COMPACT]);;
13543 (* ------------------------------------------------------------------------- *)
13544 (* Lemmas about composition of homeomorphisms. *)
13545 (* ------------------------------------------------------------------------- *)
13547 let HOMEOMORPHISM_FROM_COMPOSITION_SURJECTIVE = prove
13548 (`!f:real^M->real^N g:real^N->real^P s t u.
13549 f continuous_on s /\ IMAGE f s = t /\
13550 g continuous_on t /\ IMAGE g t SUBSET u /\
13551 (?h. homeomorphism (s,u) (g o f,h))
13552 ==> (?f'. homeomorphism (s,t) (f,f')) /\
13553 (?g'. homeomorphism (t,u) (g,g'))`,
13554 REPEAT GEN_TAC THEN STRIP_TAC THEN
13555 RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism; o_THM]) THEN
13556 MATCH_MP_TAC(TAUT `q /\ (q ==> p) ==> p /\ q`) THEN CONJ_TAC THENL
13557 [MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN
13558 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
13559 MATCH_MP_TAC OPEN_MAP_FROM_COMPOSITION_SURJECTIVE THEN
13560 MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `s:real^M->bool`] THEN
13561 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
13562 MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN
13563 MAP_EVERY EXISTS_TAC [`h:real^P->real^M`; `s:real^M->bool`] THEN
13564 ASM_REWRITE_TAC[homeomorphism; o_THM];
13565 REWRITE_TAC[homeomorphism; o_THM] THEN
13566 DISCH_THEN(X_CHOOSE_THEN `g':real^P->real^N` STRIP_ASSUME_TAC) THEN
13567 EXISTS_TAC `(h:real^P->real^M) o (g:real^N->real^P)` THEN
13568 ASM_SIMP_TAC[o_THM; IMAGE_o] THEN
13569 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
13570 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
13571 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]);;
13573 let HOMEOMORPHISM_FROM_COMPOSITION_INJECTIVE = prove
13574 (`!f:real^M->real^N g:real^N->real^P s t u.
13575 f continuous_on s /\ IMAGE f s SUBSET t /\
13576 g continuous_on t /\ IMAGE g t SUBSET u /\
13577 (!x y. x IN t /\ y IN t /\ g x = g y ==> x = y) /\
13578 (?h. homeomorphism (s,u) (g o f,h))
13579 ==> (?f'. homeomorphism (s,t) (f,f')) /\
13580 (?g'. homeomorphism (t,u) (g,g'))`,
13581 REPEAT GEN_TAC THEN STRIP_TAC THEN
13582 RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism; o_THM]) THEN
13583 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
13584 [MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN
13585 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
13586 MATCH_MP_TAC OPEN_MAP_FROM_COMPOSITION_INJECTIVE THEN
13587 MAP_EVERY EXISTS_TAC [`g:real^N->real^P`; `u:real^P->bool`] THEN
13588 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
13589 MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN
13590 MAP_EVERY EXISTS_TAC [`h:real^P->real^M`; `s:real^M->bool`] THEN
13591 ASM_REWRITE_TAC[homeomorphism; o_THM];
13592 REWRITE_TAC[homeomorphism; o_THM] THEN
13593 DISCH_THEN(X_CHOOSE_THEN `f':real^N->real^M` STRIP_ASSUME_TAC) THEN
13594 EXISTS_TAC `(f:real^M->real^N) o (h:real^P->real^M)` THEN
13595 ASM_SIMP_TAC[o_THM; IMAGE_o] THEN
13596 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
13597 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
13598 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]);;
13600 (* ------------------------------------------------------------------------- *)
13601 (* Preservation of topological properties. *)
13602 (* ------------------------------------------------------------------------- *)
13604 let HOMEOMORPHIC_COMPACTNESS = prove
13605 (`!s t. s homeomorphic t ==> (compact s <=> compact t)`,
13606 REWRITE_TAC[homeomorphic; homeomorphism] THEN
13607 MESON_TAC[COMPACT_CONTINUOUS_IMAGE]);;
13609 let HOMEOMORPHIC_CONNECTEDNESS = prove
13610 (`!s t. s homeomorphic t ==> (connected s <=> connected t)`,
13611 REWRITE_TAC[homeomorphic; homeomorphism] THEN
13612 MESON_TAC[CONNECTED_CONTINUOUS_IMAGE]);;
13614 (* ------------------------------------------------------------------------- *)
13615 (* Results on translation, scaling etc. *)
13616 (* ------------------------------------------------------------------------- *)
13618 let HOMEOMORPHIC_SCALING = prove
13619 (`!s:real^N->bool c. ~(c = &0) ==> s homeomorphic (IMAGE (\x. c % x) s)`,
13620 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
13621 MAP_EVERY EXISTS_TAC [`\x:real^N. c % x`; `\x:real^N. inv(c) % x`] THEN
13622 ASM_SIMP_TAC[CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID; FORALL_IN_IMAGE] THEN
13623 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_RINV] THEN
13624 SIMP_TAC[VECTOR_MUL_LID; IN_IMAGE; REAL_MUL_LID] THEN MESON_TAC[]);;
13626 let HOMEOMORPHIC_TRANSLATION = prove
13627 (`!s a:real^N. s homeomorphic (IMAGE (\x. a + x) s)`,
13628 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
13629 MAP_EVERY EXISTS_TAC [`\x:real^N. a + x`; `\x:real^N. --a + x`] THEN
13630 ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN
13631 SIMP_TAC[VECTOR_ADD_ASSOC; VECTOR_ADD_LINV; VECTOR_ADD_RINV;
13632 FORALL_IN_IMAGE; VECTOR_ADD_LID] THEN
13633 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[]);;
13635 let HOMEOMORPHIC_AFFINITY = prove
13636 (`!s a:real^N c. ~(c = &0) ==> s homeomorphic (IMAGE (\x. a + c % x) s)`,
13637 REPEAT STRIP_TAC THEN
13638 MATCH_MP_TAC HOMEOMORPHIC_TRANS THEN
13639 EXISTS_TAC `IMAGE (\x:real^N. c % x) s` THEN
13640 ASM_SIMP_TAC[HOMEOMORPHIC_SCALING] THEN
13641 SUBGOAL_THEN `(\x:real^N. a + c % x) = (\x. a + x) o (\x. c % x)`
13642 SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
13643 REWRITE_TAC[IMAGE_o; HOMEOMORPHIC_TRANSLATION]);;
13645 let [HOMEOMORPHIC_BALLS; HOMEOMORPHIC_CBALLS; HOMEOMORPHIC_SPHERES] =
13646 (CONJUNCTS o prove)
13647 (`(!a:real^N b:real^N d e.
13648 &0 < d /\ &0 < e ==> ball(a,d) homeomorphic ball(b,e)) /\
13649 (!a:real^N b:real^N d e.
13650 &0 < d /\ &0 < e ==> cball(a,d) homeomorphic cball(b,e)) /\
13651 (!a:real^N b:real^N d e.
13652 &0 < d /\ &0 < e ==> sphere(a,d) homeomorphic sphere(b,e))`,
13653 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
13654 EXISTS_TAC `\x:real^N. b + (e / d) % (x - a)` THEN
13655 EXISTS_TAC `\x:real^N. a + (d / e) % (x - b)` THEN
13656 ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_SUB; CONTINUOUS_ON_CMUL;
13657 CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID; IN_BALL; IN_CBALL; IN_SPHERE] THEN
13658 REWRITE_TAC[dist; VECTOR_ARITH `a - (a + b) = --b:real^N`; NORM_NEG] THEN
13659 REWRITE_TAC[real_div; VECTOR_ARITH
13660 `a + d % ((b + e % (x - a)) - b) = (&1 - d * e) % a + (d * e) % x`] THEN
13661 ONCE_REWRITE_TAC[REAL_ARITH
13662 `(e * d') * (d * e') = (d * d') * (e * e')`] THEN
13663 ASM_SIMP_TAC[REAL_MUL_RINV; REAL_LT_IMP_NZ; REAL_MUL_LID; REAL_SUB_REFL] THEN
13664 REWRITE_TAC[NORM_MUL; VECTOR_MUL_LZERO; VECTOR_MUL_LID; VECTOR_ADD_LID] THEN
13665 ASM_SIMP_TAC[REAL_ABS_MUL; REAL_ABS_INV; REAL_ARITH
13666 `&0 < x ==> (abs x = x)`] THEN
13667 GEN_REWRITE_TAC(BINOP_CONV o BINDER_CONV o funpow 2 RAND_CONV)
13668 [GSYM REAL_MUL_RID] THEN
13669 ONCE_REWRITE_TAC[AC REAL_MUL_AC `(a * b) * c = (a * c) * b`] THEN
13670 ASM_SIMP_TAC[REAL_LE_LMUL_EQ; GSYM real_div; REAL_LE_LDIV_EQ; REAL_MUL_LID;
13671 GSYM REAL_MUL_ASSOC; REAL_LT_LMUL_EQ; REAL_LT_LDIV_EQ; NORM_SUB] THEN
13672 ASM_SIMP_TAC[REAL_DIV_REFL; REAL_LT_IMP_NZ; REAL_MUL_RID]);;
13674 (* ------------------------------------------------------------------------- *)
13675 (* Homeomorphism of one-point compactifications. *)
13676 (* ------------------------------------------------------------------------- *)
13678 let HOMEOMORPHIC_ONE_POINT_COMPACTIFICATIONS = prove
13679 (`!s:real^M->bool t:real^N->bool a b.
13680 compact s /\ compact t /\ a IN s /\ b IN t /\
13681 (s DELETE a) homeomorphic (t DELETE b)
13682 ==> s homeomorphic t`,
13683 REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_COMPACT THEN
13684 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homeomorphic]) THEN
13685 REWRITE_TAC[HOMEOMORPHISM; LEFT_IMP_EXISTS_THM] THEN
13686 MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^N->real^M`] THEN
13688 EXISTS_TAC `\x. if x = a then b else (f:real^M->real^N) x` THEN
13689 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
13690 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
13691 X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
13692 ASM_CASES_TAC `x:real^M = a` THEN ASM_REWRITE_TAC[] THENL
13693 [REWRITE_TAC[continuous_within] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
13694 MP_TAC(ISPECL [`b:real^N`; `e:real`] CENTRE_IN_BALL) THEN
13695 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
13697 `closed_in (subtopology euclidean s)
13698 { x | x IN (s DELETE a) /\
13699 (f:real^M->real^N)(x) IN t DIFF ball(b,e)}`
13701 [MATCH_MP_TAC CLOSED_SUBSET THEN CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
13702 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN SUBGOAL_THEN
13703 `{x | x IN s DELETE a /\ f x IN t DIFF ball(b,e)} =
13704 IMAGE (g:real^N->real^M) (t DIFF ball (b,e))`
13705 SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
13706 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
13707 ASM_SIMP_TAC[COMPACT_DIFF; OPEN_BALL] THEN
13708 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
13709 CONTINUOUS_ON_SUBSET)) THEN ASM SET_TAC[];
13710 REWRITE_TAC[closed_in; open_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
13711 DISCH_THEN(MP_TAC o SPEC `a:real^M` o last o CONJUNCTS) THEN
13712 ASM_REWRITE_TAC[IN_ELIM_THM; IN_DIFF; IN_DELETE] THEN
13713 SIMP_TAC[IMP_CONJ; DE_MORGAN_THM] THEN
13714 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN
13715 ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN
13716 ASM_REWRITE_TAC[DIST_REFL] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
13717 RULE_ASSUM_TAC(REWRITE_RULE[IN_BALL]) THEN ASM SET_TAC[]];
13718 UNDISCH_TAC `(f:real^M->real^N) continuous_on (s DELETE a)` THEN
13719 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
13720 DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[IN_DELETE] THEN
13721 REWRITE_TAC[continuous_within] THEN
13722 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
13723 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[IN_DELETE] THEN
13724 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
13725 EXISTS_TAC `min d (dist(a:real^M,x))` THEN
13726 ASM_REWRITE_TAC[REAL_LT_MIN; GSYM DIST_NZ] THEN
13727 ASM_MESON_TAC[REAL_LT_REFL]]);;
13729 (* ------------------------------------------------------------------------- *)
13730 (* Homeomorphisms between open intervals in real^1 and then in real^N. *)
13731 (* Could prove similar things for closed intervals, but they drop out of *)
13732 (* later stuff in "convex.ml" even more easily. *)
13733 (* ------------------------------------------------------------------------- *)
13735 let HOMEOMORPHIC_OPEN_INTERVALS_1 = prove
13737 drop a < drop b /\ drop c < drop d
13738 ==> interval(a,b) homeomorphic interval(c,d)`,
13740 `!a b. drop a < drop b
13741 ==> interval(vec 0:real^1,vec 1) homeomorphic interval(a,b)`
13743 [REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
13744 EXISTS_TAC `(\x. a + drop x % (b - a)):real^1->real^1` THEN
13745 EXISTS_TAC `(\x. inv(drop b - drop a) % (x - a)):real^1->real^1` THEN
13746 ASM_REWRITE_TAC[IN_INTERVAL_1; GSYM DROP_EQ] THEN
13747 REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_NEG; DROP_VEC; DROP_SUB] THEN
13748 REWRITE_TAC[REAL_ARITH `inv b * a:real = a / b`] THEN
13749 ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_SUB_LT;
13750 REAL_LT_ADDR; REAL_EQ_LDIV_EQ; REAL_DIV_RMUL; REAL_LT_IMP_NZ;
13751 REAL_LT_MUL; REAL_MUL_LZERO; REAL_ADD_SUB; REAL_LT_RMUL_EQ;
13752 REAL_ARITH `a + x < b <=> x < &1 * (b - a)`] THEN
13753 REPEAT CONJ_TAC THENL
13755 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
13756 MATCH_MP_TAC CONTINUOUS_ON_VMUL THEN
13757 REWRITE_TAC[o_DEF; LIFT_DROP; CONTINUOUS_ON_ID];
13758 MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN
13759 ASM_SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]];
13760 REPEAT STRIP_TAC THEN
13761 FIRST_ASSUM(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN
13762 FIRST_X_ASSUM(MP_TAC o SPECL [`c:real^1`; `d:real^1`]) THEN
13763 ASM_REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN
13764 GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [HOMEOMORPHIC_SYM] THEN
13765 REWRITE_TAC[HOMEOMORPHIC_TRANS]]);;
13767 let HOMEOMORPHIC_OPEN_INTERVAL_UNIV_1 = prove
13768 (`!a b. drop a < drop b ==> interval(a,b) homeomorphic (:real^1)`,
13769 REPEAT STRIP_TAC THEN
13770 MP_TAC(SPECL [`a:real^1`; `b:real^1`; `--vec 1:real^1`; `vec 1:real^1`]
13771 HOMEOMORPHIC_OPEN_INTERVALS_1) THEN
13772 ASM_REWRITE_TAC[DROP_VEC; DROP_NEG] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
13773 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] HOMEOMORPHIC_TRANS) THEN
13774 POP_ASSUM_LIST(K ALL_TAC) THEN
13775 REWRITE_TAC[HOMEOMORPHIC_MINIMAL; IN_UNIV] THEN
13776 EXISTS_TAC `\x:real^1. inv(&1 - norm x) % x` THEN
13777 EXISTS_TAC `\y. if &0 <= drop y then inv(&1 + drop y) % y
13778 else inv(&1 - drop y) % y` THEN
13779 REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
13780 [X_GEN_TAC `x:real^1` THEN REWRITE_TAC[IN_INTERVAL_1] THEN
13781 REWRITE_TAC[DROP_NEG; DROP_VEC; DROP_CMUL; NORM_REAL; GSYM drop] THEN
13782 SIMP_TAC[REAL_LE_MUL_EQ; REAL_LT_INV_EQ; REAL_LE_MUL_EQ; REAL_ARITH
13783 `--a < x /\ x < a ==> &0 < a - abs x`] THEN
13784 SIMP_TAC[real_abs; VECTOR_MUL_ASSOC] THEN
13785 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
13786 GEN_REWRITE_TAC RAND_CONV [GSYM VECTOR_MUL_LID] THEN
13787 AP_THM_TAC THEN AP_TERM_TAC THEN
13788 REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD;
13789 X_GEN_TAC `y:real^1` THEN COND_CASES_TAC THEN
13790 ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_NEG; DROP_VEC; REAL_BOUNDS_LT] THEN
13791 REWRITE_TAC[DROP_CMUL; REAL_ABS_MUL; REAL_ABS_INV] THEN
13792 REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div)] THEN
13793 ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 <= x ==> &0 < abs(&1 + x)`;
13794 REAL_ARITH `~(&0 <= x) ==> &0 < abs(&1 - x)`] THEN
13795 (CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
13796 REWRITE_TAC[NORM_REAL; VECTOR_MUL_ASSOC] THEN
13797 REWRITE_TAC[GSYM drop; DROP_CMUL; REAL_ABS_MUL] THEN
13798 ASM_REWRITE_TAC[real_abs; REAL_LE_INV_EQ] THEN
13799 ASM_SIMP_TAC[REAL_ARITH `&0 <= x ==> &0 <= &1 + x`;
13800 REAL_ARITH `~(&0 <= x) ==> &0 <= &1 - x`] THEN
13801 GEN_REWRITE_TAC RAND_CONV [GSYM VECTOR_MUL_LID] THEN
13802 AP_THM_TAC THEN AP_TERM_TAC THEN
13803 REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD;
13804 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
13805 X_GEN_TAC `x:real^1` THEN
13806 REWRITE_TAC[IN_INTERVAL_1; DROP_NEG; DROP_VEC] THEN
13807 DISCH_TAC THEN MATCH_MP_TAC CONTINUOUS_MUL THEN
13808 REWRITE_TAC[CONTINUOUS_AT_ID] THEN
13809 ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN
13810 REWRITE_TAC[NETLIMIT_AT; o_DEF; LIFT_SUB; LIFT_DROP] THEN
13812 [MATCH_MP_TAC CONTINUOUS_SUB THEN
13813 SIMP_TAC[CONTINUOUS_CONST; REWRITE_RULE[o_DEF] CONTINUOUS_AT_LIFT_NORM];
13814 REWRITE_TAC[NORM_REAL; GSYM drop] THEN ASM_REAL_ARITH_TAC];
13815 SUBGOAL_THEN `(:real^1) = {x | x$1 >= &0} UNION {x | x$1 <= &0}`
13817 [REWRITE_TAC[EXTENSION; IN_UNION; IN_UNION; IN_ELIM_THM; IN_UNIV] THEN
13819 MATCH_MP_TAC CONTINUOUS_ON_CASES THEN
13820 REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE; CLOSED_HALFSPACE_COMPONENT_GE;
13822 REWRITE_TAC[GSYM drop; REAL_NOT_LE; real_ge; REAL_LET_ANTISYM] THEN
13823 SIMP_TAC[REAL_LE_ANTISYM; REAL_SUB_RZERO; REAL_ADD_RID] THEN
13824 CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
13825 X_GEN_TAC `y:real^1` THEN REWRITE_TAC[IN_ELIM_THM; real_ge] THEN
13826 DISCH_TAC THEN MATCH_MP_TAC CONTINUOUS_MUL THEN
13827 REWRITE_TAC[CONTINUOUS_AT_ID] THEN
13828 ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN
13829 REWRITE_TAC[NETLIMIT_AT; o_DEF; LIFT_ADD; LIFT_SUB; LIFT_DROP] THEN
13830 ASM_SIMP_TAC[CONTINUOUS_ADD; CONTINUOUS_AT_ID; CONTINUOUS_SUB;
13831 CONTINUOUS_CONST] THEN
13832 ASM_REAL_ARITH_TAC]]);;
13834 let HOMEOMORPHIC_OPEN_INTERVALS = prove
13835 (`!a b:real^N c d:real^N.
13836 (interval(a,b) = {} <=> interval(c,d) = {})
13837 ==> interval(a,b) homeomorphic interval(c,d)`,
13838 REPEAT GEN_TAC THEN ASM_CASES_TAC `interval(c:real^N,d) = {}` THEN
13839 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[HOMEOMORPHIC_REFL] THEN
13841 `!i. 1 <= i /\ i <= dimindex(:N)
13842 ==> interval(lift((a:real^N)$i),lift((b:real^N)$i)) homeomorphic
13843 interval(lift((c:real^N)$i),lift((d:real^N)$i))`
13845 [RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN
13846 ASM_SIMP_TAC[HOMEOMORPHIC_OPEN_INTERVALS_1; LIFT_DROP];
13848 REWRITE_TAC[HOMEOMORPHIC_MINIMAL; IN_INTERVAL_1; LIFT_DROP] THEN
13849 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
13850 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
13851 MAP_EVERY X_GEN_TAC [`f:num->real^1->real^1`; `g:num->real^1->real^1`] THEN
13855 drop((f:num->real^1->real^1) i (lift(x$i)))):real^N->real^N` THEN
13858 drop((g:num->real^1->real^1) i (lift(x$i)))):real^N->real^N` THEN
13859 ASM_SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; CART_EQ; LIFT_DROP] THEN
13860 ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN
13861 SIMP_TAC[LAMBDA_BETA; LIFT_DROP] THEN CONJ_TAC THEN REPEAT STRIP_TAC THEN
13862 ONCE_REWRITE_TAC[GSYM o_DEF] THEN
13863 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
13864 ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT] THEN
13865 MATCH_MP_TAC CONTINUOUS_ON_SUBSET THENL
13866 [EXISTS_TAC `interval(lift((a:real^N)$i),lift((b:real^N)$i))`;
13867 EXISTS_TAC `interval(lift((c:real^N)$i),lift((d:real^N)$i))`] THEN
13868 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1] THEN
13869 ASM_SIMP_TAC[LIFT_DROP; IN_INTERVAL]);;
13871 let HOMEOMORPHIC_OPEN_INTERVAL_UNIV = prove
13873 ~(interval(a,b) = {})
13874 ==> interval(a,b) homeomorphic (:real^N)`,
13875 REPEAT STRIP_TAC THEN
13877 `!i. 1 <= i /\ i <= dimindex(:N)
13878 ==> interval(lift((a:real^N)$i),lift((b:real^N)$i)) homeomorphic
13881 [RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN
13882 ASM_SIMP_TAC[HOMEOMORPHIC_OPEN_INTERVAL_UNIV_1; LIFT_DROP];
13884 REWRITE_TAC[HOMEOMORPHIC_MINIMAL; IN_INTERVAL_1; LIFT_DROP] THEN
13885 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
13886 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; IN_UNIV] THEN
13887 MAP_EVERY X_GEN_TAC [`f:num->real^1->real^1`; `g:num->real^1->real^1`] THEN
13891 drop((f:num->real^1->real^1) i (lift(x$i)))):real^N->real^N` THEN
13894 drop((g:num->real^1->real^1) i (lift(x$i)))):real^N->real^N` THEN
13895 ASM_SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; CART_EQ; LIFT_DROP; IN_UNIV] THEN
13896 ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN
13897 SIMP_TAC[LAMBDA_BETA; LIFT_DROP] THEN CONJ_TAC THEN REPEAT STRIP_TAC THEN
13898 ONCE_REWRITE_TAC[GSYM o_DEF] THEN
13899 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
13900 ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT] THEN
13901 MATCH_MP_TAC CONTINUOUS_ON_SUBSET THENL
13902 [EXISTS_TAC `interval(lift((a:real^N)$i),lift((b:real^N)$i))`;
13903 EXISTS_TAC `(:real^1)`] THEN
13904 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; IN_UNIV] THEN
13905 ASM_SIMP_TAC[LIFT_DROP; IN_INTERVAL]);;
13907 let HOMEOMORPHIC_BALL_UNIV = prove
13908 (`!a:real^N r. &0 < r ==> ball(a,r) homeomorphic (:real^N)`,
13909 REPEAT GEN_TAC THEN GEOM_ORIGIN_TAC `a:real^N` THEN REPEAT STRIP_TAC THEN
13910 SUBGOAL_THEN `?y:real^N. r = norm(y)` (CHOOSE_THEN SUBST_ALL_TAC) THENL
13911 [ASM_MESON_TAC[VECTOR_CHOOSE_SIZE; REAL_LT_IMP_LE]; POP_ASSUM MP_TAC] THEN
13912 REWRITE_TAC[NORM_POS_LT] THEN GEOM_NORMALIZE_TAC `y:real^N` THEN
13913 SIMP_TAC[] THEN GEN_TAC THEN REPEAT(DISCH_THEN(K ALL_TAC)) THEN
13914 REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
13915 EXISTS_TAC `\z:real^N. inv(&1 - norm(z)) % z` THEN
13916 EXISTS_TAC `\z:real^N. inv(&1 + norm(z)) % z` THEN
13917 REWRITE_TAC[IN_BALL; IN_UNIV; DIST_0; VECTOR_MUL_ASSOC; VECTOR_MUL_EQ_0;
13918 VECTOR_ARITH `a % x:real^N = x <=> (a - &1) % x = vec 0`] THEN
13919 REPEAT CONJ_TAC THENL
13920 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN DISJ1_TAC THEN
13921 REWRITE_TAC[GSYM REAL_INV_MUL; REAL_SUB_0; REAL_INV_EQ_1] THEN
13922 REWRITE_TAC[NORM_MUL; REAL_ABS_INV] THEN
13923 ASM_SIMP_TAC[REAL_ARITH `x < &1 ==> abs(&1 - x) = &1 - x`] THEN
13924 POP_ASSUM MP_TAC THEN CONV_TAC REAL_FIELD;
13925 X_GEN_TAC `y:real^N` THEN REWRITE_TAC[NORM_MUL; REAL_ABS_INV] THEN
13926 ASM_SIMP_TAC[NORM_POS_LE; REAL_ARITH
13927 `&0 <= y ==> inv(abs(&1 + y)) * z = z / (&1 + y)`] THEN
13928 ASM_SIMP_TAC[NORM_POS_LE; REAL_LT_LDIV_EQ; REAL_ARITH
13929 `&0 <= y ==> &0 < &1 + y`] THEN
13930 CONJ_TAC THENL [REAL_ARITH_TAC; DISJ1_TAC] THEN
13931 REWRITE_TAC[GSYM REAL_INV_MUL; REAL_SUB_0; REAL_INV_EQ_1] THEN
13932 MP_TAC(ISPEC `y:real^N` NORM_POS_LE) THEN CONV_TAC REAL_FIELD;
13933 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[CONTINUOUS_ON_ID] THEN
13934 GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM o_DEF] THEN
13935 MATCH_MP_TAC CONTINUOUS_ON_INV THEN
13936 SIMP_TAC[IN_BALL_0; REAL_SUB_0; REAL_ARITH `x < &1 ==> ~(&1 = x)`] THEN
13937 REWRITE_TAC[o_DEF; LIFT_SUB] THEN MATCH_MP_TAC CONTINUOUS_ON_SUB THEN
13938 REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
13939 MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN
13940 REWRITE_TAC[CONTINUOUS_ON_ID];
13941 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[CONTINUOUS_ON_ID] THEN
13942 GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM o_DEF] THEN
13943 MATCH_MP_TAC CONTINUOUS_ON_INV THEN
13944 SIMP_TAC[NORM_POS_LE; REAL_ARITH `&0 <= x ==> ~(&1 + x = &0)`] THEN
13945 REWRITE_TAC[o_DEF; LIFT_ADD] THEN MATCH_MP_TAC CONTINUOUS_ON_ADD THEN
13946 REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
13947 MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN
13948 REWRITE_TAC[CONTINUOUS_ON_ID]]);;
13950 (* ------------------------------------------------------------------------- *)
13951 (* Cardinalities of various useful sets. *)
13952 (* ------------------------------------------------------------------------- *)
13954 let CARD_EQ_EUCLIDEAN = prove
13955 (`(:real^N) =_c (:real)`,
13956 MATCH_MP_TAC CARD_EQ_CART THEN REWRITE_TAC[real_INFINITE]);;
13958 let UNCOUNTABLE_EUCLIDEAN = prove
13959 (`~COUNTABLE(:real^N)`,
13960 MATCH_MP_TAC CARD_EQ_REAL_IMP_UNCOUNTABLE THEN
13961 REWRITE_TAC[CARD_EQ_EUCLIDEAN]);;
13963 let CARD_EQ_INTERVAL = prove
13964 (`(!a b:real^N. ~(interval(a,b) = {}) ==> interval[a,b] =_c (:real)) /\
13965 (!a b:real^N. ~(interval(a,b) = {}) ==> interval(a,b) =_c (:real))`,
13966 REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN
13967 ASM_CASES_TAC `interval(a:real^N,b) = {}` THEN ASM_REWRITE_TAC[] THEN
13968 CONJ_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
13969 [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN
13970 REWRITE_TAC[CARD_LE_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN
13971 REWRITE_TAC[CARD_EQ_EUCLIDEAN];
13972 TRANS_TAC CARD_LE_TRANS `interval(a:real^N,b)` THEN
13973 SIMP_TAC[CARD_LE_SUBSET; INTERVAL_OPEN_SUBSET_CLOSED];
13974 TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN
13975 REWRITE_TAC[CARD_LE_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN
13976 REWRITE_TAC[CARD_EQ_EUCLIDEAN];
13978 TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN
13979 SIMP_TAC[ONCE_REWRITE_RULE[CARD_EQ_SYM] CARD_EQ_IMP_LE;
13980 CARD_EQ_EUCLIDEAN] THEN
13981 FIRST_X_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_OPEN_INTERVAL_UNIV) THEN
13982 DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN
13983 MESON_TAC[CARD_EQ_IMP_LE; CARD_EQ_SYM]);;
13985 let UNCOUNTABLE_INTERVAL = prove
13986 (`(!a b. ~(interval(a,b) = {}) ==> ~COUNTABLE(interval[a,b])) /\
13987 (!a b. ~(interval(a,b) = {}) ==> ~COUNTABLE(interval(a,b)))`,
13988 SIMP_TAC[CARD_EQ_REAL_IMP_UNCOUNTABLE; CARD_EQ_INTERVAL]);;
13990 let COUNTABLE_OPEN_INTERVAL = prove
13991 (`!a b. COUNTABLE(interval(a,b)) <=> interval(a,b) = {}`,
13992 MESON_TAC[COUNTABLE_EMPTY; UNCOUNTABLE_INTERVAL]);;
13994 let CARD_EQ_OPEN = prove
13995 (`!s:real^N->bool. open s /\ ~(s = {}) ==> s =_c (:real)`,
13996 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
13997 [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN
13998 REWRITE_TAC[CARD_LE_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN
13999 REWRITE_TAC[CARD_EQ_EUCLIDEAN];
14000 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_INTERVAL]) THEN
14001 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
14002 DISCH_THEN(X_CHOOSE_TAC `c:real^N`) THEN
14003 DISCH_THEN(MP_TAC o SPEC `c:real^N`) THEN
14004 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
14005 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
14006 ASM_CASES_TAC `interval(a:real^N,b) = {}` THEN
14007 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN STRIP_TAC THEN
14008 TRANS_TAC CARD_LE_TRANS `interval[a:real^N,b]` THEN
14009 ASM_SIMP_TAC[CARD_LE_SUBSET] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN
14010 ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN ASM_SIMP_TAC[CARD_EQ_INTERVAL]]);;
14012 let UNCOUNTABLE_OPEN = prove
14013 (`!s:real^N->bool. open s /\ ~(s = {}) ==> ~(COUNTABLE s)`,
14014 SIMP_TAC[CARD_EQ_OPEN; CARD_EQ_REAL_IMP_UNCOUNTABLE]);;
14016 let CARD_EQ_BALL = prove
14017 (`!a:real^N r. &0 < r ==> ball(a,r) =_c (:real)`,
14018 SIMP_TAC[CARD_EQ_OPEN; OPEN_BALL; BALL_EQ_EMPTY; GSYM REAL_NOT_LT]);;
14020 let CARD_EQ_CBALL = prove
14021 (`!a:real^N r. &0 < r ==> cball(a,r) =_c (:real)`,
14022 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
14023 [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN
14024 REWRITE_TAC[CARD_LE_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN
14025 REWRITE_TAC[CARD_EQ_EUCLIDEAN];
14026 TRANS_TAC CARD_LE_TRANS `ball(a:real^N,r)` THEN
14027 SIMP_TAC[CARD_LE_SUBSET; BALL_SUBSET_CBALL] THEN
14028 MATCH_MP_TAC CARD_EQ_IMP_LE THEN
14029 ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN ASM_SIMP_TAC[CARD_EQ_BALL]]);;
14031 let FINITE_IMP_NOT_OPEN = prove
14032 (`!s:real^N->bool. FINITE s /\ ~(s = {}) ==> ~(open s)`,
14033 MESON_TAC[UNCOUNTABLE_OPEN; FINITE_IMP_COUNTABLE]);;
14035 let OPEN_IMP_INFINITE = prove
14036 (`!s. open s ==> s = {} \/ INFINITE s`,
14037 MESON_TAC[FINITE_IMP_NOT_OPEN; INFINITE]);;
14039 let EMPTY_INTERIOR_FINITE = prove
14040 (`!s:real^N->bool. FINITE s ==> interior s = {}`,
14041 REPEAT STRIP_TAC THEN MP_TAC(ISPEC `s:real^N->bool` OPEN_INTERIOR) THEN
14042 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
14043 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] FINITE_IMP_NOT_OPEN) THEN
14044 MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `s:real^N->bool` THEN
14045 ASM_REWRITE_TAC[INTERIOR_SUBSET]);;
14047 let CARD_EQ_CONNECTED = prove
14049 connected s /\ a IN s /\ b IN s /\ ~(a = b) ==> s =_c (:real)`,
14050 GEOM_ORIGIN_TAC `b:real^N` THEN GEOM_NORMALIZE_TAC `a:real^N` THEN
14051 REWRITE_TAC[NORM_EQ_SQUARE; REAL_POS; REAL_POW_ONE] THEN
14052 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
14053 [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN
14054 SIMP_TAC[CARD_LE_UNIV; CARD_EQ_EUCLIDEAN; CARD_EQ_IMP_LE];
14055 TRANS_TAC CARD_LE_TRANS `interval[vec 0:real^1,vec 1]` THEN CONJ_TAC THENL
14056 [MATCH_MP_TAC(ONCE_REWRITE_RULE[CARD_EQ_SYM] CARD_EQ_IMP_LE) THEN
14057 SIMP_TAC[UNIT_INTERVAL_NONEMPTY; CARD_EQ_INTERVAL];
14058 REWRITE_TAC[LE_C] THEN EXISTS_TAC `\x:real^N. lift(a dot x)` THEN
14059 SIMP_TAC[FORALL_LIFT; LIFT_EQ; IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN
14060 X_GEN_TAC `t:real` THEN STRIP_TAC THEN
14061 MATCH_MP_TAC CONNECTED_IVT_HYPERPLANE THEN
14062 MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `a:real^N`] THEN
14063 ASM_REWRITE_TAC[DOT_RZERO]]]);;
14065 let UNCOUNTABLE_CONNECTED = prove
14067 connected s /\ a IN s /\ b IN s /\ ~(a = b) ==> ~COUNTABLE s`,
14068 REPEAT GEN_TAC THEN STRIP_TAC THEN
14069 MATCH_MP_TAC CARD_EQ_REAL_IMP_UNCOUNTABLE THEN
14070 MATCH_MP_TAC CARD_EQ_CONNECTED THEN
14073 let CARD_LT_IMP_DISCONNECTED = prove
14074 (`!s x:real^N. s <_c (:real) /\ x IN s ==> connected_component s x = {x}`,
14075 REPEAT STRIP_TAC THEN REWRITE_TAC[SET_RULE
14076 `s = {a} <=> a IN s /\ !a b. a IN s /\ b IN s /\ ~(a = b) ==> F`] THEN
14077 REPEAT STRIP_TAC THEN REWRITE_TAC[IN] THEN
14078 ASM_REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN
14079 MP_TAC(ISPECL [`connected_component s (x:real^N)`; `a:real^N`; `b:real^N`]
14080 CARD_EQ_CONNECTED) THEN
14081 ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN
14082 DISCH_TAC THEN UNDISCH_TAC `(s:real^N->bool) <_c (:real)` THEN
14083 REWRITE_TAC[CARD_NOT_LT] THEN
14084 TRANS_TAC CARD_LE_TRANS `connected_component s (x:real^N)` THEN
14085 ASM_SIMP_TAC[ONCE_REWRITE_RULE[CARD_EQ_SYM] CARD_EQ_IMP_LE] THEN
14086 MATCH_MP_TAC CARD_LE_SUBSET THEN REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]);;
14088 let COUNTABLE_IMP_DISCONNECTED = prove
14089 (`!s x:real^N. COUNTABLE s /\ x IN s ==> connected_component s x = {x}`,
14090 SIMP_TAC[CARD_LT_IMP_DISCONNECTED; COUNTABLE_IMP_CARD_LT_REAL]);;
14092 let CONNECTED_CARD_EQ_IFF_NONTRIVIAL = prove
14094 connected s ==> (s =_c (:real) <=> ~(?a. s SUBSET {a}))`,
14095 REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
14096 [ALL_TAC; MATCH_MP_TAC CARD_EQ_CONNECTED THEN ASM SET_TAC[]] THEN
14097 FIRST_ASSUM(MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ_ALT] FINITE_SUBSET)) THEN
14098 REWRITE_TAC[FINITE_SING] THEN
14099 ASM_MESON_TAC[CARD_EQ_REAL_IMP_UNCOUNTABLE; FINITE_IMP_COUNTABLE]);;
14101 (* ------------------------------------------------------------------------- *)
14102 (* "Iff" forms of constancy of function from connected set into a set that *)
14103 (* is smaller than R, or countable, or finite, or disconnected, or discrete. *)
14104 (* ------------------------------------------------------------------------- *)
14106 let [CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ;
14107 CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ;
14108 CONTINUOUS_FINITE_RANGE_CONSTANT_EQ] = (CONJUNCTS o prove)
14109 (`(!s. connected s <=>
14110 !f:real^M->real^N t.
14111 f continuous_on s /\ IMAGE f s SUBSET t /\
14112 (!y. y IN t ==> connected_component t y = {y})
14113 ==> ?a. !x. x IN s ==> f x = a) /\
14114 (!s. connected s <=>
14116 f continuous_on s /\
14119 !y. y IN s /\ ~(f y = f x) ==> e <= norm(f y - f x))
14120 ==> ?a. !x. x IN s ==> f x = a) /\
14121 (!s. connected s <=>
14123 f continuous_on s /\ FINITE(IMAGE f s)
14124 ==> ?a. !x. x IN s ==> f x = a)`,
14125 REWRITE_TAC[AND_FORALL_THM] THEN X_GEN_TAC `s:real^M->bool` THEN
14127 `(s ==> t) /\ (t ==> u) /\ (u ==> v) /\ (v ==> s)
14128 ==> (s <=> t) /\ (s <=> u) /\ (s <=> v)`) THEN
14129 REPEAT CONJ_TAC THENL
14130 [REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^M->bool = {}` THEN
14131 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
14132 FIRST_X_ASSUM(X_CHOOSE_TAC `x:real^M` o
14133 GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
14134 EXISTS_TAC `(f:real^M->real^N) x` THEN
14135 MATCH_MP_TAC(SET_RULE
14136 `IMAGE f s SUBSET {a} ==> !y. y IN s ==> f y = a`) THEN
14137 FIRST_X_ASSUM(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN
14138 ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN(SUBST1_TAC o SYM)] THEN
14139 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
14140 ASM_SIMP_TAC[CONNECTED_CONTINUOUS_IMAGE] THEN ASM SET_TAC[];
14141 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
14142 EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN
14143 ASM_REWRITE_TAC[FORALL_IN_IMAGE; SUBSET_REFL] THEN
14144 X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
14145 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN
14146 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
14147 MATCH_MP_TAC(SET_RULE
14148 `(!y. y IN s /\ f y IN connected_component (IMAGE f s) a ==> f y = a) /\
14149 connected_component (IMAGE f s) a SUBSET (IMAGE f s) /\
14150 connected_component (IMAGE f s) a a
14151 ==> connected_component (IMAGE f s) a = {a}`) THEN
14152 REWRITE_TAC[CONNECTED_COMPONENT_SUBSET; CONNECTED_COMPONENT_REFL_EQ] THEN
14153 ASM_SIMP_TAC[FUN_IN_IMAGE] THEN X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN
14154 MP_TAC(ISPEC `connected_component (IMAGE (f:real^M->real^N) s) (f x)`
14155 CONNECTED_CLOSED) THEN
14156 REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN
14157 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
14158 ASM_REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC
14159 [`cball((f:real^M->real^N) x,e / &2)`;
14160 `(:real^N) DIFF ball((f:real^M->real^N) x,e)`] THEN
14161 REWRITE_TAC[GSYM OPEN_CLOSED; OPEN_BALL; CLOSED_CBALL] THEN
14162 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REPEAT CONJ_TAC THENL
14163 [REWRITE_TAC[SUBSET; IN_CBALL; IN_UNION; IN_DIFF; IN_BALL; IN_UNIV] THEN
14164 MATCH_MP_TAC(MESON[SUBSET; CONNECTED_COMPONENT_SUBSET]
14165 `(!x. x IN s ==> P x)
14166 ==> (!x. x IN connected_component s y ==> P x)`) THEN
14167 REWRITE_TAC[FORALL_IN_IMAGE] THEN X_GEN_TAC `z:real^M` THEN
14168 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `z:real^M`) THEN
14169 ASM_REWRITE_TAC[] THEN CONV_TAC NORM_ARITH;
14170 MATCH_MP_TAC(SET_RULE
14171 `(!x. x IN s /\ x IN t ==> F) ==> s INTER t INTER u = {}`) THEN
14172 REWRITE_TAC[IN_BALL; IN_CBALL; IN_DIFF; IN_UNIV] THEN
14173 UNDISCH_TAC `&0 < e` THEN CONV_TAC NORM_ARITH;
14174 EXISTS_TAC `(f:real^M->real^N) x` THEN
14175 ASM_SIMP_TAC[CENTRE_IN_CBALL; REAL_HALF; REAL_LT_IMP_LE; IN_INTER] THEN
14176 REWRITE_TAC[IN] THEN
14177 ASM_SIMP_TAC[CONNECTED_COMPONENT_REFL_EQ; FUN_IN_IMAGE];
14178 EXISTS_TAC `(f:real^M->real^N) y` THEN
14179 ASM_REWRITE_TAC[IN_INTER; IN_DIFF; IN_UNIV; IN_BALL; REAL_NOT_LT] THEN
14180 ASM_SIMP_TAC[ONCE_REWRITE_RULE[DIST_SYM] dist]];
14181 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `f:real^M->real^N` THEN
14182 DISCH_THEN(fun th -> STRIP_TAC THEN MATCH_MP_TAC th) THEN
14183 ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
14184 ASM_CASES_TAC `IMAGE (f:real^M->real^N) s DELETE (f x) = {}` THENL
14185 [EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN ASM SET_TAC[];
14188 `inf{norm(z - f x) |z| z IN IMAGE (f:real^M->real^N) s DELETE (f x)}` THEN
14189 REWRITE_TAC[SIMPLE_IMAGE] THEN
14190 ASM_SIMP_TAC[REAL_LT_INF_FINITE; REAL_INF_LE_FINITE; FINITE_DELETE;
14191 FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
14192 REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN
14193 REWRITE_TAC[IN_DELETE; NORM_POS_LT; VECTOR_SUB_EQ; IN_IMAGE] THEN
14194 MESON_TAC[REAL_LE_REFL];
14195 REWRITE_TAC[CONNECTED_CLOSED_IN_EQ] THEN
14196 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
14197 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
14198 MAP_EVERY X_GEN_TAC [`t:real^M->bool`; `u:real^M->bool`] THEN
14199 STRIP_TAC THEN DISCH_THEN(MP_TAC o SPEC
14200 `(\x. if x IN t then vec 0 else basis 1):real^M->real^N`) THEN
14201 REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL
14202 [EXPAND_TAC "s" THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN
14203 ASM_REWRITE_TAC[CONTINUOUS_ON_CONST] THEN ASM SET_TAC[];
14204 MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `{vec 0:real^N,basis 1}` THEN
14205 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY] THEN SET_TAC[];
14206 SUBGOAL_THEN `?a b:real^M. a IN s /\ a IN t /\ b IN s /\ ~(b IN t)`
14207 STRIP_ASSUME_TAC THENL
14208 [ASM SET_TAC[]; DISCH_THEN(CHOOSE_THEN MP_TAC)] THEN
14209 DISCH_THEN(fun th -> MP_TAC(SPEC `a:real^M` th) THEN
14210 MP_TAC(SPEC `b:real^M` th)) THEN
14211 ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
14212 CONV_TAC(RAND_CONV SYM_CONV) THEN
14213 SIMP_TAC[BASIS_NONZERO; LE_REFL; DIMINDEX_GE_1; REAL_LE_REFL]]]);;
14215 let CONTINUOUS_DISCONNECTED_RANGE_CONSTANT = prove
14216 (`!f:real^M->real^N s.
14218 f continuous_on s /\ IMAGE f s SUBSET t /\
14219 (!y. y IN t ==> connected_component t y = {y})
14220 ==> ?a. !x. x IN s ==> f x = a`,
14221 MESON_TAC[CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ]);;
14223 let CONTINUOUS_DISCRETE_RANGE_CONSTANT = prove
14224 (`!f:real^M->real^N s.
14226 f continuous_on s /\
14229 !y. y IN s /\ ~(f y = f x) ==> e <= norm(f y - f x))
14230 ==> ?a. !x. x IN s ==> f x = a`,
14231 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
14232 REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN
14233 REWRITE_TAC[IMP_IMP; GSYM CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ]);;
14235 let CONTINUOUS_FINITE_RANGE_CONSTANT = prove
14236 (`!f:real^M->real^N s.
14238 f continuous_on s /\
14240 ==> ?a. !x. x IN s ==> f x = a`,
14241 MESON_TAC[CONTINUOUS_FINITE_RANGE_CONSTANT_EQ]);;
14243 let CONTINUOUS_COUNTABLE_RANGE_CONSTANT_EQ = prove
14244 (`!s. connected s <=>
14246 f continuous_on s /\ COUNTABLE(IMAGE f s)
14247 ==> ?a. !x. x IN s ==> f x = a`,
14248 GEN_TAC THEN EQ_TAC THENL
14249 [REWRITE_TAC[CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ];
14250 REWRITE_TAC[CONTINUOUS_FINITE_RANGE_CONSTANT_EQ]] THEN
14251 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
14252 ASM_SIMP_TAC[FINITE_IMP_COUNTABLE] THEN
14253 EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN
14254 ASM_SIMP_TAC[COUNTABLE_IMP_DISCONNECTED; SUBSET_REFL]);;
14256 let CONTINUOUS_CARD_LT_RANGE_CONSTANT_EQ = prove
14257 (`!s. connected s <=>
14259 f continuous_on s /\ (IMAGE f s) <_c (:real)
14260 ==> ?a. !x. x IN s ==> f x = a`,
14261 GEN_TAC THEN EQ_TAC THENL
14262 [REWRITE_TAC[CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ];
14263 REWRITE_TAC[CONTINUOUS_COUNTABLE_RANGE_CONSTANT_EQ]] THEN
14264 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
14265 ASM_SIMP_TAC[COUNTABLE_IMP_CARD_LT_REAL] THEN
14266 EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN
14267 ASM_SIMP_TAC[CARD_LT_IMP_DISCONNECTED; SUBSET_REFL]);;
14269 let CONTINUOUS_COUNTABLE_RANGE_CONSTANT = prove
14270 (`!f:real^M->real^N s.
14271 connected s /\ f continuous_on s /\ COUNTABLE(IMAGE f s)
14272 ==> ?a. !x. x IN s ==> f x = a`,
14273 MESON_TAC[CONTINUOUS_COUNTABLE_RANGE_CONSTANT_EQ]);;
14275 let CONTINUOUS_CARD_LT_RANGE_CONSTANT = prove
14276 (`!f:real^M->real^N s.
14277 connected s /\ f continuous_on s /\ (IMAGE f s) <_c (:real)
14278 ==> ?a. !x. x IN s ==> f x = a`,
14279 MESON_TAC[CONTINUOUS_CARD_LT_RANGE_CONSTANT_EQ]);;
14281 (* ------------------------------------------------------------------------- *)
14282 (* Homeomorphism of hyperplanes. *)
14283 (* ------------------------------------------------------------------------- *)
14285 let HOMEOMORPHIC_HYPERPLANES = prove
14286 (`!a:real^N b c:real^N d.
14287 ~(a = vec 0) /\ ~(c = vec 0)
14288 ==> {x | a dot x = b} homeomorphic {x | c dot x = d}`,
14291 ==> {x:real^N | a dot x = b} homeomorphic {x:real^N | x$1 = &0}`,
14292 REPEAT STRIP_TAC THEN SUBGOAL_THEN `?c:real^N. a dot c = b`
14293 STRIP_ASSUME_TAC THENL
14294 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CART_EQ]) THEN
14295 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; VEC_COMPONENT] THEN
14296 DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN
14297 EXISTS_TAC `b / (a:real^N)$k % basis k:real^N` THEN
14298 ASM_SIMP_TAC[DOT_RMUL; DOT_BASIS; REAL_DIV_RMUL];
14299 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
14300 ABBREV_TAC `p = {x:real^N | x$1 = &0}` THEN
14301 GEOM_ORIGIN_TAC `c:real^N` THEN
14302 REWRITE_TAC[VECTOR_ADD_RID; DOT_RADD; DOT_RZERO; REAL_EQ_ADD_LCANCEL_0;
14304 REPEAT STRIP_TAC THEN UNDISCH_TAC `~(a:real^N = vec 0)` THEN
14305 GEOM_BASIS_MULTIPLE_TAC 1 `a:real^N` THEN
14306 SIMP_TAC[VECTOR_MUL_EQ_0; DE_MORGAN_THM; DOT_LMUL; REAL_ENTIRE] THEN
14307 SIMP_TAC[DOT_BASIS; LE_REFL; DIMINDEX_GE_1] THEN
14308 EXPAND_TAC "p" THEN REWRITE_TAC[HOMEOMORPHIC_REFL]]) in
14309 REPEAT STRIP_TAC THEN
14310 TRANS_TAC HOMEOMORPHIC_TRANS `{x:real^N | x$1 = &0}` THEN
14311 ASM_SIMP_TAC[lemma] THEN ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN
14312 ASM_SIMP_TAC[lemma]);;
14314 let HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE = prove
14316 ~(a = vec 0) /\ 1 <= k /\ k <= dimindex(:N)
14317 ==> {x | a dot x = b} homeomorphic {x:real^N | x$k = c}`,
14318 REPEAT STRIP_TAC THEN
14319 SUBGOAL_THEN `{x:real^N | x$k = c} = {x | basis k dot x = c}` SUBST1_TAC
14320 THENL [ASM_SIMP_TAC[DOT_BASIS]; MATCH_MP_TAC HOMEOMORPHIC_HYPERPLANES] THEN
14321 ASM_SIMP_TAC[BASIS_NONZERO]);;
14323 let HOMEOMORPHIC_STANDARD_HYPERPLANE_HYPERPLANE = prove
14325 ~(a = vec 0) /\ 1 <= k /\ k <= dimindex(:N)
14326 ==> {x:real^N | x$k = c} homeomorphic {x | a dot x = b}`,
14327 ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN
14328 REWRITE_TAC[HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE]);;
14330 let HOMEOMORPHIC_HYPERPLANE_UNIV = prove
14331 (`!a b. ~(a = vec 0) /\ dimindex(:N) = dimindex(:M) + 1
14332 ==> {x:real^N | a dot x = b} homeomorphic (:real^M)`,
14333 REPEAT STRIP_TAC THEN TRANS_TAC HOMEOMORPHIC_TRANS
14334 `{x:real^N | basis(dimindex(:N)) dot x = &0}` THEN
14335 ASM_SIMP_TAC[HOMEOMORPHIC_HYPERPLANES; BASIS_NONZERO;
14336 LE_REFL; DIMINDEX_GE_1] THEN
14337 REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN
14338 EXISTS_TAC `(\x. lambda i. x$i):real^N->real^M` THEN
14339 EXISTS_TAC `(\x. lambda i. if i <= dimindex(:M) then x$i else &0)
14340 :real^M->real^N` THEN
14341 REPEAT CONJ_TAC THENL
14342 [MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN
14343 SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
14344 VECTOR_MUL_COMPONENT];
14345 REWRITE_TAC[SUBSET_UNIV];
14346 MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN
14347 SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
14348 VECTOR_MUL_COMPONENT] THEN
14349 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
14351 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM; IN_UNIV] THEN
14352 ASM_SIMP_TAC[DOT_BASIS; LAMBDA_BETA; LE_REFL; ARITH_RULE `1 <= n + 1`;
14353 ARITH_RULE `~(m + 1 <= m)`];
14354 ASM_SIMP_TAC[IN_ELIM_THM; LAMBDA_BETA; DOT_BASIS; LE_REFL; CART_EQ;
14355 ARITH_RULE `1 <= n + 1`] THEN
14356 GEN_TAC THEN DISCH_TAC THEN X_GEN_TAC `i:num` THEN
14357 ASM_CASES_TAC `i = dimindex(:M) + 1` THEN ASM_REWRITE_TAC[COND_ID] THEN
14358 COND_CASES_TAC THEN REWRITE_TAC[] THEN ASM_ARITH_TAC;
14359 ASM_SIMP_TAC[LAMBDA_BETA; CART_EQ; IN_UNIV; LE_REFL;
14360 ARITH_RULE `i <= n ==> i <= n + 1`]]);;
14362 (* ------------------------------------------------------------------------- *)
14363 (* "Isometry" (up to constant bounds) of injective linear map etc. *)
14364 (* ------------------------------------------------------------------------- *)
14366 let CAUCHY_ISOMETRIC = prove
14368 &0 < e /\ subspace s /\
14369 linear f /\ (!x. x IN s ==> norm(f x) >= e * norm(x)) /\
14370 (!n. x(n) IN s) /\ cauchy(f o x)
14372 REPEAT GEN_TAC THEN REWRITE_TAC[real_ge] THEN
14373 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
14374 REWRITE_TAC[CAUCHY; dist; o_THM] THEN
14375 FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_SUB th)]) THEN
14376 DISCH_THEN(fun th -> X_GEN_TAC `d:real` THEN DISCH_TAC THEN MP_TAC th) THEN
14377 DISCH_THEN(MP_TAC o SPEC `d * e`) THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN
14378 ASM_MESON_TAC[REAL_LE_RDIV_EQ; REAL_MUL_SYM; REAL_LET_TRANS; SUBSPACE_SUB;
14379 REAL_LT_LDIV_EQ]);;
14381 let COMPLETE_ISOMETRIC_IMAGE = prove
14382 (`!f:real^M->real^N s e.
14383 &0 < e /\ subspace s /\
14384 linear f /\ (!x. x IN s ==> norm(f x) >= e * norm(x)) /\
14386 ==> complete(IMAGE f s)`,
14387 REPEAT GEN_TAC THEN REWRITE_TAC[complete; EXISTS_IN_IMAGE] THEN
14388 STRIP_TAC THEN X_GEN_TAC `g:num->real^N` THEN
14389 REWRITE_TAC[IN_IMAGE; SKOLEM_THM; FORALL_AND_THM] THEN
14390 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
14391 DISCH_THEN(X_CHOOSE_THEN `x:num->real^M` MP_TAC) THEN
14392 GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM FUN_EQ_THM] THEN
14393 REWRITE_TAC[GSYM o_DEF] THEN
14394 DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN
14395 FIRST_X_ASSUM(MP_TAC o SPEC `x:num->real^M`) THEN
14396 ASM_MESON_TAC[CAUCHY_ISOMETRIC; LINEAR_CONTINUOUS_AT;
14397 CONTINUOUS_AT_SEQUENTIALLY]);;
14399 let INJECTIVE_IMP_ISOMETRIC = prove
14400 (`!f:real^M->real^N s.
14401 closed s /\ subspace s /\
14402 linear f /\ (!x. x IN s /\ (f x = vec 0) ==> (x = vec 0))
14403 ==> ?e. &0 < e /\ !x. x IN s ==> norm(f x) >= e * norm(x)`,
14404 REPEAT STRIP_TAC THEN
14405 ASM_CASES_TAC `s SUBSET {vec 0 :real^M}` THENL
14406 [EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01; REAL_MUL_LID; real_ge] THEN
14407 ASM_MESON_TAC[SUBSET; IN_SING; NORM_0; LINEAR_0; REAL_LE_REFL];
14409 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [SUBSET]) THEN
14410 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; IN_SING] THEN
14411 DISCH_THEN(X_CHOOSE_THEN `a:real^M` STRIP_ASSUME_TAC) THEN
14413 [`{(f:real^M->real^N) x | x IN s /\ norm(x) = norm(a:real^M)}`;
14414 `vec 0:real^N`] DISTANCE_ATTAINS_INF) THEN
14416 [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
14417 CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
14418 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
14419 SUBST1_TAC(SET_RULE
14420 `{f x | x IN s /\ norm(x) = norm(a:real^M)} =
14421 IMAGE (f:real^M->real^N) (s INTER {x | norm x = norm a})`) THEN
14422 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
14423 ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN
14424 MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN
14426 `{x:real^M | norm x = norm(a:real^M)} = frontier(cball(vec 0,norm a))`
14428 [ASM_SIMP_TAC[FRONTIER_CBALL; NORM_POS_LT; dist; VECTOR_SUB_LZERO;
14430 ASM_SIMP_TAC[COMPACT_FRONTIER; COMPACT_CBALL]];
14432 ONCE_REWRITE_TAC[SET_RULE `{f x | P x} = IMAGE f {x | P x}`] THEN
14433 REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN
14434 DISCH_THEN(X_CHOOSE_THEN `b:real^M` MP_TAC) THEN
14435 REWRITE_TAC[IN_ELIM_THM; dist; VECTOR_SUB_LZERO; NORM_NEG] THEN
14436 STRIP_TAC THEN REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE] THEN
14437 EXISTS_TAC `norm((f:real^M->real^N) b) / norm(b)` THEN CONJ_TAC THENL
14438 [ASM_MESON_TAC[REAL_LT_DIV; NORM_POS_LT; NORM_EQ_0]; ALL_TAC] THEN
14439 X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
14440 ASM_CASES_TAC `x:real^M = vec 0` THENL
14441 [FIRST_ASSUM(fun th -> ASM_REWRITE_TAC[MATCH_MP LINEAR_0 th]) THEN
14442 REWRITE_TAC[NORM_0; REAL_MUL_RZERO; real_ge; REAL_LE_REFL];
14444 FIRST_X_ASSUM(MP_TAC o SPEC `(norm(a:real^M) / norm(x)) % x:real^M`) THEN
14446 [ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN
14447 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN ASM_MESON_TAC[subspace];
14449 FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_CMUL th]) THEN
14450 ASM_REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; real_ge] THEN
14451 ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; NORM_POS_LT] THEN
14452 REWRITE_TAC[real_div; REAL_MUL_AC]);;
14454 let CLOSED_INJECTIVE_IMAGE_SUBSPACE = prove
14455 (`!f s. subspace s /\
14457 (!x. x IN s /\ f(x) = vec 0 ==> x = vec 0) /\
14459 ==> closed(IMAGE f s)`,
14460 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM COMPLETE_EQ_CLOSED] THEN
14461 MATCH_MP_TAC COMPLETE_ISOMETRIC_IMAGE THEN
14462 ASM_REWRITE_TAC[COMPLETE_EQ_CLOSED] THEN
14463 MATCH_MP_TAC INJECTIVE_IMP_ISOMETRIC THEN
14464 ASM_REWRITE_TAC[]);;
14466 (* ------------------------------------------------------------------------- *)
14467 (* Relating linear images to open/closed/interior/closure. *)
14468 (* ------------------------------------------------------------------------- *)
14470 let OPEN_SURJECTIVE_LINEAR_IMAGE = prove
14471 (`!f:real^M->real^N.
14472 linear f /\ (!y. ?x. f x = y)
14473 ==> !s. open s ==> open(IMAGE f s)`,
14474 GEN_TAC THEN STRIP_TAC THEN
14475 REWRITE_TAC[open_def; FORALL_IN_IMAGE] THEN
14476 FIRST_ASSUM(MP_TAC o GEN `k:num` o SPEC `basis k:real^N`) THEN
14477 REWRITE_TAC[SKOLEM_THM] THEN
14478 DISCH_THEN(X_CHOOSE_THEN `b:num->real^M` STRIP_ASSUME_TAC) THEN
14479 SUBGOAL_THEN `bounded(IMAGE (b:num->real^M) (1..dimindex(:N)))` MP_TAC THENL
14480 [SIMP_TAC[FINITE_IMP_BOUNDED; FINITE_IMAGE; FINITE_NUMSEG]; ALL_TAC] THEN
14481 REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; IN_NUMSEG] THEN
14482 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
14483 X_GEN_TAC `s:real^M->bool` THEN MATCH_MP_TAC MONO_FORALL THEN
14484 X_GEN_TAC `x:real^M` THEN ASM_CASES_TAC `(x:real^M) IN s` THEN
14485 ASM_REWRITE_TAC[] THEN
14486 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
14487 EXISTS_TAC `e / B / &(dimindex(:N))` THEN
14488 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1] THEN
14489 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_IMAGE] THEN
14490 ABBREV_TAC `u = y - (f:real^M->real^N) x` THEN
14491 EXISTS_TAC `x + vsum(1..dimindex(:N)) (\i. (u:real^N)$i % b i):real^M` THEN
14492 ASM_SIMP_TAC[LINEAR_ADD; LINEAR_VSUM; FINITE_NUMSEG; o_DEF;
14493 LINEAR_CMUL; BASIS_EXPANSION] THEN
14494 CONJ_TAC THENL [EXPAND_TAC "u" THEN VECTOR_ARITH_TAC; ALL_TAC] THEN
14495 FIRST_X_ASSUM MATCH_MP_TAC THEN
14496 REWRITE_TAC[NORM_ARITH `dist(x + y,x) = norm y`] THEN
14497 MATCH_MP_TAC REAL_LET_TRANS THEN
14498 EXISTS_TAC `(dist(y,(f:real^M->real^N) x) * &(dimindex(:N))) * B` THEN
14499 ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1] THEN
14500 MATCH_MP_TAC VSUM_NORM_TRIANGLE THEN REWRITE_TAC[FINITE_NUMSEG] THEN
14501 ONCE_REWRITE_TAC[REAL_ARITH `(a * b) * c:real = b * a * c`] THEN
14502 GEN_REWRITE_TAC(RAND_CONV o LAND_CONV o RAND_CONV) [GSYM CARD_NUMSEG_1] THEN
14503 MATCH_MP_TAC SUM_BOUND THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
14504 X_GEN_TAC `k:num` THEN STRIP_TAC THEN REWRITE_TAC[NORM_MUL; dist] THEN
14505 MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[REAL_ABS_POS; NORM_POS_LE] THEN
14506 ASM_SIMP_TAC[COMPONENT_LE_NORM]);;
14508 let OPEN_BIJECTIVE_LINEAR_IMAGE_EQ = prove
14509 (`!f:real^M->real^N s.
14510 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
14511 ==> (open(IMAGE f s) <=> open s)`,
14512 REPEAT STRIP_TAC THEN EQ_TAC THENL
14513 [DISCH_TAC; ASM_MESON_TAC[OPEN_SURJECTIVE_LINEAR_IMAGE]] THEN
14514 SUBGOAL_THEN `s = {x | (f:real^M->real^N) x IN IMAGE f s}`
14515 SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
14516 MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE_UNIV THEN
14517 ASM_SIMP_TAC[LINEAR_CONTINUOUS_AT]);;
14519 add_linear_invariants [OPEN_BIJECTIVE_LINEAR_IMAGE_EQ];;
14521 let CLOSED_INJECTIVE_LINEAR_IMAGE = prove
14522 (`!f:real^M->real^N.
14523 linear f /\ (!x y. f x = f y ==> x = y)
14524 ==> !s. closed s ==> closed(IMAGE f s)`,
14525 REPEAT STRIP_TAC THEN
14526 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN
14527 ASM_REWRITE_TAC[] THEN
14528 DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN
14529 MATCH_MP_TAC CLOSED_IN_CLOSED_TRANS THEN
14530 EXISTS_TAC `IMAGE (f:real^M->real^N) (:real^M)` THEN
14532 [MP_TAC(ISPECL [`g:real^N->real^M`; `IMAGE (f:real^M->real^N) (:real^M)`;
14533 `IMAGE (g:real^N->real^M) (IMAGE (f:real^M->real^N) s)`]
14534 CONTINUOUS_CLOSED_IN_PREIMAGE) THEN
14535 ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN ANTS_TAC THENL
14536 [ASM_REWRITE_TAC[GSYM IMAGE_o; IMAGE_I]; ALL_TAC] THEN
14537 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
14538 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FUN_EQ_THM]) THEN
14539 REWRITE_TAC[EXTENSION; o_THM; I_THM] THEN SET_TAC[];
14540 MATCH_MP_TAC CLOSED_INJECTIVE_IMAGE_SUBSPACE THEN
14541 ASM_REWRITE_TAC[IN_UNIV; SUBSPACE_UNIV; CLOSED_UNIV] THEN
14542 X_GEN_TAC `x:real^M` THEN
14543 DISCH_THEN(MP_TAC o AP_TERM `g:real^N->real^M`) THEN
14544 RULE_ASSUM_TAC(REWRITE_RULE[FUN_EQ_THM; I_THM; o_THM]) THEN
14545 ASM_MESON_TAC[LINEAR_0]]);;
14547 let CLOSED_INJECTIVE_LINEAR_IMAGE_EQ = prove
14548 (`!f:real^M->real^N s.
14549 linear f /\ (!x y. f x = f y ==> x = y)
14550 ==> (closed(IMAGE f s) <=> closed s)`,
14551 REPEAT STRIP_TAC THEN EQ_TAC THENL
14552 [DISCH_TAC; ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE]] THEN
14553 SUBGOAL_THEN `s = {x | (f:real^M->real^N) x IN IMAGE f s}`
14554 SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
14555 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN
14556 ASM_SIMP_TAC[LINEAR_CONTINUOUS_AT]);;
14558 add_linear_invariants [CLOSED_INJECTIVE_LINEAR_IMAGE_EQ];;
14560 let CLOSURE_LINEAR_IMAGE_SUBSET = prove
14561 (`!f:real^M->real^N s.
14562 linear f ==> IMAGE f (closure s) SUBSET closure(IMAGE f s)`,
14563 REPEAT STRIP_TAC THEN
14564 MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN
14565 ASM_SIMP_TAC[CLOSED_CLOSURE; CLOSURE_SUBSET; LINEAR_CONTINUOUS_ON]);;
14567 let CLOSURE_INJECTIVE_LINEAR_IMAGE = prove
14568 (`!f:real^M->real^N s.
14569 linear f /\ (!x y. f x = f y ==> x = y)
14570 ==> closure(IMAGE f s) = IMAGE f (closure s)`,
14571 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
14572 ASM_SIMP_TAC[CLOSURE_LINEAR_IMAGE_SUBSET] THEN
14573 MATCH_MP_TAC CLOSURE_MINIMAL THEN
14574 SIMP_TAC[CLOSURE_SUBSET; IMAGE_SUBSET] THEN
14575 ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE; CLOSED_CLOSURE]);;
14577 add_linear_invariants [CLOSURE_INJECTIVE_LINEAR_IMAGE];;
14579 let CLOSURE_BOUNDED_LINEAR_IMAGE = prove
14580 (`!f:real^M->real^N s.
14581 linear f /\ bounded s
14582 ==> closure(IMAGE f s) = IMAGE f (closure s)`,
14583 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
14584 ASM_SIMP_TAC[CLOSURE_LINEAR_IMAGE_SUBSET] THEN
14585 MATCH_MP_TAC CLOSURE_MINIMAL THEN
14586 SIMP_TAC[CLOSURE_SUBSET; IMAGE_SUBSET] THEN
14587 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
14588 MATCH_MP_TAC COMPACT_LINEAR_IMAGE THEN
14589 ASM_REWRITE_TAC[COMPACT_CLOSURE]);;
14591 let LINEAR_INTERIOR_IMAGE_SUBSET = prove
14592 (`!f:real^M->real^N s.
14593 linear f /\ (!x y. f x = f y ==> x = y)
14594 ==> interior(IMAGE f s) SUBSET IMAGE f (interior s)`,
14595 MESON_TAC[INTERIOR_IMAGE_SUBSET; LINEAR_CONTINUOUS_AT]);;
14597 let LINEAR_IMAGE_SUBSET_INTERIOR = prove
14598 (`!f:real^M->real^N s.
14599 linear f /\ (!y. ?x. f x = y)
14600 ==> IMAGE f (interior s) SUBSET interior(IMAGE f s)`,
14601 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_MAXIMAL THEN
14602 ASM_SIMP_TAC[OPEN_SURJECTIVE_LINEAR_IMAGE; OPEN_INTERIOR;
14603 IMAGE_SUBSET; INTERIOR_SUBSET]);;
14605 let INTERIOR_BIJECTIVE_LINEAR_IMAGE = prove
14606 (`!f:real^M->real^N s.
14607 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
14608 ==> interior(IMAGE f s) = IMAGE f (interior s)`,
14609 REWRITE_TAC[interior] THEN GEOM_TRANSFORM_TAC[]);;
14611 add_linear_invariants [INTERIOR_BIJECTIVE_LINEAR_IMAGE];;
14613 let FRONTIER_BIJECTIVE_LINEAR_IMAGE = prove
14614 (`!f:real^M->real^N s.
14615 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
14616 ==> frontier(IMAGE f s) = IMAGE f (frontier s)`,
14617 REWRITE_TAC[frontier] THEN GEOM_TRANSFORM_TAC[]);;
14619 add_linear_invariants [FRONTIER_BIJECTIVE_LINEAR_IMAGE];;
14621 (* ------------------------------------------------------------------------- *)
14622 (* Corollaries, reformulations and special cases for M = N. *)
14623 (* ------------------------------------------------------------------------- *)
14625 let IN_INTERIOR_LINEAR_IMAGE = prove
14626 (`!f:real^M->real^N g s x.
14627 linear f /\ linear g /\ (f o g = I) /\ x IN interior s
14628 ==> (f x) IN interior (IMAGE f s)`,
14629 REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN REPEAT STRIP_TAC THEN
14630 MP_TAC(ISPECL [`f:real^M->real^N`; `s:real^M->bool`]
14631 LINEAR_IMAGE_SUBSET_INTERIOR) THEN
14632 ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
14635 let LINEAR_OPEN_MAPPING = prove
14636 (`!f:real^M->real^N g.
14637 linear f /\ linear g /\ (f o g = I)
14638 ==> !s. open s ==> open(IMAGE f s)`,
14639 REPEAT GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN DISCH_TAC THEN
14640 MATCH_MP_TAC OPEN_SURJECTIVE_LINEAR_IMAGE THEN
14643 let INTERIOR_INJECTIVE_LINEAR_IMAGE = prove
14644 (`!f:real^N->real^N s.
14645 linear f /\ (!x y. f x = f y ==> x = y)
14646 ==> interior(IMAGE f s) = IMAGE f (interior s)`,
14647 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_BIJECTIVE_LINEAR_IMAGE THEN
14648 ASM_MESON_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE]);;
14650 let INTERIOR_SURJECTIVE_LINEAR_IMAGE = prove
14651 (`!f:real^N->real^N s.
14652 linear f /\ (!y. ?x. f x = y)
14653 ==> interior(IMAGE f s) = IMAGE f (interior s)`,
14654 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_BIJECTIVE_LINEAR_IMAGE THEN
14655 ASM_MESON_TAC[LINEAR_SURJECTIVE_IMP_INJECTIVE]);;
14657 let CLOSURE_SURJECTIVE_LINEAR_IMAGE = prove
14658 (`!f:real^N->real^N s.
14659 linear f /\ (!y. ?x. f x = y)
14660 ==> closure(IMAGE f s) = IMAGE f (closure s)`,
14661 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_INJECTIVE_LINEAR_IMAGE THEN
14662 ASM_MESON_TAC[LINEAR_SURJECTIVE_IMP_INJECTIVE]);;
14664 let FRONTIER_INJECTIVE_LINEAR_IMAGE = prove
14665 (`!f:real^N->real^N s.
14666 linear f /\ (!x y. f x = f y ==> x = y)
14667 ==> frontier(IMAGE f s) = IMAGE f (frontier s)`,
14668 REPEAT STRIP_TAC THEN MATCH_MP_TAC FRONTIER_BIJECTIVE_LINEAR_IMAGE THEN
14669 ASM_MESON_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE]);;
14671 let FRONTIER_SURJECTIVE_LINEAR_IMAGE = prove
14672 (`!f:real^N->real^N.
14673 linear f /\ (!y. ?x. f x = y)
14674 ==> frontier(IMAGE f s) = IMAGE f (frontier s)`,
14675 REPEAT STRIP_TAC THEN MATCH_MP_TAC FRONTIER_BIJECTIVE_LINEAR_IMAGE THEN
14676 ASM_MESON_TAC[LINEAR_SURJECTIVE_IMP_INJECTIVE]);;
14678 let COMPLETE_INJECTIVE_LINEAR_IMAGE = prove
14679 (`!f:real^M->real^N.
14680 linear f /\ (!x y. f x = f y ==> x = y)
14681 ==> !s. complete s ==> complete(IMAGE f s)`,
14682 REWRITE_TAC[COMPLETE_EQ_CLOSED; CLOSED_INJECTIVE_LINEAR_IMAGE]);;
14684 let COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ = prove
14685 (`!f:real^M->real^N s.
14686 linear f /\ (!x y. f x = f y ==> x = y)
14687 ==> (complete(IMAGE f s) <=> complete s)`,
14688 REWRITE_TAC[COMPLETE_EQ_CLOSED; CLOSED_INJECTIVE_LINEAR_IMAGE_EQ]);;
14690 add_linear_invariants [COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ];;
14692 let LIMPT_INJECTIVE_LINEAR_IMAGE_EQ = prove
14693 (`!f:real^M->real^N s.
14694 linear f /\ (!x y. f x = f y ==> x = y)
14695 ==> ((f x) limit_point_of (IMAGE f s) <=> x limit_point_of s)`,
14696 REWRITE_TAC[LIMPT_APPROACHABLE; EXISTS_IN_IMAGE] THEN
14697 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN
14699 [MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_BOUNDED_BELOW_POS);
14700 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_BOUNDED_POS)] THEN
14701 ASM_REWRITE_TAC[] THEN
14702 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THENL
14703 [FIRST_X_ASSUM(MP_TAC o SPEC `e * B:real`);
14704 FIRST_X_ASSUM(MP_TAC o SPEC `e / B:real`)] THEN
14705 ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; dist; GSYM LINEAR_SUB] THEN
14706 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
14707 REPEAT(MATCH_MP_TAC MONO_AND THEN
14708 CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN
14709 ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ] THEN
14710 MATCH_MP_TAC(REAL_ARITH `a <= b ==> b < x ==> a < x`) THEN
14711 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_SIMP_TAC[REAL_LE_RDIV_EQ]);;
14713 add_linear_invariants [LIMPT_INJECTIVE_LINEAR_IMAGE_EQ];;
14715 let LIMPT_TRANSLATION_EQ = prove
14716 (`!a s x. (a + x) limit_point_of (IMAGE (\y. a + y) s) <=> x limit_point_of s`,
14717 REWRITE_TAC[limit_point_of] THEN GEOM_TRANSLATE_TAC[]);;
14719 add_translation_invariants [LIMPT_TRANSLATION_EQ];;
14721 let OPEN_OPEN_LEFT_PROJECTION = prove
14722 (`!s t:real^(M,N)finite_sum->bool.
14723 open s /\ open t ==> open {x | x IN s /\ ?y. pastecart x y IN t}`,
14724 REPEAT STRIP_TAC THEN
14726 `{x | x IN s /\ ?y. (pastecart x y:real^(M,N)finite_sum) IN t} =
14727 s INTER IMAGE fstcart t`
14729 [REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; IN_IMAGE] THEN
14730 MESON_TAC[FSTCART_PASTECART; PASTECART_FST_SND];
14731 MATCH_MP_TAC OPEN_INTER THEN ASM_REWRITE_TAC[] THEN
14732 MATCH_MP_TAC(REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM]
14733 OPEN_SURJECTIVE_LINEAR_IMAGE) THEN
14734 ASM_REWRITE_TAC[LINEAR_FSTCART] THEN MESON_TAC[FSTCART_PASTECART]]);;
14736 let OPEN_OPEN_RIGHT_PROJECTION = prove
14737 (`!s t:real^(M,N)finite_sum->bool.
14738 open s /\ open t ==> open {y | y IN s /\ ?x. pastecart x y IN t}`,
14739 REPEAT STRIP_TAC THEN
14741 `{y | y IN s /\ ?x. (pastecart x y:real^(M,N)finite_sum) IN t} =
14742 s INTER IMAGE sndcart t`
14744 [REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; IN_IMAGE] THEN
14745 MESON_TAC[SNDCART_PASTECART; PASTECART_FST_SND];
14746 MATCH_MP_TAC OPEN_INTER THEN ASM_REWRITE_TAC[] THEN
14747 MATCH_MP_TAC(REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM]
14748 OPEN_SURJECTIVE_LINEAR_IMAGE) THEN
14749 ASM_REWRITE_TAC[LINEAR_SNDCART] THEN MESON_TAC[SNDCART_PASTECART]]);;
14751 (* ------------------------------------------------------------------------- *)
14752 (* Even more special cases. *)
14753 (* ------------------------------------------------------------------------- *)
14755 let INTERIOR_NEGATIONS = prove
14756 (`!s. interior(IMAGE (--) s) = IMAGE (--) (interior s)`,
14757 GEN_TAC THEN MATCH_MP_TAC INTERIOR_INJECTIVE_LINEAR_IMAGE THEN
14758 REWRITE_TAC[linear] THEN REPEAT CONJ_TAC THEN VECTOR_ARITH_TAC);;
14760 let SYMMETRIC_INTERIOR = prove
14762 (!x. x IN s ==> --x IN s)
14763 ==> !x. x IN interior s ==> (--x) IN interior s`,
14764 REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
14765 DISCH_THEN(MP_TAC o MATCH_MP(ISPEC `(--):real^N->real^N` FUN_IN_IMAGE)) THEN
14766 REWRITE_TAC[GSYM INTERIOR_NEGATIONS] THEN
14767 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
14768 REWRITE_TAC[EXTENSION; IN_IMAGE] THEN ASM_MESON_TAC[VECTOR_NEG_NEG]);;
14770 let CLOSURE_NEGATIONS = prove
14771 (`!s. closure(IMAGE (--) s) = IMAGE (--) (closure s)`,
14772 GEN_TAC THEN MATCH_MP_TAC CLOSURE_INJECTIVE_LINEAR_IMAGE THEN
14773 REWRITE_TAC[linear] THEN REPEAT CONJ_TAC THEN VECTOR_ARITH_TAC);;
14775 let SYMMETRIC_CLOSURE = prove
14777 (!x. x IN s ==> --x IN s)
14778 ==> !x. x IN closure s ==> (--x) IN closure s`,
14779 REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
14780 DISCH_THEN(MP_TAC o MATCH_MP(ISPEC `(--):real^N->real^N` FUN_IN_IMAGE)) THEN
14781 REWRITE_TAC[GSYM CLOSURE_NEGATIONS] THEN
14782 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
14783 REWRITE_TAC[EXTENSION; IN_IMAGE] THEN ASM_MESON_TAC[VECTOR_NEG_NEG]);;
14785 (* ------------------------------------------------------------------------- *)
14786 (* Some properties of a canonical subspace. *)
14787 (* ------------------------------------------------------------------------- *)
14789 let SUBSPACE_SUBSTANDARD = prove
14791 {x:real^N | !i. d < i /\ i <= dimindex(:N) ==> x$i = &0}`,
14792 GEN_TAC THEN ASM_CASES_TAC `d <= dimindex(:N)` THENL
14793 [MP_TAC(ARITH_RULE `!i. d < i ==> 1 <= i`) THEN
14794 SIMP_TAC[subspace; IN_ELIM_THM; REAL_MUL_RZERO; REAL_ADD_LID;
14795 VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT];
14796 ASM_SIMP_TAC[ARITH_RULE `~(d:num <= e) ==> (d < i /\ i <= e <=> F)`] THEN
14797 REWRITE_TAC[SET_RULE `{x | T} = UNIV`; SUBSPACE_UNIV]]);;
14799 let CLOSED_SUBSTANDARD = prove
14801 {x:real^N | !i. d < i /\ i <= dimindex(:N) ==> x$i = &0}`,
14804 `{x:real^N | !i. d < i /\ i <= dimindex(:N) ==> x$i = &0} =
14805 INTERS {{x | basis i dot x = &0} | d < i /\ i <= dimindex(:N)}`
14808 SIMP_TAC[CLOSED_INTERS; CLOSED_HYPERPLANE; IN_ELIM_THM;
14809 LEFT_IMP_EXISTS_THM]] THEN
14810 GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_INTERS; IN_ELIM_THM] THEN
14811 SIMP_TAC[LEFT_IMP_EXISTS_THM; IN_ELIM_THM] THEN
14812 MP_TAC(ARITH_RULE `!i. d < i ==> 1 <= i`) THEN
14813 SIMP_TAC[DOT_BASIS] THEN MESON_TAC[]);;
14815 let DIM_SUBSTANDARD = prove
14816 (`!d. d <= dimindex(:N)
14817 ==> (dim {x:real^N | !i. d < i /\ i <= dimindex(:N)
14820 REPEAT STRIP_TAC THEN MATCH_MP_TAC DIM_UNIQUE THEN
14821 EXISTS_TAC `IMAGE (basis:num->real^N) (1..d)` THEN REPEAT CONJ_TAC THENL
14822 [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM; IN_NUMSEG] THEN
14823 MESON_TAC[BASIS_COMPONENT; ARITH_RULE `d < i ==> 1 <= i`; NOT_LT];
14825 MATCH_MP_TAC INDEPENDENT_MONO THEN
14826 EXISTS_TAC `{basis i :real^N | 1 <= i /\ i <= dimindex(:N)}` THEN
14827 REWRITE_TAC[INDEPENDENT_STDBASIS]THEN
14828 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM; IN_NUMSEG] THEN
14829 ASM_MESON_TAC[LE_TRANS];
14830 MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN REWRITE_TAC[HAS_SIZE_NUMSEG_1] THEN
14831 REWRITE_TAC[IN_NUMSEG] THEN ASM_MESON_TAC[LE_TRANS; BASIS_INJ]] THEN
14832 POP_ASSUM MP_TAC THEN SPEC_TAC(`d:num`,`d:num`) THEN
14834 [REWRITE_TAC[ARITH_RULE `0 < i <=> 1 <= i`; SPAN_STDBASIS] THEN
14835 SUBGOAL_THEN `IMAGE basis (1 .. 0) :real^N->bool = {}` SUBST1_TAC THENL
14836 [REWRITE_TAC[IMAGE_EQ_EMPTY; NUMSEG_EMPTY; ARITH]; ALL_TAC] THEN
14837 DISCH_TAC THEN REWRITE_TAC[SPAN_EMPTY; SUBSET; IN_ELIM_THM; IN_SING] THEN
14838 SIMP_TAC[CART_EQ; VEC_COMPONENT];
14840 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN
14841 ASM_SIMP_TAC[ARITH_RULE `SUC d <= n ==> d <= n`] THEN
14842 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN DISCH_TAC THEN
14843 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
14844 FIRST_X_ASSUM(MP_TAC o SPEC `x - (x$(SUC d)) % basis(SUC d) :real^N`) THEN
14846 [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
14847 FIRST_ASSUM(ASSUME_TAC o MATCH_MP(ARITH_RULE `d < i ==> 1 <= i`)) THEN
14848 ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT] THEN
14849 ASM_SIMP_TAC[BASIS_COMPONENT] THEN COND_CASES_TAC THEN
14850 ASM_REWRITE_TAC[REAL_MUL_RID; REAL_SUB_REFL] THEN
14851 ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_SUB_RZERO] THEN
14852 ASM_MESON_TAC[ARITH_RULE `d < i /\ ~(i = SUC d) ==> SUC d < i`];
14855 SUBST1_TAC(VECTOR_ARITH
14856 `x = (x - (x$(SUC d)) % basis(SUC d)) +
14857 x$(SUC d) % basis(SUC d) :real^N`) THEN
14858 MATCH_MP_TAC SPAN_ADD THEN CONJ_TAC THENL
14859 [ASM_MESON_TAC[SPAN_MONO; SUBSET_IMAGE; SUBSET; SUBSET_NUMSEG; LE_REFL; LE];
14860 MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC SPAN_SUPERSET THEN
14861 REWRITE_TAC[IN_IMAGE; IN_NUMSEG] THEN
14862 MESON_TAC[LE_REFL; ARITH_RULE `1 <= SUC d`]]);;
14864 (* ------------------------------------------------------------------------- *)
14865 (* Hence closure and completeness of all subspaces. *)
14866 (* ------------------------------------------------------------------------- *)
14868 let CLOSED_SUBSPACE = prove
14869 (`!s:real^N->bool. subspace s ==> closed s`,
14870 REPEAT STRIP_TAC THEN ABBREV_TAC `d = dim(s:real^N->bool)` THEN
14871 MP_TAC(MATCH_MP DIM_SUBSTANDARD
14872 (ISPEC `s:real^N->bool` DIM_SUBSET_UNIV)) THEN
14873 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
14875 [`{x:real^N | !i. d < i /\ i <= dimindex(:N)
14877 `s:real^N->bool`] SUBSPACE_ISOMORPHISM) THEN
14878 ASM_REWRITE_TAC[SUBSPACE_SUBSTANDARD] THEN
14879 DISCH_THEN(X_CHOOSE_THEN `f:real^N->real^N` MP_TAC) THEN
14880 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
14881 DISCH_THEN(CONJUNCTS_THEN2 (SUBST_ALL_TAC o SYM) STRIP_ASSUME_TAC) THEN
14882 MATCH_MP_TAC(ISPEC `f:real^N->real^N` CLOSED_INJECTIVE_IMAGE_SUBSPACE) THEN
14883 ASM_REWRITE_TAC[SUBSPACE_SUBSTANDARD; CLOSED_SUBSTANDARD] THEN
14884 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
14885 ASM_REWRITE_TAC[] THEN
14886 CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LINEAR_0]] THEN
14887 REWRITE_TAC[IN_ELIM_THM] THEN
14888 ASM_MESON_TAC[VEC_COMPONENT; ARITH_RULE `d < i ==> 1 <= i`]);;
14890 let COMPLETE_SUBSPACE = prove
14891 (`!s:real^N->bool. subspace s ==> complete s`,
14892 REWRITE_TAC[COMPLETE_EQ_CLOSED; CLOSED_SUBSPACE]);;
14894 let CLOSED_SPAN = prove
14895 (`!s. closed(span s)`,
14896 SIMP_TAC[CLOSED_SUBSPACE; SUBSPACE_SPAN]);;
14898 let DIM_CLOSURE = prove
14899 (`!s:real^N->bool. dim(closure s) = dim s`,
14900 GEN_TAC THEN REWRITE_TAC[GSYM LE_ANTISYM] THEN CONJ_TAC THENL
14901 [GEN_REWRITE_TAC RAND_CONV [GSYM DIM_SPAN]; ALL_TAC] THEN
14902 MATCH_MP_TAC DIM_SUBSET THEN REWRITE_TAC[CLOSURE_SUBSET] THEN
14903 MATCH_MP_TAC CLOSURE_MINIMAL THEN
14904 SIMP_TAC[CLOSED_SUBSPACE; SUBSPACE_SPAN; SPAN_INC]);;
14906 let CLOSED_BOUNDEDPREIM_CONTINUOUS_IMAGE = prove
14907 (`!f:real^M->real^N s.
14908 closed s /\ f continuous_on s /\
14909 (!e. bounded {x | x IN s /\ norm(f x) <= e})
14910 ==> closed(IMAGE f s)`,
14911 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_INTERS_COMPACT] THEN
14912 REWRITE_TAC[SET_RULE
14913 `cball(vec 0,e) INTER IMAGE (f:real^M->real^N) s =
14914 IMAGE f (s INTER {x | x IN s /\ f x IN cball(vec 0,e)})`] THEN
14915 X_GEN_TAC `e:real` THEN MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
14917 [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:real^M->bool` THEN
14918 ASM_REWRITE_TAC[] THEN SET_TAC[];
14919 MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN
14920 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN CONJ_TAC THENL
14921 [ASM_REWRITE_TAC[IN_CBALL_0];
14922 ASM_SIMP_TAC[CONTINUOUS_CLOSED_PREIMAGE; CLOSED_CBALL]]]);;
14924 let CLOSED_INJECTIVE_IMAGE_SUBSET_SUBSPACE = prove
14925 (`!f:real^M->real^N s t.
14926 closed s /\ s SUBSET t /\ subspace t /\
14928 (!x. x IN t /\ f(x) = vec 0 ==> x = vec 0)
14929 ==> closed(IMAGE f s)`,
14930 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSED_BOUNDEDPREIM_CONTINUOUS_IMAGE THEN
14931 ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN
14932 MP_TAC(ISPECL [`f:real^M->real^N`; `t:real^M->bool`]
14933 INJECTIVE_IMP_ISOMETRIC) THEN
14934 ASM_SIMP_TAC[CLOSED_SUBSPACE; real_ge] THEN
14935 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
14936 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
14937 X_GEN_TAC `e:real` THEN MATCH_MP_TAC BOUNDED_SUBSET THEN
14938 EXISTS_TAC `cball(vec 0:real^M,e / B)` THEN
14939 REWRITE_TAC[BOUNDED_CBALL] THEN
14940 ASM_SIMP_TAC[SUBSET; IN_ELIM_THM; IN_CBALL_0; REAL_LE_RDIV_EQ] THEN
14941 ASM_MESON_TAC[SUBSET; REAL_LE_TRANS]);;
14943 let BASIS_COORDINATES_LIPSCHITZ = prove
14948 ==> abs(c v) <= B * norm(vsum b (\v. c(v) % v))`,
14949 X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
14950 FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP INDEPENDENT_BOUND) THEN
14951 FIRST_ASSUM(X_CHOOSE_THEN `b:num->real^N` STRIP_ASSUME_TAC o
14952 GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN
14953 ABBREV_TAC `n = CARD(k:real^N->bool)` THEN
14955 [`(\x. vsum(1..n) (\i. x$i % b i)):real^N->real^N`;
14956 `span(IMAGE basis (1..n)):real^N->bool`]
14957 INJECTIVE_IMP_ISOMETRIC) THEN
14958 REWRITE_TAC[SUBSPACE_SPAN] THEN ANTS_TAC THENL
14959 [CONJ_TAC THENL [SIMP_TAC[CLOSED_SUBSPACE; SUBSPACE_SPAN]; ALL_TAC] THEN
14961 [MATCH_MP_TAC LINEAR_COMPOSE_VSUM THEN
14962 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN REPEAT STRIP_TAC THEN
14963 MATCH_MP_TAC LINEAR_VMUL_COMPONENT THEN
14964 SIMP_TAC[LINEAR_ID] THEN ASM_ARITH_TAC;
14966 X_GEN_TAC `x:real^N` THEN
14967 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
14968 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SPAN_IMAGE_BASIS]) THEN
14969 REWRITE_TAC[IN_NUMSEG] THEN DISCH_TAC THEN
14970 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN
14971 DISCH_THEN(X_CHOOSE_TAC `c:real^N->num`) THEN
14973 `vsum(1..n) (\i. (x:real^N)$i % b i:real^N) = vsum k (\v. x$(c v) % v)`
14975 [MATCH_MP_TAC VSUM_EQ_GENERAL_INVERSES THEN
14976 MAP_EVERY EXISTS_TAC [`b:num->real^N`; `c:real^N->num`] THEN
14980 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INDEPENDENT_EXPLICIT]) THEN
14981 DISCH_THEN(MP_TAC o SPEC `\v:real^N. (x:real^N)$(c v)` o CONJUNCT2) THEN
14982 ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
14983 REWRITE_TAC[CART_EQ; FORALL_IN_IMAGE; VEC_COMPONENT] THEN
14984 ASM_MESON_TAC[IN_NUMSEG];
14986 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
14987 EXISTS_TAC `inv(B:real)` THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN
14988 ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_NUMSEG] THEN
14989 MAP_EVERY X_GEN_TAC [`c:real^N->real`; `j:num`] THEN STRIP_TAC THEN
14990 ONCE_REWRITE_TAC[REAL_ARITH `inv B * x = x / B`] THEN
14991 ASM_SIMP_TAC[REAL_LE_RDIV_EQ] THEN
14992 W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o rand o rand o snd) THEN
14993 ASM_REWRITE_TAC[FINITE_NUMSEG] THEN DISCH_THEN SUBST1_TAC THEN
14994 FIRST_X_ASSUM(MP_TAC o SPEC
14995 `(lambda i. if 1 <= i /\ i <= n then c(b i:real^N) else &0):real^N`) THEN
14996 SIMP_TAC[IN_SPAN_IMAGE_BASIS; LAMBDA_BETA] THEN
14997 ANTS_TAC THENL [MESON_TAC[IN_NUMSEG]; ALL_TAC] THEN
14998 MATCH_MP_TAC(REAL_ARITH `x = v /\ u <= y ==> x >= y ==> u <= v`) THEN
15000 [AP_TERM_TAC THEN MATCH_MP_TAC VSUM_EQ_NUMSEG THEN
15001 SUBGOAL_THEN `!i. i <= n ==> i <= dimindex(:N)` MP_TAC THENL
15002 [ASM_ARITH_TAC; SIMP_TAC[LAMBDA_BETA] THEN DISCH_THEN(K ALL_TAC)] THEN
15003 REWRITE_TAC[o_THM];
15004 GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN
15005 ASM_SIMP_TAC[REAL_LE_RMUL_EQ] THEN
15007 [`(lambda i. if 1 <= i /\ i <= n then c(b i:real^N) else &0):real^N`;
15008 `j:num`] COMPONENT_LE_NORM) THEN
15009 SUBGOAL_THEN `1 <= j /\ j <= dimindex(:N)` MP_TAC THENL
15010 [ASM_ARITH_TAC; SIMP_TAC[LAMBDA_BETA] THEN ASM_REWRITE_TAC[]]]);;
15012 let BASIS_COORDINATES_CONTINUOUS = prove
15013 (`!b:real^N->bool e.
15014 independent b /\ &0 < e
15016 !c. norm(vsum b (\v. c(v) % v)) < d
15017 ==> !v. v IN b ==> abs(c v) < e`,
15018 REPEAT STRIP_TAC THEN
15019 FIRST_X_ASSUM(MP_TAC o MATCH_MP BASIS_COORDINATES_LIPSCHITZ) THEN
15020 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
15021 EXISTS_TAC `e / B:real` THEN ASM_SIMP_TAC[REAL_LT_DIV] THEN
15022 X_GEN_TAC `c:real^N->real` THEN DISCH_TAC THEN
15023 X_GEN_TAC `v:real^N` THEN DISCH_TAC THEN
15024 MATCH_MP_TAC REAL_LET_TRANS THEN
15025 EXISTS_TAC `B * norm(vsum b (\v:real^N. c v % v))` THEN
15026 ASM_SIMP_TAC[] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
15027 ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ]);;
15029 (* ------------------------------------------------------------------------- *)
15030 (* Affine transformations of intervals. *)
15031 (* ------------------------------------------------------------------------- *)
15033 let AFFINITY_INVERSES = prove
15035 ==> (\x. m % x + c) o (\x. inv(m) % x + (--(inv(m) % c))) = I /\
15036 (\x. inv(m) % x + (--(inv(m) % c))) o (\x. m % x + c) = I`,
15037 REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN
15038 REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_RNEG] THEN
15039 SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_RINV] THEN
15040 REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
15042 let REAL_AFFINITY_LE = prove
15043 (`!m c x y. &0 < m ==> (m * x + c <= y <=> x <= inv(m) * y + --(c / m))`,
15044 REWRITE_TAC[REAL_ARITH `m * x + c <= y <=> x * m <= y - c`] THEN
15045 SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN REAL_ARITH_TAC);;
15047 let REAL_LE_AFFINITY = prove
15048 (`!m c x y. &0 < m ==> (y <= m * x + c <=> inv(m) * y + --(c / m) <= x)`,
15049 REWRITE_TAC[REAL_ARITH `y <= m * x + c <=> y - c <= x * m`] THEN
15050 SIMP_TAC[GSYM REAL_LE_LDIV_EQ] THEN REAL_ARITH_TAC);;
15052 let REAL_AFFINITY_LT = prove
15053 (`!m c x y. &0 < m ==> (m * x + c < y <=> x < inv(m) * y + --(c / m))`,
15054 SIMP_TAC[REAL_LE_AFFINITY; GSYM REAL_NOT_LE]);;
15056 let REAL_LT_AFFINITY = prove
15057 (`!m c x y. &0 < m ==> (y < m * x + c <=> inv(m) * y + --(c / m) < x)`,
15058 SIMP_TAC[REAL_AFFINITY_LE; GSYM REAL_NOT_LE]);;
15060 let REAL_AFFINITY_EQ = prove
15061 (`!m c x y. ~(m = &0) ==> (m * x + c = y <=> x = inv(m) * y + --(c / m))`,
15062 CONV_TAC REAL_FIELD);;
15064 let REAL_EQ_AFFINITY = prove
15065 (`!m c x y. ~(m = &0) ==> (y = m * x + c <=> inv(m) * y + --(c / m) = x)`,
15066 CONV_TAC REAL_FIELD);;
15068 let VECTOR_AFFINITY_EQ = prove
15069 (`!m c x y. ~(m = &0)
15070 ==> (m % x + c = y <=> x = inv(m) % y + --(inv(m) % c))`,
15071 SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
15072 real_div; VECTOR_NEG_COMPONENT; REAL_AFFINITY_EQ] THEN
15073 REWRITE_TAC[REAL_MUL_AC]);;
15075 let VECTOR_EQ_AFFINITY = prove
15076 (`!m c x y. ~(m = &0)
15077 ==> (y = m % x + c <=> inv(m) % y + --(inv(m) % c) = x)`,
15078 SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
15079 real_div; VECTOR_NEG_COMPONENT; REAL_EQ_AFFINITY] THEN
15080 REWRITE_TAC[REAL_MUL_AC]);;
15082 let IMAGE_AFFINITY_INTERVAL = prove
15084 IMAGE (\x. m % x + c) (interval[a,b]) =
15085 if interval[a,b] = {} then {}
15086 else if &0 <= m then interval[m % a + c,m % b + c]
15087 else interval[m % b + c,m % a + c]`,
15088 REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[IMAGE_CLAUSES] THEN
15089 ASM_CASES_TAC `m = &0` THEN ASM_REWRITE_TAC[REAL_LE_LT] THENL
15090 [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID; COND_ID] THEN
15091 REWRITE_TAC[INTERVAL_SING] THEN ASM SET_TAC[];
15093 FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH
15094 `~(x = &0) ==> &0 < x \/ &0 < --x`)) THEN
15095 ASM_SIMP_TAC[EXTENSION; IN_IMAGE; REAL_ARITH `&0 < --x ==> ~(&0 < x)`] THENL
15097 ONCE_REWRITE_TAC[VECTOR_ARITH `x = m % y + c <=> c = (--m) % y + x`]] THEN
15098 ASM_SIMP_TAC[VECTOR_EQ_AFFINITY; REAL_LT_IMP_NZ; UNWIND_THM1] THEN
15099 SIMP_TAC[IN_INTERVAL; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
15100 VECTOR_NEG_COMPONENT] THEN
15101 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_LT_INV_EQ]) THEN
15102 SIMP_TAC[REAL_AFFINITY_LE; REAL_LE_AFFINITY; real_div] THEN
15103 DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[REAL_INV_INV] THEN
15104 REWRITE_TAC[REAL_MUL_LNEG; REAL_NEGNEG] THEN
15105 ASM_SIMP_TAC[REAL_FIELD `&0 < m ==> (inv m * x) * m = x`] THEN
15106 GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN AP_TERM_TAC THEN REAL_ARITH_TAC);;
15108 (* ------------------------------------------------------------------------- *)
15109 (* Existence of eigenvectors. The proof is only in this file because it uses *)
15110 (* a few simple results about continuous functions (at least *)
15111 (* CONTINUOUS_ON_LIFT_DOT2, CONTINUOUS_ATTAINS_SUP and CLOSED_SUBSPACE). *)
15112 (* ------------------------------------------------------------------------- *)
15114 let SELF_ADJOINT_HAS_EIGENVECTOR_IN_SUBSPACE = prove
15115 (`!f:real^N->real^N s.
15116 linear f /\ adjoint f = f /\
15117 subspace s /\ ~(s = {vec 0}) /\ (!x. x IN s ==> f x IN s)
15118 ==> ?v c. v IN s /\ norm(v) = &1 /\ f(v) = c % v`,
15120 (`!a b. (!x. a * x <= b * x pow 2) ==> &0 <= b ==> a = &0`,
15121 REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[REAL_LE_LT] THEN
15122 ASM_CASES_TAC `b = &0` THEN ASM_REWRITE_TAC[] THENL
15123 [FIRST_X_ASSUM(fun t -> MP_TAC(SPEC `&1` t) THEN
15124 MP_TAC(SPEC `-- &1` t)) THEN ASM_REAL_ARITH_TAC;
15125 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `a / &2 / b`) THEN
15126 ASM_SIMP_TAC[REAL_FIELD
15127 `&0 < b ==> (b * (a / b) pow 2) = a pow 2 / b`] THEN
15128 REWRITE_TAC[real_div; REAL_MUL_ASSOC] THEN SIMP_TAC[GSYM real_div] THEN
15129 ASM_SIMP_TAC[REAL_LE_DIV2_EQ] THEN
15130 REWRITE_TAC[REAL_LT_SQUARE; REAL_ARITH
15131 `(a * a) / &2 <= (a / &2) pow 2 <=> ~(&0 < a * a)`]]) in
15132 REPEAT STRIP_TAC THEN
15133 MP_TAC(ISPECL [`\x:real^N. (f x) dot x`;
15134 `s INTER sphere(vec 0:real^N,&1)`]
15135 CONTINUOUS_ATTAINS_SUP) THEN
15136 REWRITE_TAC[EXISTS_IN_GSPEC; FORALL_IN_GSPEC; o_DEF] THEN ANTS_TAC THENL
15137 [ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_DOT2; LINEAR_CONTINUOUS_ON;
15138 CONTINUOUS_ON_ID] THEN
15139 ASM_SIMP_TAC[COMPACT_SPHERE; CLOSED_INTER_COMPACT; CLOSED_SUBSPACE] THEN
15140 FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE
15141 `~(s = {a}) ==> a IN s ==> ?b. ~(b = a) /\ b IN s`)) THEN
15142 ASM_SIMP_TAC[SUBSPACE_0; IN_SPHERE_0; GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN
15143 DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN
15144 EXISTS_TAC `inv(norm x) % x:real^N` THEN
15145 ASM_REWRITE_TAC[IN_ELIM_THM; VECTOR_SUB_RZERO; NORM_MUL] THEN
15146 ASM_SIMP_TAC[SUBSPACE_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN
15147 ASM_SIMP_TAC[REAL_MUL_LINV; NORM_EQ_0];
15148 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `v:real^N` THEN
15149 REWRITE_TAC[IN_INTER; IN_SPHERE_0] THEN STRIP_TAC THEN
15150 ABBREV_TAC `c = (f:real^N->real^N) v dot v` THEN
15151 EXISTS_TAC `c:real` THEN ASM_REWRITE_TAC[]] THEN
15152 ABBREV_TAC `p = \x y:real^N. c * (x dot y) - (f x) dot y` THEN
15153 SUBGOAL_THEN `!x:real^N. x IN s ==> &0 <= p x x` (LABEL_TAC "POSDEF") THENL
15154 [X_GEN_TAC `x:real^N` THEN EXPAND_TAC "p" THEN REWRITE_TAC[] THEN
15155 ASM_CASES_TAC `x:real^N = vec 0` THEN DISCH_TAC THEN
15156 ASM_REWRITE_TAC[DOT_RZERO; REAL_MUL_RZERO; REAL_SUB_LE; REAL_LE_REFL] THEN
15157 FIRST_X_ASSUM(MP_TAC o SPEC `inv(norm x) % x:real^N`) THEN
15158 ASM_SIMP_TAC[SUBSPACE_MUL] THEN
15159 ASM_SIMP_TAC[LINEAR_CMUL; NORM_MUL; REAL_ABS_INV; DOT_RMUL] THEN
15160 ASM_SIMP_TAC[REAL_ABS_NORM; REAL_MUL_LINV; NORM_EQ_0; DOT_LMUL] THEN
15161 ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; DOT_POS_LT] THEN
15162 REWRITE_TAC[GSYM NORM_POW_2; real_div; REAL_INV_POW] THEN REAL_ARITH_TAC;
15164 SUBGOAL_THEN `!y:real^N. y IN s ==> !a. p v y * a <= p y y * a pow 2`
15166 [REPEAT STRIP_TAC THEN
15167 REMOVE_THEN "POSDEF" (MP_TAC o SPEC `v - (&2 * a) % y:real^N`) THEN
15168 EXPAND_TAC "p" THEN ASM_SIMP_TAC[SUBSPACE_SUB; SUBSPACE_MUL] THEN
15169 ASM_SIMP_TAC[LINEAR_SUB; LINEAR_CMUL] THEN
15170 REWRITE_TAC[DOT_LSUB; DOT_LMUL] THEN
15171 REWRITE_TAC[DOT_RSUB; DOT_RMUL] THEN
15172 SUBGOAL_THEN `f y dot (v:real^N) = f v dot y` SUBST1_TAC THENL
15173 [ASM_MESON_TAC[ADJOINT_CLAUSES; DOT_SYM]; ALL_TAC] THEN
15174 ASM_REWRITE_TAC[GSYM NORM_POW_2] THEN REWRITE_TAC[NORM_POW_2] THEN
15175 MATCH_MP_TAC(REAL_ARITH
15176 `&4 * (z - y) = x ==> &0 <= x ==> y <= z`) THEN
15177 REWRITE_TAC[DOT_SYM] THEN CONV_TAC REAL_RING;
15178 DISCH_THEN(MP_TAC o GEN `y:real^N` o DISCH `(y:real^N) IN s` o
15179 MATCH_MP lemma o C MP (ASSUME `(y:real^N) IN s`) o SPEC `y:real^N`) THEN
15180 ASM_SIMP_TAC[] THEN EXPAND_TAC "p" THEN
15181 REWRITE_TAC[GSYM DOT_LMUL; GSYM DOT_LSUB] THEN
15182 DISCH_THEN(MP_TAC o SPEC `c % v - f v:real^N`) THEN
15183 ASM_SIMP_TAC[SUBSPACE_MUL; SUBSPACE_SUB; DOT_EQ_0; VECTOR_SUB_EQ]]);;
15185 let SELF_ADJOINT_HAS_EIGENVECTOR = prove
15186 (`!f:real^N->real^N.
15187 linear f /\ adjoint f = f ==> ?v c. norm(v) = &1 /\ f(v) = c % v`,
15188 REPEAT STRIP_TAC THEN
15189 MP_TAC(ISPECL [`f:real^N->real^N`; `(:real^N)`]
15190 SELF_ADJOINT_HAS_EIGENVECTOR_IN_SUBSPACE) THEN
15191 ASM_REWRITE_TAC[SUBSPACE_UNIV; IN_UNIV] THEN DISCH_THEN MATCH_MP_TAC THEN
15192 MATCH_MP_TAC(SET_RULE `!a. ~(a IN s) ==> ~(UNIV = s)`) THEN
15193 EXISTS_TAC `vec 1:real^N` THEN
15194 REWRITE_TAC[IN_SING; VEC_EQ; ARITH_EQ]);;
15196 let SELF_ADJOINT_HAS_EIGENVECTOR_BASIS_OF_SUBSPACE = prove
15197 (`!f:real^N->real^N s.
15198 linear f /\ adjoint f = f /\
15199 subspace s /\ (!x. x IN s ==> f x IN s)
15200 ==> ?b. b SUBSET s /\
15201 pairwise orthogonal b /\
15202 (!x. x IN b ==> norm x = &1 /\ ?c. f(x) = c % x) /\
15207 (`!f:real^N->real^N s.
15208 linear f /\ adjoint f = f /\ subspace s /\ (!x. x IN s ==> f x IN s)
15209 ==> ?b. b SUBSET s /\ b HAS_SIZE dim s /\
15210 pairwise orthogonal b /\
15211 (!x. x IN b ==> norm x = &1 /\ ?c. f(x) = c % x)`,
15212 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN REWRITE_TAC[IMP_IMP] THEN
15213 GEN_TAC THEN STRIP_TAC THEN GEN_TAC THEN
15214 WF_INDUCT_TAC `dim(s:real^N->bool)` THEN STRIP_TAC THEN
15215 ASM_CASES_TAC `dim(s:real^N->bool) = 0` THENL
15216 [EXISTS_TAC `{}:real^N->bool` THEN
15217 ASM_SIMP_TAC[HAS_SIZE_CLAUSES; NOT_IN_EMPTY;
15218 PAIRWISE_EMPTY; EMPTY_SUBSET];
15220 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [DIM_EQ_0]) THEN
15221 DISCH_THEN(ASSUME_TAC o MATCH_MP (SET_RULE
15222 `~(s SUBSET {a}) ==> ~(s = {a})`)) THEN
15223 MP_TAC(ISPECL [`f:real^N->real^N`; `s:real^N->bool`]
15224 SELF_ADJOINT_HAS_EIGENVECTOR_IN_SUBSPACE) THEN
15225 ASM_REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN
15226 DISCH_THEN(X_CHOOSE_THEN `v:real^N` MP_TAC) THEN
15227 ASM_CASES_TAC `v:real^N = vec 0` THEN ASM_REWRITE_TAC[NORM_0] THEN
15228 CONV_TAC REAL_RAT_REDUCE_CONV THEN
15229 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
15230 FIRST_X_ASSUM(MP_TAC o SPEC `{y:real^N | y IN s /\ orthogonal v y}`) THEN
15231 REWRITE_TAC[SUBSPACE_ORTHOGONAL_TO_VECTOR; IN_ELIM_THM] THEN
15232 MP_TAC(ISPECL [`span {v:real^N}`; `s:real^N->bool`]
15233 DIM_SUBSPACE_ORTHOGONAL_TO_VECTORS) THEN
15234 REWRITE_TAC[ONCE_REWRITE_RULE[ORTHOGONAL_SYM] ORTHOGONAL_TO_SPAN_EQ] THEN
15235 ASM_REWRITE_TAC[SUBSPACE_SPAN; IN_SING; FORALL_UNWIND_THM2] THEN
15237 [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN ASM SET_TAC[];
15238 DISCH_THEN(SUBST1_TAC o SYM)] THEN
15239 ASM_REWRITE_TAC[DIM_SPAN; DIM_SING; ARITH_RULE `n < n + 1`] THEN
15241 [REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
15242 ASM_SIMP_TAC[SUBSPACE_INTER; SUBSPACE_ORTHOGONAL_TO_VECTOR] THEN
15243 REWRITE_TAC[orthogonal] THEN X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN
15244 MATCH_MP_TAC EQ_TRANS THEN
15245 EXISTS_TAC `(f:real^N->real^N) v dot x` THEN CONJ_TAC THENL
15246 [ASM_MESON_TAC[ADJOINT_CLAUSES];
15247 ASM_MESON_TAC[DOT_LMUL; REAL_MUL_RZERO]];
15248 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
15249 EXISTS_TAC `(v:real^N) INSERT b` THEN
15250 ASM_REWRITE_TAC[FORALL_IN_INSERT] THEN
15251 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
15252 ASM_REWRITE_TAC[PAIRWISE_INSERT] THEN
15253 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE; SUBSET; IN_ELIM_THM]) THEN
15255 [ASM_SIMP_TAC[HAS_SIZE; FINITE_INSERT; CARD_CLAUSES] THEN
15256 COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD1] THEN
15257 ASM_MESON_TAC[ORTHOGONAL_REFL];
15258 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_ELIM_THM]) THEN
15259 ASM_MESON_TAC[ORTHOGONAL_SYM]]]) in
15260 REPEAT STRIP_TAC THEN
15261 MP_TAC(ISPECL [`f:real^N->real^N`; `s:real^N->bool`] lemma) THEN
15262 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN
15263 X_GEN_TAC `b:real^N->bool` THEN
15264 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
15265 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
15266 [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN
15267 ASM_MESON_TAC[NORM_ARITH `~(norm(vec 0:real^N) = &1)`];
15268 DISCH_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
15269 [ASM_MESON_TAC[SPAN_SUBSET_SUBSPACE];
15270 MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN
15271 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN
15272 ASM_REWRITE_TAC[LE_REFL]]]);;
15274 let SELF_ADJOINT_HAS_EIGENVECTOR_BASIS = prove
15275 (`!f:real^N->real^N.
15276 linear f /\ adjoint f = f
15277 ==> ?b. pairwise orthogonal b /\
15278 (!x. x IN b ==> norm x = &1 /\ ?c. f(x) = c % x) /\
15280 span b = (:real^N) /\
15281 b HAS_SIZE (dimindex(:N))`,
15282 REPEAT STRIP_TAC THEN
15283 MP_TAC(ISPECL [`f:real^N->real^N`; `(:real^N)`]
15284 SELF_ADJOINT_HAS_EIGENVECTOR_BASIS_OF_SUBSPACE) THEN
15285 ASM_REWRITE_TAC[SUBSPACE_UNIV; IN_UNIV; DIM_UNIV; SUBSET_UNIV]);;
15287 (* ------------------------------------------------------------------------- *)
15288 (* Diagonalization of symmetric matrix. *)
15289 (* ------------------------------------------------------------------------- *)
15291 let SYMMETRIC_MATRIX_DIAGONALIZABLE_EXPLICIT = prove
15294 ==> ?P d. orthogonal_matrix P /\
15295 transp P ** A ** P = (lambda i j. if i = j then d i else &0)`,
15297 (`!A:real^N^N P:real^N^N d.
15298 A ** P = P ** (lambda i j. if i = j then d i else &0) <=>
15299 !i. 1 <= i /\ i <= dimindex(:N)
15300 ==> A ** column i P = d i % column i P`,
15301 SIMP_TAC[CART_EQ; matrix_mul; matrix_vector_mul; LAMBDA_BETA;
15302 column; VECTOR_MUL_COMPONENT] THEN
15303 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[COND_RAND] THEN
15304 SIMP_TAC[REAL_MUL_RZERO; SUM_DELTA; IN_NUMSEG] THEN
15305 EQ_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC[] THEN
15306 REWRITE_TAC[REAL_MUL_SYM]) in
15308 (`!A:real^N^N P:real^N^N d.
15309 orthogonal_matrix P /\
15310 transp P ** A ** P = (lambda i j. if i = j then d i else &0) <=>
15311 orthogonal_matrix P /\
15312 !i. 1 <= i /\ i <= dimindex(:N)
15313 ==> A ** column i P = d i % column i P`,
15314 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM lemma1; orthogonal_matrix] THEN
15315 ABBREV_TAC `D:real^N^N = lambda i j. if i = j then d i else &0` THEN
15316 MESON_TAC[MATRIX_MUL_ASSOC; MATRIX_MUL_LID]) in
15317 REPEAT STRIP_TAC THEN
15318 REWRITE_TAC[lemma2] THEN REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN
15319 REWRITE_TAC[GSYM SKOLEM_THM] THEN
15320 MP_TAC(ISPEC `\x:real^N. (A:real^N^N) ** x`
15321 SELF_ADJOINT_HAS_EIGENVECTOR_BASIS) THEN
15322 ASM_SIMP_TAC[MATRIX_SELF_ADJOINT; MATRIX_VECTOR_MUL_LINEAR;
15323 MATRIX_OF_MATRIX_VECTOR_MUL] THEN
15324 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` MP_TAC) THEN
15325 REWRITE_TAC[CONJ_ASSOC] THEN ONCE_REWRITE_TAC[IMP_CONJ_ALT] THEN
15326 REWRITE_TAC[HAS_SIZE] THEN STRIP_TAC THEN
15327 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN
15328 ASM_REWRITE_TAC[IN_NUMSEG; TAUT
15329 `p /\ q /\ x = y ==> a = b <=> p /\ q /\ ~(a = b) ==> ~(x = y)`] THEN
15330 DISCH_THEN(X_CHOOSE_THEN `f:num->real^N` STRIP_ASSUME_TAC) THEN
15331 ASM_REWRITE_TAC[PAIRWISE_IMAGE; FORALL_IN_IMAGE] THEN
15332 ASM_SIMP_TAC[pairwise; IN_NUMSEG] THEN STRIP_TAC THEN
15333 EXISTS_TAC `transp(lambda i. f i):real^N^N` THEN
15334 SIMP_TAC[COLUMN_TRANSP; ORTHOGONAL_MATRIX_TRANSP] THEN
15335 SIMP_TAC[ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_INDEXED; row] THEN
15336 SIMP_TAC[LAMBDA_ETA; LAMBDA_BETA; pairwise; IN_NUMSEG] THEN
15339 let SYMMETRIC_MATRIX_IMP_DIAGONALIZABLE = prove
15342 ==> ?P. orthogonal_matrix P /\ diagonal_matrix(transp P ** A ** P)`,
15344 DISCH_THEN(MP_TAC o MATCH_MP SYMMETRIC_MATRIX_DIAGONALIZABLE_EXPLICIT) THEN
15345 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
15346 SIMP_TAC[diagonal_matrix; LAMBDA_BETA]);;
15348 let SYMMETRIC_MATRIX_EQ_DIAGONALIZABLE = prove
15351 ?P. orthogonal_matrix P /\ diagonal_matrix(transp P ** A ** P)`,
15352 GEN_TAC THEN EQ_TAC THEN
15353 REWRITE_TAC[SYMMETRIC_MATRIX_IMP_DIAGONALIZABLE] THEN
15354 REWRITE_TAC[orthogonal_matrix] THEN
15355 DISCH_THEN(X_CHOOSE_THEN `P:real^N^N` STRIP_ASSUME_TAC) THEN
15356 ABBREV_TAC `D:real^N^N = transp P ** (A:real^N^N) ** P` THEN
15357 SUBGOAL_THEN `A:real^N^N = P ** (D:real^N^N) ** transp P` SUBST1_TAC THENL
15358 [EXPAND_TAC "D" THEN REWRITE_TAC[MATRIX_MUL_ASSOC] THEN
15359 ASM_REWRITE_TAC[MATRIX_MUL_LID] THEN
15360 ASM_REWRITE_TAC[GSYM MATRIX_MUL_ASSOC; MATRIX_MUL_RID];
15361 REWRITE_TAC[MATRIX_TRANSP_MUL; TRANSP_TRANSP; MATRIX_MUL_ASSOC] THEN
15362 ASM_MESON_TAC[TRANSP_DIAGONAL_MATRIX]]);;
15364 (* ------------------------------------------------------------------------- *)
15365 (* Some matrix identities are easier to deduce for invertible matrices. We *)
15366 (* can then extend by continuity, which is why this material needs to be *)
15367 (* here after basic topological notions have been defined. *)
15368 (* ------------------------------------------------------------------------- *)
15370 let CONTINUOUS_LIFT_DET = prove
15371 (`!(A:A->real^N^N) net.
15372 (!i j. 1 <= i /\ i <= dimindex(:N) /\
15373 1 <= j /\ j <= dimindex(:N)
15374 ==> (\x. lift(A x$i$j)) continuous net)
15375 ==> (\x. lift(det(A x))) continuous net`,
15376 REPEAT STRIP_TAC THEN REWRITE_TAC[det] THEN
15377 SIMP_TAC[LIFT_SUM; FINITE_PERMUTATIONS; FINITE_NUMSEG; o_DEF] THEN
15378 MATCH_MP_TAC CONTINUOUS_VSUM THEN
15379 SIMP_TAC[FINITE_PERMUTATIONS; FINITE_NUMSEG; LIFT_CMUL; IN_ELIM_THM] THEN
15380 X_GEN_TAC `p:num->num` THEN DISCH_TAC THEN
15381 MATCH_MP_TAC CONTINUOUS_CMUL THEN
15382 MATCH_MP_TAC CONTINUOUS_LIFT_PRODUCT THEN
15383 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
15384 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
15385 FIRST_ASSUM(MP_TAC o MATCH_MP PERMUTES_IMAGE) THEN
15386 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE `s = t ==> s SUBSET t`)) THEN
15387 ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG]);;
15389 let CONTINUOUS_ON_LIFT_DET = prove
15390 (`!A:real^M->real^N^N s.
15391 (!i j. 1 <= i /\ i <= dimindex(:N) /\
15392 1 <= j /\ j <= dimindex(:N)
15393 ==> (\x. lift(A x$i$j)) continuous_on s)
15394 ==> (\x. lift(det(A x))) continuous_on s`,
15395 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_LIFT_DET]);;
15397 let NEARBY_INVERTIBLE_MATRIX = prove
15399 ?e. &0 < e /\ !x. ~(x = &0) /\ abs x < e ==> invertible(A + x %% mat 1)`,
15400 GEN_TAC THEN MP_TAC(ISPEC `A:real^N^N` CHARACTERISTIC_POLYNOMIAL) THEN
15401 DISCH_THEN(X_CHOOSE_THEN `a:num->real` STRIP_ASSUME_TAC) THEN
15402 MP_TAC(ISPECL [`dimindex(:N)`; `a:num->real`] REAL_POLYFUN_FINITE_ROOTS) THEN
15403 MATCH_MP_TAC(TAUT `q /\ (p ==> r) ==> (p <=> q) ==> r`) THEN CONJ_TAC THENL
15404 [EXISTS_TAC `dimindex(:N)` THEN ASM_REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC;
15406 DISCH_THEN(MP_TAC o ISPEC `lift` o MATCH_MP FINITE_IMAGE) THEN
15407 DISCH_THEN(MP_TAC o MATCH_MP LIMIT_POINT_FINITE) THEN
15408 DISCH_THEN(MP_TAC o SPEC `lift(&0)`) THEN
15409 REWRITE_TAC[LIMPT_APPROACHABLE; EXISTS_IN_IMAGE; EXISTS_IN_GSPEC] THEN
15410 REWRITE_TAC[DIST_LIFT; LIFT_EQ; REAL_SUB_RZERO; NOT_FORALL_THM; NOT_IMP] THEN
15411 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN
15412 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN
15413 DISCH_THEN(fun th -> X_GEN_TAC `x:real` THEN STRIP_TAC THEN
15414 MP_TAC(SPEC `--x:real` th)) THEN
15415 FIRST_X_ASSUM(SUBST1_TAC o SYM o SPEC `--x:real`) THEN
15416 ASM_REWRITE_TAC[REAL_NEG_EQ_0; REAL_ABS_NEG] THEN
15417 ONCE_REWRITE_TAC[GSYM INVERTIBLE_NEG] THEN
15418 REWRITE_TAC[INVERTIBLE_DET_NZ; CONTRAPOS_THM] THEN
15419 REWRITE_TAC[MATRIX_SUB; MATRIX_NEG_MINUS1] THEN
15420 ONCE_REWRITE_TAC[REAL_ARITH `--x = -- &1 * x`] THEN
15421 REWRITE_TAC[GSYM MATRIX_CMUL_ADD_LDISTRIB; GSYM MATRIX_CMUL_ASSOC] THEN
15422 REWRITE_TAC[MATRIX_CMUL_LID; MATRIX_ADD_SYM]);;
15424 let MATRIX_WLOG_INVERTIBLE = prove
15425 (`!P. (!A:real^N^N. invertible A ==> P A) /\
15426 (!A:real^N^N. ?d. &0 < d /\
15427 closed {x | x IN cball(vec 0,d) /\
15428 P(A + drop x %% mat 1)})
15429 ==> !A:real^N^N. P A`,
15430 REPEAT GEN_TAC THEN
15431 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
15432 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
15433 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
15434 FIRST_ASSUM(MP_TAC o SPEC `vec 0:real^1` o
15435 GEN_REWRITE_RULE I [CLOSED_LIMPT]) THEN
15436 ASM_SIMP_TAC[IN_ELIM_THM; DROP_VEC; MATRIX_CMUL_LZERO; MATRIX_ADD_RID] THEN
15437 ANTS_TAC THENL [ALL_TAC; CONV_TAC TAUT] THEN
15438 MP_TAC(ISPEC `A:real^N^N` NEARBY_INVERTIBLE_MATRIX) THEN
15439 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
15440 REWRITE_TAC[LIMPT_APPROACHABLE] THEN X_GEN_TAC `k:real` THEN
15441 DISCH_TAC THEN REWRITE_TAC[EXISTS_LIFT; IN_ELIM_THM] THEN
15442 REWRITE_TAC[GSYM LIFT_NUM; IN_CBALL_0; NORM_LIFT; DIST_LIFT] THEN
15443 REWRITE_TAC[REAL_SUB_RZERO; LIFT_EQ; LIFT_DROP] THEN
15444 EXISTS_TAC `min d ((min e k) / &2)` THEN
15445 CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN
15446 CONJ_TAC THENL [ASM_REAL_ARITH_TAC; FIRST_X_ASSUM MATCH_MP_TAC] THEN
15447 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC);;
15449 let SYLVESTER_DETERMINANT_IDENTITY = prove
15450 (`!A:real^N^M B:real^M^N. det(mat 1 + A ** B) = det(mat 1 + B ** A)`,
15452 (`!A:real^N^N B:real^N^N. det(mat 1 + A ** B) = det(mat 1 + B ** A)`,
15453 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN GEN_TAC THEN
15454 MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN CONJ_TAC THENL
15455 [REPEAT STRIP_TAC THEN
15456 SUBGOAL_THEN `det((mat 1 + A ** B) ** A:real^N^N) =
15457 det(A ** (mat 1 + B ** A))`
15459 [REWRITE_TAC[MATRIX_ADD_RDISTRIB; MATRIX_ADD_LDISTRIB] THEN
15460 REWRITE_TAC[MATRIX_MUL_LID; MATRIX_MUL_RID; MATRIX_MUL_ASSOC];
15461 REWRITE_TAC[DET_MUL] THEN
15462 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INVERTIBLE_DET_NZ]) THEN
15463 CONV_TAC REAL_RING];
15464 X_GEN_TAC `A:real^N^N` THEN EXISTS_TAC `&1` THEN
15465 REWRITE_TAC[REAL_LT_01; SET_RULE
15466 `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
15467 MATCH_MP_TAC CLOSED_INTER THEN REWRITE_TAC[CLOSED_CBALL] THEN
15468 ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN
15469 REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN
15470 REWRITE_TAC[SET_RULE `{x | f x = a} = {x | f x IN {a}}`] THEN
15471 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN
15472 REWRITE_TAC[CLOSED_SING; LIFT_SUB] THEN X_GEN_TAC `x:real^1` THEN
15473 REWRITE_TAC[o_DEF; LIFT_SUB] THEN MATCH_MP_TAC CONTINUOUS_SUB THEN
15474 CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN
15475 MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN STRIP_TAC THEN
15476 ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; LIFT_ADD] THEN
15477 MATCH_MP_TAC CONTINUOUS_ADD THEN
15478 ASM_SIMP_TAC[matrix_mul; LAMBDA_BETA; CONTINUOUS_CONST] THEN
15479 SIMP_TAC[LIFT_SUM; FINITE_NUMSEG; o_DEF] THEN
15480 MATCH_MP_TAC CONTINUOUS_VSUM THEN
15481 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN X_GEN_TAC `k:num` THEN
15482 DISCH_TAC THENL [ONCE_REWRITE_TAC[REAL_MUL_SYM]; ALL_TAC] THEN
15483 REWRITE_TAC[LIFT_CMUL] THEN MATCH_MP_TAC CONTINUOUS_CMUL THEN
15484 REWRITE_TAC[MATRIX_ADD_COMPONENT; MATRIX_CMUL_COMPONENT; LIFT_ADD] THEN
15485 MATCH_MP_TAC CONTINUOUS_ADD THEN REWRITE_TAC[CONTINUOUS_CONST] THEN
15486 REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] LIFT_CMUL] THEN
15487 MATCH_MP_TAC CONTINUOUS_CMUL THEN
15488 REWRITE_TAC[LIFT_DROP; CONTINUOUS_AT_ID]]) in
15490 (`!A:real^N^M B:real^M^N.
15491 dimindex(:M) <= dimindex(:N)
15492 ==> det(mat 1 + A ** B) = det(mat 1 + B ** A)`,
15493 REPEAT STRIP_TAC THEN
15494 MAP_EVERY ABBREV_TAC
15496 lambda i j. if i <= dimindex(:M) then (A:real^N^M)$i$j
15499 lambda i j. if j <= dimindex(:M) then (B:real^M^N)$i$j
15501 MP_TAC(ISPECL [`A':real^N^N`; `B':real^N^N`] lemma1) THEN
15503 `(B':real^N^N) ** (A':real^N^N) = (B:real^M^N) ** (A:real^N^M)`
15505 [MAP_EVERY EXPAND_TAC ["A'"; "B'"] THEN
15506 SIMP_TAC[CART_EQ; LAMBDA_BETA; matrix_mul] THEN REPEAT STRIP_TAC THEN
15507 MATCH_MP_TAC SUM_EQ_SUPERSET THEN
15508 ASM_SIMP_TAC[IN_NUMSEG; REAL_MUL_LZERO; FINITE_NUMSEG; SUBSET_NUMSEG;
15509 LE_REFL; TAUT `(p /\ q) /\ ~(p /\ r) <=> p /\ q /\ ~r`];
15510 DISCH_THEN(SUBST1_TAC o SYM)] THEN
15511 REWRITE_TAC[det] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC
15512 `sum {p | p permutes 1..dimindex(:N) /\ !i. dimindex(:M) < i ==> p i = i}
15513 (\p. sign p * product (1..dimindex(:N))
15514 (\i. (mat 1 + (A':real^N^N) ** (B':real^N^N))$i$p i))` THEN
15517 CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_SUPERSET THEN
15518 CONJ_TAC THENL [SET_TAC[]; SIMP_TAC[IN_ELIM_THM; IMP_CONJ]] THEN
15519 X_GEN_TAC `p:num->num` THEN REPEAT STRIP_TAC THEN
15520 REWRITE_TAC[REAL_ENTIRE; PRODUCT_EQ_0_NUMSEG] THEN DISJ2_TAC THEN
15521 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN
15522 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:num` THEN
15523 REWRITE_TAC[NOT_IMP] THEN STRIP_TAC THEN
15524 FIRST_ASSUM(MP_TAC o SPEC `k:num` o CONJUNCT1 o
15525 GEN_REWRITE_RULE I [permutes]) THEN
15526 ASM_REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
15527 FIRST_ASSUM(MP_TAC o MATCH_MP PERMUTES_IMAGE) THEN
15528 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE `s = t ==> s SUBSET t`)) THEN
15529 ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG] THEN
15530 DISCH_THEN(MP_TAC o SPEC `k:num`) THEN ASM_SIMP_TAC[] THEN STRIP_TAC THEN
15531 ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MAT_COMPONENT; REAL_ADD_LID] THEN
15532 ASM_SIMP_TAC[matrix_mul; LAMBDA_BETA] THEN
15533 MATCH_MP_TAC SUM_EQ_0_NUMSEG THEN REPEAT STRIP_TAC THEN
15534 REWRITE_TAC[REAL_ENTIRE] THEN DISJ1_TAC THEN EXPAND_TAC "A'" THEN
15535 ASM_SIMP_TAC[LAMBDA_BETA; GSYM NOT_LT]] THEN
15536 CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_EQ_GENERAL THEN
15537 EXISTS_TAC `\f:num->num. f` THEN REWRITE_TAC[IN_ELIM_THM] THEN
15538 CONJ_TAC THEN X_GEN_TAC `p:num->num` THEN STRIP_TAC THENL
15539 [REWRITE_TAC[MESON[] `(?!x. P x /\ x = y) <=> P y`] THEN CONJ_TAC THENL
15540 [MATCH_MP_TAC PERMUTES_SUBSET THEN
15541 EXISTS_TAC `1..dimindex(:M)` THEN
15542 ASM_REWRITE_TAC[SUBSET_NUMSEG; LE_REFL];
15543 X_GEN_TAC `k:num` THEN DISCH_TAC THEN
15544 FIRST_X_ASSUM(MATCH_MP_TAC o CONJUNCT1 o
15545 GEN_REWRITE_RULE I [permutes]) THEN
15546 ASM_REWRITE_TAC[IN_NUMSEG; DE_MORGAN_THM; NOT_LE]];
15547 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
15548 [MATCH_MP_TAC PERMUTES_SUPERSET THEN
15549 EXISTS_TAC `1..dimindex(:N)` THEN
15550 ASM_REWRITE_TAC[IN_DIFF; IN_NUMSEG] THEN ASM_MESON_TAC[NOT_LE];
15552 AP_TERM_TAC THEN FIRST_ASSUM(SUBST1_TAC o MATCH_MP (ARITH_RULE
15553 `m:num <= n ==> n = m + (n - m)`)) THEN
15554 SIMP_TAC[PRODUCT_ADD_SPLIT; ARITH_RULE `1 <= n + 1`] THEN
15555 MATCH_MP_TAC(REAL_RING `x = y /\ z = &1 ==> x = y * z`) THEN
15557 [MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN
15558 X_GEN_TAC `i:num` THEN STRIP_TAC THEN
15559 SUBGOAL_THEN `i <= dimindex(:N)` ASSUME_TAC THENL
15560 [ASM_ARITH_TAC; ALL_TAC] THEN
15561 MP_TAC(ISPECL [`p:num->num`; `1..dimindex(:M)`] PERMUTES_IMAGE) THEN
15562 ASM_REWRITE_TAC[] THEN
15563 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE `s = t ==> s SUBSET t`)) THEN
15564 ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG] THEN
15565 DISCH_THEN(MP_TAC o SPEC `i:num`) THEN
15566 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
15567 SUBGOAL_THEN `(p:num->num) i <= dimindex(:N)` ASSUME_TAC THENL
15568 [ASM_ARITH_TAC; ALL_TAC] THEN
15569 ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MAT_COMPONENT] THEN
15570 AP_TERM_TAC THEN ASM_SIMP_TAC[matrix_mul; LAMBDA_BETA] THEN
15571 MATCH_MP_TAC SUM_EQ_NUMSEG THEN REPEAT STRIP_TAC THEN
15572 MAP_EVERY EXPAND_TAC ["A'"; "B'"] THEN
15573 ASM_SIMP_TAC[LAMBDA_BETA];
15574 MATCH_MP_TAC PRODUCT_EQ_1_NUMSEG THEN
15575 ASM_SIMP_TAC[ARITH_RULE `n + 1 <= i ==> n < i`] THEN
15576 ASM_SIMP_TAC[ARITH_RULE `m:num <= n ==> m + (n - m) = n`] THEN
15577 X_GEN_TAC `i:num` THEN STRIP_TAC THEN
15578 SUBGOAL_THEN `1 <= i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
15579 ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MAT_COMPONENT] THEN
15580 ASM_SIMP_TAC[REAL_EQ_ADD_LCANCEL_0; matrix_mul; LAMBDA_BETA] THEN
15581 MATCH_MP_TAC SUM_EQ_0_NUMSEG THEN REPEAT STRIP_TAC THEN
15582 REWRITE_TAC[REAL_ENTIRE] THEN DISJ1_TAC THEN EXPAND_TAC "A'" THEN
15583 ASM_SIMP_TAC[LAMBDA_BETA; ARITH_RULE `m + 1 <= i ==> ~(i <= m)`]]]) in
15584 REPEAT GEN_TAC THEN DISJ_CASES_TAC (ARITH_RULE
15585 `dimindex(:M) <= dimindex(:N) \/ dimindex(:N) <= dimindex(:M)`)
15586 THENL [ALL_TAC; CONV_TAC SYM_CONV] THEN
15587 MATCH_MP_TAC lemma2 THEN ASM_REWRITE_TAC[]);;
15589 let COFACTOR_MATRIX_MUL = prove
15590 (`!A B:real^N^N. cofactor(A ** B) = cofactor(A) ** cofactor(B)`,
15591 MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN CONJ_TAC THENL
15592 [GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN
15594 [ASM_SIMP_TAC[COFACTOR_MATRIX_INV; GSYM INVERTIBLE_DET_NZ;
15595 INVERTIBLE_MATRIX_MUL] THEN
15596 REWRITE_TAC[DET_MUL; MATRIX_MUL_LMUL] THEN
15597 REWRITE_TAC[MATRIX_MUL_RMUL; MATRIX_CMUL_ASSOC;
15598 GSYM MATRIX_TRANSP_MUL] THEN
15599 ASM_SIMP_TAC[MATRIX_INV_MUL];
15600 GEN_TAC THEN EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01]];
15601 X_GEN_TAC `A:real^N^N` THEN EXISTS_TAC `&1` THEN
15602 REWRITE_TAC[REAL_LT_01] THEN REWRITE_TAC[RIGHT_AND_FORALL_THM] THEN
15603 MATCH_MP_TAC CLOSED_FORALL THEN GEN_TAC] THEN
15604 REWRITE_TAC[SET_RULE
15605 `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
15606 MATCH_MP_TAC CLOSED_INTER THEN REWRITE_TAC[CLOSED_CBALL] THEN
15607 REWRITE_TAC[CART_EQ] THEN
15608 MATCH_MP_TAC CLOSED_FORALL_IN THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
15609 MATCH_MP_TAC CLOSED_FORALL_IN THEN X_GEN_TAC `j:num` THEN STRIP_TAC THEN
15610 ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN
15611 REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN
15612 REWRITE_TAC[SET_RULE `{x | f x = a} = {x | f x IN {a}}`] THEN
15613 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN
15614 REWRITE_TAC[CLOSED_SING; LIFT_SUB] THEN X_GEN_TAC `x:real^1` THEN
15615 ASM_SIMP_TAC[matrix_mul; LAMBDA_BETA; cofactor; LIFT_SUM;
15616 FINITE_NUMSEG; o_DEF] THEN
15617 (MATCH_MP_TAC CONTINUOUS_SUB THEN CONJ_TAC THENL
15619 MATCH_MP_TAC CONTINUOUS_VSUM THEN
15620 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
15621 X_GEN_TAC `k:num` THEN STRIP_TAC THEN
15622 REWRITE_TAC[LIFT_CMUL] THEN MATCH_MP_TAC CONTINUOUS_MUL THEN
15623 REWRITE_TAC[o_DEF] THEN CONJ_TAC]) THEN
15624 MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN
15625 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN
15626 ASM_SIMP_TAC[LAMBDA_BETA; CONTINUOUS_CONST] THEN
15627 REPEAT(W(fun (asl,w) ->
15628 let t = find_term is_cond w in
15629 ASM_CASES_TAC (lhand(rator t)) THEN ASM_REWRITE_TAC[CONTINUOUS_CONST])) THEN
15630 SIMP_TAC[LIFT_SUM; FINITE_NUMSEG; o_DEF] THEN
15631 TRY(MATCH_MP_TAC CONTINUOUS_VSUM THEN REWRITE_TAC[FINITE_NUMSEG] THEN
15632 REWRITE_TAC[IN_NUMSEG] THEN X_GEN_TAC `p:num` THEN STRIP_TAC) THEN
15633 REWRITE_TAC[LIFT_CMUL] THEN
15634 TRY(MATCH_MP_TAC CONTINUOUS_MUL THEN
15635 REWRITE_TAC[o_DEF; CONTINUOUS_CONST]) THEN
15636 REWRITE_TAC[MATRIX_ADD_COMPONENT; LIFT_ADD] THEN
15637 MATCH_MP_TAC CONTINUOUS_ADD THEN REWRITE_TAC[CONTINUOUS_CONST] THEN
15638 REWRITE_TAC[MATRIX_CMUL_COMPONENT; LIFT_CMUL; o_DEF] THEN
15639 MATCH_MP_TAC CONTINUOUS_MUL THEN
15640 REWRITE_TAC[CONTINUOUS_CONST; o_DEF; LIFT_DROP; CONTINUOUS_AT_ID]);;
15642 let DET_COFACTOR = prove
15643 (`!A:real^N^N. det(cofactor A) = det(A) pow (dimindex(:N) - 1)`,
15644 MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN CONJ_TAC THEN
15645 X_GEN_TAC `A:real^N^N` THENL
15646 [REWRITE_TAC[INVERTIBLE_DET_NZ] THEN STRIP_TAC THEN
15647 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_FIELD
15648 `~(a = &0) ==> a * x = a * y ==> x = y`)) THEN
15649 GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM DET_TRANSP] THEN
15650 REWRITE_TAC[GSYM DET_MUL; MATRIX_MUL_RIGHT_COFACTOR] THEN
15651 REWRITE_TAC[DET_CMUL; GSYM(CONJUNCT2 real_pow); DET_I; REAL_MUL_RID] THEN
15652 SIMP_TAC[DIMINDEX_GE_1; ARITH_RULE `1 <= n ==> SUC(n - 1) = n`];
15654 EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
15655 REWRITE_TAC[SET_RULE
15656 `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
15657 MATCH_MP_TAC CLOSED_INTER THEN REWRITE_TAC[CLOSED_CBALL] THEN
15658 ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN
15659 REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN
15660 REWRITE_TAC[SET_RULE `{x | f x = a} = {x | f x IN {a}}`] THEN
15661 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN
15662 REWRITE_TAC[CLOSED_SING; LIFT_SUB] THEN X_GEN_TAC `x:real^1` THEN
15663 MATCH_MP_TAC CONTINUOUS_SUB THEN
15664 CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC CONTINUOUS_LIFT_POW] THEN
15665 MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN
15666 MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN STRIP_TAC THEN
15667 ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MATRIX_CMUL_COMPONENT; LIFT_ADD;
15668 LIFT_CMUL; LIFT_DROP; CONTINUOUS_ADD; CONTINUOUS_CONST;
15669 CONTINUOUS_MUL; o_DEF; LIFT_DROP; CONTINUOUS_AT_ID] THEN
15670 ASM_SIMP_TAC[cofactor; LAMBDA_BETA] THEN
15671 MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN
15672 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN
15673 ASM_SIMP_TAC[LAMBDA_BETA] THEN
15674 REPEAT(W(fun (asl,w) ->
15675 let t = find_term is_cond w in
15676 ASM_CASES_TAC (lhand(rator t)) THEN ASM_REWRITE_TAC[CONTINUOUS_CONST])) THEN
15677 ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MATRIX_CMUL_COMPONENT; LIFT_ADD;
15678 LIFT_CMUL; LIFT_DROP; CONTINUOUS_ADD; CONTINUOUS_CONST;
15679 CONTINUOUS_MUL; o_DEF; LIFT_DROP; CONTINUOUS_AT_ID]);;
15681 let INVERTIBLE_COFACTOR = prove
15682 (`!A:real^N^N. invertible(cofactor A) <=> dimindex(:N) = 1 \/ invertible A`,
15683 SIMP_TAC[DET_COFACTOR; INVERTIBLE_DET_NZ; REAL_POW_EQ_0; DE_MORGAN_THM;
15684 DIMINDEX_GE_1; ARITH_RULE `1 <= n ==> (n - 1 = 0 <=> n = 1)`;
15687 let COFACTOR_COFACTOR = prove
15690 ==> cofactor(cofactor A) = (det(A) pow (dimindex(:N) - 2)) %% A`,
15691 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN DISCH_TAC THEN
15692 MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN CONJ_TAC THEN
15693 X_GEN_TAC `A:real^N^N` THENL
15694 [REWRITE_TAC[INVERTIBLE_DET_NZ] THEN DISCH_TAC THEN
15695 MP_TAC(ISPECL [`A:real^N^N`; `transp(cofactor A):real^N^N`]
15696 COFACTOR_MATRIX_MUL) THEN
15697 REWRITE_TAC[MATRIX_MUL_RIGHT_COFACTOR; COFACTOR_CMUL; COFACTOR_I] THEN
15698 REWRITE_TAC[COFACTOR_TRANSP] THEN
15699 DISCH_THEN(MP_TAC o AP_TERM `transp:real^N^N->real^N^N`) THEN
15700 REWRITE_TAC[MATRIX_TRANSP_MUL; TRANSP_TRANSP; TRANSP_MATRIX_CMUL] THEN
15701 REWRITE_TAC[TRANSP_MAT] THEN
15702 DISCH_THEN(MP_TAC o AP_TERM `(\x. x ** A):real^N^N->real^N^N`) THEN
15703 REWRITE_TAC[GSYM MATRIX_MUL_ASSOC; MATRIX_MUL_LEFT_COFACTOR] THEN
15704 REWRITE_TAC[MATRIX_MUL_LMUL; MATRIX_MUL_RMUL] THEN
15705 REWRITE_TAC[MATRIX_MUL_LID; MATRIX_MUL_RID] THEN
15706 DISCH_THEN(MP_TAC o AP_TERM `\x:real^N^N. inv(det(A:real^N^N)) %% x`) THEN
15707 ASM_SIMP_TAC[MATRIX_CMUL_ASSOC; REAL_MUL_LINV; MATRIX_CMUL_LID] THEN
15708 DISCH_THEN(SUBST1_TAC o SYM) THEN AP_THM_TAC THEN AP_TERM_TAC THEN
15709 ASM_SIMP_TAC[REAL_POW_SUB; ARITH_RULE `2 <= n ==> 1 <= n`] THEN
15710 REWRITE_TAC[REAL_POW_2; real_div; REAL_INV_POW] THEN REAL_ARITH_TAC;
15711 POP_ASSUM(K ALL_TAC)] THEN
15712 EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
15713 REWRITE_TAC[SET_RULE
15714 `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
15715 MATCH_MP_TAC CLOSED_INTER THEN REWRITE_TAC[CLOSED_CBALL] THEN
15716 REWRITE_TAC[CART_EQ] THEN
15717 MATCH_MP_TAC CLOSED_FORALL_IN THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
15718 MATCH_MP_TAC CLOSED_FORALL_IN THEN X_GEN_TAC `j:num` THEN STRIP_TAC THEN
15719 ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN
15720 REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN
15721 REWRITE_TAC[SET_RULE `{x | f x = a} = {x | f x IN {a}}`] THEN
15722 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN
15723 REWRITE_TAC[CLOSED_SING; LIFT_SUB] THEN X_GEN_TAC `x:real^1` THEN
15724 MATCH_MP_TAC CONTINUOUS_SUB THEN CONJ_TAC THENL
15726 (ONCE_REWRITE_TAC[cofactor] THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN
15727 MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN REPEAT STRIP_TAC THEN
15728 ASM_SIMP_TAC[LAMBDA_BETA] THEN
15729 REPEAT(W(fun (asl,w) ->
15730 let t = find_term is_cond w in
15731 ASM_CASES_TAC (lhand(rator t)) THEN
15732 ASM_REWRITE_TAC[CONTINUOUS_CONST])));
15733 REWRITE_TAC[MATRIX_CMUL_COMPONENT; LIFT_CMUL] THEN
15734 MATCH_MP_TAC CONTINUOUS_MUL THEN REWRITE_TAC[o_DEF] THEN CONJ_TAC THENL
15735 [MATCH_MP_TAC CONTINUOUS_LIFT_POW THEN
15736 MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN REPEAT STRIP_TAC;
15738 REWRITE_TAC[MATRIX_ADD_COMPONENT; MATRIX_CMUL_COMPONENT] THEN
15739 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
15740 REWRITE_TAC[LIFT_ADD; LIFT_CMUL; LIFT_DROP] THEN
15741 SIMP_TAC[CONTINUOUS_ADD; CONTINUOUS_CONST; CONTINUOUS_CMUL;
15742 CONTINUOUS_AT_ID]);;
15744 let RANK_COFACTOR_EQ_FULL = prove
15745 (`!A:real^N^N. rank(cofactor A) = dimindex(:N) <=>
15746 dimindex(:N) = 1 \/ rank A = dimindex(:N)`,
15747 REWRITE_TAC[RANK_EQ_FULL_DET; DET_COFACTOR; REAL_POW_EQ_0] THEN
15748 SIMP_TAC[DIMINDEX_GE_1; ARITH_RULE `1 <= n ==> (n - 1 = 0 <=> n = 1)`] THEN
15751 let COFACTOR_EQ_0 = prove
15752 (`!A:real^N^N. cofactor A = mat 0 <=> rank(A) < dimindex(:N) - 1`,
15754 (`!A:real^N^N. rank(A) < dimindex(:N) - 1 ==> cofactor A = mat 0`,
15755 GEN_TAC THEN REWRITE_TAC[RANK_ROW] THEN DISCH_TAC THEN
15756 SIMP_TAC[CART_EQ; cofactor; MAT_COMPONENT; LAMBDA_BETA; COND_ID] THEN
15757 X_GEN_TAC `m:num` THEN STRIP_TAC THEN X_GEN_TAC `n:num` THEN STRIP_TAC THEN
15758 REWRITE_TAC[DET_EQ_0_RANK] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
15759 (ARITH_RULE `r < n - 1 ==> s <= r + 1 ==> s < n`)) THEN
15760 REWRITE_TAC[RANK_ROW; rows] THEN MATCH_MP_TAC LE_TRANS THEN
15762 `dim (basis n INSERT
15763 {row i ((lambda k l. if l = n then &0 else (A:real^N^N)$k$l)
15765 | i IN (1..dimindex(:N)) DELETE m})` THEN
15767 [MATCH_MP_TAC DIM_SUBSET THEN REWRITE_TAC[GSYM IN_NUMSEG] THEN
15768 MATCH_MP_TAC(SET_RULE
15769 `m IN s /\ (!i. i IN s DELETE m ==> f i = g i) /\ f m = a
15770 ==> {f i | i IN s} SUBSET a INSERT {g i | i IN s DELETE m}`) THEN
15771 ASM_SIMP_TAC[IN_NUMSEG; IN_DELETE; row; LAMBDA_BETA; basis; LAMBDA_ETA];
15772 REWRITE_TAC[DIM_INSERT] THEN MATCH_MP_TAC(ARITH_RULE
15773 `n <= k ==> (if p then n else n + 1) <= k + 1`) THEN
15774 MATCH_MP_TAC(MESON[DIM_LINEAR_IMAGE_LE; DIM_SUBSET; LE_TRANS]
15775 `(?f. linear f /\ t SUBSET IMAGE f s) ==> dim t <= dim s`) THEN
15776 EXISTS_TAC `(\x. lambda i. if i = n then &0 else x$i)
15777 :real^N->real^N` THEN
15778 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN CONJ_TAC THENL
15779 [SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
15780 VECTOR_MUL_COMPONENT] THEN
15781 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
15783 X_GEN_TAC `i:num` THEN REWRITE_TAC[IN_NUMSEG; IN_DELETE] THEN
15784 STRIP_TAC THEN REWRITE_TAC[IN_IMAGE] THEN
15785 ONCE_REWRITE_TAC[CONJ_SYM] THEN
15786 REWRITE_TAC[EXISTS_IN_GSPEC] THEN EXISTS_TAC `i:num` THEN
15787 ASM_SIMP_TAC[row; CART_EQ; LAMBDA_BETA]]])
15790 rank A < dimindex(:N)
15791 ==> ?n x. 1 <= n /\ n <= dimindex(:N) /\
15793 rank((lambda i. if i = n then x else row i A):real^N^N)`,
15794 REPEAT STRIP_TAC THEN SUBGOAL_THEN
15795 `?n. 1 <= n /\ n <= dimindex(:N) /\
15796 row n (A:real^N^N) IN
15797 span {row j A | j IN (1..dimindex(:N)) DELETE n}`
15799 [MP_TAC(ISPEC `transp A:real^N^N` HOMOGENEOUS_LINEAR_EQUATIONS_DET) THEN
15800 ASM_REWRITE_TAC[DET_EQ_0_RANK; RANK_TRANSP] THEN
15801 DISCH_THEN(X_CHOOSE_THEN `c:real^N` STRIP_ASSUME_TAC) THEN
15802 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CART_EQ]) THEN
15803 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; VEC_COMPONENT] THEN
15804 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:num` THEN STRIP_TAC THEN
15805 ASM_REWRITE_TAC[] THEN
15806 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CART_EQ]) THEN
15807 SIMP_TAC[matrix_vector_mul; transp; VEC_COMPONENT; LAMBDA_BETA] THEN
15809 SUBGOAL_THEN `row n A = vsum ((1..dimindex(:N)) DELETE n)
15810 (\i. --((c:real^N)$i / c$n) % row i (A:real^N^N))`
15812 [ASM_SIMP_TAC[VSUM_DELETE; FINITE_NUMSEG; IN_NUMSEG; REAL_DIV_REFL] THEN
15813 REWRITE_TAC[VECTOR_ARITH `n = x - -- &1 % n <=> x:real^N = vec 0`] THEN
15814 SIMP_TAC[VSUM_COMPONENT; row; VECTOR_MUL_COMPONENT; LAMBDA_BETA;
15815 CART_EQ; REAL_ARITH `--(x / y) * z:real = --(inv y) * z * x`] THEN
15816 ASM_SIMP_TAC[SUM_LMUL; VEC_COMPONENT; REAL_MUL_RZERO];
15817 MATCH_MP_TAC SPAN_VSUM THEN SIMP_TAC[FINITE_DELETE; FINITE_NUMSEG] THEN
15818 X_GEN_TAC `i:num` THEN REWRITE_TAC[IN_DELETE; IN_NUMSEG] THEN
15819 STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN
15820 MATCH_MP_TAC SPAN_SUPERSET THEN ASM SET_TAC[]];
15821 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:num` THEN STRIP_TAC THEN
15822 ASM_REWRITE_TAC[] THEN
15823 SUBGOAL_THEN `span {row j (A:real^N^N) | j IN (1..dimindex(:N)) DELETE n}
15826 [REWRITE_TAC[PSUBSET; SUBSET_UNIV] THEN
15827 DISCH_THEN(MP_TAC o AP_TERM `dim:(real^N->bool)->num`) THEN
15828 REWRITE_TAC[DIM_UNIV] THEN
15829 MATCH_MP_TAC(ARITH_RULE `1 <= n /\ x <= n - 1 ==> ~(x = n)`) THEN
15830 REWRITE_TAC[DIMINDEX_GE_1; DIM_SPAN] THEN
15831 W(MP_TAC o PART_MATCH (lhand o rand) DIM_LE_CARD o lhand o snd) THEN
15832 ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
15833 SIMP_TAC[FINITE_IMAGE; FINITE_DELETE; FINITE_NUMSEG] THEN
15834 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] LE_TRANS) THEN
15835 W(MP_TAC o PART_MATCH (lhand o rand) CARD_IMAGE_LE o lhand o snd) THEN
15836 SIMP_TAC[FINITE_DELETE; FINITE_NUMSEG] THEN
15837 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] LE_TRANS) THEN
15838 ASM_SIMP_TAC[CARD_DELETE; IN_NUMSEG; FINITE_NUMSEG] THEN
15839 REWRITE_TAC[CARD_NUMSEG_1; LE_REFL];
15840 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
15841 `s PSUBSET UNIV ==> ?x. ~(x IN s)`)) THEN
15842 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN
15843 REWRITE_TAC[RANK_ROW] THEN DISCH_TAC THEN
15845 `!A:real^N^N. rows A = row n A INSERT
15846 {row j A | j IN (1..dimindex (:N)) DELETE n}`
15847 (fun th -> REWRITE_TAC[th])
15849 [REWRITE_TAC[rows; IN_DELETE; IN_NUMSEG] THEN ASM SET_TAC[];
15850 ASM_SIMP_TAC[DIM_INSERT]] THEN
15851 COND_CASES_TAC THENL
15852 [FIRST_X_ASSUM(MP_TAC o check (is_neg o concl)) THEN
15853 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[]
15854 `x IN span s ==> x = y /\ s = t ==> ~(y IN span t) ==> q`)) THEN
15855 ASM_SIMP_TAC[row; LAMBDA_BETA; LAMBDA_ETA];
15856 MATCH_MP_TAC(ARITH_RULE `s = t ==> s < t + 1`) THEN
15857 AP_TERM_TAC THEN REWRITE_TAC[row]] THEN
15858 MATCH_MP_TAC(SET_RULE
15859 `(!x. x IN s ==> f x = g x) ==> {f x | x IN s} = {g x | x IN s}`) THEN
15860 ASM_SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA; CART_EQ]]]) in
15861 GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[lemma1] THEN DISCH_TAC THEN
15862 MATCH_MP_TAC(ARITH_RULE
15863 `r <= n /\ ~(r = n) /\ ~(r = n - 1) ==> r < n - 1`) THEN
15864 REPEAT CONJ_TAC THENL
15865 [MP_TAC(ISPEC `A:real^N^N` RANK_BOUND) THEN ARITH_TAC;
15866 REWRITE_TAC[RANK_EQ_FULL_DET] THEN
15867 MP_TAC(SYM(ISPEC `A:real^N^N` MATRIX_MUL_LEFT_COFACTOR)) THEN
15868 ASM_REWRITE_TAC[MATRIX_CMUL_EQ_0; TRANSP_MAT; MATRIX_MUL_LZERO] THEN
15869 REWRITE_TAC[MAT_EQ; ARITH_EQ];
15871 MP_TAC(ISPEC `A:real^N^N` lemma2) THEN
15872 ASM_REWRITE_TAC[DIMINDEX_GE_1; ARITH_RULE `n - 1 < n <=> 1 <= n`] THEN
15873 DISCH_THEN(X_CHOOSE_THEN `n:num` (X_CHOOSE_THEN `x:real^N`
15874 STRIP_ASSUME_TAC)) THEN
15875 FIRST_ASSUM(MP_TAC o MATCH_MP (ARITH_RULE
15876 `n - 1 < k ==> k <= MIN n n ==> k = n`)) THEN
15877 REWRITE_TAC[RANK_BOUND; RANK_EQ_FULL_DET] THEN
15878 MP_TAC(GEN `A:real^N^N` (ISPECL [`A:real^N^N`; `n:num`]
15879 DET_COFACTOR_EXPANSION)) THEN
15880 ASM_SIMP_TAC[] THEN DISCH_THEN(K ALL_TAC) THEN MATCH_MP_TAC SUM_EQ_0 THEN
15881 X_GEN_TAC `m:num` THEN SIMP_TAC[IN_NUMSEG; REAL_ENTIRE] THEN STRIP_TAC THEN
15882 DISJ2_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CART_EQ]) THEN
15883 DISCH_THEN(MP_TAC o SPEC `n:num`) THEN ASM_REWRITE_TAC[CART_EQ] THEN
15884 DISCH_THEN(MP_TAC o SPEC `m:num`) THEN
15885 ASM_SIMP_TAC[MAT_COMPONENT; COND_ID] THEN
15886 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EQ_TRANS) THEN
15887 ASM_SIMP_TAC[cofactor; LAMBDA_BETA] THEN AP_TERM_TAC THEN
15888 ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA; row] THEN
15889 REPEAT STRIP_TAC THEN
15890 REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[LAMBDA_BETA]) THEN
15893 let RANK_COFACTOR_EQ_1 = prove
15894 (`!A:real^N^N. rank(cofactor A) = 1 <=>
15895 dimindex(:N) = 1 \/ rank A = dimindex(:N) - 1`,
15896 GEN_TAC THEN ASM_CASES_TAC `dimindex(:N) = 1` THENL
15897 [ASM_MESON_TAC[RANK_COFACTOR_EQ_FULL]; ASM_REWRITE_TAC[]] THEN
15899 [ASM_CASES_TAC `cofactor A:real^N^N = mat 0` THEN
15900 ASM_REWRITE_TAC[RANK_0; ARITH_EQ] THEN DISCH_TAC THEN
15901 MATCH_MP_TAC(ARITH_RULE
15902 `~(r < n - 1) /\ ~(r = n) /\ r <= MIN n n ==> r = n - 1`) THEN
15903 ASM_REWRITE_TAC[RANK_BOUND; GSYM COFACTOR_EQ_0] THEN
15904 MP_TAC(ISPEC `A:real^N^N` RANK_COFACTOR_EQ_FULL) THEN ASM_REWRITE_TAC[];
15905 DISCH_TAC THEN MATCH_MP_TAC(ARITH_RULE
15906 `~(n = 0) /\ n <= 1 ==> n = 1`) THEN
15907 ASM_REWRITE_TAC[RANK_EQ_0; COFACTOR_EQ_0; LT_REFL] THEN
15908 MP_TAC(ISPECL [`A:real^N^N`; `transp(cofactor A):real^N^N`]
15909 RANK_SYLVESTER) THEN
15910 ASM_REWRITE_TAC[MATRIX_MUL_RIGHT_COFACTOR; RANK_TRANSP] THEN
15911 FIRST_ASSUM(MP_TAC o MATCH_MP (ARITH_RULE
15912 `a = n - 1 ==> 1 <= n ==> a < n`)) THEN
15913 ASM_SIMP_TAC[GSYM DET_EQ_0_RANK; DIMINDEX_GE_1] THEN
15914 DISCH_TAC THEN REWRITE_TAC[MATRIX_CMUL_LZERO; RANK_0] THEN
15917 let RANK_COFACTOR = prove
15919 rank(cofactor A) = if rank(A) = dimindex(:N) then dimindex(:N)
15920 else if rank(A) = dimindex(:N) - 1 then 1
15922 GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[RANK_COFACTOR_EQ_FULL] THEN
15923 COND_CASES_TAC THEN ASM_REWRITE_TAC[RANK_COFACTOR_EQ_1] THEN
15924 REWRITE_TAC[RANK_EQ_0; COFACTOR_EQ_0] THEN
15925 MATCH_MP_TAC(ARITH_RULE
15926 `r <= MIN n n /\ ~(r = n) /\ ~(r = n - 1) ==> r < n - 1`) THEN
15927 ASM_REWRITE_TAC[RANK_BOUND]);;
15929 (* ------------------------------------------------------------------------- *)
15930 (* Not in so many words, but combining this with intermediate value theorem *)
15931 (* implies the determinant is an open map. *)
15932 (* ------------------------------------------------------------------------- *)
15934 let DET_OPEN_MAP = prove
15937 ==> (?B:real^N^N. (!i j. abs(B$i$j - A$i$j) < e) /\ det B < det A) /\
15938 (?C:real^N^N. (!i j. abs(C$i$j - A$i$j) < e) /\ det C > det A)`,
15941 1 <= i /\ i <= dimindex(:N) /\ row i A = vec 0 /\ &0 < e
15942 ==> (?B:real^N^N. (!i j. abs(B$i$j - A$i$j) < e) /\ det B < &0) /\
15943 (?C:real^N^N. (!i j. abs(C$i$j - A$i$j) < e) /\ det C > &0)`,
15944 REPEAT GEN_TAC THEN STRIP_TAC THEN
15945 SUBGOAL_THEN `det(A:real^N^N) = &0` ASSUME_TAC THENL
15946 [ASM_MESON_TAC[DET_ZERO_ROW]; ALL_TAC] THEN
15947 MP_TAC(ISPEC `A:real^N^N` NEARBY_INVERTIBLE_MATRIX) THEN
15948 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
15949 FIRST_X_ASSUM(MP_TAC o SPEC `min d e / &2`) THEN
15950 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[INVERTIBLE_DET_NZ]] THEN
15951 DISCH_THEN(STRIP_ASSUME_TAC o MATCH_MP (REAL_ARITH
15952 `~(x = &0) ==> x < &0 \/ &0 < x`))
15953 THENL [ALL_TAC; ONCE_REWRITE_TAC[CONJ_SYM]] THEN
15955 [EXISTS_TAC `A + min d e / &2 %% mat 1:real^N^N`;
15956 EXISTS_TAC `(lambda j. if j = i then
15957 --(&1) % row i (A + min d e / &2 %% mat 1:real^N^N)
15958 else row j (A + min d e / &2 %% mat 1:real^N^N))
15960 ASM_SIMP_TAC[DET_ROW_MUL; MESON[]
15961 `(if j = i then f i else f j) = f j`] THEN
15962 REWRITE_TAC[row; LAMBDA_ETA] THEN
15963 ASM_REWRITE_TAC[real_gt; GSYM row] THEN
15964 TRY(CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC]) THEN
15965 (MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN
15966 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !A:real^N^N. A$m = A$k`
15967 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
15968 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$n = z$l`
15969 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC]) THEN
15970 ASM_SIMP_TAC[LAMBDA_BETA] THEN
15971 TRY COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
15972 ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MATRIX_CMUL_COMPONENT; MAT_COMPONENT;
15973 VECTOR_MUL_COMPONENT] THEN
15974 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CART_EQ]) THEN
15975 DISCH_THEN(MP_TAC o SPEC `l:num`) THEN
15976 ASM_SIMP_TAC[row; LAMBDA_BETA; VEC_COMPONENT] THEN
15977 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC)
15979 (`!A:real^N^N x:real^N i.
15980 1 <= i /\ i <= dimindex(:N) /\ x$i = &1
15981 ==> det(lambda k. if k = i then transp A ** x else row k A) = det A`,
15982 REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
15984 `det(lambda k. if k = i
15985 then row i (A:real^N^N) + (transp A ** x - row i A)
15986 else row k A)` THEN
15988 [REWRITE_TAC[VECTOR_ARITH `r + (x - r):real^N = x`]; ALL_TAC] THEN
15989 MATCH_MP_TAC DET_ROW_SPAN THEN
15991 `transp(A:real^N^N) ** x - row i A =
15992 vsum ((1..dimindex(:N)) DELETE i) (\k. x$k % row k A)`
15994 [SIMP_TAC[CART_EQ; VSUM_COMPONENT; VECTOR_SUB_COMPONENT; row; transp;
15995 LAMBDA_BETA; matrix_vector_mul; VECTOR_MUL_COMPONENT] THEN
15996 ASM_SIMP_TAC[SUM_DELETE; IN_NUMSEG; FINITE_NUMSEG; REAL_MUL_LID] THEN
15997 REWRITE_TAC[REAL_MUL_AC];
15998 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SPAN_VSUM THEN
15999 REWRITE_TAC[FINITE_DELETE; IN_DELETE; IN_NUMSEG; FINITE_NUMSEG] THEN
16000 X_GEN_TAC `j:num` THEN STRIP_TAC THEN MATCH_MP_TAC SPAN_MUL THEN
16001 MATCH_MP_TAC SPAN_SUPERSET THEN ASM SET_TAC[]]) in
16002 REPEAT GEN_TAC THEN DISCH_TAC THEN
16003 ASM_CASES_TAC `cofactor(A:real^N^N) = mat 0` THENL
16004 [MP_TAC(SYM(ISPEC `A:real^N^N` MATRIX_MUL_LEFT_COFACTOR)) THEN
16005 ASM_REWRITE_TAC[MATRIX_CMUL_EQ_0; TRANSP_MAT; MATRIX_MUL_LZERO] THEN
16006 REWRITE_TAC[MAT_EQ; ARITH_EQ] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
16008 `?c i. 1 <= i /\ i <= dimindex(:N) /\ c$i = &1 /\
16009 transp(A:real^N^N) ** c = vec 0`
16010 STRIP_ASSUME_TAC THENL
16011 [MP_TAC(ISPEC `transp A:real^N^N` HOMOGENEOUS_LINEAR_EQUATIONS_DET) THEN
16012 ASM_REWRITE_TAC[DET_TRANSP] THEN
16013 DISCH_THEN(X_CHOOSE_THEN `c:real^N` STRIP_ASSUME_TAC) THEN
16014 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
16015 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CART_EQ]) THEN
16016 REWRITE_TAC[VEC_COMPONENT; NOT_IMP; NOT_FORALL_THM] THEN
16017 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
16018 EXISTS_TAC `inv(c$i) % c:real^N` THEN
16019 ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; REAL_MUL_LINV] THEN
16020 ASM_REWRITE_TAC[MATRIX_VECTOR_MUL_RMUL; VECTOR_MUL_RZERO];
16023 [`(lambda k. if k = i then transp A ** c else row k (A:real^N^N)):real^N^N`;
16024 `i:num`; `min e (e / &(dimindex(:N)) /
16025 (&1 + norm(&2 % basis i - c:real^N)))`] lemma1) THEN
16026 ASM_SIMP_TAC[REAL_LT_MIN; REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1;
16027 NORM_ARITH `&0 < &1 + norm(x:real^N)`] THEN
16029 [ASM_SIMP_TAC[row; CART_EQ; VEC_COMPONENT; LAMBDA_BETA];
16031 MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN
16032 ABBREV_TAC `A':real^N^N =
16033 lambda k. if k = i then vec 0 else row k (A:real^N^N)` THEN
16034 DISCH_THEN(X_CHOOSE_THEN `B:real^N^N` STRIP_ASSUME_TAC) THEN
16035 EXISTS_TAC `(lambda k. if k = i then transp(B:real^N^N) **
16037 else row k B):real^N^N` THEN
16038 ASM_SIMP_TAC[lemma2; BASIS_COMPONENT; VECTOR_MUL_COMPONENT;
16039 VECTOR_SUB_COMPONENT; REAL_ARITH `&2 * x - x = x`] THEN
16040 (MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN
16041 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !A:real^N^N. A$m = A$k`
16042 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
16043 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$n = z$l`
16044 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC]) THEN
16045 EXPAND_TAC "A'" THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN
16046 (COND_CASES_TAC THENL
16048 FIRST_X_ASSUM(MP_TAC o SPECL [`k:num`; `l:num`]) THEN
16049 EXPAND_TAC "A'" THEN ASM_SIMP_TAC[LAMBDA_BETA; row]] THEN
16051 `(A:real^N^N)$k$l = (transp(A':real^N^N) ** (&2 % basis i - c:real^N))$l`
16053 [ASM_SIMP_TAC[matrix_vector_mul; transp; LAMBDA_BETA] THEN
16054 EXPAND_TAC "A'" THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN
16055 REWRITE_TAC[COND_RAND; COND_RATOR] THEN
16056 SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; BASIS_COMPONENT;
16057 VEC_COMPONENT; REAL_MUL_RZERO; REAL_SUB_LZERO; REAL_MUL_LZERO] THEN
16058 ASM_SIMP_TAC[SUM_CASES; FINITE_NUMSEG; SUM_0; REAL_ADD_LID] THEN
16059 ASM_SIMP_TAC[GSYM DELETE; SUM_DELETE; IN_NUMSEG; FINITE_NUMSEG] THEN
16060 UNDISCH_TAC `transp(A:real^N^N) ** (c:real^N) = vec 0` THEN
16061 ASM_SIMP_TAC[CART_EQ; VEC_COMPONENT; matrix_vector_mul; LAMBDA_BETA;
16063 DISCH_THEN(MP_TAC o SPEC `l:num`) THEN ASM_REWRITE_TAC[] THEN
16064 SIMP_TAC[REAL_MUL_RNEG; SUM_NEG] THEN REAL_ARITH_TAC;
16065 REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT; GSYM TRANSP_MATRIX_SUB;
16066 GSYM MATRIX_VECTOR_MUL_SUB_RDISTRIB]] THEN
16067 ASM_SIMP_TAC[matrix_vector_mul; transp; LAMBDA_BETA] THEN
16068 W(MP_TAC o PART_MATCH lhand SUM_ABS_NUMSEG o lhand o snd) THEN
16069 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LET_TRANS) THEN
16070 MATCH_MP_TAC SUM_BOUND_LT_GEN THEN
16071 ASM_SIMP_TAC[FINITE_NUMSEG; NUMSEG_EMPTY;
16072 GSYM NOT_LE; DIMINDEX_GE_1] THEN
16073 X_GEN_TAC `r:num` THEN REWRITE_TAC[CARD_NUMSEG_1; IN_NUMSEG] THEN
16074 STRIP_TAC THEN REWRITE_TAC[REAL_ABS_MUL] THEN
16075 TRANS_TAC REAL_LET_TRANS
16076 `abs((B - A':real^N^N)$r$l) * (&1 + norm(&2 % basis i - c:real^N))` THEN
16078 [MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[REAL_ABS_POS] THEN
16079 MATCH_MP_TAC(REAL_ARITH `a <= b ==> a <= &1 + b`) THEN
16080 ASM_SIMP_TAC[COMPONENT_LE_NORM];
16081 ASM_SIMP_TAC[MATRIX_SUB_COMPONENT; GSYM REAL_LT_RDIV_EQ;
16082 NORM_ARITH `&0 < &1 + norm(x:real^N)`]]);
16083 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CART_EQ]) THEN
16084 SIMP_TAC[CART_EQ; MAT_COMPONENT; COND_ID] THEN
16085 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; real_gt] THEN
16086 DISCH_THEN(X_CHOOSE_THEN `i:num` (CONJUNCTS_THEN2 STRIP_ASSUME_TAC
16087 (X_CHOOSE_THEN `j:num` STRIP_ASSUME_TAC))) THEN
16088 FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH
16089 `~(x = &0) ==> &0 < x \/ x < &0`))
16090 THENL [ALL_TAC; ONCE_REWRITE_TAC[CONJ_SYM]] THEN
16092 [EXISTS_TAC `(lambda m n. if m = i /\ n = j
16093 then (A:real^N^N)$i$j -
16094 e / (&1 + abs(cofactor A$i$j))
16095 else A$m$n):real^N^N`;
16096 EXISTS_TAC `(lambda m n. if m = i /\ n = j
16097 then (A:real^N^N)$i$j +
16098 e / (&1 + abs(cofactor A$i$j))
16099 else A$m$n):real^N^N`]) THEN
16101 [MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN
16102 SUBGOAL_THEN `?k. 1 <= k /\ k <= dimindex(:N) /\ !A:real^N^N. A$m = A$k`
16103 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
16104 SUBGOAL_THEN `?l. 1 <= l /\ l <= dimindex(:N) /\ !z:real^N. z$n = z$l`
16105 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
16106 ASM_SIMP_TAC[LAMBDA_BETA] THEN
16107 COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_ABS_NUM] THEN
16108 REWRITE_TAC[REAL_ARITH `abs(a - e - a) = abs e`;
16109 REAL_ARITH `abs((a + e) - a) = abs e`] THEN
16110 REWRITE_TAC[REAL_ABS_DIV; REAL_ABS_NUM; REAL_ABS_ABS] THEN
16111 ASM_SIMP_TAC[REAL_ARITH `abs(&1 + abs x) = &1 + abs x`;
16112 REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &1 + abs x`] THEN
16113 MATCH_MP_TAC(REAL_ARITH
16114 `&0 < e /\ &0 < e * x ==> abs e < e * (&1 + x)`) THEN
16115 ASM_SIMP_TAC[REAL_LT_MUL_EQ] THEN ASM_REAL_ARITH_TAC;
16117 MP_TAC(GEN `A:real^N^N` (SPECL [`A:real^N^N`; `i:num`]
16118 DET_COFACTOR_EXPANSION)) THEN
16119 ASM_SIMP_TAC[] THEN DISCH_THEN(K ALL_TAC) THEN
16120 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN
16121 ASM_SIMP_TAC[GSYM SUM_SUB_NUMSEG; LAMBDA_BETA] THEN
16122 REWRITE_TAC[REAL_ARITH `p - A$i$j * cofactor A$i$j =
16123 --(A$i$j * cofactor A$i$j - p)`] THEN
16124 REWRITE_TAC[SUM_NEG; REAL_ARITH
16125 `a * b - c * d:real = b * (a - c) + c * (b - d)`] THEN
16126 REWRITE_TAC[SUM_ADD_NUMSEG; REAL_NEG_ADD] THEN MATCH_MP_TAC(REAL_ARITH
16127 `b = &0 /\ &0 < a ==> &0 < a + b`) THEN
16129 [REWRITE_TAC[REAL_NEG_EQ_0] THEN
16130 MATCH_MP_TAC SUM_EQ_0 THEN X_GEN_TAC `m:num` THEN
16131 REWRITE_TAC[IN_NUMSEG; REAL_ENTIRE] THEN STRIP_TAC THEN DISJ2_TAC THEN
16132 REWRITE_TAC[REAL_SUB_0] THEN REWRITE_TAC[cofactor] THEN
16133 ASM_SIMP_TAC[LAMBDA_BETA] THEN AP_TERM_TAC THEN
16134 ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN ASM_MESON_TAC[];
16136 REWRITE_TAC[GSYM SUM_NEG; GSYM REAL_MUL_RNEG] THEN
16137 MATCH_MP_TAC SUM_POS_LT THEN REWRITE_TAC[FINITE_NUMSEG] THEN
16138 MATCH_MP_TAC(MESON[REAL_LT_IMP_LE; REAL_LE_REFL]
16139 `(?i. P i /\ &0 < f i /\ (!j. P j /\ ~(j = i) ==> f j = &0))
16140 ==> (!j. P j ==> &0 <= f j) /\ (?j. P j /\ &0 < f j)`) THEN
16141 EXISTS_TAC `j:num` THEN ASM_REWRITE_TAC[FINITE_NUMSEG] THEN
16142 ASM_SIMP_TAC[REAL_SUB_REFL; REAL_MUL_RZERO; IN_NUMSEG; REAL_NEG_0] THEN
16143 REWRITE_TAC[REAL_ARITH `a - (a + e):real = --e`;
16144 REAL_ARITH `a - (a - e):real = e`; REAL_NEG_NEG] THEN
16145 ASM_SIMP_TAC[REAL_LT_MUL_EQ] THEN
16146 REWRITE_TAC[REAL_ARITH `&0 < a * --b <=> &0 < --a * b`] THEN
16147 ASM_SIMP_TAC[REAL_LT_MUL_EQ; REAL_NEG_GT0] THEN
16148 MATCH_MP_TAC REAL_LT_DIV THEN ASM_REAL_ARITH_TAC]);;
16150 (* ------------------------------------------------------------------------- *)
16151 (* Infinite sums of vectors. Allow general starting point (and more). *)
16152 (* ------------------------------------------------------------------------- *)
16154 parse_as_infix("sums",(12,"right"));;
16156 let sums = new_definition
16157 `(f sums l) s = ((\n. vsum(s INTER (0..n)) f) --> l) sequentially`;;
16159 let infsum = new_definition
16160 `infsum s f = @l. (f sums l) s`;;
16162 let summable = new_definition
16163 `summable s f = ?l. (f sums l) s`;;
16165 let SUMS_SUMMABLE = prove
16166 (`!f l s. (f sums l) s ==> summable s f`,
16167 REWRITE_TAC[summable] THEN MESON_TAC[]);;
16169 let SUMS_INFSUM = prove
16170 (`!f s. (f sums (infsum s f)) s <=> summable s f`,
16171 REWRITE_TAC[infsum; summable] THEN MESON_TAC[]);;
16173 let SUMS_LIM = prove
16174 (`!f:num->real^N s.
16175 (f sums lim sequentially (\n. vsum (s INTER (0..n)) f)) s
16177 GEN_TAC THEN GEN_TAC THEN EQ_TAC THENL [MESON_TAC[summable];
16178 REWRITE_TAC[summable; sums] THEN STRIP_TAC THEN REWRITE_TAC[lim] THEN
16179 ASM_MESON_TAC[]]);;
16181 let FINITE_INTER_NUMSEG = prove
16182 (`!s m n. FINITE(s INTER (m..n))`,
16183 MESON_TAC[FINITE_SUBSET; FINITE_NUMSEG; INTER_SUBSET]);;
16185 let SERIES_FROM = prove
16186 (`!f l k. (f sums l) (from k) = ((\n. vsum(k..n) f) --> l) sequentially`,
16187 REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN
16188 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
16189 AP_THM_TAC THEN AP_TERM_TAC THEN
16190 REWRITE_TAC[EXTENSION; numseg; from; IN_ELIM_THM; IN_INTER] THEN ARITH_TAC);;
16192 let SERIES_UNIQUE = prove
16193 (`!f:num->real^N l l' s. (f sums l) s /\ (f sums l') s ==> (l = l')`,
16194 REWRITE_TAC[sums] THEN MESON_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; LIM_UNIQUE]);;
16196 let INFSUM_UNIQUE = prove
16197 (`!f:num->real^N l s. (f sums l) s ==> infsum s f = l`,
16198 MESON_TAC[SERIES_UNIQUE; SUMS_INFSUM; summable]);;
16200 let SERIES_TERMS_TOZERO = prove
16201 (`!f l n. (f sums l) (from n) ==> (f --> vec 0) sequentially`,
16202 REPEAT GEN_TAC THEN SIMP_TAC[sums; LIM_SEQUENTIALLY; FROM_INTER_NUMSEG] THEN
16203 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
16204 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
16205 ASM_REWRITE_TAC[REAL_HALF] THEN DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
16206 EXISTS_TAC `N + n + 1` THEN X_GEN_TAC `m:num` THEN DISCH_TAC THEN
16207 FIRST_X_ASSUM(fun th ->
16208 MP_TAC(SPEC `m - 1` th) THEN MP_TAC(SPEC `m:num` th)) THEN
16209 SUBGOAL_THEN `0 < m /\ n <= m` (fun th -> SIMP_TAC[VSUM_CLAUSES_RIGHT; th])
16210 THENL [ASM_ARITH_TAC; ALL_TAC] THEN
16211 REPEAT(ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_TAC]) THEN
16212 REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC);;
16214 let SERIES_FINITE = prove
16215 (`!f s. FINITE s ==> (f sums (vsum s f)) s`,
16216 REPEAT GEN_TAC THEN REWRITE_TAC[num_FINITE; LEFT_IMP_EXISTS_THM] THEN
16217 X_GEN_TAC `n:num` THEN REWRITE_TAC[sums; LIM_SEQUENTIALLY] THEN
16218 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN EXISTS_TAC `n:num` THEN
16219 X_GEN_TAC `m:num` THEN DISCH_TAC THEN
16220 SUBGOAL_THEN `s INTER (0..m) = s`
16221 (fun th -> ASM_REWRITE_TAC[th; DIST_REFL]) THEN
16222 REWRITE_TAC[EXTENSION; IN_INTER; IN_NUMSEG; LE_0] THEN
16223 ASM_MESON_TAC[LE_TRANS]);;
16225 let SERIES_LINEAR = prove
16226 (`!f h l s. (f sums l) s /\ linear h ==> ((\n. h(f n)) sums h l) s`,
16227 SIMP_TAC[sums; LIM_LINEAR; FINITE_INTER; FINITE_NUMSEG;
16228 GSYM(REWRITE_RULE[o_DEF] LINEAR_VSUM)]);;
16230 let SERIES_0 = prove
16231 (`!s. ((\n. vec 0) sums (vec 0)) s`,
16232 REWRITE_TAC[sums; VSUM_0; LIM_CONST]);;
16234 let SERIES_ADD = prove
16236 (x sums x0) s /\ (y sums y0) s ==> ((\n. x n + y n) sums (x0 + y0)) s`,
16237 SIMP_TAC[sums; FINITE_INTER_NUMSEG; VSUM_ADD; LIM_ADD]);;
16239 let SERIES_SUB = prove
16241 (x sums x0) s /\ (y sums y0) s ==> ((\n. x n - y n) sums (x0 - y0)) s`,
16242 SIMP_TAC[sums; FINITE_INTER_NUMSEG; VSUM_SUB; LIM_SUB]);;
16244 let SERIES_CMUL = prove
16245 (`!x x0 c s. (x sums x0) s ==> ((\n. c % x n) sums (c % x0)) s`,
16246 SIMP_TAC[sums; FINITE_INTER_NUMSEG; VSUM_LMUL; LIM_CMUL]);;
16248 let SERIES_NEG = prove
16249 (`!x x0 s. (x sums x0) s ==> ((\n. --(x n)) sums (--x0)) s`,
16250 SIMP_TAC[sums; FINITE_INTER_NUMSEG; VSUM_NEG; LIM_NEG]);;
16252 let SUMS_IFF = prove
16253 (`!f g k. (!x. x IN k ==> f x = g x) ==> ((f sums l) k <=> (g sums l) k)`,
16254 REPEAT STRIP_TAC THEN REWRITE_TAC[sums] THEN
16255 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
16256 MATCH_MP_TAC VSUM_EQ THEN ASM_SIMP_TAC[IN_INTER]);;
16258 let SUMS_EQ = prove
16259 (`!f g k. (!x. x IN k ==> f x = g x) /\ (f sums l) k ==> (g sums l) k`,
16260 MESON_TAC[SUMS_IFF]);;
16263 (`!f:num->real^N s. (!n. n IN s ==> f n = vec 0) ==> (f sums vec 0) s`,
16264 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMS_EQ THEN
16265 EXISTS_TAC `\n:num. vec 0:real^N` THEN ASM_SIMP_TAC[SERIES_0]);;
16267 let SERIES_FINITE_SUPPORT = prove
16268 (`!f:num->real^N s k.
16269 FINITE (s INTER k) /\ (!x. x IN k /\ ~(x IN s) ==> f x = vec 0)
16270 ==> (f sums vsum (s INTER k) f) k`,
16271 REWRITE_TAC[sums; LIM_SEQUENTIALLY] THEN REPEAT STRIP_TAC THEN
16272 FIRST_ASSUM(MP_TAC o ISPEC `\x:num. x` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN
16273 REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
16274 STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
16275 SUBGOAL_THEN `vsum (k INTER (0..n)) (f:num->real^N) = vsum(s INTER k) f`
16276 (fun th -> ASM_REWRITE_TAC[DIST_REFL; th]) THEN
16277 MATCH_MP_TAC VSUM_SUPERSET THEN
16278 ASM_SIMP_TAC[SUBSET; IN_INTER; IN_NUMSEG; LE_0] THEN
16279 ASM_MESON_TAC[IN_INTER; LE_TRANS]);;
16281 let SERIES_COMPONENT = prove
16282 (`!f s l:real^N k. (f sums l) s /\ 1 <= k /\ k <= dimindex(:N)
16283 ==> ((\i. lift(f(i)$k)) sums lift(l$k)) s`,
16284 REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN STRIP_TAC THEN
16285 ONCE_REWRITE_TAC[GSYM o_DEF] THEN
16286 ASM_SIMP_TAC[GSYM LIFT_SUM; GSYM VSUM_COMPONENT;
16287 FINITE_INTER; FINITE_NUMSEG] THEN
16288 ASM_SIMP_TAC[o_DEF; LIM_COMPONENT]);;
16290 let SERIES_DIFFS = prove
16291 (`!f:num->real^N k.
16292 (f --> vec 0) sequentially
16293 ==> ((\n. f(n) - f(n + 1)) sums f(k)) (from k)`,
16294 REWRITE_TAC[sums; FROM_INTER_NUMSEG; VSUM_DIFFS] THEN
16295 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
16296 EXISTS_TAC `\n. (f:num->real^N) k - f(n + 1)` THEN CONJ_TAC THENL
16297 [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `k:num` THEN
16299 GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_SUB_RZERO] THEN
16300 MATCH_MP_TAC LIM_SUB THEN REWRITE_TAC[LIM_CONST] THEN
16301 MATCH_MP_TAC SEQ_OFFSET THEN ASM_REWRITE_TAC[]]);;
16303 let SERIES_TRIVIAL = prove
16304 (`!f. (f sums vec 0) {}`,
16305 REWRITE_TAC[sums; INTER_EMPTY; VSUM_CLAUSES; LIM_CONST]);;
16307 let SERIES_RESTRICT = prove
16309 ((\n. if n IN k then f(n) else vec 0) sums l) (:num) <=>
16311 REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN
16312 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
16313 REWRITE_TAC[FUN_EQ_THM; INTER_UNIV] THEN GEN_TAC THEN
16314 MATCH_MP_TAC(MESON[] `vsum s f = vsum t f /\ vsum t f = vsum t g
16315 ==> vsum s f = vsum t g`) THEN
16317 [MATCH_MP_TAC VSUM_SUPERSET THEN SET_TAC[];
16318 MATCH_MP_TAC VSUM_EQ THEN SIMP_TAC[IN_INTER]]);;
16320 let SERIES_VSUM = prove
16321 (`!f l k s. FINITE s /\ s SUBSET k /\ (!x. ~(x IN s) ==> f x = vec 0) /\
16322 vsum s f = l ==> (f sums l) k`,
16323 REPEAT STRIP_TAC THEN EXPAND_TAC "l" THEN
16324 SUBGOAL_THEN `s INTER k = s:num->bool` ASSUME_TAC THENL
16325 [ASM SET_TAC []; ASM_MESON_TAC [SERIES_FINITE_SUPPORT]]);;
16327 let SUMS_REINDEX = prove
16329 ((\x. a(x + k)) sums l) (from n) <=> (a sums l) (from(n + k))`,
16330 REPEAT GEN_TAC THEN REWRITE_TAC[sums; FROM_INTER_NUMSEG] THEN
16331 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM VSUM_OFFSET] THEN
16332 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
16333 ASM_MESON_TAC[ARITH_RULE `N + k:num <= n ==> n = (n - k) + k /\ N <= n - k`;
16334 ARITH_RULE `N + k:num <= n ==> N <= n + k`]);;
16336 let SUMS_REINDEX_GEN = prove
16338 ((\x. a(x + k)) sums l) s <=> (a sums l) (IMAGE (\i. i + k) s)`,
16339 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN
16342 `\i. if i IN IMAGE (\i. i + k) s then (a:num->real^N) i else vec 0`;
16343 `l:real^N`; `0`] SUMS_REINDEX) THEN
16344 REWRITE_TAC[FROM_0] THEN
16345 SIMP_TAC[EQ_ADD_RCANCEL; SET_RULE
16346 `(!x y:num. x + k = y + k <=> x = y)
16347 ==> ((x + k) IN IMAGE (\i. i + k) s <=> x IN s)`] THEN
16348 DISCH_THEN SUBST1_TAC THEN
16349 GEN_REWRITE_TAC LAND_CONV [GSYM SERIES_RESTRICT] THEN
16350 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
16351 REWRITE_TAC[FUN_EQ_THM; IN_FROM; ADD_CLAUSES] THEN
16352 SUBGOAL_THEN `!x:num. x IN IMAGE (\i. i + k) s ==> k <= x` MP_TAC THENL
16353 [REWRITE_TAC[FORALL_IN_IMAGE] THEN ARITH_TAC; SET_TAC[]]);;
16355 (* ------------------------------------------------------------------------- *)
16356 (* Similar combining theorems just for summability. *)
16357 (* ------------------------------------------------------------------------- *)
16359 let SUMMABLE_LINEAR = prove
16360 (`!f h s. summable s f /\ linear h ==> summable s (\n. h(f n))`,
16361 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_LINEAR]);;
16363 let SUMMABLE_0 = prove
16364 (`!s. summable s (\n. vec 0)`,
16365 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_0]);;
16367 let SUMMABLE_ADD = prove
16368 (`!x y s. summable s x /\ summable s y ==> summable s (\n. x n + y n)`,
16369 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_ADD]);;
16371 let SUMMABLE_SUB = prove
16372 (`!x y s. summable s x /\ summable s y ==> summable s (\n. x n - y n)`,
16373 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_SUB]);;
16375 let SUMMABLE_CMUL = prove
16376 (`!s x c. summable s x ==> summable s (\n. c % x n)`,
16377 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_CMUL]);;
16379 let SUMMABLE_NEG = prove
16380 (`!x s. summable s x ==> summable s (\n. --(x n))`,
16381 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_NEG]);;
16383 let SUMMABLE_IFF = prove
16384 (`!f g k. (!x. x IN k ==> f x = g x) ==> (summable k f <=> summable k g)`,
16385 REWRITE_TAC[summable] THEN MESON_TAC[SUMS_IFF]);;
16387 let SUMMABLE_EQ = prove
16388 (`!f g k. (!x. x IN k ==> f x = g x) /\ summable k f ==> summable k g`,
16389 REWRITE_TAC[summable] THEN MESON_TAC[SUMS_EQ]);;
16391 let SUMMABLE_COMPONENT = prove
16392 (`!f:num->real^N s k.
16393 summable s f /\ 1 <= k /\ k <= dimindex(:N)
16394 ==> summable s (\i. lift(f(i)$k))`,
16395 REPEAT STRIP_TAC THEN
16396 FIRST_X_ASSUM(X_CHOOSE_TAC `l:real^N` o REWRITE_RULE[summable]) THEN
16397 REWRITE_TAC[summable] THEN EXISTS_TAC `lift((l:real^N)$k)` THEN
16398 ASM_SIMP_TAC[SERIES_COMPONENT]);;
16400 let SERIES_SUBSET = prove
16403 ((\i. if i IN s then x i else vec 0) sums l) t
16405 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
16406 REWRITE_TAC[sums] THEN MATCH_MP_TAC EQ_IMP THEN
16407 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
16408 ASM_SIMP_TAC[GSYM VSUM_RESTRICT_SET; FINITE_INTER_NUMSEG] THEN
16409 AP_THM_TAC THEN AP_TERM_TAC THEN POP_ASSUM MP_TAC THEN SET_TAC[]);;
16411 let SUMMABLE_SUBSET = prove
16414 summable t (\i. if i IN s then x i else vec 0)
16416 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_SUBSET]);;
16418 let SUMMABLE_TRIVIAL = prove
16419 (`!f:num->real^N. summable {} f`,
16420 GEN_TAC THEN REWRITE_TAC[summable] THEN EXISTS_TAC `vec 0:real^N` THEN
16421 REWRITE_TAC[SERIES_TRIVIAL]);;
16423 let SUMMABLE_RESTRICT = prove
16424 (`!f:num->real^N k.
16425 summable (:num) (\n. if n IN k then f(n) else vec 0) <=>
16427 REWRITE_TAC[summable; SERIES_RESTRICT]);;
16429 let SUMS_FINITE_DIFF = prove
16430 (`!f:num->real^N t s l.
16431 t SUBSET s /\ FINITE t /\ (f sums l) s
16432 ==> (f sums (l - vsum t f)) (s DIFF t)`,
16433 REPEAT GEN_TAC THEN
16434 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
16435 FIRST_ASSUM(MP_TAC o ISPEC `f:num->real^N` o MATCH_MP SERIES_FINITE) THEN
16436 ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN
16437 REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
16438 DISCH_THEN(MP_TAC o MATCH_MP SERIES_SUB) THEN
16439 MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
16440 REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `x:num` THEN REWRITE_TAC[IN_DIFF] THEN
16441 FIRST_ASSUM(MP_TAC o SPEC `x:num` o GEN_REWRITE_RULE I [SUBSET]) THEN
16442 MAP_EVERY ASM_CASES_TAC [`(x:num) IN s`; `(x:num) IN t`] THEN
16443 ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);;
16445 let SUMS_FINITE_UNION = prove
16446 (`!f:num->real^N s t l.
16447 FINITE t /\ (f sums l) s
16448 ==> (f sums (l + vsum (t DIFF s) f)) (s UNION t)`,
16449 REPEAT GEN_TAC THEN
16450 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
16451 FIRST_ASSUM(MP_TAC o SPEC `s:num->bool` o MATCH_MP FINITE_DIFF) THEN
16452 DISCH_THEN(MP_TAC o ISPEC `f:num->real^N` o MATCH_MP SERIES_FINITE) THEN
16453 ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN
16454 REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
16455 DISCH_THEN(MP_TAC o MATCH_MP SERIES_ADD) THEN
16456 MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
16457 REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `x:num` THEN
16458 REWRITE_TAC[IN_DIFF; IN_UNION] THEN
16459 MAP_EVERY ASM_CASES_TAC [`(x:num) IN s`; `(x:num) IN t`] THEN
16460 ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);;
16462 let SUMS_OFFSET = prove
16464 (f sums l) (from m) /\ 0 < n /\ m <= n
16465 ==> (f sums l - vsum (m..n - 1) f) (from n)`,
16466 REPEAT STRIP_TAC THEN
16467 SUBGOAL_THEN `from n = from m DIFF (m..(n-1))` SUBST1_TAC THENL
16468 [REWRITE_TAC[EXTENSION; IN_FROM; IN_DIFF; IN_NUMSEG] THEN ASM_ARITH_TAC;
16469 MATCH_MP_TAC SUMS_FINITE_DIFF THEN ASM_REWRITE_TAC[FINITE_NUMSEG] THEN
16470 SIMP_TAC[SUBSET; IN_FROM; IN_NUMSEG]]);;
16472 let SUMS_OFFSET_REV = prove
16473 (`!f:num->real^N l m n.
16474 (f sums l) (from m) /\ 0 < m /\ n <= m
16476 ==> (f sums (l + vsum(n..m-1) f)) (from n)`,
16477 REPEAT STRIP_TAC THEN
16478 MP_TAC(ISPECL [`f:num->real^N`; `from m`; `n..m-1`; `l:real^N`]
16479 SUMS_FINITE_UNION) THEN
16480 ASM_REWRITE_TAC[FINITE_NUMSEG] THEN MATCH_MP_TAC EQ_IMP THEN
16481 BINOP_TAC THENL [AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC; ALL_TAC] THEN
16482 REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNION; IN_FROM; IN_NUMSEG] THEN
16485 let SUMMABLE_REINDEX = prove
16486 (`!k a n. summable (from n) (\x. a (x + k)) <=> summable (from(n + k)) a`,
16487 REWRITE_TAC[summable; GSYM SUMS_REINDEX]);;
16489 let SERIES_DROP_LE = prove
16491 (f sums a) s /\ (g sums b) s /\
16492 (!x. x IN s ==> drop(f x) <= drop(g x))
16493 ==> drop a <= drop b`,
16494 REWRITE_TAC[sums] THEN REPEAT STRIP_TAC THEN
16495 MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LE) THEN
16496 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; TRIVIAL_LIMIT_SEQUENTIALLY] THEN
16497 EXISTS_TAC `\n. vsum (s INTER (0..n)) (f:num->real^1)` THEN
16498 EXISTS_TAC `\n. vsum (s INTER (0..n)) (g:num->real^1)` THEN
16499 ASM_REWRITE_TAC[DROP_VSUM] THEN EXISTS_TAC `0` THEN REPEAT STRIP_TAC THEN
16500 MATCH_MP_TAC SUM_LE THEN
16501 ASM_SIMP_TAC[FINITE_INTER; FINITE_NUMSEG; o_THM; IN_INTER; IN_NUMSEG]);;
16503 let SERIES_DROP_POS = prove
16505 (f sums a) s /\ (!x. x IN s ==> &0 <= drop(f x))
16507 REPEAT STRIP_TAC THEN
16508 MP_TAC(ISPECL [`(\n. vec 0):num->real^1`; `f:num->real^1`; `s:num->bool`;
16509 `vec 0:real^1`; `a:real^1`] SERIES_DROP_LE) THEN
16510 ASM_SIMP_TAC[SUMS_0; DROP_VEC]);;
16512 let SERIES_BOUND = prove
16513 (`!f:num->real^N g s a b.
16514 (f sums a) s /\ ((lift o g) sums (lift b)) s /\
16515 (!i. i IN s ==> norm(f i) <= g i)
16517 REWRITE_TAC[sums] THEN REPEAT STRIP_TAC THEN
16518 MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN
16519 EXISTS_TAC `\n. vsum (s INTER (0..n)) (f:num->real^N)` THEN
16520 ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
16521 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `0` THEN
16522 X_GEN_TAC `m:num` THEN DISCH_TAC THEN
16523 TRANS_TAC REAL_LE_TRANS `sum (s INTER (0..m)) g` THEN CONJ_TAC THEN
16524 ASM_SIMP_TAC[VSUM_NORM_LE; IN_INTER; FINITE_NUMSEG; FINITE_INTER] THEN
16525 RULE_ASSUM_TAC(REWRITE_RULE[GSYM sums]) THEN
16526 UNDISCH_TAC `((lift o g) sums lift b) s` THEN
16527 GEN_REWRITE_TAC LAND_CONV [GSYM SERIES_RESTRICT] THEN
16528 REWRITE_TAC[GSYM FROM_0] THEN DISCH_THEN(MP_TAC o SPEC `m + 1` o MATCH_MP
16529 (ONCE_REWRITE_RULE[IMP_CONJ] SUMS_OFFSET)) THEN
16530 ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
16531 REWRITE_TAC[ARITH_RULE `0 < m + 1`; o_DEF; ADD_SUB] THEN
16532 REWRITE_TAC[GSYM VSUM_RESTRICT_SET] THEN
16533 REWRITE_TAC[VSUM_REAL; o_DEF; LIFT_DROP; ETA_AX] THEN
16534 DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] SERIES_DROP_POS)) THEN
16535 REWRITE_TAC[DROP_SUB; LIFT_DROP; ONCE_REWRITE_RULE[INTER_COMM] (GSYM INTER);
16537 DISCH_THEN MATCH_MP_TAC THEN REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
16538 ASM_SIMP_TAC[LIFT_DROP; DROP_VEC; REAL_LE_REFL] THEN
16539 ASM_MESON_TAC[NORM_ARITH `norm(x:real^N) <= y ==> &0 <= y`]);;
16541 (* ------------------------------------------------------------------------- *)
16542 (* Similar combining theorems for infsum. *)
16543 (* ------------------------------------------------------------------------- *)
16545 let INFSUM_LINEAR = prove
16546 (`!f h s. summable s f /\ linear h
16547 ==> infsum s (\n. h(f n)) = h(infsum s f)`,
16548 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
16549 MATCH_MP_TAC SERIES_LINEAR THEN ASM_REWRITE_TAC[SUMS_INFSUM]);;
16551 let INFSUM_0 = prove
16552 (`infsum s (\i. vec 0) = vec 0`,
16553 MATCH_MP_TAC INFSUM_UNIQUE THEN REWRITE_TAC[SERIES_0]);;
16555 let INFSUM_ADD = prove
16556 (`!x y s. summable s x /\ summable s y
16557 ==> infsum s (\i. x i + y i) = infsum s x + infsum s y`,
16558 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
16559 MATCH_MP_TAC SERIES_ADD THEN ASM_REWRITE_TAC[SUMS_INFSUM]);;
16561 let INFSUM_SUB = prove
16562 (`!x y s. summable s x /\ summable s y
16563 ==> infsum s (\i. x i - y i) = infsum s x - infsum s y`,
16564 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
16565 MATCH_MP_TAC SERIES_SUB THEN ASM_REWRITE_TAC[SUMS_INFSUM]);;
16567 let INFSUM_CMUL = prove
16568 (`!s x c. summable s x ==> infsum s (\n. c % x n) = c % infsum s x`,
16569 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
16570 MATCH_MP_TAC SERIES_CMUL THEN ASM_REWRITE_TAC[SUMS_INFSUM]);;
16572 let INFSUM_NEG = prove
16573 (`!s x. summable s x ==> infsum s (\n. --(x n)) = --(infsum s x)`,
16574 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
16575 MATCH_MP_TAC SERIES_NEG THEN ASM_REWRITE_TAC[SUMS_INFSUM]);;
16577 let INFSUM_EQ = prove
16578 (`!f g k. summable k f /\ summable k g /\ (!x. x IN k ==> f x = g x)
16579 ==> infsum k f = infsum k g`,
16580 REPEAT STRIP_TAC THEN REWRITE_TAC[infsum] THEN
16581 AP_TERM_TAC THEN ABS_TAC THEN ASM_MESON_TAC[SUMS_EQ; SUMS_INFSUM]);;
16583 let INFSUM_RESTRICT = prove
16584 (`!k a:num->real^N.
16585 infsum (:num) (\n. if n IN k then a n else vec 0) = infsum k a`,
16586 REPEAT GEN_TAC THEN
16587 MP_TAC(ISPECL [`a:num->real^N`; `k:num->bool`] SUMMABLE_RESTRICT) THEN
16588 ASM_CASES_TAC `summable k (a:num->real^N)` THEN ASM_REWRITE_TAC[] THEN
16590 [MATCH_MP_TAC INFSUM_UNIQUE THEN
16591 ASM_REWRITE_TAC[SERIES_RESTRICT; SUMS_INFSUM];
16592 RULE_ASSUM_TAC(REWRITE_RULE[summable; NOT_EXISTS_THM]) THEN
16593 ASM_REWRITE_TAC[infsum]]);;
16595 let PARTIAL_SUMS_COMPONENT_LE_INFSUM = prove
16596 (`!f:num->real^N s k n.
16597 1 <= k /\ k <= dimindex(:N) /\
16598 (!i. i IN s ==> &0 <= (f i)$k) /\
16600 ==> (vsum (s INTER (0..n)) f)$k <= (infsum s f)$k`,
16601 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUMS_INFSUM] THEN
16602 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
16603 REWRITE_TAC[sums; LIM_SEQUENTIALLY] THEN DISCH_TAC THEN
16604 REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
16605 FIRST_X_ASSUM(MP_TAC o SPEC
16606 `vsum (s INTER (0..n)) (f:num->real^N)$k - (infsum s f)$k`) THEN
16607 ASM_REWRITE_TAC[REAL_SUB_LT] THEN
16608 DISCH_THEN(X_CHOOSE_THEN `N:num` (MP_TAC o SPEC `N + n:num`)) THEN
16609 REWRITE_TAC[LE_ADD; REAL_NOT_LT; dist] THEN
16610 MATCH_MP_TAC REAL_LE_TRANS THEN
16611 EXISTS_TAC `abs((vsum (s INTER (0..N + n)) f - infsum s f:real^N)$k)` THEN
16612 ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN REWRITE_TAC[VECTOR_SUB_COMPONENT] THEN
16613 MATCH_MP_TAC(REAL_ARITH `s < a /\ a <= b ==> a - s <= abs(b - s)`) THEN
16614 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN
16615 SIMP_TAC[NUMSEG_ADD_SPLIT; LE_0; UNION_OVER_INTER] THEN
16616 W(MP_TAC o PART_MATCH (lhs o rand) VSUM_UNION o lhand o rand o snd) THEN
16618 [SIMP_TAC[FINITE_INTER; FINITE_NUMSEG; DISJOINT; EXTENSION] THEN
16619 REWRITE_TAC[IN_INTER; NOT_IN_EMPTY; IN_NUMSEG] THEN ARITH_TAC;
16620 DISCH_THEN SUBST1_TAC THEN
16621 REWRITE_TAC[REAL_LE_ADDR; VECTOR_ADD_COMPONENT] THEN
16622 ASM_SIMP_TAC[VSUM_COMPONENT] THEN MATCH_MP_TAC SUM_POS_LE THEN
16623 ASM_SIMP_TAC[FINITE_INTER; IN_INTER; FINITE_NUMSEG]]);;
16625 let PARTIAL_SUMS_DROP_LE_INFSUM = prove
16627 (!i. i IN s ==> &0 <= drop(f i)) /\
16629 ==> drop(vsum (s INTER (0..n)) f) <= drop(infsum s f)`,
16630 REPEAT STRIP_TAC THEN REWRITE_TAC[drop] THEN
16631 MATCH_MP_TAC PARTIAL_SUMS_COMPONENT_LE_INFSUM THEN
16632 ASM_REWRITE_TAC[DIMINDEX_1; LE_REFL; GSYM drop]);;
16634 (* ------------------------------------------------------------------------- *)
16635 (* Cauchy criterion for series. *)
16636 (* ------------------------------------------------------------------------- *)
16638 let SEQUENCE_CAUCHY_WLOG = prove
16639 (`!P s. (!m n:num. P m /\ P n ==> dist(s m,s n) < e) <=>
16640 (!m n. P m /\ P n /\ m <= n ==> dist(s m,s n) < e)`,
16641 MESON_TAC[DIST_SYM; LE_CASES]);;
16643 let VSUM_DIFF_LEMMA = prove
16644 (`!f:num->real^N k m n.
16646 ==> vsum(k INTER (0..n)) f - vsum(k INTER (0..m)) f =
16647 vsum(k INTER (m+1..n)) f`,
16648 REPEAT STRIP_TAC THEN
16649 MP_TAC(ISPECL [`f:num->real^N`; `k INTER (0..n)`; `k INTER (0..m)`]
16652 [SIMP_TAC[FINITE_INTER; FINITE_NUMSEG] THEN MATCH_MP_TAC
16653 (SET_RULE `s SUBSET t ==> (u INTER s SUBSET u INTER t)`) THEN
16654 REWRITE_TAC[SUBSET; IN_NUMSEG] THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
16655 DISCH_THEN(SUBST1_TAC o SYM) THEN AP_THM_TAC THEN AP_TERM_TAC THEN
16656 REWRITE_TAC[SET_RULE
16657 `(k INTER s) DIFF (k INTER t) = k INTER (s DIFF t)`] THEN
16658 AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_DIFF; IN_NUMSEG] THEN
16659 POP_ASSUM MP_TAC THEN ARITH_TAC]);;
16661 let NORM_VSUM_TRIVIAL_LEMMA = prove
16662 (`!e. &0 < e ==> (P ==> norm(vsum(s INTER (m..n)) f) < e <=>
16663 P ==> n < m \/ norm(vsum(s INTER (m..n)) f) < e)`,
16664 REPEAT STRIP_TAC THEN ASM_CASES_TAC `n:num < m` THEN ASM_REWRITE_TAC[] THEN
16665 FIRST_X_ASSUM(SUBST1_TAC o GEN_REWRITE_RULE I [GSYM NUMSEG_EMPTY]) THEN
16666 ASM_REWRITE_TAC[VSUM_CLAUSES; NORM_0; INTER_EMPTY]);;
16668 let SERIES_CAUCHY = prove
16669 (`!f s. (?l. (f sums l) s) =
16671 ==> ?N. !m n. m >= N
16672 ==> norm(vsum(s INTER (m..n)) f) < e`,
16673 REPEAT GEN_TAC THEN REWRITE_TAC[sums; CONVERGENT_EQ_CAUCHY; cauchy] THEN
16674 REWRITE_TAC[SEQUENCE_CAUCHY_WLOG] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
16675 SIMP_TAC[dist; VSUM_DIFF_LEMMA; NORM_VSUM_TRIVIAL_LEMMA] THEN
16676 REWRITE_TAC[GE; TAUT `a ==> b \/ c <=> a /\ ~b ==> c`] THEN
16677 REWRITE_TAC[NOT_LT; ARITH_RULE
16678 `(N <= m /\ N <= n /\ m <= n) /\ m + 1 <= n <=>
16679 N + 1 <= m + 1 /\ m + 1 <= n`] THEN
16680 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN
16681 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
16682 EQ_TAC THEN DISCH_THEN(X_CHOOSE_TAC `N:num`) THENL
16683 [EXISTS_TAC `N + 1`; EXISTS_TAC `N:num`] THEN
16684 REPEAT STRIP_TAC THEN
16685 ASM_SIMP_TAC[ARITH_RULE `N + 1 <= m + 1 ==> N <= m + 1`] THEN
16686 FIRST_X_ASSUM(MP_TAC o SPECL [`m - 1`; `n:num`]) THEN
16687 SUBGOAL_THEN `m - 1 + 1 = m` SUBST_ALL_TAC THENL
16688 [ALL_TAC; ANTS_TAC THEN SIMP_TAC[]] THEN
16691 let SUMMABLE_CAUCHY = prove
16692 (`!f s. summable s f <=>
16694 ==> ?N. !m n. m >= N ==> norm(vsum(s INTER (m..n)) f) < e`,
16695 REWRITE_TAC[summable; GSYM SERIES_CAUCHY]);;
16697 let SUMMABLE_IFF_EVENTUALLY = prove
16698 (`!f g k. (?N. !n. N <= n /\ n IN k ==> f n = g n)
16699 ==> (summable k f <=> summable k g)`,
16700 REWRITE_TAC[summable; SERIES_CAUCHY] THEN REPEAT GEN_TAC THEN
16701 DISCH_THEN(X_CHOOSE_THEN `N0:num` STRIP_ASSUME_TAC) THEN
16702 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN
16703 AP_TERM_TAC THEN EQ_TAC THEN
16704 DISCH_THEN(X_CHOOSE_THEN `N1:num`
16705 (fun th -> EXISTS_TAC `N0 + N1:num` THEN MP_TAC th)) THEN
16706 REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
16707 DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
16708 (ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC]) THEN
16709 MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
16710 MATCH_MP_TAC VSUM_EQ THEN ASM_SIMP_TAC[IN_INTER; IN_NUMSEG] THEN
16711 REPEAT STRIP_TAC THENL [ALL_TAC; CONV_TAC SYM_CONV] THEN
16712 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
16715 let SUMMABLE_EQ_EVENTUALLY = prove
16716 (`!f g k. (?N. !n. N <= n /\ n IN k ==> f n = g n) /\ summable k f
16718 MESON_TAC[SUMMABLE_IFF_EVENTUALLY]);;
16720 let SUMMABLE_IFF_COFINITE = prove
16721 (`!f s t. FINITE((s DIFF t) UNION (t DIFF s))
16722 ==> (summable s f <=> summable t f)`,
16723 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM SUMMABLE_RESTRICT] THEN
16724 MATCH_MP_TAC SUMMABLE_IFF_EVENTUALLY THEN
16725 FIRST_ASSUM(MP_TAC o ISPEC `\x:num.x` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN
16726 DISCH_THEN(X_CHOOSE_THEN `N:num` MP_TAC) THEN REWRITE_TAC[IN_UNIV] THEN
16727 DISCH_TAC THEN EXISTS_TAC `N + 1` THEN
16728 REWRITE_TAC[ARITH_RULE `N + 1 <= n <=> ~(n <= N)`] THEN ASM SET_TAC[]);;
16730 let SUMMABLE_EQ_COFINITE = prove
16731 (`!f s t. FINITE((s DIFF t) UNION (t DIFF s)) /\ summable s f
16733 MESON_TAC[SUMMABLE_IFF_COFINITE]);;
16735 let SUMMABLE_FROM_ELSEWHERE = prove
16736 (`!f m n. summable (from m) f ==> summable (from n) f`,
16737 REPEAT GEN_TAC THEN
16738 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] SUMMABLE_EQ_COFINITE) THEN
16739 MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `0..(m+n)` THEN
16740 SIMP_TAC[FINITE_NUMSEG; SUBSET; IN_NUMSEG; IN_UNION; IN_DIFF; IN_FROM] THEN
16743 (* ------------------------------------------------------------------------- *)
16744 (* Uniform vesion of Cauchy criterion. *)
16745 (* ------------------------------------------------------------------------- *)
16747 let SERIES_CAUCHY_UNIFORM = prove
16748 (`!P f:A->num->real^N k.
16750 ==> ?N. !n x. N <= n /\ P x
16751 ==> dist(vsum(k INTER (0..n)) (f x),
16753 (!e. &0 < e ==> ?N. !m n x. N <= m /\ P x
16754 ==> norm(vsum(k INTER (m..n)) (f x)) < e)`,
16755 REPEAT GEN_TAC THEN
16756 REWRITE_TAC[sums; UNIFORMLY_CONVERGENT_EQ_CAUCHY; cauchy] THEN
16757 ONCE_REWRITE_TAC[MESON[]
16758 `(!m n:num y. N <= m /\ N <= n /\ P y ==> Q m n y) <=>
16759 (!y. P y ==> !m n. N <= m /\ N <= n ==> Q m n y)`] THEN
16760 REWRITE_TAC[SEQUENCE_CAUCHY_WLOG] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
16761 SIMP_TAC[dist; VSUM_DIFF_LEMMA; NORM_VSUM_TRIVIAL_LEMMA] THEN
16762 REWRITE_TAC[GE; TAUT `a ==> b \/ c <=> a /\ ~b ==> c`] THEN
16763 REWRITE_TAC[NOT_LT; ARITH_RULE
16764 `(N <= m /\ N <= n /\ m <= n) /\ m + 1 <= n <=>
16765 N + 1 <= m + 1 /\ m + 1 <= n`] THEN
16766 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN
16767 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
16768 EQ_TAC THEN DISCH_THEN(X_CHOOSE_TAC `N:num`) THENL
16769 [EXISTS_TAC `N + 1`; EXISTS_TAC `N:num`] THEN
16770 REPEAT STRIP_TAC THEN
16771 ASM_SIMP_TAC[ARITH_RULE `N + 1 <= m + 1 ==> N <= m + 1`] THEN
16772 FIRST_X_ASSUM(MP_TAC o SPEC `x:A`) THEN ASM_REWRITE_TAC[] THEN
16773 DISCH_THEN(MP_TAC o SPECL [`m - 1`; `n:num`]) THEN
16774 SUBGOAL_THEN `m - 1 + 1 = m` SUBST_ALL_TAC THENL
16775 [ALL_TAC; ANTS_TAC THEN SIMP_TAC[]] THEN
16778 (* ------------------------------------------------------------------------- *)
16779 (* So trivially, terms of a convergent series go to zero. *)
16780 (* ------------------------------------------------------------------------- *)
16782 let SERIES_GOESTOZERO = prove
16783 (`!s x. summable s x
16785 ==> eventually (\n. n IN s ==> norm(x n) < e) sequentially`,
16786 REPEAT GEN_TAC THEN REWRITE_TAC[summable; SERIES_CAUCHY] THEN
16787 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
16788 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
16789 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN
16790 X_GEN_TAC `n:num` THEN REPEAT STRIP_TAC THEN
16791 FIRST_X_ASSUM(MP_TAC o SPECL [`n:num`; `n:num`]) THEN
16792 ASM_SIMP_TAC[NUMSEG_SING; GE; SET_RULE `n IN s ==> s INTER {n} = {n}`] THEN
16793 REWRITE_TAC[VSUM_SING]);;
16795 let SUMMABLE_IMP_TOZERO = prove
16796 (`!f:num->real^N k.
16798 ==> ((\n. if n IN k then f(n) else vec 0) --> vec 0) sequentially`,
16799 REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM SUMMABLE_RESTRICT] THEN
16800 REWRITE_TAC[summable; LIM_SEQUENTIALLY; INTER_UNIV; sums] THEN
16801 DISCH_THEN(X_CHOOSE_TAC `l:real^N`) THEN X_GEN_TAC `e:real` THEN
16802 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
16803 ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN
16804 X_GEN_TAC `N:num` THEN DISCH_TAC THEN EXISTS_TAC `N + 1` THEN
16805 X_GEN_TAC `n:num` THEN DISCH_TAC THEN
16806 FIRST_X_ASSUM(fun th ->
16807 MP_TAC(SPEC `n - 1` th) THEN MP_TAC(SPEC `n:num` th)) THEN
16808 ASM_SIMP_TAC[ARITH_RULE `N + 1 <= n ==> N <= n /\ N <= n - 1`] THEN
16809 ABBREV_TAC `m = n - 1` THEN
16810 SUBGOAL_THEN `n = SUC m` SUBST1_TAC THENL
16811 [ASM_ARITH_TAC; ALL_TAC] THEN
16812 REWRITE_TAC[VSUM_CLAUSES_NUMSEG; LE_0] THEN
16813 REWRITE_TAC[NORM_ARITH `dist(x,vec 0) = norm x`] THEN
16814 COND_CASES_TAC THEN ASM_REWRITE_TAC[NORM_0] THEN CONV_TAC NORM_ARITH);;
16816 let SUMMABLE_IMP_BOUNDED = prove
16817 (`!f:num->real^N k. summable k f ==> bounded (IMAGE f k)`,
16818 REPEAT GEN_TAC THEN
16819 DISCH_THEN(MP_TAC o MATCH_MP SUMMABLE_IMP_TOZERO) THEN
16820 DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN
16821 REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; IN_UNIV] THEN
16822 MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[REAL_LT_IMP_LE; NORM_0]);;
16824 let SUMMABLE_IMP_SUMS_BOUNDED = prove
16825 (`!f:num->real^N k.
16826 summable (from k) f ==> bounded { vsum(k..n) f | n IN (:num) }`,
16827 REWRITE_TAC[summable; sums; LEFT_IMP_EXISTS_THM] THEN REPEAT GEN_TAC THEN
16828 DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN
16829 REWRITE_TAC[FROM_INTER_NUMSEG; SIMPLE_IMAGE]);;
16831 (* ------------------------------------------------------------------------- *)
16832 (* Comparison test. *)
16833 (* ------------------------------------------------------------------------- *)
16835 let SERIES_COMPARISON = prove
16836 (`!f g s. (?l. ((lift o g) sums l) s) /\
16837 (?N. !n. n >= N /\ n IN s ==> norm(f n) <= g n)
16838 ==> ?l:real^N. (f sums l) s`,
16839 REPEAT GEN_TAC THEN REWRITE_TAC[SERIES_CAUCHY] THEN
16840 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC `N1:num`)) THEN
16841 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
16842 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
16843 DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN
16844 EXISTS_TAC `N1 + N2:num` THEN
16845 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN
16846 MATCH_MP_TAC REAL_LET_TRANS THEN
16847 EXISTS_TAC `norm (vsum (s INTER (m .. n)) (lift o g))` THEN CONJ_TAC THENL
16848 [SIMP_TAC[GSYM LIFT_SUM; FINITE_INTER_NUMSEG; NORM_LIFT] THEN
16849 MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs(a)`) THEN
16850 MATCH_MP_TAC VSUM_NORM_LE THEN
16851 REWRITE_TAC[FINITE_INTER_NUMSEG; IN_INTER; IN_NUMSEG] THEN
16852 ASM_MESON_TAC[ARITH_RULE `m >= N1 + N2:num /\ m <= x ==> x >= N1`];
16853 ASM_MESON_TAC[ARITH_RULE `m >= N1 + N2:num ==> m >= N2`]]);;
16855 let SUMMABLE_COMPARISON = prove
16856 (`!f g s. summable s (lift o g) /\
16857 (?N. !n. n >= N /\ n IN s ==> norm(f n) <= g n)
16859 REWRITE_TAC[summable; SERIES_COMPARISON]);;
16861 let SERIES_LIFT_ABSCONV_IMP_CONV = prove
16862 (`!x:num->real^N k. summable k (\n. lift(norm(x n))) ==> summable k x`,
16863 REWRITE_TAC[summable] THEN REPEAT STRIP_TAC THEN
16864 MATCH_MP_TAC SERIES_COMPARISON THEN
16865 EXISTS_TAC `\n:num. norm(x n:real^N)` THEN
16866 ASM_REWRITE_TAC[o_DEF; REAL_LE_REFL] THEN ASM_MESON_TAC[]);;
16868 let SUMMABLE_SUBSET_ABSCONV = prove
16869 (`!x:num->real^N s t.
16870 summable s (\n. lift(norm(x n))) /\ t SUBSET s
16871 ==> summable t (\n. lift(norm(x n)))`,
16872 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMMABLE_SUBSET THEN
16873 EXISTS_TAC `s:num->bool` THEN ASM_REWRITE_TAC[] THEN
16874 REWRITE_TAC[summable] THEN MATCH_MP_TAC SERIES_COMPARISON THEN
16875 EXISTS_TAC `\n:num. norm(x n:real^N)` THEN
16876 ASM_REWRITE_TAC[o_DEF; GSYM summable] THEN
16877 EXISTS_TAC `0` THEN REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
16878 REWRITE_TAC[REAL_LE_REFL; NORM_LIFT; REAL_ABS_NORM; NORM_0; NORM_POS_LE]);;
16880 let SERIES_COMPARISON_BOUND = prove
16881 (`!f:num->real^N g s a.
16882 (g sums a) s /\ (!i. i IN s ==> norm(f i) <= drop(g i))
16883 ==> ?l. (f sums l) s /\ norm(l) <= drop a`,
16884 REPEAT STRIP_TAC THEN
16885 MP_TAC(ISPECL [`f:num->real^N`; `drop o (g:num->real^1)`; `s:num->bool`]
16886 SUMMABLE_COMPARISON) THEN
16887 REWRITE_TAC[o_DEF; LIFT_DROP; GE; ETA_AX; summable] THEN
16888 ANTS_TAC THENL [ASM_MESON_TAC[]; MATCH_MP_TAC MONO_EXISTS] THEN
16889 X_GEN_TAC `l:real^N` THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
16890 RULE_ASSUM_TAC(REWRITE_RULE[FROM_0; INTER_UNIV; sums]) THEN
16891 MATCH_MP_TAC SERIES_BOUND THEN MAP_EVERY EXISTS_TAC
16892 [`f:num->real^N`; `drop o (g:num->real^1)`; `s:num->bool`] THEN
16893 ASM_REWRITE_TAC[sums; o_DEF; LIFT_DROP; ETA_AX]);;
16895 (* ------------------------------------------------------------------------- *)
16896 (* Uniform version of comparison test. *)
16897 (* ------------------------------------------------------------------------- *)
16899 let SERIES_COMPARISON_UNIFORM = prove
16900 (`!f g P s. (?l. ((lift o g) sums l) s) /\
16901 (?N. !n x. N <= n /\ n IN s /\ P x ==> norm(f x n) <= g n)
16904 ==> ?N. !n x. N <= n /\ P x
16905 ==> dist(vsum(s INTER (0..n)) (f x),
16907 REPEAT GEN_TAC THEN SIMP_TAC[GE; SERIES_CAUCHY; SERIES_CAUCHY_UNIFORM] THEN
16908 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC `N1:num`)) THEN
16909 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
16910 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
16911 DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN
16912 EXISTS_TAC `N1 + N2:num` THEN
16913 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`; `x:A`] THEN DISCH_TAC THEN
16914 MATCH_MP_TAC REAL_LET_TRANS THEN
16915 EXISTS_TAC `norm (vsum (s INTER (m .. n)) (lift o g))` THEN CONJ_TAC THENL
16916 [SIMP_TAC[GSYM LIFT_SUM; FINITE_INTER_NUMSEG; NORM_LIFT] THEN
16917 MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs(a)`) THEN
16918 MATCH_MP_TAC VSUM_NORM_LE THEN
16919 REWRITE_TAC[FINITE_INTER_NUMSEG; IN_INTER; IN_NUMSEG] THEN
16920 ASM_MESON_TAC[ARITH_RULE `N1 + N2:num <= m /\ m <= x ==> N1 <= x`];
16921 ASM_MESON_TAC[ARITH_RULE `N1 + N2:num <= m ==> N2 <= m`]]);;
16923 (* ------------------------------------------------------------------------- *)
16925 (* ------------------------------------------------------------------------- *)
16927 let SERIES_RATIO = prove
16930 (!n. n >= N ==> norm(a(SUC n)) <= c * norm(a(n)))
16931 ==> ?l:real^N. (a sums l) s`,
16932 REWRITE_TAC[GE] THEN REPEAT STRIP_TAC THEN
16933 MATCH_MP_TAC SERIES_COMPARISON THEN
16934 DISJ_CASES_TAC(REAL_ARITH `c <= &0 \/ &0 < c`) THENL
16935 [EXISTS_TAC `\n:num. &0` THEN REWRITE_TAC[o_DEF; LIFT_NUM] THEN
16936 CONJ_TAC THENL [MESON_TAC[SERIES_0]; ALL_TAC] THEN
16937 EXISTS_TAC `N + 1` THEN REWRITE_TAC[GE] THEN REPEAT STRIP_TAC THEN
16938 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `c * norm(a(n - 1):real^N)` THEN
16940 [ASM_MESON_TAC[ARITH_RULE `N + 1 <= n ==> SUC(n - 1) = n /\ N <= n - 1`];
16942 MATCH_MP_TAC(REAL_ARITH `&0 <= --c * x ==> c * x <= &0`) THEN
16943 MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[NORM_POS_LE] THEN
16944 UNDISCH_TAC `c <= &0` THEN REAL_ARITH_TAC;
16945 ASSUME_TAC(MATCH_MP REAL_LT_IMP_LE (ASSUME `&0 < c`))] THEN
16946 EXISTS_TAC `\n. norm(a(N):real^N) * c pow (n - N)` THEN
16947 REWRITE_TAC[] THEN CONJ_TAC THENL
16949 EXISTS_TAC `N:num` THEN
16950 SIMP_TAC[GE; LE_EXISTS; IMP_CONJ; ADD_SUB2; LEFT_IMP_EXISTS_THM] THEN
16951 SUBGOAL_THEN `!d:num. norm(a(N + d):real^N) <= norm(a N) * c pow d`
16952 (fun th -> MESON_TAC[th]) THEN INDUCT_TAC THEN
16953 REWRITE_TAC[ADD_CLAUSES; real_pow; REAL_MUL_RID; REAL_LE_REFL] THEN
16954 MATCH_MP_TAC REAL_LE_TRANS THEN
16955 EXISTS_TAC `c * norm((a:num->real^N) (N + d))` THEN
16956 ASM_SIMP_TAC[LE_ADD] THEN ASM_MESON_TAC[REAL_LE_LMUL; REAL_MUL_AC]] THEN
16957 GEN_REWRITE_TAC I [SERIES_CAUCHY] THEN X_GEN_TAC `e:real` THEN
16958 SIMP_TAC[GSYM LIFT_SUM; FINITE_INTER; NORM_LIFT; FINITE_NUMSEG] THEN
16959 DISCH_TAC THEN SIMP_TAC[SUM_LMUL; FINITE_INTER; FINITE_NUMSEG] THEN
16960 ASM_CASES_TAC `(a:num->real^N) N = vec 0` THENL
16961 [ASM_REWRITE_TAC[NORM_0; REAL_MUL_LZERO; REAL_ABS_NUM]; ALL_TAC] THEN
16962 MP_TAC(SPECL [`c:real`; `((&1 - c) * e) / norm((a:num->real^N) N)`]
16963 REAL_ARCH_POW_INV) THEN
16964 ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; REAL_SUB_LT; NORM_POS_LT; GE] THEN
16965 DISCH_THEN(X_CHOOSE_TAC `M:num`) THEN EXISTS_TAC `N + M:num` THEN
16966 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN
16967 MATCH_MP_TAC REAL_LET_TRANS THEN
16968 EXISTS_TAC `abs(norm((a:num->real^N) N) *
16969 sum(m..n) (\i. c pow (i - N)))` THEN
16971 [REWRITE_TAC[REAL_ABS_MUL] THEN MATCH_MP_TAC REAL_LE_LMUL THEN
16972 REWRITE_TAC[REAL_ABS_POS] THEN
16973 MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= y ==> abs x <= abs y`) THEN
16974 ASM_SIMP_TAC[SUM_POS_LE; FINITE_INTER_NUMSEG; REAL_POW_LE] THEN
16975 MATCH_MP_TAC SUM_SUBSET THEN ASM_SIMP_TAC[REAL_POW_LE] THEN
16976 REWRITE_TAC[FINITE_INTER_NUMSEG; FINITE_NUMSEG] THEN
16977 REWRITE_TAC[IN_INTER; IN_DIFF] THEN MESON_TAC[];
16979 REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_NORM] THEN
16980 DISJ_CASES_TAC(ARITH_RULE `n:num < m \/ m <= n`) THENL
16981 [ASM_SIMP_TAC[SUM_TRIV_NUMSEG; REAL_ABS_NUM; REAL_MUL_RZERO]; ALL_TAC] THEN
16982 SUBGOAL_THEN `m = 0 + m /\ n = (n - m) + m` (CONJUNCTS_THEN SUBST1_TAC) THENL
16983 [UNDISCH_TAC `m:num <= n` THEN ARITH_TAC; ALL_TAC] THEN
16984 REWRITE_TAC[SUM_OFFSET] THEN UNDISCH_TAC `N + M:num <= m` THEN
16985 SIMP_TAC[LE_EXISTS] THEN DISCH_THEN(X_CHOOSE_THEN `d:num` SUBST_ALL_TAC) THEN
16986 REWRITE_TAC[ARITH_RULE `(i + (N + M) + d) - N:num = (M + d) + i`] THEN
16987 ONCE_REWRITE_TAC[REAL_POW_ADD] THEN REWRITE_TAC[SUM_LMUL; SUM_GP] THEN
16988 ASM_SIMP_TAC[LT; REAL_LT_IMP_NE] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
16989 ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_POS_LT; REAL_ABS_MUL] THEN
16990 REWRITE_TAC[REAL_ABS_POW] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
16991 ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_ABS_DIV; REAL_POW_LT; REAL_ARITH
16992 `&0 < c /\ c < &1 ==> &0 < abs c /\ &0 < abs(&1 - c)`; REAL_LT_LDIV_EQ] THEN
16993 MATCH_MP_TAC(REAL_ARITH
16994 `&0 < x /\ x <= &1 /\ &1 <= e ==> abs(c pow 0 - x) < e`) THEN
16995 ASM_SIMP_TAC[REAL_POW_LT; REAL_POW_1_LE; REAL_LT_IMP_LE] THEN
16996 ASM_SIMP_TAC[REAL_ARITH `c < &1 ==> x * abs(&1 - c) = (&1 - c) * x`] THEN
16997 REWRITE_TAC[real_div; REAL_INV_MUL; REAL_POW_ADD; REAL_MUL_ASSOC] THEN
16998 REWRITE_TAC[REAL_ARITH
16999 `(((a * b) * c) * d) * e = (e * ((a * b) * c)) * d`] THEN
17000 ASM_SIMP_TAC[GSYM real_div; REAL_LE_RDIV_EQ; REAL_POW_LT; REAL_MUL_LID;
17001 REAL_ARITH `&0 < c ==> abs c = c`] THEN
17002 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
17003 `xm < e ==> &0 <= (d - &1) * e ==> xm <= d * e`)) THEN
17004 MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THENL
17005 [REWRITE_TAC[REAL_SUB_LE; GSYM REAL_POW_INV] THEN
17006 MATCH_MP_TAC REAL_POW_LE_1 THEN
17007 MATCH_MP_TAC REAL_INV_1_LE THEN ASM_SIMP_TAC[REAL_LT_IMP_LE];
17008 MATCH_MP_TAC REAL_LT_IMP_LE THEN
17009 ASM_SIMP_TAC[REAL_SUB_LT; REAL_LT_MUL; REAL_LT_DIV; NORM_POS_LT]]);;
17011 (* ------------------------------------------------------------------------- *)
17012 (* Ostensibly weaker versions of the boundedness of partial sums. *)
17013 (* ------------------------------------------------------------------------- *)
17015 let BOUNDED_PARTIAL_SUMS = prove
17016 (`!f:num->real^N k.
17017 bounded { vsum(k..n) f | n IN (:num) }
17018 ==> bounded { vsum(m..n) f | m IN (:num) /\ n IN (:num) }`,
17019 REPEAT STRIP_TAC THEN
17020 SUBGOAL_THEN `bounded { vsum(0..n) f:real^N | n IN (:num) }` MP_TAC THENL
17021 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
17022 REWRITE_TAC[bounded] THEN
17023 REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; IN_UNIV] THEN
17024 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
17025 EXISTS_TAC `sum { i:num | i < k} (\i. norm(f i:real^N)) + B` THEN
17026 X_GEN_TAC `i:num` THEN ASM_CASES_TAC `i:num < k` THENL
17027 [MATCH_MP_TAC(REAL_ARITH
17028 `!y. x <= y /\ y <= a /\ &0 < b ==> x <= a + b`) THEN
17029 EXISTS_TAC `sum (0..i) (\i. norm(f i:real^N))` THEN
17030 ASM_SIMP_TAC[VSUM_NORM; FINITE_NUMSEG] THEN
17031 MATCH_MP_TAC SUM_SUBSET THEN
17032 REWRITE_TAC[FINITE_NUMSEG; FINITE_NUMSEG_LT; NORM_POS_LE] THEN
17033 REWRITE_TAC[IN_DIFF; IN_NUMSEG; IN_ELIM_THM] THEN ASM_ARITH_TAC;
17035 ASM_CASES_TAC `k = 0` THENL
17036 [FIRST_X_ASSUM SUBST_ALL_TAC THEN MATCH_MP_TAC(REAL_ARITH
17037 `x <= B /\ &0 <= b ==> x <= b + B`) THEN
17038 ASM_SIMP_TAC[SUM_POS_LE; FINITE_NUMSEG_LT; NORM_POS_LE];
17040 MP_TAC(ISPECL [`f:num->real^N`; `0`; `k:num`; `i:num`]
17041 VSUM_COMBINE_L) THEN
17042 ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
17043 DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[NUMSEG_LT] THEN
17044 MATCH_MP_TAC(NORM_ARITH
17045 `norm(x) <= a /\ norm(y) <= b ==> norm(x + y) <= a + b`) THEN
17046 ASM_SIMP_TAC[VSUM_NORM; FINITE_NUMSEG];
17048 DISCH_THEN(fun th ->
17049 MP_TAC(MATCH_MP BOUNDED_DIFFS (W CONJ th)) THEN MP_TAC th) THEN
17050 REWRITE_TAC[IMP_IMP; GSYM BOUNDED_UNION] THEN
17051 MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b ==> c <=> b ==> a ==> c`]
17052 BOUNDED_SUBSET) THEN
17053 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNION; LEFT_IMP_EXISTS_THM; IN_UNIV] THEN
17054 MAP_EVERY X_GEN_TAC [`x:real^N`; `m:num`; `n:num`] THEN
17055 DISCH_THEN SUBST1_TAC THEN
17056 ASM_CASES_TAC `m = 0` THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
17057 ASM_CASES_TAC `n:num < m` THENL
17058 [DISJ2_TAC THEN REPEAT(EXISTS_TAC `vsum(0..0) (f:num->real^N)`) THEN
17059 ASM_SIMP_TAC[VSUM_TRIV_NUMSEG; VECTOR_SUB_REFL] THEN MESON_TAC[];
17061 DISJ2_TAC THEN MAP_EVERY EXISTS_TAC
17062 [`vsum(0..n) (f:num->real^N)`; `vsum(0..(m-1)) (f:num->real^N)`] THEN
17063 CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
17064 MP_TAC(ISPECL [`f:num->real^N`; `0`; `m:num`; `n:num`]
17065 VSUM_COMBINE_L) THEN
17066 ANTS_TAC THENL [ASM_ARITH_TAC; VECTOR_ARITH_TAC]);;
17068 (* ------------------------------------------------------------------------- *)
17069 (* General Dirichlet convergence test (could make this uniform on a set). *)
17070 (* ------------------------------------------------------------------------- *)
17072 let SUMMABLE_BILINEAR_PARTIAL_PRE = prove
17073 (`!f g h:real^M->real^N->real^P l k.
17075 ((\n. h (f(n + 1)) (g(n))) --> l) sequentially /\
17076 summable (from k) (\n. h (f(n + 1) - f(n)) (g(n)))
17077 ==> summable (from k) (\n. h (f n) (g(n) - g(n - 1)))`,
17078 REPEAT GEN_TAC THEN
17079 REWRITE_TAC[summable; sums; FROM_INTER_NUMSEG] THEN
17080 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
17081 FIRST_ASSUM(fun th ->
17082 REWRITE_TAC[MATCH_MP BILINEAR_VSUM_PARTIAL_PRE th]) THEN
17083 DISCH_THEN(X_CHOOSE_TAC `l':real^P`) THEN
17084 EXISTS_TAC `l - (h:real^M->real^N->real^P) (f k) (g(k - 1)) - l'` THEN
17085 REWRITE_TAC[LIM_CASES_SEQUENTIALLY] THEN
17086 REPEAT(MATCH_MP_TAC LIM_SUB THEN ASM_REWRITE_TAC[LIM_CONST]));;
17088 let SERIES_DIRICHLET_BILINEAR = prove
17089 (`!f g h:real^M->real^N->real^P k m p l.
17091 bounded { vsum (m..n) f | n IN (:num)} /\
17092 summable (from p) (\n. lift(norm(g(n + 1) - g(n)))) /\
17093 ((\n. h (g(n + 1)) (vsum(1..n) f)) --> l) sequentially
17094 ==> summable (from k) (\n. h (g n) (f n))`,
17095 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE THEN
17096 EXISTS_TAC `1` THEN
17097 FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP BOUNDED_PARTIAL_SUMS) THEN
17098 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
17099 SIMP_TAC[IN_ELIM_THM; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN
17100 REWRITE_TAC[MESON[] `(!x a b. x = f a b ==> p a b) <=> (!a b. p a b)`] THEN
17101 X_GEN_TAC `B:real` THEN STRIP_TAC THEN
17102 FIRST_ASSUM(MP_TAC o MATCH_MP BILINEAR_BOUNDED_POS) THEN
17103 DISCH_THEN(X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC) THEN
17104 MATCH_MP_TAC SUMMABLE_EQ THEN
17105 EXISTS_TAC `\n. (h:real^M->real^N->real^P)
17106 (g n) (vsum (1..n) f - vsum (1..n-1) f)` THEN
17107 SIMP_TAC[IN_FROM; GSYM NUMSEG_RREC] THEN
17108 SIMP_TAC[VSUM_CLAUSES; FINITE_NUMSEG; IN_NUMSEG;
17109 ARITH_RULE `1 <= n ==> ~(n <= n - 1)`] THEN
17111 [REPEAT STRIP_TAC THEN ASM_SIMP_TAC[BILINEAR_RADD; BILINEAR_RSUB] THEN
17114 MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE THEN EXISTS_TAC `p:num` THEN
17115 MP_TAC(ISPECL [`g:num->real^M`; `\n. vsum(1..n) f:real^N`;
17116 `h:real^M->real^N->real^P`; `l:real^P`; `p:num`]
17117 SUMMABLE_BILINEAR_PARTIAL_PRE) THEN
17118 REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN
17119 ASM_REWRITE_TAC[] THEN
17121 `summable (from p) (lift o (\n. C * B * norm(g(n + 1) - g(n):real^M)))`
17122 MP_TAC THENL [ASM_SIMP_TAC[o_DEF; LIFT_CMUL; SUMMABLE_CMUL]; ALL_TAC] THEN
17123 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUMMABLE_COMPARISON) THEN
17124 EXISTS_TAC `0` THEN REWRITE_TAC[IN_FROM; GE; LE_0] THEN
17125 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
17126 `C * norm(g(n + 1) - g(n):real^M) * norm(vsum (1..n) f:real^N)` THEN
17127 ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN
17128 GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN
17129 ASM_SIMP_TAC[REAL_LE_LMUL; NORM_POS_LE]);;
17131 let SERIES_DIRICHLET = prove
17132 (`!f:num->real^N g N k m.
17133 bounded { vsum (m..n) f | n IN (:num)} /\
17134 (!n. N <= n ==> g(n + 1) <= g(n)) /\
17135 ((lift o g) --> vec 0) sequentially
17136 ==> summable (from k) (\n. g(n) % f(n))`,
17137 REPEAT STRIP_TAC THEN
17138 MP_TAC(ISPECL [`f:num->real^N`; `lift o (g:num->real)`;
17139 `\x y:real^N. drop x % y`] SERIES_DIRICHLET_BILINEAR) THEN
17140 REWRITE_TAC[o_THM; LIFT_DROP] THEN DISCH_THEN MATCH_MP_TAC THEN
17141 MAP_EVERY EXISTS_TAC [`m:num`; `N:num`; `vec 0:real^N`] THEN CONJ_TAC THENL
17142 [REWRITE_TAC[bilinear; linear; DROP_ADD; DROP_CMUL] THEN
17143 REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC;
17145 ASM_REWRITE_TAC[GSYM LIFT_SUB; NORM_LIFT] THEN
17146 FIRST_ASSUM(MP_TAC o SPEC `1` o MATCH_MP SEQ_OFFSET) THEN
17147 REWRITE_TAC[o_THM] THEN DISCH_TAC THEN CONJ_TAC THENL
17148 [MATCH_MP_TAC SUMMABLE_EQ_EVENTUALLY THEN
17149 EXISTS_TAC `\n. lift(g(n) - g(n + 1))` THEN REWRITE_TAC[] THEN
17151 [ASM_MESON_TAC[REAL_ARITH `b <= a ==> abs(b - a) = a - b`];
17152 REWRITE_TAC[summable; sums; FROM_INTER_NUMSEG; VSUM_DIFFS; LIFT_SUB] THEN
17153 REWRITE_TAC[LIM_CASES_SEQUENTIALLY] THEN
17154 EXISTS_TAC `lift(g(N:num)) - vec 0` THEN
17155 MATCH_MP_TAC LIM_SUB THEN ASM_REWRITE_TAC[LIM_CONST]];
17156 MATCH_MP_TAC LIM_NULL_VMUL_BOUNDED THEN ASM_REWRITE_TAC[o_DEF] THEN
17157 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
17158 FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP BOUNDED_PARTIAL_SUMS) THEN
17159 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
17160 SIMP_TAC[IN_ELIM_THM; IN_UNIV] THEN MESON_TAC[]]);;
17162 (* ------------------------------------------------------------------------- *)
17163 (* Rearranging absolutely convergent series. *)
17164 (* ------------------------------------------------------------------------- *)
17166 let SERIES_INJECTIVE_IMAGE_STRONG = prove
17167 (`!x:num->real^N s f.
17168 summable (IMAGE f s) (\n. lift(norm(x n))) /\
17169 (!m n. m IN s /\ n IN s /\ f m = f n ==> m = n)
17170 ==> ((\n. vsum (IMAGE f s INTER (0..n)) x -
17171 vsum (s INTER (0..n)) (x o f)) --> vec 0)
17174 (`!f:A->real^N s t.
17175 FINITE s /\ FINITE t
17176 ==> vsum s f - vsum t f = vsum (s DIFF t) f - vsum (t DIFF s) f`,
17177 REPEAT STRIP_TAC THEN
17178 ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s DIFF (s INTER t)`] THEN
17179 ASM_SIMP_TAC[VSUM_DIFF; INTER_SUBSET] THEN
17180 REWRITE_TAC[INTER_COMM] THEN VECTOR_ARITH_TAC) in
17181 REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY] THEN
17182 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
17183 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUMMABLE_CAUCHY]) THEN
17184 SIMP_TAC[VSUM_REAL; FINITE_INTER; FINITE_NUMSEG] THEN
17185 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [o_DEF] THEN
17186 REWRITE_TAC[NORM_LIFT; LIFT_DROP] THEN
17187 SIMP_TAC[real_abs; SUM_POS_LE; NORM_POS_LE; FINITE_INTER; FINITE_NUMSEG] THEN
17188 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
17189 ASM_REWRITE_TAC[dist; GE; VECTOR_SUB_RZERO; REAL_HALF] THEN
17190 DISCH_THEN(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC) THEN
17191 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN
17192 DISCH_THEN(X_CHOOSE_TAC `g:num->num`) THEN
17193 MP_TAC(ISPECL [`g:num->num`; `0..N`] UPPER_BOUND_FINITE_SET) THEN
17194 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG; LE_0] THEN
17195 DISCH_THEN(X_CHOOSE_TAC `P:num`) THEN
17196 EXISTS_TAC `MAX N P` THEN X_GEN_TAC `n:num` THEN
17197 SIMP_TAC[ARITH_RULE `MAX a b <= c <=> a <= c /\ b <= c`] THEN DISCH_TAC THEN
17198 W(MP_TAC o PART_MATCH (rand o rand) VSUM_IMAGE o rand o
17199 rand o lhand o snd) THEN
17201 [ASM_MESON_TAC[FINITE_INTER; FINITE_NUMSEG; IN_INTER];
17202 DISCH_THEN(SUBST1_TAC o SYM)] THEN
17203 W(MP_TAC o PART_MATCH (lhand o rand) lemma o rand o lhand o snd) THEN
17204 SIMP_TAC[FINITE_INTER; FINITE_IMAGE; FINITE_NUMSEG] THEN
17205 DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC(NORM_ARITH
17206 `norm a < e / &2 /\ norm b < e / &2 ==> norm(a - b:real^N) < e`) THEN
17208 W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
17209 SIMP_TAC[FINITE_DIFF; FINITE_IMAGE; FINITE_INTER; FINITE_NUMSEG] THEN
17210 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LET_TRANS) THEN
17211 MATCH_MP_TAC REAL_LET_TRANS THENL
17213 `sum(IMAGE (f:num->num) s INTER (N..n)) (\i. norm(x i :real^N))` THEN
17214 ASM_SIMP_TAC[LE_REFL] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
17215 SIMP_TAC[NORM_POS_LE; FINITE_INTER; FINITE_NUMSEG] THEN
17216 MATCH_MP_TAC(SET_RULE
17217 `(!x. x IN s /\ f(x) IN n /\ ~(x IN m) ==> f x IN t)
17218 ==> (IMAGE f s INTER n) DIFF (IMAGE f (s INTER m)) SUBSET
17219 IMAGE f s INTER t`) THEN
17220 ASM_SIMP_TAC[IN_NUMSEG; LE_0; NOT_LE] THEN
17221 X_GEN_TAC `i:num` THEN STRIP_TAC THEN
17222 MATCH_MP_TAC LT_IMP_LE THEN ONCE_REWRITE_TAC[GSYM NOT_LE] THEN
17223 FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE BINDER_CONV
17224 [GSYM CONTRAPOS_THM]) THEN
17225 ASM_SIMP_TAC[] THEN ASM_ARITH_TAC;
17226 MP_TAC(ISPECL [`f:num->num`; `0..n`] UPPER_BOUND_FINITE_SET) THEN
17227 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG; LE_0] THEN
17228 DISCH_THEN(X_CHOOSE_TAC `p:num`) THEN
17230 `sum(IMAGE (f:num->num) s INTER (N..p)) (\i. norm(x i :real^N))` THEN
17231 ASM_SIMP_TAC[LE_REFL] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
17232 SIMP_TAC[NORM_POS_LE; FINITE_INTER; FINITE_NUMSEG] THEN
17233 MATCH_MP_TAC(SET_RULE
17234 `(!x. x IN s /\ x IN n /\ ~(f x IN m) ==> f x IN t)
17235 ==> (IMAGE f (s INTER n) DIFF (IMAGE f s) INTER m) SUBSET
17236 (IMAGE f s INTER t)`) THEN
17237 ASM_SIMP_TAC[IN_NUMSEG; LE_0] THEN ASM_ARITH_TAC]);;
17239 let SERIES_INJECTIVE_IMAGE = prove
17240 (`!x:num->real^N s f l.
17241 summable (IMAGE f s) (\n. lift(norm(x n))) /\
17242 (!m n. m IN s /\ n IN s /\ f m = f n ==> m = n)
17243 ==> (((x o f) sums l) s <=> (x sums l) (IMAGE f s))`,
17244 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN REWRITE_TAC[sums] THEN
17245 MATCH_MP_TAC LIM_TRANSFORM_EQ THEN REWRITE_TAC[] THEN
17246 MATCH_MP_TAC SERIES_INJECTIVE_IMAGE_STRONG THEN
17247 ASM_REWRITE_TAC[]);;
17249 let SERIES_REARRANGE_EQ = prove
17250 (`!x:num->real^N s p l.
17251 summable s (\n. lift(norm(x n))) /\ p permutes s
17252 ==> (((x o p) sums l) s <=> (x sums l) s)`,
17253 REPEAT STRIP_TAC THEN
17254 MP_TAC(ISPECL [`x:num->real^N`; `s:num->bool`; `p:num->num`; `l:real^N`]
17255 SERIES_INJECTIVE_IMAGE) THEN
17256 ASM_SIMP_TAC[PERMUTES_IMAGE] THEN
17257 ASM_MESON_TAC[PERMUTES_INJECTIVE]);;
17259 let SERIES_REARRANGE = prove
17260 (`!x:num->real^N s p l.
17261 summable s (\n. lift(norm(x n))) /\ p permutes s /\ (x sums l) s
17262 ==> ((x o p) sums l) s`,
17263 MESON_TAC[SERIES_REARRANGE_EQ]);;
17265 let SUMMABLE_REARRANGE = prove
17267 summable s (\n. lift(norm(x n))) /\ p permutes s
17268 ==> summable s (x o p)`,
17269 MESON_TAC[SERIES_LIFT_ABSCONV_IMP_CONV; summable; SERIES_REARRANGE]);;
17271 (* ------------------------------------------------------------------------- *)
17272 (* Banach fixed point theorem (not really topological...) *)
17273 (* ------------------------------------------------------------------------- *)
17275 let BANACH_FIX = prove
17276 (`!f s c. complete s /\ ~(s = {}) /\
17277 &0 <= c /\ c < &1 /\
17278 (IMAGE f s) SUBSET s /\
17279 (!x y. x IN s /\ y IN s ==> dist(f(x),f(y)) <= c * dist(x,y))
17280 ==> ?!x:real^N. x IN s /\ (f x = x)`,
17281 REPEAT STRIP_TAC THEN REWRITE_TAC[EXISTS_UNIQUE_THM] THEN CONJ_TAC THENL
17283 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
17284 SUBGOAL_THEN `dist((f:real^N->real^N) x,f y) <= c * dist(x,y)` MP_TAC THENL
17285 [ASM_MESON_TAC[]; ALL_TAC] THEN
17286 ASM_REWRITE_TAC[REAL_ARITH `a <= c * a <=> &0 <= --a * (&1 - c)`] THEN
17287 ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; REAL_SUB_LT; real_div] THEN
17288 REWRITE_TAC[REAL_MUL_LZERO; REAL_ARITH `&0 <= --x <=> ~(&0 < x)`] THEN
17289 MESON_TAC[DIST_POS_LT]] THEN
17290 STRIP_ASSUME_TAC(prove_recursive_functions_exist num_RECURSION
17291 `(z 0 = @x:real^N. x IN s) /\ (!n. z(SUC n) = f(z n))`) THEN
17292 SUBGOAL_THEN `!n. (z:num->real^N) n IN s` ASSUME_TAC THENL
17293 [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN
17294 ASM_MESON_TAC[MEMBER_NOT_EMPTY; SUBSET; IN_IMAGE];
17296 UNDISCH_THEN `z 0 = @x:real^N. x IN s` (K ALL_TAC) THEN
17297 SUBGOAL_THEN `?x:real^N. x IN s /\ (z --> x) sequentially` MP_TAC THENL
17299 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN
17300 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
17301 ABBREV_TAC `e = dist(f(a:real^N),a)` THEN
17302 SUBGOAL_THEN `~(&0 < e)` (fun th -> ASM_MESON_TAC[th; DIST_POS_LT]) THEN
17304 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
17305 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
17306 ASM_REWRITE_TAC[REAL_HALF] THEN DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
17308 `dist(f(z N),a:real^N) < e / &2 /\ dist(f(z(N:num)),f(a)) < e / &2`
17309 (fun th -> ASM_MESON_TAC[th; DIST_TRIANGLE_HALF_R; REAL_LT_REFL]) THEN
17310 CONJ_TAC THENL [ASM_MESON_TAC[ARITH_RULE `N <= SUC N`]; ALL_TAC] THEN
17311 MATCH_MP_TAC REAL_LET_TRANS THEN
17312 EXISTS_TAC `c * dist((z:num->real^N) N,a)` THEN ASM_SIMP_TAC[] THEN
17313 MATCH_MP_TAC(REAL_ARITH `x < y /\ c * x <= &1 * x ==> c * x < y`) THEN
17314 ASM_SIMP_TAC[LE_REFL; REAL_LE_RMUL; DIST_POS_LE; REAL_LT_IMP_LE]] THEN
17315 FIRST_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [complete]) THEN
17316 ASM_REWRITE_TAC[CAUCHY] THEN
17317 SUBGOAL_THEN `!n. dist(z(n):real^N,z(SUC n)) <= c pow n * dist(z(0),z(1))`
17320 REWRITE_TAC[real_pow; ARITH; REAL_MUL_LID; REAL_LE_REFL] THEN
17321 MATCH_MP_TAC REAL_LE_TRANS THEN
17322 EXISTS_TAC `c * dist(z(n):real^N,z(SUC n))` THEN
17323 CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
17324 REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_LE_LMUL];
17327 `!m n:num. (&1 - c) * dist(z(m):real^N,z(m+n))
17328 <= c pow m * dist(z(0),z(1)) * (&1 - c pow n)`
17330 [GEN_TAC THEN INDUCT_TAC THENL
17331 [REWRITE_TAC[ADD_CLAUSES; DIST_REFL; REAL_MUL_RZERO] THEN
17332 MATCH_MP_TAC REAL_LE_MUL THEN
17333 ASM_SIMP_TAC[REAL_LE_MUL; REAL_POW_LE; DIST_POS_LE; REAL_SUB_LE;
17334 REAL_POW_1_LE; REAL_LT_IMP_LE];
17336 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
17337 `(&1 - c) * (dist(z m:real^N,z(m + n)) + dist(z(m + n),z(m + SUC n)))` THEN
17338 ASM_SIMP_TAC[REAL_LE_LMUL; REAL_SUB_LE; REAL_LT_IMP_LE; DIST_TRIANGLE] THEN
17339 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
17340 `c * x <= y ==> c * x' + y <= y' ==> c * (x + x') <= y'`)) THEN
17341 REWRITE_TAC[REAL_ARITH
17342 `q + a * b * (&1 - x) <= a * b * (&1 - y) <=> q <= a * b * (x - y)`] THEN
17343 REWRITE_TAC[ADD_CLAUSES; real_pow] THEN
17344 REWRITE_TAC[REAL_ARITH `a * b * (d - c * d) = (&1 - c) * a * d * b`] THEN
17345 MATCH_MP_TAC REAL_LE_LMUL THEN
17346 ASM_SIMP_TAC[REAL_SUB_LE; REAL_LT_IMP_LE] THEN
17347 REWRITE_TAC[GSYM REAL_POW_ADD; REAL_MUL_ASSOC] THEN ASM_MESON_TAC[];
17349 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
17350 ASM_CASES_TAC `(z:num->real^N) 0 = z 1` THENL
17351 [FIRST_X_ASSUM SUBST_ALL_TAC THEN EXISTS_TAC `0` THEN
17352 REWRITE_TAC[GE; LE_0] THEN X_GEN_TAC `n:num` THEN
17353 FIRST_X_ASSUM(MP_TAC o SPECL [`0`; `n:num`]) THEN
17354 REWRITE_TAC[ADD_CLAUSES; DIST_REFL; REAL_MUL_LZERO; REAL_MUL_RZERO] THEN
17355 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
17356 ASM_CASES_TAC `(z:num->real^N) 0 = z n` THEN
17357 ASM_REWRITE_TAC[DIST_REFL; REAL_NOT_LE] THEN
17358 ASM_SIMP_TAC[REAL_LT_MUL; DIST_POS_LT; REAL_SUB_LT];
17360 MP_TAC(SPECL [`c:real`; `e * (&1 - c) / dist((z:num->real^N) 0,z 1)`]
17361 REAL_ARCH_POW_INV) THEN
17362 ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; REAL_SUB_LT; DIST_POS_LT] THEN
17363 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
17364 REWRITE_TAC[real_div; GE; REAL_MUL_ASSOC] THEN
17365 ASM_SIMP_TAC[REAL_LT_RDIV_EQ; GSYM real_div; DIST_POS_LT] THEN
17366 ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; REAL_SUB_LT] THEN DISCH_TAC THEN
17367 REWRITE_TAC[LE_EXISTS; LEFT_IMP_EXISTS_THM] THEN
17368 GEN_TAC THEN X_GEN_TAC `d:num` THEN DISCH_THEN SUBST_ALL_TAC THEN
17369 ONCE_REWRITE_TAC[DIST_SYM] THEN
17370 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(REAL_ARITH
17371 `d < e ==> x <= d ==> x < e`)) THEN
17372 ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN
17373 FIRST_X_ASSUM(MP_TAC o SPECL [`N:num`; `d:num`]) THEN
17374 MATCH_MP_TAC(REAL_ARITH
17375 `(c * d) * e <= (c * d) * &1 ==> x * y <= c * d * e ==> y * x <= c * d`) THEN
17376 MATCH_MP_TAC REAL_LE_LMUL THEN
17377 ASM_SIMP_TAC[REAL_LE_MUL; REAL_POW_LE; DIST_POS_LE; REAL_ARITH
17378 `&0 <= x ==> &1 - x <= &1`]);;
17380 (* ------------------------------------------------------------------------- *)
17381 (* Edelstein fixed point theorem. *)
17382 (* ------------------------------------------------------------------------- *)
17384 let EDELSTEIN_FIX = prove
17385 (`!f s. compact s /\ ~(s = {}) /\ (IMAGE f s) SUBSET s /\
17386 (!x y. x IN s /\ y IN s /\ ~(x = y) ==> dist(f(x),f(y)) < dist(x,y))
17387 ==> ?!x:real^N. x IN s /\ f x = x`,
17388 MAP_EVERY X_GEN_TAC [`g:real^N->real^N`; `s:real^N->bool`] THEN
17389 REPEAT STRIP_TAC THEN REWRITE_TAC[EXISTS_UNIQUE_THM] THEN CONJ_TAC THENL
17390 [ALL_TAC; ASM_MESON_TAC[REAL_LT_REFL]] THEN
17392 `!x y. x IN s /\ y IN s ==> dist((g:real^N->real^N)(x),g(y)) <= dist(x,y)`
17394 [REPEAT STRIP_TAC THEN ASM_CASES_TAC `x:real^N = y` THEN
17395 ASM_SIMP_TAC[DIST_REFL; REAL_LE_LT];
17397 ASM_CASES_TAC `?x:real^N. x IN s /\ ~(g x = x)` THENL
17398 [ALL_TAC; ASM SET_TAC[]] THEN
17399 FIRST_X_ASSUM(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN
17400 ABBREV_TAC `y = (g:real^N->real^N) x` THEN
17401 SUBGOAL_THEN `(y:real^N) IN s` ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
17402 FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_PCROSS o W CONJ) THEN
17403 REWRITE_TAC[compact; PCROSS] THEN
17404 (STRIP_ASSUME_TAC o prove_general_recursive_function_exists)
17405 `?f:num->real^N->real^N.
17406 (!z. f 0 z = z) /\ (!z n. f (SUC n) z = g(f n z))` THEN
17407 SUBGOAL_THEN `!n z. z IN s ==> (f:num->real^N->real^N) n z IN s`
17408 STRIP_ASSUME_TAC THENL [INDUCT_TAC THEN ASM SET_TAC[]; ALL_TAC] THEN
17410 `!m n w z. m <= n /\ w IN s /\ z IN s
17411 ==> dist((f:num->real^N->real^N) n w,f n z) <= dist(f m w,f m z)`
17413 [REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN
17414 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
17415 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE]) THEN
17416 ASM_SIMP_TAC[REAL_LE_REFL] THEN MESON_TAC[REAL_LE_TRANS];
17418 DISCH_THEN(MP_TAC o SPEC
17419 `\n:num. pastecart (f n (x:real^N)) (f n y:real^N)`) THEN
17420 ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN
17421 MAP_EVERY X_GEN_TAC [`l:real^(N,N)finite_sum`; `s:num->num`] THEN
17422 REWRITE_TAC[o_DEF; IN_ELIM_THM] THEN
17423 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
17424 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
17425 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
17426 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC SUBST_ALL_TAC) THEN
17428 `(\x:real^(N,N)finite_sum. fstcart x) continuous_on UNIV /\
17429 (\x:real^(N,N)finite_sum. sndcart x) continuous_on UNIV`
17431 [CONJ_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN
17432 REWRITE_TAC[ETA_AX; LINEAR_FSTCART; LINEAR_SNDCART];
17434 REWRITE_TAC[CONTINUOUS_ON_SEQUENTIALLY; IN_UNIV] THEN
17435 DISCH_THEN(CONJUNCTS_THEN(fun th -> FIRST_ASSUM(MP_TAC o MATCH_MP th))) THEN
17436 REWRITE_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART; IMP_IMP] THEN
17437 ONCE_REWRITE_TAC[CONJ_SYM] THEN
17438 DISCH_THEN(fun th -> CONJUNCTS_THEN2 (LABEL_TAC "A") (LABEL_TAC "B") th THEN
17439 MP_TAC(MATCH_MP LIM_SUB th)) THEN
17440 REWRITE_TAC[] THEN DISCH_THEN(LABEL_TAC "AB") THEN
17442 `!n. dist(a:real^N,b) <= dist((f:num->real^N->real^N) n x,f n y)`
17443 STRIP_ASSUME_TAC THENL
17444 [X_GEN_TAC `N:num` THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
17445 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN
17446 USE_THEN "AB" (MP_TAC o REWRITE_RULE[LIM_SEQUENTIALLY]) THEN
17447 DISCH_THEN(fun th -> FIRST_X_ASSUM(MP_TAC o MATCH_MP th)) THEN
17448 REWRITE_TAC[NOT_EXISTS_THM] THEN X_GEN_TAC `M:num` THEN
17449 DISCH_THEN(MP_TAC o SPEC `M + N:num`) THEN REWRITE_TAC[LE_ADD] THEN
17450 MATCH_MP_TAC(NORM_ARITH
17451 `dist(fx,fy) <= dist(x,y)
17452 ==> ~(dist(fx - fy,a - b) < dist(a,b) - dist(x,y))`) THEN
17453 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
17454 FIRST_X_ASSUM(MP_TAC o SPEC `M + N:num` o MATCH_MP MONOTONE_BIGGER) THEN
17457 SUBGOAL_THEN `b:real^N = a` SUBST_ALL_TAC THENL
17458 [MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN
17459 ABBREV_TAC `e = dist(a,b) - dist((g:real^N->real^N) a,g b)` THEN
17460 SUBGOAL_THEN `&0 < e` ASSUME_TAC THENL
17461 [ASM_MESON_TAC[REAL_SUB_LT]; ALL_TAC] THEN
17463 `?n. dist((f:num->real^N->real^N) n x,a) < e / &2 /\
17464 dist(f n y,b) < e / &2`
17465 STRIP_ASSUME_TAC THENL
17466 [MAP_EVERY (fun s -> USE_THEN s (MP_TAC o SPEC `e / &2` o
17467 REWRITE_RULE[LIM_SEQUENTIALLY])) ["A"; "B"] THEN
17468 ASM_REWRITE_TAC[REAL_HALF] THEN
17469 DISCH_THEN(X_CHOOSE_TAC `M:num`) THEN
17470 DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
17471 EXISTS_TAC `(s:num->num) (M + N)` THEN
17472 CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC;
17474 SUBGOAL_THEN `dist(f (SUC n) x,(g:real^N->real^N) a) +
17475 dist((f:num->real^N->real^N) (SUC n) y,g b) < e`
17477 [ASM_REWRITE_TAC[] THEN
17478 MATCH_MP_TAC(REAL_ARITH `x < e / &2 /\ y < e / &2 ==> x + y < e`) THEN
17479 CONJ_TAC THEN FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
17481 ==> dist(g x,g y) <= dist(x,y) ==> dist(g x,g y) < e`)) THEN
17484 MP_TAC(SPEC `SUC n` (ASSUME
17485 `!n. dist (a:real^N,b) <=
17486 dist ((f:num->real^N->real^N) n x,f n y)`)) THEN
17487 EXPAND_TAC "e" THEN NORM_ARITH_TAC;
17489 EXISTS_TAC `a:real^N` THEN ASM_REWRITE_TAC[] THEN
17490 MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
17491 EXISTS_TAC `\n:num. (f:num->real^N->real^N) (SUC(s n)) x` THEN
17492 REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN CONJ_TAC THENL
17493 [ASM_REWRITE_TAC[] THEN
17494 SUBGOAL_THEN `(g:real^N->real^N) continuous_on s` MP_TAC THENL
17495 [REWRITE_TAC[continuous_on] THEN ASM_MESON_TAC[REAL_LET_TRANS];
17497 REWRITE_TAC[CONTINUOUS_ON_SEQUENTIALLY; o_DEF] THEN
17498 DISCH_THEN MATCH_MP_TAC THEN ASM_SIMP_TAC[];
17499 SUBGOAL_THEN `!n. (f:num->real^N->real^N) (SUC n) x = f n y`
17500 (fun th -> ASM_SIMP_TAC[th]) THEN
17501 INDUCT_TAC THEN ASM_REWRITE_TAC[]]);;
17503 (* ------------------------------------------------------------------------- *)
17504 (* Dini's theorem. *)
17505 (* ------------------------------------------------------------------------- *)
17508 (`!f:num->real^N->real^1 g s.
17509 compact s /\ (!n. (f n) continuous_on s) /\ g continuous_on s /\
17510 (!x. x IN s ==> ((\n. (f n x)) --> g x) sequentially) /\
17511 (!n x. x IN s ==> drop(f n x) <= drop(f (n + 1) x))
17513 ==> eventually (\n. !x. x IN s ==> norm(f n x - g x) < e)
17515 REPEAT STRIP_TAC THEN
17517 `!x:real^N m n:num. x IN s /\ m <= n ==> drop(f m x) <= drop(f n x)`
17519 [GEN_TAC THEN ASM_CASES_TAC `(x:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN
17520 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_SIMP_TAC[ADD1] THEN
17523 SUBGOAL_THEN `!n:num x:real^N. x IN s ==> drop(f n x) <= drop(g x)`
17525 [REPEAT STRIP_TAC THEN
17526 MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LE) THEN
17527 EXISTS_TAC `\m:num. (f:num->real^N->real^1) n x` THEN
17528 EXISTS_TAC `\m:num. (f:num->real^N->real^1) m x` THEN
17529 ASM_SIMP_TAC[LIM_CONST; TRIVIAL_LIMIT_SEQUENTIALLY] THEN
17530 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN ASM_MESON_TAC[];
17532 RULE_ASSUM_TAC(REWRITE_RULE[LIM_SEQUENTIALLY; dist]) THEN
17533 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I
17534 [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN
17535 DISCH_THEN(MP_TAC o SPEC
17536 `IMAGE (\n. { x | x IN s /\ norm((f:num->real^N->real^1) n x - g x) < e})
17538 REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN
17539 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
17540 REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE; SUBSET_UNION; UNIONS_IMAGE] THEN
17541 REWRITE_TAC[IN_UNIV; IN_ELIM_THM; EVENTUALLY_SEQUENTIALLY] THEN
17542 SIMP_TAC[SUBSET; IN_UNIV; IN_ELIM_THM] THEN ANTS_TAC THENL
17543 [CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LE_REFL]] THEN
17544 X_GEN_TAC `n:num` THEN REWRITE_TAC[GSYM IN_BALL_0] THEN
17545 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE THEN
17546 ASM_SIMP_TAC[OPEN_BALL; CONTINUOUS_ON_SUB; ETA_AX];
17548 DISCH_THEN(X_CHOOSE_THEN `k:num->bool` (CONJUNCTS_THEN2
17549 (MP_TAC o SPEC `\n:num. n` o MATCH_MP UPPER_BOUND_FINITE_SET)
17550 (LABEL_TAC "*"))) THEN
17551 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
17552 REWRITE_TAC[] THEN STRIP_TAC THEN X_GEN_TAC `n:num` THEN
17553 DISCH_TAC THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
17554 REMOVE_THEN "*" (MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
17555 DISCH_THEN(X_CHOOSE_THEN `m:num` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
17556 REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB] THEN MATCH_MP_TAC(REAL_ARITH
17557 `m <= n /\ n <= g ==> abs(m - g) < e ==> abs(n - g) < e`) THEN
17558 ASM_MESON_TAC[LE_TRANS]]);;
17560 (* ------------------------------------------------------------------------- *)
17561 (* Closest point of a (closed) set to a point. *)
17562 (* ------------------------------------------------------------------------- *)
17564 let closest_point = new_definition
17565 `closest_point s a = @x. x IN s /\ !y. y IN s ==> dist(a,x) <= dist(a,y)`;;
17567 let CLOSEST_POINT_EXISTS = prove
17568 (`!s a. closed s /\ ~(s = {})
17569 ==> (closest_point s a) IN s /\
17570 !y. y IN s ==> dist(a,closest_point s a) <= dist(a,y)`,
17571 REWRITE_TAC[closest_point] THEN CONV_TAC(ONCE_DEPTH_CONV SELECT_CONV) THEN
17572 REWRITE_TAC[DISTANCE_ATTAINS_INF]);;
17574 let CLOSEST_POINT_IN_SET = prove
17575 (`!s a. closed s /\ ~(s = {}) ==> (closest_point s a) IN s`,
17576 MESON_TAC[CLOSEST_POINT_EXISTS]);;
17578 let CLOSEST_POINT_LE = prove
17579 (`!s a x. closed s /\ x IN s ==> dist(a,closest_point s a) <= dist(a,x)`,
17580 MESON_TAC[CLOSEST_POINT_EXISTS; MEMBER_NOT_EMPTY]);;
17582 let CLOSEST_POINT_SELF = prove
17583 (`!s x:real^N. x IN s ==> closest_point s x = x`,
17584 REPEAT STRIP_TAC THEN REWRITE_TAC[closest_point] THEN
17585 MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN GEN_TAC THEN EQ_TAC THENL
17586 [STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
17587 ASM_SIMP_TAC[DIST_LE_0; DIST_REFL];
17588 STRIP_TAC THEN ASM_REWRITE_TAC[DIST_REFL; DIST_POS_LE]]);;
17590 let CLOSEST_POINT_REFL = prove
17591 (`!s x:real^N. closed s /\ ~(s = {}) ==> (closest_point s x = x <=> x IN s)`,
17592 MESON_TAC[CLOSEST_POINT_IN_SET; CLOSEST_POINT_SELF]);;
17594 let DIST_CLOSEST_POINT_LIPSCHITZ = prove
17596 closed s /\ ~(s = {})
17597 ==> abs(dist(x,closest_point s x) - dist(y,closest_point s y))
17599 REPEAT GEN_TAC THEN DISCH_TAC THEN
17600 FIRST_ASSUM(MP_TAC o MATCH_MP CLOSEST_POINT_EXISTS) THEN
17601 DISCH_THEN(fun th ->
17602 CONJUNCTS_THEN2 ASSUME_TAC
17603 (MP_TAC o SPEC `closest_point s (y:real^N)`) (SPEC `x:real^N` th) THEN
17604 CONJUNCTS_THEN2 ASSUME_TAC
17605 (MP_TAC o SPEC `closest_point s (x:real^N)`) (SPEC `y:real^N` th)) THEN
17606 ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);;
17608 let CONTINUOUS_AT_DIST_CLOSEST_POINT = prove
17610 closed s /\ ~(s = {})
17611 ==> (\x. lift(dist(x,closest_point s x))) continuous (at x)`,
17612 REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_at; DIST_LIFT] THEN
17613 ASM_MESON_TAC[DIST_CLOSEST_POINT_LIPSCHITZ; REAL_LET_TRANS]);;
17615 let CONTINUOUS_ON_DIST_CLOSEST_POINT = prove
17616 (`!s t. closed s /\ ~(s = {})
17617 ==> (\x. lift(dist(x,closest_point s x))) continuous_on t`,
17618 MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON;
17619 CONTINUOUS_AT_DIST_CLOSEST_POINT]);;
17621 let UNIFORMLY_CONTINUOUS_ON_DIST_CLOSEST_POINT = prove
17622 (`!s t:real^N->bool.
17623 closed s /\ ~(s = {})
17624 ==> (\x. lift(dist(x,closest_point s x))) uniformly_continuous_on t`,
17625 REPEAT STRIP_TAC THEN REWRITE_TAC[uniformly_continuous_on; DIST_LIFT] THEN
17626 ASM_MESON_TAC[DIST_CLOSEST_POINT_LIPSCHITZ; REAL_LET_TRANS]);;
17628 let SEGMENT_TO_CLOSEST_POINT = prove
17630 closed s /\ ~(s = {})
17631 ==> segment(a,closest_point s a) INTER s = {}`,
17632 REPEAT STRIP_TAC THEN
17633 REWRITE_TAC[SET_RULE `s INTER t = {} <=> !x. x IN s ==> ~(x IN t)`] THEN
17634 GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP DIST_IN_OPEN_SEGMENT) THEN
17635 MATCH_MP_TAC(TAUT `(r ==> ~p) ==> p /\ q ==> ~r`) THEN
17636 ASM_MESON_TAC[CLOSEST_POINT_EXISTS; REAL_NOT_LT; DIST_SYM]);;
17638 let SEGMENT_TO_POINT_EXISTS = prove
17640 closed s /\ ~(s = {}) ==> ?b. b IN s /\ segment(a,b) INTER s = {}`,
17641 MESON_TAC[SEGMENT_TO_CLOSEST_POINT; CLOSEST_POINT_EXISTS]);;
17643 let CLOSEST_POINT_IN_INTERIOR = prove
17645 closed s /\ ~(s = {})
17646 ==> ((closest_point s x) IN interior s <=> x IN interior s)`,
17647 REPEAT STRIP_TAC THEN ASM_CASES_TAC `(x:real^N) IN s` THEN
17648 ASM_SIMP_TAC[CLOSEST_POINT_SELF] THEN
17649 MATCH_MP_TAC(TAUT `~q /\ ~p ==> (p <=> q)`) THEN
17650 CONJ_TAC THENL [ASM_MESON_TAC[INTERIOR_SUBSET; SUBSET]; STRIP_TAC] THEN
17651 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR_CBALL]) THEN
17652 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
17653 SUBGOAL_THEN `closest_point s (x:real^N) IN s` ASSUME_TAC THENL
17654 [ASM_MESON_TAC[INTERIOR_SUBSET; SUBSET]; ALL_TAC] THEN
17655 SUBGOAL_THEN `~(closest_point s (x:real^N) = x)` ASSUME_TAC THENL
17656 [ASM_MESON_TAC[]; ALL_TAC] THEN
17657 MP_TAC(ISPECL [`s:real^N->bool`; `x:real^N`;
17658 `closest_point s x -
17659 (min (&1) (e / norm(closest_point s x - x))) %
17660 (closest_point s x - x):real^N`]
17661 CLOSEST_POINT_LE) THEN
17662 ASM_REWRITE_TAC[dist; NOT_IMP; VECTOR_ARITH
17663 `x - (y - e % (y - x)):real^N = (&1 - e) % (x - y)`] THEN
17665 [FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
17666 REWRITE_TAC[IN_CBALL; NORM_ARITH `dist(a:real^N,a - x) = norm x`] THEN
17667 REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN
17668 ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN
17669 MATCH_MP_TAC(REAL_ARITH `&0 <= a ==> abs(min (&1) a) <= a`) THEN
17670 ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_DIV; NORM_POS_LE];
17671 REWRITE_TAC[NORM_MUL; REAL_ARITH
17672 `~(n <= a * n) <=> &0 < (&1 - a) * n`] THEN
17673 MATCH_MP_TAC REAL_LT_MUL THEN
17674 ASM_SIMP_TAC[NORM_POS_LT; VECTOR_SUB_EQ] THEN
17675 MATCH_MP_TAC(REAL_ARITH
17676 `&0 < e /\ e <= &1 ==> &0 < &1 - abs(&1 - e)`) THEN
17677 REWRITE_TAC[REAL_MIN_LE; REAL_LT_MIN; REAL_LT_01; REAL_LE_REFL] THEN
17678 ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ]]);;
17680 let CLOSEST_POINT_IN_FRONTIER = prove
17682 closed s /\ ~(s = {}) /\ ~(x IN interior s)
17683 ==> (closest_point s x) IN frontier s`,
17684 SIMP_TAC[frontier; IN_DIFF; CLOSEST_POINT_IN_INTERIOR] THEN
17685 SIMP_TAC[CLOSEST_POINT_IN_SET; CLOSURE_CLOSED]);;
17687 (* ------------------------------------------------------------------------- *)
17688 (* More general infimum of distance between two sets. *)
17689 (* ------------------------------------------------------------------------- *)
17691 let setdist = new_definition
17693 if s = {} \/ t = {} then &0
17694 else inf {dist(x,y) | x IN s /\ y IN t}`;;
17696 let SETDIST_EMPTY = prove
17697 (`(!t. setdist({},t) = &0) /\ (!s. setdist(s,{}) = &0)`,
17698 REWRITE_TAC[setdist]);;
17700 let SETDIST_POS_LE = prove
17701 (`!s t. &0 <= setdist(s,t)`,
17702 REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN
17703 COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN
17704 MATCH_MP_TAC REAL_LE_INF THEN
17705 REWRITE_TAC[FORALL_IN_GSPEC; DIST_POS_LE] THEN ASM SET_TAC[]);;
17707 let REAL_LE_SETDIST = prove
17708 (`!s t:real^N->bool d.
17709 ~(s = {}) /\ ~(t = {}) /\
17710 (!x y. x IN s /\ y IN t ==> d <= dist(x,y))
17711 ==> d <= setdist(s,t)`,
17712 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[setdist] THEN
17713 MP_TAC(ISPEC `{dist(x:real^N,y) | x IN s /\ y IN t}` INF) THEN
17714 REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL
17715 [CONJ_TAC THENL [ASM SET_TAC[]; MESON_TAC[DIST_POS_LE]]; ALL_TAC] THEN
17718 let SETDIST_LE_DIST = prove
17719 (`!s t x y:real^N. x IN s /\ y IN t ==> setdist(s,t) <= dist(x,y)`,
17720 REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN
17721 COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
17722 MP_TAC(ISPEC `{dist(x:real^N,y) | x IN s /\ y IN t}` INF) THEN
17723 REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL
17724 [CONJ_TAC THENL [ASM SET_TAC[]; MESON_TAC[DIST_POS_LE]]; ALL_TAC] THEN
17727 let REAL_LE_SETDIST_EQ = prove
17728 (`!d s t:real^N->bool.
17729 d <= setdist(s,t) <=>
17730 (!x y. x IN s /\ y IN t ==> d <= dist(x,y)) /\
17731 (s = {} \/ t = {} ==> d <= &0)`,
17732 REPEAT GEN_TAC THEN MAP_EVERY ASM_CASES_TAC
17733 [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN
17734 ASM_REWRITE_TAC[SETDIST_EMPTY; NOT_IN_EMPTY] THEN
17735 ASM_MESON_TAC[REAL_LE_SETDIST; SETDIST_LE_DIST; REAL_LE_TRANS]);;
17737 let REAL_SETDIST_LT_EXISTS = prove
17738 (`!s t:real^N->bool b.
17739 ~(s = {}) /\ ~(t = {}) /\ setdist(s,t) < b
17740 ==> ?x y. x IN s /\ y IN t /\ dist(x,y) < b`,
17741 REWRITE_TAC[GSYM REAL_NOT_LE; REAL_LE_SETDIST_EQ] THEN MESON_TAC[]);;
17743 let SETDIST_REFL = prove
17744 (`!s:real^N->bool. setdist(s,s) = &0`,
17745 GEN_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM; SETDIST_POS_LE] THEN
17746 ASM_CASES_TAC `s:real^N->bool = {}` THENL
17747 [ASM_REWRITE_TAC[setdist; REAL_LE_REFL]; ALL_TAC] THEN
17748 ASM_MESON_TAC[SETDIST_LE_DIST; MEMBER_NOT_EMPTY; DIST_REFL]);;
17750 let SETDIST_SYM = prove
17751 (`!s t. setdist(s,t) = setdist(t,s)`,
17752 REPEAT GEN_TAC THEN REWRITE_TAC[setdist; DISJ_SYM] THEN
17753 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
17754 AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
17755 MESON_TAC[DIST_SYM]);;
17757 let SETDIST_TRIANGLE = prove
17758 (`!s a t:real^N->bool.
17759 setdist(s,t) <= setdist(s,{a}) + setdist({a},t)`,
17760 REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN
17761 ASM_REWRITE_TAC[SETDIST_EMPTY; REAL_ADD_LID; SETDIST_POS_LE] THEN
17762 ASM_CASES_TAC `t:real^N->bool = {}` THEN
17763 ASM_REWRITE_TAC[SETDIST_EMPTY; REAL_ADD_RID; SETDIST_POS_LE] THEN
17764 ONCE_REWRITE_TAC[GSYM REAL_LE_SUB_RADD] THEN
17765 MATCH_MP_TAC REAL_LE_SETDIST THEN
17766 ASM_REWRITE_TAC[NOT_INSERT_EMPTY; IN_SING; IMP_CONJ;
17767 RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN
17768 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
17769 ONCE_REWRITE_TAC[REAL_ARITH `x - y <= z <=> x - z <= y`] THEN
17770 MATCH_MP_TAC REAL_LE_SETDIST THEN
17771 ASM_REWRITE_TAC[NOT_INSERT_EMPTY; IN_SING; IMP_CONJ;
17772 RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN
17773 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
17774 REWRITE_TAC[REAL_LE_SUB_RADD] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
17775 EXISTS_TAC `dist(x:real^N,y)` THEN
17776 ASM_SIMP_TAC[SETDIST_LE_DIST] THEN CONV_TAC NORM_ARITH);;
17778 let SETDIST_SINGS = prove
17779 (`!x y. setdist({x},{y}) = dist(x,y)`,
17780 REWRITE_TAC[setdist; NOT_INSERT_EMPTY] THEN
17781 REWRITE_TAC[SET_RULE `{f x y | x IN {a} /\ y IN {b}} = {f a b}`] THEN
17782 SIMP_TAC[INF_INSERT_FINITE; FINITE_EMPTY]);;
17784 let SETDIST_LIPSCHITZ = prove
17785 (`!s t x y:real^N. abs(setdist({x},s) - setdist({y},s)) <= dist(x,y)`,
17786 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM SETDIST_SINGS] THEN
17787 REWRITE_TAC[REAL_ARITH
17788 `abs(x - y) <= z <=> x <= z + y /\ y <= z + x`] THEN
17789 MESON_TAC[SETDIST_TRIANGLE; SETDIST_SYM]);;
17791 let CONTINUOUS_AT_LIFT_SETDIST = prove
17792 (`!s x:real^N. (\y. lift(setdist({y},s))) continuous (at x)`,
17793 REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_at; DIST_LIFT] THEN
17794 ASM_MESON_TAC[SETDIST_LIPSCHITZ; REAL_LET_TRANS]);;
17796 let CONTINUOUS_ON_LIFT_SETDIST = prove
17797 (`!s t:real^N->bool. (\y. lift(setdist({y},s))) continuous_on t`,
17798 MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON;
17799 CONTINUOUS_AT_LIFT_SETDIST]);;
17801 let UNIFORMLY_CONTINUOUS_ON_LIFT_SETDIST = prove
17802 (`!s t:real^N->bool.
17803 (\y. lift(setdist({y},s))) uniformly_continuous_on t`,
17804 REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on; DIST_LIFT] THEN
17805 ASM_MESON_TAC[SETDIST_LIPSCHITZ; REAL_LET_TRANS]);;
17807 let SETDIST_DIFFERENCES = prove
17808 (`!s t. setdist(s,t) = setdist({vec 0},{x - y:real^N | x IN s /\ y IN t})`,
17809 REPEAT GEN_TAC THEN REWRITE_TAC[setdist; NOT_INSERT_EMPTY;
17810 SET_RULE `{f x y | x IN s /\ y IN t} = {} <=> s = {} \/ t = {}`] THEN
17811 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN
17812 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_SING] THEN
17813 REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM; UNWIND_THM2; DIST_0] THEN
17814 REWRITE_TAC[dist] THEN MESON_TAC[]);;
17816 let SETDIST_SUBSET_RIGHT = prove
17817 (`!s t u:real^N->bool.
17818 ~(t = {}) /\ t SUBSET u ==> setdist(s,u) <= setdist(s,t)`,
17819 REPEAT STRIP_TAC THEN
17820 MAP_EVERY ASM_CASES_TAC [`s:real^N->bool = {}`; `u:real^N->bool = {}`] THEN
17821 ASM_REWRITE_TAC[SETDIST_EMPTY; SETDIST_POS_LE; REAL_LE_REFL] THEN
17822 ASM_REWRITE_TAC[setdist] THEN MATCH_MP_TAC REAL_LE_INF_SUBSET THEN
17823 ASM_REWRITE_TAC[FORALL_IN_GSPEC; SUBSET] THEN
17824 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
17825 MESON_TAC[DIST_POS_LE]);;
17827 let SETDIST_SUBSET_LEFT = prove
17828 (`!s t u:real^N->bool.
17829 ~(s = {}) /\ s SUBSET t ==> setdist(t,u) <= setdist(s,u)`,
17830 MESON_TAC[SETDIST_SUBSET_RIGHT; SETDIST_SYM]);;
17832 let SETDIST_CLOSURE = prove
17833 (`(!s t:real^N->bool. setdist(closure s,t) = setdist(s,t)) /\
17834 (!s t:real^N->bool. setdist(s,closure t) = setdist(s,t))`,
17835 GEN_REWRITE_TAC RAND_CONV [SWAP_FORALL_THM] THEN
17836 GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SETDIST_SYM] THEN
17838 REWRITE_TAC[MESON[REAL_LE_ANTISYM]
17839 `x:real = y <=> !d. d <= x <=> d <= y`] THEN
17840 REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN
17841 MAP_EVERY ASM_CASES_TAC [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN
17842 ASM_REWRITE_TAC[CLOSURE_EQ_EMPTY; CLOSURE_EMPTY; NOT_IN_EMPTY] THEN
17843 MATCH_MP_TAC(SET_RULE
17845 (!y. Q y /\ (!x. x IN s ==> P x y) ==> (!x. x IN c ==> P x y))
17846 ==> ((!x y. x IN c /\ Q y ==> P x y) <=>
17847 (!x y. x IN s /\ Q y ==> P x y))`) THEN
17848 REWRITE_TAC[CLOSURE_SUBSET] THEN GEN_TAC THEN STRIP_TAC THEN
17849 MATCH_MP_TAC CONTINUOUS_GE_ON_CLOSURE THEN
17850 ASM_REWRITE_TAC[o_DEF; dist] THEN
17851 MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN
17852 SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]);;
17854 let SETDIST_COMPACT_CLOSED = prove
17855 (`!s t:real^N->bool.
17856 compact s /\ closed t /\ ~(s = {}) /\ ~(t = {})
17857 ==> ?x y. x IN s /\ y IN t /\ dist(x,y) = setdist(s,t)`,
17858 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
17859 MATCH_MP_TAC(MESON[]
17860 `(!x y. P x /\ Q y ==> S x y) /\ (?x y. P x /\ Q y /\ R x y)
17861 ==> ?x y. P x /\ Q y /\ R x y /\ S x y`) THEN
17862 SIMP_TAC[SETDIST_LE_DIST] THEN
17863 ASM_REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN
17864 MP_TAC(ISPECL [`{x - y:real^N | x IN s /\ y IN t}`; `vec 0:real^N`]
17865 DISTANCE_ATTAINS_INF) THEN
17866 ASM_SIMP_TAC[COMPACT_CLOSED_DIFFERENCES; EXISTS_IN_GSPEC; FORALL_IN_GSPEC;
17867 DIST_0; GSYM CONJ_ASSOC] THEN
17868 REWRITE_TAC[dist] THEN DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[]);;
17870 let SETDIST_CLOSED_COMPACT = prove
17871 (`!s t:real^N->bool.
17872 closed s /\ compact t /\ ~(s = {}) /\ ~(t = {})
17873 ==> ?x y. x IN s /\ y IN t /\ dist(x,y) = setdist(s,t)`,
17874 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
17875 MATCH_MP_TAC(MESON[]
17876 `(!x y. P x /\ Q y ==> S x y) /\ (?x y. P x /\ Q y /\ R x y)
17877 ==> ?x y. P x /\ Q y /\ R x y /\ S x y`) THEN
17878 SIMP_TAC[SETDIST_LE_DIST] THEN
17879 ASM_REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN
17880 MP_TAC(ISPECL [`{x - y:real^N | x IN s /\ y IN t}`; `vec 0:real^N`]
17881 DISTANCE_ATTAINS_INF) THEN
17882 ASM_SIMP_TAC[CLOSED_COMPACT_DIFFERENCES; EXISTS_IN_GSPEC; FORALL_IN_GSPEC;
17883 DIST_0; GSYM CONJ_ASSOC] THEN
17884 REWRITE_TAC[dist] THEN DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[]);;
17886 let SETDIST_EQ_0_COMPACT_CLOSED = prove
17887 (`!s t:real^N->bool.
17888 compact s /\ closed t
17889 ==> (setdist(s,t) = &0 <=> s = {} \/ t = {} \/ ~(s INTER t = {}))`,
17890 REPEAT STRIP_TAC THEN
17891 MAP_EVERY ASM_CASES_TAC [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN
17892 ASM_REWRITE_TAC[SETDIST_EMPTY] THEN EQ_TAC THENL
17893 [MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`]
17894 SETDIST_COMPACT_CLOSED) THEN ASM_REWRITE_TAC[] THEN
17895 REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN MESON_TAC[DIST_EQ_0];
17896 REWRITE_TAC[GSYM REAL_LE_ANTISYM; SETDIST_POS_LE] THEN
17897 REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN
17898 MESON_TAC[SETDIST_LE_DIST; DIST_EQ_0]]);;
17900 let SETDIST_EQ_0_CLOSED_COMPACT = prove
17901 (`!s t:real^N->bool.
17902 closed s /\ compact t
17903 ==> (setdist(s,t) = &0 <=> s = {} \/ t = {} \/ ~(s INTER t = {}))`,
17904 ONCE_REWRITE_TAC[SETDIST_SYM] THEN
17905 SIMP_TAC[SETDIST_EQ_0_COMPACT_CLOSED] THEN SET_TAC[]);;
17907 let SETDIST_EQ_0_BOUNDED = prove
17908 (`!s t:real^N->bool.
17909 (bounded s \/ bounded t)
17910 ==> (setdist(s,t) = &0 <=>
17911 s = {} \/ t = {} \/ ~(closure(s) INTER closure(t) = {}))`,
17912 REPEAT GEN_TAC THEN
17913 MAP_EVERY ASM_CASES_TAC [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN
17914 ASM_REWRITE_TAC[SETDIST_EMPTY] THEN STRIP_TAC THEN
17915 ONCE_REWRITE_TAC[MESON[SETDIST_CLOSURE]
17916 `setdist(s,t) = setdist(closure s,closure t)`] THEN
17917 ASM_SIMP_TAC[SETDIST_EQ_0_COMPACT_CLOSED; SETDIST_EQ_0_CLOSED_COMPACT;
17918 COMPACT_CLOSURE; CLOSED_CLOSURE; CLOSURE_EQ_EMPTY]);;
17921 let SETDIST_TRANSLATION = prove
17923 setdist(IMAGE (\x. a + x) s,IMAGE (\x. a + x) t) = setdist(s,t)`,
17924 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[SETDIST_DIFFERENCES] THEN
17925 AP_TERM_TAC THEN AP_TERM_TAC THEN
17926 REWRITE_TAC[SET_RULE
17927 `{f x y | x IN IMAGE g s /\ y IN IMAGE g t} =
17928 {f (g x) (g y) | x IN s /\ y IN t}`] THEN
17929 REWRITE_TAC[VECTOR_ARITH `(a + x) - (a + y):real^N = x - y`]);;
17931 add_translation_invariants [SETDIST_TRANSLATION];;
17933 let SETDIST_LINEAR_IMAGE = prove
17934 (`!f:real^M->real^N s t.
17935 linear f /\ (!x. norm(f x) = norm x)
17936 ==> setdist(IMAGE f s,IMAGE f t) = setdist(s,t)`,
17937 REPEAT STRIP_TAC THEN REWRITE_TAC[setdist; IMAGE_EQ_EMPTY] THEN
17938 COND_CASES_TAC THEN ASM_REWRITE_TAC[dist] THEN AP_TERM_TAC THEN
17939 REWRITE_TAC[SET_RULE
17940 `{f x y | x IN IMAGE g s /\ y IN IMAGE g t} =
17941 {f (g x) (g y) | x IN s /\ y IN t}`] THEN
17942 FIRST_X_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_SUB th)]) THEN
17943 ASM_REWRITE_TAC[]);;
17945 add_linear_invariants [SETDIST_LINEAR_IMAGE];;
17947 let SETDIST_UNIQUE = prove
17948 (`!s t a b:real^N d.
17949 a IN s /\ b IN t /\ dist(a,b) = d /\
17950 (!x y. x IN s /\ y IN t ==> dist(a,b) <= dist(x,y))
17951 ==> setdist(s,t) = d`,
17952 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
17953 [ASM_MESON_TAC[SETDIST_LE_DIST];
17954 MATCH_MP_TAC REAL_LE_SETDIST THEN ASM SET_TAC[]]);;
17956 let SETDIST_CLOSEST_POINT = prove
17958 closed s /\ ~(s = {}) ==> setdist({a},s) = dist(a,closest_point s a)`,
17959 REPEAT STRIP_TAC THEN MATCH_MP_TAC SETDIST_UNIQUE THEN
17960 REWRITE_TAC[RIGHT_EXISTS_AND_THM; IN_SING; UNWIND_THM2] THEN
17961 EXISTS_TAC `closest_point s (a:real^N)` THEN
17962 ASM_MESON_TAC[CLOSEST_POINT_EXISTS; DIST_SYM]);;
17964 let SETDIST_EQ_0_SING = prove
17965 (`(!s x:real^N. setdist({x},s) = &0 <=> s = {} \/ x IN closure s) /\
17966 (!s x:real^N. setdist(s,{x}) = &0 <=> s = {} \/ x IN closure s)`,
17967 SIMP_TAC[SETDIST_EQ_0_BOUNDED; BOUNDED_SING; CLOSURE_SING] THEN SET_TAC[]);;
17969 let SETDIST_EQ_0_CLOSED = prove
17970 (`!s x. closed s ==> (setdist({x},s) = &0 <=> s = {} \/ x IN s)`,
17971 SIMP_TAC[SETDIST_EQ_0_COMPACT_CLOSED; COMPACT_SING] THEN SET_TAC[]);;
17973 let SETDIST_EQ_0_CLOSED_IN = prove
17974 (`!u s x. closed_in (subtopology euclidean u) s /\ x IN u
17975 ==> (setdist({x},s) = &0 <=> s = {} \/ x IN s)`,
17976 REWRITE_TAC[SETDIST_EQ_0_SING; CLOSED_IN_INTER_CLOSURE] THEN SET_TAC[]);;
17978 let SETDIST_SING_IN_SET = prove
17979 (`!x s. x IN s ==> setdist({x},s) = &0`,
17980 SIMP_TAC[SETDIST_EQ_0_SING; REWRITE_RULE[SUBSET] CLOSURE_SUBSET]);;
17982 let SETDIST_SING_TRIANGLE = prove
17983 (`!s x y:real^N. abs(setdist({x},s) - setdist({y},s)) <= dist(x,y)`,
17984 REPEAT GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN
17985 ASM_REWRITE_TAC[SETDIST_EMPTY; REAL_SUB_REFL; REAL_ABS_NUM; DIST_POS_LE] THEN
17986 REWRITE_TAC[GSYM REAL_BOUNDS_LE; REAL_NEG_SUB] THEN REPEAT STRIP_TAC THEN
17987 ONCE_REWRITE_TAC[REAL_ARITH `a - b <= c <=> a - c <= b`;
17988 REAL_ARITH `--a <= b - c <=> c - a <= b`] THEN
17989 MATCH_MP_TAC REAL_LE_SETDIST THEN ASM_REWRITE_TAC[NOT_INSERT_EMPTY] THEN
17990 SIMP_TAC[IN_SING; IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN
17991 X_GEN_TAC `z:real^N` THEN DISCH_TAC THENL
17992 [MATCH_MP_TAC(NORM_ARITH
17993 `a <= dist(y:real^N,z) ==> a - dist(x,y) <= dist(x,z)`);
17994 MATCH_MP_TAC(NORM_ARITH
17995 `a <= dist(x:real^N,z) ==> a - dist(x,y) <= dist(y,z)`)] THEN
17996 MATCH_MP_TAC SETDIST_LE_DIST THEN ASM_REWRITE_TAC[IN_SING]);;
17998 let SETDIST_LE_SING = prove
17999 (`!s t x:real^N. x IN s ==> setdist(s,t) <= setdist({x},t)`,
18000 REPEAT STRIP_TAC THEN MATCH_MP_TAC SETDIST_SUBSET_LEFT THEN ASM SET_TAC[]);;
18002 let SETDIST_BALLS = prove
18003 (`(!a b:real^N r s.
18004 setdist(ball(a,r),ball(b,s)) =
18005 if r <= &0 \/ s <= &0 then &0 else max (&0) (dist(a,b) - (r + s))) /\
18007 setdist(ball(a,r),cball(b,s)) =
18008 if r <= &0 \/ s < &0 then &0 else max (&0) (dist(a,b) - (r + s))) /\
18010 setdist(cball(a,r),ball(b,s)) =
18011 if r < &0 \/ s <= &0 then &0 else max (&0) (dist(a,b) - (r + s))) /\
18013 setdist(cball(a,r),cball(b,s)) =
18014 if r < &0 \/ s < &0 then &0 else max (&0) (dist(a,b) - (r + s)))`,
18015 REWRITE_TAC[MESON[]
18016 `(x = if p then y else z) <=> (p ==> x = y) /\ (~p ==> x = z)`] THEN
18017 SIMP_TAC[TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN
18018 SIMP_TAC[BALL_EMPTY; CBALL_EMPTY; SETDIST_EMPTY; DE_MORGAN_THM] THEN
18019 ONCE_REWRITE_TAC[MESON[SETDIST_CLOSURE]
18020 `setdist(s,t) = setdist(closure s,closure t)`] THEN
18021 SIMP_TAC[REAL_NOT_LE; REAL_NOT_LT; CLOSURE_BALL] THEN
18022 REWRITE_TAC[SETDIST_CLOSURE] THEN
18023 MATCH_MP_TAC(TAUT `(s ==> p /\ q /\ r) /\ s ==> p /\ q /\ r /\ s`) THEN
18024 CONJ_TAC THENL [MESON_TAC[REAL_LT_IMP_LE]; REPEAT GEN_TAC] THEN
18025 REWRITE_TAC[real_max; REAL_SUB_LE] THEN COND_CASES_TAC THEN
18026 SIMP_TAC[SETDIST_EQ_0_BOUNDED; BOUNDED_CBALL; CLOSED_CBALL; CLOSURE_CLOSED;
18027 CBALL_EQ_EMPTY; INTER_BALLS_EQ_EMPTY]
18028 THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN
18029 ASM_CASES_TAC `b:real^N = a` THENL
18030 [FIRST_X_ASSUM SUBST_ALL_TAC THEN
18031 RULE_ASSUM_TAC(REWRITE_RULE[DIST_REFL]) THEN
18032 ASM_CASES_TAC `r = &0 /\ s = &0` THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN
18033 ASM_SIMP_TAC[CBALL_SING; SETDIST_SINGS] THEN REAL_ARITH_TAC;
18035 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
18037 MATCH_MP_TAC REAL_LE_SETDIST THEN
18038 ASM_REWRITE_TAC[CBALL_EQ_EMPTY; REAL_NOT_LT; IN_CBALL] THEN
18039 CONV_TAC NORM_ARITH] THEN
18040 MATCH_MP_TAC REAL_LE_TRANS THEN
18041 EXISTS_TAC `dist(a + r / dist(a,b) % (b - a):real^N,
18042 b - s / dist(a,b) % (b - a))` THEN
18044 [MATCH_MP_TAC SETDIST_LE_DIST THEN
18045 REWRITE_TAC[IN_CBALL; NORM_ARITH `dist(a:real^N,a + x) = norm x`;
18046 NORM_ARITH `dist(a:real^N,a - x) = norm x`] THEN
18047 ONCE_REWRITE_TAC[DIST_SYM] THEN
18048 REWRITE_TAC[dist; NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN
18049 ASM_SIMP_TAC[REAL_DIV_RMUL; VECTOR_SUB_EQ; NORM_EQ_0] THEN
18050 ASM_REAL_ARITH_TAC;
18051 REWRITE_TAC[dist; VECTOR_ARITH
18052 `(a + d % (b - a)) - (b - e % (b - a)):real^N =
18053 (&1 - d - e) % (a - b)`] THEN
18054 REWRITE_TAC[NORM_MUL; REAL_ARITH
18055 `&1 - r / y - s / y = &1 - (r + s) / y`] THEN
18056 ONCE_REWRITE_TAC[GSYM REAL_ABS_NORM] THEN
18057 REWRITE_TAC[GSYM REAL_ABS_MUL] THEN REWRITE_TAC[REAL_ABS_NORM] THEN
18058 ASM_SIMP_TAC[VECTOR_SUB_EQ; NORM_EQ_0; REAL_FIELD
18059 `~(n = &0) ==> (&1 - x / n) * n = n - x`] THEN
18060 REWRITE_TAC[GSYM dist] THEN ASM_REAL_ARITH_TAC]);;
18062 (* ------------------------------------------------------------------------- *)
18063 (* Use set distance for an easy proof of separation properties etc. *)
18064 (* ------------------------------------------------------------------------- *)
18066 let SEPARATION_CLOSURES = prove
18067 (`!s t:real^N->bool.
18068 s INTER closure(t) = {} /\ t INTER closure(s) = {}
18069 ==> ?u v. DISJOINT u v /\ open u /\ open v /\
18070 s SUBSET u /\ t SUBSET v`,
18071 REPEAT STRIP_TAC THEN
18072 ASM_CASES_TAC `s:real^N->bool = {}` THENL
18073 [MAP_EVERY EXISTS_TAC [`{}:real^N->bool`; `(:real^N)`] THEN
18074 ASM_REWRITE_TAC[OPEN_EMPTY; OPEN_UNIV] THEN ASM SET_TAC[];
18076 ASM_CASES_TAC `t:real^N->bool = {}` THENL
18077 [MAP_EVERY EXISTS_TAC [`(:real^N)`; `{}:real^N->bool`] THEN
18078 ASM_REWRITE_TAC[OPEN_EMPTY; OPEN_UNIV] THEN ASM SET_TAC[];
18080 EXISTS_TAC `{x | x IN (:real^N) /\
18081 lift(setdist({x},t) - setdist({x},s)) IN
18082 {x | &0 < x$1}}` THEN
18083 EXISTS_TAC `{x | x IN (:real^N) /\
18084 lift(setdist({x},t) - setdist({x},s)) IN
18085 {x | x$1 < &0}}` THEN
18086 REPEAT CONJ_TAC THENL
18087 [REWRITE_TAC[SET_RULE `DISJOINT s t <=> !x. x IN s /\ x IN t ==> F`] THEN
18088 REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN REAL_ARITH_TAC;
18089 MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE THEN
18090 SIMP_TAC[REWRITE_RULE[real_gt] OPEN_HALFSPACE_COMPONENT_GT; OPEN_UNIV] THEN
18091 SIMP_TAC[LIFT_SUB; CONTINUOUS_ON_SUB; CONTINUOUS_ON_LIFT_SETDIST];
18092 MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE THEN
18093 SIMP_TAC[OPEN_HALFSPACE_COMPONENT_LT; OPEN_UNIV] THEN
18094 SIMP_TAC[LIFT_SUB; CONTINUOUS_ON_SUB; CONTINUOUS_ON_LIFT_SETDIST];
18095 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNIV; GSYM drop; LIFT_DROP] THEN
18096 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH
18097 `&0 <= x /\ y = &0 /\ ~(x = &0) ==> &0 < x - y`);
18098 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNIV; GSYM drop; LIFT_DROP] THEN
18099 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH
18100 `&0 <= y /\ x = &0 /\ ~(y = &0) ==> x - y < &0`)] THEN
18101 ASM_SIMP_TAC[SETDIST_POS_LE; SETDIST_EQ_0_BOUNDED; BOUNDED_SING] THEN
18102 ASM_SIMP_TAC[CLOSED_SING; CLOSURE_CLOSED; NOT_INSERT_EMPTY;
18103 REWRITE_RULE[SUBSET] CLOSURE_SUBSET;
18104 SET_RULE `{a} INTER s = {} <=> ~(a IN s)`] THEN
18107 let SEPARATION_NORMAL = prove
18108 (`!s t:real^N->bool.
18109 closed s /\ closed t /\ s INTER t = {}
18110 ==> ?u v. open u /\ open v /\
18111 s SUBSET u /\ t SUBSET v /\ u INTER v = {}`,
18112 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM DISJOINT] THEN
18113 ONCE_REWRITE_TAC[TAUT
18114 `a /\ b /\ c /\ d /\ e <=> e /\ a /\ b /\ c /\ d`] THEN
18115 MATCH_MP_TAC SEPARATION_CLOSURES THEN
18116 ASM_SIMP_TAC[CLOSURE_CLOSED] THEN ASM SET_TAC[]);;
18118 let SEPARATION_NORMAL_LOCAL = prove
18119 (`!s t u:real^N->bool.
18120 closed_in (subtopology euclidean u) s /\
18121 closed_in (subtopology euclidean u) t /\
18123 ==> ?s' t'. open_in (subtopology euclidean u) s' /\
18124 open_in (subtopology euclidean u) t' /\
18125 s SUBSET s' /\ t SUBSET t' /\ s' INTER t' = {}`,
18126 REPEAT STRIP_TAC THEN
18127 ASM_CASES_TAC `s:real^N->bool = {}` THENL
18128 [MAP_EVERY EXISTS_TAC [`{}:real^N->bool`; `u:real^N->bool`] THEN
18129 ASM_SIMP_TAC[OPEN_IN_REFL; OPEN_IN_EMPTY; INTER_EMPTY; EMPTY_SUBSET] THEN
18130 ASM_MESON_TAC[CLOSED_IN_IMP_SUBSET];
18132 ASM_CASES_TAC `t:real^N->bool = {}` THENL
18133 [MAP_EVERY EXISTS_TAC [`u:real^N->bool`; `{}:real^N->bool`] THEN
18134 ASM_SIMP_TAC[OPEN_IN_REFL; OPEN_IN_EMPTY; INTER_EMPTY; EMPTY_SUBSET] THEN
18135 ASM_MESON_TAC[CLOSED_IN_IMP_SUBSET];
18137 EXISTS_TAC `{x:real^N | x IN u /\ setdist({x},s) < setdist({x},t)}` THEN
18138 EXISTS_TAC `{x:real^N | x IN u /\ setdist({x},t) < setdist({x},s)}` THEN
18139 SIMP_TAC[EXTENSION; SUBSET; IN_ELIM_THM; SETDIST_SING_IN_SET; IN_INTER;
18140 NOT_IN_EMPTY; SETDIST_POS_LE; CONJ_ASSOC;
18141 REAL_ARITH `&0 < x <=> &0 <= x /\ ~(x = &0)`] THEN
18142 CONJ_TAC THENL [ALL_TAC; MESON_TAC[REAL_LT_ANTISYM]] THEN
18143 ONCE_REWRITE_TAC[GSYM CONJ_ASSOC] THEN CONJ_TAC THENL
18145 ASM_MESON_TAC[SETDIST_EQ_0_CLOSED_IN; CLOSED_IN_IMP_SUBSET; SUBSET;
18146 MEMBER_NOT_EMPTY; IN_INTER]] THEN
18147 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN
18148 ONCE_REWRITE_TAC[MESON[LIFT_DROP] `&0 < x <=> &0 < drop(lift x)`] THEN
18149 REWRITE_TAC[SET_RULE
18150 `{x | x IN u /\ &0 < drop(f x)} =
18151 {x | x IN u /\ f x IN {x | &0 < drop x}}`] THEN
18152 REWRITE_TAC[drop] THEN CONJ_TAC THEN
18153 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE THEN
18154 REWRITE_TAC[OPEN_HALFSPACE_COMPONENT_LT; LIFT_SUB;
18155 REWRITE_RULE[real_gt] OPEN_HALFSPACE_COMPONENT_GT; OPEN_UNIV] THEN
18156 SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_LIFT_SETDIST]);;
18158 let SEPARATION_NORMAL_COMPACT = prove
18159 (`!s t:real^N->bool.
18160 compact s /\ closed t /\ s INTER t = {}
18161 ==> ?u v. open u /\ compact(closure u) /\ open v /\
18162 s SUBSET u /\ t SUBSET v /\ u INTER v = {}`,
18163 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_CLOSURE] THEN
18164 REPEAT STRIP_TAC THEN FIRST_ASSUM
18165 (MP_TAC o SPEC `vec 0:real^N` o MATCH_MP BOUNDED_SUBSET_BALL) THEN
18166 DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN
18167 MP_TAC(ISPECL [`s:real^N->bool`; `t UNION ((:real^N) DIFF ball(vec 0,r))`]
18168 SEPARATION_NORMAL) THEN
18169 ASM_SIMP_TAC[CLOSED_UNION; GSYM OPEN_CLOSED; OPEN_BALL] THEN
18170 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
18171 REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
18172 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
18173 CONJ_TAC THENL [MATCH_MP_TAC BOUNDED_CLOSURE; ASM SET_TAC[]] THEN
18174 MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC `ball(vec 0:real^N,r)` THEN
18175 REWRITE_TAC[BOUNDED_BALL] THEN ASM SET_TAC[]);;
18177 let SEPARATION_HAUSDORFF = prove
18180 ==> ?u v. open u /\ open v /\ x IN u /\ y IN v /\ (u INTER v = {})`,
18181 REPEAT STRIP_TAC THEN
18182 MP_TAC(SPECL [`{x:real^N}`; `{y:real^N}`] SEPARATION_NORMAL) THEN
18183 REWRITE_TAC[SING_SUBSET; CLOSED_SING] THEN
18184 DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[]);;
18186 let SEPARATION_T2 = prove
18188 ~(x = y) <=> ?u v. open u /\ open v /\ x IN u /\ y IN v /\
18190 REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[SEPARATION_HAUSDORFF] THEN
18191 REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN MESON_TAC[]);;
18193 let SEPARATION_T1 = prove
18195 ~(x = y) <=> ?u v. open u /\ open v /\ x IN u /\ ~(y IN u) /\
18196 ~(x IN v) /\ y IN v`,
18197 REPEAT STRIP_TAC THEN EQ_TAC THENL
18198 [ASM_SIMP_TAC[SEPARATION_T2; EXTENSION; NOT_IN_EMPTY; IN_INTER];
18199 ALL_TAC] THEN MESON_TAC[]);;
18201 let SEPARATION_T0 = prove
18202 (`!x:real^N y. ~(x = y) <=> ?u. open u /\ ~(x IN u <=> y IN u)`,
18203 MESON_TAC[SEPARATION_T1]);;
18205 (* ------------------------------------------------------------------------- *)
18206 (* Hausdorff distance between sets. *)
18207 (* ------------------------------------------------------------------------- *)
18209 let hausdist = new_definition
18210 `hausdist(s:real^N->bool,t:real^N->bool) =
18211 let ds = {setdist({x},t) | x IN s} UNION {setdist({y},s) | y IN t} in
18212 if ~(ds = {}) /\ (?b. !d. d IN ds ==> d <= b) then sup ds
18215 let HAUSDIST_POS_LE = prove
18216 (`!s t:real^N->bool. &0 <= hausdist(s,t)`,
18217 REPEAT GEN_TAC THEN REWRITE_TAC[hausdist; LET_DEF; LET_END_DEF] THEN
18218 REWRITE_TAC[FORALL_IN_GSPEC; FORALL_IN_UNION] THEN
18219 COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN
18220 MATCH_MP_TAC REAL_LE_SUP THEN
18221 ASM_REWRITE_TAC[FORALL_IN_GSPEC; FORALL_IN_UNION; SETDIST_POS_LE] THEN
18222 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
18223 ASM_REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN
18224 MATCH_MP_TAC(SET_RULE
18225 `~(s = {}) /\ (!x. x IN s ==> P x) ==> ?y. y IN s /\ P y`) THEN
18226 ASM_REWRITE_TAC[FORALL_IN_GSPEC; FORALL_IN_UNION; SETDIST_POS_LE]);;
18228 let HAUSDIST_REFL = prove
18229 (`!s:real^N->bool. hausdist(s,s) = &0`,
18230 GEN_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM; HAUSDIST_POS_LE] THEN
18231 REWRITE_TAC[hausdist; LET_DEF; LET_END_DEF] THEN
18232 COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN
18233 MATCH_MP_TAC REAL_SUP_LE THEN
18234 REWRITE_TAC[FORALL_IN_GSPEC; FORALL_IN_UNION] THEN
18235 ASM_SIMP_TAC[SETDIST_SING_IN_SET; REAL_LE_REFL]);;
18237 let HAUSDIST_SYM = prove
18238 (`!s t:real^N->bool. hausdist(s,t) = hausdist(t,s)`,
18239 REPEAT GEN_TAC THEN REWRITE_TAC[hausdist; LET_DEF; LET_END_DEF] THEN
18240 GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [UNION_COMM] THEN
18243 let HAUSDIST_EMPTY = prove
18244 (`(!t:real^N->bool. hausdist ({},t) = &0) /\
18245 (!s:real^N->bool. hausdist (s,{}) = &0)`,
18246 REWRITE_TAC[hausdist; LET_DEF; LET_END_DEF; SETDIST_EMPTY] THEN
18247 REWRITE_TAC[SET_RULE `{f x | x IN {}} = {}`; UNION_EMPTY] THEN
18248 REWRITE_TAC[SET_RULE `{c |x| x IN s} = {} <=> s = {}`] THEN
18249 X_GEN_TAC `s:real^N->bool` THEN
18250 ASM_CASES_TAC `s:real^N->bool = {}` THEN ASM_REWRITE_TAC[] THEN
18251 ASM_SIMP_TAC[SET_RULE `~(s = {}) ==> {c |x| x IN s} = {c}`] THEN
18252 REWRITE_TAC[SUP_SING; COND_ID]);;
18254 let HAUSDIST_SINGS = prove
18255 (`!x y:real^N. hausdist({x},{y}) = dist(x,y)`,
18256 REWRITE_TAC[hausdist; LET_DEF; LET_END_DEF; SETDIST_SINGS] THEN
18257 REWRITE_TAC[SET_RULE `{f x | x IN {a}} = {f a}`] THEN
18258 REWRITE_TAC[DIST_SYM; UNION_IDEMPOT; SUP_SING; NOT_INSERT_EMPTY] THEN
18259 REWRITE_TAC[IN_SING; FORALL_UNWIND_THM2] THEN
18260 MESON_TAC[REAL_LE_REFL]);;
18262 let HAUSDIST_EQ = prove
18263 (`!s t:real^M->bool s' t':real^N->bool.
18264 (!b. (!x. x IN s ==> setdist({x},t) <= b) /\
18265 (!y. y IN t ==> setdist({y},s) <= b) <=>
18266 (!x. x IN s' ==> setdist({x},t') <= b) /\
18267 (!y. y IN t' ==> setdist({y},s') <= b))
18268 ==> hausdist(s,t) = hausdist(s',t')`,
18269 REPEAT STRIP_TAC THEN REWRITE_TAC[hausdist; LET_DEF; LET_END_DEF] THEN
18270 MATCH_MP_TAC(MESON[]
18271 `(p <=> p') /\ s = s'
18272 ==> (if p then s else &0) = (if p' then s' else &0)`) THEN
18275 [PURE_REWRITE_TAC[SET_RULE `s = {} <=> !x. x IN s ==> F`];
18276 AP_TERM_TAC THEN ABS_TAC];
18277 MATCH_MP_TAC SUP_EQ] THEN
18278 PURE_REWRITE_TAC[FORALL_IN_UNION; FORALL_IN_GSPEC] THEN
18279 ASM_REWRITE_TAC[] THEN
18280 REWRITE_TAC[DE_MORGAN_THM; NOT_FORALL_THM; MEMBER_NOT_EMPTY] THEN
18281 REWRITE_TAC[GSYM DE_MORGAN_THM] THEN AP_TERM_TAC THEN EQ_TAC THEN
18282 DISCH_THEN(fun th -> POP_ASSUM MP_TAC THEN ASSUME_TAC th) THEN
18283 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
18284 DISCH_THEN(MP_TAC o SPEC `--(&1):real`) THEN
18285 SIMP_TAC[SETDIST_POS_LE; REAL_ARITH `&0 <= x ==> ~(x <= --(&1))`] THEN
18288 let HAUSDIST_TRANSLATION = prove
18289 (`!a s t:real^N->bool.
18290 hausdist(IMAGE (\x. a + x) s,IMAGE (\x. a + x) t) = hausdist(s,t)`,
18291 REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN
18292 REWRITE_TAC[SET_RULE `{f x | x IN IMAGE g s} = {f(g x) | x IN s}`] THEN
18293 REWRITE_TAC[SET_RULE `{a + x:real^N} = IMAGE (\x. a + x) {x}`] THEN
18294 REWRITE_TAC[SETDIST_TRANSLATION]);;
18296 add_translation_invariants [HAUSDIST_TRANSLATION];;
18298 let HAUSDIST_LINEAR_IMAGE = prove
18299 (`!f:real^M->real^N s t.
18300 linear f /\ (!x. norm(f x) = norm x)
18301 ==> hausdist(IMAGE f s,IMAGE f t) = hausdist(s,t)`,
18302 REPEAT STRIP_TAC THEN
18303 REPEAT GEN_TAC THEN REWRITE_TAC[hausdist] THEN
18304 REWRITE_TAC[SET_RULE `{f x | x IN IMAGE g s} = {f(g x) | x IN s}`] THEN
18305 ONCE_REWRITE_TAC[SET_RULE `{(f:real^M->real^N) x} = IMAGE f {x}`] THEN
18306 ASM_SIMP_TAC[SETDIST_LINEAR_IMAGE]);;
18308 add_linear_invariants [HAUSDIST_LINEAR_IMAGE];;
18310 let HAUSDIST_CLOSURE = prove
18311 (`(!s t:real^N->bool. hausdist(closure s,t) = hausdist(s,t)) /\
18312 (!s t:real^N->bool. hausdist(s,closure t) = hausdist(s,t))`,
18313 REPEAT STRIP_TAC THEN MATCH_MP_TAC HAUSDIST_EQ THEN
18314 GEN_TAC THEN BINOP_TAC THEN REWRITE_TAC[SETDIST_CLOSURE] THEN
18315 PURE_ONCE_REWRITE_TAC[SET_RULE
18316 `(!x. P x ==> Q x) <=> (!x. P x ==> x IN {x | Q x})`] THEN
18317 MATCH_MP_TAC FORALL_IN_CLOSURE_EQ THEN
18318 REWRITE_TAC[EMPTY_GSPEC; CONTINUOUS_ON_ID; CLOSED_EMPTY] THEN
18319 ONCE_REWRITE_TAC[MESON[LIFT_DROP] `x <= b <=> drop(lift x) <= b`] THEN
18320 REWRITE_TAC[SET_RULE
18321 `{x | drop(lift(f x)) <= b} =
18322 {x | x IN UNIV /\ lift(f x) IN {x | drop x <= b}}`] THEN
18323 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN
18324 REWRITE_TAC[CLOSED_UNIV; CONTINUOUS_ON_LIFT_SETDIST] THEN
18325 REWRITE_TAC[drop; CLOSED_HALFSPACE_COMPONENT_LE]);;
18327 let REAL_HAUSDIST_LE = prove
18328 (`!s t:real^N->bool b.
18329 ~(s = {}) /\ ~(t = {}) /\
18330 (!x. x IN s ==> setdist({x},t) <= b) /\
18331 (!y. y IN t ==> setdist({y},s) <= b)
18332 ==> hausdist(s,t) <= b`,
18333 REPEAT STRIP_TAC THEN
18334 REWRITE_TAC[hausdist; LET_DEF; LET_END_DEF; SETDIST_SINGS] THEN
18335 ASM_REWRITE_TAC[EMPTY_UNION; SET_RULE `{f x | x IN s} = {} <=> s = {}`] THEN
18336 REWRITE_TAC[FORALL_IN_UNION; FORALL_IN_GSPEC] THEN
18337 COND_CASES_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
18338 MATCH_MP_TAC REAL_SUP_LE THEN
18339 ASM_REWRITE_TAC[EMPTY_UNION; SET_RULE `{f x | x IN s} = {} <=> s = {}`] THEN
18340 ASM_REWRITE_TAC[FORALL_IN_UNION; FORALL_IN_GSPEC]);;
18342 let REAL_HAUSDIST_LE_SUMS = prove
18343 (`!s t:real^N->bool b.
18344 ~(s = {}) /\ ~(t = {}) /\
18345 s SUBSET {y + z | y IN t /\ z IN cball(vec 0,b)} /\
18346 t SUBSET {y + z | y IN s /\ z IN cball(vec 0,b)}
18347 ==> hausdist(s,t) <= b`,
18348 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_CBALL_0] THEN
18349 REWRITE_TAC[VECTOR_ARITH `a:real^N = b + x <=> a - b = x`;
18350 ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN
18351 REWRITE_TAC[GSYM dist] THEN REPEAT STRIP_TAC THEN
18352 MATCH_MP_TAC REAL_HAUSDIST_LE THEN
18353 ASM_MESON_TAC[SETDIST_LE_DIST; REAL_LE_TRANS; IN_SING]);;
18355 let REAL_LE_HAUSDIST = prove
18356 (`!s t:real^N->bool a b c z.
18357 ~(s = {}) /\ ~(t = {}) /\
18358 (!x. x IN s ==> setdist({x},t) <= b) /\
18359 (!y. y IN t ==> setdist({y},s) <= c) /\
18360 (z IN s /\ a <= setdist({z},t) \/ z IN t /\ a <= setdist({z},s))
18361 ==> a <= hausdist(s,t)`,
18362 REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
18363 REWRITE_TAC[hausdist; LET_DEF; LET_END_DEF; SETDIST_SINGS] THEN
18364 ASM_REWRITE_TAC[EMPTY_UNION; SET_RULE `{f x | x IN s} = {} <=> s = {}`] THEN
18365 REWRITE_TAC[FORALL_IN_UNION; FORALL_IN_GSPEC] THEN COND_CASES_TAC THENL
18366 [MATCH_MP_TAC REAL_LE_SUP THEN
18367 ASM_SIMP_TAC[EMPTY_UNION; SET_RULE `{f x | x IN s} = {} <=> s = {}`] THEN
18368 REWRITE_TAC[FORALL_IN_UNION; FORALL_IN_GSPEC];
18369 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN
18370 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
18371 REWRITE_TAC[NOT_FORALL_THM]] THEN
18372 EXISTS_TAC `max b c:real` THEN
18373 ASM_SIMP_TAC[REAL_LE_MAX] THEN ASM SET_TAC[]);;
18375 let SETDIST_LE_HAUSDIST = prove
18376 (`!s t:real^N->bool.
18377 bounded s /\ bounded t ==> setdist(s,t) <= hausdist(s,t)`,
18378 REPEAT STRIP_TAC THEN
18379 ASM_CASES_TAC `s:real^N->bool = {}` THEN
18380 ASM_REWRITE_TAC[SETDIST_EMPTY; HAUSDIST_EMPTY; REAL_LE_REFL] THEN
18381 ASM_CASES_TAC `t:real^N->bool = {}` THEN
18382 ASM_REWRITE_TAC[SETDIST_EMPTY; HAUSDIST_EMPTY; REAL_LE_REFL] THEN
18383 MATCH_MP_TAC REAL_LE_HAUSDIST THEN REWRITE_TAC[CONJ_ASSOC] THEN
18384 ASM_REWRITE_TAC[RIGHT_EXISTS_AND_THM; LEFT_EXISTS_AND_THM] THEN
18386 [ALL_TAC; ASM_MESON_TAC[SETDIST_LE_SING; MEMBER_NOT_EMPTY]] THEN
18387 MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`] BOUNDED_DIFFS) THEN
18388 ASM_REWRITE_TAC[] THEN REWRITE_TAC[bounded; FORALL_IN_GSPEC; GSYM dist] THEN
18389 DISCH_THEN(X_CHOOSE_TAC `b:real`) THEN
18390 CONJ_TAC THEN EXISTS_TAC `b:real` THEN REPEAT STRIP_TAC THEN
18391 ASM_MESON_TAC[REAL_LE_TRANS; SETDIST_LE_DIST; MEMBER_NOT_EMPTY; IN_SING;
18394 let SETDIST_SING_LE_HAUSDIST = prove
18396 bounded s /\ bounded t /\ x IN s ==> setdist({x},t) <= hausdist(s,t)`,
18397 REPEAT GEN_TAC THEN
18398 ASM_CASES_TAC `s:real^N->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
18399 ASM_CASES_TAC `t:real^N->bool = {}` THEN
18400 ASM_REWRITE_TAC[SETDIST_EMPTY; HAUSDIST_EMPTY; REAL_LE_REFL] THEN
18401 STRIP_TAC THEN MATCH_MP_TAC REAL_LE_HAUSDIST THEN
18402 ASM_REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN
18403 REWRITE_TAC[LEFT_EXISTS_AND_THM; EXISTS_OR_THM; CONJ_ASSOC] THEN
18404 CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LE_REFL]] THEN CONJ_TAC THEN
18405 MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`] BOUNDED_DIFFS) THEN
18406 ASM_REWRITE_TAC[] THEN REWRITE_TAC[bounded; FORALL_IN_GSPEC] THEN
18407 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[GSYM dist] THEN GEN_TAC THENL
18408 [ALL_TAC; ONCE_REWRITE_TAC[SWAP_FORALL_THM]] THEN
18409 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `y:real^N` THEN
18410 REPEAT STRIP_TAC THENL
18411 [UNDISCH_TAC `~(t:real^N->bool = {})`;
18412 UNDISCH_TAC `~(s:real^N->bool = {})`] THEN
18413 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
18414 DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
18415 FIRST_X_ASSUM(MP_TAC o SPEC `z:real^N`) THEN ASM_REWRITE_TAC[] THEN
18416 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THENL
18417 [ALL_TAC; ONCE_REWRITE_TAC[DIST_SYM]] THEN
18418 MATCH_MP_TAC SETDIST_LE_DIST THEN ASM_REWRITE_TAC[IN_SING]);;
18420 let UPPER_LOWER_HEMICONTINUOUS = prove
18421 (`!f:real^M->real^N->bool t s.
18422 (!x. x IN s ==> f(x) SUBSET t) /\
18423 (!u. open_in (subtopology euclidean t) u
18424 ==> open_in (subtopology euclidean s)
18425 {x | x IN s /\ f(x) SUBSET u}) /\
18426 (!u. closed_in (subtopology euclidean t) u
18427 ==> closed_in (subtopology euclidean s)
18428 {x | x IN s /\ f(x) SUBSET u})
18429 ==> !x e. x IN s /\ &0 < e /\ bounded(f x)
18431 !x'. x' IN s /\ dist(x,x') < d
18432 ==> hausdist(f x,f x') < e`,
18433 REPEAT GEN_TAC THEN DISCH_TAC THEN REPEAT STRIP_TAC THEN
18434 ASM_CASES_TAC `(f:real^M->real^N->bool) x = {}` THENL
18435 [ASM_REWRITE_TAC[HAUSDIST_EMPTY] THEN MESON_TAC[REAL_LT_01]; ALL_TAC] THEN
18436 FIRST_ASSUM(MP_TAC o SPECL [`x:real^M`; `e / &2`] o MATCH_MP
18437 UPPER_LOWER_HEMICONTINUOUS_EXPLICIT) THEN
18438 ASM_REWRITE_TAC[REAL_HALF] THEN
18439 DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN
18440 FIRST_ASSUM(MP_TAC o SPEC `vec 0:real^N` o MATCH_MP BOUNDED_SUBSET_BALL) THEN
18441 DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN
18442 FIRST_ASSUM(MP_TAC o SPEC `t INTER ball(vec 0:real^N,r)` o
18443 CONJUNCT1 o CONJUNCT2) THEN
18444 SIMP_TAC[OPEN_IN_OPEN_INTER; OPEN_BALL] THEN REWRITE_TAC[open_in] THEN
18445 DISCH_THEN(MP_TAC o SPEC `x:real^M` o CONJUNCT2) THEN
18446 ASM_SIMP_TAC[SUBSET_INTER; IN_ELIM_THM] THEN
18447 DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN
18448 EXISTS_TAC `min d1 d2:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
18449 X_GEN_TAC `x':real^M` THEN STRIP_TAC THEN
18450 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `x':real^M`)) THEN
18451 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN ASM_REWRITE_TAC[] THEN
18452 STRIP_TAC THEN STRIP_TAC THEN
18453 ASM_CASES_TAC `(f:real^M->real^N->bool) x' = {}` THEN
18454 ASM_REWRITE_TAC[HAUSDIST_EMPTY] THEN
18455 MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
18456 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_HAUSDIST_LE THEN
18457 ASM_MESON_TAC[SETDIST_LE_DIST; DIST_SYM; REAL_LE_TRANS;
18458 IN_SING; REAL_LT_IMP_LE]);;
18460 let HAUSDIST_NONTRIVIAL = prove
18461 (`!s t:real^N->bool.
18462 bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {})
18463 ==> hausdist(s,t) =
18464 sup({setdist ({x},t) | x IN s} UNION {setdist ({y},s) | y IN t})`,
18465 REPEAT STRIP_TAC THEN REWRITE_TAC[hausdist; LET_DEF; LET_END_DEF] THEN
18466 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
18467 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DE_MORGAN_THM]) THEN
18468 ASM_SIMP_TAC[EMPTY_UNION; SIMPLE_IMAGE; IMAGE_EQ_EMPTY] THEN
18469 MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN
18470 MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`] BOUNDED_DIFFS) THEN
18471 ASM_REWRITE_TAC[bounded; FORALL_IN_UNION; FORALL_IN_IMAGE; GSYM dist] THEN
18472 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN
18473 ASM_MESON_TAC[SETDIST_LE_DIST; dist; DIST_SYM; REAL_LE_TRANS;
18474 MEMBER_NOT_EMPTY; IN_SING]);;
18476 let HAUSDIST_NONTRIVIAL_ALT = prove
18477 (`!s t:real^N->bool.
18478 bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {})
18479 ==> hausdist(s,t) = max (sup {setdist ({x},t) | x IN s})
18480 (sup {setdist ({y},s) | y IN t})`,
18481 REPEAT STRIP_TAC THEN ASM_SIMP_TAC[HAUSDIST_NONTRIVIAL] THEN
18482 MATCH_MP_TAC SUP_UNION THEN
18483 ASM_REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
18485 MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`] BOUNDED_DIFFS) THEN
18486 ASM_REWRITE_TAC[bounded; FORALL_IN_UNION; FORALL_IN_IMAGE; GSYM dist] THEN
18487 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[FORALL_IN_GSPEC; GSYM dist] THEN
18488 ASM_MESON_TAC[SETDIST_LE_DIST; dist; DIST_SYM; REAL_LE_TRANS;
18489 MEMBER_NOT_EMPTY; IN_SING]);;
18491 let REAL_HAUSDIST_LE_EQ = prove
18492 (`!s t:real^N->bool b.
18493 ~(s = {}) /\ ~(t = {}) /\ bounded s /\ bounded t
18494 ==> (hausdist(s,t) <= b <=>
18495 (!x. x IN s ==> setdist({x},t) <= b) /\
18496 (!y. y IN t ==> setdist({y},s) <= b))`,
18497 REPEAT STRIP_TAC THEN
18498 ASM_SIMP_TAC[HAUSDIST_NONTRIVIAL_ALT; REAL_MAX_LE] THEN
18500 ONCE_REWRITE_TAC[SET_RULE `(!x. x IN s ==> f x <= b) <=>
18501 (!y. y IN {f x | x IN s} ==> y <= b)`] THEN
18502 MATCH_MP_TAC REAL_SUP_LE_EQ THEN
18503 ASM_REWRITE_TAC[SIMPLE_IMAGE; IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN
18504 MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`] BOUNDED_DIFFS) THEN
18505 ASM_REWRITE_TAC[bounded; FORALL_IN_UNION; FORALL_IN_IMAGE; GSYM dist] THEN
18506 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[FORALL_IN_GSPEC; GSYM dist] THEN
18507 ASM_MESON_TAC[SETDIST_LE_DIST; dist; DIST_SYM; REAL_LE_TRANS;
18508 MEMBER_NOT_EMPTY; IN_SING]);;
18510 let HAUSDIST_COMPACT_EXISTS = prove
18511 (`!s t:real^N->bool.
18512 bounded s /\ compact t /\ ~(t = {})
18513 ==> !x. x IN s ==> ?y. y IN t /\ dist(x,y) <= hausdist(s,t)`,
18514 REPEAT STRIP_TAC THEN
18515 ASM_CASES_TAC `s:real^N->bool = {}` THENL [ASM SET_TAC[]; ALL_TAC] THEN
18516 MP_TAC(ISPECL [`{x:real^N}`; `t:real^N->bool`]
18517 SETDIST_COMPACT_CLOSED) THEN
18518 ASM_SIMP_TAC[COMPACT_SING; COMPACT_IMP_CLOSED; NOT_INSERT_EMPTY] THEN
18519 REWRITE_TAC[IN_SING; UNWIND_THM2; RIGHT_EXISTS_AND_THM; UNWIND_THM1] THEN
18520 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN
18521 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
18522 MATCH_MP_TAC REAL_LE_HAUSDIST THEN
18523 ASM_REWRITE_TAC[LEFT_EXISTS_AND_THM; RIGHT_EXISTS_AND_THM] THEN
18524 REWRITE_TAC[CONJ_ASSOC] THEN
18525 CONJ_TAC THENL [CONJ_TAC; ASM_MESON_TAC[REAL_LE_REFL]] THEN
18526 MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`] BOUNDED_DIFFS) THEN
18527 ASM_SIMP_TAC[COMPACT_IMP_BOUNDED] THEN
18528 REWRITE_TAC[bounded; FORALL_IN_GSPEC; GSYM dist] THEN
18529 MATCH_MP_TAC MONO_EXISTS THEN
18530 ASM_MESON_TAC[SETDIST_LE_DIST; dist; DIST_SYM; REAL_LE_TRANS;
18531 MEMBER_NOT_EMPTY; IN_SING]);;
18533 let HAUSDIST_COMPACT_SUMS = prove
18534 (`!s t:real^N->bool.
18535 bounded s /\ compact t /\ ~(t = {})
18536 ==> s SUBSET {y + z | y IN t /\ z IN cball(vec 0,hausdist(s,t))}`,
18537 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_CBALL_0] THEN
18538 REWRITE_TAC[VECTOR_ARITH `a:real^N = b + x <=> a - b = x`;
18539 ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN
18540 REWRITE_TAC[GSYM dist; HAUSDIST_COMPACT_EXISTS]);;
18542 let HAUSDIST_TRANS = prove
18543 (`!s t u:real^N->bool.
18544 bounded s /\ bounded t /\ bounded u /\ ~(t = {})
18545 ==> hausdist(s,u) <= hausdist(s,t) + hausdist(t,u)`,
18547 (`!s t u:real^N->bool.
18548 bounded s /\ bounded t /\ bounded u /\
18549 ~(s = {}) /\ ~(t = {}) /\ ~(u = {})
18550 ==> !x. x IN s ==> setdist({x},u) <= hausdist(s,t) + hausdist(t,u)`,
18551 REPEAT STRIP_TAC THEN
18552 MP_TAC(ISPECL [`closure s:real^N->bool`; `closure t:real^N->bool`]
18553 HAUSDIST_COMPACT_EXISTS) THEN
18554 ASM_SIMP_TAC[COMPACT_CLOSURE; BOUNDED_CLOSURE; CLOSURE_EQ_EMPTY] THEN
18555 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
18556 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET; HAUSDIST_CLOSURE] THEN
18557 DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN
18558 MP_TAC(ISPECL [`closure t:real^N->bool`; `closure u:real^N->bool`]
18559 HAUSDIST_COMPACT_EXISTS) THEN
18560 ASM_SIMP_TAC[COMPACT_CLOSURE; BOUNDED_CLOSURE; CLOSURE_EQ_EMPTY] THEN
18561 DISCH_THEN(MP_TAC o SPEC `y:real^N`) THEN
18562 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET; HAUSDIST_CLOSURE] THEN
18563 DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
18564 TRANS_TAC REAL_LE_TRANS `dist(x:real^N,z)` THEN CONJ_TAC THENL
18565 [ASM_MESON_TAC[SETDIST_CLOSURE; SETDIST_LE_DIST; IN_SING]; ALL_TAC] THEN
18566 TRANS_TAC REAL_LE_TRANS `dist(x:real^N,y) + dist(y,z)` THEN
18567 REWRITE_TAC[DIST_TRIANGLE] THEN ASM_REAL_ARITH_TAC) in
18568 REPEAT STRIP_TAC THEN
18569 ASM_CASES_TAC `s:real^N->bool = {}` THEN
18570 ASM_REWRITE_TAC[HAUSDIST_EMPTY; REAL_ADD_LID; HAUSDIST_POS_LE] THEN
18571 ASM_CASES_TAC `u:real^N->bool = {}` THEN
18572 ASM_REWRITE_TAC[HAUSDIST_EMPTY; REAL_ADD_RID; HAUSDIST_POS_LE] THEN
18573 ASM_SIMP_TAC[REAL_HAUSDIST_LE_EQ] THEN
18574 ASM_MESON_TAC[lemma; HAUSDIST_SYM; SETDIST_SYM; REAL_ADD_SYM]);;
18576 let HAUSDIST_EQ_0 = prove
18577 (`!s t:real^N->bool.
18578 bounded s /\ bounded t
18579 ==> (hausdist(s,t) = &0 <=> s = {} \/ t = {} \/ closure s = closure t)`,
18580 REPEAT STRIP_TAC THEN
18581 MAP_EVERY ASM_CASES_TAC [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN
18582 ASM_REWRITE_TAC[HAUSDIST_EMPTY] THEN
18583 ASM_SIMP_TAC[GSYM REAL_LE_ANTISYM; HAUSDIST_POS_LE; REAL_HAUSDIST_LE_EQ] THEN
18584 SIMP_TAC[SETDIST_POS_LE; REAL_ARITH `&0 <= x ==> (x <= &0 <=> x = &0)`] THEN
18585 ASM_REWRITE_TAC[SETDIST_EQ_0_SING; GSYM SUBSET_ANTISYM_EQ; SUBSET] THEN
18586 SIMP_TAC[FORALL_IN_CLOSURE_EQ; CLOSED_CLOSURE; CONTINUOUS_ON_ID]);;
18588 let HAUSDIST_COMPACT_NONTRIVIAL = prove
18589 (`!s t:real^N->bool.
18590 compact s /\ compact t /\ ~(s = {}) /\ ~(t = {})
18591 ==> hausdist(s,t) =
18592 inf {e | &0 <= e /\
18593 s SUBSET {x + y | x IN t /\ norm y <= e} /\
18594 t SUBSET {x + y | x IN s /\ norm y <= e}}`,
18595 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
18596 MATCH_MP_TAC REAL_INF_UNIQUE THEN
18597 REWRITE_TAC[FORALL_IN_GSPEC; EXISTS_IN_GSPEC] THEN
18598 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
18599 REWRITE_TAC[VECTOR_ARITH `a:real^N = b + x <=> a - b = x`;
18600 ONCE_REWRITE_RULE[CONJ_SYM] UNWIND_THM1] THEN
18601 REWRITE_TAC[GSYM dist] THEN CONJ_TAC THENL
18602 [REPEAT STRIP_TAC THEN
18603 MATCH_MP_TAC REAL_HAUSDIST_LE THEN
18604 ASM_MESON_TAC[SETDIST_LE_DIST; DIST_SYM; REAL_LE_TRANS;
18605 IN_SING; REAL_LT_IMP_LE];
18606 REPEAT STRIP_TAC THEN EXISTS_TAC `hausdist(s:real^N->bool,t)` THEN
18607 ASM_REWRITE_TAC[HAUSDIST_POS_LE] THEN
18608 ASM_MESON_TAC[DIST_SYM; HAUSDIST_SYM;
18609 HAUSDIST_COMPACT_EXISTS; COMPACT_IMP_BOUNDED]]);;
18611 let HAUSDIST_BALLS = prove
18612 (`(!a b:real^N r s.
18613 hausdist(ball(a,r),ball(b,s)) =
18614 if r <= &0 \/ s <= &0 then &0 else dist(a,b) + abs(r - s)) /\
18616 hausdist(ball(a,r),cball(b,s)) =
18617 if r <= &0 \/ s < &0 then &0 else dist(a,b) + abs(r - s)) /\
18619 hausdist(cball(a,r),ball(b,s)) =
18620 if r < &0 \/ s <= &0 then &0 else dist(a,b) + abs(r - s)) /\
18622 hausdist(cball(a,r),cball(b,s)) =
18623 if r < &0 \/ s < &0 then &0 else dist(a,b) + abs(r - s))`,
18624 REWRITE_TAC[MESON[]
18625 `(x = if p then y else z) <=> (p ==> x = y) /\ (~p ==> x = z)`] THEN
18626 SIMP_TAC[TAUT `p \/ q ==> r <=> (p ==> r) /\ (q ==> r)`] THEN
18627 SIMP_TAC[BALL_EMPTY; CBALL_EMPTY; HAUSDIST_EMPTY; DE_MORGAN_THM] THEN
18628 ONCE_REWRITE_TAC[MESON[HAUSDIST_CLOSURE]
18629 `hausdist(s,t) = hausdist(closure s,closure t)`] THEN
18630 SIMP_TAC[REAL_NOT_LE; REAL_NOT_LT; CLOSURE_BALL] THEN
18631 REWRITE_TAC[HAUSDIST_CLOSURE] THEN
18632 MATCH_MP_TAC(TAUT `(s ==> p /\ q /\ r) /\ s ==> p /\ q /\ r /\ s`) THEN
18633 CONJ_TAC THENL [MESON_TAC[REAL_LT_IMP_LE]; REPEAT STRIP_TAC] THEN
18634 ASM_SIMP_TAC[HAUSDIST_NONTRIVIAL; BOUNDED_CBALL; CBALL_EQ_EMPTY;
18636 MATCH_MP_TAC SUP_UNIQUE THEN
18637 REWRITE_TAC[FORALL_IN_GSPEC; FORALL_IN_UNION] THEN
18638 REWRITE_TAC[MESON[CBALL_SING] `{a} = cball(a:real^N,&0)`] THEN
18639 ASM_REWRITE_TAC[SETDIST_BALLS; REAL_LT_REFL] THEN
18640 X_GEN_TAC `c:real` THEN REWRITE_TAC[IN_CBALL] THEN
18641 EQ_TAC THENL [ALL_TAC; NORM_ARITH_TAC] THEN
18642 ASM_CASES_TAC `b:real^N = a` THENL
18643 [ASM_REWRITE_TAC[DIST_SYM; DIST_REFL; REAL_MAX_LE] THEN
18644 DISCH_THEN(CONJUNCTS_THEN2
18645 (MP_TAC o SPEC `a + r % basis 1:real^N`)
18646 (MP_TAC o SPEC `a + s % basis 1:real^N`)) THEN
18647 REWRITE_TAC[NORM_ARITH `dist(a:real^N,a + x) = norm x`] THEN
18648 SIMP_TAC[NORM_MUL; NORM_BASIS; LE_REFL; DIMINDEX_GE_1] THEN
18649 ASM_REAL_ARITH_TAC;
18650 DISCH_THEN(CONJUNCTS_THEN2
18651 (MP_TAC o SPEC `a - r / dist(a,b) % (b - a):real^N`)
18652 (MP_TAC o SPEC `b - s / dist(a,b) % (a - b):real^N`)) THEN
18653 REWRITE_TAC[NORM_ARITH `dist(a:real^N,a - x) = norm x`] THEN
18654 REWRITE_TAC[dist; NORM_MUL; VECTOR_ARITH
18655 `b - e % (a - b) - a:real^N = (&1 + e) % (b - a)`] THEN
18656 ONCE_REWRITE_TAC[GSYM REAL_ABS_NORM] THEN
18657 REWRITE_TAC[GSYM REAL_ABS_MUL] THEN REWRITE_TAC[REAL_ABS_NORM] THEN
18658 REWRITE_TAC[NORM_SUB; REAL_ADD_RDISTRIB; REAL_MUL_LID] THEN
18659 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0; VECTOR_SUB_EQ] THEN
18660 ASM_REAL_ARITH_TAC]);;
18662 let HAUSDIST_ALT = prove
18663 (`!s t:real^N->bool.
18664 bounded s /\ bounded t /\ ~(s = {}) /\ ~(t = {})
18665 ==> hausdist(s,t) =
18666 sup {abs(setdist({x},s) - setdist({x},t)) | x IN (:real^N)}`,
18667 REPEAT GEN_TAC THEN
18668 ONCE_REWRITE_TAC[GSYM COMPACT_CLOSURE; GSYM(CONJUNCT2 SETDIST_CLOSURE);
18669 GSYM CLOSURE_EQ_EMPTY; MESON[HAUSDIST_CLOSURE]
18670 `hausdist(s:real^N->bool,t) = hausdist(closure s,closure t)`] THEN
18671 SPEC_TAC(`closure t:real^N->bool`,`t:real^N->bool`) THEN
18672 SPEC_TAC(`closure s:real^N->bool`,`s:real^N->bool`) THEN
18673 REPEAT STRIP_TAC THEN
18674 ASM_SIMP_TAC[HAUSDIST_NONTRIVIAL; COMPACT_IMP_BOUNDED] THEN
18675 MATCH_MP_TAC SUP_EQ THEN
18676 REWRITE_TAC[FORALL_IN_UNION; FORALL_IN_GSPEC; IN_UNIV] THEN
18677 REWRITE_TAC[REAL_ARITH `abs(y - x) <= b <=> x <= y + b /\ y <= x + b`] THEN
18678 GEN_TAC THEN REWRITE_TAC[FORALL_AND_THM] THEN BINOP_TAC THEN
18679 (EQ_TAC THENL [ALL_TAC; MESON_TAC[SETDIST_SING_IN_SET; REAL_ADD_LID]]) THEN
18680 DISCH_TAC THEN X_GEN_TAC `z:real^N` THENL
18681 [MP_TAC(ISPECL[`{z:real^N}`; `s:real^N->bool`] SETDIST_CLOSED_COMPACT);
18682 MP_TAC(ISPECL[`{z:real^N}`; `t:real^N->bool`] SETDIST_CLOSED_COMPACT)] THEN
18683 ASM_REWRITE_TAC[CLOSED_SING; NOT_INSERT_EMPTY] THEN
18684 REWRITE_TAC[IN_SING; RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN
18685 DISCH_THEN(X_CHOOSE_THEN `y:real^N` (STRIP_ASSUME_TAC o GSYM)) THEN
18686 FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[] THENL
18687 [MP_TAC(ISPECL[`{y:real^N}`; `t:real^N->bool`] SETDIST_CLOSED_COMPACT);
18688 MP_TAC(ISPECL[`{y:real^N}`; `s:real^N->bool`] SETDIST_CLOSED_COMPACT)] THEN
18689 ASM_REWRITE_TAC[CLOSED_SING; NOT_INSERT_EMPTY] THEN
18690 REWRITE_TAC[IN_SING; RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN
18691 DISCH_THEN(X_CHOOSE_THEN `x:real^N` (STRIP_ASSUME_TAC o GSYM)) THEN
18692 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
18693 TRANS_TAC REAL_LE_TRANS `dist(z:real^N,x)` THEN
18694 ASM_SIMP_TAC[SETDIST_LE_DIST; IN_SING] THEN
18695 UNDISCH_TAC `dist(y:real^N,x) <= b` THEN CONV_TAC NORM_ARITH);;
18697 let CONTINUOUS_DIAMETER = prove
18698 (`!s:real^N->bool e.
18699 bounded s /\ ~(s = {}) /\ &0 < e
18701 !t. bounded t /\ ~(t = {}) /\ hausdist(s,t) < d
18702 ==> abs(diameter s - diameter t) < e`,
18703 REPEAT STRIP_TAC THEN EXISTS_TAC `e / &2` THEN
18704 ASM_REWRITE_TAC[REAL_HALF] THEN REPEAT STRIP_TAC THEN
18705 SUBGOAL_THEN `diameter(s:real^N->bool) - diameter(t:real^N->bool) =
18706 diameter(closure s) - diameter(closure t)`
18707 SUBST1_TAC THENL [ASM_MESON_TAC[DIAMETER_CLOSURE]; ALL_TAC] THEN
18708 MATCH_MP_TAC REAL_LET_TRANS THEN
18709 EXISTS_TAC `&2 * hausdist(s:real^N->bool,t)` THEN
18710 CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN
18711 MP_TAC(ISPECL [`vec 0:real^N`; `hausdist(s:real^N->bool,t)`]
18712 DIAMETER_CBALL) THEN
18713 ASM_SIMP_TAC[HAUSDIST_POS_LE; GSYM REAL_NOT_LE] THEN
18714 DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC(REAL_ARITH
18715 `x <= y + e /\ y <= x + e ==> abs(x - y) <= e`) THEN
18717 W(MP_TAC o PART_MATCH (rand o rand) DIAMETER_SUMS o rand o snd) THEN
18718 ASM_SIMP_TAC[BOUNDED_CBALL; BOUNDED_CLOSURE] THEN
18719 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN
18720 MATCH_MP_TAC DIAMETER_SUBSET THEN
18721 ASM_SIMP_TAC[BOUNDED_SUMS; BOUNDED_CBALL; BOUNDED_CLOSURE] THEN
18722 ONCE_REWRITE_TAC[MESON[HAUSDIST_CLOSURE]
18723 `hausdist(s:real^N->bool,t) = hausdist(closure s,closure t)`]
18724 THENL [ALL_TAC; ONCE_REWRITE_TAC[HAUSDIST_SYM]] THEN
18725 MATCH_MP_TAC HAUSDIST_COMPACT_SUMS THEN
18726 ASM_SIMP_TAC[COMPACT_CLOSURE; BOUNDED_CLOSURE; CLOSURE_EQ_EMPTY]);;
18728 (* ------------------------------------------------------------------------- *)
18729 (* Isometries are embeddings, and even surjective in the compact case. *)
18730 (* ------------------------------------------------------------------------- *)
18732 let ISOMETRY_IMP_OPEN_MAP = prove
18733 (`!f:real^M->real^N s t u.
18735 (!x y. x IN s /\ y IN s ==> dist(f x,f y) = dist(x,y)) /\
18736 open_in (subtopology euclidean s) u
18737 ==> open_in (subtopology euclidean t) (IMAGE f u)`,
18738 REWRITE_TAC[open_in; FORALL_IN_IMAGE] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
18739 CONJ_TAC THENL [ASM SET_TAC[]; X_GEN_TAC `x:real^M` THEN DISCH_TAC] THEN
18740 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN
18741 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN
18742 STRIP_TAC THEN ASM_REWRITE_TAC[IMP_CONJ] THEN
18743 EXPAND_TAC "t" THEN REWRITE_TAC[FORALL_IN_IMAGE] THEN
18744 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET]) THEN
18745 ASM_SIMP_TAC[IN_IMAGE] THEN ASM_MESON_TAC[]);;
18747 let ISOMETRY_IMP_EMBEDDING = prove
18748 (`!f:real^M->real^N s t.
18749 IMAGE f s = t /\ (!x y. x IN s /\ y IN s ==> dist(f x,f y) = dist(x,y))
18750 ==> ?g. homeomorphism (s,t) (f,g)`,
18751 REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN
18752 ASM_SIMP_TAC[ISOMETRY_ON_IMP_CONTINUOUS_ON] THEN
18753 CONJ_TAC THENL [ASM_MESON_TAC[DIST_EQ_0]; REPEAT STRIP_TAC] THEN
18754 MATCH_MP_TAC ISOMETRY_IMP_OPEN_MAP THEN ASM_MESON_TAC[]);;
18756 let ISOMETRY_IMP_HOMEOMORPHISM_COMPACT = prove
18757 (`!f s:real^N->bool.
18758 compact s /\ IMAGE f s SUBSET s /\
18759 (!x y. x IN s /\ y IN s ==> dist(f x,f y) = dist(x,y))
18760 ==> ?g. homeomorphism (s,s) (f,g)`,
18761 REPEAT STRIP_TAC THEN
18762 SUBGOAL_THEN `IMAGE (f:real^N->real^N) s = s`
18763 (fun th -> ASM_MESON_TAC[th; ISOMETRY_IMP_EMBEDDING]) THEN
18764 FIRST_ASSUM(ASSUME_TAC o MATCH_MP ISOMETRY_ON_IMP_CONTINUOUS_ON) THEN
18765 ASM_REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN REWRITE_TAC[SUBSET] THEN
18766 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
18767 SUBGOAL_THEN `setdist({x},IMAGE (f:real^N->real^N) s) = &0` MP_TAC THENL
18768 [MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ ~(&0 < x) ==> x = &0`) THEN
18769 REWRITE_TAC[SETDIST_POS_LE] THEN DISCH_TAC THEN
18770 (X_CHOOSE_THEN `z:num->real^N` STRIP_ASSUME_TAC o
18771 prove_recursive_functions_exist num_RECURSION)
18772 `z 0 = (x:real^N) /\ !n. z(SUC n) = f(z n)` THEN
18773 SUBGOAL_THEN `!n. (z:num->real^N) n IN s` ASSUME_TAC THENL
18774 [INDUCT_TAC THEN ASM SET_TAC[]; ALL_TAC] THEN
18775 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [compact]) THEN
18776 DISCH_THEN(MP_TAC o SPEC `z:num->real^N`) THEN
18777 ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN
18778 MAP_EVERY X_GEN_TAC [`l:real^N`; `r:num->num`] THEN STRIP_TAC THEN
18779 FIRST_ASSUM(MP_TAC o MATCH_MP CONVERGENT_IMP_CAUCHY) THEN
18780 REWRITE_TAC[cauchy] THEN
18781 DISCH_THEN(MP_TAC o SPEC `setdist({x},IMAGE (f:real^N->real^N) s)`) THEN
18782 ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN `N:num`
18783 (MP_TAC o SPECL [`N:num`; `N + 1`])) THEN
18784 ANTS_TAC THENL [ARITH_TAC; REWRITE_TAC[REAL_NOT_LT; o_THM]] THEN
18785 SUBGOAL_THEN `(r:num->num) N < r (N + 1)` MP_TAC THENL
18786 [FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC;
18787 REWRITE_TAC[LT_EXISTS; LEFT_IMP_EXISTS_THM]] THEN
18788 X_GEN_TAC `d:num` THEN DISCH_THEN SUBST1_TAC THEN
18789 TRANS_TAC REAL_LE_TRANS `dist(x:real^N,z(SUC d))` THEN CONJ_TAC THENL
18790 [MATCH_MP_TAC SETDIST_LE_DIST THEN ASM SET_TAC[]; ALL_TAC] THEN
18791 MATCH_MP_TAC REAL_EQ_IMP_LE THEN
18792 SPEC_TAC(`(r:num->num) N`,`m:num`) THEN
18793 INDUCT_TAC THEN ASM_MESON_TAC[ADD_CLAUSES];
18794 REWRITE_TAC[SETDIST_EQ_0_SING; IMAGE_EQ_EMPTY] THEN
18795 ASM_MESON_TAC[COMPACT_IMP_CLOSED; NOT_IN_EMPTY;
18796 COMPACT_CONTINUOUS_IMAGE; CLOSURE_CLOSED]]);;
18798 (* ------------------------------------------------------------------------- *)
18799 (* Urysohn's lemma (for real^N, where the proof is easy using distances). *)
18800 (* ------------------------------------------------------------------------- *)
18802 let URYSOHN_LOCAL_STRONG = prove
18804 closed_in (subtopology euclidean u) s /\
18805 closed_in (subtopology euclidean u) t /\
18806 s INTER t = {} /\ ~(a = b)
18807 ==> ?f:real^N->real^M.
18808 f continuous_on u /\
18809 (!x. x IN u ==> f(x) IN segment[a,b]) /\
18810 (!x. x IN u ==> (f x = a <=> x IN s)) /\
18811 (!x. x IN u ==> (f x = b <=> x IN t))`,
18814 closed_in (subtopology euclidean u) s /\
18815 closed_in (subtopology euclidean u) t /\
18816 s INTER t = {} /\ ~(s = {}) /\ ~(t = {}) /\ ~(a = b)
18817 ==> ?f:real^N->real^M.
18818 f continuous_on u /\
18819 (!x. x IN u ==> f(x) IN segment[a,b]) /\
18820 (!x. x IN u ==> (f x = a <=> x IN s)) /\
18821 (!x. x IN u ==> (f x = b <=> x IN t))`,
18822 REPEAT STRIP_TAC THEN EXISTS_TAC
18823 `\x:real^N. a + setdist({x},s) / (setdist({x},s) + setdist({x},t)) %
18824 (b - a:real^M)` THEN REWRITE_TAC[] THEN
18826 `(!x:real^N. x IN u ==> (setdist({x},s) = &0 <=> x IN s)) /\
18827 (!x:real^N. x IN u ==> (setdist({x},t) = &0 <=> x IN t))`
18828 STRIP_ASSUME_TAC THENL
18829 [ASM_REWRITE_TAC[SETDIST_EQ_0_SING] THEN CONJ_TAC THENL
18830 [MP_TAC(ISPEC `s:real^N->bool` CLOSED_IN_CLOSED);
18831 MP_TAC(ISPEC `t:real^N->bool` CLOSED_IN_CLOSED)] THEN
18832 DISCH_THEN(MP_TAC o SPEC `u:real^N->bool`) THEN
18833 ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN `v:real^N->bool`
18834 (CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC)) THEN
18835 ASM_MESON_TAC[CLOSURE_CLOSED; INTER_SUBSET; SUBSET_CLOSURE; SUBSET;
18836 IN_INTER; CLOSURE_SUBSET];
18838 SUBGOAL_THEN `!x:real^N. x IN u ==> &0 < setdist({x},s) + setdist({x},t)`
18840 [REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH
18841 `&0 <= x /\ &0 <= y /\ ~(x = &0 /\ y = &0) ==> &0 < x + y`) THEN
18842 REWRITE_TAC[SETDIST_POS_LE] THEN ASM SET_TAC[];
18844 REPEAT CONJ_TAC THENL
18845 [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
18846 REWRITE_TAC[real_div; GSYM VECTOR_MUL_ASSOC] THEN
18847 REPEAT(MATCH_MP_TAC CONTINUOUS_ON_MUL THEN CONJ_TAC) THEN
18848 REWRITE_TAC[CONTINUOUS_ON_CONST; o_DEF] THEN
18849 REWRITE_TAC[CONTINUOUS_ON_LIFT_SETDIST] THEN
18850 MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN
18851 ASM_SIMP_TAC[REAL_LT_IMP_NZ] THEN
18852 REWRITE_TAC[LIFT_ADD] THEN MATCH_MP_TAC CONTINUOUS_ON_ADD THEN
18853 REWRITE_TAC[CONTINUOUS_ON_LIFT_SETDIST];
18854 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
18855 REWRITE_TAC[segment; IN_ELIM_THM] THEN
18856 REWRITE_TAC[VECTOR_MUL_EQ_0; LEFT_OR_DISTRIB; VECTOR_ARITH
18857 `a + x % (b - a):real^N = (&1 - u) % a + u % b <=>
18858 (x - u) % (b - a) = vec 0`;
18859 EXISTS_OR_THM] THEN
18860 DISJ1_TAC THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
18861 REWRITE_TAC[REAL_SUB_0; UNWIND_THM1] THEN
18862 ASM_SIMP_TAC[REAL_LE_DIV; REAL_LE_ADD; SETDIST_POS_LE; REAL_LE_LDIV_EQ;
18863 REAL_ARITH `a <= &1 * (a + b) <=> &0 <= b`];
18864 REWRITE_TAC[VECTOR_ARITH `a + x:real^N = a <=> x = vec 0`];
18865 REWRITE_TAC[VECTOR_ARITH `a + x % (b - a):real^N = b <=>
18866 (x - &1) % (b - a) = vec 0`]] THEN
18867 ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ] THEN
18868 ASM_SIMP_TAC[REAL_SUB_0; REAL_EQ_LDIV_EQ;
18869 REAL_MUL_LZERO; REAL_MUL_LID] THEN
18870 REWRITE_TAC[REAL_ARITH `x:real = x + y <=> y = &0`] THEN
18871 ASM_REWRITE_TAC[]) in
18872 MATCH_MP_TAC(MESON[]
18873 `(!s t. P s t <=> P t s) /\
18874 (!s t. ~(s = {}) /\ ~(t = {}) ==> P s t) /\
18875 P {} {} /\ (!t. ~(t = {}) ==> P {} t)
18876 ==> !s t. P s t`) THEN
18877 REPEAT CONJ_TAC THENL
18878 [REPEAT GEN_TAC THEN
18879 GEN_REWRITE_TAC (RAND_CONV o BINDER_CONV) [SWAP_FORALL_THM] THEN
18880 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
18881 REWRITE_TAC[SEGMENT_SYM; INTER_COMM; CONJ_ACI; EQ_SYM_EQ];
18883 REPEAT STRIP_TAC THEN EXISTS_TAC `(\x. midpoint(a,b)):real^N->real^M` THEN
18884 ASM_SIMP_TAC[NOT_IN_EMPTY; CONTINUOUS_ON_CONST; MIDPOINT_IN_SEGMENT] THEN
18885 REWRITE_TAC[midpoint] THEN CONJ_TAC THEN GEN_TAC THEN DISCH_TAC THEN
18886 UNDISCH_TAC `~(a:real^M = b)` THEN REWRITE_TAC[CONTRAPOS_THM] THEN
18888 REPEAT STRIP_TAC THEN ASM_CASES_TAC `t:real^N->bool = u` THENL
18889 [EXISTS_TAC `(\x. b):real^N->real^M` THEN
18890 ASM_REWRITE_TAC[NOT_IN_EMPTY; ENDS_IN_SEGMENT; IN_UNIV;
18891 CONTINUOUS_ON_CONST];
18892 SUBGOAL_THEN `?c:real^N. c IN u /\ ~(c IN t)` STRIP_ASSUME_TAC THENL
18893 [REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET)) THEN
18894 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM SET_TAC[];
18896 MP_TAC(ISPECL [`{c:real^N}`; `t:real^N->bool`; `u:real^N->bool`;
18897 `midpoint(a,b):real^M`; `b:real^M`] lemma) THEN
18898 ASM_REWRITE_TAC[CLOSED_IN_SING; MIDPOINT_EQ_ENDPOINT] THEN
18899 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
18900 MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[NOT_IN_EMPTY] THEN
18901 X_GEN_TAC `f:real^N->real^M` THEN STRIP_TAC THEN CONJ_TAC THENL
18903 `segment[midpoint(a,b):real^M,b] SUBSET segment[a,b]` MP_TAC
18905 [REWRITE_TAC[SUBSET; IN_SEGMENT; midpoint] THEN GEN_TAC THEN
18906 DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN
18907 EXISTS_TAC `(&1 + u) / &2` THEN ASM_REWRITE_TAC[] THEN
18908 REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
18911 SUBGOAL_THEN `~(a IN segment[midpoint(a,b):real^M,b])` MP_TAC THENL
18912 [ALL_TAC; ASM_MESON_TAC[]] THEN
18913 DISCH_THEN(MP_TAC o CONJUNCT2 o MATCH_MP DIST_IN_CLOSED_SEGMENT) THEN
18914 REWRITE_TAC[DIST_MIDPOINT] THEN
18915 UNDISCH_TAC `~(a:real^M = b)` THEN NORM_ARITH_TAC]]]);;
18917 let URYSOHN_LOCAL = prove
18919 closed_in (subtopology euclidean u) s /\
18920 closed_in (subtopology euclidean u) t /\
18922 ==> ?f:real^N->real^M.
18923 f continuous_on u /\
18924 (!x. x IN u ==> f(x) IN segment[a,b]) /\
18925 (!x. x IN s ==> f x = a) /\
18926 (!x. x IN t ==> f x = b)`,
18927 REPEAT STRIP_TAC THEN ASM_CASES_TAC `a:real^M = b` THENL
18928 [EXISTS_TAC `(\x. b):real^N->real^M` THEN
18929 ASM_REWRITE_TAC[ENDS_IN_SEGMENT; CONTINUOUS_ON_CONST];
18930 MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`; `u:real^N->bool`;
18931 `a:real^M`; `b:real^M`] URYSOHN_LOCAL_STRONG) THEN
18932 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN
18933 REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET)) THEN
18934 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN SET_TAC[]]);;
18936 let URYSOHN_STRONG = prove
18938 closed s /\ closed t /\ s INTER t = {} /\ ~(a = b)
18939 ==> ?f:real^N->real^M.
18940 f continuous_on (:real^N) /\ (!x. f(x) IN segment[a,b]) /\
18941 (!x. f x = a <=> x IN s) /\ (!x. f x = b <=> x IN t)`,
18942 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN] THEN
18943 ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN
18944 DISCH_THEN(MP_TAC o MATCH_MP URYSOHN_LOCAL_STRONG) THEN
18945 REWRITE_TAC[IN_UNIV]);;
18947 let URYSOHN = prove
18949 closed s /\ closed t /\ s INTER t = {}
18950 ==> ?f:real^N->real^M.
18951 f continuous_on (:real^N) /\ (!x. f(x) IN segment[a,b]) /\
18952 (!x. x IN s ==> f x = a) /\ (!x. x IN t ==> f x = b)`,
18953 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN] THEN
18954 ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN DISCH_THEN
18955 (MP_TAC o ISPECL [`a:real^M`; `b:real^M`] o MATCH_MP URYSOHN_LOCAL) THEN
18956 REWRITE_TAC[IN_UNIV]);;
18958 (* ------------------------------------------------------------------------- *)
18959 (* Countability of some relevant sets. *)
18960 (* ------------------------------------------------------------------------- *)
18962 let COUNTABLE_INTEGER = prove
18963 (`COUNTABLE integer`,
18964 MATCH_MP_TAC COUNTABLE_SUBSET THEN EXISTS_TAC
18965 `IMAGE (\n. (&n:real)) (:num) UNION IMAGE (\n. --(&n)) (:num)` THEN
18966 SIMP_TAC[COUNTABLE_IMAGE; COUNTABLE_UNION; NUM_COUNTABLE] THEN
18967 REWRITE_TAC[SUBSET; IN_UNION; IN_IMAGE; IN_UNIV] THEN
18968 REWRITE_TAC[IN; INTEGER_CASES]);;
18970 let CARD_EQ_INTEGER = prove
18971 (`integer =_c (:num)`,
18972 REWRITE_TAC[GSYM CARD_LE_ANTISYM; GSYM COUNTABLE_ALT; COUNTABLE_INTEGER] THEN
18973 REWRITE_TAC[le_c] THEN EXISTS_TAC `real_of_num` THEN
18974 REWRITE_TAC[IN_UNIV; REAL_OF_NUM_EQ] THEN
18975 REWRITE_TAC[IN; INTEGER_CLOSED]);;
18977 let COUNTABLE_RATIONAL = prove
18978 (`COUNTABLE rational`,
18979 MATCH_MP_TAC COUNTABLE_SUBSET THEN
18980 EXISTS_TAC `IMAGE (\(x,y). x / y) (integer CROSS integer)` THEN
18981 SIMP_TAC[COUNTABLE_IMAGE; COUNTABLE_CROSS; COUNTABLE_INTEGER] THEN
18982 REWRITE_TAC[SUBSET; IN_IMAGE; EXISTS_PAIR_THM; IN_CROSS] THEN
18983 REWRITE_TAC[rational; IN] THEN MESON_TAC[]);;
18985 let CARD_EQ_RATIONAL = prove
18986 (`rational =_c (:num)`,
18987 REWRITE_TAC[GSYM CARD_LE_ANTISYM; GSYM COUNTABLE_ALT; COUNTABLE_RATIONAL] THEN
18988 REWRITE_TAC[le_c] THEN EXISTS_TAC `real_of_num` THEN
18989 REWRITE_TAC[IN_UNIV; REAL_OF_NUM_EQ] THEN
18990 REWRITE_TAC[IN; RATIONAL_CLOSED]);;
18992 let COUNTABLE_INTEGER_COORDINATES = prove
18993 (`COUNTABLE { x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) }`,
18994 MATCH_MP_TAC COUNTABLE_CART THEN
18995 REWRITE_TAC[SET_RULE `{x | P x} = P`; COUNTABLE_INTEGER]);;
18997 let COUNTABLE_RATIONAL_COORDINATES = prove
18998 (`COUNTABLE { x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i) }`,
18999 MATCH_MP_TAC COUNTABLE_CART THEN
19000 REWRITE_TAC[SET_RULE `{x | P x} = P`; COUNTABLE_RATIONAL]);;
19002 (* ------------------------------------------------------------------------- *)
19003 (* Density of points with rational, or just dyadic rational, coordinates. *)
19004 (* ------------------------------------------------------------------------- *)
19006 let CLOSURE_DYADIC_RATIONALS = prove
19007 (`closure { inv(&2 pow n) % x |n,x|
19008 !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) } = (:real^N)`,
19009 REWRITE_TAC[EXTENSION; CLOSURE_APPROACHABLE; IN_UNIV; EXISTS_IN_GSPEC] THEN
19010 MAP_EVERY X_GEN_TAC [`x:real^N`; `e:real`] THEN DISCH_TAC THEN
19011 MP_TAC(SPECL [`inv(&2)`; `e / &(dimindex(:N))`] REAL_ARCH_POW_INV) THEN
19012 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1;
19013 REAL_POW_INV; REAL_LT_RDIV_EQ] THEN
19014 CONV_TAC REAL_RAT_REDUCE_CONV THEN MATCH_MP_TAC MONO_EXISTS THEN
19015 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
19016 EXISTS_TAC `(lambda i. floor(&2 pow n * (x:real^N)$i)):real^N` THEN
19017 ASM_SIMP_TAC[LAMBDA_BETA; FLOOR; dist; NORM_MUL] THEN
19018 MATCH_MP_TAC(MATCH_MP (REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS)
19019 (SPEC_ALL NORM_LE_L1)) THEN
19020 SIMP_TAC[LAMBDA_BETA; VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT] THEN
19021 MATCH_MP_TAC REAL_LET_TRANS THEN
19022 EXISTS_TAC `&(dimindex(:N)) * inv(&2 pow n)` THEN ASM_REWRITE_TAC[] THEN
19023 GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o RAND_CONV) [GSYM CARD_NUMSEG_1] THEN
19024 MATCH_MP_TAC SUM_BOUND THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
19025 X_GEN_TAC `k:num` THEN STRIP_TAC THEN
19026 GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN
19027 SIMP_TAC[REAL_ABS_MUL; REAL_POW_EQ_0; REAL_OF_NUM_EQ; ARITH;
19028 REAL_FIELD `~(a = &0) ==> inv a * b - x = inv a * (b - a * x)`] THEN
19029 MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[REAL_ABS_POS] THEN
19030 REWRITE_TAC[REAL_LE_REFL; REAL_ABS_POW; REAL_ABS_INV; REAL_ABS_NUM] THEN
19031 MP_TAC(SPEC `&2 pow n * (x:real^N)$k` FLOOR) THEN REAL_ARITH_TAC);;
19033 let CLOSURE_RATIONAL_COORDINATES = prove
19034 (`closure { x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i) } =
19036 MATCH_MP_TAC(SET_RULE `!s. s SUBSET t /\ s = UNIV ==> t = UNIV`) THEN
19038 `closure { inv(&2 pow n) % x:real^N |n,x|
19039 !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) }` THEN
19041 CONJ_TAC THENL [ALL_TAC; REWRITE_TAC[CLOSURE_DYADIC_RATIONALS]] THEN
19042 MATCH_MP_TAC SUBSET_CLOSURE THEN
19043 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_THM; VECTOR_MUL_COMPONENT] THEN
19044 ASM_SIMP_TAC[RATIONAL_CLOSED]);;
19046 let CLOSURE_DYADIC_RATIONALS_IN_OPEN_SET = prove
19049 ==> closure(s INTER
19050 { inv(&2 pow n) % x | n,x |
19051 !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) }) =
19053 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_OPEN_INTER_SUPERSET THEN
19054 ASM_REWRITE_TAC[CLOSURE_DYADIC_RATIONALS; SUBSET_UNIV]);;
19056 let CLOSURE_RATIONALS_IN_OPEN_SET = prove
19059 ==> closure(s INTER
19060 { inv(&2 pow n) % x | n,x |
19061 !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) }) =
19063 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_OPEN_INTER_SUPERSET THEN
19064 ASM_REWRITE_TAC[CLOSURE_DYADIC_RATIONALS; SUBSET_UNIV]);;
19066 (* ------------------------------------------------------------------------- *)
19067 (* Various separability-type properties. *)
19068 (* ------------------------------------------------------------------------- *)
19070 let UNIV_SECOND_COUNTABLE = prove
19071 (`?b. COUNTABLE b /\ (!c. c IN b ==> open c) /\
19072 !s:real^N->bool. open s ==> ?u. u SUBSET b /\ s = UNIONS u`,
19074 `IMAGE (\(v:real^N,q). ball(v,q))
19075 ({v | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(v$i)} CROSS
19077 REPEAT CONJ_TAC THENL
19078 [MATCH_MP_TAC COUNTABLE_IMAGE THEN MATCH_MP_TAC COUNTABLE_CROSS THEN
19079 REWRITE_TAC[COUNTABLE_RATIONAL] THEN MATCH_MP_TAC COUNTABLE_CART THEN
19080 REWRITE_TAC[COUNTABLE_RATIONAL; SET_RULE `{x | P x} = P`];
19081 REWRITE_TAC[FORALL_IN_IMAGE; CROSS; FORALL_IN_GSPEC; OPEN_BALL];
19082 REPEAT STRIP_TAC THEN
19083 ASM_CASES_TAC `s:real^N->bool = {}` THENL
19084 [EXISTS_TAC `{}:(real^N->bool)->bool` THEN
19085 ASM_REWRITE_TAC[UNIONS_0; EMPTY_SUBSET];
19087 EXISTS_TAC `{c | c IN IMAGE (\(v:real^N,q). ball(v,q))
19088 ({v | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(v$i)} CROSS
19089 rational) /\ c SUBSET s}` THEN
19090 CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
19091 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN
19092 REWRITE_TAC[SUBSET; IN_UNIONS; IN_ELIM_THM] THEN
19093 REWRITE_TAC[GSYM CONJ_ASSOC; EXISTS_IN_IMAGE] THEN
19094 REWRITE_TAC[CROSS; EXISTS_PAIR_THM; EXISTS_IN_GSPEC] THEN
19095 REWRITE_TAC[IN_ELIM_PAIR_THM] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
19096 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN
19097 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
19098 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; SUBSET; IN_BALL] THEN
19099 X_GEN_TAC `e:real` THEN STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
19100 MP_TAC(REWRITE_RULE[EXTENSION; IN_UNIV] CLOSURE_RATIONAL_COORDINATES) THEN
19101 REWRITE_TAC[CLOSURE_APPROACHABLE] THEN
19102 DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `e / &4`]) THEN
19103 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[IN_ELIM_THM]] THEN
19104 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
19105 SUBGOAL_THEN `?x. rational x /\ e / &3 < x /\ x < e / &2`
19106 (X_CHOOSE_THEN `q:real` STRIP_ASSUME_TAC)
19108 [MP_TAC(ISPECL [`&5 / &12 * e`; `e / &12`] RATIONAL_APPROXIMATION) THEN
19109 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN
19110 SIMP_TAC[] THEN REAL_ARITH_TAC;
19111 EXISTS_TAC `q:real` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
19112 [ASM_REWRITE_TAC[IN];
19113 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
19114 REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC;
19115 ASM_REAL_ARITH_TAC]]]);;
19117 let UNIV_SECOND_COUNTABLE_SEQUENCE = prove
19118 (`?b:num->real^N->bool.
19119 (!m n. b m = b n <=> m = n) /\
19121 (!s. open s ==> ?k. s = UNIONS {b n | n IN k})`,
19122 X_CHOOSE_THEN `bb:(real^N->bool)->bool` STRIP_ASSUME_TAC
19123 UNIV_SECOND_COUNTABLE THEN
19124 MP_TAC(ISPEC `bb:(real^N->bool)->bool` COUNTABLE_AS_INJECTIVE_IMAGE) THEN
19126 [ASM_REWRITE_TAC[INFINITE] THEN DISCH_TAC THEN
19128 `INFINITE {ball(vec 0:real^N,inv(&n + &1)) | n IN (:num)}`
19130 [REWRITE_TAC[SIMPLE_IMAGE] THEN MATCH_MP_TAC(REWRITE_RULE
19131 [RIGHT_IMP_FORALL_THM; IMP_IMP] INFINITE_IMAGE_INJ) THEN
19132 REWRITE_TAC[num_INFINITE] THEN MATCH_MP_TAC WLOG_LT THEN SIMP_TAC[] THEN
19133 CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
19134 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN
19135 REWRITE_TAC[EXTENSION] THEN
19136 DISCH_THEN(MP_TAC o SPEC `inv(&n + &1) % basis 1:real^N`) THEN
19137 REWRITE_TAC[IN_BALL; DIST_0; NORM_MUL; REAL_ABS_INV] THEN
19138 SIMP_TAC[NORM_BASIS; DIMINDEX_GE_1; LE_REFL; REAL_MUL_RID] THEN
19139 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
19140 REWRITE_TAC[REAL_ARITH `abs(&n + &1) = &n + &1`; REAL_LT_REFL] THEN
19141 MATCH_MP_TAC REAL_LT_INV2 THEN
19142 REWRITE_TAC[REAL_OF_NUM_LT; REAL_OF_NUM_ADD] THEN ASM_ARITH_TAC;
19143 REWRITE_TAC[INFINITE; SIMPLE_IMAGE] THEN
19144 MATCH_MP_TAC FINITE_SUBSET THEN
19145 EXISTS_TAC `IMAGE UNIONS {u | u SUBSET bb} :(real^N->bool)->bool` THEN
19146 ASM_SIMP_TAC[FINITE_IMAGE; FINITE_POWERSET] THEN
19147 GEN_REWRITE_TAC I [SUBSET] THEN SIMP_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN
19148 X_GEN_TAC `n:num` THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN
19149 ASM_MESON_TAC[OPEN_BALL]];
19150 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:num->real^N->bool` THEN
19151 DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN
19152 RULE_ASSUM_TAC(REWRITE_RULE[FORALL_IN_IMAGE; IN_UNIV]) THEN
19153 REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN
19154 X_GEN_TAC `s:real^N->bool` THEN DISCH_TAC THEN
19155 FIRST_X_ASSUM(MP_TAC o SPEC `s:real^N->bool`) THEN
19156 ASM_REWRITE_TAC[SUBSET_IMAGE; LEFT_AND_EXISTS_THM; SUBSET_UNIV] THEN
19157 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
19158 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[SIMPLE_IMAGE]]);;
19160 let SUBSET_SECOND_COUNTABLE = prove
19163 (!c. c IN b ==> ~(c = {}) /\ open_in(subtopology euclidean s) c) /\
19164 !t. open_in(subtopology euclidean s) t
19165 ==> ?u. u SUBSET b /\ t = UNIONS u`,
19168 `?b. COUNTABLE b /\
19169 (!c:real^N->bool. c IN b ==> open_in(subtopology euclidean s) c) /\
19170 !t. open_in(subtopology euclidean s) t
19171 ==> ?u. u SUBSET b /\ t = UNIONS u`
19172 STRIP_ASSUME_TAC THENL
19173 [X_CHOOSE_THEN `B:(real^N->bool)->bool` STRIP_ASSUME_TAC
19174 UNIV_SECOND_COUNTABLE THEN
19175 EXISTS_TAC `{s INTER c :real^N->bool | c IN B}` THEN
19176 ASM_SIMP_TAC[SIMPLE_IMAGE; COUNTABLE_IMAGE] THEN
19177 ASM_SIMP_TAC[FORALL_IN_IMAGE; EXISTS_SUBSET_IMAGE; OPEN_IN_OPEN_INTER] THEN
19178 REWRITE_TAC[OPEN_IN_OPEN] THEN
19179 X_GEN_TAC `t:real^N->bool` THEN
19180 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
19181 FIRST_X_ASSUM SUBST_ALL_TAC THEN
19182 SUBGOAL_THEN `?b. b SUBSET B /\ u:real^N->bool = UNIONS b`
19183 STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
19184 FIRST_X_ASSUM SUBST_ALL_TAC THEN
19185 EXISTS_TAC `b:(real^N->bool)->bool` THEN ASM_REWRITE_TAC[] THEN
19186 REWRITE_TAC[INTER_UNIONS] THEN AP_TERM_TAC THEN SET_TAC[];
19187 EXISTS_TAC `b DELETE ({}:real^N->bool)` THEN
19188 ASM_SIMP_TAC[COUNTABLE_DELETE; IN_DELETE; SUBSET_DELETE] THEN
19189 X_GEN_TAC `t:real^N->bool` THEN DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN
19190 DISCH_THEN(X_CHOOSE_THEN `u:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
19191 EXISTS_TAC `u DELETE ({}:real^N->bool)` THEN
19192 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
19193 FIRST_X_ASSUM SUBST_ALL_TAC THEN
19194 REWRITE_TAC[EXTENSION; IN_UNIONS] THEN
19195 GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
19196 REWRITE_TAC[IN_DELETE] THEN SET_TAC[]]);;
19198 let SEPARABLE = prove
19200 ?t. COUNTABLE t /\ t SUBSET s /\ s SUBSET closure t`,
19201 MP_TAC SUBSET_SECOND_COUNTABLE THEN
19202 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `s:real^N->bool` THEN
19203 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_AND_EXISTS_THM] THEN
19204 DISCH_THEN(X_CHOOSE_THEN `B:(real^N->bool)->bool`
19205 (CONJUNCTS_THEN2 ASSUME_TAC (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC))) THEN
19206 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
19207 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
19208 X_GEN_TAC `f:(real^N->bool)->real^N` THEN DISCH_TAC THEN
19209 EXISTS_TAC `IMAGE (f:(real^N->bool)->real^N) B` THEN
19210 ASM_SIMP_TAC[COUNTABLE_IMAGE] THEN CONJ_TAC THENL
19211 [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
19212 X_GEN_TAC `c:real^N->bool` THEN DISCH_TAC THEN
19213 FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N->bool`) THEN
19214 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
19215 FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_SUBSET) THEN
19216 REWRITE_TAC[TOPSPACE_SUBTOPOLOGY; TOPSPACE_EUCLIDEAN] THEN ASM SET_TAC[];
19217 REWRITE_TAC[SUBSET; CLOSURE_APPROACHABLE; EXISTS_IN_IMAGE] THEN
19218 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
19219 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
19222 open_in (subtopology euclidean s) t
19223 ==> (?u. u SUBSET B /\ t = UNIONS u)`
19224 (MP_TAC o SPEC `s INTER ball(x:real^N,e)`) THEN
19225 SIMP_TAC[OPEN_IN_OPEN_INTER; OPEN_BALL; LEFT_IMP_EXISTS_THM] THEN
19226 X_GEN_TAC `b:(real^N->bool)->bool` THEN
19227 ASM_CASES_TAC `b:(real^N->bool)->bool = {}` THENL
19228 [MATCH_MP_TAC(TAUT `~b ==> a /\ b ==> c`) THEN
19229 ASM_REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY; UNIONS_0] THEN
19230 ASM_MESON_TAC[CENTRE_IN_BALL];
19232 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
19233 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N->bool` THEN
19234 DISCH_TAC THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
19235 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
19236 DISCH_THEN(MP_TAC o SPEC `(f:(real^N->bool)->real^N) c`) THEN
19237 ONCE_REWRITE_TAC[DIST_SYM] THEN REWRITE_TAC[IN_INTER; IN_BALL] THEN
19238 MATCH_MP_TAC(TAUT `a /\ c ==> (a /\ b <=> c) ==> b`) THEN
19239 CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
19240 FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N->bool`) THEN
19241 ANTS_TAC THENL [ASM SET_TAC[]; STRIP_TAC] THEN
19242 FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_SUBSET) THEN
19243 REWRITE_TAC[TOPSPACE_SUBTOPOLOGY; TOPSPACE_EUCLIDEAN] THEN
19246 let OPEN_SET_RATIONAL_COORDINATES = prove
19247 (`!s. open s /\ ~(s = {})
19248 ==> ?x:real^N. x IN s /\
19249 !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)`,
19250 REPEAT STRIP_TAC THEN
19252 `~(closure { x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i) } INTER
19253 (s:real^N->bool) = {})`
19255 [ASM_REWRITE_TAC[CLOSURE_RATIONAL_COORDINATES; INTER_UNIV]; ALL_TAC] THEN
19256 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; CLOSURE_APPROACHABLE; IN_INTER;
19258 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
19259 FIRST_X_ASSUM(MP_TAC o SPEC `a:real^N` o REWRITE_RULE[open_def]) THEN
19260 ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;
19262 let OPEN_COUNTABLE_UNION_OPEN_INTERVALS,
19263 OPEN_COUNTABLE_UNION_CLOSED_INTERVALS = (CONJ_PAIR o prove)
19264 (`(!s:real^N->bool.
19266 ==> ?D. COUNTABLE D /\
19267 (!i. i IN D ==> i SUBSET s /\ ?a b. i = interval(a,b)) /\
19271 ==> ?D. COUNTABLE D /\
19272 (!i. i IN D ==> i SUBSET s /\ ?a b. i = interval[a,b]) /\
19274 REPEAT STRIP_TAC THENL
19276 `{i | i IN IMAGE (\(a:real^N,b). interval(a,b))
19277 ({x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)} CROSS
19278 {x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)}) /\
19281 `{i | i IN IMAGE (\(a:real^N,b). interval[a,b])
19282 ({x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)} CROSS
19283 {x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)}) /\
19285 (SIMP_TAC[COUNTABLE_RESTRICT; COUNTABLE_IMAGE; COUNTABLE_CROSS;
19286 COUNTABLE_RATIONAL_COORDINATES] THEN
19287 REWRITE_TAC[IN_ELIM_THM; UNIONS_GSPEC; IMP_CONJ; GSYM CONJ_ASSOC] THEN
19288 REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN
19289 REWRITE_TAC[FORALL_PAIR_THM; EXISTS_PAIR_THM; IN_CROSS; IN_ELIM_THM] THEN
19290 CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
19291 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
19292 X_GEN_TAC `x:real^N` THEN EQ_TAC THENL [SET_TAC[]; DISCH_TAC] THEN
19293 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N` o REWRITE_RULE[open_def]) THEN
19294 ASM_REWRITE_TAC[] THEN
19295 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
19297 `!i. 1 <= i /\ i <= dimindex(:N)
19298 ==> ?a b. rational a /\ rational b /\
19299 a < (x:real^N)$i /\ (x:real^N)$i < b /\
19300 abs(b - a) < e / &(dimindex(:N))`
19302 [REPEAT STRIP_TAC THEN MATCH_MP_TAC RATIONAL_APPROXIMATION_STRADDLE THEN
19303 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1];
19304 REWRITE_TAC[LAMBDA_SKOLEM]] THEN
19305 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN
19306 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN
19307 DISCH_TAC THEN ASM_SIMP_TAC[SUBSET; IN_INTERVAL; REAL_LT_IMP_LE] THEN
19308 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
19309 REWRITE_TAC[dist] THEN MP_TAC(ISPEC `y - x:real^N` NORM_LE_L1) THEN
19310 MATCH_MP_TAC(REAL_ARITH `s < e ==> n <= s ==> n < e`) THEN
19311 MATCH_MP_TAC SUM_BOUND_LT_GEN THEN
19312 REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; CARD_NUMSEG_1] THEN
19313 REWRITE_TAC[DIMINDEX_GE_1; IN_NUMSEG; VECTOR_SUB_COMPONENT] THEN
19314 X_GEN_TAC `k:num` THEN STRIP_TAC THEN
19315 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `k:num`)) THEN ASM_REWRITE_TAC[] THEN
19316 ASM_REAL_ARITH_TAC));;
19318 let LINDELOF = prove
19319 (`!f:(real^N->bool)->bool.
19320 (!s. s IN f ==> open s)
19321 ==> ?f'. f' SUBSET f /\ COUNTABLE f' /\ UNIONS f' = UNIONS f`,
19322 REPEAT STRIP_TAC THEN
19324 `?b. COUNTABLE b /\
19325 (!c:real^N->bool. c IN b ==> open c) /\
19326 (!s. open s ==> ?u. u SUBSET b /\ s = UNIONS u)`
19327 STRIP_ASSUME_TAC THENL [ASM_REWRITE_TAC[UNIV_SECOND_COUNTABLE]; ALL_TAC] THEN
19329 `d = {s:real^N->bool | s IN b /\ ?u. u IN f /\ s SUBSET u}` THEN
19331 `COUNTABLE d /\ UNIONS f :real^N->bool = UNIONS d`
19332 STRIP_ASSUME_TAC THENL
19333 [EXPAND_TAC "d" THEN ASM_SIMP_TAC[COUNTABLE_RESTRICT] THEN ASM SET_TAC[];
19336 `!s:real^N->bool. ?u. s IN d ==> u IN f /\ s SUBSET u`
19337 MP_TAC THENL [EXPAND_TAC "d" THEN SET_TAC[]; ALL_TAC] THEN
19338 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
19339 X_GEN_TAC `g:(real^N->bool)->(real^N->bool)` THEN STRIP_TAC THEN
19340 EXISTS_TAC `IMAGE (g:(real^N->bool)->(real^N->bool)) d` THEN
19341 ASM_SIMP_TAC[COUNTABLE_IMAGE; UNIONS_IMAGE] THEN
19342 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN ASM SET_TAC[]);;
19344 let LINDELOF_OPEN_IN = prove
19345 (`!f u:real^N->bool.
19346 (!s. s IN f ==> open_in (subtopology euclidean u) s)
19347 ==> ?f'. f' SUBSET f /\ COUNTABLE f' /\ UNIONS f' = UNIONS f`,
19348 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN
19349 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
19350 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
19351 X_GEN_TAC `v:(real^N->bool)->real^N->bool` THEN DISCH_TAC THEN
19352 MP_TAC(ISPEC `IMAGE (v:(real^N->bool)->real^N->bool) f` LINDELOF) THEN
19353 ASM_SIMP_TAC[FORALL_IN_IMAGE] THEN
19354 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
19355 REWRITE_TAC[EXISTS_COUNTABLE_SUBSET_IMAGE] THEN
19356 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f':(real^N->bool)->bool` THEN
19357 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
19359 `!f'. f' SUBSET f ==> UNIONS f' = (u:real^N->bool) INTER UNIONS (IMAGE v f')`
19360 MP_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[SUBSET_REFL]]);;
19362 let COUNTABLE_DISJOINT_OPEN_SUBSETS = prove
19363 (`!f. (!s:real^N->bool. s IN f ==> open s) /\ pairwise DISJOINT f
19365 REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP LINDELOF) THEN
19366 DISCH_THEN(X_CHOOSE_THEN `g:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
19367 MATCH_MP_TAC COUNTABLE_SUBSET THEN
19368 EXISTS_TAC `({}:real^N->bool) INSERT g` THEN
19369 ASM_REWRITE_TAC[COUNTABLE_INSERT] THEN
19370 REWRITE_TAC[SUBSET; IN_INSERT] THEN
19371 REPEAT(POP_ASSUM MP_TAC) THEN
19372 REWRITE_TAC[EXTENSION; SUBSET] THEN
19373 REWRITE_TAC[IN_UNIONS; pairwise] THEN
19374 REWRITE_TAC[SET_RULE `DISJOINT s t <=> !x. ~(x IN s /\ x IN t)`] THEN
19375 REWRITE_TAC[NOT_IN_EMPTY] THEN MESON_TAC[]);;
19377 let CARD_EQ_OPEN_SETS = prove
19378 (`{s:real^N->bool | open s} =_c (:real)`,
19379 REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
19380 [X_CHOOSE_THEN `b:(real^N->bool)->bool` STRIP_ASSUME_TAC
19381 UNIV_SECOND_COUNTABLE THEN
19382 TRANS_TAC CARD_LE_TRANS `{s:(real^N->bool)->bool | s SUBSET b}` THEN
19384 [REWRITE_TAC[LE_C] THEN
19385 EXISTS_TAC `UNIONS:((real^N->bool)->bool)->real^N->bool` THEN
19386 REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[];
19387 TRANS_TAC CARD_LE_TRANS `{s | s SUBSET (:num)}` THEN CONJ_TAC THENL
19388 [MATCH_MP_TAC CARD_LE_POWERSET THEN ASM_REWRITE_TAC[GSYM COUNTABLE_ALT];
19389 REWRITE_TAC[SUBSET_UNIV; UNIV_GSPEC] THEN
19390 MESON_TAC[CARD_EQ_IMP_LE; CARD_EQ_SYM; CARD_EQ_REAL]]];
19391 REWRITE_TAC[le_c; IN_UNIV; IN_ELIM_THM] THEN
19392 EXISTS_TAC `\x. ball(x % basis 1:real^N,&1)` THEN
19393 REWRITE_TAC[OPEN_BALL; GSYM SUBSET_ANTISYM_EQ; SUBSET_BALLS] THEN
19394 CONV_TAC REAL_RAT_REDUCE_CONV THEN
19395 REWRITE_TAC[NORM_ARITH `dist(p:real^N,q) + &1 <= &1 <=> p = q`] THEN
19396 REWRITE_TAC[VECTOR_MUL_RCANCEL; EQ_SYM_EQ] THEN
19397 SIMP_TAC[BASIS_NONZERO; DIMINDEX_GE_1; ARITH]]);;
19399 let CARD_EQ_CLOSED_SETS = prove
19400 (`{s:real^N->bool | closed s} =_c (:real)`,
19402 `{s:real^N->bool | closed s} =
19403 IMAGE (\s. (:real^N) DIFF s) {s | open s}`
19405 [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
19406 REWRITE_TAC[IN_ELIM_THM; GSYM OPEN_CLOSED] THEN
19407 MESON_TAC[SET_RULE `UNIV DIFF (UNIV DIFF s) = s`];
19408 TRANS_TAC CARD_EQ_TRANS `{s:real^N->bool | open s}` THEN
19409 REWRITE_TAC[CARD_EQ_OPEN_SETS] THEN
19410 MATCH_MP_TAC CARD_EQ_IMAGE THEN SET_TAC[]]);;
19412 let CARD_EQ_COMPACT_SETS = prove
19413 (`{s:real^N->bool | compact s} =_c (:real)`,
19414 REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
19415 [TRANS_TAC CARD_LE_TRANS `{s:real^N->bool | closed s}` THEN
19416 SIMP_TAC[CARD_EQ_IMP_LE; CARD_EQ_CLOSED_SETS] THEN
19417 MATCH_MP_TAC CARD_LE_SUBSET THEN
19418 SIMP_TAC[SUBSET; IN_ELIM_THM; COMPACT_IMP_CLOSED];
19419 REWRITE_TAC[le_c; IN_UNIV; IN_ELIM_THM] THEN
19420 EXISTS_TAC `\x. {x % basis 1:real^N}` THEN
19421 REWRITE_TAC[COMPACT_SING; SET_RULE `{x} = {y} <=> x = y`] THEN
19422 SIMP_TAC[VECTOR_MUL_RCANCEL; BASIS_NONZERO; DIMINDEX_GE_1; ARITH]]);;
19424 let COUNTABLE_NON_CONDENSATION_POINTS = prove
19425 (`!s:real^N->bool. COUNTABLE(s DIFF {x | x condensation_point_of s})`,
19426 REPEAT STRIP_TAC THEN REWRITE_TAC[condensation_point_of] THEN
19427 MATCH_MP_TAC COUNTABLE_SUBSET THEN
19428 X_CHOOSE_THEN `b:(real^N->bool)->bool` STRIP_ASSUME_TAC
19429 UNIV_SECOND_COUNTABLE THEN
19431 `s INTER UNIONS { u:real^N->bool | u IN b /\ COUNTABLE(s INTER u)}` THEN
19432 REWRITE_TAC[INTER_UNIONS; IN_ELIM_THM] THEN CONJ_TAC THENL
19433 [MATCH_MP_TAC COUNTABLE_UNIONS THEN SIMP_TAC[FORALL_IN_GSPEC] THEN
19434 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
19435 ASM_SIMP_TAC[COUNTABLE_IMAGE; COUNTABLE_RESTRICT];
19436 SIMP_TAC[SUBSET; UNIONS_GSPEC; IN_ELIM_THM; IN_INTER; IN_DIFF] THEN
19437 X_GEN_TAC `x:real^N` THEN
19438 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
19439 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN
19440 X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN
19441 SUBGOAL_THEN `?u:real^N->bool. x IN u /\ u IN b /\ u SUBSET t` MP_TAC THENL
19442 [ASM SET_TAC[]; MATCH_MP_TAC MONO_EXISTS] THEN
19443 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
19444 MATCH_MP_TAC COUNTABLE_SUBSET THEN
19445 EXISTS_TAC `s INTER t:real^N->bool` THEN ASM SET_TAC[]]);;
19447 let CARD_EQ_CONDENSATION_POINTS_IN_SET = prove
19449 ~(COUNTABLE s) ==> {x | x IN s /\ x condensation_point_of s} =_c s`,
19450 REPEAT STRIP_TAC THEN
19451 TRANS_TAC CARD_EQ_TRANS
19452 `(s DIFF {x | x condensation_point_of s}) +_c
19453 {x:real^N | x IN s /\ x condensation_point_of s}` THEN
19455 [ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN MATCH_MP_TAC CARD_ADD_ABSORB THEN
19456 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
19457 [POP_ASSUM MP_TAC THEN REWRITE_TAC[INFINITE; CONTRAPOS_THM] THEN
19458 DISCH_THEN(MP_TAC o CONJ (SPEC `s:real^N->bool`
19459 COUNTABLE_NON_CONDENSATION_POINTS) o MATCH_MP FINITE_IMP_COUNTABLE) THEN
19460 REWRITE_TAC[GSYM COUNTABLE_UNION] THEN MATCH_MP_TAC EQ_IMP THEN
19461 AP_TERM_TAC THEN SET_TAC[];
19462 REWRITE_TAC[INFINITE_CARD_LE] THEN
19463 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] CARD_LE_TRANS) THEN
19464 REWRITE_TAC[GSYM COUNTABLE_ALT; COUNTABLE_NON_CONDENSATION_POINTS]];
19465 ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN
19466 W(MP_TAC o PART_MATCH (rand o rand) CARD_DISJOINT_UNION o rand o snd) THEN
19467 ANTS_TAC THENL [SET_TAC[]; ALL_TAC] THEN
19468 MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN SET_TAC[]]);;
19470 let LIMPT_OF_CONDENSATION_POINTS,CONDENSATION_POINT_OF_CONDENSATION_POINTS =
19471 (CONJ_PAIR o prove)
19473 x limit_point_of {y | y condensation_point_of s} <=>
19474 x condensation_point_of s) /\
19476 x condensation_point_of {y | y condensation_point_of s} <=>
19477 x condensation_point_of s)`,
19478 REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
19479 `(r ==> q) /\ (q ==> p) /\ (p ==> r)
19480 ==> (q <=> p) /\ (r <=> p)`) THEN
19481 REWRITE_TAC[CONDENSATION_POINT_IMP_LIMPT] THEN CONJ_TAC THENL
19482 [REWRITE_TAC[LIMPT_APPROACHABLE; CONDENSATION_POINT_INFINITE_BALL] THEN
19483 REPEAT GEN_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN
19484 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
19485 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
19486 DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN
19487 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
19488 ASM_REWRITE_TAC[REAL_HALF; CONTRAPOS_THM] THEN
19489 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] COUNTABLE_SUBSET) THEN
19490 SIMP_TAC[SUBSET; IN_INTER; IN_BALL] THEN
19491 REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC;
19492 ONCE_REWRITE_TAC[CONDENSATION_POINT_INFINITE_BALL] THEN DISCH_TAC THEN
19493 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
19494 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
19495 ASM_REWRITE_TAC[REAL_HALF] THEN DISCH_THEN(MP_TAC o MATCH_MP
19496 (MESON[CARD_EQ_CONDENSATION_POINTS_IN_SET; CARD_COUNTABLE_CONG]
19498 ==> ~COUNTABLE {x | x IN s /\ x condensation_point_of s}`)) THEN
19499 REWRITE_TAC[UNCOUNTABLE_REAL; CONTRAPOS_THM] THEN
19500 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] COUNTABLE_SUBSET) THEN
19501 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INTER] THEN X_GEN_TAC `y:real^N` THEN
19502 REPEAT STRIP_TAC THENL
19503 [ASM_MESON_TAC[CONDENSATION_POINT_OF_SUBSET; INTER_SUBSET]; ALL_TAC] THEN
19504 MATCH_MP_TAC(SET_RULE `!s. x IN s /\ s SUBSET t ==> x IN t`) THEN
19505 EXISTS_TAC `closure(s INTER ball(x:real^N,e / &2))` THEN CONJ_TAC THENL
19506 [REWRITE_TAC[closure; IN_UNION; IN_ELIM_THM] THEN DISJ2_TAC THEN
19507 ASM_SIMP_TAC[CONDENSATION_POINT_IMP_LIMPT];
19508 TRANS_TAC SUBSET_TRANS `closure(ball(x:real^N,e / &2))` THEN
19509 SIMP_TAC[SUBSET_CLOSURE; INTER_SUBSET] THEN
19510 ASM_SIMP_TAC[CLOSURE_BALL; REAL_HALF; SUBSET_BALLS; DIST_REFL] THEN
19511 ASM_REAL_ARITH_TAC]]);;
19513 let CLOSED_CONDENSATION_POINTS = prove
19514 (`!s:real^N->bool. closed {x | x condensation_point_of s}`,
19515 SIMP_TAC[CLOSED_LIMPT; LIMPT_OF_CONDENSATION_POINTS; IN_ELIM_THM]);;
19517 let CANTOR_BENDIXSON = prove
19520 ==> ?t u. closed t /\ (!x. x IN t ==> x limit_point_of t) /\
19521 COUNTABLE u /\ s = t UNION u`,
19522 REPEAT STRIP_TAC THEN MAP_EVERY EXISTS_TAC
19523 [`{x:real^N | x condensation_point_of s}`;
19524 `s DIFF {x:real^N | x condensation_point_of s}`] THEN
19525 REWRITE_TAC[COUNTABLE_NON_CONDENSATION_POINTS; CLOSED_CONDENSATION_POINTS;
19526 IN_ELIM_THM; LIMPT_OF_CONDENSATION_POINTS] THEN
19527 REWRITE_TAC[SET_RULE `s = t UNION (s DIFF t) <=> t SUBSET s`] THEN
19528 RULE_ASSUM_TAC(REWRITE_RULE[CLOSED_LIMPT]) THEN
19529 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
19530 ASM_MESON_TAC[CONDENSATION_POINT_IMP_LIMPT]);;
19532 (* ------------------------------------------------------------------------- *)
19533 (* A discrete set is countable, and an uncountable set has a limit point. *)
19534 (* ------------------------------------------------------------------------- *)
19536 let DISCRETE_IMP_COUNTABLE = prove
19538 (!x. x IN s ==> ?e. &0 < e /\
19539 !y. y IN s /\ ~(y = x) ==> e <= norm(y - x))
19541 REPEAT STRIP_TAC THEN
19544 ==> ?q. (!i. 1 <= i /\ i <= dimindex(:N) ==> rational(q$i)) /\
19545 !y:real^N. y IN s /\ ~(y = x) ==> norm(x - q) < norm(y - q)`
19547 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
19548 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
19549 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
19550 MP_TAC(SET_RULE `x IN (:real^N)`) THEN
19551 REWRITE_TAC[GSYM CLOSURE_RATIONAL_COORDINATES] THEN
19552 REWRITE_TAC[CLOSURE_APPROACHABLE; IN_ELIM_THM] THEN
19553 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
19554 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `q:real^N` THEN
19555 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
19556 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
19557 FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[] THEN
19558 REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC;
19559 POP_ASSUM(K ALL_TAC) THEN
19560 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
19561 X_GEN_TAC `q:real^N->real^N` THEN DISCH_TAC THEN
19564 `{ x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i) }`;
19565 `(:num)`] CARD_LE_TRANS) THEN
19566 REWRITE_TAC[COUNTABLE; ge_c] THEN DISCH_THEN MATCH_MP_TAC THEN
19567 SIMP_TAC[REWRITE_RULE[COUNTABLE; ge_c] COUNTABLE_RATIONAL_COORDINATES] THEN
19568 REWRITE_TAC[le_c] THEN EXISTS_TAC `q:real^N->real^N` THEN
19569 ASM_SIMP_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[REAL_LT_ANTISYM]]);;
19571 let UNCOUNTABLE_CONTAINS_LIMIT_POINT = prove
19572 (`!s. ~(COUNTABLE s) ==> ?x. x IN s /\ x limit_point_of s`,
19573 GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP
19574 (ONCE_REWRITE_RULE[GSYM CONTRAPOS_THM] DISCRETE_IMP_COUNTABLE)) THEN
19575 REWRITE_TAC[LIMPT_APPROACHABLE; GSYM REAL_NOT_LT; dist] THEN
19578 (* ------------------------------------------------------------------------- *)
19579 (* The Brouwer reduction theorem. *)
19580 (* ------------------------------------------------------------------------- *)
19582 let BROUWER_REDUCTION_THEOREM_GEN = prove
19583 (`!P s:real^N->bool.
19584 (!f. (!n. closed(f n) /\ P(f n)) /\ (!n. f(SUC n) SUBSET f(n))
19585 ==> P(INTERS {f n | n IN (:num)})) /\
19587 ==> ?t. t SUBSET s /\ closed t /\ P t /\
19588 (!u. u SUBSET s /\ closed u /\ P u ==> ~(u PSUBSET t))`,
19589 REPEAT STRIP_TAC THEN
19591 `?b:num->real^N->bool.
19592 (!m n. b m = b n <=> m = n) /\
19593 (!n. open (b n)) /\
19594 (!s. open s ==> (?k. s = UNIONS {b n | n IN k}))`
19595 STRIP_ASSUME_TAC THENL
19596 [REWRITE_TAC[UNIV_SECOND_COUNTABLE_SEQUENCE]; ALL_TAC] THEN
19597 X_CHOOSE_THEN `a:num->real^N->bool` MP_TAC
19598 (prove_recursive_functions_exist num_RECURSION
19599 `a 0 = (s:real^N->bool) /\
19601 if ?u. u SUBSET a(n) /\ closed u /\ P u /\ u INTER (b n) = {}
19602 then @u. u SUBSET a(n) /\ closed u /\ P u /\ u INTER (b n) = {}
19604 DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "base") (LABEL_TAC "step")) THEN
19605 EXISTS_TAC `INTERS {a n :real^N->bool | n IN (:num)}` THEN
19606 SUBGOAL_THEN `!n. (a:num->real^N->bool)(SUC n) SUBSET a(n)` ASSUME_TAC THENL
19607 [GEN_TAC THEN ASM_REWRITE_TAC[] THEN
19608 COND_CASES_TAC THEN REWRITE_TAC[SUBSET_REFL] THEN
19609 FIRST_X_ASSUM(MP_TAC o SELECT_RULE) THEN MESON_TAC[];
19611 SUBGOAL_THEN `!n. (a:num->real^N->bool) n SUBSET s` ASSUME_TAC THENL
19612 [INDUCT_TAC THEN ASM_MESON_TAC[SUBSET_REFL; SUBSET_TRANS]; ALL_TAC] THEN
19613 SUBGOAL_THEN `!n. closed((a:num->real^N->bool) n) /\ P(a n)` ASSUME_TAC THENL
19614 [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN
19615 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
19616 FIRST_X_ASSUM(MP_TAC o SELECT_RULE) THEN MESON_TAC[];
19618 REPEAT CONJ_TAC THENL
19620 MATCH_MP_TAC CLOSED_INTERS THEN
19621 ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV] THEN SET_TAC[];
19622 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[];
19623 X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN
19624 REWRITE_TAC[PSUBSET_ALT] THEN
19625 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
19626 REWRITE_TAC[INTERS_GSPEC; EXISTS_IN_GSPEC; IN_UNIV] THEN
19627 DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN
19629 `?n. x IN (b:num->real^N->bool)(n) /\ t INTER b n = {}`
19630 STRIP_ASSUME_TAC THENL
19631 [MP_TAC(ISPEC `(:real^N) DIFF t` OPEN_CONTAINS_BALL) THEN
19632 ASM_REWRITE_TAC[GSYM closed] THEN
19633 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
19634 ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN
19635 REWRITE_TAC[SET_RULE `s SUBSET UNIV DIFF t <=> t INTER s = {}`] THEN
19636 X_GEN_TAC `e:real` THEN
19637 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
19638 MP_TAC(ISPECL [`x:real^N`; `e:real`] CENTRE_IN_BALL) THEN
19639 FIRST_X_ASSUM(MP_TAC o SPEC `ball(x:real^N,e)`) THEN
19640 ASM_REWRITE_TAC[OPEN_BALL; LEFT_IMP_EXISTS_THM] THEN
19641 X_GEN_TAC `k:num->bool` THEN DISCH_THEN SUBST1_TAC THEN
19642 REWRITE_TAC[IN_UNIONS; INTER_UNIONS; EMPTY_UNIONS; FORALL_IN_GSPEC] THEN
19644 REMOVE_THEN "step" (MP_TAC o SPEC `n:num`) THEN
19645 COND_CASES_TAC THENL
19646 [DISCH_THEN(ASSUME_TAC o SYM) THEN
19647 FIRST_X_ASSUM(MP_TAC o SELECT_RULE) THEN ASM_REWRITE_TAC[] THEN
19649 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN
19650 DISCH_THEN(MP_TAC o SPEC `t:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
19651 ASM SET_TAC[]]]]);;
19653 let BROUWER_REDUCTION_THEOREM = prove
19654 (`!P s:real^N->bool.
19655 (!f. (!n. compact(f n) /\ ~(f n = {}) /\ P(f n)) /\
19656 (!n. f(SUC n) SUBSET f(n))
19657 ==> P(INTERS {f n | n IN (:num)})) /\
19658 compact s /\ ~(s = {}) /\ P s
19659 ==> ?t. t SUBSET s /\ compact t /\ ~(t = {}) /\ P t /\
19660 (!u. u SUBSET s /\ closed u /\ ~(u = {}) /\ P u
19661 ==> ~(u PSUBSET t))`,
19662 REPEAT STRIP_TAC THEN
19663 MP_TAC(ISPECL [`\t:real^N->bool. ~(t = {}) /\ t SUBSET s /\ P t`;
19665 BROUWER_REDUCTION_THEOREM_GEN) THEN
19666 ASM_SIMP_TAC[COMPACT_IMP_CLOSED; SUBSET_REFL] THEN ANTS_TAC THENL
19667 [GEN_TAC THEN STRIP_TAC THEN
19668 SUBGOAL_THEN `!n. compact((f:num->real^N->bool) n)` ASSUME_TAC THENL
19669 [ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_SUBSET]; ALL_TAC] THEN
19670 REPEAT CONJ_TAC THENL
19671 [MATCH_MP_TAC COMPACT_NEST THEN ASM_REWRITE_TAC[] THEN
19672 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_SIMP_TAC[] THEN SET_TAC[];
19674 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]];
19675 MATCH_MP_TAC MONO_EXISTS THEN ASM_SIMP_TAC[] THEN
19676 ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_SUBSET]]);;
19678 (* ------------------------------------------------------------------------- *)
19679 (* The Arzela-Ascoli theorem. *)
19680 (* ------------------------------------------------------------------------- *)
19682 let SUBSEQUENCE_DIAGONALIZATION_LEMMA = prove
19683 (`!P:num->(num->A)->bool.
19684 (!i r:num->A. ?k. (!m n. m < n ==> k m < k n) /\ P i (r o k)) /\
19685 (!i r:num->A k1 k2 N.
19686 P i (r o k1) /\ (!j. N <= j ==> ?j'. j <= j' /\ k2 j = k1 j')
19688 ==> !r:num->A. ?k. (!m n. m < n ==> k m < k n) /\ (!i. P i (r o k))`,
19689 REPEAT GEN_TAC THEN
19690 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
19691 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [SKOLEM_THM] THEN
19692 REWRITE_TAC[FORALL_AND_THM; TAUT
19693 `(p ==> q /\ r) <=> (p ==> q) /\ (p ==> r)`] THEN
19694 DISCH_THEN(X_CHOOSE_THEN
19695 `kk:num->(num->A)->num->num` STRIP_ASSUME_TAC) THEN
19696 X_GEN_TAC `r:num->A` THEN
19697 (STRIP_ASSUME_TAC o prove_recursive_functions_exist num_RECURSION)
19698 `(rr 0 = (kk:num->(num->A)->num->num) 0 r) /\
19699 (!n. rr(SUC n) = rr n o kk (SUC n) (r o rr n))` THEN
19700 EXISTS_TAC `\n. (rr:num->num->num) n n` THEN REWRITE_TAC[ETA_AX] THEN
19702 `(!i. (!m n. m < n ==> (rr:num->num->num) i m < rr i n)) /\
19703 (!i. (P:num->(num->A)->bool) i (r o rr i))`
19704 STRIP_ASSUME_TAC THENL
19705 [REWRITE_TAC[AND_FORALL_THM] THEN
19706 INDUCT_TAC THEN ASM_REWRITE_TAC[o_ASSOC] THEN
19707 REWRITE_TAC[o_THM] THEN ASM_MESON_TAC[];
19709 SUBGOAL_THEN `!i j n. i <= j ==> (rr:num->num->num) i n <= rr j n`
19711 [REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [LE_EXISTS] THEN
19712 SIMP_TAC[LEFT_IMP_EXISTS_THM] THEN SPEC_TAC(`j:num`,`j:num`) THEN
19713 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN SIMP_TAC[FORALL_UNWIND_THM2] THEN
19714 INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES; LE_REFL] THEN
19715 ASM_REWRITE_TAC[] THEN FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP
19716 (REWRITE_RULE[IMP_CONJ] LE_TRANS)) THEN REWRITE_TAC[o_THM] THEN
19717 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP
19720 (!m n. m < n ==> f m < f n) ==> (!m n. m <= n ==> f m <= f n)`) o
19721 SPEC `i + d:num`) THEN
19722 SPEC_TAC(`n:num`,`n:num`) THEN MATCH_MP_TAC MONOTONE_BIGGER THEN
19726 [MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN
19727 MATCH_MP_TAC LET_TRANS THEN
19728 EXISTS_TAC `(rr:num->num->num) n m` THEN
19729 ASM_MESON_TAC[LT_IMP_LE];
19732 `!m n i. n <= m ==> ?j. i <= j /\ (rr:num->num->num) m i = rr n j`
19735 X_GEN_TAC `i:num` THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
19736 EXISTS_TAC `(rr:num->num->num) i` THEN ASM_REWRITE_TAC[] THEN
19737 EXISTS_TAC `i:num` THEN ASM_MESON_TAC[]] THEN
19739 `!p d i. ?j. i <= j /\ (rr:num->num->num) (p + d) i = rr p j`
19740 (fun th -> MESON_TAC[LE_EXISTS; th]) THEN
19741 X_GEN_TAC `p:num` THEN MATCH_MP_TAC num_INDUCTION THEN
19742 ASM_REWRITE_TAC[ADD_CLAUSES] THEN CONJ_TAC THENL
19743 [MESON_TAC[LE_REFL]; ALL_TAC] THEN
19744 X_GEN_TAC `d:num` THEN DISCH_THEN(LABEL_TAC "+") THEN
19745 X_GEN_TAC `i:num` THEN ASM_REWRITE_TAC[o_THM] THEN
19746 REMOVE_THEN "+" (MP_TAC o SPEC
19747 `(kk:num->(num->A)->num->num) (SUC(p + d))
19748 ((r:num->A) o (rr:num->num->num) (p + d)) i`) THEN
19749 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `j:num` THEN
19750 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
19751 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LE_TRANS) THEN
19752 SPEC_TAC(`i:num`,`i:num`) THEN MATCH_MP_TAC MONOTONE_BIGGER THEN
19753 ASM_REWRITE_TAC[o_THM] THEN ASM_MESON_TAC[]);;
19755 let FUNCTION_CONVERGENT_SUBSEQUENCE = prove
19756 (`!f:num->real^M->real^N s M.
19757 COUNTABLE s /\ (!n x. x IN s ==> norm(f n x) <= M)
19758 ==> ?k. (!m n:num. m < n ==> k m < k n) /\
19759 !x. x IN s ==> ?l. ((\n. f (k n) x) --> l) sequentially`,
19760 REPEAT STRIP_TAC THEN
19761 ASM_CASES_TAC `s:real^M->bool = {}` THENL
19762 [EXISTS_TAC `\n:num. n` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY];
19764 MP_TAC(ISPEC `s:real^M->bool` COUNTABLE_AS_IMAGE) THEN
19765 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
19766 X_GEN_TAC `X:num->real^M` THEN DISCH_THEN SUBST_ALL_TAC THEN
19768 `\i r. ?l. ((\n. ((f:num->real^M->real^N) o (r:num->num)) n
19769 ((X:num->real^M) i)) --> l) sequentially`
19770 SUBSEQUENCE_DIAGONALIZATION_LEMMA) THEN
19771 REWRITE_TAC[FORALL_IN_IMAGE; o_THM; IN_UNIV] THEN
19772 ANTS_TAC THENL [ALL_TAC; DISCH_THEN MATCH_ACCEPT_TAC] THEN CONJ_TAC THENL
19773 [RULE_ASSUM_TAC(REWRITE_RULE[FORALL_IN_IMAGE; IN_UNIV]) THEN
19774 MAP_EVERY X_GEN_TAC [`i:num`; `r:num->num`] THEN
19775 MP_TAC(ISPEC `cball(vec 0:real^N,M)` compact) THEN
19776 REWRITE_TAC[COMPACT_CBALL] THEN DISCH_THEN(MP_TAC o SPEC
19777 `\n. (f:num->real^M->real^N) ((r:num->num) n) (X(i:num))`) THEN
19778 ASM_REWRITE_TAC[IN_CBALL_0; o_DEF] THEN MESON_TAC[];
19779 REPEAT GEN_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY; GE] THEN
19780 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
19781 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
19782 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
19783 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
19784 ASM_MESON_TAC[LE_TRANS; ARITH_RULE `MAX a b <= c <=> a <= c /\ b <= c`]]);;
19786 let ARZELA_ASCOLI = prove
19787 (`!f:num->real^M->real^N s M.
19789 (!n x. x IN s ==> norm(f n x) <= M) /\
19790 (!x e. x IN s /\ &0 < e
19792 !n y. y IN s /\ norm(x - y) < d
19793 ==> norm(f n x - f n y) < e)
19794 ==> ?g. g continuous_on s /\
19795 ?r. (!m n:num. m < n ==> r m < r n) /\
19797 ==> ?N. !n x. n >= N /\ x IN s
19798 ==> norm(f(r n) x - g x) < e`,
19799 REPEAT STRIP_TAC THEN REWRITE_TAC[GE] THEN
19800 MATCH_MP_TAC(MESON[]
19801 `(!k g. V k g ==> N g) /\ (?k. M k /\ ?g. V k g)
19802 ==> ?g. N g /\ ?k. M k /\ V k g`) THEN
19804 [MAP_EVERY X_GEN_TAC [`k:num->num`; `g:real^M->real^N`] THEN
19805 STRIP_TAC THEN MATCH_MP_TAC(ISPEC `sequentially`
19806 CONTINUOUS_UNIFORM_LIMIT) THEN
19807 EXISTS_TAC `(f:num->real^M->real^N) o (k:num->num)` THEN
19808 ASM_SIMP_TAC[EVENTUALLY_SEQUENTIALLY; o_THM; TRIVIAL_LIMIT_SEQUENTIALLY;
19809 RIGHT_IMP_FORALL_THM; IMP_IMP] THEN
19810 EXISTS_TAC `0` THEN REWRITE_TAC[continuous_on; dist] THEN
19811 ASM_MESON_TAC[NORM_SUB];
19814 [`IMAGE (f:num->real^M->real^N) (:num)`;
19816 COMPACT_UNIFORMLY_EQUICONTINUOUS) THEN
19817 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE; IN_UNIV] THEN
19819 [REWRITE_TAC[dist] THEN ONCE_REWRITE_TAC[NORM_SUB] THEN ASM_MESON_TAC[];
19820 ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(K ALL_TAC o SPEC `x:real^M`)] THEN
19821 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
19822 REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; dist] THEN
19823 DISCH_THEN(ASSUME_TAC o ONCE_REWRITE_RULE[NORM_SUB]) THEN
19824 REWRITE_TAC[GSYM dist; UNIFORMLY_CONVERGENT_EQ_CAUCHY] THEN
19825 X_CHOOSE_THEN `r:real^M->bool` STRIP_ASSUME_TAC
19826 (ISPEC `s:real^M->bool` SEPARABLE) THEN
19827 MP_TAC(ISPECL [`f:num->real^M->real^N`; `r:real^M->bool`; `M:real`]
19828 FUNCTION_CONVERGENT_SUBSEQUENCE) THEN
19829 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
19830 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:num->num` THEN
19831 REWRITE_TAC[CONVERGENT_EQ_CAUCHY; cauchy] THEN
19832 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*")) THEN
19833 ASM_REWRITE_TAC[] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
19834 FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN
19835 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
19836 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
19837 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL]) THEN
19838 DISCH_THEN(MP_TAC o SPEC `IMAGE (\x:real^M. ball(x,d)) r`) THEN
19839 REWRITE_TAC[FORALL_IN_IMAGE; OPEN_BALL] THEN
19840 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN
19841 REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE] THEN ANTS_TAC THENL
19842 [MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `closure r:real^M->bool` THEN
19843 ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET; CLOSURE_APPROACHABLE] THEN
19844 X_GEN_TAC `x:real^M` THEN DISCH_THEN(MP_TAC o SPEC `d:real`) THEN
19845 ASM_REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM; IN_BALL];
19846 DISCH_THEN(X_CHOOSE_THEN `t:real^M->bool` STRIP_ASSUME_TAC)] THEN
19847 REMOVE_THEN "*" MP_TAC THEN REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
19848 GEN_REWRITE_TAC LAND_CONV [SWAP_FORALL_THM] THEN
19849 DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
19850 ASM_REWRITE_TAC[REAL_ARITH `&0 < e / &3 <=> &0 < e`] THEN
19851 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
19852 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
19853 X_GEN_TAC `M:real^M->num` THEN DISCH_THEN(LABEL_TAC "*") THEN
19854 MP_TAC(ISPECL [`M:real^M->num`; `t:real^M->bool`]
19855 UPPER_BOUND_FINITE_SET) THEN
19856 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
19858 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`; `x:real^M`] THEN STRIP_TAC THEN
19859 UNDISCH_TAC `s SUBSET UNIONS (IMAGE (\x:real^M. ball (x,d)) t)` THEN
19860 REWRITE_TAC[SUBSET; UNIONS_IMAGE; IN_ELIM_THM] THEN
19861 DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN
19862 ASM_REWRITE_TAC[IN_BALL; LEFT_IMP_EXISTS_THM; dist] THEN
19863 X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN
19864 MATCH_MP_TAC(NORM_ARITH
19865 `norm(f (k(m:num)) y - f (k m) x) < e / &3 /\
19866 norm(f (k n) y - f (k n) x) < e / &3 /\
19867 norm(f (k m) y - f (k n) y) < e / &3
19868 ==> norm(f (k m) x - f (k n) x :real^M) < e`) THEN
19869 ASM_SIMP_TAC[] THEN REMOVE_THEN "*" (MP_TAC o SPEC `y:real^M`) THEN
19870 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
19871 DISCH_THEN(MP_TAC o SPECL [`m:num`; `n:num`]) THEN
19872 ASM_REWRITE_TAC[dist; GE] THEN ASM_MESON_TAC[SUBSET; LE_TRANS]);;
19874 (* ------------------------------------------------------------------------- *)
19875 (* Two forms of the Baire propery of dense sets. *)
19876 (* ------------------------------------------------------------------------- *)
19879 (`!g s:real^N->bool.
19880 closed s /\ COUNTABLE g /\
19882 ==> open_in (subtopology euclidean s) t /\ s SUBSET closure t)
19883 ==> s SUBSET closure(INTERS g)`,
19884 REPEAT STRIP_TAC THEN ASM_CASES_TAC `g:(real^N->bool)->bool = {}` THEN
19885 ASM_REWRITE_TAC[INTERS_0; CLOSURE_UNIV; SUBSET_UNIV] THEN
19886 MP_TAC(ISPEC `g:(real^N->bool)->bool` COUNTABLE_AS_IMAGE) THEN
19887 ASM_REWRITE_TAC[] THEN
19888 MAP_EVERY (C UNDISCH_THEN (K ALL_TAC))
19889 [`COUNTABLE(g:(real^N->bool)->bool)`;
19890 `~(g:(real^N->bool)->bool = {})`] THEN
19891 DISCH_THEN(X_CHOOSE_THEN `g:num->real^N->bool` SUBST_ALL_TAC) THEN
19892 RULE_ASSUM_TAC(REWRITE_RULE[FORALL_IN_IMAGE; IN_UNIV]) THEN
19893 REWRITE_TAC[SUBSET; CLOSURE_APPROACHABLE] THEN
19894 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
19895 X_GEN_TAC `e:real` THEN DISCH_TAC THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
19896 REWRITE_TAC[GSYM IN_BALL; GSYM IN_INTER; MEMBER_NOT_EMPTY] THEN
19898 `?t:num->real^N->bool.
19899 (!n. open_in (subtopology euclidean s) (t n) /\ ~(t n = {}) /\
19900 s INTER closure(t n) SUBSET g n /\
19901 closure(t n) SUBSET ball(x,e)) /\
19902 (!n. t(SUC n) SUBSET t n)`
19903 STRIP_ASSUME_TAC THENL
19905 `!u n. open_in (subtopology euclidean s) u /\ ~(u = {}) /\
19906 closure u SUBSET ball(x,e)
19907 ==> ?y. open_in (subtopology euclidean s) y /\
19909 s INTER closure y SUBSET (g:num->real^N->bool) n /\
19910 closure y SUBSET ball(x,e) /\
19913 [MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `n:num`] THEN STRIP_TAC THEN
19914 SUBGOAL_THEN `?y:real^N. y IN u /\ y IN g(n:num)` STRIP_ASSUME_TAC THENL
19915 [FIRST_X_ASSUM(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC o SPEC `n:num`) THEN
19916 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
19917 FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
19918 DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN
19919 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [open_in]) THEN
19920 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `y:real^N`)) THEN
19921 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `d:real` THEN
19922 STRIP_TAC THEN REWRITE_TAC[SUBSET; CLOSURE_APPROACHABLE] THEN
19926 `open_in (subtopology euclidean s) (u INTER g(n:num):real^N->bool)`
19927 MP_TAC THENL [ASM_SIMP_TAC[OPEN_IN_INTER]; ALL_TAC] THEN
19928 GEN_REWRITE_TAC LAND_CONV [OPEN_IN_CONTAINS_BALL] THEN
19929 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `y:real^N`)) THEN
19930 ASM_REWRITE_TAC[IN_INTER] THEN
19931 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
19932 EXISTS_TAC `s INTER ball(y:real^N,d / &2)` THEN
19933 SIMP_TAC[OPEN_IN_OPEN_INTER; OPEN_BALL] THEN REPEAT CONJ_TAC THENL
19934 [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN EXISTS_TAC `y:real^N` THEN
19935 ASM_REWRITE_TAC[CENTRE_IN_BALL; REAL_HALF; IN_INTER] THEN
19937 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
19938 `b SUBSET u INTER g ==> !s. s SUBSET b ==> s SUBSET g`)) THEN
19939 MATCH_MP_TAC(SET_RULE
19940 `closure(s INTER b) SUBSET closure b /\ closure b SUBSET c
19941 ==> s INTER closure(s INTER b) SUBSET c INTER s`) THEN
19942 SIMP_TAC[SUBSET_CLOSURE; INTER_SUBSET] THEN
19943 ASM_SIMP_TAC[CLOSURE_BALL; SUBSET_BALLS; REAL_HALF; DIST_REFL] THEN
19944 ASM_REAL_ARITH_TAC;
19945 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
19946 SUBSET_TRANS)) THEN MATCH_MP_TAC SUBSET_CLOSURE;
19948 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
19949 `b INTER s SUBSET u INTER g ==> c SUBSET b
19950 ==> s INTER c SUBSET u`)) THEN
19951 REWRITE_TAC[SUBSET_BALLS; DIST_REFL] THEN ASM_REAL_ARITH_TAC;
19952 MATCH_MP_TAC DEPENDENT_CHOICE THEN ASM_SIMP_TAC[GSYM CONJ_ASSOC] THEN
19953 FIRST_X_ASSUM(MP_TAC o SPECL [`s INTER ball(x:real^N,e / &2)`; `0`]) THEN
19954 ASM_SIMP_TAC[OPEN_IN_OPEN_INTER; OPEN_BALL; GSYM MEMBER_NOT_EMPTY] THEN
19955 ANTS_TAC THENL [REWRITE_TAC[LEFT_AND_EXISTS_THM]; MESON_TAC[]] THEN
19956 EXISTS_TAC `x:real^N` THEN
19957 ASM_REWRITE_TAC[CENTRE_IN_BALL; REAL_HALF; IN_INTER] THEN
19958 TRANS_TAC SUBSET_TRANS `closure(ball(x:real^N,e / &2))` THEN
19959 SIMP_TAC[SUBSET_CLOSURE; INTER_SUBSET] THEN
19960 ASM_SIMP_TAC[CLOSURE_BALL; SUBSET_BALLS; REAL_HALF; DIST_REFL] THEN
19961 ASM_REAL_ARITH_TAC];
19963 `(\n. s INTER closure(t n)):num->real^N->bool` COMPACT_NEST) THEN
19965 [REWRITE_TAC[FORALL_AND_THM] THEN REPEAT CONJ_TAC THENL
19966 [GEN_TAC THEN MATCH_MP_TAC CLOSED_INTER_COMPACT THEN
19967 ASM_MESON_TAC[BOUNDED_SUBSET; BOUNDED_BALL; COMPACT_EQ_BOUNDED_CLOSED;
19969 GEN_TAC THEN MATCH_MP_TAC(SET_RULE
19970 `~(t = {}) /\ t SUBSET s /\ t SUBSET closure t
19971 ==> ~(s INTER closure t = {})`) THEN
19972 ASM_MESON_TAC[CLOSURE_SUBSET; OPEN_IN_IMP_SUBSET];
19973 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
19974 ASM_SIMP_TAC[SUBSET_CLOSURE; SET_RULE
19975 `t SUBSET u ==> s INTER t SUBSET s INTER u`] THEN
19977 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> ~(s = {}) ==> ~(t = {})`) THEN
19978 REWRITE_TAC[SUBSET_INTER] THEN
19979 REWRITE_TAC[SUBSET; IN_INTERS; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN
19982 let BAIRE_ALT = prove
19983 (`!g s:real^N->bool.
19984 closed s /\ ~(s = {}) /\ COUNTABLE g /\ UNIONS g = s
19985 ==> ?t u. t IN g /\ open_in (subtopology euclidean s) u /\
19986 u SUBSET (closure t)`,
19987 REPEAT STRIP_TAC THEN MP_TAC(ISPECL
19988 [`IMAGE (\t:real^N->bool. s DIFF closure t) g`; `s:real^N->bool`] BAIRE) THEN
19989 ASM_SIMP_TAC[COUNTABLE_IMAGE; FORALL_IN_IMAGE] THEN
19990 MATCH_MP_TAC(TAUT `~q /\ (~r ==> p) ==> (p ==> q) ==> r`) THEN
19992 [MATCH_MP_TAC(SET_RULE
19993 `~(s = {}) /\ (t = {} ==> closure t = {}) /\ t = {}
19994 ==> ~(s SUBSET closure t)`) THEN
19995 ASM_SIMP_TAC[CLOSURE_EMPTY] THEN
19996 MATCH_MP_TAC(SET_RULE `i SUBSET s /\ s DIFF i = s ==> i = {}`) THEN
19997 CONJ_TAC THENL [REWRITE_TAC[INTERS_IMAGE] THEN ASM SET_TAC[]; ALL_TAC] THEN
19998 REWRITE_TAC[DIFF_INTERS] THEN
19999 REWRITE_TAC[SET_RULE `{f x | x IN IMAGE g s} = {f(g x) | x IN s}`] THEN
20000 REWRITE_TAC[SET_RULE `s DIFF (s DIFF t) = s INTER t`] THEN
20001 REWRITE_TAC[SET_RULE `{s INTER closure t | t IN g} =
20002 {s INTER t | t IN IMAGE closure g}`] THEN
20003 SIMP_TAC[GSYM INTER_UNIONS; SET_RULE `s INTER t = s <=> s SUBSET t`] THEN
20004 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
20005 GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM IMAGE_ID] THEN
20006 MATCH_MP_TAC UNIONS_MONO_IMAGE THEN REWRITE_TAC[CLOSURE_SUBSET];
20007 REWRITE_TAC[NOT_EXISTS_THM] THEN STRIP_TAC THEN
20008 X_GEN_TAC `t:real^N->bool` THEN REPEAT STRIP_TAC THENL
20009 [ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s DIFF (s INTER t)`] THEN
20010 MATCH_MP_TAC OPEN_IN_DIFF THEN
20011 ASM_SIMP_TAC[CLOSED_IN_CLOSED_INTER; CLOSED_CLOSURE; OPEN_IN_REFL];
20012 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
20013 REWRITE_TAC[CLOSURE_APPROACHABLE] THEN
20014 X_GEN_TAC `e:real` THEN DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL
20015 [`t:real^N->bool`; `s INTER ball(x:real^N,e)`]) THEN
20016 ASM_SIMP_TAC[OPEN_IN_OPEN_INTER; OPEN_BALL; SUBSET; IN_INTER; IN_BALL;
20018 MESON_TAC[DIST_SYM]]]);;
20020 (* ------------------------------------------------------------------------- *)
20021 (* Several variants of paracompactness. *)
20022 (* ------------------------------------------------------------------------- *)
20024 let PARACOMPACT = prove
20025 (`!s c. (!t:real^N->bool. t IN c ==> open t) /\ s SUBSET UNIONS c
20026 ==> ?c'. s SUBSET UNIONS c' /\
20028 ==> open u /\ ?t. t IN c /\ u SUBSET t) /\
20030 ==> ?v. open v /\ x IN v /\
20031 FINITE {u | u IN c' /\ ~(u INTER v = {})})`,
20032 REPEAT STRIP_TAC THEN
20033 ASM_CASES_TAC `s:real^N->bool = {}` THENL
20034 [EXISTS_TAC `{}:(real^N->bool)->bool` THEN
20035 ASM_REWRITE_TAC[EMPTY_SUBSET; NOT_IN_EMPTY];
20039 ==> ?t u. x IN u /\ open u /\ closure u SUBSET t /\ t IN c`
20041 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
20042 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N` o GEN_REWRITE_RULE I [SUBSET]) THEN
20043 ASM_REWRITE_TAC[IN_UNIONS] THEN MATCH_MP_TAC MONO_EXISTS THEN
20044 X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN
20045 FIRST_X_ASSUM(MP_TAC o SPEC `t:real^N->bool`) THEN
20046 ASM_REWRITE_TAC[] THEN
20047 GEN_REWRITE_TAC LAND_CONV [OPEN_CONTAINS_CBALL] THEN
20048 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
20049 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
20050 EXISTS_TAC `ball(x:real^N,e)` THEN
20051 ASM_SIMP_TAC[OPEN_BALL; CENTRE_IN_BALL; CLOSURE_BALL];
20052 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
20053 REWRITE_TAC[LEFT_IMP_EXISTS_THM; SKOLEM_THM] THEN
20054 MAP_EVERY X_GEN_TAC
20055 [`f:real^N->real^N->bool`; `e:real^N->real^N->bool`] THEN
20057 MP_TAC(ISPEC `IMAGE (e:real^N->real^N->bool) s` LINDELOF) THEN
20058 ASM_SIMP_TAC[FORALL_IN_IMAGE] THEN
20059 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
20060 REWRITE_TAC[EXISTS_COUNTABLE_SUBSET_IMAGE] THEN
20061 DISCH_THEN(X_CHOOSE_THEN `k:real^N->bool`
20062 (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
20063 ASM_CASES_TAC `k:real^N->bool = {}` THENL
20064 [ASM_REWRITE_TAC[] THEN ASM SET_TAC[]; ALL_TAC] THEN
20065 MP_TAC(ISPEC `k:real^N->bool` COUNTABLE_AS_IMAGE) THEN
20066 ASM_REWRITE_TAC[] THEN
20067 DISCH_THEN(X_CHOOSE_THEN `a:num->real^N` SUBST_ALL_TAC) THEN
20068 STRIP_TAC THEN EXISTS_TAC
20069 `{ f(a n:real^N) DIFF UNIONS {closure(e(a m)):real^N->bool | m < n} |
20071 REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV] THEN REPEAT CONJ_TAC THENL
20072 [X_GEN_TAC `n:num` THEN CONJ_TAC THENL
20073 [MATCH_MP_TAC OPEN_DIFF THEN
20074 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
20075 MATCH_MP_TAC CLOSED_UNIONS THEN
20076 REWRITE_TAC[FORALL_IN_GSPEC; CLOSED_CLOSURE] THEN
20077 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
20078 SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG_LT];
20079 EXISTS_TAC `f((a:num->real^N) n):real^N->bool` THEN ASM SET_TAC[]];
20080 REWRITE_TAC[SUBSET; UNIONS_GSPEC; IN_ELIM_THM; IN_DIFF] THEN
20081 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
20082 SUBGOAL_THEN `?n. x IN (f((a:num->real^N) n):real^N->bool)` MP_TAC THENL
20083 [RULE_ASSUM_TAC(REWRITE_RULE[UNIONS_IMAGE; EXISTS_IN_IMAGE]) THEN
20084 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
20085 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
20086 ASM_REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN
20087 DISCH_THEN(MP_TAC o snd o EQ_IMP_RULE) THEN
20088 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
20089 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:num` THEN
20091 FIRST_X_ASSUM(MP_TAC o SPEC `(a:num->real^N) n`) THEN
20092 ANTS_TAC THENL [ASM SET_TAC[]; ASM_MESON_TAC[CLOSURE_SUBSET; SUBSET]];
20093 GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN
20094 MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[]];
20095 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
20096 RULE_ASSUM_TAC(REWRITE_RULE[UNIONS_IMAGE; EXISTS_IN_IMAGE]) THEN
20097 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
20098 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
20099 ASM_REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN
20100 DISCH_THEN(MP_TAC o snd o EQ_IMP_RULE) THEN
20101 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
20102 DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN
20103 EXISTS_TAC `e((a:num->real^N) n):real^N->bool` THEN
20104 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
20105 REWRITE_TAC[SET_RULE
20106 `{u | (?n. u = f n) /\ P u} = IMAGE f {n |n| P(f n) /\ n IN (:num)}`] THEN
20107 MATCH_MP_TAC FINITE_IMAGE THEN MATCH_MP_TAC FINITE_SUBSET THEN
20108 EXISTS_TAC `{m:num | m <= n}` THEN REWRITE_TAC[FINITE_NUMSEG_LE] THEN
20109 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNIV] THEN
20110 X_GEN_TAC `m:num` THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
20111 REWRITE_TAC[NOT_LE] THEN DISCH_TAC THEN
20112 MATCH_MP_TAC(SET_RULE `u SUBSET t ==> (s DIFF t) INTER u = {}`) THEN
20113 REWRITE_TAC[SUBSET; IN_UNIONS; EXISTS_IN_GSPEC] THEN
20114 ASM_MESON_TAC[CLOSURE_SUBSET; SUBSET]]);;
20116 let PARACOMPACT_CLOSED_IN = prove
20117 (`!u:real^N->bool s c.
20118 closed_in (subtopology euclidean u) s /\
20119 (!t:real^N->bool. t IN c ==> open_in (subtopology euclidean u) t) /\
20121 ==> ?c'. s SUBSET UNIONS c' /\
20123 ==> open_in (subtopology euclidean u) v /\
20124 ?t. t IN c /\ v SUBSET t) /\
20126 ==> ?v. open_in (subtopology euclidean u) v /\ x IN v /\
20127 FINITE {n | n IN c' /\ ~(n INTER v = {})})`,
20128 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC
20129 (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC)) THEN
20130 REWRITE_TAC[OPEN_IN_OPEN] THEN
20131 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
20132 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
20133 X_GEN_TAC `uu:(real^N->bool)->(real^N->bool)` THEN
20134 DISCH_THEN(ASSUME_TAC o GSYM) THEN
20135 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CLOSED_IN_CLOSED]) THEN
20136 DISCH_THEN(X_CHOOSE_THEN `k:real^N->bool`
20137 (CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC)) THEN
20140 `((:real^N) DIFF k) INSERT IMAGE (uu:(real^N->bool)->(real^N->bool)) c`]
20142 ASM_SIMP_TAC[FORALL_IN_IMAGE; UNIONS_IMAGE; UNIONS_INSERT; FORALL_IN_INSERT;
20143 EXISTS_IN_IMAGE; EXISTS_IN_INSERT; GSYM closed] THEN
20144 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
20145 DISCH_THEN(X_CHOOSE_THEN `d:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
20146 EXISTS_TAC `{u INTER v:real^N->bool | v IN d /\ ~(v INTER k = {})}` THEN
20147 REPEAT CONJ_TAC THENL
20148 [REWRITE_TAC[UNIONS_GSPEC] THEN ASM SET_TAC[];
20149 REWRITE_TAC[FORALL_IN_GSPEC] THEN ASM SET_TAC[];
20150 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
20151 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
20152 DISCH_THEN(X_CHOOSE_THEN `v:real^N->bool` STRIP_ASSUME_TAC) THEN
20153 EXISTS_TAC `u INTER v:real^N->bool` THEN ASM_REWRITE_TAC[IN_INTER] THEN
20154 CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
20155 ONCE_REWRITE_TAC[SET_RULE
20156 `{y | y IN {f x | P x} /\ Q y} = IMAGE f {x | P x /\ Q(f x)}`] THEN
20157 MATCH_MP_TAC FINITE_IMAGE THEN
20158 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
20159 (REWRITE_RULE[IMP_CONJ] FINITE_SUBSET)) THEN SET_TAC[]]);;
20161 let PARACOMPACT_CLOSED = prove
20162 (`!s:real^N->bool c.
20163 closed s /\ (!t:real^N->bool. t IN c ==> open t) /\ s SUBSET UNIONS c
20164 ==> ?c'. s SUBSET UNIONS c' /\
20165 (!u. u IN c' ==> open u /\ ?t. t IN c /\ u SUBSET t) /\
20166 (!x. ?v. open v /\ x IN v /\
20167 FINITE {u | u IN c' /\ ~(u INTER v = {})})`,
20168 REPEAT STRIP_TAC THEN
20169 MP_TAC(ISPECL [`(:real^N)`; `s:real^N->bool`; `c:(real^N->bool)->bool`]
20170 PARACOMPACT_CLOSED_IN) THEN
20171 ASM_REWRITE_TAC[SUBTOPOLOGY_UNIV; GSYM OPEN_IN; GSYM CLOSED_IN; IN_UNIV]);;
20173 (* ------------------------------------------------------------------------- *)
20174 (* Partitions of unity subordinate to locally finite open coverings. *)
20175 (* ------------------------------------------------------------------------- *)
20177 let SUBORDINATE_PARTITION_OF_UNITY = prove
20178 (`!c s. s SUBSET UNIONS c /\ (!u. u IN c ==> open u) /\
20180 ==> ?v. open v /\ x IN v /\
20181 FINITE {u | u IN c /\ ~(u INTER v = {})})
20182 ==> ?f:(real^N->bool)->real^N->real.
20184 ==> (lift o f u) continuous_on s /\
20185 !x. x IN s ==> &0 <= f u x) /\
20186 (!x u. u IN c /\ x IN s /\ ~(x IN u) ==> f u x = &0) /\
20187 (!x. x IN s ==> sum c (\u. f u x) = &1) /\
20189 ==> ?n. open n /\ x IN n /\
20190 FINITE {u | u IN c /\
20191 ~(!x. x IN n ==> f u x = &0)})`,
20192 REPEAT STRIP_TAC THEN
20193 ASM_CASES_TAC `?u:real^N->bool. u IN c /\ s SUBSET u` THENL
20194 [FIRST_X_ASSUM(CHOOSE_THEN STRIP_ASSUME_TAC) THEN
20195 EXISTS_TAC `\v:real^N->bool x:real^N. if v = u then &1 else &0` THEN
20196 REWRITE_TAC[COND_RAND; COND_RATOR; o_DEF; REAL_POS;
20197 REAL_OF_NUM_EQ; ARITH_EQ;
20198 MESON[] `(if p then q else T) <=> p ==> q`] THEN
20199 ASM_SIMP_TAC[CONTINUOUS_ON_CONST; COND_ID; SUM_DELTA] THEN
20200 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
20201 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
20202 EXISTS_TAC `ball(x:real^N,&1)` THEN
20203 REWRITE_TAC[OPEN_BALL; CENTRE_IN_BALL; REAL_LT_01] THEN
20204 MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `{u:real^N->bool}` THEN
20205 REWRITE_TAC[FINITE_SING; SUBSET; IN_ELIM_THM; IN_SING] THEN
20206 X_GEN_TAC `v:real^N->bool` THEN
20207 ASM_CASES_TAC `v:real^N->bool = u` THEN ASM_REWRITE_TAC[];
20209 EXISTS_TAC `\u:real^N->bool x:real^N.
20211 then setdist({x},s DIFF u) / sum c (\v. setdist({x},s DIFF v))
20213 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
20214 SIMP_TAC[SUM_POS_LE; SETDIST_POS_LE; REAL_LE_DIV] THEN
20215 SIMP_TAC[SETDIST_SING_IN_SET; IN_DIFF; real_div; REAL_MUL_LZERO] THEN
20216 REWRITE_TAC[SUM_RMUL] THEN REWRITE_TAC[GSYM real_div] THEN
20217 MATCH_MP_TAC(TAUT `r /\ p /\ q ==> p /\ q /\ r`) THEN CONJ_TAC THENL
20218 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
20219 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
20220 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:real^N->bool` THEN
20221 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
20222 ASM_REWRITE_TAC[] THEN
20223 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] FINITE_SUBSET) THEN
20224 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `u:real^N->bool` THEN
20225 ASM_CASES_TAC `(u:real^N->bool) IN c` THEN
20226 ASM_REWRITE_TAC[CONTRAPOS_THM] THEN DISCH_TAC THEN
20227 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
20228 REWRITE_TAC[real_div; REAL_ENTIRE] THEN
20229 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
20230 ASM_CASES_TAC `(y:real^N) IN u` THEN
20231 ASM_SIMP_TAC[SETDIST_SING_IN_SET; IN_DIFF; REAL_MUL_LZERO] THEN
20235 `!v x:real^N. v IN c /\ x IN s /\ x IN v ==> &0 < setdist({x},s DIFF v)`
20237 [REPEAT STRIP_TAC THEN
20238 SIMP_TAC[SETDIST_POS_LE; REAL_ARITH `&0 < x <=> &0 <= x /\ ~(x = &0)`] THEN
20239 MP_TAC(ISPECL [`s:real^N->bool`; `s DIFF v:real^N->bool`; `x:real^N`]
20240 SETDIST_EQ_0_CLOSED_IN) THEN
20241 ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN
20242 ASM_SIMP_TAC[CLOSED_IN_CLOSED_INTER; GSYM OPEN_CLOSED] THEN
20243 DISCH_THEN SUBST1_TAC THEN ASM_REWRITE_TAC[] THEN
20244 ASM_REWRITE_TAC[IN_INTER; IN_DIFF; IN_UNION] THEN ASM SET_TAC[];
20247 `!x:real^N. x IN s ==> &0 < sum c (\v. setdist ({x},s DIFF v))`
20249 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
20250 ONCE_REWRITE_TAC[GSYM SUM_SUPPORT] THEN
20251 REWRITE_TAC[support; NEUTRAL_REAL_ADD] THEN
20252 MATCH_MP_TAC SUM_POS_LT THEN REWRITE_TAC[SETDIST_POS_LE] THEN
20254 [FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
20255 DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
20256 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
20257 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] FINITE_SUBSET) THEN
20258 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `u:real^N->bool` THEN
20259 ASM_CASES_TAC `(x:real^N) IN u` THEN
20260 ASM_SIMP_TAC[SETDIST_SING_IN_SET; IN_DIFF] THEN ASM SET_TAC[];
20261 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
20262 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN REWRITE_TAC[IN_UNIONS] THEN
20263 ASM_REWRITE_TAC[IN_ELIM_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
20264 ASM_MESON_TAC[REAL_LT_IMP_NZ]];
20266 ASM_SIMP_TAC[REAL_LT_IMP_NZ; REAL_DIV_REFL; o_DEF] THEN
20267 X_GEN_TAC `u:real^N->bool` THEN DISCH_TAC THEN
20268 MATCH_MP_TAC CONTINUOUS_ON_EQ THEN
20269 EXISTS_TAC `\x:real^N.
20270 lift(setdist({x},s DIFF u) / sum c (\v. setdist({x},s DIFF v)))` THEN
20271 SIMP_TAC[] THEN REWRITE_TAC[real_div; LIFT_CMUL] THEN
20272 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN
20273 SIMP_TAC[CONTINUOUS_ON_LIFT_SETDIST; o_DEF] THEN
20274 MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN
20275 ASM_SIMP_TAC[REAL_LT_IMP_NZ; CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
20276 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
20277 FIRST_X_ASSUM(fun th ->
20278 MP_TAC(SPEC `x:real^N` th) THEN ASM_REWRITE_TAC[] THEN
20279 DISCH_THEN(X_CHOOSE_THEN `n:real^N->bool` STRIP_ASSUME_TAC)) THEN
20280 MATCH_MP_TAC CONTINUOUS_TRANSFORM_WITHIN_OPEN_IN THEN
20281 MAP_EVERY EXISTS_TAC
20282 [`\x:real^N. lift(sum {v | v IN c /\ ~(v INTER n = {})}
20283 (\v. setdist({x},s DIFF v)))`;
20284 `s INTER n:real^N->bool`] THEN
20285 ASM_SIMP_TAC[IN_INTER; OPEN_IN_OPEN_INTER] THEN CONJ_TAC THENL
20286 [X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN AP_TERM_TAC THEN
20287 CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_EQ_SUPERSET THEN
20288 ASM_REWRITE_TAC[SUBSET_RESTRICT] THEN X_GEN_TAC `v:real^N->bool` THEN
20289 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
20290 ASM_REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN
20291 MATCH_MP_TAC SETDIST_SING_IN_SET THEN ASM SET_TAC[];
20292 ASM_SIMP_TAC[LIFT_SUM; o_DEF] THEN MATCH_MP_TAC CONTINUOUS_VSUM THEN
20293 ASM_SIMP_TAC[CONTINUOUS_AT_LIFT_SETDIST; CONTINUOUS_AT_WITHIN]]);;