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 BALL_TRANSLATION = prove
530 (`!a x r. ball(a + x,r) = IMAGE (\y. a + y) (ball(x,r))`,
531 REWRITE_TAC[ball] THEN GEOM_TRANSLATE_TAC[]);;
533 let CBALL_TRANSLATION = prove
534 (`!a x r. cball(a + x,r) = IMAGE (\y. a + y) (cball(x,r))`,
535 REWRITE_TAC[cball] THEN GEOM_TRANSLATE_TAC[]);;
537 let SPHERE_TRANSLATION = prove
538 (`!a x r. sphere(a + x,r) = IMAGE (\y. a + y) (sphere(x,r))`,
539 REWRITE_TAC[sphere] THEN GEOM_TRANSLATE_TAC[]);;
541 add_translation_invariants
542 [BALL_TRANSLATION; CBALL_TRANSLATION; SPHERE_TRANSLATION];;
544 let BALL_LINEAR_IMAGE = prove
545 (`!f:real^M->real^N x r.
546 linear f /\ (!y. ?x. f x = y) /\ (!x. norm(f x) = norm x)
547 ==> ball(f x,r) = IMAGE f (ball(x,r))`,
548 REWRITE_TAC[ball] THEN GEOM_TRANSFORM_TAC[]);;
550 let CBALL_LINEAR_IMAGE = prove
551 (`!f:real^M->real^N x r.
552 linear f /\ (!y. ?x. f x = y) /\ (!x. norm(f x) = norm x)
553 ==> cball(f x,r) = IMAGE f (cball(x,r))`,
554 REWRITE_TAC[cball] THEN GEOM_TRANSFORM_TAC[]);;
556 let SPHERE_LINEAR_IMAGE = prove
557 (`!f:real^M->real^N x r.
558 linear f /\ (!y. ?x. f x = y) /\ (!x. norm(f x) = norm x)
559 ==> sphere(f x,r) = IMAGE f (sphere(x,r))`,
560 REWRITE_TAC[sphere] THEN GEOM_TRANSFORM_TAC[]);;
562 add_linear_invariants
563 [BALL_LINEAR_IMAGE; CBALL_LINEAR_IMAGE; SPHERE_LINEAR_IMAGE];;
565 let BALL_SCALING = prove
566 (`!c. &0 < c ==> !x r. ball(c % x,c * r) = IMAGE (\x. c % x) (ball(x,r))`,
567 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
568 MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN REWRITE_TAC[] THEN CONJ_TAC THENL
569 [ASM_MESON_TAC[SURJECTIVE_SCALING; REAL_LT_IMP_NZ]; ALL_TAC] THEN
570 REWRITE_TAC[IN_BALL; DIST_MUL] THEN
571 ASM_SIMP_TAC[REAL_ARITH `&0 < c ==> abs c = c`; REAL_LT_LMUL_EQ]);;
573 let CBALL_SCALING = prove
574 (`!c. &0 < c ==> !x r. cball(c % x,c * r) = IMAGE (\x. c % x) (cball(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_CBALL; DIST_MUL] THEN
579 ASM_SIMP_TAC[REAL_ARITH `&0 < c ==> abs c = c`; REAL_LE_LMUL_EQ]);;
581 add_scaling_theorems [BALL_SCALING; CBALL_SCALING];;
583 let CBALL_DIFF_BALL = prove
584 (`!a r. cball(a,r) DIFF ball(a,r) = sphere(a,r)`,
585 REWRITE_TAC[ball; cball; sphere; EXTENSION; IN_DIFF; IN_ELIM_THM] THEN
588 let BALL_UNION_SPHERE = prove
589 (`!a r. ball(a,r) UNION sphere(a,r) = cball(a,r)`,
590 REWRITE_TAC[ball; cball; sphere; EXTENSION; IN_UNION; IN_ELIM_THM] THEN
593 let SPHERE_UNION_BALL = prove
594 (`!a r. sphere(a,r) UNION ball(a,r) = cball(a,r)`,
595 REWRITE_TAC[ball; cball; sphere; EXTENSION; IN_UNION; IN_ELIM_THM] THEN
598 let CBALL_DIFF_SPHERE = prove
599 (`!a r. cball(a,r) DIFF sphere(a,r) = ball(a,r)`,
600 REWRITE_TAC[EXTENSION; IN_DIFF; IN_SPHERE; IN_BALL; IN_CBALL] THEN
603 let OPEN_BALL = prove
604 (`!x e. open(ball(x,e))`,
605 REWRITE_TAC[open_def; ball; IN_ELIM_THM] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
606 MESON_TAC[REAL_SUB_LT; REAL_LT_SUB_LADD; REAL_ADD_SYM; REAL_LET_TRANS;
607 DIST_TRIANGLE_ALT]);;
609 let CENTRE_IN_BALL = prove
610 (`!x e. x IN ball(x,e) <=> &0 < e`,
611 MESON_TAC[IN_BALL; DIST_REFL]);;
613 let OPEN_CONTAINS_BALL = prove
614 (`!s. open s <=> !x. x IN s ==> ?e. &0 < e /\ ball(x,e) SUBSET s`,
615 REWRITE_TAC[open_def; SUBSET; IN_BALL] THEN REWRITE_TAC[DIST_SYM]);;
617 let OPEN_CONTAINS_BALL_EQ = prove
618 (`!s. open s ==> (!x. x IN s <=> ?e. &0 < e /\ ball(x,e) SUBSET s)`,
619 MESON_TAC[OPEN_CONTAINS_BALL; SUBSET; CENTRE_IN_BALL]);;
621 let BALL_EQ_EMPTY = prove
622 (`!x e. (ball(x,e) = {}) <=> e <= &0`,
623 REWRITE_TAC[EXTENSION; IN_BALL; NOT_IN_EMPTY; REAL_NOT_LT] THEN
624 MESON_TAC[DIST_POS_LE; REAL_LE_TRANS; DIST_REFL]);;
626 let BALL_EMPTY = prove
627 (`!x e. e <= &0 ==> ball(x,e) = {}`,
628 REWRITE_TAC[BALL_EQ_EMPTY]);;
630 let OPEN_CONTAINS_CBALL = prove
631 (`!s. open s <=> !x. x IN s ==> ?e. &0 < e /\ cball(x,e) SUBSET s`,
632 GEN_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN EQ_TAC THENL
633 [ALL_TAC; ASM_MESON_TAC[SUBSET_TRANS; BALL_SUBSET_CBALL]] THEN
634 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
635 REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL] THEN
636 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
637 EXISTS_TAC `e / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN
638 SUBGOAL_THEN `e / &2 < e` (fun th -> ASM_MESON_TAC[th; REAL_LET_TRANS]) THEN
639 ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
640 UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC);;
642 let OPEN_CONTAINS_CBALL_EQ = prove
643 (`!s. open s ==> (!x. x IN s <=> ?e. &0 < e /\ cball(x,e) SUBSET s)`,
644 MESON_TAC[OPEN_CONTAINS_CBALL; SUBSET; REAL_LT_IMP_LE; CENTRE_IN_CBALL]);;
646 let SPHERE_EQ_EMPTY = prove
647 (`!a:real^N r. sphere(a,r) = {} <=> r < &0`,
648 REWRITE_TAC[sphere; EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN
649 REPEAT GEN_TAC THEN EQ_TAC THENL [ALL_TAC; CONV_TAC NORM_ARITH] THEN
650 MESON_TAC[VECTOR_CHOOSE_DIST; REAL_NOT_LE]);;
652 let SPHERE_EMPTY = prove
653 (`!a:real^N r. r < &0 ==> sphere(a,r) = {}`,
654 REWRITE_TAC[SPHERE_EQ_EMPTY]);;
656 let NEGATIONS_BALL = prove
657 (`!r. IMAGE (--) (ball(vec 0:real^N,r)) = ball(vec 0,r)`,
658 GEN_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
659 REWRITE_TAC[IN_BALL_0; NORM_NEG] THEN MESON_TAC[VECTOR_NEG_NEG]);;
661 let NEGATIONS_CBALL = prove
662 (`!r. IMAGE (--) (cball(vec 0:real^N,r)) = cball(vec 0,r)`,
663 GEN_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
664 REWRITE_TAC[IN_CBALL_0; NORM_NEG] THEN MESON_TAC[VECTOR_NEG_NEG]);;
666 let NEGATIONS_SPHERE = prove
667 (`!r. IMAGE (--) (sphere(vec 0:real^N,r)) = sphere(vec 0,r)`,
668 GEN_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
669 REWRITE_TAC[IN_SPHERE_0; NORM_NEG] THEN MESON_TAC[VECTOR_NEG_NEG]);;
671 (* ------------------------------------------------------------------------- *)
672 (* Basic "localization" results are handy for connectedness. *)
673 (* ------------------------------------------------------------------------- *)
675 let OPEN_IN_OPEN = prove
677 open_in (subtopology euclidean u) s <=> ?t. open t /\ (s = u INTER t)`,
678 REPEAT STRIP_TAC THEN REWRITE_TAC[OPEN_IN_SUBTOPOLOGY; GSYM OPEN_IN] THEN
679 REWRITE_TAC[INTER_ACI]);;
681 let OPEN_IN_INTER_OPEN = prove
682 (`!s t u:real^N->bool.
683 open_in (subtopology euclidean u) s /\ open t
684 ==> open_in (subtopology euclidean u) (s INTER t)`,
685 REWRITE_TAC[OPEN_IN_OPEN] THEN REPEAT STRIP_TAC THEN
686 ASM_REWRITE_TAC[INTER_ASSOC] THEN ASM_MESON_TAC[OPEN_INTER]);;
688 let OPEN_IN_OPEN_INTER = prove
689 (`!u s. open s ==> open_in (subtopology euclidean u) (u INTER s)`,
690 REWRITE_TAC[OPEN_IN_OPEN] THEN MESON_TAC[]);;
692 let OPEN_OPEN_IN_TRANS = prove
693 (`!s t. open s /\ open t /\ t SUBSET s
694 ==> open_in (subtopology euclidean s) t`,
695 MESON_TAC[OPEN_IN_OPEN_INTER; SET_RULE `t SUBSET s ==> t = s INTER t`]);;
697 let OPEN_SUBSET = prove
699 s SUBSET t /\ open s ==> open_in (subtopology euclidean t) s`,
700 REPEAT STRIP_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN
701 EXISTS_TAC `s:real^N->bool` THEN ASM SET_TAC[]);;
703 let CLOSED_IN_CLOSED = prove
705 closed_in (subtopology euclidean u) s <=> ?t. closed t /\ (s = u INTER t)`,
706 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_IN_SUBTOPOLOGY; GSYM CLOSED_IN] THEN
707 REWRITE_TAC[INTER_ACI]);;
709 let CLOSED_SUBSET_EQ = prove
711 closed s ==> (closed_in (subtopology euclidean u) s <=> s SUBSET u)`,
712 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
713 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN
714 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY];
715 REWRITE_TAC[CLOSED_IN_CLOSED] THEN EXISTS_TAC `s:real^N->bool` THEN
718 let CLOSED_IN_INTER_CLOSED = prove
719 (`!s t u:real^N->bool.
720 closed_in (subtopology euclidean u) s /\ closed t
721 ==> closed_in (subtopology euclidean u) (s INTER t)`,
722 REWRITE_TAC[CLOSED_IN_CLOSED] THEN REPEAT STRIP_TAC THEN
723 ASM_REWRITE_TAC[INTER_ASSOC] THEN ASM_MESON_TAC[CLOSED_INTER]);;
725 let CLOSED_IN_CLOSED_INTER = prove
726 (`!u s. closed s ==> closed_in (subtopology euclidean u) (u INTER s)`,
727 REWRITE_TAC[CLOSED_IN_CLOSED] THEN MESON_TAC[]);;
729 let CLOSED_CLOSED_IN_TRANS = prove
730 (`!s t. closed s /\ closed t /\ t SUBSET s
731 ==> closed_in (subtopology euclidean s) t`,
732 MESON_TAC[CLOSED_IN_CLOSED_INTER; SET_RULE `t SUBSET s ==> t = s INTER t`]);;
734 let CLOSED_SUBSET = prove
736 s SUBSET t /\ closed s ==> closed_in (subtopology euclidean t) s`,
737 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN
738 EXISTS_TAC `s:real^N->bool` THEN ASM SET_TAC[]);;
740 let OPEN_IN_SUBSET_TRANS = prove
741 (`!s t u:real^N->bool.
742 open_in (subtopology euclidean u) s /\ s SUBSET t /\ t SUBSET u
743 ==> open_in (subtopology euclidean t) s`,
744 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN; LEFT_AND_EXISTS_THM] THEN
745 MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]);;
747 let CLOSED_IN_SUBSET_TRANS = prove
748 (`!s t u:real^N->bool.
749 closed_in (subtopology euclidean u) s /\ s SUBSET t /\ t SUBSET u
750 ==> closed_in (subtopology euclidean t) s`,
751 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED; LEFT_AND_EXISTS_THM] THEN
752 MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]);;
756 open_in (subtopology euclidean u) s <=>
758 !x. x IN s ==> ?e. &0 < e /\
759 !x'. x' IN u /\ dist(x',x) < e ==> x' IN s`,
761 REWRITE_TAC[OPEN_IN_SUBTOPOLOGY; GSYM OPEN_IN] THEN EQ_TAC THENL
762 [REWRITE_TAC[open_def] THEN ASM SET_TAC[INTER_SUBSET; IN_INTER];
764 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
765 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
766 REWRITE_TAC[SKOLEM_THM] THEN DISCH_THEN(X_CHOOSE_TAC `d:real^N->real`) THEN
767 EXISTS_TAC `UNIONS {b | ?x:real^N. (b = ball(x,d x)) /\ x IN s}` THEN
769 [MATCH_MP_TAC OPEN_UNIONS THEN
770 ASM_SIMP_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM; OPEN_BALL];
771 GEN_REWRITE_TAC I [EXTENSION] THEN
772 REWRITE_TAC[IN_INTER; IN_UNIONS; IN_ELIM_THM] THEN
773 ASM_MESON_TAC[SUBSET; DIST_REFL; DIST_SYM; IN_BALL]]);;
775 let OPEN_IN_CONTAINS_BALL = prove
777 open_in (subtopology euclidean t) s <=>
779 !x. x IN s ==> ?e. &0 < e /\ ball(x,e) INTER t SUBSET s`,
780 REWRITE_TAC[open_in; INTER; SUBSET; IN_ELIM_THM; IN_BALL] THEN
781 MESON_TAC[DIST_SYM]);;
783 let OPEN_IN_CONTAINS_CBALL = prove
785 open_in (subtopology euclidean t) s <=>
787 !x. x IN s ==> ?e. &0 < e /\ cball(x,e) INTER t SUBSET s`,
788 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_CONTAINS_BALL] THEN
789 AP_TERM_TAC THEN REWRITE_TAC[IN_BALL; IN_INTER; SUBSET; IN_CBALL] THEN
790 MESON_TAC[REAL_ARITH `&0 < e ==> &0 < e / &2 /\ (x <= e / &2 ==> x < e)`;
793 (* ------------------------------------------------------------------------- *)
794 (* These "transitivity" results are handy too. *)
795 (* ------------------------------------------------------------------------- *)
797 let OPEN_IN_TRANS = prove
798 (`!s t u. open_in (subtopology euclidean t) s /\
799 open_in (subtopology euclidean u) t
800 ==> open_in (subtopology euclidean u) s`,
801 ASM_MESON_TAC[OPEN_IN_OPEN; OPEN_IN; OPEN_INTER; INTER_ASSOC]);;
803 let OPEN_IN_OPEN_TRANS = prove
804 (`!s t. open_in (subtopology euclidean t) s /\ open t ==> open s`,
805 REWRITE_TAC[ONCE_REWRITE_RULE[GSYM SUBTOPOLOGY_UNIV] OPEN_IN] THEN
806 REWRITE_TAC[OPEN_IN_TRANS]);;
808 let CLOSED_IN_TRANS = prove
809 (`!s t u. closed_in (subtopology euclidean t) s /\
810 closed_in (subtopology euclidean u) t
811 ==> closed_in (subtopology euclidean u) s`,
812 ASM_MESON_TAC[CLOSED_IN_CLOSED; CLOSED_IN; CLOSED_INTER; INTER_ASSOC]);;
814 let CLOSED_IN_CLOSED_TRANS = prove
815 (`!s t. closed_in (subtopology euclidean t) s /\ closed t ==> closed s`,
816 REWRITE_TAC[ONCE_REWRITE_RULE[GSYM SUBTOPOLOGY_UNIV] CLOSED_IN] THEN
817 REWRITE_TAC[CLOSED_IN_TRANS]);;
819 let OPEN_IN_SUBTOPOLOGY_INTER_SUBSET = prove
820 (`!s u v. open_in (subtopology euclidean u) (u INTER s) /\ v SUBSET u
821 ==> open_in (subtopology euclidean v) (v INTER s)`,
822 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN; LEFT_AND_EXISTS_THM] THEN
823 MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]);;
825 let OPEN_IN_OPEN_EQ = prove
827 ==> (open_in (subtopology euclidean s) t <=> open t /\ t SUBSET s)`,
828 MESON_TAC[OPEN_OPEN_IN_TRANS; OPEN_IN_OPEN_TRANS; open_in]);;
830 let CLOSED_IN_CLOSED_EQ = prove
832 ==> (closed_in (subtopology euclidean s) t <=>
833 closed t /\ t SUBSET s)`,
834 MESON_TAC[CLOSED_CLOSED_IN_TRANS; CLOSED_IN_CLOSED_TRANS; closed_in;
835 TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]);;
837 (* ------------------------------------------------------------------------- *)
838 (* Also some invariance theorems for relative topology. *)
839 (* ------------------------------------------------------------------------- *)
841 let OPEN_IN_TRANSLATION_EQ = prove
842 (`!a s t. open_in (subtopology euclidean (IMAGE (\x. a + x) t))
843 (IMAGE (\x. a + x) s) <=>
844 open_in (subtopology euclidean t) s`,
845 REWRITE_TAC[open_in] THEN GEOM_TRANSLATE_TAC[]);;
847 add_translation_invariants [OPEN_IN_TRANSLATION_EQ];;
849 let CLOSED_IN_TRANSLATION_EQ = prove
850 (`!a s t. closed_in (subtopology euclidean (IMAGE (\x. a + x) t))
851 (IMAGE (\x. a + x) s) <=>
852 closed_in (subtopology euclidean t) s`,
853 REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
854 GEOM_TRANSLATE_TAC[]);;
856 add_translation_invariants [CLOSED_IN_TRANSLATION_EQ];;
858 let OPEN_IN_INJECTIVE_LINEAR_IMAGE = prove
859 (`!f:real^M->real^N s t.
860 linear f /\ (!x y. f x = f y ==> x = y)
861 ==> (open_in (subtopology euclidean (IMAGE f t)) (IMAGE f s) <=>
862 open_in (subtopology euclidean t) s)`,
863 REWRITE_TAC[open_in; FORALL_IN_IMAGE; IMP_CONJ; SUBSET] THEN
864 REPEAT STRIP_TAC THEN
865 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (SET_RULE
866 `(!x y. f x = f y ==> x = y) ==> (!x s. f x IN IMAGE f s <=> x IN s)`)) THEN
867 ASM_REWRITE_TAC[] THEN
868 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_BOUNDED_POS) THEN
869 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_BOUNDED_BELOW_POS) THEN
870 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
871 X_GEN_TAC `B2:real` THEN STRIP_TAC THEN
872 X_GEN_TAC `B1:real` THEN STRIP_TAC THEN
873 AP_TERM_TAC THEN AP_TERM_TAC THEN
874 GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `x:real^M` THEN
875 REWRITE_TAC[] THEN AP_TERM_TAC THEN
876 FIRST_ASSUM(ASSUME_TAC o GSYM o MATCH_MP LINEAR_SUB) THEN
877 ASM_REWRITE_TAC[dist; IMP_IMP] THEN EQ_TAC THEN
878 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THENL
879 [EXISTS_TAC `e / B1:real`; EXISTS_TAC `e * B2:real`] THEN
880 ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV] THEN
881 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THENL
882 [MATCH_MP_TAC(REAL_ARITH
883 `norm(f x) <= B1 * norm(x) /\ norm(x) * B1 < e ==> norm(f x) < e`) THEN
884 ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ];
885 MATCH_MP_TAC(REAL_ARITH
886 `norm x <= norm (f x :real^N) / B2 /\ norm(f x) / B2 < e
887 ==> norm x < e`) THEN
888 ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LT_LDIV_EQ]]);;
890 add_linear_invariants [OPEN_IN_INJECTIVE_LINEAR_IMAGE];;
892 let CLOSED_IN_INJECTIVE_LINEAR_IMAGE = prove
893 (`!f:real^M->real^N s t.
894 linear f /\ (!x y. f x = f y ==> x = y)
895 ==> (closed_in (subtopology euclidean (IMAGE f t)) (IMAGE f s) <=>
896 closed_in (subtopology euclidean t) s)`,
897 REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
898 GEOM_TRANSFORM_TAC[]);;
900 add_linear_invariants [CLOSED_IN_INJECTIVE_LINEAR_IMAGE];;
902 (* ------------------------------------------------------------------------- *)
904 (* ------------------------------------------------------------------------- *)
906 let connected = new_definition
908 ~(?e1 e2. open e1 /\ open e2 /\ s SUBSET (e1 UNION e2) /\
909 (e1 INTER e2 INTER s = {}) /\
910 ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))`;;
912 let CONNECTED_CLOSED = prove
915 ~(?e1 e2. closed e1 /\ closed e2 /\ s SUBSET (e1 UNION e2) /\
916 (e1 INTER e2 INTER s = {}) /\
917 ~(e1 INTER s = {}) /\ ~(e2 INTER s = {}))`,
918 GEN_TAC THEN REWRITE_TAC[connected] THEN AP_TERM_TAC THEN
919 EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
920 MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN STRIP_TAC THEN
921 MAP_EVERY EXISTS_TAC [`(:real^N) DIFF v`; `(:real^N) DIFF u`] THEN
922 ASM_REWRITE_TAC[GSYM closed; GSYM OPEN_CLOSED] THEN ASM SET_TAC[]);;
924 let CONNECTED_OPEN_IN = prove
925 (`!s. connected s <=>
927 open_in (subtopology euclidean s) e1 /\
928 open_in (subtopology euclidean s) e2 /\
929 s SUBSET e1 UNION e2 /\
933 GEN_TAC THEN REWRITE_TAC[connected; OPEN_IN_OPEN] THEN
934 REWRITE_TAC[LEFT_AND_EXISTS_THM; RIGHT_AND_EXISTS_THM] THEN
935 CONV_TAC(ONCE_DEPTH_CONV UNWIND_CONV) THEN
936 AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
939 let CONNECTED_OPEN_IN_EQ = prove
940 (`!s. connected s <=>
942 open_in (subtopology euclidean s) e1 /\
943 open_in (subtopology euclidean s) e2 /\
944 e1 UNION e2 = s /\ e1 INTER e2 = {} /\
945 ~(e1 = {}) /\ ~(e2 = {}))`,
946 GEN_TAC THEN REWRITE_TAC[CONNECTED_OPEN_IN] THEN
947 AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
948 EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN
949 RULE_ASSUM_TAC(REWRITE_RULE[OPEN_IN_CLOSED_IN_EQ;
950 TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]) THEN
953 let CONNECTED_CLOSED_IN = prove
954 (`!s. connected s <=>
956 closed_in (subtopology euclidean s) e1 /\
957 closed_in (subtopology euclidean s) e2 /\
958 s SUBSET e1 UNION e2 /\
962 GEN_TAC THEN REWRITE_TAC[CONNECTED_CLOSED; CLOSED_IN_CLOSED] THEN
963 REWRITE_TAC[LEFT_AND_EXISTS_THM; RIGHT_AND_EXISTS_THM] THEN
964 CONV_TAC(ONCE_DEPTH_CONV UNWIND_CONV) THEN
965 AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
968 let CONNECTED_CLOSED_IN_EQ = prove
969 (`!s. connected s <=>
971 closed_in (subtopology euclidean s) e1 /\
972 closed_in (subtopology euclidean s) e2 /\
974 e1 UNION e2 = s /\ e1 INTER e2 = {} /\
975 ~(e1 = {}) /\ ~(e2 = {}))`,
976 GEN_TAC THEN REWRITE_TAC[CONNECTED_CLOSED_IN] THEN
977 AP_TERM_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
978 EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[SUBSET_REFL] THEN
979 RULE_ASSUM_TAC(REWRITE_RULE[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY]) THEN
982 let CONNECTED_CLOPEN = prove
983 (`!s. connected s <=>
984 !t. open_in (subtopology euclidean s) t /\
985 closed_in (subtopology euclidean s) t ==> t = {} \/ t = s`,
986 GEN_TAC THEN REWRITE_TAC[connected; OPEN_IN_OPEN; CLOSED_IN_CLOSED] THEN
987 GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o BINDER_CONV) [GSYM EXISTS_DIFF] THEN
988 ONCE_REWRITE_TAC[TAUT `(~a <=> b) <=> (a <=> ~b)`] THEN
989 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; GSYM CONJ_ASSOC; DE_MORGAN_THM] THEN
990 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> b /\ a /\ c /\ d`] THEN
991 REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN REWRITE_TAC[GSYM closed] THEN
992 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN AP_TERM_TAC THEN ABS_TAC THEN
993 REWRITE_TAC[LEFT_AND_EXISTS_THM; RIGHT_AND_EXISTS_THM] THEN
994 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN AP_TERM_TAC THEN ABS_TAC THEN
995 REWRITE_TAC[TAUT `(a /\ b) /\ (c /\ d) /\ e <=> a /\ c /\ b /\ d /\ e`] THEN
996 REWRITE_TAC[RIGHT_EXISTS_AND_THM; UNWIND_THM2] THEN
997 AP_TERM_TAC THEN AP_TERM_TAC THEN SET_TAC[]);;
999 let CONNECTED_CLOSED_SET = prove
1002 ==> (connected s <=>
1003 ~(?e1 e2. closed e1 /\ closed e2 /\ ~(e1 = {}) /\ ~(e2 = {}) /\
1004 e1 UNION e2 = s /\ e1 INTER e2 = {}))`,
1005 REPEAT STRIP_TAC THEN EQ_TAC THENL
1006 [REWRITE_TAC[CONNECTED_CLOSED; CONTRAPOS_THM] THEN
1007 REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
1008 SIMP_TAC[] THEN SET_TAC[];
1009 REWRITE_TAC[CONNECTED_CLOSED_IN; CONTRAPOS_THM; LEFT_IMP_EXISTS_THM] THEN
1010 REWRITE_TAC[CLOSED_IN_CLOSED; LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN
1011 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN REWRITE_TAC[IMP_IMP] THEN
1013 [`e1:real^N->bool`; `e2:real^N->bool`;
1014 `u:real^N->bool`; `v:real^N->bool`] THEN
1015 STRIP_TAC THEN MAP_EVERY (C UNDISCH_THEN SUBST_ALL_TAC)
1016 [`e1:real^N->bool = s INTER u`;
1017 `e2:real^N->bool = s INTER v`] THEN
1018 MAP_EVERY EXISTS_TAC
1019 [`s INTER u:real^N->bool`; `s INTER v:real^N->bool`] THEN
1020 ASM_SIMP_TAC[CLOSED_INTER] THEN ASM SET_TAC[]]);;
1022 let CONNECTED_OPEN_SET = prove
1025 ==> (connected s <=>
1026 ~(?e1 e2. open e1 /\ open e2 /\ ~(e1 = {}) /\ ~(e2 = {}) /\
1027 e1 UNION e2 = s /\ e1 INTER e2 = {}))`,
1028 REPEAT STRIP_TAC THEN EQ_TAC THENL
1029 [REWRITE_TAC[connected; CONTRAPOS_THM] THEN
1030 REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
1031 SIMP_TAC[] THEN SET_TAC[];
1032 REWRITE_TAC[CONNECTED_OPEN_IN; CONTRAPOS_THM; LEFT_IMP_EXISTS_THM] THEN
1033 REWRITE_TAC[OPEN_IN_OPEN; LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN
1034 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN REWRITE_TAC[IMP_IMP] THEN
1036 [`e1:real^N->bool`; `e2:real^N->bool`;
1037 `u:real^N->bool`; `v:real^N->bool`] THEN
1038 STRIP_TAC THEN MAP_EVERY (C UNDISCH_THEN SUBST_ALL_TAC)
1039 [`e1:real^N->bool = s INTER u`;
1040 `e2:real^N->bool = s INTER v`] THEN
1041 MAP_EVERY EXISTS_TAC
1042 [`s INTER u:real^N->bool`; `s INTER v:real^N->bool`] THEN
1043 ASM_SIMP_TAC[OPEN_INTER] THEN ASM SET_TAC[]]);;
1045 let CONNECTED_EMPTY = prove
1047 REWRITE_TAC[connected; INTER_EMPTY]);;
1049 let CONNECTED_SING = prove
1050 (`!a. connected{a}`,
1051 REWRITE_TAC[connected] THEN SET_TAC[]);;
1053 let CONNECTED_UNIONS = prove
1054 (`!P:(real^N->bool)->bool.
1055 (!s. s IN P ==> connected s) /\ ~(INTERS P = {})
1056 ==> connected(UNIONS P)`,
1057 GEN_TAC THEN REWRITE_TAC[connected; NOT_EXISTS_THM] THEN STRIP_TAC THEN
1058 MAP_EVERY X_GEN_TAC [`e1:real^N->bool`; `e2:real^N->bool`] THEN
1059 STRIP_TAC THEN UNDISCH_TAC `~(INTERS P :real^N->bool = {})` THEN
1060 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTERS] THEN
1061 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
1062 SUBGOAL_THEN `(a:real^N) IN e1 \/ a IN e2` STRIP_ASSUME_TAC THENL
1064 UNDISCH_TAC `~(e2 INTER UNIONS P:real^N->bool = {})`;
1065 UNDISCH_TAC `~(e1 INTER UNIONS P:real^N->bool = {})`] THEN
1066 PURE_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER; IN_UNIONS] THEN
1067 DISCH_THEN(X_CHOOSE_THEN `b:real^N`
1068 (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
1069 DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN
1070 UNDISCH_TAC `!t:real^N->bool. t IN P ==> a IN t` THEN
1071 DISCH_THEN(MP_TAC o SPEC `s:real^N->bool`) THEN
1072 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
1073 FIRST_X_ASSUM(MP_TAC o SPEC `s:real^N->bool`) THEN
1074 ASM_REWRITE_TAC[] THEN
1075 DISCH_THEN(MP_TAC o SPECL [`e1:real^N->bool`; `e2:real^N->bool`]) THEN
1078 let CONNECTED_UNION = prove
1079 (`!s t:real^N->bool.
1080 connected s /\ connected t /\ ~(s INTER t = {})
1081 ==> connected (s UNION t)`,
1082 REWRITE_TAC[GSYM UNIONS_2; GSYM INTERS_2] THEN
1083 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_UNIONS THEN
1086 let CONNECTED_DIFF_OPEN_FROM_CLOSED = prove
1087 (`!s t u:real^N->bool.
1088 s SUBSET t /\ t SUBSET u /\
1089 open s /\ closed t /\ connected u /\ connected(t DIFF s)
1090 ==> connected(u DIFF s)`,
1091 REPEAT STRIP_TAC THEN REWRITE_TAC[connected; NOT_EXISTS_THM] THEN
1092 MAP_EVERY X_GEN_TAC [`v:real^N->bool`; `w:real^N->bool`] THEN STRIP_TAC THEN
1093 UNDISCH_TAC `connected(t DIFF s:real^N->bool)` THEN SIMP_TAC[connected] THEN
1094 MAP_EVERY EXISTS_TAC [`v:real^N->bool`; `w:real^N->bool`] THEN
1095 ASM_REWRITE_TAC[] THEN
1096 REPLICATE_TAC 2 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
1097 POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
1098 MAP_EVERY (fun t -> SPEC_TAC(t,t)) [`v:real^N->bool`; `w:real^N->bool`] THEN
1099 MATCH_MP_TAC(MESON[]
1100 `(!v w. P v w ==> P w v) /\ (!w v. P v w /\ Q w ==> F)
1101 ==> !w v. P v w ==> ~(Q v) /\ ~(Q w)`) THEN
1102 CONJ_TAC THENL [SIMP_TAC[CONJ_ACI; INTER_ACI; UNION_ACI]; ALL_TAC] THEN
1103 REPEAT STRIP_TAC THEN
1104 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [connected]) THEN SIMP_TAC[] THEN
1105 MAP_EVERY EXISTS_TAC [`v UNION s:real^N->bool`; `w DIFF t:real^N->bool`] THEN
1106 ASM_SIMP_TAC[OPEN_UNION; OPEN_DIFF] THEN ASM SET_TAC[]);;
1108 let CONNECTED_DISJOINT_UNIONS_OPEN_UNIQUE = prove
1109 (`!f:(real^N->bool)->bool f'.
1110 pairwise DISJOINT f /\ pairwise DISJOINT f' /\
1111 (!s. s IN f ==> open s /\ connected s /\ ~(s = {})) /\
1112 (!s. s IN f' ==> open s /\ connected s /\ ~(s = {})) /\
1113 UNIONS f = UNIONS f'
1115 GEN_REWRITE_TAC (funpow 2 BINDER_CONV o RAND_CONV) [EXTENSION] THEN
1116 MATCH_MP_TAC(MESON[]
1117 `(!s t. P s t ==> P t s) /\ (!s t x. P s t /\ x IN s ==> x IN t)
1118 ==> (!s t. P s t ==> (!x. x IN s <=> x IN t))`) THEN
1119 CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
1120 GEN_TAC THEN GEN_TAC THEN X_GEN_TAC `s:real^N->bool` THEN STRIP_TAC THEN
1122 `?t a:real^N. t IN f' /\ a IN s /\ a IN t` STRIP_ASSUME_TAC
1123 THENL [ASM SET_TAC[]; ALL_TAC] THEN
1124 SUBGOAL_THEN `s:real^N->bool = t` (fun th -> ASM_REWRITE_TAC[th]) THEN
1125 REWRITE_TAC[EXTENSION] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
1126 MAP_EVERY (fun t -> SPEC_TAC(t,t))
1127 [`s:real^N->bool`; `t:real^N->bool`;
1128 `f:(real^N->bool)->bool`; `f':(real^N->bool)->bool`] THEN
1129 MATCH_MP_TAC(MESON[]
1130 `(!f f' s t. P f f' s t ==> P f' f t s) /\
1131 (!f f' s t x. P f f' s t /\ x IN s ==> x IN t)
1132 ==> (!f' f t s. P f f' s t ==> (!x. x IN s <=> x IN t))`) THEN
1133 CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
1134 REPLICATE_TAC 4 GEN_TAC THEN X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN
1136 `!s:real^N->bool. s IN f ==> open s /\ connected s /\ ~(s = {})` THEN
1137 DISCH_THEN(MP_TAC o SPEC `s:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
1138 STRIP_TAC THEN ASM_CASES_TAC `(b:real^N) IN t` THEN
1139 ASM_REWRITE_TAC[] THEN
1140 UNDISCH_TAC `connected(s:real^N->bool)` THEN
1141 REWRITE_TAC[connected] THEN
1142 MAP_EVERY EXISTS_TAC
1143 [`t:real^N->bool`; `UNIONS(f' DELETE (t:real^N->bool))`] THEN
1144 REPEAT STRIP_TAC THENL
1146 MATCH_MP_TAC OPEN_UNIONS THEN ASM_SIMP_TAC[IN_DELETE];
1147 REWRITE_TAC[GSYM UNIONS_INSERT] THEN ASM SET_TAC[];
1148 MATCH_MP_TAC(SET_RULE `t INTER u = {} ==> t INTER u INTER s = {}`) THEN
1149 REWRITE_TAC[INTER_UNIONS; EMPTY_UNIONS; FORALL_IN_GSPEC] THEN
1150 REWRITE_TAC[IN_DELETE; GSYM DISJOINT] THEN ASM_MESON_TAC[pairwise];
1154 (* ------------------------------------------------------------------------- *)
1155 (* Sort of induction principle for connected sets. *)
1156 (* ------------------------------------------------------------------------- *)
1158 let CONNECTED_INDUCTION = prove
1159 (`!P Q s:real^N->bool.
1161 (!t a. open_in (subtopology euclidean s) t /\ a IN t
1162 ==> ?z. z IN t /\ P z) /\
1164 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
1165 !x y. x IN t /\ y IN t /\ P x /\ P y /\ Q x ==> Q y)
1166 ==> !a b. a IN s /\ b IN s /\ P a /\ P b /\ Q a ==> Q b`,
1167 REPEAT STRIP_TAC THEN
1168 GEN_REWRITE_TAC I [TAUT `p <=> ~ ~p`] THEN DISCH_TAC THEN
1169 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONNECTED_OPEN_IN]) THEN
1170 REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC
1171 [`{b:real^N | ?t. open_in (subtopology euclidean s) t /\ b IN t /\
1172 !x. x IN t /\ P x ==> Q x}`;
1173 `{b:real^N | ?t. open_in (subtopology euclidean s) t /\ b IN t /\
1174 !x. x IN t /\ P x ==> ~(Q x)}`] THEN
1175 REPEAT CONJ_TAC THENL
1176 [ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN
1177 X_GEN_TAC `c:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN
1178 MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[];
1179 ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN
1180 X_GEN_TAC `c:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN
1181 MATCH_MP_TAC MONO_EXISTS THEN ASM SET_TAC[];
1182 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNION] THEN
1183 X_GEN_TAC `c:real^N` THEN DISCH_TAC THEN
1184 FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N`) THEN ASM SET_TAC[];
1185 REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY; IN_ELIM_THM] THEN
1186 X_GEN_TAC `c:real^N` THEN DISCH_THEN(CONJUNCTS_THEN2
1187 (X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC)
1188 (X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC)) THEN
1189 FIRST_X_ASSUM(MP_TAC o SPECL [`t INTER u:real^N->bool`; `c:real^N`]) THEN
1190 ASM_SIMP_TAC[OPEN_IN_INTER] THEN ASM SET_TAC[];
1194 let CONNECTED_EQUIVALENCE_RELATION_GEN = prove
1195 (`!P R s:real^N->bool.
1197 (!x y. R x y ==> R y x) /\
1198 (!x y z. R x y /\ R y z ==> R x z) /\
1199 (!t a. open_in (subtopology euclidean s) t /\ a IN t
1200 ==> ?z. z IN t /\ P z) /\
1202 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
1203 !x y. x IN t /\ y IN t /\ P x /\ P y ==> R x y)
1204 ==> !a b. a IN s /\ b IN s /\ P a /\ P b ==> R a b`,
1205 REPEAT GEN_TAC THEN STRIP_TAC THEN
1207 `!a:real^N. a IN s /\ P a
1208 ==> !b c. b IN s /\ c IN s /\ P b /\ P c /\ R a b ==> R a c`
1209 MP_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
1210 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONNECTED_INDUCTION THEN
1213 let CONNECTED_INDUCTION_SIMPLE = prove
1214 (`!P s:real^N->bool.
1217 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
1218 !x y. x IN t /\ y IN t /\ P x ==> P y)
1219 ==> !a b. a IN s /\ b IN s /\ P a ==> P b`,
1220 MP_TAC(ISPEC `\x:real^N. T` CONNECTED_INDUCTION) THEN
1222 REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN MESON_TAC[]);;
1224 let CONNECTED_EQUIVALENCE_RELATION = prove
1225 (`!R s:real^N->bool.
1227 (!x y. R x y ==> R y x) /\
1228 (!x y z. R x y /\ R y z ==> R x z) /\
1230 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
1231 !x. x IN t ==> R a x)
1232 ==> !a b. a IN s /\ b IN s ==> R a b`,
1233 REPEAT GEN_TAC THEN STRIP_TAC THEN
1235 `!a:real^N. a IN s ==> !b c. b IN s /\ c IN s /\ R a b ==> R a c`
1236 MP_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
1237 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONNECTED_INDUCTION_SIMPLE THEN
1240 (* ------------------------------------------------------------------------- *)
1242 (* ------------------------------------------------------------------------- *)
1244 parse_as_infix ("limit_point_of",(12,"right"));;
1246 let limit_point_of = new_definition
1247 `x limit_point_of s <=>
1248 !t. x IN t /\ open t ==> ?y. ~(y = x) /\ y IN s /\ y IN t`;;
1250 let LIMPT_SUBSET = prove
1251 (`!x s t. x limit_point_of s /\ s SUBSET t ==> x limit_point_of t`,
1252 REWRITE_TAC[limit_point_of; SUBSET] THEN MESON_TAC[]);;
1254 let LIMPT_APPROACHABLE = prove
1255 (`!x s. x limit_point_of s <=>
1256 !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ dist(x',x) < e`,
1257 REPEAT GEN_TAC THEN REWRITE_TAC[limit_point_of] THEN
1258 MESON_TAC[open_def; DIST_SYM; OPEN_BALL; CENTRE_IN_BALL; IN_BALL]);;
1260 let LIMPT_APPROACHABLE_LE = prove
1261 (`!x s. x limit_point_of s <=>
1262 !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ dist(x',x) <= e`,
1263 REPEAT GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
1264 MATCH_MP_TAC(TAUT `(~a <=> ~b) ==> (a <=> b)`) THEN
1265 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN
1266 REWRITE_TAC[TAUT `~(a /\ b /\ c) <=> c ==> ~(a /\ b)`; APPROACHABLE_LT_LE]);;
1268 let LIMPT_UNIV = prove
1269 (`!x:real^N. x limit_point_of UNIV`,
1270 GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE; IN_UNIV] THEN
1271 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1272 SUBGOAL_THEN `?c:real^N. norm(c) = e / &2` CHOOSE_TAC THENL
1273 [ASM_SIMP_TAC[VECTOR_CHOOSE_SIZE; REAL_HALF; REAL_LT_IMP_LE];
1275 EXISTS_TAC `x + c:real^N` THEN
1276 REWRITE_TAC[dist; VECTOR_EQ_ADDR] THEN ASM_REWRITE_TAC[VECTOR_ADD_SUB] THEN
1277 SUBGOAL_THEN `&0 < e / &2 /\ e / &2 < e`
1278 (fun th -> ASM_MESON_TAC[th; NORM_0; REAL_LT_REFL]) THEN
1279 SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
1280 UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC);;
1282 let CLOSED_LIMPT = prove
1283 (`!s. closed s <=> !x. x limit_point_of s ==> x IN s`,
1284 REWRITE_TAC[closed] THEN ONCE_REWRITE_TAC[OPEN_SUBOPEN] THEN
1285 REWRITE_TAC[limit_point_of; IN_DIFF; IN_UNIV; SUBSET] THEN MESON_TAC[]);;
1287 let LIMPT_EMPTY = prove
1288 (`!x. ~(x limit_point_of {})`,
1289 REWRITE_TAC[LIMPT_APPROACHABLE; NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]);;
1291 let NO_LIMIT_POINT_IMP_CLOSED = prove
1292 (`!s. ~(?x. x limit_point_of s) ==> closed s`,
1293 MESON_TAC[CLOSED_LIMPT]);;
1295 let CLOSED_POSITIVE_ORTHANT = prove
1296 (`closed {x:real^N | !i. 1 <= i /\ i <= dimindex(:N)
1298 REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE] THEN
1299 REWRITE_TAC[IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
1300 X_GEN_TAC `i:num` THEN STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
1301 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `--(x:real^N $ i)`) THEN
1302 ASM_REWRITE_TAC[REAL_LT_RNEG; REAL_ADD_LID; NOT_EXISTS_THM] THEN
1303 X_GEN_TAC `y:real^N` THEN
1304 MATCH_MP_TAC(TAUT `(a ==> ~c) ==> ~(a /\ b /\ c)`) THEN DISCH_TAC THEN
1305 MATCH_MP_TAC(REAL_ARITH `!b. abs x <= b /\ b <= a ==> ~(a + x < &0)`) THEN
1306 EXISTS_TAC `abs((y - x :real^N)$i)` THEN
1307 ASM_SIMP_TAC[dist; COMPONENT_LE_NORM] THEN
1308 ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; REAL_ARITH
1309 `x < &0 /\ &0 <= y ==> abs(x) <= abs(y - x)`]);;
1311 let FINITE_SET_AVOID = prove
1312 (`!a:real^N s. FINITE s
1313 ==> ?d. &0 < d /\ !x. x IN s /\ ~(x = a) ==> d <= dist(a,x)`,
1314 GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1315 REWRITE_TAC[NOT_IN_EMPTY] THEN
1316 CONJ_TAC THENL [MESON_TAC[REAL_LT_01]; ALL_TAC] THEN
1317 MAP_EVERY X_GEN_TAC [`x:real^N`; `s:real^N->bool`] THEN
1318 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
1319 FIRST_X_ASSUM(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
1320 ASM_CASES_TAC `x:real^N = a` THEN REWRITE_TAC[IN_INSERT] THENL
1321 [ASM_MESON_TAC[]; ALL_TAC] THEN
1322 EXISTS_TAC `min d (dist(a:real^N,x))` THEN
1323 ASM_REWRITE_TAC[REAL_LT_MIN; GSYM DIST_NZ; REAL_MIN_LE] THEN
1324 ASM_MESON_TAC[REAL_LE_REFL]);;
1326 let LIMIT_POINT_FINITE = prove
1327 (`!s a. FINITE s ==> ~(a limit_point_of s)`,
1328 REWRITE_TAC[LIMPT_APPROACHABLE; GSYM REAL_NOT_LE] THEN
1329 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM; REAL_NOT_LE;
1330 REAL_NOT_LT; TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN
1331 MESON_TAC[FINITE_SET_AVOID; DIST_SYM]);;
1333 let LIMPT_SING = prove
1334 (`!x y:real^N. ~(x limit_point_of {y})`,
1335 SIMP_TAC[LIMIT_POINT_FINITE; FINITE_SING]);;
1337 let LIMIT_POINT_UNION = prove
1338 (`!s t x:real^N. x limit_point_of (s UNION t) <=>
1339 x limit_point_of s \/ x limit_point_of t`,
1340 REPEAT GEN_TAC THEN EQ_TAC THENL
1341 [ALL_TAC; MESON_TAC[LIMPT_SUBSET; SUBSET_UNION]] THEN
1342 REWRITE_TAC[LIMPT_APPROACHABLE; IN_UNION] THEN DISCH_TAC THEN
1343 MATCH_MP_TAC(TAUT `(~a ==> b) ==> a \/ b`) THEN
1344 REWRITE_TAC[NOT_FORALL_THM; LEFT_IMP_EXISTS_THM; NOT_IMP] THEN
1345 X_GEN_TAC `e:real` THEN STRIP_TAC THEN X_GEN_TAC `d:real` THEN DISCH_TAC THEN
1346 FIRST_X_ASSUM(MP_TAC o SPEC `min d e`) THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
1349 let LIMPT_INSERT = prove
1350 (`!s x y:real^N. x limit_point_of (y INSERT s) <=> x limit_point_of s`,
1351 ONCE_REWRITE_TAC[SET_RULE `y INSERT s = {y} UNION s`] THEN
1352 REWRITE_TAC[LIMIT_POINT_UNION] THEN
1353 SIMP_TAC[FINITE_SING; LIMIT_POINT_FINITE]);;
1355 let LIMPT_OF_LIMPTS = prove
1357 x limit_point_of {y | y limit_point_of s} ==> x limit_point_of s`,
1358 REWRITE_TAC[LIMPT_APPROACHABLE; IN_ELIM_THM] THEN REPEAT GEN_TAC THEN
1359 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1360 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
1361 DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN
1362 FIRST_X_ASSUM(MP_TAC o SPEC `dist(y:real^N,x)`) THEN
1363 ASM_SIMP_TAC[DIST_POS_LT] THEN MATCH_MP_TAC MONO_EXISTS THEN
1364 GEN_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1365 REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC);;
1367 let CLOSED_LIMPTS = prove
1368 (`!s. closed {x:real^N | x limit_point_of s}`,
1369 REWRITE_TAC[CLOSED_LIMPT; IN_ELIM_THM; LIMPT_OF_LIMPTS]);;
1371 let DISCRETE_IMP_CLOSED = prove
1372 (`!s:real^N->bool e.
1374 (!x y. x IN s /\ y IN s /\ norm(y - x) < e ==> y = x)
1376 REPEAT STRIP_TAC THEN
1377 SUBGOAL_THEN `!x:real^N. ~(x limit_point_of s)`
1378 (fun th -> MESON_TAC[th; CLOSED_LIMPT]) THEN
1379 GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN DISCH_TAC THEN
1380 FIRST_ASSUM(MP_TAC o SPEC `e / &2`) THEN
1381 REWRITE_TAC[REAL_HALF; ASSUME `&0 < e`] THEN
1382 DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN
1383 FIRST_X_ASSUM(MP_TAC o SPEC `min (e / &2) (dist(x:real^N,y))`) THEN
1384 ASM_SIMP_TAC[REAL_LT_MIN; DIST_POS_LT; REAL_HALF] THEN
1385 DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
1386 FIRST_X_ASSUM(MP_TAC o SPECL [`y:real^N`; `z:real^N`]) THEN
1387 ASM_REWRITE_TAC[] THEN ASM_NORM_ARITH_TAC);;
1389 let LIMPT_OF_UNIV = prove
1390 (`!x. x limit_point_of (:real^N)`,
1391 GEN_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE; IN_UNIV] THEN
1392 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1393 MP_TAC(ISPECL [`x:real^N`; `e / &2`] VECTOR_CHOOSE_DIST) THEN
1394 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN
1395 POP_ASSUM MP_TAC THEN CONV_TAC NORM_ARITH);;
1397 let LIMPT_OF_OPEN_IN = prove
1399 open_in (subtopology euclidean s) t /\ x limit_point_of s /\ x IN t
1400 ==> x limit_point_of t`,
1401 REWRITE_TAC[open_in; SUBSET; LIMPT_APPROACHABLE] THEN
1402 REPEAT GEN_TAC THEN STRIP_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1403 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
1404 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
1405 FIRST_X_ASSUM(MP_TAC o SPEC `min d e / &2`) THEN
1406 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN
1407 GEN_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THEN
1408 TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN ASM_REWRITE_TAC[] THEN
1409 ASM_REAL_ARITH_TAC);;
1411 let LIMPT_OF_OPEN = prove
1412 (`!s x:real^N. open s /\ x IN s ==> x limit_point_of s`,
1413 REWRITE_TAC[OPEN_IN] THEN ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN
1414 MESON_TAC[LIMPT_OF_OPEN_IN; LIMPT_OF_UNIV]);;
1416 let OPEN_IN_SING = prove
1417 (`!s a. open_in (subtopology euclidean s) {a} <=>
1418 a IN s /\ ~(a limit_point_of s)`,
1419 REWRITE_TAC[open_in; LIMPT_APPROACHABLE; SING_SUBSET; IN_SING] THEN
1420 REWRITE_TAC[FORALL_UNWIND_THM2] THEN MESON_TAC[]);;
1422 (* ------------------------------------------------------------------------- *)
1423 (* Interior of a set. *)
1424 (* ------------------------------------------------------------------------- *)
1426 let interior = new_definition
1427 `interior s = {x | ?t. open t /\ x IN t /\ t SUBSET s}`;;
1429 let INTERIOR_EQ = prove
1430 (`!s. (interior s = s) <=> open s`,
1431 GEN_TAC THEN REWRITE_TAC[EXTENSION; interior; IN_ELIM_THM] THEN
1432 GEN_REWRITE_TAC RAND_CONV [OPEN_SUBOPEN] THEN MESON_TAC[SUBSET]);;
1434 let INTERIOR_OPEN = prove
1435 (`!s. open s ==> (interior s = s)`,
1436 MESON_TAC[INTERIOR_EQ]);;
1438 let INTERIOR_EMPTY = prove
1439 (`interior {} = {}`,
1440 SIMP_TAC[INTERIOR_OPEN; OPEN_EMPTY]);;
1442 let INTERIOR_UNIV = prove
1443 (`interior(:real^N) = (:real^N)`,
1444 SIMP_TAC[INTERIOR_OPEN; OPEN_UNIV]);;
1446 let OPEN_INTERIOR = prove
1447 (`!s. open(interior s)`,
1448 GEN_TAC THEN REWRITE_TAC[interior] THEN GEN_REWRITE_TAC I [OPEN_SUBOPEN] THEN
1449 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN MESON_TAC[]);;
1451 let INTERIOR_INTERIOR = prove
1452 (`!s. interior(interior s) = interior s`,
1453 MESON_TAC[INTERIOR_EQ; OPEN_INTERIOR]);;
1455 let INTERIOR_SUBSET = prove
1456 (`!s. (interior s) SUBSET s`,
1457 REWRITE_TAC[SUBSET; interior; IN_ELIM_THM] THEN MESON_TAC[]);;
1459 let SUBSET_INTERIOR = prove
1460 (`!s t. s SUBSET t ==> (interior s) SUBSET (interior t)`,
1461 REWRITE_TAC[interior; SUBSET; IN_ELIM_THM] THEN MESON_TAC[]);;
1463 let INTERIOR_MAXIMAL = prove
1464 (`!s t. t SUBSET s /\ open t ==> t SUBSET (interior s)`,
1465 REWRITE_TAC[interior; SUBSET; IN_ELIM_THM] THEN MESON_TAC[]);;
1467 let INTERIOR_MAXIMAL_EQ = prove
1468 (`!s t:real^N->bool. open s ==> (s SUBSET interior t <=> s SUBSET t)`,
1469 MESON_TAC[INTERIOR_MAXIMAL; SUBSET_TRANS; INTERIOR_SUBSET]);;
1471 let INTERIOR_UNIQUE = prove
1472 (`!s t. t SUBSET s /\ open t /\ (!t'. t' SUBSET s /\ open t' ==> t' SUBSET t)
1473 ==> (interior s = t)`,
1474 MESON_TAC[SUBSET_ANTISYM; INTERIOR_MAXIMAL; INTERIOR_SUBSET;
1477 let IN_INTERIOR = prove
1478 (`!x s. x IN interior s <=> ?e. &0 < e /\ ball(x,e) SUBSET s`,
1479 REWRITE_TAC[interior; IN_ELIM_THM] THEN
1480 MESON_TAC[OPEN_CONTAINS_BALL; SUBSET_TRANS; CENTRE_IN_BALL; OPEN_BALL]);;
1482 let OPEN_SUBSET_INTERIOR = prove
1483 (`!s t. open s ==> (s SUBSET interior t <=> s SUBSET t)`,
1484 MESON_TAC[INTERIOR_MAXIMAL; INTERIOR_SUBSET; SUBSET_TRANS]);;
1486 let INTERIOR_INTER = prove
1487 (`!s t:real^N->bool. interior(s INTER t) = interior s INTER interior t`,
1488 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
1489 [REWRITE_TAC[SUBSET_INTER] THEN CONJ_TAC THEN
1490 MATCH_MP_TAC SUBSET_INTERIOR THEN REWRITE_TAC[INTER_SUBSET];
1491 MATCH_MP_TAC INTERIOR_MAXIMAL THEN SIMP_TAC[OPEN_INTER; OPEN_INTERIOR] THEN
1492 MATCH_MP_TAC(SET_RULE
1493 `s SUBSET s' /\ t SUBSET t' ==> s INTER t SUBSET s' INTER t'`) THEN
1494 REWRITE_TAC[INTERIOR_SUBSET]]);;
1496 let INTERIOR_FINITE_INTERS = prove
1497 (`!s:(real^N->bool)->bool.
1498 FINITE s ==> interior(INTERS s) = INTERS(IMAGE interior s)`,
1499 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1500 REWRITE_TAC[INTERS_0; INTERS_INSERT; INTERIOR_UNIV; IMAGE_CLAUSES] THEN
1501 SIMP_TAC[INTERIOR_INTER]);;
1503 let INTERIOR_INTERS_SUBSET = prove
1504 (`!f. interior(INTERS f) SUBSET INTERS (IMAGE interior f)`,
1505 REWRITE_TAC[SUBSET; IN_INTERIOR; IN_INTERS; FORALL_IN_IMAGE] THEN
1508 let UNION_INTERIOR_SUBSET = prove
1509 (`!s t:real^N->bool.
1510 interior s UNION interior t SUBSET interior(s UNION t)`,
1511 SIMP_TAC[INTERIOR_MAXIMAL_EQ; OPEN_UNION; OPEN_INTERIOR] THEN
1512 REPEAT GEN_TAC THEN MATCH_MP_TAC(SET_RULE
1513 `s SUBSET s' /\ t SUBSET t' ==> (s UNION t) SUBSET (s' UNION t')`) THEN
1514 REWRITE_TAC[INTERIOR_SUBSET]);;
1516 let INTERIOR_EQ_EMPTY = prove
1517 (`!s:real^N->bool. interior s = {} <=> !t. open t /\ t SUBSET s ==> t = {}`,
1518 MESON_TAC[INTERIOR_MAXIMAL_EQ; SUBSET_EMPTY;
1519 OPEN_INTERIOR; INTERIOR_SUBSET]);;
1521 let INTERIOR_EQ_EMPTY_ALT = prove
1524 !t. open t /\ ~(t = {}) ==> ~(t DIFF s = {})`,
1525 GEN_TAC THEN REWRITE_TAC[INTERIOR_EQ_EMPTY] THEN SET_TAC[]);;
1527 let INTERIOR_LIMIT_POINT = prove
1528 (`!s x:real^N. x IN interior s ==> x limit_point_of s`,
1530 REWRITE_TAC[IN_INTERIOR; IN_ELIM_THM; SUBSET; IN_BALL] THEN
1531 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
1532 REWRITE_TAC[LIMPT_APPROACHABLE] THEN X_GEN_TAC `d:real` THEN
1534 MP_TAC(ISPECL [`x:real^N`; `min d e / &2`] VECTOR_CHOOSE_DIST) THEN
1535 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
1536 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
1537 REPEAT CONJ_TAC THENL
1538 [FIRST_X_ASSUM MATCH_MP_TAC;
1539 CONV_TAC (RAND_CONV SYM_CONV) THEN REWRITE_TAC[GSYM DIST_EQ_0];
1540 ONCE_REWRITE_TAC[DIST_SYM]] THEN
1541 ASM_REAL_ARITH_TAC);;
1543 let INTERIOR_SING = prove
1544 (`!a:real^N. interior {a} = {}`,
1545 REWRITE_TAC[EXTENSION; NOT_IN_EMPTY] THEN
1546 MESON_TAC[INTERIOR_LIMIT_POINT; LIMPT_SING]);;
1548 let INTERIOR_CLOSED_UNION_EMPTY_INTERIOR = prove
1549 (`!s t:real^N->bool.
1550 closed(s) /\ interior(t) = {}
1551 ==> interior(s UNION t) = interior(s)`,
1552 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
1553 SIMP_TAC[SUBSET_INTERIOR; SUBSET_UNION] THEN
1554 REWRITE_TAC[SUBSET; IN_INTERIOR; IN_INTER; IN_UNION] THEN
1555 X_GEN_TAC `x:real^N` THEN MATCH_MP_TAC MONO_EXISTS THEN
1556 X_GEN_TAC `e:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1557 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
1558 SUBGOAL_THEN `(y:real^N) limit_point_of s`
1559 (fun th -> ASM_MESON_TAC[CLOSED_LIMPT; th]) THEN
1560 REWRITE_TAC[IN_INTERIOR; NOT_IN_EMPTY; LIMPT_APPROACHABLE] THEN
1561 X_GEN_TAC `d:real` THEN DISCH_TAC THEN
1563 `?z:real^N. ~(z IN t) /\ ~(z = y) /\ dist(z,y) < d /\ dist(x,z) < e`
1564 (fun th -> ASM_MESON_TAC[th; IN_BALL]) THEN
1565 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN
1566 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
1567 REWRITE_TAC[IN_INTERIOR; NOT_IN_EMPTY; NOT_EXISTS_THM] THEN
1568 ABBREV_TAC `k = min d (e - dist(x:real^N,y))` THEN
1569 SUBGOAL_THEN `&0 < k` ASSUME_TAC THENL
1570 [ASM_ARITH_TAC; ALL_TAC] THEN
1571 SUBGOAL_THEN `?w:real^N. dist(y,w) = k / &2` CHOOSE_TAC THENL
1572 [ASM_SIMP_TAC[VECTOR_CHOOSE_DIST; REAL_HALF; REAL_LT_IMP_LE]; ALL_TAC] THEN
1573 DISCH_THEN(MP_TAC o SPECL [`w:real^N`; `k / &4`]) THEN
1574 ASM_SIMP_TAC[SUBSET; NOT_FORALL_THM; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH;
1575 NOT_IMP; IN_BALL] THEN
1576 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:real^N` THEN
1577 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN ASM_REWRITE_TAC[] THEN
1578 ASM_NORM_ARITH_TAC);;
1580 let INTERIOR_UNION_EQ_EMPTY = prove
1581 (`!s t:real^N->bool.
1582 closed s \/ closed t
1583 ==> (interior(s UNION t) = {} <=>
1584 interior s = {} /\ interior t = {})`,
1585 REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THENL
1586 [ASM_MESON_TAC[SUBSET_UNION; SUBSET_INTERIOR; SUBSET_EMPTY];
1587 ASM_MESON_TAC[UNION_COMM; INTERIOR_CLOSED_UNION_EMPTY_INTERIOR]]);;
1589 let INTERIOR_UNIONS_OPEN_SUBSETS = prove
1590 (`!s:real^N->bool. UNIONS {t | open t /\ t SUBSET s} = interior s`,
1591 GEN_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN
1592 SIMP_TAC[OPEN_UNIONS; IN_ELIM_THM] THEN SET_TAC[]);;
1594 (* ------------------------------------------------------------------------- *)
1595 (* Closure of a set. *)
1596 (* ------------------------------------------------------------------------- *)
1598 let closure = new_definition
1599 `closure s = s UNION {x | x limit_point_of s}`;;
1601 let CLOSURE_INTERIOR = prove
1602 (`!s:real^N->bool. closure s = UNIV DIFF (interior (UNIV DIFF s))`,
1603 REWRITE_TAC[EXTENSION; closure; IN_UNION; IN_DIFF; IN_UNIV; interior;
1604 IN_ELIM_THM; limit_point_of; SUBSET] THEN
1607 let INTERIOR_CLOSURE = prove
1608 (`!s:real^N->bool. interior s = UNIV DIFF (closure (UNIV DIFF s))`,
1609 let lemma = prove(`!s t. UNIV DIFF (UNIV DIFF t) = t`,SET_TAC[]) in
1610 REWRITE_TAC[CLOSURE_INTERIOR; lemma]);;
1612 let CLOSED_CLOSURE = prove
1613 (`!s. closed(closure s)`,
1614 let lemma = prove(`UNIV DIFF (UNIV DIFF s) = s`,SET_TAC[]) in
1615 REWRITE_TAC[closed; CLOSURE_INTERIOR; lemma; OPEN_INTERIOR]);;
1617 let CLOSURE_HULL = prove
1618 (`!s. closure s = closed hull s`,
1619 GEN_TAC THEN MATCH_MP_TAC(GSYM HULL_UNIQUE) THEN
1620 REWRITE_TAC[CLOSED_CLOSURE; SUBSET] THEN
1621 REWRITE_TAC[closure; IN_UNION; IN_ELIM_THM; CLOSED_LIMPT] THEN
1622 MESON_TAC[limit_point_of]);;
1624 let CLOSURE_EQ = prove
1625 (`!s. (closure s = s) <=> closed s`,
1626 SIMP_TAC[CLOSURE_HULL; HULL_EQ; CLOSED_INTERS]);;
1628 let CLOSURE_CLOSED = prove
1629 (`!s. closed s ==> (closure s = s)`,
1630 MESON_TAC[CLOSURE_EQ]);;
1632 let CLOSURE_CLOSURE = prove
1633 (`!s. closure(closure s) = closure s`,
1634 REWRITE_TAC[CLOSURE_HULL; HULL_HULL]);;
1636 let CLOSURE_SUBSET = prove
1637 (`!s. s SUBSET (closure s)`,
1638 REWRITE_TAC[CLOSURE_HULL; HULL_SUBSET]);;
1640 let SUBSET_CLOSURE = prove
1641 (`!s t. s SUBSET t ==> (closure s) SUBSET (closure t)`,
1642 REWRITE_TAC[CLOSURE_HULL; HULL_MONO]);;
1644 let CLOSURE_UNION = prove
1645 (`!s t:real^N->bool. closure(s UNION t) = closure s UNION closure t`,
1646 REWRITE_TAC[LIMIT_POINT_UNION; closure] THEN SET_TAC[]);;
1648 let CLOSURE_INTER_SUBSET = prove
1649 (`!s t. closure(s INTER t) SUBSET closure(s) INTER closure(t)`,
1650 REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET_INTER] THEN
1651 CONJ_TAC THEN MATCH_MP_TAC SUBSET_CLOSURE THEN SET_TAC[]);;
1653 let CLOSURE_INTERS_SUBSET = prove
1654 (`!f. closure(INTERS f) SUBSET INTERS(IMAGE closure f)`,
1655 REWRITE_TAC[SET_RULE `s SUBSET INTERS f <=> !t. t IN f ==> s SUBSET t`] THEN
1656 REWRITE_TAC[FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN
1657 MATCH_MP_TAC SUBSET_CLOSURE THEN ASM SET_TAC[]);;
1659 let CLOSURE_MINIMAL = prove
1660 (`!s t. s SUBSET t /\ closed t ==> (closure s) SUBSET t`,
1661 REWRITE_TAC[HULL_MINIMAL; CLOSURE_HULL]);;
1663 let CLOSURE_MINIMAL_EQ = prove
1664 (`!s t:real^N->bool. closed t ==> (closure s SUBSET t <=> s SUBSET t)`,
1665 MESON_TAC[SUBSET_TRANS; CLOSURE_SUBSET; CLOSURE_MINIMAL]);;
1667 let CLOSURE_UNIQUE = prove
1668 (`!s t. s SUBSET t /\ closed t /\
1669 (!t'. s SUBSET t' /\ closed t' ==> t SUBSET t')
1670 ==> (closure s = t)`,
1671 REWRITE_TAC[CLOSURE_HULL; HULL_UNIQUE]);;
1673 let CLOSURE_EMPTY = prove
1675 SIMP_TAC[CLOSURE_CLOSED; CLOSED_EMPTY]);;
1677 let CLOSURE_UNIV = prove
1678 (`closure(:real^N) = (:real^N)`,
1679 SIMP_TAC[CLOSURE_CLOSED; CLOSED_UNIV]);;
1681 let CLOSURE_UNIONS = prove
1682 (`!f. FINITE f ==> closure(UNIONS f) = UNIONS {closure s | s IN f}`,
1683 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1684 REWRITE_TAC[UNIONS_0; UNIONS_INSERT; SET_RULE `{f x | x IN {}} = {}`;
1685 SET_RULE `{f x | x IN a INSERT s} = (f a) INSERT {f x | x IN s}`] THEN
1686 SIMP_TAC[CLOSURE_EMPTY; CLOSURE_UNION]);;
1688 let CLOSURE_EQ_EMPTY = prove
1689 (`!s. closure s = {} <=> s = {}`,
1690 GEN_TAC THEN EQ_TAC THEN SIMP_TAC[CLOSURE_EMPTY] THEN
1691 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> t = {} ==> s = {}`) THEN
1692 REWRITE_TAC[CLOSURE_SUBSET]);;
1694 let CLOSURE_SUBSET_EQ = prove
1695 (`!s:real^N->bool. closure s SUBSET s <=> closed s`,
1696 GEN_TAC THEN REWRITE_TAC[GSYM CLOSURE_EQ] THEN
1697 MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN SET_TAC[]);;
1699 let OPEN_INTER_CLOSURE_EQ_EMPTY = prove
1700 (`!s t:real^N->bool.
1701 open s ==> (s INTER (closure t) = {} <=> s INTER t = {})`,
1702 REPEAT STRIP_TAC THEN EQ_TAC THENL
1703 [MP_TAC(ISPEC `t:real^N->bool` CLOSURE_SUBSET) THEN SET_TAC[]; ALL_TAC] THEN
1704 DISCH_TAC THEN REWRITE_TAC[CLOSURE_INTERIOR] THEN
1705 MATCH_MP_TAC(SET_RULE `s SUBSET t ==> s INTER (UNIV DIFF t) = {}`) THEN
1706 ASM_SIMP_TAC[OPEN_SUBSET_INTERIOR] THEN ASM SET_TAC[]);;
1708 let OPEN_INTER_CLOSURE_SUBSET = prove
1709 (`!s t:real^N->bool.
1710 open s ==> (s INTER (closure t)) SUBSET closure(s INTER t)`,
1711 REPEAT STRIP_TAC THEN
1712 SIMP_TAC[SUBSET; IN_INTER; closure; IN_UNION; IN_ELIM_THM] THEN
1713 X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1714 DISJ2_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
1715 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1716 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [open_def]) THEN
1717 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
1718 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
1719 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIMPT_APPROACHABLE]) THEN
1720 DISCH_THEN(MP_TAC o SPEC `min d e`) THEN
1721 ASM_REWRITE_TAC[REAL_LT_MIN; IN_INTER] THEN
1722 MATCH_MP_TAC MONO_EXISTS THEN ASM_MESON_TAC[]);;
1724 let CLOSURE_OPEN_INTER_SUPERSET = prove
1725 (`!s t:real^N->bool.
1726 open s /\ s SUBSET closure t ==> closure(s INTER t) = closure s`,
1727 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
1728 SIMP_TAC[SUBSET_CLOSURE; INTER_SUBSET] THEN
1729 MATCH_MP_TAC CLOSURE_MINIMAL THEN REWRITE_TAC[CLOSED_CLOSURE] THEN
1730 W(MP_TAC o PART_MATCH (rand o rand)
1731 OPEN_INTER_CLOSURE_SUBSET o rand o snd) THEN
1732 ASM_REWRITE_TAC[] THEN
1733 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] SUBSET_TRANS) THEN ASM SET_TAC[]);;
1735 let CLOSURE_COMPLEMENT = prove
1736 (`!s:real^N->bool. closure(UNIV DIFF s) = UNIV DIFF interior(s)`,
1737 REWRITE_TAC[SET_RULE `s = UNIV DIFF t <=> UNIV DIFF s = t`] THEN
1738 REWRITE_TAC[GSYM INTERIOR_CLOSURE]);;
1740 let INTERIOR_COMPLEMENT = prove
1741 (`!s:real^N->bool. interior(UNIV DIFF s) = UNIV DIFF closure(s)`,
1742 REWRITE_TAC[SET_RULE `s = UNIV DIFF t <=> UNIV DIFF s = t`] THEN
1743 REWRITE_TAC[GSYM CLOSURE_INTERIOR]);;
1745 let CONNECTED_INTERMEDIATE_CLOSURE = prove
1746 (`!s t:real^N->bool.
1747 connected s /\ s SUBSET t /\ t SUBSET closure s ==> connected t`,
1748 REPEAT GEN_TAC THEN REWRITE_TAC[connected; NOT_EXISTS_THM] THEN
1750 MAP_EVERY X_GEN_TAC [`u:real^N->bool`; `v:real^N->bool`] THEN STRIP_TAC THEN
1751 FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^N->bool`; `v:real^N->bool`]) THEN
1752 ASM_REWRITE_TAC[] THEN ASSUME_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN
1753 REPLICATE_TAC 2 (CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
1754 REWRITE_TAC[GSYM DE_MORGAN_THM] THEN STRIP_TAC THENL
1755 [SUBGOAL_THEN `(closure s) SUBSET ((:real^N) DIFF u)` MP_TAC THENL
1756 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_REWRITE_TAC[GSYM OPEN_CLOSED];
1758 SUBGOAL_THEN `(closure s) SUBSET ((:real^N) DIFF v)` MP_TAC THENL
1759 [MATCH_MP_TAC CLOSURE_MINIMAL THEN ASM_REWRITE_TAC[GSYM OPEN_CLOSED];
1763 let CONNECTED_CLOSURE = prove
1764 (`!s:real^N->bool. connected s ==> connected(closure s)`,
1765 MESON_TAC[CONNECTED_INTERMEDIATE_CLOSURE; CLOSURE_SUBSET; SUBSET_REFL]);;
1767 let CONNECTED_UNION_STRONG = prove
1768 (`!s t:real^N->bool.
1769 connected s /\ connected t /\ ~(closure s INTER t = {})
1770 ==> connected(s UNION t)`,
1771 REPEAT STRIP_TAC THEN
1772 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
1773 DISCH_THEN(X_CHOOSE_TAC `p:real^N`) THEN
1774 SUBGOAL_THEN `s UNION t = ((p:real^N) INSERT s) UNION t` SUBST1_TAC THENL
1775 [ASM SET_TAC[]; ALL_TAC] THEN
1776 MATCH_MP_TAC CONNECTED_UNION THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
1777 [MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN
1778 EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN
1779 MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[];
1782 let INTERIOR_DIFF = prove
1783 (`!s t. interior(s DIFF t) = interior(s) DIFF closure(t)`,
1784 ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN
1785 REWRITE_TAC[INTERIOR_INTER; CLOSURE_INTERIOR] THEN SET_TAC[]);;
1787 let LIMPT_OF_CLOSURE = prove
1788 (`!x:real^N s. x limit_point_of closure s <=> x limit_point_of s`,
1789 REWRITE_TAC[closure; IN_UNION; IN_ELIM_THM; LIMIT_POINT_UNION] THEN
1790 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT `(q ==> p) ==> (p \/ q <=> p)`) THEN
1791 REWRITE_TAC[LIMPT_OF_LIMPTS]);;
1793 let CLOSED_IN_LIMPT = prove
1794 (`!s t. closed_in (subtopology euclidean t) s <=>
1795 s SUBSET t /\ !x:real^N. x limit_point_of s /\ x IN t ==> x IN s`,
1796 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN_CLOSED] THEN EQ_TAC THENL
1797 [DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
1798 ASM_SIMP_TAC[IN_INTER] THEN
1799 ASM_MESON_TAC[CLOSED_LIMPT; LIMPT_SUBSET; INTER_SUBSET];
1800 STRIP_TAC THEN EXISTS_TAC `closure s :real^N->bool` THEN
1801 REWRITE_TAC[CLOSED_CLOSURE] THEN REWRITE_TAC[closure] THEN
1804 let INTERIOR_CLOSURE_IDEMP = prove
1806 interior(closure(interior(closure s))) = interior(closure s)`,
1807 GEN_TAC THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN
1808 ASM_MESON_TAC[OPEN_INTERIOR; CLOSURE_SUBSET; CLOSURE_CLOSURE; SUBSET_TRANS;
1809 OPEN_SUBSET_INTERIOR;SUBSET_CLOSURE; INTERIOR_SUBSET]);;
1811 let CLOSURE_INTERIOR_IDEMP = prove
1813 closure(interior(closure(interior s))) = closure(interior s)`,
1815 ONCE_REWRITE_TAC[SET_RULE `s = t <=> UNIV DIFF s = UNIV DIFF t`] THEN
1816 REWRITE_TAC[GSYM INTERIOR_COMPLEMENT; GSYM CLOSURE_COMPLEMENT] THEN
1817 REWRITE_TAC[INTERIOR_CLOSURE_IDEMP]);;
1819 let NOWHERE_DENSE_UNION = prove
1820 (`!s t:real^N->bool.
1821 interior(closure(s UNION t)) = {} <=>
1822 interior(closure s) = {} /\ interior(closure t) = {}`,
1823 SIMP_TAC[CLOSURE_UNION; INTERIOR_UNION_EQ_EMPTY; CLOSED_CLOSURE]);;
1825 let NOWHERE_DENSE = prove
1827 interior(closure s) = {} <=>
1828 !t. open t /\ ~(t = {})
1829 ==> ?u. open u /\ ~(u = {}) /\ u SUBSET t /\ u INTER s = {}`,
1830 GEN_TAC THEN REWRITE_TAC[INTERIOR_EQ_EMPTY_ALT] THEN EQ_TAC THEN
1831 DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THENL
1832 [EXISTS_TAC `t DIFF closure s:real^N->bool` THEN
1833 ASM_SIMP_TAC[OPEN_DIFF; CLOSED_CLOSURE] THEN
1834 MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN SET_TAC[];
1835 FIRST_X_ASSUM(MP_TAC o SPEC `t:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
1836 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
1837 MP_TAC(ISPECL [`u:real^N->bool`; `s:real^N->bool`]
1838 OPEN_INTER_CLOSURE_EQ_EMPTY) THEN
1841 (* ------------------------------------------------------------------------- *)
1842 (* Frontier (aka boundary). *)
1843 (* ------------------------------------------------------------------------- *)
1845 let frontier = new_definition
1846 `frontier s = (closure s) DIFF (interior s)`;;
1848 let FRONTIER_CLOSED = prove
1849 (`!s. closed(frontier s)`,
1850 SIMP_TAC[frontier; CLOSED_DIFF; CLOSED_CLOSURE; OPEN_INTERIOR]);;
1852 let FRONTIER_CLOSURES = prove
1853 (`!s:real^N->bool. frontier s = (closure s) INTER (closure(UNIV DIFF s))`,
1854 let lemma = prove(`s DIFF (UNIV DIFF t) = s INTER t`,SET_TAC[]) in
1855 REWRITE_TAC[frontier; INTERIOR_CLOSURE; lemma]);;
1857 let FRONTIER_STRADDLE = prove
1860 !e. &0 < e ==> (?x. x IN s /\ dist(a,x) < e) /\
1861 (?x. ~(x IN s) /\ dist(a,x) < e)`,
1862 REPEAT GEN_TAC THEN REWRITE_TAC[FRONTIER_CLOSURES; IN_INTER] THEN
1863 REWRITE_TAC[closure; IN_UNION; IN_ELIM_THM; limit_point_of;
1864 IN_UNIV; IN_DIFF] THEN
1865 ASM_MESON_TAC[IN_BALL; SUBSET; OPEN_CONTAINS_BALL;
1866 CENTRE_IN_BALL; OPEN_BALL; DIST_REFL]);;
1868 let FRONTIER_SUBSET_CLOSED = prove
1869 (`!s. closed s ==> (frontier s) SUBSET s`,
1870 MESON_TAC[frontier; CLOSURE_CLOSED; SUBSET_DIFF]);;
1872 let FRONTIER_EMPTY = prove
1873 (`frontier {} = {}`,
1874 REWRITE_TAC[frontier; CLOSURE_EMPTY; EMPTY_DIFF]);;
1876 let FRONTIER_UNIV = prove
1877 (`frontier(:real^N) = {}`,
1878 REWRITE_TAC[frontier; CLOSURE_UNIV; INTERIOR_UNIV] THEN SET_TAC[]);;
1880 let FRONTIER_SUBSET_EQ = prove
1881 (`!s:real^N->bool. (frontier s) SUBSET s <=> closed s`,
1882 GEN_TAC THEN EQ_TAC THEN SIMP_TAC[FRONTIER_SUBSET_CLOSED] THEN
1883 REWRITE_TAC[frontier] THEN
1884 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
1885 `s DIFF t SUBSET u ==> t SUBSET u ==> s SUBSET u`)) THEN
1886 REWRITE_TAC[INTERIOR_SUBSET; CLOSURE_SUBSET_EQ]);;
1888 let FRONTIER_COMPLEMENT = prove
1889 (`!s:real^N->bool. frontier(UNIV DIFF s) = frontier s`,
1890 REWRITE_TAC[frontier; CLOSURE_COMPLEMENT; INTERIOR_COMPLEMENT] THEN
1893 let FRONTIER_DISJOINT_EQ = prove
1894 (`!s. (frontier s) INTER s = {} <=> open s`,
1895 ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT; OPEN_CLOSED] THEN
1896 REWRITE_TAC[GSYM FRONTIER_SUBSET_EQ] THEN SET_TAC[]);;
1898 let FRONTIER_INTER_SUBSET = prove
1899 (`!s t. frontier(s INTER t) SUBSET frontier(s) UNION frontier(t)`,
1900 REPEAT GEN_TAC THEN REWRITE_TAC[frontier; INTERIOR_INTER] THEN
1901 MATCH_MP_TAC(SET_RULE
1902 `cst SUBSET cs INTER ct
1903 ==> cst DIFF (s INTER t) SUBSET (cs DIFF s) UNION (ct DIFF t)`) THEN
1904 REWRITE_TAC[CLOSURE_INTER_SUBSET]);;
1906 let FRONTIER_UNION_SUBSET = prove
1907 (`!s t:real^N->bool. frontier(s UNION t) SUBSET frontier s UNION frontier t`,
1908 ONCE_REWRITE_TAC[GSYM FRONTIER_COMPLEMENT] THEN
1909 REWRITE_TAC[SET_RULE `u DIFF (s UNION t) = (u DIFF s) INTER (u DIFF t)`] THEN
1910 REWRITE_TAC[FRONTIER_INTER_SUBSET]);;
1912 let FRONTIER_INTERIORS = prove
1913 (`!s. frontier s = (:real^N) DIFF interior(s) DIFF interior((:real^N) DIFF s)`,
1914 REWRITE_TAC[frontier; CLOSURE_INTERIOR] THEN SET_TAC[]);;
1916 let FRONTIER_FRONTIER_SUBSET = prove
1917 (`!s:real^N->bool. frontier(frontier s) SUBSET frontier s`,
1918 GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [frontier] THEN
1919 SIMP_TAC[CLOSURE_CLOSED; FRONTIER_CLOSED] THEN SET_TAC[]);;
1921 let INTERIOR_FRONTIER = prove
1923 interior(frontier s) = interior(closure s) DIFF closure(interior s)`,
1924 ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN
1925 REWRITE_TAC[GSYM INTERIOR_COMPLEMENT; GSYM INTERIOR_INTER; frontier] THEN
1926 GEN_TAC THEN AP_TERM_TAC THEN SET_TAC[]);;
1928 let INTERIOR_FRONTIER_EMPTY = prove
1929 (`!s:real^N->bool. open s \/ closed s ==> interior(frontier s) = {}`,
1930 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[INTERIOR_FRONTIER] THEN
1931 ASM_SIMP_TAC[CLOSURE_CLOSED; INTERIOR_OPEN] THEN
1932 REWRITE_TAC[SET_RULE `s DIFF t = {} <=> s SUBSET t`] THEN
1933 REWRITE_TAC[INTERIOR_SUBSET; CLOSURE_SUBSET]);;
1935 let FRONTIER_FRONTIER_FRONTIER = prove
1936 (`!s:real^N->bool. frontier(frontier(frontier s)) = frontier(frontier s)`,
1937 GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [frontier] THEN
1938 SIMP_TAC[CLOSURE_CLOSED; FRONTIER_CLOSED; INTERIOR_FRONTIER_EMPTY] THEN
1941 let CONNECTED_INTER_FRONTIER = prove
1942 (`!s t:real^N->bool.
1943 connected s /\ ~(s INTER t = {}) /\ ~(s DIFF t = {})
1944 ==> ~(s INTER frontier t = {})`,
1945 REWRITE_TAC[FRONTIER_INTERIORS] THEN REPEAT STRIP_TAC THEN
1946 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONNECTED_OPEN_IN]) THEN
1947 REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC
1948 [`s INTER interior t:real^N->bool`;
1949 `s INTER (interior((:real^N) DIFF t))`] THEN
1950 SIMP_TAC[OPEN_IN_OPEN_INTER; OPEN_INTERIOR] THEN
1951 MAP_EVERY (MP_TAC o C ISPEC INTERIOR_SUBSET)
1952 [`t:real^N->bool`; `(:real^N) DIFF t`] THEN
1955 let INTERIOR_CLOSED_EQ_EMPTY_AS_FRONTIER = prove
1957 closed s /\ interior s = {} <=> ?t. open t /\ s = frontier t`,
1958 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THENL
1959 [EXISTS_TAC `(:real^N) DIFF s` THEN
1960 ASM_SIMP_TAC[OPEN_DIFF; OPEN_UNIV; FRONTIER_COMPLEMENT] THEN
1961 ASM_SIMP_TAC[frontier; CLOSURE_CLOSED; DIFF_EMPTY];
1962 ASM_SIMP_TAC[FRONTIER_CLOSED; INTERIOR_FRONTIER_EMPTY]]);;
1964 let FRONTIER_UNION = prove
1965 (`!s t:real^N->bool.
1966 closure s INTER closure t = {}
1967 ==> frontier(s UNION t) = frontier(s) UNION frontier(t)`,
1968 REPEAT STRIP_TAC THEN
1969 MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[FRONTIER_UNION_SUBSET] THEN
1970 GEN_REWRITE_TAC RAND_CONV [frontier] THEN
1971 REWRITE_TAC[CLOSURE_UNION] THEN MATCH_MP_TAC(SET_RULE
1972 `(fs SUBSET cs /\ ft SUBSET ct) /\ k INTER fs = {} /\ k INTER ft = {}
1973 ==> (fs UNION ft) SUBSET (cs UNION ct) DIFF k`) THEN
1974 CONJ_TAC THENL [REWRITE_TAC[frontier] THEN SET_TAC[]; ALL_TAC] THEN
1977 ONCE_REWRITE_TAC[UNION_COMM] THEN
1978 RULE_ASSUM_TAC(ONCE_REWRITE_RULE[INTER_COMM])] THEN
1979 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
1980 `s INTER t = {} ==> s' SUBSET s /\ s' INTER u INTER (UNIV DIFF t) = {}
1981 ==> u INTER s' = {}`)) THEN
1982 REWRITE_TAC[frontier; SUBSET_DIFF; GSYM INTERIOR_COMPLEMENT] THEN
1983 REWRITE_TAC[GSYM INTERIOR_INTER; SET_RULE
1984 `(s UNION t) INTER (UNIV DIFF t) = s DIFF t`] THEN
1985 MATCH_MP_TAC(SET_RULE
1986 `ti SUBSET si ==> (c DIFF si) INTER ti = {}`) THEN
1987 SIMP_TAC[SUBSET_INTERIOR; SUBSET_DIFF]);;
1989 let CLOSURE_UNION_FRONTIER = prove
1990 (`!s:real^N->bool. closure s = s UNION frontier s`,
1991 GEN_TAC THEN REWRITE_TAC[frontier] THEN
1992 MP_TAC(ISPEC `s:real^N->bool` INTERIOR_SUBSET) THEN
1993 MP_TAC(ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN
1996 (* ------------------------------------------------------------------------- *)
1997 (* A variant of nets (slightly non-standard but good for our purposes). *)
1998 (* ------------------------------------------------------------------------- *)
2000 let net_tybij = new_type_definition "net" ("mk_net","netord")
2002 (`?g:A->A->bool. !x y. (!z. g z x ==> g z y) \/ (!z. g z y ==> g z x)`,
2003 EXISTS_TAC `\x:A y:A. F` THEN REWRITE_TAC[]));;
2006 (`!n x y. (!z. netord n z x ==> netord n z y) \/
2007 (!z. netord n z y ==> netord n z x)`,
2008 REWRITE_TAC[net_tybij; ETA_AX]);;
2011 (`!n x y. netord n x x /\ netord n y y
2012 ==> ?z. netord n z z /\
2013 !w. netord n w z ==> netord n w x /\ netord n w y`,
2016 let NET_DILEMMA = prove
2017 (`!net. (?a. (?x. netord net x a) /\ (!x. netord net x a ==> P x)) /\
2018 (?b. (?x. netord net x b) /\ (!x. netord net x b ==> Q x))
2019 ==> ?c. (?x. netord net x c) /\ (!x. netord net x c ==> P x /\ Q x)`,
2022 (* ------------------------------------------------------------------------- *)
2023 (* Common nets and the "within" modifier for nets. *)
2024 (* ------------------------------------------------------------------------- *)
2026 parse_as_infix("within",(14,"right"));;
2027 parse_as_infix("in_direction",(14,"right"));;
2029 let at = new_definition
2030 `at a = mk_net(\x y. &0 < dist(x,a) /\ dist(x,a) <= dist(y,a))`;;
2032 let at_infinity = new_definition
2033 `at_infinity = mk_net(\x y. norm(x) >= norm(y))`;;
2035 let sequentially = new_definition
2036 `sequentially = mk_net(\m:num n. m >= n)`;;
2038 let within = new_definition
2039 `net within s = mk_net(\x y. netord net x y /\ x IN s)`;;
2041 let in_direction = new_definition
2042 `a in_direction v = (at a) within {b | ?c. &0 <= c /\ (b - a = c % v)}`;;
2044 (* ------------------------------------------------------------------------- *)
2045 (* Prove that they are all nets. *)
2046 (* ------------------------------------------------------------------------- *)
2048 let NET_PROVE_TAC[def] =
2049 REWRITE_TAC[GSYM FUN_EQ_THM; def] THEN
2050 REWRITE_TAC[ETA_AX] THEN
2051 ASM_SIMP_TAC[GSYM(CONJUNCT2 net_tybij)];;
2055 netord(at a) x y <=> &0 < dist(x,a) /\ dist(x,a) <= dist(y,a)`,
2056 GEN_TAC THEN NET_PROVE_TAC[at] THEN
2057 MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS; REAL_LET_TRANS]);;
2059 let AT_INFINITY = prove
2060 (`!x y. netord at_infinity x y <=> norm(x) >= norm(y)`,
2061 NET_PROVE_TAC[at_infinity] THEN
2062 REWRITE_TAC[real_ge; REAL_LE_REFL] THEN
2063 MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS]);;
2065 let SEQUENTIALLY = prove
2066 (`!m n. netord sequentially m n <=> m >= n`,
2067 NET_PROVE_TAC[sequentially] THEN REWRITE_TAC[GE; LE_REFL] THEN
2068 MESON_TAC[LE_CASES; LE_REFL; LE_TRANS]);;
2071 (`!n s x y. netord(n within s) x y <=> netord n x y /\ x IN s`,
2072 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[within; GSYM FUN_EQ_THM] THEN
2073 REWRITE_TAC[GSYM(CONJUNCT2 net_tybij); ETA_AX] THEN
2076 let IN_DIRECTION = prove
2077 (`!a v x y. netord(a in_direction v) x y <=>
2078 &0 < dist(x,a) /\ dist(x,a) <= dist(y,a) /\
2079 ?c. &0 <= c /\ (x - a = c % v)`,
2080 REWRITE_TAC[WITHIN; AT; in_direction; IN_ELIM_THM; CONJ_ACI]);;
2082 let WITHIN_UNIV = prove
2083 (`!x:real^N. at x within UNIV = at x`,
2084 REWRITE_TAC[within; at; IN_UNIV] THEN REWRITE_TAC[ETA_AX; net_tybij]);;
2086 let WITHIN_WITHIN = prove
2087 (`!net s t. (net within s) within t = net within (s INTER t)`,
2088 ONCE_REWRITE_TAC[within] THEN
2089 REWRITE_TAC[WITHIN; IN_INTER; GSYM CONJ_ASSOC]);;
2091 (* ------------------------------------------------------------------------- *)
2092 (* Identify trivial limits, where we can't approach arbitrarily closely. *)
2093 (* ------------------------------------------------------------------------- *)
2095 let trivial_limit = new_definition
2096 `trivial_limit net <=>
2098 ?a:A b. ~(a = b) /\ !x. ~(netord(net) x a) /\ ~(netord(net) x b)`;;
2100 let TRIVIAL_LIMIT_WITHIN = prove
2101 (`!a:real^N. trivial_limit (at a within s) <=> ~(a limit_point_of s)`,
2102 REWRITE_TAC[trivial_limit; LIMPT_APPROACHABLE_LE; WITHIN; AT; DIST_NZ] THEN
2103 REPEAT GEN_TAC THEN EQ_TAC THENL
2104 [DISCH_THEN(DISJ_CASES_THEN MP_TAC) THENL
2105 [MESON_TAC[REAL_LT_01; REAL_LT_REFL; VECTOR_CHOOSE_DIST;
2106 DIST_REFL; REAL_LT_IMP_LE];
2107 DISCH_THEN(X_CHOOSE_THEN `b:real^N` (X_CHOOSE_THEN `c:real^N`
2108 STRIP_ASSUME_TAC)) THEN
2109 SUBGOAL_THEN `&0 < dist(a,b:real^N) \/ &0 < dist(a,c:real^N)` MP_TAC THEN
2110 ASM_MESON_TAC[DIST_TRIANGLE; DIST_SYM; GSYM DIST_NZ; GSYM DIST_EQ_0;
2111 REAL_ARITH `x <= &0 + &0 ==> ~(&0 < x)`]];
2112 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN
2113 X_GEN_TAC `e:real` THEN DISCH_TAC THEN DISJ2_TAC THEN
2114 EXISTS_TAC `a:real^N` THEN
2115 SUBGOAL_THEN `?b:real^N. dist(a,b) = e` MP_TAC THENL
2116 [ASM_SIMP_TAC[VECTOR_CHOOSE_DIST; REAL_LT_IMP_LE]; ALL_TAC] THEN
2117 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN
2118 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
2119 ASM_MESON_TAC[REAL_NOT_LE; DIST_REFL; DIST_NZ; DIST_SYM]]);;
2121 let TRIVIAL_LIMIT_AT = prove
2122 (`!a. ~(trivial_limit (at a))`,
2123 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
2124 REWRITE_TAC[TRIVIAL_LIMIT_WITHIN; LIMPT_UNIV]);;
2126 let TRIVIAL_LIMIT_AT_INFINITY = prove
2127 (`~(trivial_limit at_infinity)`,
2128 REWRITE_TAC[trivial_limit; AT_INFINITY; real_ge] THEN
2129 MESON_TAC[REAL_LE_REFL; VECTOR_CHOOSE_SIZE; REAL_LT_01; REAL_LT_LE]);;
2131 let TRIVIAL_LIMIT_SEQUENTIALLY = prove
2132 (`~(trivial_limit sequentially)`,
2133 REWRITE_TAC[trivial_limit; SEQUENTIALLY] THEN
2134 MESON_TAC[GE_REFL; NOT_SUC]);;
2136 let LIM_WITHIN_CLOSED_TRIVIAL = prove
2137 (`!a s. closed s /\ ~(a IN s) ==> trivial_limit (at a within s)`,
2138 REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN MESON_TAC[CLOSED_LIMPT]);;
2140 let NONTRIVIAL_LIMIT_WITHIN = prove
2141 (`!net s. trivial_limit net ==> trivial_limit(net within s)`,
2142 REWRITE_TAC[trivial_limit; WITHIN] THEN MESON_TAC[]);;
2144 (* ------------------------------------------------------------------------- *)
2145 (* Some property holds "sufficiently close" to the limit point. *)
2146 (* ------------------------------------------------------------------------- *)
2148 let eventually = new_definition
2149 `eventually p net <=>
2150 trivial_limit net \/
2151 ?y. (?x. netord net x y) /\ (!x. netord net x y ==> p x)`;;
2153 let EVENTUALLY_HAPPENS = prove
2154 (`!net p. eventually p net ==> trivial_limit net \/ ?x. p x`,
2155 REWRITE_TAC[eventually] THEN MESON_TAC[]);;
2157 let EVENTUALLY_WITHIN_LE = prove
2159 eventually p (at a within s) <=>
2160 ?d. &0 < d /\ !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d ==> p(x)`,
2161 REWRITE_TAC[eventually; AT; WITHIN; TRIVIAL_LIMIT_WITHIN] THEN
2162 REWRITE_TAC[LIMPT_APPROACHABLE_LE; DIST_NZ] THEN
2163 REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[REAL_LTE_TRANS]; ALL_TAC] THEN
2164 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
2165 MATCH_MP_TAC(TAUT `(a ==> b) ==> ~a \/ b`) THEN DISCH_TAC THEN
2166 SUBGOAL_THEN `?b:real^M. dist(a,b) = d` MP_TAC THENL
2167 [ASM_SIMP_TAC[VECTOR_CHOOSE_DIST; REAL_LT_IMP_LE]; ALL_TAC] THEN
2168 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^M` THEN
2169 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
2170 ASM_MESON_TAC[REAL_NOT_LE; DIST_REFL; DIST_NZ; DIST_SYM]);;
2172 let EVENTUALLY_WITHIN = prove
2174 eventually p (at a within s) <=>
2175 ?d. &0 < d /\ !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d ==> p(x)`,
2176 REWRITE_TAC[EVENTUALLY_WITHIN_LE] THEN
2177 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] THEN
2178 REWRITE_TAC[APPROACHABLE_LT_LE]);;
2180 let EVENTUALLY_AT = prove
2181 (`!a p. eventually p (at a) <=>
2182 ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d ==> p(x)`,
2183 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
2184 REWRITE_TAC[EVENTUALLY_WITHIN; IN_UNIV]);;
2186 let EVENTUALLY_SEQUENTIALLY = prove
2187 (`!p. eventually p sequentially <=> ?N. !n. N <= n ==> p n`,
2188 REWRITE_TAC[eventually; SEQUENTIALLY; GE; LE_REFL;
2189 TRIVIAL_LIMIT_SEQUENTIALLY] THEN MESON_TAC[LE_REFL]);;
2191 let EVENTUALLY_AT_INFINITY = prove
2192 (`!p. eventually p at_infinity <=> ?b. !x. norm(x) >= b ==> p x`,
2193 REWRITE_TAC[eventually; AT_INFINITY; TRIVIAL_LIMIT_AT_INFINITY] THEN
2194 REPEAT GEN_TAC THEN EQ_TAC THENL [MESON_TAC[REAL_LE_REFL]; ALL_TAC] THEN
2195 MESON_TAC[real_ge; REAL_LE_REFL; VECTOR_CHOOSE_SIZE;
2196 REAL_ARITH `&0 <= b \/ (!x. x >= &0 ==> x >= b)`]);;
2198 let ALWAYS_EVENTUALLY = prove
2199 (`(!x. p x) ==> eventually p net`,
2200 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[eventually; trivial_limit] THEN
2203 (* ------------------------------------------------------------------------- *)
2204 (* Combining theorems for "eventually". *)
2205 (* ------------------------------------------------------------------------- *)
2207 let EVENTUALLY_AND = prove
2209 eventually (\x. p x /\ q x) net <=>
2210 eventually p net /\ eventually q net`,
2211 REPEAT GEN_TAC THEN REWRITE_TAC[eventually] THEN
2212 ASM_CASES_TAC `trivial_limit(net:(A net))` THEN ASM_REWRITE_TAC[] THEN
2213 EQ_TAC THEN SIMP_TAC[NET_DILEMMA] THEN MESON_TAC[]);;
2215 let EVENTUALLY_MONO = prove
2217 (!x. p x ==> q x) /\ eventually p net
2218 ==> eventually q net`,
2219 REWRITE_TAC[eventually] THEN MESON_TAC[]);;
2221 let EVENTUALLY_MP = prove
2223 eventually (\x. p x ==> q x) net /\ eventually p net
2224 ==> eventually q net`,
2225 REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
2226 REWRITE_TAC[eventually] THEN MESON_TAC[]);;
2228 let EVENTUALLY_FALSE = prove
2229 (`!net. eventually (\x. F) net <=> trivial_limit net`,
2230 REWRITE_TAC[eventually] THEN MESON_TAC[]);;
2232 let EVENTUALLY_TRUE = prove
2233 (`!net. eventually (\x. T) net <=> T`,
2234 REWRITE_TAC[eventually; trivial_limit] THEN MESON_TAC[]);;
2236 let NOT_EVENTUALLY = prove
2237 (`!net p. (!x. ~(p x)) /\ ~(trivial_limit net) ==> ~(eventually p net)`,
2238 REWRITE_TAC[eventually] THEN MESON_TAC[]);;
2240 let EVENTUALLY_FORALL = prove
2241 (`!net:(A net) p s:B->bool.
2242 FINITE s /\ ~(s = {})
2243 ==> (eventually (\x. !a. a IN s ==> p a x) net <=>
2244 !a. a IN s ==> eventually (p a) net)`,
2245 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
2246 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2247 REWRITE_TAC[FORALL_IN_INSERT; EVENTUALLY_AND; ETA_AX] THEN
2248 MAP_EVERY X_GEN_TAC [`b:B`; `t:B->bool`] THEN
2249 ASM_CASES_TAC `t:B->bool = {}` THEN
2250 ASM_SIMP_TAC[NOT_IN_EMPTY; EVENTUALLY_TRUE]);;
2252 let FORALL_EVENTUALLY = prove
2253 (`!net:(A net) p s:B->bool.
2254 FINITE s /\ ~(s = {})
2255 ==> ((!a. a IN s ==> eventually (p a) net) <=>
2256 eventually (\x. !a. a IN s ==> p a x) net)`,
2257 SIMP_TAC[EVENTUALLY_FORALL]);;
2259 (* ------------------------------------------------------------------------- *)
2260 (* Limits, defined as vacuously true when the limit is trivial. *)
2261 (* ------------------------------------------------------------------------- *)
2263 parse_as_infix("-->",(12,"right"));;
2265 let tendsto = new_definition
2266 `(f --> l) net <=> !e. &0 < e ==> eventually (\x. dist(f(x),l) < e) net`;;
2268 let lim = new_definition
2269 `lim net f = @l. (f --> l) net`;;
2273 trivial_limit net \/
2274 !e. &0 < e ==> ?y. (?x. netord(net) x y) /\
2275 !x. netord(net) x y ==> dist(f(x),l) < e`,
2276 REWRITE_TAC[tendsto; eventually] THEN MESON_TAC[]);;
2278 (* ------------------------------------------------------------------------- *)
2279 (* Show that they yield usual definitions in the various cases. *)
2280 (* ------------------------------------------------------------------------- *)
2282 let LIM_WITHIN_LE = prove
2283 (`!f:real^M->real^N l a s.
2284 (f --> l)(at a within s) <=>
2285 !e. &0 < e ==> ?d. &0 < d /\
2286 !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d
2287 ==> dist(f(x),l) < e`,
2288 REWRITE_TAC[tendsto; EVENTUALLY_WITHIN_LE]);;
2290 let LIM_WITHIN = prove
2291 (`!f:real^M->real^N l a s.
2292 (f --> l) (at a within s) <=>
2295 !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d
2296 ==> dist(f(x),l) < e`,
2297 REWRITE_TAC[tendsto; EVENTUALLY_WITHIN] THEN MESON_TAC[]);;
2300 (`!f l:real^N a:real^M.
2301 (f --> l) (at a) <=>
2303 ==> ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d
2304 ==> dist(f(x),l) < e`,
2305 REWRITE_TAC[tendsto; EVENTUALLY_AT] THEN MESON_TAC[]);;
2307 let LIM_AT_INFINITY = prove
2308 (`!f l. (f --> l) at_infinity <=>
2309 !e. &0 < e ==> ?b. !x. norm(x) >= b ==> dist(f(x),l) < e`,
2310 REWRITE_TAC[tendsto; EVENTUALLY_AT_INFINITY] THEN MESON_TAC[]);;
2312 let LIM_SEQUENTIALLY = prove
2313 (`!s l. (s --> l) sequentially <=>
2314 !e. &0 < e ==> ?N. !n. N <= n ==> dist(s(n),l) < e`,
2315 REWRITE_TAC[tendsto; EVENTUALLY_SEQUENTIALLY] THEN MESON_TAC[]);;
2317 let LIM_EVENTUALLY = prove
2318 (`!net f l. eventually (\x. f x = l) net ==> (f --> l) net`,
2319 REWRITE_TAC[eventually; LIM] THEN MESON_TAC[DIST_REFL]);;
2321 (* ------------------------------------------------------------------------- *)
2322 (* The expected monotonicity property. *)
2323 (* ------------------------------------------------------------------------- *)
2325 let LIM_WITHIN_EMPTY = prove
2326 (`!f l x. (f --> l) (at x within {})`,
2327 REWRITE_TAC[LIM_WITHIN; NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]);;
2329 let LIM_WITHIN_SUBSET = prove
2331 (f --> l) (at a within s) /\ t SUBSET s ==> (f --> l) (at a within t)`,
2332 REWRITE_TAC[LIM_WITHIN; SUBSET] THEN MESON_TAC[]);;
2334 let LIM_UNION = prove
2336 (f --> l) (at x within s) /\ (f --> l) (at x within t)
2337 ==> (f --> l) (at x within (s UNION t))`,
2338 REPEAT GEN_TAC THEN REWRITE_TAC[LIM_WITHIN; IN_UNION] THEN
2339 REWRITE_TAC[AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN
2340 X_GEN_TAC `e:real` THEN ASM_CASES_TAC `&0 < e` THEN ASM_SIMP_TAC[] THEN
2341 DISCH_THEN(CONJUNCTS_THEN2
2342 (X_CHOOSE_TAC `d1:real`) (X_CHOOSE_TAC `d2:real`)) THEN
2343 EXISTS_TAC `min d1 d2` THEN ASM_MESON_TAC[REAL_LT_MIN]);;
2345 let LIM_UNION_UNIV = prove
2347 (f --> l) (at x within s) /\ (f --> l) (at x within t) /\
2348 s UNION t = (:real^N)
2349 ==> (f --> l) (at x)`,
2350 MESON_TAC[LIM_UNION; WITHIN_UNIV]);;
2352 (* ------------------------------------------------------------------------- *)
2353 (* Composition of limits. *)
2354 (* ------------------------------------------------------------------------- *)
2356 let LIM_COMPOSE_WITHIN = prove
2357 (`!net f:real^M->real^N g:real^N->real^P s y z.
2359 eventually (\w. f w IN s /\ (f w = y ==> g y = z)) net /\
2360 (g --> z) (at y within s)
2361 ==> ((g o f) --> z) net`,
2362 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto; CONJ_ASSOC] THEN
2363 ONCE_REWRITE_TAC[LEFT_AND_FORALL_THM] THEN
2364 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2365 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2366 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
2367 REWRITE_TAC[EVENTUALLY_WITHIN; GSYM DIST_NZ; o_DEF] THEN
2368 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
2369 FIRST_X_ASSUM(MP_TAC o SPEC `d:real`) THEN
2370 ASM_REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
2371 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
2372 ASM_MESON_TAC[DIST_REFL]);;
2374 let LIM_COMPOSE_AT = prove
2375 (`!net f:real^M->real^N g:real^N->real^P y z.
2377 eventually (\w. f w = y ==> g y = z) net /\
2379 ==> ((g o f) --> z) net`,
2380 REPEAT STRIP_TAC THEN
2381 MP_TAC(ISPECL [`net:(real^M)net`; `f:real^M->real^N`; `g:real^N->real^P`;
2382 `(:real^N)`; `y:real^N`; `z:real^P`]
2383 LIM_COMPOSE_WITHIN) THEN
2384 ASM_REWRITE_TAC[IN_UNIV; WITHIN_UNIV]);;
2386 (* ------------------------------------------------------------------------- *)
2387 (* Interrelations between restricted and unrestricted limits. *)
2388 (* ------------------------------------------------------------------------- *)
2390 let LIM_AT_WITHIN = prove
2391 (`!f l a s. (f --> l)(at a) ==> (f --> l)(at a within s)`,
2392 REWRITE_TAC[LIM_AT; LIM_WITHIN] THEN MESON_TAC[]);;
2394 let LIM_WITHIN_OPEN = prove
2396 a IN s /\ open s ==> ((f --> l)(at a within s) <=> (f --> l)(at a))`,
2397 REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[LIM_AT_WITHIN] THEN
2398 REWRITE_TAC[LIM_AT; LIM_WITHIN] THEN
2399 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2400 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
2401 DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN
2402 FIRST_X_ASSUM(MP_TAC o SPEC `a:real^M` o GEN_REWRITE_RULE I [open_def]) THEN
2403 ASM_REWRITE_TAC[] THEN
2404 DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN
2405 MP_TAC(SPECL [`d1:real`; `d2:real`] REAL_DOWN2) THEN ASM_REWRITE_TAC[] THEN
2406 ASM_MESON_TAC[REAL_LT_TRANS]);;
2408 (* ------------------------------------------------------------------------- *)
2409 (* More limit point characterizations. *)
2410 (* ------------------------------------------------------------------------- *)
2412 let LIMPT_SEQUENTIAL_INJ = prove
2414 x limit_point_of s <=>
2415 ?f. (!n. f(n) IN (s DELETE x)) /\
2416 (!m n. f m = f n <=> m = n) /\
2417 (f --> x) sequentially`,
2419 REWRITE_TAC[LIMPT_APPROACHABLE; LIM_SEQUENTIALLY; IN_DELETE] THEN
2420 EQ_TAC THENL [ALL_TAC; MESON_TAC[GE; LE_REFL]] THEN
2421 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
2422 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
2423 X_GEN_TAC `y:real->real^N` THEN DISCH_TAC THEN
2424 (STRIP_ASSUME_TAC o prove_recursive_functions_exist num_RECURSION)
2426 (!n. z (SUC n):real^N = y(min (inv(&2 pow (SUC n))) (dist(z n,x))))` THEN
2427 EXISTS_TAC `z:num->real^N` THEN
2429 `!n. z(n) IN s /\ ~(z n:real^N = x) /\ dist(z n,x) < inv(&2 pow n)`
2431 [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
2432 ASM_SIMP_TAC[REAL_LT_01] THEN FIRST_X_ASSUM(MP_TAC o SPEC
2433 `min (inv(&2 pow (SUC n))) (dist(z n:real^N,x))`) THEN
2434 ASM_SIMP_TAC[REAL_LT_MIN; REAL_LT_INV_EQ; REAL_LT_POW2; DIST_POS_LT];
2435 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
2436 [MATCH_MP_TAC WLOG_LT THEN REWRITE_TAC[EQ_SYM_EQ] THEN
2437 SUBGOAL_THEN `!m n:num. m < n ==> dist(z n:real^N,x) < dist(z m,x)`
2438 (fun th -> MESON_TAC[th; REAL_LT_REFL; LT_REFL]) THEN
2439 MATCH_MP_TAC TRANSITIVE_STEPWISE_LT THEN
2440 CONJ_TAC THENL [REAL_ARITH_TAC; GEN_TAC THEN ASM_REWRITE_TAC[]] THEN
2441 FIRST_X_ASSUM(MP_TAC o SPEC
2442 `min (inv(&2 pow (SUC n))) (dist(z n:real^N,x))`) THEN
2443 ASM_SIMP_TAC[REAL_LT_MIN; REAL_LT_INV_EQ; REAL_LT_POW2; DIST_POS_LT];
2444 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2445 MP_TAC(ISPECL [`inv(&2)`; `e:real`] REAL_ARCH_POW_INV) THEN
2446 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN
2447 X_GEN_TAC `N:num` THEN REWRITE_TAC[REAL_POW_INV] THEN DISCH_TAC THEN
2448 X_GEN_TAC `n:num` THEN DISCH_TAC THEN
2449 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
2450 REAL_LT_TRANS)) THEN
2451 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `inv(&2 pow n)` THEN
2452 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
2453 ASM_REWRITE_TAC[REAL_LT_POW2] THEN MATCH_MP_TAC REAL_POW_MONO THEN
2454 REWRITE_TAC[REAL_OF_NUM_LE] THEN ASM_ARITH_TAC]]);;
2456 let LIMPT_SEQUENTIAL = prove
2458 x limit_point_of s <=>
2459 ?f. (!n. f(n) IN (s DELETE x)) /\ (f --> x) sequentially`,
2460 REPEAT GEN_TAC THEN EQ_TAC THENL
2461 [REWRITE_TAC[LIMPT_SEQUENTIAL_INJ] THEN MESON_TAC[];
2462 REWRITE_TAC[LIMPT_APPROACHABLE; LIM_SEQUENTIALLY; IN_DELETE] THEN
2463 MESON_TAC[GE; LE_REFL]]);;
2465 let [LIMPT_INFINITE_OPEN; LIMPT_INFINITE_BALL; LIMPT_INFINITE_CBALL] =
2468 x limit_point_of s <=> !t. x IN t /\ open t ==> INFINITE(s INTER t)) /\
2470 x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER ball(x,e))) /\
2472 x limit_point_of s <=> !e. &0 < e ==> INFINITE(s INTER cball(x,e)))`,
2473 REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
2474 `(q ==> p) /\ (r ==> s) /\ (s ==> q) /\ (p ==> r)
2475 ==> (p <=> q) /\ (p <=> r) /\ (p <=> s)`) THEN
2476 REPEAT CONJ_TAC THENL
2477 [REWRITE_TAC[limit_point_of; INFINITE; SET_RULE
2478 `(?y. ~(y = x) /\ y IN s /\ y IN t) <=> ~(s INTER t SUBSET {x})`] THEN
2479 MESON_TAC[FINITE_SUBSET; FINITE_SING];
2480 MESON_TAC[INFINITE_SUPERSET; BALL_SUBSET_CBALL;
2481 SET_RULE `t SUBSET u ==> s INTER t SUBSET s INTER u`];
2482 MESON_TAC[INFINITE_SUPERSET; OPEN_CONTAINS_CBALL;
2483 SET_RULE `t SUBSET u ==> s INTER t SUBSET s INTER u`];
2484 REWRITE_TAC[LIMPT_SEQUENTIAL_INJ; IN_DELETE; FORALL_AND_THM] THEN
2485 DISCH_THEN(X_CHOOSE_THEN `f:num->real^N` STRIP_ASSUME_TAC) THEN
2486 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2487 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
2488 DISCH_THEN(MP_TAC o SPEC `e:real`) THEN
2489 ASM_REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[DIST_SYM] IN_BALL)] THEN
2490 DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
2491 MATCH_MP_TAC INFINITE_SUPERSET THEN
2492 EXISTS_TAC `IMAGE (f:num->real^N) (from N)` THEN
2493 ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_FROM; IN_INTER] THEN
2494 ASM_MESON_TAC[INFINITE_IMAGE_INJ; INFINITE_FROM]]);;
2496 let INFINITE_OPEN_IN = prove
2497 (`!u s:real^N->bool.
2498 open_in (subtopology euclidean u) s /\ (?x. x IN s /\ x limit_point_of u)
2500 REPEAT STRIP_TAC THEN
2501 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN
2502 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
2503 FIRST_X_ASSUM(MP_TAC o SPEC `t:real^N->bool` o
2504 GEN_REWRITE_RULE I [LIMPT_INFINITE_OPEN]) THEN
2505 FIRST_X_ASSUM SUBST_ALL_TAC THEN ASM SET_TAC[]);;
2507 (* ------------------------------------------------------------------------- *)
2508 (* Condensation points. *)
2509 (* ------------------------------------------------------------------------- *)
2511 parse_as_infix ("condensation_point_of",(12,"right"));;
2513 let condensation_point_of = new_definition
2514 `x condensation_point_of s <=>
2515 !t. x IN t /\ open t ==> ~COUNTABLE(s INTER t)`;;
2517 let CONDENSATION_POINT_IMP_LIMPT = prove
2518 (`!x s. x condensation_point_of s ==> x limit_point_of s`,
2519 REWRITE_TAC[condensation_point_of; LIMPT_INFINITE_OPEN; INFINITE] THEN
2520 MESON_TAC[FINITE_IMP_COUNTABLE]);;
2522 let CONDENSATION_POINT_INFINITE_BALL,CONDENSATION_POINT_INFINITE_CBALL =
2525 x condensation_point_of s <=>
2526 !e. &0 < e ==> ~COUNTABLE(s INTER ball(x,e))) /\
2528 x condensation_point_of s <=>
2529 !e. &0 < e ==> ~COUNTABLE(s INTER cball(x,e)))`,
2530 REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
2531 `(p ==> q) /\ (q ==> r) /\ (r ==> p)
2532 ==> (p <=> q) /\ (p <=> r)`) THEN
2533 REWRITE_TAC[condensation_point_of] THEN REPEAT CONJ_TAC THENL
2534 [MESON_TAC[OPEN_BALL; CENTRE_IN_BALL];
2535 MESON_TAC[BALL_SUBSET_CBALL; COUNTABLE_SUBSET;
2536 SET_RULE `t SUBSET u ==> s INTER t SUBSET s INTER u`];
2537 MESON_TAC[COUNTABLE_SUBSET; OPEN_CONTAINS_CBALL;
2538 SET_RULE `t SUBSET u ==> s INTER t SUBSET s INTER u`]]);;
2540 let LIMPT_OF_CONDENSATION_POINTS = prove
2542 x limit_point_of {y | y condensation_point_of s}
2543 ==> x condensation_point_of s`,
2544 REWRITE_TAC[LIMPT_APPROACHABLE; CONDENSATION_POINT_INFINITE_BALL] THEN
2545 REPEAT GEN_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN
2546 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2547 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
2548 DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN
2549 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
2550 ASM_REWRITE_TAC[REAL_HALF; CONTRAPOS_THM] THEN
2551 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] COUNTABLE_SUBSET) THEN
2552 SIMP_TAC[SUBSET; IN_INTER; IN_BALL] THEN
2553 REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC);;
2555 let CLOSED_CONDENSATION_POINTS = prove
2556 (`!s:real^N->bool. closed {x | x condensation_point_of s}`,
2557 SIMP_TAC[CLOSED_LIMPT; LIMPT_OF_CONDENSATION_POINTS; IN_ELIM_THM]);;
2559 (* ------------------------------------------------------------------------- *)
2560 (* Basic arithmetical combining theorems for limits. *)
2561 (* ------------------------------------------------------------------------- *)
2563 let LIM_LINEAR = prove
2564 (`!net:(A)net h f l.
2565 (f --> l) net /\ linear h ==> ((\x. h(f x)) --> h l) net`,
2566 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
2567 ASM_CASES_TAC `trivial_limit (net:(A)net)` THEN ASM_REWRITE_TAC[] THEN
2568 STRIP_TAC THEN FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o
2569 MATCH_MP LINEAR_BOUNDED_POS) THEN
2570 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2571 FIRST_X_ASSUM(MP_TAC o SPEC `e / B`) THEN
2572 ASM_SIMP_TAC[REAL_LT_DIV; dist; GSYM LINEAR_SUB; REAL_LT_RDIV_EQ] THEN
2573 ASM_MESON_TAC[REAL_LET_TRANS; REAL_MUL_SYM]);;
2575 let LIM_CONST = prove
2576 (`!net a:real^N. ((\x. a) --> a) net`,
2577 SIMP_TAC[LIM; DIST_REFL; trivial_limit] THEN MESON_TAC[]);;
2579 let LIM_CMUL = prove
2580 (`!f l c. (f --> l) net ==> ((\x. c % f x) --> c % l) net`,
2581 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_LINEAR THEN
2582 ASM_REWRITE_TAC[REWRITE_RULE[ETA_AX]
2583 (MATCH_MP LINEAR_COMPOSE_CMUL LINEAR_ID)]);;
2585 let LIM_CMUL_EQ = prove
2587 ~(c = &0) ==> (((\x. c % f x) --> c % l) net <=> (f --> l) net)`,
2588 REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[LIM_CMUL] THEN
2589 DISCH_THEN(MP_TAC o SPEC `inv c:real` o MATCH_MP LIM_CMUL) THEN
2590 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID; ETA_AX]);;
2593 (`!net f l:real^N. (f --> l) net ==> ((\x. --(f x)) --> --l) net`,
2594 REPEAT GEN_TAC THEN REWRITE_TAC[LIM; dist] THEN
2595 REWRITE_TAC[VECTOR_ARITH `--x - --y = --(x - y:real^N)`; NORM_NEG]);;
2597 let LIM_NEG_EQ = prove
2598 (`!net f l:real^N. ((\x. --(f x)) --> --l) net <=> (f --> l) net`,
2599 REPEAT GEN_TAC THEN EQ_TAC THEN
2600 DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG) THEN
2601 REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);;
2604 (`!net:(A)net f g l m.
2605 (f --> l) net /\ (g --> m) net ==> ((\x. f(x) + g(x)) --> l + m) net`,
2606 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
2607 ASM_CASES_TAC `trivial_limit (net:(A)net)` THEN
2608 ASM_REWRITE_TAC[AND_FORALL_THM] THEN
2609 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2610 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
2611 DISCH_THEN(MP_TAC o MATCH_MP NET_DILEMMA) THEN MATCH_MP_TAC MONO_EXISTS THEN
2612 MESON_TAC[REAL_HALF; DIST_TRIANGLE_ADD; REAL_LT_ADD2; REAL_LET_TRANS]);;
2615 (`!net:(A)net f:A->real^N l.
2617 ==> ((\x. lambda i. (abs(f(x)$i))) --> (lambda i. abs(l$i)):real^N) net`,
2618 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
2619 ASM_CASES_TAC `trivial_limit (net:(A)net)` THEN ASM_REWRITE_TAC[] THEN
2620 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
2621 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
2622 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
2623 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
2624 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
2625 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
2626 MATCH_MP_TAC(NORM_ARITH
2627 `norm(x - y) <= norm(a - b) ==> dist(a,b) < e ==> dist(x,y) < e`) THEN
2628 MATCH_MP_TAC NORM_LE_COMPONENTWISE THEN
2629 SIMP_TAC[LAMBDA_BETA; VECTOR_SUB_COMPONENT] THEN
2633 (`!net:(A)net f g l m.
2634 (f --> l) net /\ (g --> m) net ==> ((\x. f(x) - g(x)) --> l - m) net`,
2635 REWRITE_TAC[real_sub; VECTOR_SUB] THEN ASM_SIMP_TAC[LIM_ADD; LIM_NEG]);;
2638 (`!net:(A)net f g l:real^N m:real^N.
2639 (f --> l) net /\ (g --> m) net
2640 ==> ((\x. lambda i. max (f(x)$i) (g(x)$i))
2641 --> (lambda i. max (l$i) (m$i)):real^N) net`,
2642 REPEAT GEN_TAC THEN DISCH_TAC THEN
2643 FIRST_ASSUM(MP_TAC o MATCH_MP LIM_ADD) THEN
2644 FIRST_ASSUM(MP_TAC o MATCH_MP LIM_SUB) THEN
2645 DISCH_THEN(MP_TAC o MATCH_MP LIM_ABS) THEN
2646 REWRITE_TAC[IMP_IMP] THEN
2647 DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN
2648 DISCH_THEN(MP_TAC o SPEC `inv(&2)` o MATCH_MP LIM_CMUL) THEN
2649 MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THEN
2650 SIMP_TAC[FUN_EQ_THM; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
2651 VECTOR_SUB_COMPONENT; LAMBDA_BETA] THEN
2655 (`!net:(A)net f g l:real^N m:real^N.
2656 (f --> l) net /\ (g --> m) net
2657 ==> ((\x. lambda i. min (f(x)$i) (g(x)$i))
2658 --> (lambda i. min (l$i) (m$i)):real^N) net`,
2660 DISCH_THEN(CONJUNCTS_THEN(MP_TAC o MATCH_MP LIM_NEG)) THEN
2661 REWRITE_TAC[IMP_IMP] THEN
2662 DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG o MATCH_MP LIM_MAX) THEN
2663 MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THEN
2664 SIMP_TAC[FUN_EQ_THM; CART_EQ; LAMBDA_BETA; VECTOR_NEG_COMPONENT] THEN
2667 let LIM_NORM = prove
2668 (`!net f:A->real^N l.
2669 (f --> l) net ==> ((\x. lift(norm(f x))) --> lift(norm l)) net`,
2670 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto; DIST_LIFT] THEN
2671 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
2673 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
2674 REWRITE_TAC[] THEN NORM_ARITH_TAC);;
2676 let LIM_NULL = prove
2677 (`!net f l. (f --> l) net <=> ((\x. f(x) - l) --> vec 0) net`,
2678 REWRITE_TAC[LIM; dist; VECTOR_SUB_RZERO]);;
2680 let LIM_NULL_NORM = prove
2681 (`!net f. (f --> vec 0) net <=> ((\x. lift(norm(f x))) --> vec 0) net`,
2682 REWRITE_TAC[LIM; dist; VECTOR_SUB_RZERO; REAL_ABS_NORM; NORM_LIFT]);;
2684 let LIM_NULL_CMUL_EQ = prove
2686 ~(c = &0) ==> (((\x. c % f x) --> vec 0) net <=> (f --> vec 0) net)`,
2687 MESON_TAC[LIM_CMUL_EQ; VECTOR_MUL_RZERO]);;
2689 let LIM_NULL_COMPARISON = prove
2690 (`!net f g. eventually (\x. norm(f x) <= g x) net /\
2691 ((\x. lift(g x)) --> vec 0) net
2692 ==> (f --> vec 0) net`,
2693 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto; RIGHT_AND_FORALL_THM] THEN
2694 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2695 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
2696 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
2697 REWRITE_TAC[dist; VECTOR_SUB_RZERO; NORM_LIFT] THEN REAL_ARITH_TAC);;
2699 let LIM_COMPONENT = prove
2700 (`!net f i l:real^N. (f --> l) net /\ 1 <= i /\ i <= dimindex(:N)
2701 ==> ((\a. lift(f(a)$i)) --> lift(l$i)) net`,
2702 REWRITE_TAC[LIM; dist; GSYM LIFT_SUB; NORM_LIFT] THEN
2703 SIMP_TAC[GSYM VECTOR_SUB_COMPONENT] THEN
2704 MESON_TAC[COMPONENT_LE_NORM; REAL_LET_TRANS]);;
2706 let LIM_TRANSFORM_BOUND = prove
2707 (`!f g. eventually (\n. norm(f n) <= norm(g n)) net /\ (g --> vec 0) net
2708 ==> (f --> vec 0) net`,
2710 REWRITE_TAC[tendsto; RIGHT_AND_FORALL_THM] THEN
2711 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2712 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
2713 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
2714 REWRITE_TAC[dist; VECTOR_SUB_RZERO] THEN REAL_ARITH_TAC);;
2716 let LIM_NULL_CMUL_BOUNDED = prove
2718 eventually (\a. g a = vec 0 \/ abs(f a) <= B) net /\
2720 ==> ((\n. f n % g n) --> vec 0) net`,
2721 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto] THEN STRIP_TAC THEN
2722 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2723 FIRST_X_ASSUM(MP_TAC o SPEC `e / (abs B + &1)`) THEN
2724 ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < abs x + &1`] THEN
2725 UNDISCH_TAC `eventually (\a. g a:real^N = vec 0 \/ abs(f a) <= B)
2727 REWRITE_TAC[IMP_IMP; GSYM EVENTUALLY_AND] THEN
2728 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MP) THEN
2729 REWRITE_TAC[dist; VECTOR_SUB_RZERO; o_THM; NORM_LIFT; NORM_MUL] THEN
2730 MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `x:A` THEN REWRITE_TAC[] THEN
2731 ASM_CASES_TAC `(g:A->real^N) x = vec 0` THEN
2732 ASM_REWRITE_TAC[NORM_0; REAL_MUL_RZERO] THEN
2733 STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
2734 EXISTS_TAC `B * e / (abs B + &1)` THEN
2735 ASM_SIMP_TAC[REAL_LE_MUL2; REAL_ABS_POS; NORM_POS_LE; REAL_LT_IMP_LE] THEN
2736 REWRITE_TAC[REAL_ARITH `c * (a / b) = (c * a) / b`] THEN
2737 SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 < abs x + &1`] THEN
2738 MATCH_MP_TAC(REAL_ARITH
2739 `e * B <= e * abs B /\ &0 < e ==> B * e < e * (abs B + &1)`) THEN
2740 ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN REAL_ARITH_TAC);;
2742 let LIM_NULL_VMUL_BOUNDED = prove
2744 ((lift o f) --> vec 0) net /\
2745 eventually (\a. f a = &0 \/ norm(g a) <= B) net
2746 ==> ((\n. f n % g n) --> vec 0) net`,
2747 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto] THEN STRIP_TAC THEN
2748 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2749 FIRST_X_ASSUM(MP_TAC o SPEC `e / (abs B + &1)`) THEN
2750 ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < abs x + &1`] THEN
2751 UNDISCH_TAC `eventually(\a. f a = &0 \/ norm((g:A->real^N) a) <= B) net` THEN
2752 REWRITE_TAC[IMP_IMP; GSYM EVENTUALLY_AND] THEN
2753 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MP) THEN
2754 REWRITE_TAC[dist; VECTOR_SUB_RZERO; o_THM; NORM_LIFT; NORM_MUL] THEN
2755 MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `x:A` THEN REWRITE_TAC[] THEN
2756 ASM_CASES_TAC `(f:A->real) x = &0` THEN
2757 ASM_REWRITE_TAC[REAL_ABS_NUM; REAL_MUL_LZERO] THEN
2758 STRIP_TAC THEN MATCH_MP_TAC REAL_LET_TRANS THEN
2759 EXISTS_TAC `e / (abs B + &1) * B` THEN
2760 ASM_SIMP_TAC[REAL_LE_MUL2; REAL_ABS_POS; NORM_POS_LE; REAL_LT_IMP_LE] THEN
2761 REWRITE_TAC[REAL_ARITH `(a / b) * c = (a * c) / b`] THEN
2762 SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 < abs x + &1`] THEN
2763 MATCH_MP_TAC(REAL_ARITH
2764 `e * B <= e * abs B /\ &0 < e ==> e * B < e * (abs B + &1)`) THEN
2765 ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN REAL_ARITH_TAC);;
2767 let LIM_VSUM = prove
2768 (`!f:A->B->real^N s.
2769 FINITE s /\ (!i. i IN s ==> ((f i) --> (l i)) net)
2770 ==> ((\x. vsum s (\i. f i x)) --> vsum s l) net`,
2771 GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
2772 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2773 SIMP_TAC[VSUM_CLAUSES; LIM_CONST; LIM_ADD; IN_INSERT; ETA_AX]);;
2775 (* ------------------------------------------------------------------------- *)
2776 (* Deducing things about the limit from the elements. *)
2777 (* ------------------------------------------------------------------------- *)
2779 let LIM_IN_CLOSED_SET = prove
2780 (`!net f:A->real^N s l.
2781 closed s /\ eventually (\x. f(x) IN s) net /\
2782 ~(trivial_limit net) /\ (f --> l) net
2784 REWRITE_TAC[closed] THEN REPEAT STRIP_TAC THEN
2785 MATCH_MP_TAC(SET_RULE `~(x IN (UNIV DIFF s)) ==> x IN s`) THEN
2787 FIRST_ASSUM(MP_TAC o SPEC `l:real^N` o GEN_REWRITE_RULE I
2788 [OPEN_CONTAINS_BALL]) THEN
2789 ASM_REWRITE_TAC[SUBSET; IN_BALL; IN_DIFF; IN_UNION] THEN
2790 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
2791 FIRST_X_ASSUM(MP_TAC o SPEC `e:real` o GEN_REWRITE_RULE I [tendsto]) THEN
2792 UNDISCH_TAC `eventually (\x. (f:A->real^N) x IN s) net` THEN
2793 ASM_REWRITE_TAC[GSYM EVENTUALLY_AND; TAUT `a ==> ~b <=> ~(a /\ b)`] THEN
2794 MATCH_MP_TAC NOT_EVENTUALLY THEN ASM_MESON_TAC[DIST_SYM]);;
2796 (* ------------------------------------------------------------------------- *)
2797 (* Need to prove closed(cball(x,e)) before deducing this as a corollary. *)
2798 (* ------------------------------------------------------------------------- *)
2800 let LIM_NORM_UBOUND = prove
2801 (`!net:(A)net f (l:real^N) b.
2802 ~(trivial_limit net) /\
2804 eventually (\x. norm(f x) <= b) net
2806 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2807 ASM_REWRITE_TAC[LIM] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2808 ASM_REWRITE_TAC[eventually] THEN
2809 STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
2810 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN
2812 `?x:A. dist(f(x):real^N,l) < norm(l:real^N) - b /\ norm(f x) <= b`
2813 (CHOOSE_THEN MP_TAC) THENL [ASM_MESON_TAC[NET]; ALL_TAC] THEN
2814 REWRITE_TAC[REAL_NOT_LT; REAL_LE_SUB_RADD; DE_MORGAN_THM; dist] THEN
2817 let LIM_NORM_LBOUND = prove
2818 (`!net:(A)net f (l:real^N) b.
2819 ~(trivial_limit net) /\ (f --> l) net /\
2820 eventually (\x. b <= norm(f x)) net
2822 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2823 ASM_REWRITE_TAC[LIM] THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2824 ASM_REWRITE_TAC[eventually] THEN
2825 STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
2826 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN
2828 `?x:A. dist(f(x):real^N,l) < b - norm(l:real^N) /\ b <= norm(f x)`
2829 (CHOOSE_THEN MP_TAC) THENL [ASM_MESON_TAC[NET]; ALL_TAC] THEN
2830 REWRITE_TAC[REAL_NOT_LT; REAL_LE_SUB_RADD; DE_MORGAN_THM; dist] THEN
2833 (* ------------------------------------------------------------------------- *)
2834 (* Uniqueness of the limit, when nontrivial. *)
2835 (* ------------------------------------------------------------------------- *)
2837 let LIM_UNIQUE = prove
2838 (`!net:(A)net f l:real^N l'.
2839 ~(trivial_limit net) /\ (f --> l) net /\ (f --> l') net ==> (l = l')`,
2840 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2841 DISCH_THEN(ASSUME_TAC o REWRITE_RULE[VECTOR_SUB_REFL] o MATCH_MP LIM_SUB) THEN
2842 SUBGOAL_THEN `!e. &0 < e ==> norm(l:real^N - l') <= e` MP_TAC THENL
2843 [GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC LIM_NORM_UBOUND THEN
2844 MAP_EVERY EXISTS_TAC [`net:(A)net`; `\x:A. vec 0 : real^N`] THEN
2845 ASM_SIMP_TAC[NORM_0; REAL_LT_IMP_LE; eventually] THEN
2846 ASM_MESON_TAC[trivial_limit];
2847 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[DIST_NZ; dist] THEN
2848 DISCH_TAC THEN DISCH_THEN(MP_TAC o SPEC `norm(l - l':real^N) / &2`) THEN
2849 ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_LE_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
2850 UNDISCH_TAC `&0 < norm(l - l':real^N)` THEN REAL_ARITH_TAC]);;
2852 let TENDSTO_LIM = prove
2853 (`!net f l. ~(trivial_limit net) /\ (f --> l) net ==> lim net f = l`,
2854 REWRITE_TAC[lim] THEN MESON_TAC[LIM_UNIQUE]);;
2856 let LIM_CONST_EQ = prove
2857 (`!net:(A net) c d:real^N.
2858 ((\x. c) --> d) net <=> trivial_limit net \/ c = d`,
2860 ASM_CASES_TAC `trivial_limit (net:A net)` THEN ASM_REWRITE_TAC[] THENL
2861 [ASM_REWRITE_TAC[LIM]; ALL_TAC] THEN
2862 EQ_TAC THEN SIMP_TAC[LIM_CONST] THEN DISCH_TAC THEN
2863 MATCH_MP_TAC(SPEC `net:A net` LIM_UNIQUE) THEN
2864 EXISTS_TAC `(\x. c):A->real^N` THEN ASM_REWRITE_TAC[LIM_CONST]);;
2866 (* ------------------------------------------------------------------------- *)
2867 (* Some unwieldy but occasionally useful theorems about uniform limits. *)
2868 (* ------------------------------------------------------------------------- *)
2870 let UNIFORM_LIM_ADD = prove
2871 (`!net:(A)net P f g l m.
2873 ==> eventually (\x. !n:B. P n ==> norm(f n x - l n) < e) net) /\
2875 ==> eventually (\x. !n. P n ==> norm(g n x - m n) < e) net)
2879 ==> norm((f n x + g n x) - (l n + m n)) < e)
2881 REPEAT GEN_TAC THEN REWRITE_TAC[AND_FORALL_THM] THEN DISCH_TAC THEN
2882 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2883 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
2884 ASM_REWRITE_TAC[REAL_HALF; GSYM EVENTUALLY_AND] THEN
2885 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
2886 GEN_TAC THEN REWRITE_TAC[AND_FORALL_THM] THEN
2887 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:B` THEN
2888 ASM_CASES_TAC `(P:B->bool) n` THEN ASM_REWRITE_TAC[] THEN
2889 CONV_TAC NORM_ARITH);;
2891 let UNIFORM_LIM_SUB = prove
2892 (`!net:(A)net P f g l m.
2894 ==> eventually (\x. !n:B. P n ==> norm(f n x - l n) < e) net) /\
2896 ==> eventually (\x. !n. P n ==> norm(g n x - m n) < e) net)
2900 ==> norm((f n x - g n x) - (l n - m n)) < e)
2902 REPEAT GEN_TAC THEN REWRITE_TAC[AND_FORALL_THM] THEN DISCH_TAC THEN
2903 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2904 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
2905 ASM_REWRITE_TAC[REAL_HALF; GSYM EVENTUALLY_AND] THEN
2906 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
2907 GEN_TAC THEN REWRITE_TAC[AND_FORALL_THM] THEN
2908 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:B` THEN
2909 ASM_CASES_TAC `(P:B->bool) n` THEN ASM_REWRITE_TAC[] THEN
2910 CONV_TAC NORM_ARITH);;
2912 (* ------------------------------------------------------------------------- *)
2913 (* Limit under bilinear function, uniform version first. *)
2914 (* ------------------------------------------------------------------------- *)
2916 let UNIFORM_LIM_BILINEAR = prove
2917 (`!net:(A)net P (h:real^M->real^N->real^P) f g l m b1 b2.
2919 eventually (\x. !n. P n ==> norm(l n) <= b1) net /\
2920 eventually (\x. !n. P n ==> norm(m n) <= b2) net /\
2922 ==> eventually (\x. !n:B. P n ==> norm(f n x - l n) < e) net) /\
2924 ==> eventually (\x. !n. P n ==> norm(g n x - m n) < e) net)
2928 ==> norm(h (f n x) (g n x) - h (l n) (m n)) < e)
2931 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2932 FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o MATCH_MP
2933 BILINEAR_BOUNDED_POS) THEN
2934 REWRITE_TAC[AND_FORALL_THM; RIGHT_AND_FORALL_THM] THEN DISCH_TAC THEN
2935 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2936 FIRST_X_ASSUM(MP_TAC o SPEC
2937 `min (abs b2 + &1) (e / &2 / (B * (abs b1 + abs b2 + &2)))`) THEN
2938 ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; REAL_LT_MUL; REAL_LT_MIN;
2939 REAL_ARITH `&0 < abs x + &1`;
2940 REAL_ARITH `&0 < abs x + abs y + &2`] THEN
2941 REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
2942 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
2943 X_GEN_TAC `x:A` THEN REWRITE_TAC[AND_FORALL_THM] THEN
2944 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:B` THEN
2945 ASM_CASES_TAC `(P:B->bool) n` THEN ASM_REWRITE_TAC[] THEN
2947 ONCE_REWRITE_TAC[VECTOR_ARITH
2948 `h a b - h c d :real^N = (h a b - h a d) + (h a d - h c d)`] THEN
2949 ASM_SIMP_TAC[GSYM BILINEAR_LSUB; GSYM BILINEAR_RSUB] THEN
2950 MATCH_MP_TAC NORM_TRIANGLE_LT THEN
2951 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
2952 (MESON[REAL_LE_ADD2; REAL_LET_TRANS]
2953 `(!x y. norm(h x y:real^P) <= B * norm x * norm y)
2954 ==> B * norm a * norm b + B * norm c * norm d < e
2955 ==> norm(h a b) + norm(h c d) < e`)) THEN
2956 MATCH_MP_TAC(REAL_ARITH
2957 `x * B < e / &2 /\ y * B < e / &2 ==> B * x + B * y < e`) THEN
2958 CONJ_TAC THEN ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THENL
2959 [ONCE_REWRITE_TAC[REAL_MUL_SYM]; ALL_TAC] THEN
2960 MATCH_MP_TAC REAL_LET_TRANS THEN
2961 EXISTS_TAC `e / &2 / (B * (abs b1 + abs b2 + &2)) *
2962 (abs b1 + abs b2 + &1)` THEN
2964 [MATCH_MP_TAC REAL_LE_MUL2 THEN
2965 ASM_SIMP_TAC[NORM_POS_LE; REAL_LT_IMP_LE] THEN
2966 ASM_SIMP_TAC[REAL_ARITH `a <= b2 ==> a <= abs b1 + abs b2 + &1`] THEN
2967 ASM_MESON_TAC[NORM_ARITH
2968 `norm(f - l:real^P) < abs b2 + &1 /\ norm(l) <= b1
2969 ==> norm(f) <= abs b1 + abs b2 + &1`];
2970 ONCE_REWRITE_TAC[real_div] THEN
2971 ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_HALF; GSYM REAL_MUL_ASSOC;
2973 REWRITE_TAC[REAL_ARITH `B * inv x * y < B <=> B * y / x < B * &1`] THEN
2974 ASM_SIMP_TAC[REAL_LT_INV_EQ; REAL_LT_LMUL_EQ; REAL_LT_LDIV_EQ;
2975 REAL_ARITH `&0 < abs x + abs y + &2`] THEN
2978 let LIM_BILINEAR = prove
2979 (`!net:(A)net (h:real^M->real^N->real^P) f g l m.
2980 (f --> l) net /\ (g --> m) net /\ bilinear h
2981 ==> ((\x. h (f x) (g x)) --> (h l m)) net`,
2982 REPEAT STRIP_TAC THEN
2984 [`net:(A)net`; `\x:one. T`; `h:real^M->real^N->real^P`;
2985 `\n:one. (f:A->real^M)`; `\n:one. (g:A->real^N)`;
2986 `\n:one. (l:real^M)`; `\n:one. (m:real^N)`;
2987 `norm(l:real^M)`; `norm(m:real^N)`]
2988 UNIFORM_LIM_BILINEAR) THEN
2989 ASM_REWRITE_TAC[REAL_LE_REFL; EVENTUALLY_TRUE] THEN
2990 ASM_REWRITE_TAC[GSYM dist; GSYM tendsto]);;
2992 (* ------------------------------------------------------------------------- *)
2993 (* These are special for limits out of the same vector space. *)
2994 (* ------------------------------------------------------------------------- *)
2996 let LIM_WITHIN_ID = prove
2997 (`!a s. ((\x. x) --> a) (at a within s)`,
2998 REWRITE_TAC[LIM_WITHIN] THEN MESON_TAC[]);;
3000 let LIM_AT_ID = prove
3001 (`!a. ((\x. x) --> a) (at a)`,
3002 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN REWRITE_TAC[LIM_WITHIN_ID]);;
3004 let LIM_AT_ZERO = prove
3005 (`!f:real^M->real^N l a.
3006 (f --> l) (at a) <=> ((\x. f(a + x)) --> l) (at(vec 0))`,
3007 REPEAT GEN_TAC THEN REWRITE_TAC[LIM_AT] THEN
3008 AP_TERM_TAC THEN ABS_TAC THEN
3009 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
3010 AP_TERM_TAC THEN ABS_TAC THEN
3011 ASM_CASES_TAC `&0 < d` THEN ASM_REWRITE_TAC[] THEN
3012 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `x:real^M` THENL
3013 [FIRST_X_ASSUM(MP_TAC o SPEC `a + x:real^M`) THEN
3014 REWRITE_TAC[dist; VECTOR_ADD_SUB; VECTOR_SUB_RZERO];
3015 FIRST_X_ASSUM(MP_TAC o SPEC `x - a:real^M`) THEN
3016 REWRITE_TAC[dist; VECTOR_SUB_RZERO; VECTOR_SUB_ADD2]]);;
3018 (* ------------------------------------------------------------------------- *)
3019 (* It's also sometimes useful to extract the limit point from the net. *)
3020 (* ------------------------------------------------------------------------- *)
3022 let netlimit = new_definition
3023 `netlimit net = @a. !x. ~(netord net x a)`;;
3025 let NETLIMIT_WITHIN = prove
3026 (`!a:real^N s. ~(trivial_limit (at a within s))
3027 ==> (netlimit (at a within s) = a)`,
3028 REWRITE_TAC[trivial_limit; netlimit; AT; WITHIN; DE_MORGAN_THM] THEN
3029 REPEAT STRIP_TAC THEN MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN
3031 `!x:real^N. ~(&0 < dist(x,a) /\ dist(x,a) <= dist(a,a) /\ x IN s)`
3033 [ASM_MESON_TAC[DIST_REFL; REAL_NOT_LT]; ASM_MESON_TAC[]]);;
3035 let NETLIMIT_AT = prove
3036 (`!a. netlimit(at a) = a`,
3037 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
3038 MATCH_MP_TAC NETLIMIT_WITHIN THEN
3039 SIMP_TAC[TRIVIAL_LIMIT_AT; WITHIN_UNIV]);;
3041 (* ------------------------------------------------------------------------- *)
3042 (* Transformation of limit. *)
3043 (* ------------------------------------------------------------------------- *)
3045 let LIM_TRANSFORM = prove
3047 ((\x. f x - g x) --> vec 0) net /\ (f --> l) net ==> (g --> l) net`,
3048 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN
3049 DISCH_THEN(MP_TAC o MATCH_MP LIM_NEG) THEN MATCH_MP_TAC EQ_IMP THEN
3050 AP_THM_TAC THEN BINOP_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN
3053 let LIM_TRANSFORM_EVENTUALLY = prove
3055 eventually (\x. f x = g x) net /\ (f --> l) net ==> (g --> l) net`,
3056 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
3057 DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o MATCH_MP LIM_EVENTUALLY) MP_TAC) THEN
3058 MESON_TAC[LIM_TRANSFORM]);;
3060 let LIM_TRANSFORM_WITHIN = prove
3063 (!x'. x' IN s /\ &0 < dist(x',x) /\ dist(x',x) < d ==> f(x') = g(x')) /\
3064 (f --> l) (at x within s)
3065 ==> (g --> l) (at x within s)`,
3066 REPEAT GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
3067 DISCH_TAC THEN DISCH_TAC THEN
3068 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM) THEN
3069 REWRITE_TAC[LIM_WITHIN] THEN REPEAT STRIP_TAC THEN EXISTS_TAC `d:real` THEN
3070 ASM_SIMP_TAC[VECTOR_SUB_REFL; DIST_REFL]);;
3072 let LIM_TRANSFORM_AT = prove
3075 (!x'. &0 < dist(x',x) /\ dist(x',x) < d ==> f(x') = g(x')) /\
3077 ==> (g --> l) (at x)`,
3078 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN MESON_TAC[LIM_TRANSFORM_WITHIN]);;
3080 let LIM_TRANSFORM_EQ = prove
3081 (`!net f:A->real^N g l.
3082 ((\x. f x - g x) --> vec 0) net ==> ((f --> l) net <=> (g --> l) net)`,
3083 REPEAT STRIP_TAC THEN EQ_TAC THEN
3084 DISCH_TAC THEN MATCH_MP_TAC LIM_TRANSFORM THENL
3085 [EXISTS_TAC `f:A->real^N` THEN ASM_REWRITE_TAC[];
3086 EXISTS_TAC `g:A->real^N` THEN ASM_REWRITE_TAC[] THEN
3087 ONCE_REWRITE_TAC[GSYM LIM_NEG_EQ] THEN
3088 ASM_REWRITE_TAC[VECTOR_NEG_SUB; VECTOR_NEG_0]]);;
3090 let LIM_TRANSFORM_WITHIN_SET = prove
3092 eventually (\x. x IN s <=> x IN t) (at a)
3093 ==> ((f --> l) (at a within s) <=> (f --> l) (at a within t))`,
3094 REPEAT GEN_TAC THEN REWRITE_TAC[EVENTUALLY_AT; LIM_WITHIN] THEN
3095 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
3096 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3097 FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
3098 DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
3099 EXISTS_TAC `min d k:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
3102 (* ------------------------------------------------------------------------- *)
3103 (* Common case assuming being away from some crucial point like 0. *)
3104 (* ------------------------------------------------------------------------- *)
3106 let LIM_TRANSFORM_AWAY_WITHIN = prove
3107 (`!f:real^M->real^N g a b s.
3109 (!x. x IN s /\ ~(x = a) /\ ~(x = b) ==> f(x) = g(x)) /\
3110 (f --> l) (at a within s)
3111 ==> (g --> l) (at a within s)`,
3112 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN
3113 MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `dist(a:real^M,b)`] THEN
3114 ASM_REWRITE_TAC[GSYM DIST_NZ] THEN X_GEN_TAC `y:real^M` THEN
3115 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
3116 ASM_MESON_TAC[DIST_SYM; REAL_LT_REFL]);;
3118 let LIM_TRANSFORM_AWAY_AT = prove
3119 (`!f:real^M->real^N g a b.
3121 (!x. ~(x = a) /\ ~(x = b) ==> f(x) = g(x)) /\
3123 ==> (g --> l) (at a)`,
3124 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
3125 MESON_TAC[LIM_TRANSFORM_AWAY_WITHIN]);;
3127 (* ------------------------------------------------------------------------- *)
3128 (* Alternatively, within an open set. *)
3129 (* ------------------------------------------------------------------------- *)
3131 let LIM_TRANSFORM_WITHIN_OPEN = prove
3132 (`!f g:real^M->real^N s a.
3134 (!x. x IN s /\ ~(x = a) ==> f x = g x) /\
3136 ==> (g --> l) (at a)`,
3137 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_AT THEN
3138 EXISTS_TAC `f:real^M->real^N` THEN ASM_REWRITE_TAC[] THEN
3139 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN
3140 DISCH_THEN(MP_TAC o SPEC `a:real^M`) THEN ASM_REWRITE_TAC[] THEN
3141 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[SUBSET; IN_BALL] THEN
3142 ASM_MESON_TAC[DIST_NZ; DIST_SYM]);;
3144 (* ------------------------------------------------------------------------- *)
3145 (* Another quite common idiom of an explicit conditional in a sequence. *)
3146 (* ------------------------------------------------------------------------- *)
3148 let LIM_CASES_FINITE_SEQUENTIALLY = prove
3149 (`!f g l. FINITE {n | P n}
3150 ==> (((\n. if P n then f n else g n) --> l) sequentially <=>
3151 (g --> l) sequentially)`,
3152 REPEAT STRIP_TAC THEN EQ_TAC THEN
3153 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN
3154 FIRST_ASSUM(MP_TAC o SPEC `\n:num. n` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN
3155 REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
3156 X_GEN_TAC `N:num` THEN DISCH_TAC THEN SIMP_TAC[EVENTUALLY_SEQUENTIALLY] THEN
3157 EXISTS_TAC `N + 1` THEN
3158 ASM_MESON_TAC[ARITH_RULE `~(x <= n /\ n + 1 <= x)`]);;
3160 let LIM_CASES_COFINITE_SEQUENTIALLY = prove
3161 (`!f g l. FINITE {n | ~P n}
3162 ==> (((\n. if P n then f n else g n) --> l) sequentially <=>
3163 (f --> l) sequentially)`,
3164 ONCE_REWRITE_TAC[TAUT `(if p then x else y) = (if ~p then y else x)`] THEN
3165 REWRITE_TAC[LIM_CASES_FINITE_SEQUENTIALLY]);;
3167 let LIM_CASES_SEQUENTIALLY = prove
3168 (`!f g l m. (((\n. if m <= n then f n else g n) --> l) sequentially <=>
3169 (f --> l) sequentially) /\
3170 (((\n. if m < n then f n else g n) --> l) sequentially <=>
3171 (f --> l) sequentially) /\
3172 (((\n. if n <= m then f n else g n) --> l) sequentially <=>
3173 (g --> l) sequentially) /\
3174 (((\n. if n < m then f n else g n) --> l) sequentially <=>
3175 (g --> l) sequentially)`,
3176 SIMP_TAC[LIM_CASES_FINITE_SEQUENTIALLY; LIM_CASES_COFINITE_SEQUENTIALLY;
3177 NOT_LE; NOT_LT; FINITE_NUMSEG_LT; FINITE_NUMSEG_LE]);;
3179 (* ------------------------------------------------------------------------- *)
3180 (* A congruence rule allowing us to transform limits assuming not at point. *)
3181 (* ------------------------------------------------------------------------- *)
3183 let LIM_CONG_WITHIN = prove
3184 (`(!x. ~(x = a) ==> f x = g x)
3185 ==> (((\x. f x) --> l) (at a within s) <=> ((g --> l) (at a within s)))`,
3186 REWRITE_TAC[LIM_WITHIN; GSYM DIST_NZ] THEN SIMP_TAC[]);;
3188 let LIM_CONG_AT = prove
3189 (`(!x. ~(x = a) ==> f x = g x)
3190 ==> (((\x. f x) --> l) (at a) <=> ((g --> l) (at a)))`,
3191 REWRITE_TAC[LIM_AT; GSYM DIST_NZ] THEN SIMP_TAC[]);;
3193 extend_basic_congs [LIM_CONG_WITHIN; LIM_CONG_AT];;
3195 (* ------------------------------------------------------------------------- *)
3196 (* Useful lemmas on closure and set of possible sequential limits. *)
3197 (* ------------------------------------------------------------------------- *)
3199 let CLOSURE_SEQUENTIAL = prove
3201 l IN closure(s) <=> ?x. (!n. x(n) IN s) /\ (x --> l) sequentially`,
3202 REWRITE_TAC[closure; IN_UNION; LIMPT_SEQUENTIAL; IN_ELIM_THM; IN_DELETE] THEN
3203 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
3204 `((b ==> c) /\ (~a /\ c ==> b)) /\ (a ==> c) ==> (a \/ b <=> c)`) THEN
3205 CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN DISCH_TAC THEN
3206 EXISTS_TAC `\n:num. l:real^N` THEN
3207 ASM_REWRITE_TAC[LIM_CONST]);;
3209 let CLOSED_CONTAINS_SEQUENTIAL_LIMIT = prove
3211 closed s /\ (!n. x n IN s) /\ (x --> l) sequentially ==> l IN s`,
3212 MESON_TAC[CLOSURE_SEQUENTIAL; CLOSURE_CLOSED]);;
3214 let CLOSED_SEQUENTIAL_LIMITS = prove
3216 !x l. (!n. x(n) IN s) /\ (x --> l) sequentially ==> l IN s`,
3217 MESON_TAC[CLOSURE_SEQUENTIAL; CLOSURE_CLOSED;
3218 CLOSED_LIMPT; LIMPT_SEQUENTIAL; IN_DELETE]);;
3220 let CLOSURE_APPROACHABLE = prove
3221 (`!x s. x IN closure(s) <=> !e. &0 < e ==> ?y. y IN s /\ dist(y,x) < e`,
3222 REWRITE_TAC[closure; LIMPT_APPROACHABLE; IN_UNION; IN_ELIM_THM] THEN
3223 MESON_TAC[DIST_REFL]);;
3225 let CLOSED_APPROACHABLE = prove
3227 ==> ((!e. &0 < e ==> ?y. y IN s /\ dist(y,x) < e) <=> x IN s)`,
3228 MESON_TAC[CLOSURE_CLOSED; CLOSURE_APPROACHABLE]);;
3230 let IN_CLOSURE_DELETE = prove
3231 (`!s x:real^N. x IN closure(s DELETE x) <=> x limit_point_of s`,
3232 SIMP_TAC[CLOSURE_APPROACHABLE; LIMPT_APPROACHABLE; IN_DELETE; CONJ_ASSOC]);;
3234 (* ------------------------------------------------------------------------- *)
3235 (* Some other lemmas about sequences. *)
3236 (* ------------------------------------------------------------------------- *)
3238 let SEQ_OFFSET = prove
3239 (`!f l k. (f --> l) sequentially ==> ((\i. f(i + k)) --> l) sequentially`,
3240 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
3241 MESON_TAC[ARITH_RULE `N <= n ==> N <= n + k:num`]);;
3243 let SEQ_OFFSET_NEG = prove
3244 (`!f l k. (f --> l) sequentially ==> ((\i. f(i - k)) --> l) sequentially`,
3245 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
3246 MESON_TAC[ARITH_RULE `N + k <= n ==> N <= n - k:num`]);;
3248 let SEQ_OFFSET_REV = prove
3249 (`!f l k. ((\i. f(i + k)) --> l) sequentially ==> (f --> l) sequentially`,
3250 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
3251 MESON_TAC[ARITH_RULE `N + k <= n ==> N <= n - k /\ (n - k) + k = n:num`]);;
3253 let SEQ_HARMONIC = prove
3254 (`((\n. lift(inv(&n))) --> vec 0) sequentially`,
3255 REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3256 FIRST_ASSUM(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC o
3257 GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN
3258 EXISTS_TAC `N:num` THEN REPEAT STRIP_TAC THEN
3259 REWRITE_TAC[dist; VECTOR_SUB_RZERO; NORM_LIFT] THEN
3260 ASM_REWRITE_TAC[REAL_ABS_INV; REAL_ABS_NUM] THEN
3261 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN
3262 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
3263 ASM_REWRITE_TAC[REAL_OF_NUM_LT; REAL_OF_NUM_LE; LT_NZ]);;
3265 (* ------------------------------------------------------------------------- *)
3266 (* More properties of closed balls. *)
3267 (* ------------------------------------------------------------------------- *)
3269 let CLOSED_CBALL = prove
3270 (`!x:real^N e. closed(cball(x,e))`,
3271 REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS; IN_CBALL; dist] THEN
3272 GEN_TAC THEN GEN_TAC THEN X_GEN_TAC `s:num->real^N` THEN
3273 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
3274 MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN
3275 EXISTS_TAC `\n. x - (s:num->real^N) n` THEN
3276 REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
3277 ASM_SIMP_TAC[LIM_SUB; LIM_CONST; SEQUENTIALLY] THEN MESON_TAC[GE_REFL]);;
3279 let IN_INTERIOR_CBALL = prove
3280 (`!x s. x IN interior s <=> ?e. &0 < e /\ cball(x,e) SUBSET s`,
3281 REWRITE_TAC[interior; IN_ELIM_THM] THEN
3282 MESON_TAC[OPEN_CONTAINS_CBALL; SUBSET_TRANS;
3283 BALL_SUBSET_CBALL; CENTRE_IN_BALL; OPEN_BALL]);;
3285 let LIMPT_BALL = prove
3286 (`!x:real^N y e. y limit_point_of ball(x,e) <=> &0 < e /\ y IN cball(x,e)`,
3287 REPEAT GEN_TAC THEN ASM_CASES_TAC `&0 < e` THENL
3288 [ALL_TAC; ASM_MESON_TAC[LIMPT_EMPTY; REAL_NOT_LT; BALL_EQ_EMPTY]] THEN
3289 ASM_REWRITE_TAC[] THEN EQ_TAC THENL
3290 [MESON_TAC[CLOSED_CBALL; CLOSED_LIMPT; LIMPT_SUBSET; BALL_SUBSET_CBALL];
3291 REWRITE_TAC[IN_CBALL; LIMPT_APPROACHABLE; IN_BALL]] THEN
3292 DISCH_TAC THEN X_GEN_TAC `d:real` THEN DISCH_TAC THEN
3293 ASM_CASES_TAC `y:real^N = x` THEN ASM_REWRITE_TAC[DIST_NZ] THENL
3294 [MP_TAC(SPECL [`d:real`; `e:real`] REAL_DOWN2) THEN
3295 ASM_REWRITE_TAC[] THEN
3296 GEN_MESON_TAC 0 40 1 [VECTOR_CHOOSE_DIST; DIST_SYM; REAL_LT_IMP_LE];
3298 MP_TAC(SPECL [`norm(y:real^N - x)`; `d:real`] REAL_DOWN2) THEN
3299 RULE_ASSUM_TAC(REWRITE_RULE[DIST_NZ; dist]) THEN ASM_REWRITE_TAC[] THEN
3300 DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
3301 EXISTS_TAC `(y:real^N) - (k / dist(y,x)) % (y - x)` THEN
3302 REWRITE_TAC[dist; VECTOR_ARITH `(y - c % z) - y = --c % z`] THEN
3303 REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; REAL_ABS_NEG] THEN
3304 ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_LT_IMP_NZ] THEN
3305 REWRITE_TAC[VECTOR_ARITH `x - (y - k % (y - x)) = (&1 - k) % (x - y)`] THEN
3306 ASM_SIMP_TAC[REAL_ARITH `&0 < k ==> &0 < abs k`; NORM_MUL] THEN
3307 ASM_SIMP_TAC[REAL_ARITH `&0 < k /\ k < d ==> abs k < d`] THEN
3308 MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `norm(x:real^N - y)` THEN
3309 ASM_REWRITE_TAC[] THEN GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN
3310 MATCH_MP_TAC REAL_LT_RMUL THEN CONJ_TAC THENL
3311 [ALL_TAC; ASM_MESON_TAC[NORM_SUB]] THEN
3312 MATCH_MP_TAC(REAL_ARITH `&0 < k /\ k < &1 ==> abs(&1 - k) < &1`) THEN
3313 ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_MUL_LZERO;
3316 let CLOSURE_BALL = prove
3317 (`!x:real^N e. &0 < e ==> (closure(ball(x,e)) = cball(x,e))`,
3318 SIMP_TAC[EXTENSION; closure; IN_ELIM_THM; IN_UNION; LIMPT_BALL] THEN
3319 REWRITE_TAC[IN_BALL; IN_CBALL] THEN REAL_ARITH_TAC);;
3321 let INTERIOR_CBALL = prove
3322 (`!x:real^N e. interior(cball(x,e)) = ball(x,e)`,
3323 REPEAT GEN_TAC THEN ASM_CASES_TAC `&0 <= e` THENL
3325 SUBGOAL_THEN `cball(x:real^N,e) = {} /\ ball(x:real^N,e) = {}`
3326 (fun th -> REWRITE_TAC[th; INTERIOR_EMPTY]) THEN
3327 REWRITE_TAC[IN_BALL; IN_CBALL; EXTENSION; NOT_IN_EMPTY] THEN
3328 CONJ_TAC THEN X_GEN_TAC `y:real^N` THEN
3329 MP_TAC(ISPECL [`x:real^N`; `y:real^N`] DIST_POS_LE) THEN
3330 POP_ASSUM MP_TAC THEN REAL_ARITH_TAC] THEN
3331 MATCH_MP_TAC INTERIOR_UNIQUE THEN
3332 REWRITE_TAC[BALL_SUBSET_CBALL; OPEN_BALL] THEN
3333 X_GEN_TAC `t:real^N->bool` THEN
3334 SIMP_TAC[SUBSET; IN_CBALL; IN_BALL; REAL_LT_LE] THEN STRIP_TAC THEN
3335 X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
3336 FIRST_X_ASSUM(MP_TAC o SPEC `z:real^N` o GEN_REWRITE_RULE I [open_def]) THEN
3337 ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN `d:real` MP_TAC) THEN
3338 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3339 ASM_CASES_TAC `z:real^N = x` THENL
3340 [FIRST_X_ASSUM SUBST_ALL_TAC THEN
3341 FIRST_X_ASSUM(X_CHOOSE_TAC `k:real` o MATCH_MP REAL_DOWN) THEN
3342 SUBGOAL_THEN `?w:real^N. dist(w,x) = k` STRIP_ASSUME_TAC THENL
3343 [ASM_MESON_TAC[VECTOR_CHOOSE_DIST; DIST_SYM; REAL_LT_IMP_LE];
3344 ASM_MESON_TAC[REAL_NOT_LE; DIST_REFL; DIST_SYM]];
3345 RULE_ASSUM_TAC(REWRITE_RULE[DIST_NZ]) THEN
3346 DISCH_THEN(MP_TAC o SPEC `z + ((d / &2) / dist(z,x)) % (z - x:real^N)`) THEN
3347 REWRITE_TAC[dist; VECTOR_ADD_SUB; NORM_MUL; REAL_ABS_DIV;
3348 REAL_ABS_NORM; REAL_ABS_NUM] THEN
3349 ASM_SIMP_TAC[REAL_DIV_RMUL; GSYM dist; REAL_LT_IMP_NZ] THEN
3350 ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
3351 ASM_REWRITE_TAC[REAL_ARITH `abs d < d * &2 <=> &0 < d`] THEN
3352 DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN REWRITE_TAC[dist] THEN
3353 REWRITE_TAC[VECTOR_ARITH `x - (z + k % (z - x)) = (&1 + k) % (x - z)`] THEN
3354 REWRITE_TAC[REAL_NOT_LE; NORM_MUL] THEN
3355 GEN_REWRITE_TAC LAND_CONV [GSYM REAL_MUL_LID] THEN
3356 ONCE_REWRITE_TAC[NORM_SUB] THEN
3357 ASM_SIMP_TAC[REAL_LT_RMUL_EQ; GSYM dist] THEN
3358 MATCH_MP_TAC(REAL_ARITH `&0 < x ==> &1 < abs(&1 + x)`) THEN
3359 ONCE_REWRITE_TAC[DIST_SYM] THEN
3360 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH]]);;
3362 let FRONTIER_BALL = prove
3363 (`!a e. &0 < e ==> frontier(ball(a,e)) = sphere(a,e)`,
3364 SIMP_TAC[frontier; sphere; CLOSURE_BALL; INTERIOR_OPEN; OPEN_BALL;
3365 REAL_LT_IMP_LE] THEN
3366 REWRITE_TAC[EXTENSION; IN_DIFF; IN_ELIM_THM; IN_BALL; IN_CBALL] THEN
3369 let FRONTIER_CBALL = prove
3370 (`!a e. frontier(cball(a,e)) = sphere(a,e)`,
3371 SIMP_TAC[frontier; sphere; INTERIOR_CBALL; CLOSED_CBALL; CLOSURE_CLOSED;
3372 REAL_LT_IMP_LE] THEN
3373 REWRITE_TAC[EXTENSION; IN_DIFF; IN_ELIM_THM; IN_BALL; IN_CBALL] THEN
3376 let CBALL_EQ_EMPTY = prove
3377 (`!x e. (cball(x,e) = {}) <=> e < &0`,
3378 REWRITE_TAC[EXTENSION; IN_CBALL; NOT_IN_EMPTY; REAL_NOT_LE] THEN
3379 MESON_TAC[DIST_POS_LE; DIST_REFL; REAL_LTE_TRANS]);;
3381 let CBALL_EMPTY = prove
3382 (`!x e. e < &0 ==> cball(x,e) = {}`,
3383 REWRITE_TAC[CBALL_EQ_EMPTY]);;
3385 let CBALL_EQ_SING = prove
3386 (`!x:real^N e. (cball(x,e) = {x}) <=> e = &0`,
3387 REPEAT GEN_TAC THEN REWRITE_TAC[EXTENSION; IN_CBALL; IN_SING] THEN
3388 EQ_TAC THENL [ALL_TAC; MESON_TAC[DIST_LE_0]] THEN
3389 DISCH_THEN(fun th -> MP_TAC(SPEC `x + (e / &2) % basis 1:real^N` th) THEN
3390 MP_TAC(SPEC `x:real^N` th)) THEN
3391 REWRITE_TAC[dist; VECTOR_ARITH `x - (x + e):real^N = --e`;
3392 VECTOR_ARITH `x + e = x <=> e:real^N = vec 0`] THEN
3393 REWRITE_TAC[NORM_NEG; NORM_MUL; VECTOR_MUL_EQ_0; NORM_0; VECTOR_SUB_REFL] THEN
3394 SIMP_TAC[NORM_BASIS; BASIS_NONZERO; LE_REFL; DIMINDEX_GE_1] THEN
3397 let CBALL_SING = prove
3398 (`!x e. e = &0 ==> cball(x,e) = {x}`,
3399 REWRITE_TAC[CBALL_EQ_SING]);;
3401 let SPHERE_SING = prove
3402 (`!x e. e = &0 ==> sphere(x,e) = {x}`,
3403 SIMP_TAC[sphere; DIST_EQ_0; SING_GSPEC]);;
3405 let SPHERE_EQ_SING = prove
3406 (`!a:real^N r x. sphere(a,r) = {x} <=> x = a /\ r = &0`,
3407 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[SPHERE_SING] THEN
3408 ASM_CASES_TAC `r < &0` THEN ASM_SIMP_TAC[SPHERE_EMPTY; NOT_INSERT_EMPTY] THEN
3409 ASM_CASES_TAC `r = &0` THEN ASM_SIMP_TAC[SPHERE_SING] THENL
3410 [ASM SET_TAC[]; ALL_TAC] THEN
3411 MATCH_MP_TAC(SET_RULE
3412 `!y. (x IN s ==> y IN s /\ ~(y = x)) ==> ~(s = {x})`) THEN
3413 EXISTS_TAC `a - (x - a):real^N` THEN REWRITE_TAC[IN_SPHERE] THEN
3414 REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC NORM_ARITH);;
3416 (* ------------------------------------------------------------------------- *)
3417 (* For points in the interior, localization of limits makes no difference. *)
3418 (* ------------------------------------------------------------------------- *)
3420 let EVENTUALLY_WITHIN_INTERIOR = prove
3423 ==> (eventually p (at x within s) <=> eventually p (at x))`,
3424 REWRITE_TAC[EVENTUALLY_WITHIN; EVENTUALLY_AT; IN_INTERIOR] THEN
3425 REPEAT GEN_TAC THEN SIMP_TAC[SUBSET; IN_BALL; LEFT_IMP_FORALL_THM] THEN
3426 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
3427 EQ_TAC THEN DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
3428 EXISTS_TAC `min (d:real) e` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
3429 ASM_MESON_TAC[DIST_SYM]);;
3431 let LIM_WITHIN_INTERIOR = prove
3434 ==> ((f --> l) (at x within s) <=> (f --> l) (at x))`,
3435 SIMP_TAC[tendsto; EVENTUALLY_WITHIN_INTERIOR]);;
3437 let NETLIMIT_WITHIN_INTERIOR = prove
3438 (`!s x:real^N. x IN interior s ==> netlimit(at x within s) = x`,
3439 REPEAT STRIP_TAC THEN MATCH_MP_TAC NETLIMIT_WITHIN THEN
3440 REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN
3441 FIRST_ASSUM(MP_TAC o MATCH_MP(REWRITE_RULE[OPEN_CONTAINS_BALL]
3442 (SPEC_ALL OPEN_INTERIOR))) THEN
3443 ASM_MESON_TAC[LIMPT_SUBSET; LIMPT_BALL; CENTRE_IN_CBALL; REAL_LT_IMP_LE;
3444 SUBSET_TRANS; INTERIOR_SUBSET]);;
3446 (* ------------------------------------------------------------------------- *)
3447 (* A non-singleton connected set is perfect (i.e. has no isolated points). *)
3448 (* ------------------------------------------------------------------------- *)
3450 let CONNECTED_IMP_PERFECT = prove
3452 connected s /\ ~(?a. s = {a}) /\ x IN s ==> x limit_point_of s`,
3453 REPEAT STRIP_TAC THEN REWRITE_TAC[limit_point_of] THEN
3454 X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN
3455 MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN
3456 FIRST_ASSUM(MP_TAC o SPEC `x:real^N` o GEN_REWRITE_RULE I
3457 [OPEN_CONTAINS_CBALL]) THEN
3458 ASM_REWRITE_TAC[] THEN
3459 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
3460 FIRST_X_ASSUM(MP_TAC o SPEC `{x:real^N}` o
3461 GEN_REWRITE_RULE I [CONNECTED_CLOPEN]) THEN
3462 REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL
3463 [REWRITE_TAC[OPEN_IN_OPEN] THEN EXISTS_TAC `t:real^N->bool` THEN
3465 REWRITE_TAC[CLOSED_IN_CLOSED] THEN
3466 EXISTS_TAC `cball(x:real^N,e)` THEN REWRITE_TAC[CLOSED_CBALL] THEN
3467 REWRITE_TAC[EXTENSION; IN_INTER; IN_SING] THEN
3468 ASM_MESON_TAC[CENTRE_IN_CBALL; SUBSET; REAL_LT_IMP_LE];
3471 (* ------------------------------------------------------------------------- *)
3473 (* ------------------------------------------------------------------------- *)
3475 let bounded = new_definition
3476 `bounded s <=> ?a. !x:real^N. x IN s ==> norm(x) <= a`;;
3478 let BOUNDED_EMPTY = prove
3480 REWRITE_TAC[bounded; NOT_IN_EMPTY]);;
3482 let BOUNDED_SUBSET = prove
3483 (`!s t. bounded t /\ s SUBSET t ==> bounded s`,
3484 MESON_TAC[bounded; SUBSET]);;
3486 let BOUNDED_INTERIOR = prove
3487 (`!s:real^N->bool. bounded s ==> bounded(interior s)`,
3488 MESON_TAC[BOUNDED_SUBSET; INTERIOR_SUBSET]);;
3490 let BOUNDED_CLOSURE = prove
3491 (`!s:real^N->bool. bounded s ==> bounded(closure s)`,
3492 REWRITE_TAC[bounded; CLOSURE_SEQUENTIAL] THEN
3493 GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
3494 MESON_TAC[REWRITE_RULE[eventually] LIM_NORM_UBOUND;
3495 TRIVIAL_LIMIT_SEQUENTIALLY; trivial_limit]);;
3497 let BOUNDED_CLOSURE_EQ = prove
3498 (`!s:real^N->bool. bounded(closure s) <=> bounded s`,
3499 GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_CLOSURE] THEN
3500 MESON_TAC[BOUNDED_SUBSET; CLOSURE_SUBSET]);;
3502 let BOUNDED_CBALL = prove
3503 (`!x:real^N e. bounded(cball(x,e))`,
3504 REPEAT GEN_TAC THEN REWRITE_TAC[bounded] THEN
3505 EXISTS_TAC `norm(x:real^N) + e` THEN REWRITE_TAC[IN_CBALL; dist] THEN
3508 let BOUNDED_BALL = prove
3509 (`!x e. bounded(ball(x,e))`,
3510 MESON_TAC[BALL_SUBSET_CBALL; BOUNDED_CBALL; BOUNDED_SUBSET]);;
3512 let FINITE_IMP_BOUNDED = prove
3513 (`!s:real^N->bool. FINITE s ==> bounded s`,
3514 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[BOUNDED_EMPTY] THEN
3515 REWRITE_TAC[bounded; IN_INSERT] THEN X_GEN_TAC `x:real^N` THEN GEN_TAC THEN
3516 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `B:real`) STRIP_ASSUME_TAC) THEN
3517 EXISTS_TAC `norm(x:real^N) + abs B` THEN REPEAT STRIP_TAC THEN
3518 ASM_MESON_TAC[NORM_POS_LE; REAL_ARITH
3519 `(y <= b /\ &0 <= x ==> y <= x + abs b) /\ x <= x + abs b`]);;
3521 let BOUNDED_UNION = prove
3522 (`!s t. bounded (s UNION t) <=> bounded s /\ bounded t`,
3523 REWRITE_TAC[bounded; IN_UNION] THEN MESON_TAC[REAL_LE_MAX]);;
3525 let BOUNDED_UNIONS = prove
3526 (`!f. FINITE f /\ (!s. s IN f ==> bounded s) ==> bounded(UNIONS f)`,
3527 REWRITE_TAC[IMP_CONJ] THEN
3528 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3529 REWRITE_TAC[UNIONS_0; BOUNDED_EMPTY; IN_INSERT; UNIONS_INSERT] THEN
3530 MESON_TAC[BOUNDED_UNION]);;
3532 let BOUNDED_POS = prove
3533 (`!s. bounded s <=> ?b. &0 < b /\ !x. x IN s ==> norm(x) <= b`,
3534 REWRITE_TAC[bounded] THEN
3535 MESON_TAC[REAL_ARITH `&0 < &1 + abs(y) /\ (x <= y ==> x <= &1 + abs(y))`]);;
3537 let BOUNDED_POS_LT = prove
3538 (`!s. bounded s <=> ?b. &0 < b /\ !x. x IN s ==> norm(x) < b`,
3539 REWRITE_TAC[bounded] THEN
3540 MESON_TAC[REAL_LT_IMP_LE;
3541 REAL_ARITH `&0 < &1 + abs(y) /\ (x <= y ==> x < &1 + abs(y))`]);;
3543 let BOUNDED_INTER = prove
3544 (`!s t. bounded s \/ bounded t ==> bounded (s INTER t)`,
3545 MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET]);;
3547 let BOUNDED_DIFF = prove
3548 (`!s t. bounded s ==> bounded (s DIFF t)`,
3549 MESON_TAC[BOUNDED_SUBSET; SUBSET_DIFF]);;
3551 let BOUNDED_INSERT = prove
3552 (`!x s. bounded(x INSERT s) <=> bounded s`,
3553 ONCE_REWRITE_TAC[SET_RULE `x INSERT s = {x} UNION s`] THEN
3554 SIMP_TAC[BOUNDED_UNION; FINITE_IMP_BOUNDED; FINITE_RULES]);;
3556 let BOUNDED_SING = prove
3558 REWRITE_TAC[BOUNDED_INSERT; BOUNDED_EMPTY]);;
3560 let BOUNDED_INTERS = prove
3561 (`!f:(real^N->bool)->bool.
3562 (?s:real^N->bool. s IN f /\ bounded s) ==> bounded(INTERS f)`,
3563 REWRITE_TAC[LEFT_IMP_EXISTS_THM; IMP_CONJ] THEN REPEAT GEN_TAC THEN
3564 DISCH_TAC THEN MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN
3567 let NOT_BOUNDED_UNIV = prove
3568 (`~(bounded (:real^N))`,
3569 REWRITE_TAC[BOUNDED_POS; NOT_FORALL_THM; NOT_EXISTS_THM; IN_UNIV;
3570 DE_MORGAN_THM; REAL_NOT_LE] THEN
3571 X_GEN_TAC `B:real` THEN ASM_CASES_TAC `&0 < B` THEN ASM_REWRITE_TAC[] THEN
3572 MP_TAC(SPEC `B + &1` VECTOR_CHOOSE_SIZE) THEN
3573 ASM_SIMP_TAC[REAL_ARITH `&0 < B ==> &0 <= B + &1`] THEN
3574 MATCH_MP_TAC MONO_EXISTS THEN REAL_ARITH_TAC);;
3576 let COBOUNDED_IMP_UNBOUNDED = prove
3577 (`!s. bounded((:real^N) DIFF s) ==> ~bounded s`,
3578 GEN_TAC THEN REWRITE_TAC[TAUT `a ==> ~b <=> ~(a /\ b)`] THEN
3579 REWRITE_TAC[GSYM BOUNDED_UNION; SET_RULE `UNIV DIFF s UNION s = UNIV`] THEN
3580 REWRITE_TAC[NOT_BOUNDED_UNIV]);;
3582 let BOUNDED_LINEAR_IMAGE = prove
3583 (`!f:real^M->real^N s. bounded s /\ linear f ==> bounded(IMAGE f s)`,
3584 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN
3585 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `B1:real`) MP_TAC) THEN
3586 DISCH_THEN(X_CHOOSE_TAC `B2:real` o MATCH_MP LINEAR_BOUNDED_POS) THEN
3587 EXISTS_TAC `B2 * B1` THEN ASM_SIMP_TAC[REAL_LT_MUL; FORALL_IN_IMAGE] THEN
3588 X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN
3589 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `B2 * norm(x:real^M)` THEN
3590 ASM_SIMP_TAC[REAL_LE_LMUL_EQ]);;
3592 let BOUNDED_LINEAR_IMAGE_EQ = prove
3593 (`!f s. linear f /\ (!x y. f x = f y ==> x = y)
3594 ==> (bounded (IMAGE f s) <=> bounded s)`,
3595 MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE BOUNDED_LINEAR_IMAGE));;
3597 add_linear_invariants [BOUNDED_LINEAR_IMAGE_EQ];;
3599 let BOUNDED_SCALING = prove
3600 (`!c s. bounded s ==> bounded (IMAGE (\x. c % x) s)`,
3601 REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_LINEAR_IMAGE THEN
3602 ASM_SIMP_TAC[LINEAR_COMPOSE_CMUL; LINEAR_ID]);;
3604 let BOUNDED_NEGATIONS = prove
3605 (`!s. bounded s ==> bounded (IMAGE (--) s)`,
3607 DISCH_THEN(MP_TAC o SPEC `-- &1` o MATCH_MP BOUNDED_SCALING) THEN
3608 REWRITE_TAC[bounded; IN_IMAGE; VECTOR_MUL_LNEG; VECTOR_MUL_LID]);;
3610 let BOUNDED_TRANSLATION = prove
3611 (`!a:real^N s. bounded s ==> bounded (IMAGE (\x. a + x) s)`,
3612 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN
3613 DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN
3614 EXISTS_TAC `B + norm(a:real^N)` THEN POP_ASSUM MP_TAC THEN
3615 MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL [NORM_ARITH_TAC; ALL_TAC] THEN
3616 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
3617 REWRITE_TAC[] THEN NORM_ARITH_TAC);;
3619 let BOUNDED_TRANSLATION_EQ = prove
3620 (`!a s. bounded (IMAGE (\x:real^N. a + x) s) <=> bounded s`,
3621 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_TRANSLATION] THEN
3622 DISCH_THEN(MP_TAC o SPEC `--a:real^N` o MATCH_MP BOUNDED_TRANSLATION) THEN
3623 REWRITE_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID;
3624 VECTOR_ARITH `--a + a + x:real^N = x`]);;
3626 add_translation_invariants [BOUNDED_TRANSLATION_EQ];;
3628 let BOUNDED_DIFFS = prove
3629 (`!s t:real^N->bool.
3630 bounded s /\ bounded t ==> bounded {x - y | x IN s /\ y IN t}`,
3631 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN
3632 DISCH_THEN(CONJUNCTS_THEN2
3633 (X_CHOOSE_TAC `B:real`) (X_CHOOSE_TAC `C:real`)) THEN
3634 EXISTS_TAC `B + C:real` THEN REWRITE_TAC[IN_ELIM_THM] THEN
3635 CONJ_TAC THENL [ASM_REAL_ARITH_TAC; REPEAT STRIP_TAC] THEN
3636 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(NORM_ARITH
3637 `norm x <= a /\ norm y <= b ==> norm(x - y) <= a + b`) THEN
3640 let BOUNDED_SUMS = prove
3641 (`!s t:real^N->bool.
3642 bounded s /\ bounded t ==> bounded {x + y | x IN s /\ y IN t}`,
3643 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN
3644 DISCH_THEN(CONJUNCTS_THEN2
3645 (X_CHOOSE_TAC `B:real`) (X_CHOOSE_TAC `C:real`)) THEN
3646 EXISTS_TAC `B + C:real` THEN REWRITE_TAC[IN_ELIM_THM] THEN
3647 CONJ_TAC THENL [ASM_REAL_ARITH_TAC; REPEAT STRIP_TAC] THEN
3648 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(NORM_ARITH
3649 `norm x <= a /\ norm y <= b ==> norm(x + y) <= a + b`) THEN
3652 let BOUNDED_SUMS_IMAGE = prove
3653 (`!f g t. bounded {f x | x IN t} /\ bounded {g x | x IN t}
3654 ==> bounded {f x + g x | x IN t}`,
3655 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUMS) THEN
3656 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN
3659 let BOUNDED_SUMS_IMAGES = prove
3660 (`!f:A->B->real^N t s.
3662 (!a. a IN s ==> bounded {f x a | x IN t})
3663 ==> bounded { vsum s (f x) | x IN t}`,
3664 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
3665 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3666 SIMP_TAC[VSUM_CLAUSES] THEN CONJ_TAC THENL
3667 [DISCH_THEN(K ALL_TAC) THEN MATCH_MP_TAC BOUNDED_SUBSET THEN
3668 EXISTS_TAC `{vec 0:real^N}` THEN
3669 SIMP_TAC[FINITE_IMP_BOUNDED; FINITE_RULES] THEN SET_TAC[];
3671 REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_SUMS_IMAGE THEN
3672 ASM_SIMP_TAC[IN_INSERT]);;
3674 let BOUNDED_SUBSET_BALL = prove
3675 (`!s x:real^N. bounded(s) ==> ?r. &0 < r /\ s SUBSET ball(x,r)`,
3676 REPEAT GEN_TAC THEN REWRITE_TAC[BOUNDED_POS] THEN
3677 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
3678 EXISTS_TAC `&2 * B + norm(x:real^N)` THEN
3679 ASM_SIMP_TAC[NORM_POS_LE; REAL_ARITH
3680 `&0 < B /\ &0 <= x ==> &0 < &2 * B + x`] THEN
3681 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
3682 FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[IN_BALL] THEN
3683 UNDISCH_TAC `&0 < B` THEN NORM_ARITH_TAC);;
3685 let BOUNDED_SUBSET_CBALL = prove
3686 (`!s x:real^N. bounded(s) ==> ?r. &0 < r /\ s SUBSET cball(x,r)`,
3687 MESON_TAC[BOUNDED_SUBSET_BALL; SUBSET_TRANS; BALL_SUBSET_CBALL]);;
3689 let UNBOUNDED_INTER_COBOUNDED = prove
3690 (`!s t. ~bounded s /\ bounded((:real^N) DIFF t) ==> ~(s INTER t = {})`,
3691 REWRITE_TAC[SET_RULE `s INTER t = {} <=> s SUBSET (:real^N) DIFF t`] THEN
3692 MESON_TAC[BOUNDED_SUBSET]);;
3694 let COBOUNDED_INTER_UNBOUNDED = prove
3695 (`!s t. bounded((:real^N) DIFF s) /\ ~bounded t ==> ~(s INTER t = {})`,
3696 REWRITE_TAC[SET_RULE `s INTER t = {} <=> t SUBSET (:real^N) DIFF s`] THEN
3697 MESON_TAC[BOUNDED_SUBSET]);;
3699 let SUBSPACE_BOUNDED_EQ_TRIVIAL = prove
3700 (`!s:real^N->bool. subspace s ==> (bounded s <=> s = {vec 0})`,
3701 REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[BOUNDED_SING] THEN
3702 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
3703 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
3704 `~(s = {a}) ==> a IN s ==> ?b. b IN s /\ ~(b = a)`)) THEN
3705 ASM_SIMP_TAC[SUBSPACE_0] THEN
3706 DISCH_THEN(X_CHOOSE_THEN `v:real^N` STRIP_ASSUME_TAC) THEN
3707 REWRITE_TAC[bounded; NOT_EXISTS_THM] THEN X_GEN_TAC `B:real` THEN
3708 DISCH_THEN(MP_TAC o SPEC `(B + &1) / norm v % v:real^N`) THEN
3709 ASM_SIMP_TAC[SUBSPACE_MUL; NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN
3710 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN REAL_ARITH_TAC);;
3712 let BOUNDED_COMPONENTWISE = prove
3714 bounded s <=> !i. 1 <= i /\ i <= dimindex(:N)
3715 ==> bounded (IMAGE (\x. lift(x$i)) s)`,
3716 GEN_TAC THEN REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; NORM_LIFT] THEN
3717 EQ_TAC THENL [ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS]; ALL_TAC] THEN
3718 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
3719 SIMP_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `b:num->real` THEN
3720 DISCH_TAC THEN EXISTS_TAC `sum(1..dimindex(:N)) b` THEN CONJ_TAC THENL
3721 [MATCH_MP_TAC REAL_LET_TRANS THEN
3722 EXISTS_TAC `sum(1..dimindex(:N)) (\i. &0)` THEN
3723 SIMP_TAC[SUM_POS_LE_NUMSEG; REAL_POS] THEN
3724 MATCH_MP_TAC SUM_LT_ALL THEN
3725 ASM_SIMP_TAC[IN_NUMSEG; FINITE_NUMSEG; NUMSEG_EMPTY] THEN
3726 REWRITE_TAC[NOT_LT; DIMINDEX_GE_1];
3727 REPEAT STRIP_TAC THEN
3728 W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN
3729 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
3730 MATCH_MP_TAC SUM_LE THEN ASM_SIMP_TAC[IN_NUMSEG; FINITE_NUMSEG]]);;
3732 (* ------------------------------------------------------------------------- *)
3733 (* Some theorems on sups and infs using the notion "bounded". *)
3734 (* ------------------------------------------------------------------------- *)
3736 let BOUNDED_LIFT = prove
3737 (`!s. bounded(IMAGE lift s) <=> ?a. !x. x IN s ==> abs(x) <= a`,
3738 REWRITE_TAC[bounded; FORALL_LIFT; NORM_LIFT; LIFT_IN_IMAGE_LIFT]);;
3740 let BOUNDED_HAS_SUP = prove
3741 (`!s. bounded(IMAGE lift s) /\ ~(s = {})
3742 ==> (!x. x IN s ==> x <= sup s) /\
3743 (!b. (!x. x IN s ==> x <= b) ==> sup s <= b)`,
3744 REWRITE_TAC[BOUNDED_LIFT; IMAGE_EQ_EMPTY] THEN
3745 MESON_TAC[SUP; REAL_ARITH `abs(x) <= a ==> x <= a`]);;
3747 let SUP_INSERT = prove
3748 (`!x s. bounded (IMAGE lift s)
3749 ==> sup(x INSERT s) = if s = {} then x else max x (sup s)`,
3750 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_UNIQUE THEN
3751 COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THENL
3752 [MESON_TAC[REAL_LE_REFL]; ALL_TAC] THEN
3753 REWRITE_TAC[REAL_LE_MAX; REAL_LT_MAX; IN_INSERT] THEN
3754 MP_TAC(ISPEC `s:real->bool` BOUNDED_HAS_SUP) THEN ASM_REWRITE_TAC[] THEN
3755 REPEAT STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_REFL; REAL_NOT_LT]);;
3757 let BOUNDED_HAS_INF = prove
3758 (`!s. bounded(IMAGE lift s) /\ ~(s = {})
3759 ==> (!x. x IN s ==> inf s <= x) /\
3760 (!b. (!x. x IN s ==> b <= x) ==> b <= inf s)`,
3761 REWRITE_TAC[BOUNDED_LIFT; IMAGE_EQ_EMPTY] THEN
3762 MESON_TAC[INF; REAL_ARITH `abs(x) <= a ==> --a <= x`]);;
3764 let INF_INSERT = prove
3765 (`!x s. bounded (IMAGE lift s)
3766 ==> inf(x INSERT s) = if s = {} then x else min x (inf s)`,
3767 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INF_UNIQUE THEN
3768 COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_SING] THENL
3769 [MESON_TAC[REAL_LE_REFL]; ALL_TAC] THEN
3770 REWRITE_TAC[REAL_MIN_LE; REAL_MIN_LT; IN_INSERT] THEN
3771 MP_TAC(ISPEC `s:real->bool` BOUNDED_HAS_INF) THEN ASM_REWRITE_TAC[] THEN
3772 REPEAT STRIP_TAC THEN ASM_MESON_TAC[REAL_LE_REFL; REAL_NOT_LT]);;
3774 (* ------------------------------------------------------------------------- *)
3775 (* Subset relation on balls. *)
3776 (* ------------------------------------------------------------------------- *)
3778 let SUBSET_BALLS = prove
3779 (`(!a a':real^N r r'.
3780 ball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r <= r' \/ r <= &0) /\
3782 ball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r <= &0) /\
3784 cball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r < r' \/ r < &0) /\
3786 cball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r < &0)`,
3789 cball(a,r) SUBSET cball(a',r') <=> dist(a,a') + r <= r' \/ r < &0) /\
3791 cball(a,r) SUBSET ball(a',r') <=> dist(a,a') + r < r' \/ r < &0)`,
3793 (GEOM_ORIGIN_TAC `a':real^N` THEN
3794 REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET; IN_CBALL; IN_BALL] THEN
3795 EQ_TAC THENL [REWRITE_TAC[DIST_0]; NORM_ARITH_TAC] THEN
3796 DISJ_CASES_TAC(REAL_ARITH `r < &0 \/ &0 <= r`) THEN
3797 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN DISJ1_TAC THEN
3798 ASM_CASES_TAC `a:real^N = vec 0` THENL
3799 [FIRST_X_ASSUM(MP_TAC o SPEC `r % basis 1:real^N`) THEN
3800 ASM_SIMP_TAC[DIST_0; NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL];
3801 FIRST_X_ASSUM(MP_TAC o SPEC `(&1 + r / norm(a)) % a:real^N`) THEN
3802 SIMP_TAC[dist; VECTOR_ARITH `a - (&1 + x) % a:real^N = --(x % a)`] THEN
3803 ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; NORM_NEG; REAL_POS;
3804 REAL_LE_DIV; NORM_POS_LE; REAL_ADD_RDISTRIB; REAL_DIV_RMUL;
3805 NORM_EQ_0; REAL_ARITH `&0 <= x ==> abs(&1 + x) = &1 + x`]] THEN
3806 UNDISCH_TAC `&0 <= r` THEN NORM_ARITH_TAC))
3807 and tac = DISCH_THEN(MP_TAC o MATCH_MP SUBSET_CLOSURE) THEN
3808 ASM_SIMP_TAC[CLOSED_CBALL; CLOSURE_CLOSED; CLOSURE_BALL] in
3809 REWRITE_TAC[AND_FORALL_THM] THEN GEOM_ORIGIN_TAC `a':real^N` THEN
3810 REPEAT STRIP_TAC THEN
3812 [ALL_TAC; REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL] THEN NORM_ARITH_TAC]) THEN
3813 MATCH_MP_TAC(SET_RULE
3814 `(s = {} <=> q) /\ (s SUBSET t /\ ~(s = {}) /\ ~(t = {}) ==> p)
3815 ==> s SUBSET t ==> p \/ q`) THEN
3816 REWRITE_TAC[BALL_EQ_EMPTY; CBALL_EQ_EMPTY; REAL_NOT_LE; REAL_NOT_LT] THEN
3817 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THENL
3818 [tac; tac; ALL_TAC; ALL_TAC] THEN REWRITE_TAC[lemma] THEN
3819 REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC);;
3821 (* ------------------------------------------------------------------------- *)
3822 (* Compactness (the definition is the one based on convegent subsequences). *)
3823 (* ------------------------------------------------------------------------- *)
3825 let compact = new_definition
3829 ==> ?l r. l IN s /\ (!m n:num. m < n ==> r(m) < r(n)) /\
3830 ((f o r) --> l) sequentially`;;
3832 let MONOTONE_BIGGER = prove
3833 (`!r. (!m n. m < n ==> r(m) < r(n)) ==> !n:num. n <= r(n)`,
3834 GEN_TAC THEN DISCH_TAC THEN INDUCT_TAC THEN
3835 ASM_MESON_TAC[LE_0; ARITH_RULE `n <= m /\ m < p ==> SUC n <= p`; LT]);;
3837 let LIM_SUBSEQUENCE = prove
3838 (`!s r l. (!m n. m < n ==> r(m) < r(n)) /\ (s --> l) sequentially
3839 ==> (s o r --> l) sequentially`,
3840 REWRITE_TAC[LIM_SEQUENTIALLY; o_THM] THEN
3841 MESON_TAC[MONOTONE_BIGGER; LE_TRANS]);;
3843 let MONOTONE_SUBSEQUENCE = prove
3844 (`!s:num->real. ?r:num->num.
3845 (!m n. m < n ==> r(m) < r(n)) /\
3846 ((!m n. m <= n ==> s(r(m)) <= s(r(n))) \/
3847 (!m n. m <= n ==> s(r(n)) <= s(r(m))))`,
3849 ASM_CASES_TAC `!n:num. ?p. n < p /\ !m. p <= m ==> s(m) <= s(p)` THEN
3850 POP_ASSUM MP_TAC THEN
3851 REWRITE_TAC[NOT_FORALL_THM; NOT_EXISTS_THM; NOT_IMP; DE_MORGAN_THM] THEN
3852 REWRITE_TAC[RIGHT_OR_EXISTS_THM; SKOLEM_THM; REAL_NOT_LE; REAL_NOT_LT] THENL
3853 [ABBREV_TAC `N = 0`; DISCH_THEN(X_CHOOSE_THEN `N:num` MP_TAC)] THEN
3854 DISCH_THEN(X_CHOOSE_THEN `next:num->num` STRIP_ASSUME_TAC) THEN
3855 (MP_TAC o prove_recursive_functions_exist num_RECURSION)
3856 `(r 0 = next(SUC N)) /\ (!n. r(SUC n) = next(r n))` THEN
3857 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN STRIP_TAC THENL
3858 [SUBGOAL_THEN `!m:num n:num. r n <= m ==> s(m) <= s(r n):real`
3859 ASSUME_TAC THEN TRY CONJ_TAC THEN TRY DISJ2_TAC THEN
3860 GEN_TAC THEN INDUCT_TAC THEN ASM_REWRITE_TAC[LT; LE] THEN
3861 ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL; LT_IMP_LE; LT_TRANS];
3862 SUBGOAL_THEN `!n. N < (r:num->num) n` ASSUME_TAC THEN
3863 TRY(CONJ_TAC THENL [GEN_TAC; DISJ1_TAC THEN GEN_TAC]) THEN
3864 INDUCT_TAC THEN ASM_REWRITE_TAC[LT; LE] THEN
3865 TRY STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
3866 ASM_MESON_TAC[REAL_LT_REFL; LT_LE; LTE_TRANS; REAL_LE_REFL;
3867 REAL_LT_LE; REAL_LE_TRANS; LT]]);;
3869 let CONVERGENT_BOUNDED_INCREASING = prove
3870 (`!s:num->real b. (!m n. m <= n ==> s m <= s n) /\ (!n. abs(s n) <= b)
3871 ==> ?l. !e. &0 < e ==> ?N. !n. N <= n ==> abs(s n - l) < e`,
3872 REPEAT STRIP_TAC THEN
3873 MP_TAC(SPEC `\x. ?n. (s:num->real) n = x` REAL_COMPLETE) THEN
3874 REWRITE_TAC[] THEN ANTS_TAC THENL
3875 [ASM_MESON_TAC[REAL_ARITH `abs(x) <= b ==> x <= b`]; ALL_TAC] THEN
3876 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real` THEN STRIP_TAC THEN
3877 X_GEN_TAC `e:real` THEN STRIP_TAC THEN
3878 FIRST_X_ASSUM(MP_TAC o SPEC `l - e`) THEN
3879 ASM_MESON_TAC[REAL_ARITH `&0 < e ==> ~(l <= l - e)`;
3880 REAL_ARITH `x <= y /\ y <= l /\ ~(x <= l - e) ==> abs(y - l) < e`]);;
3882 let CONVERGENT_BOUNDED_MONOTONE = prove
3883 (`!s:num->real b. (!n. abs(s n) <= b) /\
3884 ((!m n. m <= n ==> s m <= s n) \/
3885 (!m n. m <= n ==> s n <= s m))
3886 ==> ?l. !e. &0 < e ==> ?N. !n. N <= n ==> abs(s n - l) < e`,
3887 REPEAT STRIP_TAC THENL
3888 [ASM_MESON_TAC[CONVERGENT_BOUNDED_INCREASING]; ALL_TAC] THEN
3889 MP_TAC(SPEC `\n. --((s:num->real) n)` CONVERGENT_BOUNDED_INCREASING) THEN
3890 ASM_REWRITE_TAC[REAL_LE_NEG2; REAL_ABS_NEG] THEN
3891 ASM_MESON_TAC[REAL_ARITH `abs(x - --l) = abs(--x - l)`]);;
3893 let COMPACT_REAL_LEMMA = prove
3894 (`!s b. (!n:num. abs(s n) <= b)
3895 ==> ?l r. (!m n:num. m < n ==> r(m) < r(n)) /\
3896 !e. &0 < e ==> ?N. !n. N <= n ==> abs(s(r n) - l) < e`,
3897 REPEAT GEN_TAC THEN DISCH_TAC THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
3898 MP_TAC(SPEC `s:num->real` MONOTONE_SUBSEQUENCE) THEN
3899 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN DISCH_TAC THEN ASM_SIMP_TAC[] THEN
3900 MATCH_MP_TAC CONVERGENT_BOUNDED_MONOTONE THEN ASM_MESON_TAC[]);;
3902 let COMPACT_LEMMA = prove
3903 (`!s. bounded s /\ (!n. (x:num->real^N) n IN s)
3904 ==> !d. d <= dimindex(:N)
3905 ==> ?l:real^N r. (!m n. m < n ==> r m < (r:num->num) n) /\
3907 ==> ?N. !n i. 1 <= i /\ i <= d
3909 ==> abs(x(r n)$i - l$i) < e`,
3910 GEN_TAC THEN REWRITE_TAC[bounded] THEN
3911 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `b:real`) ASSUME_TAC) THEN
3913 [REWRITE_TAC[ARITH_RULE `1 <= i /\ i <= 0 <=> F`; CONJ_ASSOC] THEN
3914 DISCH_TAC THEN EXISTS_TAC `\n:num. n` THEN REWRITE_TAC[];
3916 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN
3917 ASM_SIMP_TAC[ARITH_RULE `SUC d <= n ==> d <= n`] THEN STRIP_TAC THEN
3918 MP_TAC(SPECL [`\n:num. (x:num->real^N) (r n) $ (SUC d)`; `b:real`]
3919 COMPACT_REAL_LEMMA) THEN
3920 REWRITE_TAC[] THEN ANTS_TAC THENL
3921 [ASM_MESON_TAC[REAL_LE_TRANS; COMPONENT_LE_NORM; ARITH_RULE `1 <= SUC n`];
3923 DISCH_THEN(X_CHOOSE_THEN `y:real` (X_CHOOSE_THEN `s:num->num`
3924 STRIP_ASSUME_TAC)) THEN
3925 MAP_EVERY EXISTS_TAC
3926 [`(lambda k. if k = SUC d then y else (l:real^N)$k):real^N`;
3927 `(r:num->num) o (s:num->num)`] THEN
3928 ASM_SIMP_TAC[o_THM] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3929 REPEAT(FIRST_ASSUM(C UNDISCH_THEN (MP_TAC o SPEC `e:real`) o concl)) THEN
3930 ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_TAC `N1:num`) THEN
3931 DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN EXISTS_TAC `N1 + N2:num` THEN
3932 FIRST_ASSUM(fun th -> SIMP_TAC[LAMBDA_BETA; MATCH_MP(ARITH_RULE
3933 `SUC d <= n ==> !i. 1 <= i /\ i <= SUC d ==> 1 <= i /\ i <= n`) th]) THEN
3934 REWRITE_TAC[LE] THEN REPEAT STRIP_TAC THEN
3935 ASM_REWRITE_TAC[] THEN TRY COND_CASES_TAC THEN
3936 ASM_MESON_TAC[MONOTONE_BIGGER; LE_TRANS;
3937 ARITH_RULE `N1 + N2 <= n ==> N2 <= n:num /\ N1 <= n`;
3938 ARITH_RULE `1 <= i /\ i <= d /\ SUC d <= n
3939 ==> ~(i = SUC d) /\ 1 <= SUC d /\ d <= n /\ i <= n`]);;
3941 let BOUNDED_CLOSED_IMP_COMPACT = prove
3942 (`!s:real^N->bool. bounded s /\ closed s ==> compact s`,
3943 REPEAT STRIP_TAC THEN REWRITE_TAC[compact] THEN
3944 X_GEN_TAC `x:num->real^N` THEN DISCH_TAC THEN
3945 MP_TAC(ISPEC `s:real^N->bool` COMPACT_LEMMA) THEN
3946 ASM_REWRITE_TAC[] THEN
3947 DISCH_THEN(MP_TAC o SPEC `dimindex(:N)`) THEN
3948 REWRITE_TAC[LE_REFL] THEN
3949 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real^N` THEN
3950 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `r:num->num` THEN ASM_SIMP_TAC[] THEN
3951 STRIP_TAC THEN MATCH_MP_TAC(TAUT `(b ==> a) /\ b ==> a /\ b`) THEN
3952 REPEAT STRIP_TAC THENL
3953 [FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CLOSED_SEQUENTIAL_LIMITS]) THEN
3954 EXISTS_TAC `(x:num->real^N) o (r:num->num)` THEN
3955 ASM_REWRITE_TAC[o_THM];
3957 REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3958 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2 / &(dimindex(:N))`) THEN
3959 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; DIMINDEX_NONZERO;
3960 REAL_HALF; ARITH_RULE `0 < n <=> ~(n = 0)`] THEN
3961 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
3962 REWRITE_TAC[dist] THEN REPEAT STRIP_TAC THEN
3963 MATCH_MP_TAC(MATCH_MP (REAL_ARITH `a <= b ==> b < e ==> a < e`)
3964 (SPEC_ALL NORM_LE_L1)) THEN
3965 MATCH_MP_TAC REAL_LET_TRANS THEN
3966 EXISTS_TAC `sum (1..dimindex(:N))
3967 (\k. e / &2 / &(dimindex(:N)))` THEN
3969 [MATCH_MP_TAC SUM_LE_NUMSEG THEN
3970 SIMP_TAC[o_THM; LAMBDA_BETA; vector_sub] THEN
3971 ASM_MESON_TAC[REAL_LT_IMP_LE; LE_TRANS];
3972 ASM_SIMP_TAC[SUM_CONST_NUMSEG; ADD_SUB; REAL_DIV_LMUL; REAL_OF_NUM_EQ;
3973 DIMINDEX_NONZERO; REAL_LE_REFL; REAL_LT_LDIV_EQ; ARITH;
3974 REAL_OF_NUM_LT; REAL_ARITH `x < x * &2 <=> &0 < x`]]);;
3976 (* ------------------------------------------------------------------------- *)
3978 (* ------------------------------------------------------------------------- *)
3980 let cauchy = new_definition
3981 `cauchy (s:num->real^N) <=>
3982 !e. &0 < e ==> ?N. !m n. m >= N /\ n >= N ==> dist(s m,s n) < e`;;
3984 let complete = new_definition
3986 !f:num->real^N. (!n. f n IN s) /\ cauchy f
3987 ==> ?l. l IN s /\ (f --> l) sequentially`;;
3991 cauchy s <=> !e. &0 < e ==> ?N. !n. n >= N ==> dist(s n,s N) < e`,
3992 REPEAT GEN_TAC THEN REWRITE_TAC[cauchy; GE] THEN EQ_TAC THENL
3993 [MESON_TAC[LE_REFL]; DISCH_TAC] THEN
3994 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3995 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
3996 MESON_TAC[DIST_TRIANGLE_HALF_L]);;
3998 let CONVERGENT_IMP_CAUCHY = prove
3999 (`!s l. (s --> l) sequentially ==> cauchy s`,
4000 REWRITE_TAC[LIM_SEQUENTIALLY; cauchy] THEN
4001 REPEAT GEN_TAC THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
4002 FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
4003 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
4004 ASM_MESON_TAC[GE; LE_REFL; DIST_TRIANGLE_HALF_L]);;
4006 let CAUCHY_IMP_BOUNDED = prove
4007 (`!s:num->real^N. cauchy s ==> bounded {y | ?n. y = s n}`,
4008 REWRITE_TAC[cauchy; bounded; IN_ELIM_THM] THEN GEN_TAC THEN
4009 DISCH_THEN(MP_TAC o SPEC `&1`) THEN REWRITE_TAC[REAL_LT_01] THEN
4010 DISCH_THEN(X_CHOOSE_THEN `N:num` (MP_TAC o SPEC `N:num`)) THEN
4011 REWRITE_TAC[GE_REFL] THEN DISCH_TAC THEN
4012 SUBGOAL_THEN `!n:num. N <= n ==> norm(s n :real^N) <= norm(s N) + &1`
4014 [ASM_MESON_TAC[GE; dist; DIST_SYM; NORM_TRIANGLE_SUB;
4015 REAL_ARITH `a <= b + c /\ c < &1 ==> a <= b + &1`];
4016 MP_TAC(ISPECL [`\n:num. norm(s n :real^N)`; `0..N`]
4017 UPPER_BOUND_FINITE_SET_REAL) THEN
4018 SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; LE_0; LEFT_IMP_EXISTS_THM] THEN
4019 ASM_MESON_TAC[LE_CASES;
4020 REAL_ARITH `x <= a \/ x <= b ==> x <= abs a + abs b`]]);;
4022 let COMPACT_IMP_COMPLETE = prove
4023 (`!s:real^N->bool. compact s ==> complete s`,
4024 GEN_TAC THEN REWRITE_TAC[complete; compact] THEN
4025 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `f:num->real^N` THEN
4026 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
4027 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
4028 DISCH_THEN(X_CHOOSE_THEN `r:num->num` STRIP_ASSUME_TAC) THEN
4029 FIRST_X_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] LIM_ADD)) THEN
4030 DISCH_THEN(MP_TAC o SPEC `\n. (f:num->real^N)(n) - f(r n)`) THEN
4031 DISCH_THEN(MP_TAC o SPEC `vec 0: real^N`) THEN ASM_REWRITE_TAC[o_THM] THEN
4032 REWRITE_TAC[VECTOR_ADD_RID; VECTOR_SUB_ADD2; ETA_AX] THEN
4033 DISCH_THEN MATCH_MP_TAC THEN
4034 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [cauchy]) THEN
4035 REWRITE_TAC[GE; LIM; SEQUENTIALLY; dist; VECTOR_SUB_RZERO] THEN
4036 SUBGOAL_THEN `!n:num. n <= r(n)` MP_TAC THENL [INDUCT_TAC; ALL_TAC] THEN
4037 ASM_MESON_TAC[ LE_TRANS; LE_REFL; LT; LET_TRANS; LE_0; LE_SUC_LT]);;
4039 let COMPLETE_UNIV = prove
4040 (`complete(:real^N)`,
4041 REWRITE_TAC[complete; IN_UNIV] THEN X_GEN_TAC `x:num->real^N` THEN
4042 DISCH_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_IMP_BOUNDED) THEN
4043 DISCH_THEN(ASSUME_TAC o MATCH_MP BOUNDED_CLOSURE) THEN
4044 MP_TAC(ISPEC `closure {y:real^N | ?n:num. y = x n}`
4045 COMPACT_IMP_COMPLETE) THEN
4046 ASM_SIMP_TAC[BOUNDED_CLOSED_IMP_COMPACT; CLOSED_CLOSURE; complete] THEN
4047 DISCH_THEN(MP_TAC o SPEC `x:num->real^N`) THEN
4048 ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
4049 ASM_REWRITE_TAC[closure; IN_ELIM_THM; IN_UNION] THEN MESON_TAC[]);;
4051 let COMPLETE_EQ_CLOSED = prove
4052 (`!s:real^N->bool. complete s <=> closed s`,
4053 GEN_TAC THEN EQ_TAC THENL
4054 [REWRITE_TAC[complete; CLOSED_LIMPT; LIMPT_SEQUENTIAL] THEN
4055 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN GEN_TAC THEN
4056 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN MATCH_MP_TAC MONO_FORALL THEN
4057 MESON_TAC[CONVERGENT_IMP_CAUCHY; IN_DELETE; LIM_UNIQUE;
4058 TRIVIAL_LIMIT_SEQUENTIALLY];
4059 REWRITE_TAC[complete; CLOSED_SEQUENTIAL_LIMITS] THEN DISCH_TAC THEN
4060 X_GEN_TAC `f:num->real^N` THEN STRIP_TAC THEN
4061 MP_TAC(REWRITE_RULE[complete] COMPLETE_UNIV) THEN
4062 DISCH_THEN(MP_TAC o SPEC `f:num->real^N`) THEN
4063 ASM_REWRITE_TAC[IN_UNIV] THEN ASM_MESON_TAC[]]);;
4065 let CONVERGENT_EQ_CAUCHY = prove
4066 (`!s. (?l. (s --> l) sequentially) <=> cauchy s`,
4067 GEN_TAC THEN EQ_TAC THENL
4068 [REWRITE_TAC[LEFT_IMP_EXISTS_THM; CONVERGENT_IMP_CAUCHY];
4069 REWRITE_TAC[REWRITE_RULE[complete; IN_UNIV] COMPLETE_UNIV]]);;
4071 let CONVERGENT_IMP_BOUNDED = prove
4072 (`!s l. (s --> l) sequentially ==> bounded (IMAGE s (:num))`,
4073 REWRITE_TAC[LEFT_FORALL_IMP_THM; CONVERGENT_EQ_CAUCHY] THEN
4074 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CAUCHY_IMP_BOUNDED) THEN
4075 REWRITE_TAC[IMAGE; IN_UNIV]);;
4077 (* ------------------------------------------------------------------------- *)
4078 (* Total boundedness. *)
4079 (* ------------------------------------------------------------------------- *)
4081 let COMPACT_IMP_TOTALLY_BOUNDED = prove
4084 ==> !e. &0 < e ==> ?k. FINITE k /\ k SUBSET s /\
4085 s SUBSET (UNIONS(IMAGE (\x. ball(x,e)) k))`,
4086 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
4087 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN
4088 REWRITE_TAC[TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`; SUBSET] THEN
4089 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
4091 `?x:num->real^N. !n. x(n) IN s /\ !m. m < n ==> ~(dist(x(m),x(n)) < e)`
4095 !n. x(n) = @y. y IN s /\ !m. m < n ==> ~(dist(x(m),y) < e)`
4097 [MATCH_MP_TAC(MATCH_MP WF_REC WF_num) THEN SIMP_TAC[]; ALL_TAC] THEN
4098 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:num->real^N` THEN
4099 DISCH_TAC THEN MATCH_MP_TAC num_WF THEN X_GEN_TAC `n:num` THEN
4100 FIRST_X_ASSUM(SUBST1_TAC o SPEC `n:num`) THEN STRIP_TAC THEN
4101 CONV_TAC SELECT_CONV THEN
4102 FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (x:num->real^N) {m | m < n}`) THEN
4103 SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG_LT; NOT_FORALL_THM; NOT_IMP] THEN
4104 REWRITE_TAC[IN_UNIONS; IN_IMAGE; IN_ELIM_THM] THEN ASM_MESON_TAC[IN_BALL];
4106 REWRITE_TAC[compact; NOT_FORALL_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
4107 X_GEN_TAC `x:num->real^N` THEN REWRITE_TAC[NOT_IMP; FORALL_AND_THM] THEN
4108 STRIP_TAC THEN ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN REPEAT STRIP_TAC THEN
4109 FIRST_X_ASSUM(MP_TAC o MATCH_MP CONVERGENT_IMP_CAUCHY) THEN
4110 REWRITE_TAC[cauchy] THEN DISCH_THEN(MP_TAC o SPEC `e:real`) THEN
4111 ASM_REWRITE_TAC[o_THM; NOT_EXISTS_THM; NOT_IMP; NOT_FORALL_THM; NOT_IMP] THEN
4112 X_GEN_TAC `N:num` THEN MAP_EVERY EXISTS_TAC [`N:num`; `SUC N`] THEN
4113 CONJ_TAC THENL [ARITH_TAC; ASM_MESON_TAC[LT]]);;
4115 (* ------------------------------------------------------------------------- *)
4116 (* Heine-Borel theorem (following Burkill & Burkill vol. 2) *)
4117 (* ------------------------------------------------------------------------- *)
4119 let HEINE_BOREL_LEMMA = prove
4122 ==> !t. s SUBSET (UNIONS t) /\ (!b. b IN t ==> open b)
4124 !x. x IN s ==> ?b. b IN t /\ ball(x,e) SUBSET b`,
4125 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
4126 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN
4127 DISCH_THEN(CHOOSE_THEN (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
4128 DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `&1 / (&n + &1)`) THEN
4129 SIMP_TAC[REAL_LT_DIV; REAL_LT_01; REAL_ARITH `x <= y ==> x < y + &1`;
4130 FORALL_AND_THM; REAL_POS; NOT_FORALL_THM; NOT_IMP; SKOLEM_THM; compact] THEN
4131 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN REWRITE_TAC[NOT_EXISTS_THM] THEN
4132 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
4133 DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`l:real^N`; `r:num->num`] THEN
4135 SUBGOAL_THEN `?b:real^N->bool. l IN b /\ b IN t` STRIP_ASSUME_TAC THENL
4136 [ASM_MESON_TAC[SUBSET; IN_UNIONS]; ALL_TAC] THEN
4137 SUBGOAL_THEN `?e. &0 < e /\ !z:real^N. dist(z,l) < e ==> z IN b`
4138 STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[open_def]; ALL_TAC] THEN
4139 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
4140 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
4141 SUBGOAL_THEN `&0 < e / &2` (fun th ->
4142 REWRITE_TAC[th; o_THM] THEN MP_TAC(GEN_REWRITE_RULE I [REAL_ARCH_INV] th))
4143 THENL [ASM_REWRITE_TAC[REAL_HALF]; ALL_TAC] THEN
4144 DISCH_THEN(X_CHOOSE_THEN `N1:num` STRIP_ASSUME_TAC) THEN
4145 DISCH_THEN(X_CHOOSE_THEN `N2:num` STRIP_ASSUME_TAC) THEN
4146 FIRST_X_ASSUM(MP_TAC o SPECL
4147 [`(r:num->num)(N1 + N2)`; `b:real^N->bool`]) THEN
4148 ASM_REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
4149 FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC DIST_TRIANGLE_HALF_R THEN
4150 EXISTS_TAC `(f:num->real^N)(r(N1 + N2:num))` THEN CONJ_TAC THENL
4151 [ALL_TAC; FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC] THEN
4152 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_BALL]) THEN
4153 MATCH_MP_TAC(REAL_ARITH `a <= b ==> x < a ==> x < b`) THEN
4154 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `inv(&N1)` THEN
4155 ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN REWRITE_TAC[real_div; REAL_MUL_LID] THEN
4156 MATCH_MP_TAC REAL_LE_INV2 THEN
4157 REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
4158 ASM_MESON_TAC[ARITH_RULE `(~(n = 0) ==> 0 < n)`; LE_ADD; MONOTONE_BIGGER;
4159 LT_IMP_LE; LE_TRANS]);;
4161 let COMPACT_IMP_HEINE_BOREL = prove
4162 (`!s. compact (s:real^N->bool)
4163 ==> !f. (!t. t IN f ==> open t) /\ s SUBSET (UNIONS f)
4164 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (UNIONS f')`,
4165 REPEAT STRIP_TAC THEN
4166 FIRST_ASSUM(MP_TAC o SPEC `f:(real^N->bool)->bool` o
4167 MATCH_MP HEINE_BOREL_LEMMA) THEN ASM_REWRITE_TAC[] THEN
4168 DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
4169 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
4170 REWRITE_TAC[SKOLEM_THM; SUBSET; IN_BALL] THEN
4171 DISCH_THEN(X_CHOOSE_TAC `B:real^N->real^N->bool`) THEN
4172 FIRST_ASSUM(MP_TAC o SPEC `e:real` o
4173 MATCH_MP COMPACT_IMP_TOTALLY_BOUNDED) THEN
4174 ASM_REWRITE_TAC[UNIONS_IMAGE; SUBSET; IN_ELIM_THM] THEN
4175 REWRITE_TAC[IN_UNIONS; IN_BALL] THEN
4176 DISCH_THEN(X_CHOOSE_THEN `k:real^N->bool` STRIP_ASSUME_TAC) THEN
4177 EXISTS_TAC `IMAGE (B:real^N->real^N->bool) k` THEN
4178 ASM_SIMP_TAC[FINITE_IMAGE; SUBSET; IN_IMAGE; LEFT_IMP_EXISTS_THM] THEN
4179 ASM_MESON_TAC[IN_BALL]);;
4181 (* ------------------------------------------------------------------------- *)
4182 (* Bolzano-Weierstrass property. *)
4183 (* ------------------------------------------------------------------------- *)
4185 let HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS = prove
4187 (!f. (!t. t IN f ==> open t) /\ s SUBSET (UNIONS f)
4188 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (UNIONS f'))
4189 ==> !t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t`,
4190 REWRITE_TAC[RIGHT_IMP_FORALL_THM; limit_point_of] THEN REPEAT GEN_TAC THEN
4191 ONCE_REWRITE_TAC[TAUT `a ==> b /\ c ==> d <=> c ==> ~d ==> a ==> ~b`] THEN
4192 REWRITE_TAC[NOT_FORALL_THM; NOT_EXISTS_THM; RIGHT_AND_FORALL_THM] THEN
4193 DISCH_TAC THEN REWRITE_TAC[SKOLEM_THM] THEN
4194 DISCH_THEN(X_CHOOSE_TAC `f:real^N->real^N->bool`) THEN
4195 DISCH_THEN(MP_TAC o SPEC
4196 `{t:real^N->bool | ?x:real^N. x IN s /\ (t = f x)}`) THEN
4197 REWRITE_TAC[INFINITE; SUBSET; IN_ELIM_THM; IN_UNIONS; NOT_IMP] THEN
4198 ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
4199 DISCH_THEN(X_CHOOSE_THEN `g:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
4200 MATCH_MP_TAC FINITE_SUBSET THEN
4201 EXISTS_TAC `{x:real^N | x IN t /\ (f(x):real^N->bool) IN g}` THEN
4203 [MATCH_MP_TAC FINITE_IMAGE_INJ_GENERAL THEN ASM_MESON_TAC[SUBSET];
4204 SIMP_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `u:real^N` THEN
4205 DISCH_TAC THEN SUBGOAL_THEN `(u:real^N) IN s` ASSUME_TAC THEN
4206 ASM_MESON_TAC[SUBSET]]);;
4208 (* ------------------------------------------------------------------------- *)
4209 (* Complete the chain of compactness variants. *)
4210 (* ------------------------------------------------------------------------- *)
4212 let BOLZANO_WEIERSTRASS_IMP_BOUNDED = prove
4214 (!t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t)
4216 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
4217 SIMP_TAC[compact; bounded] THEN
4218 REWRITE_TAC[NOT_FORALL_THM; NOT_EXISTS_THM; SKOLEM_THM; NOT_IMP] THEN
4219 REWRITE_TAC[REAL_NOT_LE] THEN
4220 DISCH_THEN(X_CHOOSE_TAC `beyond:real->real^N`) THEN
4221 (MP_TAC o prove_recursive_functions_exist num_RECURSION)
4222 `(f(0) = beyond(&0)) /\
4223 (!n. f(SUC n) = beyond(norm(f n) + &1):real^N)` THEN
4224 DISCH_THEN(X_CHOOSE_THEN `x:num->real^N` STRIP_ASSUME_TAC) THEN
4225 EXISTS_TAC `IMAGE (x:num->real^N) UNIV` THEN
4227 `!m n. m < n ==> norm((x:num->real^N) m) + &1 < norm(x n)`
4229 [GEN_TAC THEN INDUCT_TAC THEN ASM_REWRITE_TAC[LT] THEN
4230 ASM_MESON_TAC[REAL_LT_TRANS; REAL_ARITH `b < b + &1`];
4232 SUBGOAL_THEN `!m n. ~(m = n) ==> &1 < dist((x:num->real^N) m,x n)`
4234 [REPEAT GEN_TAC THEN REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC
4235 (SPECL [`m:num`; `n:num`] LT_CASES) THEN
4236 ASM_MESON_TAC[dist; LT_CASES; NORM_TRIANGLE_SUB; NORM_SUB;
4237 REAL_ARITH `x + &1 < y /\ y <= x + d ==> &1 < d`];
4239 REPEAT CONJ_TAC THENL
4240 [ASM_MESON_TAC[INFINITE_IMAGE_INJ; num_INFINITE; DIST_REFL;
4241 REAL_ARITH `~(&1 < &0)`];
4242 REWRITE_TAC[SUBSET; IN_IMAGE; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN
4243 GEN_TAC THEN INDUCT_TAC THEN ASM_MESON_TAC[];
4245 X_GEN_TAC `l:real^N` THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
4246 REWRITE_TAC[IN_IMAGE; IN_UNIV; LEFT_AND_EXISTS_THM] THEN
4247 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2] THEN
4248 STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC `&1 / &2`) THEN
4249 CONV_TAC REAL_RAT_REDUCE_CONV THEN
4250 DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN
4251 FIRST_X_ASSUM(MP_TAC o SPEC `dist((x:num->real^N) k,l)`) THEN
4252 ASM_SIMP_TAC[DIST_POS_LT] THEN
4253 DISCH_THEN(X_CHOOSE_THEN `m:num` STRIP_ASSUME_TAC) THEN
4254 ASM_CASES_TAC `m:num = k` THEN
4255 ASM_MESON_TAC[DIST_TRIANGLE_HALF_L; REAL_LT_TRANS; REAL_LT_REFL]);;
4257 let SEQUENCE_INFINITE_LEMMA = prove
4258 (`!f l. (!n. ~(f(n) = l)) /\ (f --> l) sequentially
4259 ==> INFINITE {y:real^N | ?n. y = f n}`,
4260 REWRITE_TAC[INFINITE] THEN REPEAT STRIP_TAC THEN MP_TAC(ISPEC
4261 `IMAGE (\y:real^N. dist(y,l)) {y | ?n:num. y = f n}` INF_FINITE) THEN
4262 ASM_SIMP_TAC[GSYM MEMBER_NOT_EMPTY; IN_IMAGE; FINITE_IMAGE; IN_ELIM_THM] THEN
4263 ASM_MESON_TAC[LIM_SEQUENTIALLY; LE_REFL; REAL_NOT_LE; DIST_POS_LT]);;
4265 let LIMPT_OF_SEQUENCE_SUBSEQUENCE = prove
4267 l limit_point_of (IMAGE f (:num))
4268 ==> ?r. (!m n. m < n ==> r(m) < r(n)) /\ ((f o r) --> l) sequentially`,
4269 REPEAT STRIP_TAC THEN
4270 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIMPT_APPROACHABLE]) THEN
4271 DISCH_THEN(MP_TAC o GEN `n:num` o SPEC
4272 `inf((inv(&n + &1)) INSERT
4273 IMAGE (\k. dist((f:num->real^N) k,l))
4274 {k | k IN 0..n /\ ~(f k = l)})`) THEN
4275 SIMP_TAC[REAL_LT_INF_FINITE; FINITE_INSERT; NOT_INSERT_EMPTY;
4276 FINITE_RESTRICT; FINITE_NUMSEG; FINITE_IMAGE] THEN
4277 REWRITE_TAC[FORALL_IN_INSERT; EXISTS_IN_IMAGE; FORALL_IN_IMAGE; IN_UNIV] THEN
4278 REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
4279 SIMP_TAC[FORALL_AND_THM; FORALL_IN_GSPEC; GSYM DIST_NZ; SKOLEM_THM] THEN
4280 DISCH_THEN(X_CHOOSE_THEN `nn:num->num` STRIP_ASSUME_TAC) THEN
4281 (MP_TAC o prove_recursive_functions_exist num_RECURSION)
4282 `r 0 = nn 0 /\ (!n. r (SUC n) = nn(r n))` THEN
4283 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `r:num->num` THEN
4285 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
4286 [MATCH_MP_TAC TRANSITIVE_STEPWISE_LT THEN REWRITE_TAC[LT_TRANS] THEN
4287 X_GEN_TAC `n:num` THEN ASM_REWRITE_TAC[] THEN
4288 FIRST_X_ASSUM(MP_TAC o SPECL
4289 [`(r:num->num) n`; `(nn:num->num)(r(n:num))`]) THEN
4290 ASM_REWRITE_TAC[IN_NUMSEG; LE_0; REAL_LT_REFL] THEN ARITH_TAC;
4291 DISCH_THEN(ASSUME_TAC o MATCH_MP MONOTONE_BIGGER)] THEN
4292 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
4293 X_GEN_TAC `e:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_ARCH_INV] THEN
4294 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
4295 MATCH_MP_TAC num_INDUCTION THEN ASM_REWRITE_TAC[CONJUNCT1 LE] THEN
4296 X_GEN_TAC `n:num` THEN DISCH_THEN(K ALL_TAC) THEN DISCH_TAC THEN
4297 ASM_REWRITE_TAC[o_THM] THEN MATCH_MP_TAC REAL_LT_TRANS THEN
4298 EXISTS_TAC `inv(&((r:num->num) n) + &1)` THEN ASM_REWRITE_TAC[] THEN
4299 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN
4300 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
4301 ASM_SIMP_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_LT; LE_1; REAL_OF_NUM_ADD] THEN
4302 MATCH_MP_TAC(ARITH_RULE `N <= SUC n /\ n <= r n ==> N <= r n + 1`) THEN
4303 ASM_REWRITE_TAC[]);;
4305 let SEQUENCE_UNIQUE_LIMPT = prove
4307 (f --> l) sequentially /\ l' limit_point_of {y | ?n. y = f n}
4309 REWRITE_TAC[SET_RULE `{y | ?n. y = f n} = IMAGE f (:num)`] THEN
4310 REPEAT STRIP_TAC THEN
4311 FIRST_X_ASSUM(MP_TAC o MATCH_MP LIMPT_OF_SEQUENCE_SUBSEQUENCE) THEN
4312 DISCH_THEN(X_CHOOSE_THEN `r:num->num` STRIP_ASSUME_TAC) THEN
4313 MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
4314 EXISTS_TAC `(f:num->real^N) o (r:num->num)` THEN
4315 ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; LIM_SUBSEQUENCE]);;
4317 let BOLZANO_WEIERSTRASS_IMP_CLOSED = prove
4319 (!t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t)
4321 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS] THEN
4322 MAP_EVERY X_GEN_TAC [`f:num->real^N`; `l:real^N`] THEN
4324 MAP_EVERY (MP_TAC o ISPECL [`f:num->real^N`; `l:real^N`])
4325 [SEQUENCE_UNIQUE_LIMPT; SEQUENCE_INFINITE_LEMMA] THEN
4327 `(~d ==> a /\ ~(b /\ c)) ==> (a ==> b) ==> c ==> d`) THEN
4328 DISCH_TAC THEN CONJ_TAC THENL [ASM_MESON_TAC[]; STRIP_TAC] THEN
4329 FIRST_X_ASSUM(MP_TAC o SPEC `{y:real^N | ?n:num. y = f n}`) THEN
4330 ASM_REWRITE_TAC[NOT_IMP] THEN CONJ_TAC THENL
4331 [REWRITE_TAC[SUBSET; IN_ELIM_THM];
4332 ABBREV_TAC `t = {y:real^N | ?n:num. y = f n}`] THEN
4335 (* ------------------------------------------------------------------------- *)
4336 (* Hence express everything as an equivalence. *)
4337 (* ------------------------------------------------------------------------- *)
4339 let COMPACT_EQ_HEINE_BOREL = prove
4342 !f. (!t. t IN f ==> open t) /\ s SUBSET (UNIONS f)
4343 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET (UNIONS f')`,
4344 GEN_TAC THEN EQ_TAC THEN SIMP_TAC[COMPACT_IMP_HEINE_BOREL] THEN
4345 DISCH_THEN(MP_TAC o MATCH_MP HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS) THEN
4346 DISCH_TAC THEN MATCH_MP_TAC BOUNDED_CLOSED_IMP_COMPACT THEN
4347 ASM_SIMP_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED;
4348 BOLZANO_WEIERSTRASS_IMP_CLOSED]);;
4350 let COMPACT_EQ_BOLZANO_WEIERSTRASS = prove
4353 !t. INFINITE t /\ t SUBSET s ==> ?x. x IN s /\ x limit_point_of t`,
4354 GEN_TAC THEN EQ_TAC THENL
4355 [SIMP_TAC[COMPACT_EQ_HEINE_BOREL; HEINE_BOREL_IMP_BOLZANO_WEIERSTRASS];
4356 SIMP_TAC[BOLZANO_WEIERSTRASS_IMP_BOUNDED; BOLZANO_WEIERSTRASS_IMP_CLOSED;
4357 BOUNDED_CLOSED_IMP_COMPACT]]);;
4359 let COMPACT_EQ_BOUNDED_CLOSED = prove
4360 (`!s:real^N->bool. compact s <=> bounded s /\ closed s`,
4361 GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BOUNDED_CLOSED_IMP_COMPACT] THEN
4362 SIMP_TAC[COMPACT_EQ_BOLZANO_WEIERSTRASS; BOLZANO_WEIERSTRASS_IMP_BOUNDED;
4363 BOLZANO_WEIERSTRASS_IMP_CLOSED]);;
4365 let COMPACT_IMP_BOUNDED = prove
4366 (`!s. compact s ==> bounded s`,
4367 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED]);;
4369 let COMPACT_IMP_CLOSED = prove
4370 (`!s. compact s ==> closed s`,
4371 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED]);;
4373 let COMPACT_SEQUENCE_WITH_LIMIT = prove
4375 (f --> l) sequentially ==> compact (l INSERT IMAGE f (:num))`,
4376 REPEAT STRIP_TAC THEN REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
4377 REWRITE_TAC[BOUNDED_INSERT] THEN CONJ_TAC THENL
4378 [ASM_MESON_TAC[CONVERGENT_IMP_BOUNDED];
4379 SIMP_TAC[CLOSED_LIMPT; LIMPT_INSERT; IN_INSERT] THEN
4380 REWRITE_TAC[IMAGE; IN_UNIV] THEN REPEAT STRIP_TAC THEN DISJ1_TAC THEN
4381 MATCH_MP_TAC SEQUENCE_UNIQUE_LIMPT THEN ASM_MESON_TAC[]]);;
4383 let CLOSED_IN_COMPACT = prove
4384 (`!s t:real^N->bool.
4385 compact s /\ closed_in (subtopology euclidean s) t
4387 SIMP_TAC[IMP_CONJ; COMPACT_EQ_BOUNDED_CLOSED; CLOSED_IN_CLOSED_EQ] THEN
4388 MESON_TAC[BOUNDED_SUBSET]);;
4390 (* ------------------------------------------------------------------------- *)
4391 (* A version of Heine-Borel for subtopology. *)
4392 (* ------------------------------------------------------------------------- *)
4394 let COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY = prove
4397 (!f. (!t. t IN f ==> open_in(subtopology euclidean s) t) /\
4399 ==> ?f'. f' SUBSET f /\ FINITE f' /\ s SUBSET UNIONS f')`,
4400 GEN_TAC THEN REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN EQ_TAC THEN
4401 DISCH_TAC THEN X_GEN_TAC `f:(real^N->bool)->bool` THENL
4402 [REWRITE_TAC[OPEN_IN_OPEN] THEN
4403 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
4404 REWRITE_TAC[SKOLEM_THM] THEN
4405 DISCH_THEN(CONJUNCTS_THEN2
4406 (X_CHOOSE_TAC `m:(real^N->bool)->(real^N->bool)`) ASSUME_TAC) THEN
4407 FIRST_X_ASSUM(MP_TAC o SPEC
4408 `IMAGE (m:(real^N->bool)->(real^N->bool)) f`) THEN
4409 ASM_SIMP_TAC[FORALL_IN_IMAGE] THEN
4410 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4411 DISCH_THEN(X_CHOOSE_THEN `f':(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
4412 EXISTS_TAC `IMAGE (\t:real^N->bool. s INTER t) f'` THEN
4413 ASM_SIMP_TAC[FINITE_IMAGE; UNIONS_IMAGE; SUBSET; FORALL_IN_IMAGE] THEN
4414 CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
4415 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET_IMAGE]) THEN
4416 STRIP_TAC THEN ASM_REWRITE_TAC[FORALL_IN_IMAGE] THEN ASM_MESON_TAC[SUBSET];
4418 FIRST_X_ASSUM(MP_TAC o SPEC `{s INTER t:real^N->bool | t IN f}`) THEN
4419 REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; OPEN_IN_OPEN; UNIONS_IMAGE] THEN
4420 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4421 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN
4422 REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE; UNIONS_IMAGE] THEN
4423 MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]]);;
4425 (* ------------------------------------------------------------------------- *)
4426 (* More easy lemmas. *)
4427 (* ------------------------------------------------------------------------- *)
4429 let COMPACT_CLOSURE = prove
4430 (`!s. compact(closure s) <=> bounded s`,
4431 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_CLOSURE; BOUNDED_CLOSURE_EQ]);;
4433 let BOLZANO_WEIERSTRASS_CONTRAPOS = prove
4434 (`!s t:real^N->bool.
4435 compact s /\ t SUBSET s /\
4436 (!x. x IN s ==> ~(x limit_point_of t))
4438 REWRITE_TAC[COMPACT_EQ_BOLZANO_WEIERSTRASS; INFINITE] THEN MESON_TAC[]);;
4440 let DISCRETE_BOUNDED_IMP_FINITE = prove
4441 (`!s:real^N->bool e.
4443 (!x y. x IN s /\ y IN s /\ norm(y - x) < e ==> y = x) /\
4446 REPEAT STRIP_TAC THEN
4447 SUBGOAL_THEN `compact(s:real^N->bool)` MP_TAC THENL
4448 [ASM_REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
4449 ASM_MESON_TAC[DISCRETE_IMP_CLOSED];
4450 DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_HEINE_BOREL)] THEN
4451 DISCH_THEN(MP_TAC o SPEC `IMAGE (\x:real^N. ball(x,e)) s`) THEN
4452 REWRITE_TAC[FORALL_IN_IMAGE; OPEN_BALL; UNIONS_IMAGE; IN_ELIM_THM] THEN
4454 [REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ASM_MESON_TAC[CENTRE_IN_BALL];
4455 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`]] THEN
4456 REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE] THEN
4457 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
4458 SUBGOAL_THEN `s:real^N->bool = t` (fun th -> ASM_REWRITE_TAC[th]) THEN
4459 MATCH_MP_TAC SUBSET_ANTISYM THEN ASM_REWRITE_TAC[] THEN
4460 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
4461 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [UNIONS_IMAGE]) THEN
4462 DISCH_THEN(MP_TAC o SPEC `x:real^N` o GEN_REWRITE_RULE I [SUBSET]) THEN
4463 ASM_REWRITE_TAC[IN_ELIM_THM; IN_BALL; dist] THEN ASM_MESON_TAC[SUBSET]);;
4465 let BOLZANO_WEIERSTRASS = prove
4466 (`!s:real^N->bool. bounded s /\ INFINITE s ==> ?x. x limit_point_of s`,
4467 GEN_TAC THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
4468 FIRST_ASSUM(ASSUME_TAC o MATCH_MP NO_LIMIT_POINT_IMP_CLOSED) THEN
4470 MP_TAC(ISPEC `s:real^N->bool` COMPACT_EQ_BOLZANO_WEIERSTRASS) THEN
4471 ASM_REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
4472 DISCH_THEN(MP_TAC o SPEC `s:real^N->bool`) THEN
4473 ASM_REWRITE_TAC[SUBSET_REFL] THEN ASM_MESON_TAC[]);;
4475 (* ------------------------------------------------------------------------- *)
4476 (* In particular, some common special cases. *)
4477 (* ------------------------------------------------------------------------- *)
4479 let COMPACT_EMPTY = prove
4481 REWRITE_TAC[compact; NOT_IN_EMPTY]);;
4483 let COMPACT_UNION = prove
4484 (`!s t. compact s /\ compact t ==> compact (s UNION t)`,
4485 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_UNION; CLOSED_UNION]);;
4487 let COMPACT_INTER = prove
4488 (`!s t. compact s /\ compact t ==> compact (s INTER t)`,
4489 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_INTER; CLOSED_INTER]);;
4491 let COMPACT_INTER_CLOSED = prove
4492 (`!s t. compact s /\ closed t ==> compact (s INTER t)`,
4493 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_INTER] THEN
4494 MESON_TAC[BOUNDED_SUBSET; INTER_SUBSET]);;
4496 let CLOSED_INTER_COMPACT = prove
4497 (`!s t. closed s /\ compact t ==> compact (s INTER t)`,
4498 MESON_TAC[COMPACT_INTER_CLOSED; INTER_COMM]);;
4500 let COMPACT_INTERS = prove
4501 (`!f:(real^N->bool)->bool.
4502 (!s. s IN f ==> compact s) /\ ~(f = {})
4503 ==> compact(INTERS f)`,
4504 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_INTERS] THEN
4505 REPEAT STRIP_TAC THEN MATCH_MP_TAC BOUNDED_INTERS THEN ASM SET_TAC[]);;
4507 let FINITE_IMP_CLOSED = prove
4508 (`!s. FINITE s ==> closed s`,
4509 MESON_TAC[BOLZANO_WEIERSTRASS_IMP_CLOSED; INFINITE; FINITE_SUBSET]);;
4511 let FINITE_IMP_CLOSED_IN = prove
4512 (`!s t. FINITE s /\ s SUBSET t ==> closed_in (subtopology euclidean t) s`,
4513 SIMP_TAC[CLOSED_SUBSET_EQ; FINITE_IMP_CLOSED]);;
4515 let FINITE_IMP_COMPACT = prove
4516 (`!s. FINITE s ==> compact s`,
4517 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; FINITE_IMP_CLOSED; FINITE_IMP_BOUNDED]);;
4519 let COMPACT_SING = prove
4521 SIMP_TAC[FINITE_IMP_COMPACT; FINITE_RULES]);;
4523 let COMPACT_INSERT = prove
4524 (`!a s. compact s ==> compact(a INSERT s)`,
4525 ONCE_REWRITE_TAC[SET_RULE `a INSERT s = {a} UNION s`] THEN
4526 SIMP_TAC[COMPACT_UNION; COMPACT_SING]);;
4528 let CLOSED_SING = prove
4530 MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; COMPACT_SING]);;
4532 let CLOSED_IN_SING = prove
4533 (`!u x:real^N. closed_in (subtopology euclidean u) {x} <=> x IN u`,
4534 SIMP_TAC[CLOSED_SUBSET_EQ; CLOSED_SING] THEN SET_TAC[]);;
4536 let CLOSURE_SING = prove
4537 (`!x:real^N. closure {x} = {x}`,
4538 SIMP_TAC[CLOSURE_CLOSED; CLOSED_SING]);;
4540 let CLOSED_INSERT = prove
4541 (`!a s. closed s ==> closed(a INSERT s)`,
4542 ONCE_REWRITE_TAC[SET_RULE `a INSERT s = {a} UNION s`] THEN
4543 SIMP_TAC[CLOSED_UNION; CLOSED_SING]);;
4545 let COMPACT_CBALL = prove
4546 (`!x e. compact(cball(x,e))`,
4547 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_CBALL; CLOSED_CBALL]);;
4549 let COMPACT_FRONTIER_BOUNDED = prove
4550 (`!s. bounded s ==> compact(frontier s)`,
4551 SIMP_TAC[frontier; COMPACT_EQ_BOUNDED_CLOSED;
4552 CLOSED_DIFF; OPEN_INTERIOR; CLOSED_CLOSURE] THEN
4553 MESON_TAC[SUBSET_DIFF; BOUNDED_SUBSET; BOUNDED_CLOSURE]);;
4555 let COMPACT_FRONTIER = prove
4556 (`!s. compact s ==> compact (frontier s)`,
4557 MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; COMPACT_FRONTIER_BOUNDED]);;
4559 let BOUNDED_FRONTIER = prove
4560 (`!s:real^N->bool. bounded s ==> bounded(frontier s)`,
4561 MESON_TAC[COMPACT_FRONTIER_BOUNDED; COMPACT_IMP_BOUNDED]);;
4563 let FRONTIER_SUBSET_COMPACT = prove
4564 (`!s. compact s ==> frontier s SUBSET s`,
4565 MESON_TAC[FRONTIER_SUBSET_CLOSED; COMPACT_EQ_BOUNDED_CLOSED]);;
4567 let OPEN_DELETE = prove
4568 (`!s x. open s ==> open(s DELETE x)`,
4569 let lemma = prove(`s DELETE x = s DIFF {x}`,SET_TAC[]) in
4570 SIMP_TAC[lemma; OPEN_DIFF; CLOSED_SING]);;
4572 let OPEN_IN_DELETE = prove
4574 open_in (subtopology euclidean u) s
4575 ==> open_in (subtopology euclidean u) (s DELETE a)`,
4576 REPEAT STRIP_TAC THEN ASM_CASES_TAC `(a:real^N) IN s` THENL
4577 [ONCE_REWRITE_TAC[SET_RULE `s DELETE a = s DIFF {a}`] THEN
4578 MATCH_MP_TAC OPEN_IN_DIFF THEN ASM_REWRITE_TAC[CLOSED_IN_SING] THEN
4579 FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN ASM SET_TAC[];
4580 ASM_SIMP_TAC[SET_RULE `~(a IN s) ==> s DELETE a = s`]]);;
4582 let CLOSED_INTERS_COMPACT = prove
4584 closed s <=> !e. compact(cball(vec 0,e) INTER s)`,
4585 GEN_TAC THEN EQ_TAC THENL
4586 [SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_INTER; CLOSED_CBALL;
4587 BOUNDED_INTER; BOUNDED_CBALL];
4589 STRIP_TAC THEN REWRITE_TAC[CLOSED_LIMPT] THEN
4590 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
4591 FIRST_X_ASSUM(MP_TAC o SPEC `norm(x:real^N) + &1`) THEN
4592 DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_CLOSED) THEN
4593 REWRITE_TAC[CLOSED_LIMPT] THEN DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
4594 REWRITE_TAC[IN_INTER] THEN ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
4595 POP_ASSUM MP_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
4596 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
4597 FIRST_X_ASSUM(MP_TAC o SPEC `min e (&1 / &2)`) THEN
4598 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN
4599 X_GEN_TAC `y:real^N` THEN SIMP_TAC[IN_INTER; IN_CBALL] THEN NORM_ARITH_TAC);;
4601 let COMPACT_UNIONS = prove
4602 (`!s. FINITE s /\ (!t. t IN s ==> compact t) ==> compact(UNIONS s)`,
4603 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_UNIONS; BOUNDED_UNIONS]);;
4605 let COMPACT_DIFF = prove
4606 (`!s t. compact s /\ open t ==> compact(s DIFF t)`,
4607 ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN
4608 SIMP_TAC[COMPACT_INTER_CLOSED; GSYM OPEN_CLOSED]);;
4610 let COMPACT_SPHERE = prove
4611 (`!a:real^N r. compact(sphere(a,r))`,
4613 REWRITE_TAC[GSYM FRONTIER_CBALL] THEN MATCH_MP_TAC COMPACT_FRONTIER THEN
4614 REWRITE_TAC[COMPACT_CBALL]);;
4616 let BOUNDED_SPHERE = prove
4617 (`!a:real^N r. bounded(sphere(a,r))`,
4618 SIMP_TAC[COMPACT_SPHERE; COMPACT_IMP_BOUNDED]);;
4620 let CLOSED_SPHERE = prove
4621 (`!a r. closed(sphere(a,r))`,
4622 SIMP_TAC[COMPACT_SPHERE; COMPACT_IMP_CLOSED]);;
4624 let FRONTIER_SING = prove
4625 (`!a:real^N. frontier {a} = {a}`,
4626 REWRITE_TAC[frontier; CLOSURE_SING; INTERIOR_SING; DIFF_EMPTY]);;
4628 (* ------------------------------------------------------------------------- *)
4629 (* Finite intersection property. I could make it an equivalence in fact. *)
4630 (* ------------------------------------------------------------------------- *)
4632 let COMPACT_IMP_FIP = prove
4633 (`!s:real^N->bool f.
4635 (!t. t IN f ==> closed t) /\
4636 (!f'. FINITE f' /\ f' SUBSET f ==> ~(s INTER (INTERS f') = {}))
4637 ==> ~(s INTER (INTERS f) = {})`,
4638 let lemma = prove(`(s = UNIV DIFF t) <=> (UNIV DIFF s = t)`,SET_TAC[]) in
4639 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
4640 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL]) THEN
4641 DISCH_THEN(MP_TAC o SPEC `IMAGE (\t:real^N->bool. UNIV DIFF t) f`) THEN
4642 ASM_SIMP_TAC[FORALL_IN_IMAGE] THEN
4643 DISCH_THEN(fun th -> REPEAT STRIP_TAC THEN MP_TAC th) THEN
4644 ASM_SIMP_TAC[OPEN_DIFF; CLOSED_DIFF; OPEN_UNIV; CLOSED_UNIV; NOT_IMP] THEN
4646 [UNDISCH_TAC `(s:real^N->bool) INTER INTERS f = {}` THEN
4647 ONCE_REWRITE_TAC[SUBSET; EXTENSION] THEN
4648 REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE] THEN SET_TAC[];
4649 DISCH_THEN(X_CHOOSE_THEN `g:(real^N->bool)->bool` MP_TAC) THEN
4650 FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE (\t:real^N->bool. UNIV DIFF t) g`) THEN
4651 ASM_CASES_TAC `FINITE(g:(real^N->bool)->bool)` THEN
4652 ASM_SIMP_TAC[FINITE_IMAGE] THEN ONCE_REWRITE_TAC[SUBSET; EXTENSION] THEN
4653 REWRITE_TAC[FORALL_IN_IMAGE; IN_INTER; IN_INTERS; IN_IMAGE; IN_DIFF;
4654 IN_UNIV; NOT_IN_EMPTY; lemma; UNWIND_THM1; IN_UNIONS] THEN
4657 let CLOSED_FIP = prove
4658 (`!f. (!t:real^N->bool. t IN f ==> closed t) /\ (?t. t IN f /\ bounded t) /\
4659 (!f'. FINITE f' /\ f' SUBSET f ==> ~(INTERS f' = {}))
4660 ==> ~(INTERS f = {})`,
4661 GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
4662 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC)
4664 MATCH_MP_TAC(SET_RULE `!s. ~(s INTER f = {}) ==> ~(f = {})`) THEN
4665 EXISTS_TAC `s:real^N->bool` THEN MATCH_MP_TAC COMPACT_IMP_FIP THEN
4666 ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
4667 GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC COMPACT_IMP_FIP THEN
4668 ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
4669 CONJ_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC] THEN
4670 GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[GSYM INTERS_INSERT] THEN
4671 FIRST_X_ASSUM MATCH_MP_TAC THEN
4672 ASM_REWRITE_TAC[FINITE_INSERT] THEN ASM SET_TAC[]);;
4674 let COMPACT_FIP = prove
4675 (`!f. (!t:real^N->bool. t IN f ==> compact t) /\
4676 (!f'. FINITE f' /\ f' SUBSET f ==> ~(INTERS f' = {}))
4677 ==> ~(INTERS f = {})`,
4678 GEN_TAC THEN STRIP_TAC THEN
4679 ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THEN
4680 ASM_REWRITE_TAC[INTERS_0; UNIV_NOT_EMPTY] THEN
4681 MATCH_MP_TAC CLOSED_FIP THEN
4682 ASM_SIMP_TAC[COMPACT_IMP_CLOSED] THEN
4683 ASM_MESON_TAC[MEMBER_NOT_EMPTY; COMPACT_IMP_BOUNDED]);;
4685 (* ------------------------------------------------------------------------- *)
4686 (* Bounded closed nest property (proof does not use Heine-Borel). *)
4687 (* ------------------------------------------------------------------------- *)
4689 let BOUNDED_CLOSED_NEST = prove
4690 (`!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\
4691 (!m n. m <= n ==> s(n) SUBSET s(m)) /\
4693 ==> ?a:real^N. !n:num. a IN s(n)`,
4694 GEN_TAC THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; SKOLEM_THM] THEN
4695 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
4696 DISCH_THEN(CONJUNCTS_THEN2
4697 (X_CHOOSE_TAC `a:num->real^N`) STRIP_ASSUME_TAC) THEN
4698 SUBGOAL_THEN `compact(s 0:real^N->bool)` MP_TAC THENL
4699 [ASM_MESON_TAC[BOUNDED_CLOSED_IMP_COMPACT]; ALL_TAC] THEN
4700 REWRITE_TAC[compact] THEN
4701 DISCH_THEN(MP_TAC o SPEC `a:num->real^N`) THEN
4702 ANTS_TAC THENL [ASM_MESON_TAC[SUBSET; LE_0]; ALL_TAC] THEN
4703 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real^N` THEN
4704 REWRITE_TAC[LIM_SEQUENTIALLY; o_THM] THEN
4705 DISCH_THEN(X_CHOOSE_THEN `r:num->num` STRIP_ASSUME_TAC) THEN
4706 GEN_REWRITE_TAC I [TAUT `p <=> ~(~p)`] THEN
4707 GEN_REWRITE_TAC RAND_CONV [NOT_FORALL_THM] THEN
4708 DISCH_THEN(X_CHOOSE_THEN `N:num` MP_TAC) THEN
4709 MP_TAC(ISPECL [`l:real^N`; `(s:num->real^N->bool) N`]
4710 CLOSED_APPROACHABLE) THEN
4711 ASM_MESON_TAC[SUBSET; LE_REFL; LE_TRANS; LE_CASES; MONOTONE_BIGGER]);;
4713 (* ------------------------------------------------------------------------- *)
4714 (* Decreasing case does not even need compactness, just completeness. *)
4715 (* ------------------------------------------------------------------------- *)
4717 let DECREASING_CLOSED_NEST = prove
4718 (`!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\
4719 (!m n. m <= n ==> s(n) SUBSET s(m)) /\
4720 (!e. &0 < e ==> ?n. !x y. x IN s(n) /\ y IN s(n) ==> dist(x,y) < e)
4721 ==> ?a:real^N. !n:num. a IN s(n)`,
4722 GEN_TAC THEN REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; SKOLEM_THM] THEN
4723 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
4724 DISCH_THEN(CONJUNCTS_THEN2
4725 (X_CHOOSE_TAC `a:num->real^N`) STRIP_ASSUME_TAC) THEN
4726 SUBGOAL_THEN `?l:real^N. (a --> l) sequentially` MP_TAC THENL
4727 [ASM_MESON_TAC[cauchy; GE; SUBSET; LE_TRANS; LE_REFL;
4728 complete; COMPLETE_UNIV; IN_UNIV];
4729 ASM_MESON_TAC[LIM_SEQUENTIALLY; CLOSED_APPROACHABLE;
4730 SUBSET; LE_REFL; LE_TRANS; LE_CASES]]);;
4732 (* ------------------------------------------------------------------------- *)
4733 (* Strengthen it to the intersection actually being a singleton. *)
4734 (* ------------------------------------------------------------------------- *)
4736 let DECREASING_CLOSED_NEST_SING = prove
4737 (`!s. (!n. closed(s n)) /\ (!n. ~(s n = {})) /\
4738 (!m n. m <= n ==> s(n) SUBSET s(m)) /\
4739 (!e. &0 < e ==> ?n. !x y. x IN s(n) /\ y IN s(n) ==> dist(x,y) < e)
4740 ==> ?a:real^N. INTERS {t | ?n:num. t = s n} = {a}`,
4741 GEN_TAC THEN DISCH_TAC THEN
4742 FIRST_ASSUM(MP_TAC o MATCH_MP DECREASING_CLOSED_NEST) THEN
4743 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN
4744 DISCH_TAC THEN REWRITE_TAC[EXTENSION; IN_INTERS; IN_SING; IN_ELIM_THM] THEN
4745 ASM_MESON_TAC[DIST_POS_LT; REAL_LT_REFL; SUBSET; LE_CASES]);;
4747 (* ------------------------------------------------------------------------- *)
4748 (* A version for a more general chain, not indexed by N. *)
4749 (* ------------------------------------------------------------------------- *)
4751 let BOUNDED_CLOSED_CHAIN = prove
4752 (`!f b:real^N->bool.
4753 (!s. s IN f ==> closed s /\ ~(s = {})) /\
4754 (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s) /\
4756 ==> ~(INTERS f = {})`,
4757 REPEAT GEN_TAC THEN STRIP_TAC THEN
4758 SUBGOAL_THEN `~(b INTER (INTERS f):real^N->bool = {})` MP_TAC THENL
4759 [ALL_TAC; SET_TAC[]] THEN
4760 MATCH_MP_TAC COMPACT_IMP_FIP THEN
4761 ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN
4762 X_GEN_TAC `u:(real^N->bool)->bool` THEN STRIP_TAC THEN
4763 SUBGOAL_THEN `?s:real^N->bool. s IN f /\ !t. t IN u ==> s SUBSET t`
4764 MP_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
4765 UNDISCH_TAC `(u:(real^N->bool)->bool) SUBSET f` THEN
4766 UNDISCH_TAC `FINITE(u:(real^N->bool)->bool)` THEN
4767 SPEC_TAC(`u:(real^N->bool)->bool`,`u:(real^N->bool)->bool`) THEN
4768 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
4769 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
4770 MAP_EVERY X_GEN_TAC [`t:real^N->bool`; `u:(real^N->bool)->bool`] THEN
4771 REWRITE_TAC[INSERT_SUBSET] THEN
4772 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
4773 ASM_REWRITE_TAC[] THEN
4774 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
4775 DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN
4776 FIRST_X_ASSUM(MP_TAC o SPECL [`s:real^N->bool`; `t:real^N->bool`]) THEN
4779 (* ------------------------------------------------------------------------- *)
4780 (* Analogous things directly for compactness. *)
4781 (* ------------------------------------------------------------------------- *)
4783 let COMPACT_CHAIN = prove
4784 (`!f:(real^N->bool)->bool.
4785 (!s. s IN f ==> compact s /\ ~(s = {})) /\
4786 (!s t. s IN f /\ t IN f ==> s SUBSET t \/ t SUBSET s)
4787 ==> ~(INTERS f = {})`,
4788 GEN_TAC THEN REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN STRIP_TAC THEN
4789 ASM_CASES_TAC `f:(real^N->bool)->bool = {}` THENL
4790 [ASM_REWRITE_TAC[INTERS_0] THEN SET_TAC[];
4791 MATCH_MP_TAC BOUNDED_CLOSED_CHAIN THEN ASM SET_TAC[]]);;
4793 let COMPACT_NEST = prove
4794 (`!s. (!n. compact(s n) /\ ~(s n = {})) /\
4795 (!m n. m <= n ==> s n SUBSET s m)
4796 ==> ~(INTERS {s n | n IN (:num)} = {})`,
4797 GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC COMPACT_CHAIN THEN
4798 ASM_SIMP_TAC[FORALL_IN_GSPEC; IN_UNIV; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
4799 MATCH_MP_TAC WLOG_LE THEN ASM_MESON_TAC[]);;
4801 (* ------------------------------------------------------------------------- *)
4802 (* Cauchy-type criteria for *uniform* convergence. *)
4803 (* ------------------------------------------------------------------------- *)
4805 let UNIFORMLY_CONVERGENT_EQ_CAUCHY = prove
4806 (`!P s:num->A->real^N.
4808 ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e) <=>
4810 ==> ?N. !m n x. N <= m /\ N <= n /\ P x
4811 ==> dist(s m x,s n x) < e)`,
4812 REPEAT GEN_TAC THEN EQ_TAC THENL
4813 [DISCH_THEN(X_CHOOSE_TAC `l:A->real^N`) THEN X_GEN_TAC `e:real` THEN
4814 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
4815 ASM_REWRITE_TAC[REAL_HALF] THEN MESON_TAC[DIST_TRIANGLE_HALF_L];
4818 SUBGOAL_THEN `!x:A. P x ==> cauchy (\n. s n x :real^N)` MP_TAC THENL
4819 [REWRITE_TAC[cauchy; GE] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
4820 REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY; LIM_SEQUENTIALLY] THEN
4821 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
4822 REWRITE_TAC[SKOLEM_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
4823 X_GEN_TAC `l:A->real^N` THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN
4824 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
4825 ASM_REWRITE_TAC[REAL_HALF] THEN MATCH_MP_TAC MONO_EXISTS THEN
4826 X_GEN_TAC `N:num` THEN STRIP_TAC THEN
4827 MAP_EVERY X_GEN_TAC [`n:num`; `x:A`] THEN STRIP_TAC THEN
4828 FIRST_X_ASSUM(MP_TAC o SPEC `x:A`) THEN ASM_REWRITE_TAC[] THEN
4829 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
4830 DISCH_THEN(X_CHOOSE_TAC `M:num`) THEN
4831 FIRST_X_ASSUM(MP_TAC o SPECL [`n:num`; `N + M:num`; `x:A`]) THEN
4832 ASM_REWRITE_TAC[LE_ADD] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN
4833 FIRST_X_ASSUM(MP_TAC o SPEC `M + N:num`) THEN REWRITE_TAC[LE_ADD] THEN
4834 ASM_MESON_TAC[DIST_TRIANGLE_HALF_L; DIST_SYM]);;
4836 let UNIFORMLY_CAUCHY_IMP_UNIFORMLY_CONVERGENT = prove
4837 (`!P (s:num->A->real^N) l.
4839 ==> ?N. !m n x. N <= m /\ N <= n /\ P x ==> dist(s m x,s n x) < e) /\
4840 (!x. P x ==> !e. &0 < e ==> ?N. !n. N <= n ==> dist(s n x,l x) < e)
4841 ==> (!e. &0 < e ==> ?N. !n x. N <= n /\ P x ==> dist(s n x,l x) < e)`,
4842 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM UNIFORMLY_CONVERGENT_EQ_CAUCHY] THEN
4843 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `l':A->real^N`) ASSUME_TAC) THEN
4844 SUBGOAL_THEN `!x. P x ==> (l:A->real^N) x = l' x` MP_TAC THENL
4845 [ALL_TAC; ASM_MESON_TAC[]] THEN
4846 REPEAT STRIP_TAC THEN MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
4847 EXISTS_TAC `\n. (s:num->A->real^N) n x` THEN
4848 REWRITE_TAC[LIM_SEQUENTIALLY; TRIVIAL_LIMIT_SEQUENTIALLY] THEN
4851 (* ------------------------------------------------------------------------- *)
4852 (* Define continuity over a net to take in restrictions of the set. *)
4853 (* ------------------------------------------------------------------------- *)
4855 parse_as_infix ("continuous",(12,"right"));;
4857 let continuous = new_definition
4858 `f continuous net <=> (f --> f(netlimit net)) net`;;
4860 let CONTINUOUS_TRIVIAL_LIMIT = prove
4861 (`!f net. trivial_limit net ==> f continuous net`,
4862 SIMP_TAC[continuous; LIM]);;
4864 let CONTINUOUS_WITHIN = prove
4865 (`!f x:real^M. f continuous (at x within s) <=> (f --> f(x)) (at x within s)`,
4866 REPEAT GEN_TAC THEN REWRITE_TAC[continuous] THEN
4867 ASM_CASES_TAC `trivial_limit(at (x:real^M) within s)` THENL
4868 [ASM_REWRITE_TAC[LIM]; ASM_SIMP_TAC[NETLIMIT_WITHIN]]);;
4870 let CONTINUOUS_AT = prove
4871 (`!f (x:real^N). f continuous (at x) <=> (f --> f(x)) (at x)`,
4872 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
4873 REWRITE_TAC[CONTINUOUS_WITHIN; IN_UNIV]);;
4875 let CONTINUOUS_AT_WITHIN = prove
4876 (`!f:real^M->real^N x s.
4877 f continuous (at x) ==> f continuous (at x within s)`,
4878 SIMP_TAC[LIM_AT_WITHIN; CONTINUOUS_AT; CONTINUOUS_WITHIN]);;
4880 let CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL = prove
4881 (`!a s. closed s /\ ~(a IN s) ==> f continuous (at a within s)`,
4882 ASM_SIMP_TAC[continuous; LIM; LIM_WITHIN_CLOSED_TRIVIAL]);;
4884 let CONTINUOUS_TRANSFORM_WITHIN = prove
4885 (`!f g:real^M->real^N s x d.
4887 (!x'. x' IN s /\ dist(x',x) < d ==> f(x') = g(x')) /\
4888 f continuous (at x within s)
4889 ==> g continuous (at x within s)`,
4890 REWRITE_TAC[CONTINUOUS_WITHIN] THEN
4891 MESON_TAC[LIM_TRANSFORM_WITHIN; DIST_REFL]);;
4893 let CONTINUOUS_TRANSFORM_AT = prove
4894 (`!f g:real^M->real^N x d.
4895 &0 < d /\ (!x'. dist(x',x) < d ==> f(x') = g(x')) /\
4897 ==> g continuous (at x)`,
4898 REWRITE_TAC[CONTINUOUS_AT] THEN
4899 MESON_TAC[LIM_TRANSFORM_AT; DIST_REFL]);;
4901 (* ------------------------------------------------------------------------- *)
4902 (* Derive the epsilon-delta forms, which we often use as "definitions" *)
4903 (* ------------------------------------------------------------------------- *)
4905 let continuous_within = prove
4906 (`f continuous (at x within s) <=>
4909 !x'. x' IN s /\ dist(x',x) < d ==> dist(f(x'),f(x)) < e`,
4910 REWRITE_TAC[CONTINUOUS_WITHIN; LIM_WITHIN] THEN
4911 REWRITE_TAC[GSYM DIST_NZ] THEN MESON_TAC[DIST_REFL]);;
4913 let continuous_at = prove
4914 (`f continuous (at x) <=>
4915 !e. &0 < e ==> ?d. &0 < d /\
4916 !x'. dist(x',x) < d ==> dist(f(x'),f(x)) < e`,
4917 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
4918 REWRITE_TAC[continuous_within; IN_UNIV]);;
4920 (* ------------------------------------------------------------------------- *)
4921 (* Versions in terms of open balls. *)
4922 (* ------------------------------------------------------------------------- *)
4924 let CONTINUOUS_WITHIN_BALL = prove
4925 (`!f s x. f continuous (at x within s) <=>
4928 IMAGE f (ball(x,d) INTER s) SUBSET ball(f x,e)`,
4929 SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_BALL; continuous_within; IN_INTER] THEN
4930 MESON_TAC[DIST_SYM]);;
4932 let CONTINUOUS_AT_BALL = prove
4933 (`!f x. f continuous (at x) <=>
4936 IMAGE f (ball(x,d)) SUBSET ball(f x,e)`,
4937 SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_BALL; continuous_at] THEN
4938 MESON_TAC[DIST_SYM]);;
4940 (* ------------------------------------------------------------------------- *)
4941 (* For setwise continuity, just start from the epsilon-delta definitions. *)
4942 (* ------------------------------------------------------------------------- *)
4944 parse_as_infix ("continuous_on",(12,"right"));;
4945 parse_as_infix ("uniformly_continuous_on",(12,"right"));;
4947 let continuous_on = new_definition
4948 `f continuous_on s <=>
4949 !x. x IN s ==> !e. &0 < e
4951 !x'. x' IN s /\ dist(x',x) < d
4952 ==> dist(f(x'),f(x)) < e`;;
4954 let uniformly_continuous_on = new_definition
4955 `f uniformly_continuous_on s <=>
4958 !x x'. x IN s /\ x' IN s /\ dist(x',x) < d
4959 ==> dist(f(x'),f(x)) < e`;;
4961 (* ------------------------------------------------------------------------- *)
4962 (* Some simple consequential lemmas. *)
4963 (* ------------------------------------------------------------------------- *)
4965 let UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS = prove
4966 (`!f s. f uniformly_continuous_on s ==> f continuous_on s`,
4967 REWRITE_TAC[uniformly_continuous_on; continuous_on] THEN MESON_TAC[]);;
4969 let CONTINUOUS_AT_IMP_CONTINUOUS_ON = prove
4970 (`!f s. (!x. x IN s ==> f continuous (at x)) ==> f continuous_on s`,
4971 REWRITE_TAC[continuous_at; continuous_on] THEN MESON_TAC[]);;
4973 let CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN = prove
4974 (`!f s. f continuous_on s <=> !x. x IN s ==> f continuous (at x within s)`,
4975 REWRITE_TAC[continuous_on; continuous_within]);;
4977 let CONTINUOUS_ON = prove
4978 (`!f (s:real^N->bool).
4979 f continuous_on s <=> !x. x IN s ==> (f --> f(x)) (at x within s)`,
4980 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_WITHIN]);;
4982 let CONTINUOUS_ON_EQ_CONTINUOUS_AT = prove
4983 (`!f:real^M->real^N s.
4984 open s ==> (f continuous_on s <=> (!x. x IN s ==> f continuous (at x)))`,
4985 SIMP_TAC[CONTINUOUS_ON; CONTINUOUS_AT; LIM_WITHIN_OPEN]);;
4987 let CONTINUOUS_WITHIN_SUBSET = prove
4988 (`!f s t x. f continuous (at x within s) /\ t SUBSET s
4989 ==> f continuous (at x within t)`,
4990 REWRITE_TAC[CONTINUOUS_WITHIN] THEN MESON_TAC[LIM_WITHIN_SUBSET]);;
4992 let CONTINUOUS_ON_SUBSET = prove
4993 (`!f s t. f continuous_on s /\ t SUBSET s ==> f continuous_on t`,
4994 REWRITE_TAC[CONTINUOUS_ON] THEN MESON_TAC[SUBSET; LIM_WITHIN_SUBSET]);;
4996 let UNIFORMLY_CONTINUOUS_ON_SUBSET = prove
4997 (`!f s t. f uniformly_continuous_on s /\ t SUBSET s
4998 ==> f uniformly_continuous_on t`,
4999 REWRITE_TAC[uniformly_continuous_on] THEN
5000 MESON_TAC[SUBSET; LIM_WITHIN_SUBSET]);;
5002 let CONTINUOUS_ON_INTERIOR = prove
5003 (`!f:real^M->real^N s x.
5004 f continuous_on s /\ x IN interior(s) ==> f continuous at x`,
5005 REWRITE_TAC[interior; IN_ELIM_THM] THEN
5006 MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; CONTINUOUS_ON_SUBSET]);;
5008 let CONTINUOUS_ON_EQ = prove
5009 (`!f g s. (!x. x IN s ==> f(x) = g(x)) /\ f continuous_on s
5010 ==> g continuous_on s`,
5011 SIMP_TAC[continuous_on; IMP_CONJ]);;
5013 let UNIFORMLY_CONTINUOUS_ON_EQ = prove
5015 (!x. x IN s ==> f x = g x) /\ f uniformly_continuous_on s
5016 ==> g uniformly_continuous_on s`,
5017 SIMP_TAC[uniformly_continuous_on; IMP_CONJ]);;
5019 let CONTINUOUS_ON_SING = prove
5020 (`!f:real^M->real^N a. f continuous_on {a}`,
5021 SIMP_TAC[continuous_on; IN_SING; FORALL_UNWIND_THM2; DIST_REFL] THEN
5024 let CONTINUOUS_ON_EMPTY = prove
5025 (`!f:real^M->real^N. f continuous_on {}`,
5026 MESON_TAC[CONTINUOUS_ON_SING; EMPTY_SUBSET; CONTINUOUS_ON_SUBSET]);;
5028 let CONTINUOUS_ON_NO_LIMPT = prove
5029 (`!f:real^M->real^N s.
5030 ~(?x. x limit_point_of s) ==> f continuous_on s`,
5031 REWRITE_TAC[continuous_on; LIMPT_APPROACHABLE] THEN MESON_TAC[DIST_REFL]);;
5033 let CONTINUOUS_ON_FINITE = prove
5034 (`!f:real^M->real^N s. FINITE s ==> f continuous_on s`,
5035 MESON_TAC[CONTINUOUS_ON_NO_LIMPT; LIMIT_POINT_FINITE]);;
5037 let CONTRACTION_IMP_CONTINUOUS_ON = prove
5038 (`!f:real^M->real^N.
5039 (!x y. x IN s /\ y IN s ==> dist(f x,f y) <= dist(x,y))
5040 ==> f continuous_on s`,
5041 SIMP_TAC[continuous_on] THEN MESON_TAC[REAL_LET_TRANS]);;
5043 let ISOMETRY_ON_IMP_CONTINUOUS_ON = prove
5044 (`!f:real^M->real^N.
5045 (!x y. x IN s /\ y IN s ==> dist(f x,f y) = dist(x,y))
5046 ==> f continuous_on s`,
5047 SIMP_TAC[CONTRACTION_IMP_CONTINUOUS_ON; REAL_LE_REFL]);;
5049 (* ------------------------------------------------------------------------- *)
5050 (* Characterization of various kinds of continuity in terms of sequences. *)
5051 (* ------------------------------------------------------------------------- *)
5053 let CONTINUOUS_WITHIN_SEQUENTIALLY = prove
5055 f continuous (at a within s) <=>
5056 !x. (!n. x(n) IN s) /\ (x --> a) sequentially
5057 ==> ((f o x) --> f(a)) sequentially`,
5058 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within] THEN EQ_TAC THENL
5059 [REWRITE_TAC[LIM_SEQUENTIALLY; o_THM] THEN MESON_TAC[]; ALL_TAC] THEN
5060 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
5061 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN
5062 DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5063 DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `&1 / (&n + &1)`) THEN
5064 SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; REAL_OF_NUM_LE; REAL_POS; ARITH;
5065 REAL_ARITH `&0 <= n ==> &0 < n + &1`; NOT_FORALL_THM; SKOLEM_THM] THEN
5066 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[NOT_IMP; FORALL_AND_THM] THEN
5067 X_GEN_TAC `y:num->real^N` THEN REWRITE_TAC[LIM_SEQUENTIALLY; o_THM] THEN
5068 STRIP_TAC THEN CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LE_REFL]] THEN
5069 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC FORALL_POS_MONO_1 THEN
5070 CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_TRANS]; ALL_TAC] THEN
5071 X_GEN_TAC `n:num` THEN EXISTS_TAC `n:num` THEN X_GEN_TAC `m:num` THEN
5072 DISCH_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN
5073 EXISTS_TAC `&1 / (&m + &1)` THEN ASM_REWRITE_TAC[] THEN
5074 ASM_SIMP_TAC[REAL_LE_INV2; real_div; REAL_ARITH `&0 <= x ==> &0 < x + &1`;
5075 REAL_POS; REAL_MUL_LID; REAL_LE_RADD; REAL_OF_NUM_LE]);;
5077 let CONTINUOUS_AT_SEQUENTIALLY = prove
5079 f continuous (at a) <=>
5080 !x. (x --> a) sequentially
5081 ==> ((f o x) --> f(a)) sequentially`,
5082 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
5083 REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY; IN_UNIV]);;
5085 let CONTINUOUS_ON_SEQUENTIALLY = prove
5086 (`!f s:real^N->bool.
5087 f continuous_on s <=>
5088 !x a. a IN s /\ (!n. x(n) IN s) /\ (x --> a) sequentially
5089 ==> ((f o x) --> f(a)) sequentially`,
5090 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
5091 CONTINUOUS_WITHIN_SEQUENTIALLY] THEN MESON_TAC[]);;
5093 let UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY = prove
5094 (`!f s:real^N->bool.
5095 f uniformly_continuous_on s <=>
5096 !x y. (!n. x(n) IN s) /\ (!n. y(n) IN s) /\
5097 ((\n. x(n) - y(n)) --> vec 0) sequentially
5098 ==> ((\n. f(x(n)) - f(y(n))) --> vec 0) sequentially`,
5099 REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on] THEN
5100 REWRITE_TAC[LIM_SEQUENTIALLY; dist; VECTOR_SUB_RZERO] THEN
5101 EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
5102 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
5103 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; NOT_EXISTS_THM] THEN
5104 DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5105 DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `&1 / (&n + &1)`) THEN
5106 SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; REAL_OF_NUM_LE; REAL_POS; ARITH;
5107 REAL_ARITH `&0 <= n ==> &0 < n + &1`; NOT_FORALL_THM; SKOLEM_THM] THEN
5108 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:num->real^N` THEN
5109 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:num->real^N` THEN
5110 REWRITE_TAC[NOT_IMP; FORALL_AND_THM] THEN STRIP_TAC THEN
5111 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[NORM_SUB] THEN CONJ_TAC THENL
5112 [MATCH_MP_TAC FORALL_POS_MONO_1 THEN
5113 CONJ_TAC THENL [ASM_MESON_TAC[REAL_LT_TRANS]; ALL_TAC] THEN
5114 X_GEN_TAC `n:num` THEN EXISTS_TAC `n:num` THEN X_GEN_TAC `m:num` THEN
5115 DISCH_TAC THEN MATCH_MP_TAC REAL_LTE_TRANS THEN
5116 EXISTS_TAC `&1 / (&m + &1)` THEN ASM_REWRITE_TAC[] THEN
5117 ASM_SIMP_TAC[REAL_LE_INV2; real_div; REAL_ARITH `&0 <= x ==> &0 < x + &1`;
5118 REAL_POS; REAL_MUL_LID; REAL_LE_RADD; REAL_OF_NUM_LE];
5119 EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN
5120 EXISTS_TAC `\x:num. x` THEN ASM_REWRITE_TAC[LE_REFL]]);;
5122 let LIM_CONTINUOUS_FUNCTION = prove
5124 f continuous (at l) /\ (g --> l) net ==> ((\x. f(g x)) --> f l) net`,
5125 REWRITE_TAC[tendsto; continuous_at; eventually] THEN MESON_TAC[]);;
5127 (* ------------------------------------------------------------------------- *)
5128 (* Combination results for pointwise continuity. *)
5129 (* ------------------------------------------------------------------------- *)
5131 let CONTINUOUS_CONST = prove
5132 (`!net c. (\x. c) continuous net`,
5133 REWRITE_TAC[continuous; LIM_CONST]);;
5135 let CONTINUOUS_CMUL = prove
5136 (`!f c net. f continuous net ==> (\x. c % f(x)) continuous net`,
5137 REWRITE_TAC[continuous; LIM_CMUL]);;
5139 let CONTINUOUS_NEG = prove
5140 (`!f net. f continuous net ==> (\x. --(f x)) continuous net`,
5141 REWRITE_TAC[continuous; LIM_NEG]);;
5143 let CONTINUOUS_ADD = prove
5144 (`!f g net. f continuous net /\ g continuous net
5145 ==> (\x. f(x) + g(x)) continuous net`,
5146 REWRITE_TAC[continuous; LIM_ADD]);;
5148 let CONTINUOUS_SUB = prove
5149 (`!f g net. f continuous net /\ g continuous net
5150 ==> (\x. f(x) - g(x)) continuous net`,
5151 REWRITE_TAC[continuous; LIM_SUB]);;
5153 let CONTINUOUS_ABS = prove
5154 (`!(f:A->real^N) net.
5156 ==> (\x. (lambda i. abs(f(x)$i)):real^N) continuous net`,
5157 REWRITE_TAC[continuous; LIM_ABS]);;
5159 let CONTINUOUS_MAX = prove
5160 (`!(f:A->real^N) (g:A->real^N) net.
5161 f continuous net /\ g continuous net
5162 ==> (\x. (lambda i. max (f(x)$i) (g(x)$i)):real^N) continuous net`,
5163 REWRITE_TAC[continuous; LIM_MAX]);;
5165 let CONTINUOUS_MIN = prove
5166 (`!(f:A->real^N) (g:A->real^N) net.
5167 f continuous net /\ g continuous net
5168 ==> (\x. (lambda i. min (f(x)$i) (g(x)$i)):real^N) continuous net`,
5169 REWRITE_TAC[continuous; LIM_MIN]);;
5171 let CONTINUOUS_VSUM = prove
5172 (`!net f s. FINITE s /\ (!a. a IN s ==> (f a) continuous net)
5173 ==> (\x. vsum s (\a. f a x)) continuous net`,
5174 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
5175 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
5176 SIMP_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY; VSUM_CLAUSES;
5177 CONTINUOUS_CONST; CONTINUOUS_ADD; ETA_AX]);;
5179 (* ------------------------------------------------------------------------- *)
5180 (* Same thing for setwise continuity. *)
5181 (* ------------------------------------------------------------------------- *)
5183 let CONTINUOUS_ON_CONST = prove
5184 (`!s c. (\x. c) continuous_on s`,
5185 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_CONST]);;
5187 let CONTINUOUS_ON_CMUL = prove
5188 (`!f c s. f continuous_on s ==> (\x. c % f(x)) continuous_on s`,
5189 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_CMUL]);;
5191 let CONTINUOUS_ON_NEG = prove
5192 (`!f s. f continuous_on s
5193 ==> (\x. --(f x)) continuous_on s`,
5194 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_NEG]);;
5196 let CONTINUOUS_ON_ADD = prove
5197 (`!f g s. f continuous_on s /\ g continuous_on s
5198 ==> (\x. f(x) + g(x)) continuous_on s`,
5199 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_ADD]);;
5201 let CONTINUOUS_ON_SUB = prove
5202 (`!f g s. f continuous_on s /\ g continuous_on s
5203 ==> (\x. f(x) - g(x)) continuous_on s`,
5204 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_SUB]);;
5206 let CONTINUOUS_ON_ABS = prove
5207 (`!f:real^M->real^N s.
5209 ==> (\x. (lambda i. abs(f(x)$i)):real^N) continuous_on s`,
5210 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_ABS]);;
5212 let CONTINUOUS_ON_MAX = prove
5213 (`!f:real^M->real^N g:real^M->real^N s.
5214 f continuous_on s /\ g continuous_on s
5215 ==> (\x. (lambda i. max (f(x)$i) (g(x)$i)):real^N)
5217 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_MAX]);;
5219 let CONTINUOUS_ON_MIN = prove
5220 (`!f:real^M->real^N g:real^M->real^N s.
5221 f continuous_on s /\ g continuous_on s
5222 ==> (\x. (lambda i. min (f(x)$i) (g(x)$i)):real^N)
5224 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_MIN]);;
5226 let CONTINUOUS_ON_VSUM = prove
5227 (`!t f s. FINITE s /\ (!a. a IN s ==> (f a) continuous_on t)
5228 ==> (\x. vsum s (\a. f a x)) continuous_on t`,
5229 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_VSUM]);;
5231 (* ------------------------------------------------------------------------- *)
5232 (* Same thing for uniform continuity, using sequential formulations. *)
5233 (* ------------------------------------------------------------------------- *)
5235 let UNIFORMLY_CONTINUOUS_ON_CONST = prove
5236 (`!s c. (\x. c) uniformly_continuous_on s`,
5237 REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY; o_DEF;
5238 VECTOR_SUB_REFL; LIM_CONST]);;
5240 let LINEAR_UNIFORMLY_CONTINUOUS_ON = prove
5241 (`!f:real^M->real^N s. linear f ==> f uniformly_continuous_on s`,
5242 REPEAT STRIP_TAC THEN
5243 ASM_SIMP_TAC[uniformly_continuous_on; dist; GSYM LINEAR_SUB] THEN
5244 FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o
5245 MATCH_MP LINEAR_BOUNDED_POS) THEN
5246 X_GEN_TAC `e:real` THEN DISCH_TAC THEN EXISTS_TAC `e / B:real` THEN
5247 ASM_SIMP_TAC[REAL_LT_DIV] THEN
5248 MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN
5249 MATCH_MP_TAC REAL_LET_TRANS THEN
5250 EXISTS_TAC `B * norm(y - x:real^M)` THEN ASM_REWRITE_TAC[] THEN
5251 ASM_MESON_TAC[REAL_LT_RDIV_EQ; REAL_MUL_SYM]);;
5253 let UNIFORMLY_CONTINUOUS_ON_COMPOSE = prove
5254 (`!f g s. f uniformly_continuous_on s /\
5255 g uniformly_continuous_on (IMAGE f s)
5256 ==> (g o f) uniformly_continuous_on s`,
5258 (`(!y. ((?x. (y = f x) /\ P x) /\ Q y ==> R y)) <=>
5259 (!x. P x /\ Q (f x) ==> R (f x))`,
5262 REWRITE_TAC[uniformly_continuous_on; o_THM; IN_IMAGE] THEN
5263 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN REWRITE_TAC[lemma] THEN
5264 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN
5265 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN REWRITE_TAC[lemma] THEN
5266 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5267 MATCH_MP_TAC MONO_FORALL THEN
5268 X_GEN_TAC `e:real` THEN ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
5271 let BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE = prove
5272 (`!f:real^M->real^N g (h:real^N->real^P->real^Q) s.
5273 f uniformly_continuous_on s /\ g uniformly_continuous_on s /\
5274 bilinear h /\ bounded(IMAGE f s) /\ bounded(IMAGE g s)
5275 ==> (\x. h (f x) (g x)) uniformly_continuous_on s`,
5276 REPEAT STRIP_TAC THEN REWRITE_TAC[uniformly_continuous_on; dist] THEN
5277 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5279 `!a b c d. (h:real^N->real^P->real^Q) a b - h c d =
5280 h (a - c) b + h c (b - d)`
5281 (fun th -> ONCE_REWRITE_TAC[th])
5283 [FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP BILINEAR_LSUB th]) THEN
5284 FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP BILINEAR_RSUB th]) THEN
5287 FIRST_X_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o
5288 MATCH_MP BILINEAR_BOUNDED_POS) THEN
5289 UNDISCH_TAC `bounded(IMAGE (g:real^M->real^P) s)` THEN
5290 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
5291 REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN
5292 DISCH_THEN(X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) THEN
5293 DISCH_THEN(X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC) THEN
5294 UNDISCH_TAC `(g:real^M->real^P) uniformly_continuous_on s` THEN
5295 UNDISCH_TAC `(f:real^M->real^N) uniformly_continuous_on s` THEN
5296 REWRITE_TAC[uniformly_continuous_on] THEN
5297 DISCH_THEN(MP_TAC o SPEC `e / &2 / &2 / B / B2`) THEN
5298 ASM_SIMP_TAC[REAL_LT_DIV; REAL_HALF; dist] THEN
5299 DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN
5300 DISCH_THEN(MP_TAC o SPEC `e / &2 / &2 / B / B1`) THEN
5301 ASM_SIMP_TAC[REAL_LT_DIV; REAL_HALF; dist] THEN
5302 DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN
5303 EXISTS_TAC `min d1 d2` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
5304 MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN
5305 REPEAT(FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `y:real^M`])) THEN
5306 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
5307 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC
5308 `B * e / &2 / &2 / B / B2 * B2 + B * B1 * e / &2 / &2 / B / B1` THEN
5310 [MATCH_MP_TAC(NORM_ARITH
5311 `norm(x) <= a /\ norm(y) <= b ==> norm(x + y:real^N) <= a + b`) THEN
5313 FIRST_X_ASSUM(fun th -> W(MP_TAC o PART_MATCH lhand th o lhand o snd)) THEN
5314 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
5315 MATCH_MP_TAC REAL_LE_LMUL THEN ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN
5316 MATCH_MP_TAC REAL_LE_MUL2 THEN
5317 ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_POS_LE];
5318 ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN
5319 ASM_REAL_ARITH_TAC]);;
5321 let UNIFORMLY_CONTINUOUS_ON_MUL = prove
5322 (`!f g:real^M->real^N s.
5323 (lift o f) uniformly_continuous_on s /\ g uniformly_continuous_on s /\
5324 bounded(IMAGE (lift o f) s) /\ bounded(IMAGE g s)
5325 ==> (\x. f x % g x) uniformly_continuous_on s`,
5326 REPEAT STRIP_TAC THEN
5328 [`lift o (f:real^M->real)`; `g:real^M->real^N`;
5329 `\c (v:real^N). drop c % v`; `s:real^M->bool`]
5330 BILINEAR_UNIFORMLY_CONTINUOUS_ON_COMPOSE) THEN
5331 ASM_REWRITE_TAC[o_THM; LIFT_DROP] THEN DISCH_THEN MATCH_MP_TAC THEN
5332 REWRITE_TAC[bilinear; linear; DROP_ADD; DROP_CMUL] THEN VECTOR_ARITH_TAC);;
5334 let UNIFORMLY_CONTINUOUS_ON_CMUL = prove
5335 (`!f c s. f uniformly_continuous_on s
5336 ==> (\x. c % f(x)) uniformly_continuous_on s`,
5337 REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY] THEN
5338 REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
5339 DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
5340 ASM_REWRITE_TAC[] THEN
5341 DISCH_THEN(MP_TAC o MATCH_MP LIM_CMUL) THEN
5342 ASM_SIMP_TAC[VECTOR_SUB_LDISTRIB; VECTOR_MUL_RZERO]);;
5344 let UNIFORMLY_CONTINUOUS_ON_VMUL = prove
5345 (`!s:real^M->bool c v:real^N.
5346 (lift o c) uniformly_continuous_on s
5347 ==> (\x. c x % v) uniformly_continuous_on s`,
5349 DISCH_THEN(MP_TAC o ISPEC `\x. (drop x % v:real^N)` o MATCH_MP
5350 (REWRITE_RULE[IMP_CONJ] UNIFORMLY_CONTINUOUS_ON_COMPOSE)) THEN
5351 REWRITE_TAC[o_DEF; LIFT_DROP] THEN DISCH_THEN MATCH_MP_TAC THEN
5352 MATCH_MP_TAC LINEAR_UNIFORMLY_CONTINUOUS_ON THEN
5353 MATCH_MP_TAC LINEAR_VMUL_DROP THEN REWRITE_TAC[LINEAR_ID]);;
5355 let UNIFORMLY_CONTINUOUS_ON_NEG = prove
5356 (`!f s. f uniformly_continuous_on s
5357 ==> (\x. --(f x)) uniformly_continuous_on s`,
5358 ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN
5359 REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_CMUL]);;
5361 let UNIFORMLY_CONTINUOUS_ON_ADD = prove
5362 (`!f g s. f uniformly_continuous_on s /\ g uniformly_continuous_on s
5363 ==> (\x. f(x) + g(x)) uniformly_continuous_on s`,
5364 REPEAT GEN_TAC THEN REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY] THEN
5365 REWRITE_TAC[AND_FORALL_THM] THEN
5366 REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
5367 DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
5368 ASM_REWRITE_TAC[o_DEF] THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN
5369 MATCH_MP_TAC EQ_IMP THEN
5370 REWRITE_TAC[VECTOR_ADD_LID] THEN AP_THM_TAC THEN BINOP_TAC THEN
5371 REWRITE_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC);;
5373 let UNIFORMLY_CONTINUOUS_ON_SUB = prove
5374 (`!f g s. f uniformly_continuous_on s /\ g uniformly_continuous_on s
5375 ==> (\x. f(x) - g(x)) uniformly_continuous_on s`,
5376 REWRITE_TAC[VECTOR_SUB] THEN
5377 SIMP_TAC[UNIFORMLY_CONTINUOUS_ON_NEG; UNIFORMLY_CONTINUOUS_ON_ADD]);;
5379 let UNIFORMLY_CONTINUOUS_ON_VSUM = prove
5380 (`!t f s. FINITE s /\ (!a. a IN s ==> (f a) uniformly_continuous_on t)
5381 ==> (\x. vsum s (\a. f a x)) uniformly_continuous_on t`,
5382 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
5383 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
5384 SIMP_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY; VSUM_CLAUSES;
5385 UNIFORMLY_CONTINUOUS_ON_CONST; UNIFORMLY_CONTINUOUS_ON_ADD; ETA_AX]);;
5387 (* ------------------------------------------------------------------------- *)
5388 (* Identity function is continuous in every sense. *)
5389 (* ------------------------------------------------------------------------- *)
5391 let CONTINUOUS_WITHIN_ID = prove
5392 (`!a s. (\x. x) continuous (at a within s)`,
5393 REWRITE_TAC[continuous_within] THEN MESON_TAC[]);;
5395 let CONTINUOUS_AT_ID = prove
5396 (`!a. (\x. x) continuous (at a)`,
5397 REWRITE_TAC[continuous_at] THEN MESON_TAC[]);;
5399 let CONTINUOUS_ON_ID = prove
5400 (`!s. (\x. x) continuous_on s`,
5401 REWRITE_TAC[continuous_on] THEN MESON_TAC[]);;
5403 let UNIFORMLY_CONTINUOUS_ON_ID = prove
5404 (`!s. (\x. x) uniformly_continuous_on s`,
5405 REWRITE_TAC[uniformly_continuous_on] THEN MESON_TAC[]);;
5407 (* ------------------------------------------------------------------------- *)
5408 (* Continuity of all kinds is preserved under composition. *)
5409 (* ------------------------------------------------------------------------- *)
5411 let CONTINUOUS_WITHIN_COMPOSE = prove
5412 (`!f g x s. f continuous (at x within s) /\
5413 g continuous (at (f x) within IMAGE f s)
5414 ==> (g o f) continuous (at x within s)`,
5415 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within; o_THM; IN_IMAGE] THEN
5416 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5417 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
5420 let CONTINUOUS_AT_COMPOSE = prove
5421 (`!f g x. f continuous (at x) /\ g continuous (at (f x))
5422 ==> (g o f) continuous (at x)`,
5423 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
5424 MESON_TAC[CONTINUOUS_WITHIN_COMPOSE; IN_IMAGE; CONTINUOUS_WITHIN_SUBSET;
5425 SUBSET_UNIV; IN_UNIV]);;
5427 let CONTINUOUS_ON_COMPOSE = prove
5428 (`!f g s. f continuous_on s /\ g continuous_on (IMAGE f s)
5429 ==> (g o f) continuous_on s`,
5430 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
5431 MESON_TAC[IN_IMAGE; CONTINUOUS_WITHIN_COMPOSE]);;
5433 (* ------------------------------------------------------------------------- *)
5434 (* Continuity in terms of open preimages. *)
5435 (* ------------------------------------------------------------------------- *)
5437 let CONTINUOUS_WITHIN_OPEN = prove
5438 (`!f:real^M->real^N x u.
5439 f continuous (at x within u) <=>
5440 !t. open t /\ f(x) IN t
5441 ==> ?s. open s /\ x IN s /\
5442 !x'. x' IN s /\ x' IN u ==> f(x') IN t`,
5443 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_within] THEN EQ_TAC THENL
5444 [DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN
5445 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
5446 GEN_REWRITE_TAC LAND_CONV [open_def] THEN
5447 DISCH_THEN(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN
5448 ASM_MESON_TAC[IN_BALL; DIST_SYM; OPEN_BALL; CENTRE_IN_BALL; DIST_SYM];
5449 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5450 FIRST_X_ASSUM(MP_TAC o SPEC `ball((f:real^M->real^N) x,e)`) THEN
5451 ASM_SIMP_TAC[OPEN_BALL; CENTRE_IN_BALL] THEN
5452 MESON_TAC[open_def; IN_BALL; REAL_LT_TRANS; DIST_SYM]]);;
5454 let CONTINUOUS_AT_OPEN = prove
5455 (`!f:real^M->real^N x.
5456 f continuous (at x) <=>
5457 !t. open t /\ f(x) IN t
5458 ==> ?s. open s /\ x IN s /\
5459 !x'. x' IN s ==> f(x') IN t`,
5460 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_at] THEN EQ_TAC THENL
5461 [DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN
5462 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
5463 GEN_REWRITE_TAC LAND_CONV [open_def] THEN
5464 DISCH_THEN(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN
5465 ASM_MESON_TAC[IN_BALL; DIST_SYM; OPEN_BALL; CENTRE_IN_BALL];
5466 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5467 FIRST_X_ASSUM(MP_TAC o SPEC `ball((f:real^M->real^N) x,e)`) THEN
5468 ASM_SIMP_TAC[OPEN_BALL; CENTRE_IN_BALL] THEN
5469 MESON_TAC[open_def; IN_BALL; REAL_LT_TRANS; DIST_SYM]]);;
5471 let CONTINUOUS_ON_OPEN_GEN = prove
5472 (`!f:real^M->real^N s t.
5474 ==> (f continuous_on s <=>
5475 !u. open_in (subtopology euclidean t) u
5476 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN u})`,
5477 REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_on] THEN EQ_TAC THENL
5478 [REWRITE_TAC[open_in; SUBSET; IN_ELIM_THM] THEN
5479 DISCH_TAC THEN X_GEN_TAC `u:real^N->bool` THEN STRIP_TAC THEN
5480 CONJ_TAC THENL [ASM_MESON_TAC[DIST_REFL]; ALL_TAC] THEN
5481 X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN
5482 FIRST_X_ASSUM(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN ASM SET_TAC[];
5483 DISCH_TAC THEN X_GEN_TAC `x:real^M` THEN
5484 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5485 FIRST_X_ASSUM(MP_TAC o
5486 SPEC `ball((f:real^M->real^N) x,e) INTER t`) THEN
5488 [ASM_MESON_TAC[OPEN_IN_OPEN; INTER_COMM; OPEN_BALL]; ALL_TAC] THEN
5489 REWRITE_TAC[open_in; SUBSET; IN_INTER; IN_ELIM_THM; IN_BALL; IN_IMAGE] THEN
5490 REWRITE_TAC[AND_FORALL_THM] THEN DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN
5491 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE]) THEN
5492 ASM_MESON_TAC[DIST_REFL; DIST_SYM]]);;
5494 let CONTINUOUS_ON_OPEN = prove
5495 (`!f:real^M->real^N s.
5496 f continuous_on s <=>
5497 !t. open_in (subtopology euclidean (IMAGE f s)) t
5498 ==> open_in (subtopology euclidean s) {x | x IN s /\ f(x) IN t}`,
5499 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_OPEN_GEN THEN
5500 REWRITE_TAC[SUBSET_REFL]);;
5502 let CONTINUOUS_OPEN_IN_PREIMAGE_GEN = prove
5503 (`!f:real^M->real^N s t u.
5504 f continuous_on s /\ IMAGE f s SUBSET t /\
5505 open_in (subtopology euclidean t) u
5506 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN u}`,
5507 MESON_TAC[CONTINUOUS_ON_OPEN_GEN]);;
5509 let CONTINUOUS_ON_IMP_OPEN_IN = prove
5510 (`!f:real^M->real^N s t.
5511 f continuous_on s /\
5512 open_in (subtopology euclidean (IMAGE f s)) t
5513 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`,
5514 MESON_TAC[CONTINUOUS_ON_OPEN]);;
5516 (* ------------------------------------------------------------------------- *)
5517 (* Similarly in terms of closed sets. *)
5518 (* ------------------------------------------------------------------------- *)
5520 let CONTINUOUS_ON_CLOSED_GEN = prove
5521 (`!f:real^M->real^N s t.
5523 ==> (f continuous_on s <=>
5524 !u. closed_in (subtopology euclidean t) u
5525 ==> closed_in (subtopology euclidean s)
5526 {x | x IN s /\ f x IN u})`,
5527 REPEAT STRIP_TAC THEN FIRST_ASSUM(fun th ->
5528 ONCE_REWRITE_TAC[MATCH_MP CONTINUOUS_ON_OPEN_GEN th]) THEN
5529 EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `u:real^N->bool` THEN
5530 FIRST_X_ASSUM(MP_TAC o SPEC `t DIFF u:real^N->bool`) THENL
5531 [REWRITE_TAC[closed_in]; REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ]] THEN
5532 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
5533 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
5534 ASM_REWRITE_TAC[SUBSET_RESTRICT] THEN
5535 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]);;
5537 let CONTINUOUS_ON_CLOSED = prove
5538 (`!f:real^M->real^N s.
5539 f continuous_on s <=>
5540 !t. closed_in (subtopology euclidean (IMAGE f s)) t
5541 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f(x) IN t}`,
5542 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CLOSED_GEN THEN
5543 REWRITE_TAC[SUBSET_REFL]);;
5545 let CONTINUOUS_CLOSED_IN_PREIMAGE_GEN = prove
5546 (`!f:real^M->real^N s t u.
5547 f continuous_on s /\ IMAGE f s SUBSET t /\
5548 closed_in (subtopology euclidean t) u
5549 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN u}`,
5550 MESON_TAC[CONTINUOUS_ON_CLOSED_GEN]);;
5552 let CONTINUOUS_ON_IMP_CLOSED_IN = prove
5553 (`!f:real^M->real^N s t.
5554 f continuous_on s /\
5555 closed_in (subtopology euclidean (IMAGE f s)) t
5556 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`,
5557 MESON_TAC[CONTINUOUS_ON_CLOSED]);;
5559 (* ------------------------------------------------------------------------- *)
5560 (* Half-global and completely global cases. *)
5561 (* ------------------------------------------------------------------------- *)
5563 let CONTINUOUS_OPEN_IN_PREIMAGE = prove
5565 f continuous_on s /\ open t
5566 ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`,
5567 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE
5568 `x IN s /\ f x IN t <=> x IN s /\ f x IN (t INTER IMAGE f s)`] THEN
5569 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CONTINUOUS_ON_OPEN]) THEN
5570 ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN
5571 ASM_REWRITE_TAC[]);;
5573 let CONTINUOUS_CLOSED_IN_PREIMAGE = prove
5575 f continuous_on s /\ closed t
5576 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`,
5577 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SET_RULE
5578 `x IN s /\ f x IN t <=> x IN s /\ f x IN (t INTER IMAGE f s)`] THEN
5579 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[CONTINUOUS_ON_CLOSED]) THEN
5580 ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC CLOSED_IN_CLOSED_INTER THEN
5581 ASM_REWRITE_TAC[]);;
5583 let CONTINUOUS_OPEN_PREIMAGE = prove
5584 (`!f:real^M->real^N s t.
5585 f continuous_on s /\ open s /\ open t
5586 ==> open {x | x IN s /\ f(x) IN t}`,
5587 REPEAT STRIP_TAC THEN
5588 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_ON_OPEN]) THEN
5589 REWRITE_TAC [OPEN_IN_OPEN] THEN
5590 DISCH_THEN(MP_TAC o SPEC `IMAGE (f:real^M->real^N) s INTER t`) THEN
5592 [EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC [];
5594 SUBGOAL_THEN `{x | x IN s /\ (f:real^M->real^N) x IN t} =
5595 s INTER t'` SUBST1_TAC THENL
5596 [ASM SET_TAC []; ASM_MESON_TAC [OPEN_INTER]]]);;
5598 let CONTINUOUS_CLOSED_PREIMAGE = prove
5599 (`!f:real^M->real^N s t.
5600 f continuous_on s /\ closed s /\ closed t
5601 ==> closed {x | x IN s /\ f(x) IN t}`,
5602 REPEAT STRIP_TAC THEN
5603 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_ON_CLOSED]) THEN
5604 REWRITE_TAC [CLOSED_IN_CLOSED] THEN
5605 DISCH_THEN(MP_TAC o SPEC `IMAGE (f:real^M->real^N) s INTER t`) THEN
5607 [EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC [];
5609 SUBGOAL_THEN `{x | x IN s /\ (f:real^M->real^N) x IN t} =
5610 s INTER t'` SUBST1_TAC THENL
5611 [ASM SET_TAC []; ASM_MESON_TAC [CLOSED_INTER]]]);;
5613 let CONTINUOUS_OPEN_PREIMAGE_UNIV = prove
5614 (`!f:real^M->real^N s.
5615 (!x. f continuous (at x)) /\ open s ==> open {x | f(x) IN s}`,
5616 REPEAT STRIP_TAC THEN
5617 MP_TAC(SPECL [`f:real^M->real^N`; `(:real^M)`; `s:real^N->bool`]
5618 CONTINUOUS_OPEN_PREIMAGE) THEN
5619 ASM_SIMP_TAC[OPEN_UNIV; IN_UNIV; CONTINUOUS_AT_IMP_CONTINUOUS_ON]);;
5621 let CONTINUOUS_CLOSED_PREIMAGE_UNIV = prove
5622 (`!f:real^M->real^N s.
5623 (!x. f continuous (at x)) /\ closed s ==> closed {x | f(x) IN s}`,
5624 REPEAT STRIP_TAC THEN
5625 MP_TAC(SPECL [`f:real^M->real^N`; `(:real^M)`; `s:real^N->bool`]
5626 CONTINUOUS_CLOSED_PREIMAGE) THEN
5627 ASM_SIMP_TAC[CLOSED_UNIV; IN_UNIV; CONTINUOUS_AT_IMP_CONTINUOUS_ON]);;
5629 let CONTINUOUS_OPEN_IN_PREIMAGE_EQ = prove
5630 (`!f:real^M->real^N s.
5631 f continuous_on s <=>
5632 !t. open t ==> open_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`,
5633 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[CONTINUOUS_OPEN_IN_PREIMAGE] THEN
5634 REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN DISCH_TAC THEN
5635 X_GEN_TAC `t:real^N->bool` THEN GEN_REWRITE_TAC LAND_CONV [OPEN_IN_OPEN] THEN
5636 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
5637 FIRST_X_ASSUM(MP_TAC o SPEC `u:real^N->bool`) THEN
5638 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[]);;
5640 let CONTINUOUS_CLOSED_IN_PREIMAGE_EQ = prove
5641 (`!f:real^M->real^N s.
5642 f continuous_on s <=>
5644 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x IN t}`,
5645 REPEAT GEN_TAC THEN EQ_TAC THEN SIMP_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE] THEN
5646 REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN DISCH_TAC THEN
5647 X_GEN_TAC `t:real^N->bool` THEN
5648 GEN_REWRITE_TAC LAND_CONV [CLOSED_IN_CLOSED] THEN
5649 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
5650 FIRST_X_ASSUM(MP_TAC o SPEC `u:real^N->bool`) THEN
5651 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[]);;
5653 (* ------------------------------------------------------------------------- *)
5654 (* Quotient maps are occasionally useful. *)
5655 (* ------------------------------------------------------------------------- *)
5657 let OPEN_MAP_IMP_QUOTIENT_MAP = prove
5658 (`!f:real^M->real^N s.
5659 f continuous_on s /\
5660 (!t. open_in (subtopology euclidean s) t
5661 ==> open_in (subtopology euclidean (IMAGE f s)) (IMAGE f t))
5662 ==> !t. t SUBSET IMAGE f s
5663 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=>
5664 open_in (subtopology euclidean (IMAGE f s)) t)`,
5665 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
5667 `t = IMAGE f {x | x IN s /\ (f:real^M->real^N) x IN t}`
5668 SUBST1_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[]];
5669 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_ON_OPEN]) THEN
5672 let CLOSED_MAP_IMP_QUOTIENT_MAP = prove
5673 (`!f:real^M->real^N s.
5674 f continuous_on s /\
5675 (!t. closed_in (subtopology euclidean s) t
5676 ==> closed_in (subtopology euclidean (IMAGE f s)) (IMAGE f t))
5677 ==> !t. t SUBSET IMAGE f s
5678 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN t} <=>
5679 open_in (subtopology euclidean (IMAGE f s)) t)`,
5680 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
5681 [FIRST_X_ASSUM(MP_TAC o SPEC
5682 `s DIFF {x | x IN s /\ (f:real^M->real^N) x IN t}`) THEN
5684 [MATCH_MP_TAC CLOSED_IN_DIFF THEN
5685 ASM_SIMP_TAC[CLOSED_IN_SUBTOPOLOGY_REFL;
5686 TOPSPACE_EUCLIDEAN; SUBSET_UNIV];
5687 REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
5688 DISCH_THEN(MP_TAC o CONJUNCT2) THEN MATCH_MP_TAC EQ_IMP THEN
5689 AP_TERM_TAC THEN ASM SET_TAC[]];
5690 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_ON_OPEN]) THEN
5693 let CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP = prove
5694 (`!f:real^M->real^N g s t.
5695 f continuous_on s /\ IMAGE f s SUBSET t /\
5696 g continuous_on t /\ IMAGE g t SUBSET s /\
5697 (!y. y IN t ==> f(g y) = y)
5699 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
5700 open_in (subtopology euclidean t) u))`,
5701 REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN REPEAT STRIP_TAC THEN EQ_TAC THENL
5702 [DISCH_TAC THEN FIRST_ASSUM(MP_TAC o SPEC `(IMAGE (g:real^N->real^M) t)
5704 {x | x IN s /\ (f:real^M->real^N) x IN u}`) THEN
5706 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN
5707 REWRITE_TAC[OPEN_IN_OPEN] THEN MATCH_MP_TAC MONO_EXISTS THEN
5709 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN ASM SET_TAC[]];
5710 DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
5711 SUBGOAL_THEN `IMAGE (f:real^M->real^N) s = t`
5712 (fun th -> ASM_REWRITE_TAC[th]) THEN
5715 let CONTINUOUS_LEFT_INVERSE_IMP_QUOTIENT_MAP = prove
5716 (`!f:real^M->real^N g s.
5717 f continuous_on s /\ g continuous_on (IMAGE f s) /\
5718 (!x. x IN s ==> g(f x) = x)
5719 ==> (!u. u SUBSET (IMAGE f s)
5720 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
5721 open_in (subtopology euclidean (IMAGE f s)) u))`,
5722 REPEAT GEN_TAC THEN STRIP_TAC THEN
5723 MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN
5724 EXISTS_TAC `g:real^N->real^M` THEN
5725 ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);;
5727 let QUOTIENT_MAP_OPEN_CLOSED = prove
5728 (`!f:real^M->real^N s t.
5730 ==> ((!u. u SUBSET t
5731 ==> (open_in (subtopology euclidean s)
5732 {x | x IN s /\ f x IN u} <=>
5733 open_in (subtopology euclidean t) u)) <=>
5735 ==> (closed_in (subtopology euclidean s)
5736 {x | x IN s /\ f x IN u} <=>
5737 closed_in (subtopology euclidean t) u)))`,
5738 SIMP_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
5739 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
5740 X_GEN_TAC `u:real^N->bool` THEN
5741 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `t DIFF u:real^N->bool`) THEN
5742 ASM_SIMP_TAC[SET_RULE `u SUBSET t ==> t DIFF (t DIFF u) = u`] THEN
5743 (ANTS_TAC THENL [SET_TAC[]; DISCH_THEN(SUBST1_TAC o SYM)]) THEN
5744 REWRITE_TAC[SUBSET_RESTRICT] THEN AP_TERM_TAC THEN ASM SET_TAC[]);;
5746 (* ------------------------------------------------------------------------- *)
5747 (* More properties of open and closed maps. *)
5748 (* ------------------------------------------------------------------------- *)
5750 let CLOSED_MAP_IMP_OPEN_MAP = prove
5751 (`!f:real^M->real^N s t.
5754 (!u. closed_in (subtopology euclidean s) u
5755 ==> closed_in (subtopology euclidean t) (IMAGE f u)) /\
5756 (!u. open_in (subtopology euclidean s) u
5757 ==> open_in (subtopology euclidean s)
5758 {x | x IN s /\ f x IN IMAGE f u})
5759 ==> (!u. open_in (subtopology euclidean s) u
5760 ==> open_in (subtopology euclidean t) (IMAGE f u))`,
5761 REPEAT STRIP_TAC THEN
5763 `IMAGE (f:real^M->real^N) u =
5764 t DIFF IMAGE f (s DIFF {x | x IN s /\ f x IN IMAGE f u})`
5766 [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN ASM SET_TAC[];
5767 MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN
5768 FIRST_X_ASSUM MATCH_MP_TAC THEN
5769 MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[OPEN_IN_REFL] THEN
5770 ASM_SIMP_TAC[CLOSED_IN_REFL]]);;
5772 let OPEN_MAP_IMP_CLOSED_MAP = prove
5773 (`!f:real^M->real^N s t.
5775 (!u. open_in (subtopology euclidean s) u
5776 ==> open_in (subtopology euclidean t) (IMAGE f u)) /\
5777 (!u. closed_in (subtopology euclidean s) u
5778 ==> closed_in (subtopology euclidean s)
5779 {x | x IN s /\ f x IN IMAGE f u})
5780 ==> (!u. closed_in (subtopology euclidean s) u
5781 ==> closed_in (subtopology euclidean t) (IMAGE f u))`,
5782 REPEAT STRIP_TAC THEN
5784 `IMAGE (f:real^M->real^N) u =
5785 t DIFF IMAGE f (s DIFF {x | x IN s /\ f x IN IMAGE f u})`
5787 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN ASM SET_TAC[];
5788 MATCH_MP_TAC CLOSED_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN
5789 FIRST_X_ASSUM MATCH_MP_TAC THEN
5790 MATCH_MP_TAC OPEN_IN_DIFF THEN REWRITE_TAC[CLOSED_IN_REFL] THEN
5791 ASM_SIMP_TAC[OPEN_IN_REFL]]);;
5793 let OPEN_MAP_FROM_COMPOSITION_SURJECTIVE = prove
5794 (`!f:real^M->real^N g:real^N->real^P s t u.
5795 f continuous_on s /\ IMAGE f s = t /\ IMAGE g t SUBSET u /\
5796 (!k. open_in (subtopology euclidean s) k
5797 ==> open_in (subtopology euclidean u) (IMAGE (g o f) k))
5798 ==> (!k. open_in (subtopology euclidean t) k
5799 ==> open_in (subtopology euclidean u) (IMAGE g k))`,
5800 REPEAT STRIP_TAC THEN SUBGOAL_THEN
5801 `IMAGE g k = IMAGE ((g:real^N->real^P) o (f:real^M->real^N))
5802 {x | x IN s /\ f(x) IN k}`
5804 [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
5805 REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[];
5806 FIRST_X_ASSUM MATCH_MP_TAC THEN
5807 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN
5808 EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL]]);;
5810 let CLOSED_MAP_FROM_COMPOSITION_SURJECTIVE = prove
5811 (`!f:real^M->real^N g:real^N->real^P s t u.
5812 f continuous_on s /\ IMAGE f s = t /\ IMAGE g t SUBSET u /\
5813 (!k. closed_in (subtopology euclidean s) k
5814 ==> closed_in (subtopology euclidean u) (IMAGE (g o f) k))
5815 ==> (!k. closed_in (subtopology euclidean t) k
5816 ==> closed_in (subtopology euclidean u) (IMAGE g k))`,
5817 REPEAT STRIP_TAC THEN SUBGOAL_THEN
5818 `IMAGE g k = IMAGE ((g:real^N->real^P) o (f:real^M->real^N))
5819 {x | x IN s /\ f(x) IN k}`
5821 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
5822 REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[];
5823 FIRST_X_ASSUM MATCH_MP_TAC THEN
5824 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN
5825 EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL]]);;
5827 let OPEN_MAP_FROM_COMPOSITION_INJECTIVE = prove
5828 (`!f:real^M->real^N g:real^N->real^P s t u.
5829 IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\
5830 g continuous_on t /\ (!x y. x IN t /\ y IN t /\ g x = g y ==> x = y) /\
5831 (!k. open_in (subtopology euclidean s) k
5832 ==> open_in (subtopology euclidean u) (IMAGE (g o f) k))
5833 ==> (!k. open_in (subtopology euclidean s) k
5834 ==> open_in (subtopology euclidean t) (IMAGE f k))`,
5835 REPEAT STRIP_TAC THEN SUBGOAL_THEN
5836 `IMAGE f k = {x | x IN t /\
5837 g(x) IN IMAGE ((g:real^N->real^P) o (f:real^M->real^N)) k}`
5839 [FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_IN_IMP_SUBSET) THEN
5840 REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[];
5841 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE_GEN THEN
5842 EXISTS_TAC `u:real^P->bool` THEN ASM_SIMP_TAC[]]);;
5844 let CLOSED_MAP_FROM_COMPOSITION_INJECTIVE = prove
5845 (`!f:real^M->real^N g:real^N->real^P s t u.
5846 IMAGE f s SUBSET t /\ IMAGE g t SUBSET u /\
5847 g continuous_on t /\ (!x y. x IN t /\ y IN t /\ g x = g y ==> x = y) /\
5848 (!k. closed_in (subtopology euclidean s) k
5849 ==> closed_in (subtopology euclidean u) (IMAGE (g o f) k))
5850 ==> (!k. closed_in (subtopology euclidean s) k
5851 ==> closed_in (subtopology euclidean t) (IMAGE f k))`,
5852 REPEAT STRIP_TAC THEN SUBGOAL_THEN
5853 `IMAGE f k = {x | x IN t /\
5854 g(x) IN IMAGE ((g:real^N->real^P) o (f:real^M->real^N)) k}`
5856 [FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
5857 REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[];
5858 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE_GEN THEN
5859 EXISTS_TAC `u:real^P->bool` THEN ASM_SIMP_TAC[]]);;
5861 (* ------------------------------------------------------------------------- *)
5862 (* Two equivalent characterizations of a proper/perfect map. *)
5863 (* ------------------------------------------------------------------------- *)
5865 let PROPER_MAP = prove
5866 (`!f:real^M->real^N s t.
5868 ==> ((!k. k SUBSET t /\ compact k ==> compact {x | x IN s /\ f x IN k}) <=>
5869 (!k. closed_in (subtopology euclidean s) k
5870 ==> closed_in (subtopology euclidean t) (IMAGE f k)) /\
5871 (!a. a IN t ==> compact {x | x IN s /\ f x = a}))`,
5872 REPEAT STRIP_TAC THEN EQ_TAC THENL
5873 [REPEAT STRIP_TAC THENL
5875 ONCE_REWRITE_TAC[SET_RULE `x = a <=> x IN {a}`] THEN
5876 FIRST_X_ASSUM MATCH_MP_TAC THEN
5877 ASM_REWRITE_TAC[SING_SUBSET; COMPACT_SING]] THEN
5878 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
5879 REWRITE_TAC[CLOSED_IN_LIMPT] THEN
5880 CONJ_TAC THENL [ASM SET_TAC[]; X_GEN_TAC `y:real^N`] THEN
5881 REWRITE_TAC[LIMPT_SEQUENTIAL_INJ; IN_DELETE] THEN
5882 REWRITE_TAC[IN_IMAGE; LEFT_AND_EXISTS_THM; SKOLEM_THM] THEN
5883 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
5884 REWRITE_TAC[GSYM CONJ_ASSOC; FORALL_AND_THM] THEN
5885 ONCE_REWRITE_TAC[GSYM FUN_EQ_THM] THEN
5886 REWRITE_TAC[UNWIND_THM2; FUN_EQ_THM] THEN
5887 DISCH_THEN(X_CHOOSE_THEN `x:num->real^M` STRIP_ASSUME_TAC) THEN
5889 `~(INTERS {{a | a IN k /\
5890 (f:real^M->real^N) a IN
5891 (y INSERT IMAGE (\i. f(x(n + i))) (:num))} |
5894 [MATCH_MP_TAC COMPACT_FIP THEN CONJ_TAC THENL
5895 [REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV] THEN X_GEN_TAC `n:num` THEN
5896 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CLOSED_IN_CLOSED]) THEN
5897 DISCH_THEN(X_CHOOSE_THEN `c:real^M->bool` STRIP_ASSUME_TAC) THEN
5898 ASM_REWRITE_TAC[SET_RULE
5899 `{x | x IN s INTER k /\ P x} = k INTER {x | x IN s /\ P x}`] THEN
5900 MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN
5901 FIRST_X_ASSUM MATCH_MP_TAC THEN
5902 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
5903 MATCH_MP_TAC COMPACT_SEQUENCE_WITH_LIMIT THEN
5904 FIRST_ASSUM(MP_TAC o SPEC `n:num` o MATCH_MP SEQ_OFFSET) THEN
5905 REWRITE_TAC[ADD_SYM];
5906 REWRITE_TAC[SIMPLE_IMAGE; FORALL_FINITE_SUBSET_IMAGE] THEN
5907 X_GEN_TAC `i:num->bool` THEN STRIP_TAC THEN
5908 FIRST_ASSUM(MP_TAC o ISPEC `\n:num. n` o MATCH_MP
5909 UPPER_BOUND_FINITE_SET) THEN
5910 REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_TAC `m:num`) THEN
5911 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; INTERS_IMAGE; IN_ELIM_THM] THEN
5912 EXISTS_TAC `(x:num->real^M) m` THEN
5913 X_GEN_TAC `p:num` THEN DISCH_TAC THEN
5914 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
5915 REWRITE_TAC[IN_INSERT; IN_IMAGE; IN_UNIV] THEN DISJ2_TAC THEN
5916 EXISTS_TAC `m - p:num` THEN
5917 ASM_MESON_TAC[ARITH_RULE `p <= m ==> p + m - p:num = m`]];
5918 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN MATCH_MP_TAC MONO_EXISTS THEN
5919 X_GEN_TAC `x:real^M` THEN
5920 REWRITE_TAC[INTERS_GSPEC; IN_ELIM_THM; IN_UNIV] THEN
5921 DISCH_THEN(fun th -> LABEL_TAC "*" th THEN MP_TAC(SPEC `0` th)) THEN
5922 REWRITE_TAC[ADD_CLAUSES; IN_INSERT; IN_IMAGE; IN_UNIV] THEN
5923 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (DISJ_CASES_THEN MP_TAC)) THEN
5924 ASM_SIMP_TAC[] THEN DISCH_THEN(X_CHOOSE_TAC `i:num`) THEN
5925 REMOVE_THEN "*" (MP_TAC o SPEC `i + 1`) THEN
5926 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
5927 ASM_REWRITE_TAC[IN_INSERT; IN_IMAGE; IN_UNIV] THEN ARITH_TAC];
5928 STRIP_TAC THEN X_GEN_TAC `k:real^N->bool` THEN STRIP_TAC THEN
5929 REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN
5930 X_GEN_TAC `c:(real^M->bool)->bool` THEN STRIP_TAC THEN
5933 ==> ?g. g SUBSET c /\ FINITE g /\
5934 {x | x IN s /\ (f:real^M->real^N) x = a} SUBSET UNIONS g`
5936 [X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN UNDISCH_THEN
5937 `!a. a IN t ==> compact {x | x IN s /\ (f:real^M->real^N) x = a}`
5938 (MP_TAC o SPEC `a:real^N`) THEN
5939 ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[COMPACT_EQ_HEINE_BOREL]] THEN
5940 DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
5941 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
5942 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
5943 X_GEN_TAC `uu:real^N->(real^M->bool)->bool` THEN
5944 DISCH_THEN(LABEL_TAC "*")] THEN
5947 ==> ?v. open v /\ a IN v /\
5948 {x | x IN s /\ (f:real^M->real^N) x IN v} SUBSET UNIONS(uu a)`
5950 [REPEAT STRIP_TAC THEN
5952 `!k. closed_in (subtopology euclidean s) k
5953 ==> closed_in (subtopology euclidean t)
5954 (IMAGE (f:real^M->real^N) k)`
5955 (MP_TAC o SPEC `(s:real^M->bool) DIFF UNIONS(uu(a:real^N))`) THEN
5956 SIMP_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ANTS_TAC THENL
5957 [CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
5958 REWRITE_TAC[SET_RULE `s DIFF (s DIFF t) = s INTER t`] THEN
5959 MATCH_MP_TAC OPEN_IN_OPEN_INTER THEN
5960 MATCH_MP_TAC OPEN_UNIONS THEN ASM SET_TAC[];
5961 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5962 REWRITE_TAC[OPEN_IN_OPEN] THEN MATCH_MP_TAC MONO_EXISTS THEN
5963 X_GEN_TAC `v:real^N->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
5964 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `a:real^N`)) THEN
5965 ASM_REWRITE_TAC[] THEN REPEAT
5966 ((ANTS_TAC THENL [ASM SET_TAC[]; DISCH_TAC]) ORELSE STRIP_TAC)
5967 THENL [ALL_TAC; ASM SET_TAC[]] THEN
5968 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
5969 DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN ASM SET_TAC[]];
5970 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
5971 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
5972 X_GEN_TAC `vv:real^N->(real^N->bool)` THEN
5973 DISCH_THEN(LABEL_TAC "+")] THEN
5974 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL]) THEN
5975 DISCH_THEN(MP_TAC o SPEC `IMAGE (vv:real^N->(real^N->bool)) k`) THEN
5976 ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN
5977 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r ==> s <=> q /\ p ==> r ==> s`] THEN
5978 REWRITE_TAC[FORALL_FINITE_SUBSET_IMAGE] THEN
5979 X_GEN_TAC `j:real^N->bool` THEN REPEAT STRIP_TAC THEN
5980 EXISTS_TAC `UNIONS(IMAGE (uu:real^N->(real^M->bool)->bool) j)` THEN
5981 REPEAT CONJ_TAC THENL
5983 ASM_SIMP_TAC[FINITE_UNIONS; FORALL_IN_IMAGE; FINITE_IMAGE] THEN
5985 REWRITE_TAC[UNIONS_IMAGE; SUBSET; IN_UNIONS; IN_ELIM_THM] THEN
5988 let PROPER_MAP_FROM_COMPACT = prove
5989 (`!f:real^M->real^N s k.
5990 f continuous_on s /\ IMAGE f s SUBSET t /\ compact s /\
5991 closed_in (subtopology euclidean t) k
5992 ==> compact {x | x IN s /\ f x IN k}`,
5993 REPEAT STRIP_TAC THEN
5994 MATCH_MP_TAC CLOSED_IN_COMPACT THEN EXISTS_TAC `s:real^M->bool` THEN
5995 ASM_MESON_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_GEN]);;
5997 (* ------------------------------------------------------------------------- *)
5998 (* Pasting functions together on open sets. *)
5999 (* ------------------------------------------------------------------------- *)
6001 let PASTING_LEMMA = prove
6002 (`!f:A->real^M->real^N g t s k.
6004 ==> open_in (subtopology euclidean s) (t i) /\
6005 (f i) continuous_on (t i)) /\
6006 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j
6007 ==> f i x = f j x) /\
6008 (!x. x IN s ==> ?j. j IN k /\ x IN t j /\ g x = f j x)
6009 ==> g continuous_on s`,
6010 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_OPEN_IN_PREIMAGE_EQ] THEN
6011 STRIP_TAC THEN X_GEN_TAC `u:real^N->bool` THEN DISCH_TAC THEN
6013 `{x | x IN s /\ g x IN u} =
6014 UNIONS {{x | x IN (t i) /\ ((f:A->real^M->real^N) i x) IN u} |
6017 [SUBGOAL_THEN `!i. i IN k ==> ((t:A->real^M->bool) i) SUBSET s`
6019 [ASM_MESON_TAC[OPEN_IN_SUBSET; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY];
6020 REWRITE_TAC[UNIONS_GSPEC] THEN ASM SET_TAC[]];
6021 MATCH_MP_TAC OPEN_IN_UNIONS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN
6022 ASM_MESON_TAC[OPEN_IN_TRANS]]);;
6024 let PASTING_LEMMA_EXISTS = prove
6025 (`!f:A->real^M->real^N t s k.
6026 s SUBSET UNIONS {t i | i IN k} /\
6028 ==> open_in (subtopology euclidean s) (t i) /\
6029 (f i) continuous_on (t i)) /\
6030 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j
6032 ==> ?g. g continuous_on s /\
6033 (!x i. i IN k /\ x IN s INTER t i ==> g x = f i x)`,
6034 REPEAT STRIP_TAC THEN
6035 EXISTS_TAC `\x. (f:A->real^M->real^N)(@i. i IN k /\ x IN t i) x` THEN
6036 CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN MATCH_MP_TAC PASTING_LEMMA THEN
6037 MAP_EVERY EXISTS_TAC
6038 [`f:A->real^M->real^N`; `t:A->real^M->bool`; `k:A->bool`] THEN
6041 let CONTINUOUS_ON_UNION_LOCAL_OPEN = prove
6042 (`!f:real^M->real^N s.
6043 open_in (subtopology euclidean (s UNION t)) s /\
6044 open_in (subtopology euclidean (s UNION t)) t /\
6045 f continuous_on s /\ f continuous_on t
6046 ==> f continuous_on (s UNION t)`,
6047 REPEAT STRIP_TAC THEN MP_TAC(ISPECL
6048 [`\i:(real^M->bool). (f:real^M->real^N)`; `f:real^M->real^N`;
6049 `\i:(real^M->bool). i`; `s UNION t:real^M->bool`; `{s:real^M->bool,t}`]
6050 PASTING_LEMMA) THEN DISCH_THEN MATCH_MP_TAC THEN
6051 ASM_REWRITE_TAC[FORALL_IN_INSERT; EXISTS_IN_INSERT; NOT_IN_EMPTY] THEN
6052 REWRITE_TAC[IN_UNION]);;
6054 let CONTINUOUS_ON_UNION_OPEN = prove
6055 (`!f s t. open s /\ open t /\ f continuous_on s /\ f continuous_on t
6056 ==> f continuous_on (s UNION t)`,
6057 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL_OPEN THEN
6058 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN
6059 ASM_SIMP_TAC[OPEN_UNION] THEN SET_TAC[]);;
6061 let CONTINUOUS_ON_CASES_LOCAL_OPEN = prove
6062 (`!P f g:real^M->real^N s t.
6063 open_in (subtopology euclidean (s UNION t)) s /\
6064 open_in (subtopology euclidean (s UNION t)) t /\
6065 f continuous_on s /\ g continuous_on t /\
6066 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x)
6067 ==> (\x. if P x then f x else g x) continuous_on (s UNION t)`,
6068 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL_OPEN THEN
6069 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL
6070 [EXISTS_TAC `f:real^M->real^N`; EXISTS_TAC `g:real^M->real^N`] THEN
6071 ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;
6073 let CONTINUOUS_ON_CASES_OPEN = prove
6077 f continuous_on s /\
6078 g continuous_on t /\
6079 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x)
6080 ==> (\x. if P x then f x else g x) continuous_on s UNION t`,
6081 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL_OPEN THEN
6082 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN
6083 ASM_SIMP_TAC[OPEN_UNION] THEN SET_TAC[]);;
6085 (* ------------------------------------------------------------------------- *)
6086 (* Likewise on closed sets, with a finiteness assumption. *)
6087 (* ------------------------------------------------------------------------- *)
6089 let PASTING_LEMMA_CLOSED = prove
6090 (`!f:A->real^M->real^N g t s k.
6093 ==> closed_in (subtopology euclidean s) (t i) /\
6094 (f i) continuous_on (t i)) /\
6095 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j
6096 ==> f i x = f j x) /\
6097 (!x. x IN s ==> ?j. j IN k /\ x IN t j /\ g x = f j x)
6098 ==> g continuous_on s`,
6099 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN
6100 STRIP_TAC THEN X_GEN_TAC `u:real^N->bool` THEN DISCH_TAC THEN
6102 `{x | x IN s /\ g x IN u} =
6103 UNIONS {{x | x IN (t i) /\ ((f:A->real^M->real^N) i x) IN u} |
6106 [SUBGOAL_THEN `!i. i IN k ==> ((t:A->real^M->bool) i) SUBSET s`
6108 [ASM_MESON_TAC[CLOSED_IN_SUBSET; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY];
6109 REWRITE_TAC[UNIONS_GSPEC] THEN ASM SET_TAC[]];
6110 MATCH_MP_TAC CLOSED_IN_UNIONS THEN
6111 ASM_SIMP_TAC[SIMPLE_IMAGE; FINITE_IMAGE; FORALL_IN_IMAGE] THEN
6112 ASM_MESON_TAC[CLOSED_IN_TRANS]]);;
6114 let PASTING_LEMMA_EXISTS_CLOSED = prove
6115 (`!f:A->real^M->real^N t s k.
6117 s SUBSET UNIONS {t i | i IN k} /\
6119 ==> closed_in (subtopology euclidean s) (t i) /\
6120 (f i) continuous_on (t i)) /\
6121 (!i j x. i IN k /\ j IN k /\ x IN s INTER t i INTER t j
6123 ==> ?g. g continuous_on s /\
6124 (!x i. i IN k /\ x IN s INTER t i ==> g x = f i x)`,
6125 REPEAT STRIP_TAC THEN
6126 EXISTS_TAC `\x. (f:A->real^M->real^N)(@i. i IN k /\ x IN t i) x` THEN
6127 CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
6128 MATCH_MP_TAC PASTING_LEMMA_CLOSED THEN
6129 MAP_EVERY EXISTS_TAC
6130 [`f:A->real^M->real^N`; `t:A->real^M->bool`; `k:A->bool`] THEN
6133 (* ------------------------------------------------------------------------- *)
6134 (* Closure of halflines, halfspaces and hyperplanes. *)
6135 (* ------------------------------------------------------------------------- *)
6137 let LIM_LIFT_DOT = prove
6138 (`!f:real^M->real^N a.
6139 (f --> l) net ==> ((lift o (\y. a dot f(y))) --> lift(a dot l)) net`,
6140 REPEAT GEN_TAC THEN ASM_CASES_TAC `a = vec 0:real^N` THENL
6141 [ASM_REWRITE_TAC[DOT_LZERO; LIFT_NUM; o_DEF; LIM_CONST]; ALL_TAC] THEN
6142 REWRITE_TAC[LIM] THEN MATCH_MP_TAC MONO_OR THEN REWRITE_TAC[] THEN
6143 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6144 FIRST_X_ASSUM(MP_TAC o SPEC `e / norm(a:real^N)`) THEN
6145 ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; REAL_LT_RDIV_EQ] THEN
6146 REWRITE_TAC[dist; o_THM; GSYM LIFT_SUB; GSYM DOT_RSUB; NORM_LIFT] THEN
6147 ONCE_REWRITE_TAC[DOT_SYM] THEN
6148 MESON_TAC[NORM_CAUCHY_SCHWARZ_ABS; REAL_MUL_SYM; REAL_LET_TRANS]);;
6150 let CONTINUOUS_AT_LIFT_DOT = prove
6151 (`!a:real^N x. (lift o (\y. a dot y)) continuous at x`,
6152 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_AT; o_THM] THEN
6153 MATCH_MP_TAC LIM_LIFT_DOT THEN REWRITE_TAC[LIM_AT] THEN MESON_TAC[]);;
6155 let CONTINUOUS_ON_LIFT_DOT = prove
6156 (`!s. (lift o (\y. a dot y)) continuous_on s`,
6157 SIMP_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON; CONTINUOUS_AT_LIFT_DOT]);;
6159 let CLOSED_INTERVAL_LEFT = prove
6162 {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> x$i <= b$i}`,
6163 REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE; IN_ELIM_THM] THEN
6164 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
6165 FIRST_X_ASSUM(MP_TAC o SPEC `(x:real^N)$i - (b:real^N)$i`) THEN
6166 ASM_REWRITE_TAC[REAL_SUB_LT] THEN
6167 DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN
6168 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
6169 REWRITE_TAC[dist; REAL_NOT_LT] THEN
6170 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((z - x :real^N)$i)` THEN
6171 ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
6172 ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
6173 ASM_SIMP_TAC[REAL_ARITH `z <= b /\ b < x ==> x - b <= abs(z - x)`]);;
6175 let CLOSED_INTERVAL_RIGHT = prove
6178 {x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= x$i}`,
6179 REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE; IN_ELIM_THM] THEN
6180 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
6181 FIRST_X_ASSUM(MP_TAC o SPEC `(a:real^N)$i - (x:real^N)$i`) THEN
6182 ASM_REWRITE_TAC[REAL_SUB_LT] THEN
6183 DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN
6184 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
6185 REWRITE_TAC[dist; REAL_NOT_LT] THEN
6186 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((z - x :real^N)$i)` THEN
6187 ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
6188 ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
6189 ASM_SIMP_TAC[REAL_ARITH `x < a /\ a <= z ==> a - x <= abs(z - x)`]);;
6191 let CLOSED_HALFSPACE_LE = prove
6192 (`!a:real^N b. closed {x | a dot x <= b}`,
6194 MP_TAC(ISPEC `(:real^N)` CONTINUOUS_ON_LIFT_DOT) THEN
6195 REWRITE_TAC[CONTINUOUS_ON_CLOSED; GSYM CLOSED_IN; SUBTOPOLOGY_UNIV] THEN
6196 DISCH_THEN(MP_TAC o SPEC
6197 `IMAGE lift {r | ?x:real^N. (a dot x = r) /\ r <= b}`) THEN
6200 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
6201 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; IN_UNIV] THEN
6202 REWRITE_TAC[o_DEF] THEN MESON_TAC[LIFT_DROP]] THEN
6203 REWRITE_TAC[CLOSED_IN_CLOSED] THEN
6204 EXISTS_TAC `{x | !i. 1 <= i /\ i <= dimindex(:1)
6205 ==> (x:real^1)$i <= (lift b)$i}` THEN
6206 REWRITE_TAC[CLOSED_INTERVAL_LEFT] THEN
6207 SIMP_TAC[EXTENSION; IN_IMAGE; IN_UNIV; IN_ELIM_THM; IN_INTER;
6208 VEC_COMPONENT; DIMINDEX_1; LAMBDA_BETA; o_THM] THEN
6209 SIMP_TAC[ARITH_RULE `1 <= i /\ i <= 1 <=> (i = 1)`] THEN
6210 REWRITE_TAC[GSYM drop; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
6211 MESON_TAC[LIFT_DROP]);;
6213 let CLOSED_HALFSPACE_GE = prove
6214 (`!a:real^N b. closed {x | a dot x >= b}`,
6215 REWRITE_TAC[REAL_ARITH `a >= b <=> --a <= --b`] THEN
6216 REWRITE_TAC[GSYM DOT_LNEG; CLOSED_HALFSPACE_LE]);;
6218 let CLOSED_HYPERPLANE = prove
6219 (`!a b. closed {x | a dot x = b}`,
6220 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
6221 REWRITE_TAC[REAL_ARITH `b <= a dot x <=> a dot x >= b`] THEN
6222 REWRITE_TAC[SET_RULE `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN
6223 SIMP_TAC[CLOSED_INTER; CLOSED_HALFSPACE_LE; CLOSED_HALFSPACE_GE]);;
6225 let CLOSED_STANDARD_HYPERPLANE = prove
6226 (`!k a. closed {x:real^N | x$k = a}`,
6228 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
6230 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6231 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSED_HYPERPLANE) THEN
6232 ASM_SIMP_TAC[DOT_BASIS]);;
6234 let CLOSED_HALFSPACE_COMPONENT_LE = prove
6235 (`!a k. closed {x:real^N | x$k <= a}`,
6237 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
6239 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6240 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSED_HALFSPACE_LE) THEN
6241 ASM_SIMP_TAC[DOT_BASIS]);;
6243 let CLOSED_HALFSPACE_COMPONENT_GE = prove
6244 (`!a k. closed {x:real^N | x$k >= a}`,
6246 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
6248 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6249 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSED_HALFSPACE_GE) THEN
6250 ASM_SIMP_TAC[DOT_BASIS]);;
6252 (* ------------------------------------------------------------------------- *)
6253 (* Openness of halfspaces. *)
6254 (* ------------------------------------------------------------------------- *)
6256 let OPEN_HALFSPACE_LT = prove
6257 (`!a b. open {x | a dot x < b}`,
6258 REWRITE_TAC[GSYM REAL_NOT_LE] THEN
6259 REWRITE_TAC[SET_RULE `{x | ~p x} = UNIV DIFF {x | p x}`] THEN
6260 REWRITE_TAC[GSYM closed; GSYM real_ge; CLOSED_HALFSPACE_GE]);;
6262 let OPEN_HALFSPACE_COMPONENT_LT = prove
6263 (`!a k. open {x:real^N | x$k < a}`,
6265 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
6267 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6268 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] OPEN_HALFSPACE_LT) THEN
6269 ASM_SIMP_TAC[DOT_BASIS]);;
6271 let OPEN_HALFSPACE_GT = prove
6272 (`!a b. open {x | a dot x > b}`,
6273 REWRITE_TAC[REAL_ARITH `x > y <=> ~(x <= y)`] THEN
6274 REWRITE_TAC[SET_RULE `{x | ~p x} = UNIV DIFF {x | p x}`] THEN
6275 REWRITE_TAC[GSYM closed; CLOSED_HALFSPACE_LE]);;
6277 let OPEN_HALFSPACE_COMPONENT_GT = prove
6278 (`!a k. open {x:real^N | x$k > a}`,
6280 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
6282 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6283 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] OPEN_HALFSPACE_GT) THEN
6284 ASM_SIMP_TAC[DOT_BASIS]);;
6286 let OPEN_POSITIVE_MULTIPLES = prove
6287 (`!s:real^N->bool. open s ==> open {c % x | &0 < c /\ x IN s}`,
6288 REWRITE_TAC[open_def; FORALL_IN_GSPEC] THEN GEN_TAC THEN DISCH_TAC THEN
6289 MAP_EVERY X_GEN_TAC [`c:real`; `x:real^N`] THEN STRIP_TAC THEN
6290 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
6291 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
6292 EXISTS_TAC `c * e:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN
6293 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
6294 FIRST_X_ASSUM(MP_TAC o SPEC `inv(c) % y:real^N`) THEN ANTS_TAC THENL
6295 [SUBGOAL_THEN `x:real^N = inv c % c % x` SUBST1_TAC THENL
6296 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID;
6298 ASM_SIMP_TAC[DIST_MUL; real_abs; REAL_LT_INV_EQ; REAL_LT_IMP_LE] THEN
6299 ONCE_REWRITE_TAC[REAL_ARITH `inv c * x:real = x / c`] THEN
6300 ASM_MESON_TAC[REAL_LT_LDIV_EQ; REAL_MUL_SYM]];
6301 DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
6302 EXISTS_TAC `c:real` THEN EXISTS_TAC `inv(c) % y:real^N` THEN
6303 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; REAL_LT_IMP_NZ] THEN
6304 VECTOR_ARITH_TAC]);;
6306 (* ------------------------------------------------------------------------- *)
6307 (* Closures and interiors of halfspaces. *)
6308 (* ------------------------------------------------------------------------- *)
6310 let INTERIOR_HALFSPACE_LE = prove
6312 ~(a = vec 0) ==> interior {x | a dot x <= b} = {x | a dot x < b}`,
6313 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_UNIQUE THEN
6314 SIMP_TAC[OPEN_HALFSPACE_LT; SUBSET; IN_ELIM_THM; REAL_LT_IMP_LE] THEN
6315 X_GEN_TAC `s:real^N->bool` THEN STRIP_TAC THEN
6316 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN ASM_SIMP_TAC[REAL_LT_LE] THEN
6318 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN
6319 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
6320 DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
6321 REWRITE_TAC[SUBSET; IN_CBALL] THEN
6322 DISCH_THEN(MP_TAC o SPEC `x + e / norm(a) % a:real^N`) THEN
6323 REWRITE_TAC[NORM_ARITH `dist(x:real^N,x + y) = norm y`] THEN
6324 ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; REAL_DIV_RMUL;
6325 NORM_EQ_0; REAL_ARITH `&0 < x ==> abs x <= x`] THEN
6327 FIRST_X_ASSUM(MP_TAC o SPEC `x + e / norm(a) % a:real^N`) THEN
6328 ASM_REWRITE_TAC[DOT_RADD; DOT_RMUL] THEN
6329 MATCH_MP_TAC(REAL_ARITH `&0 < e ==> ~(b + e <= b)`) THEN
6330 ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; NORM_POS_LT; DOT_POS_LT]);;
6332 let INTERIOR_HALFSPACE_GE = prove
6334 ~(a = vec 0) ==> interior {x | a dot x >= b} = {x | a dot x > b}`,
6335 REPEAT STRIP_TAC THEN
6336 ONCE_REWRITE_TAC[REAL_ARITH `a >= b <=> --a <= --b`;
6337 REAL_ARITH `a > b <=> --a < --b`] THEN
6338 ASM_SIMP_TAC[GSYM DOT_LNEG; INTERIOR_HALFSPACE_LE; VECTOR_NEG_EQ_0]);;
6340 let INTERIOR_HALFSPACE_COMPONENT_LE = prove
6341 (`!a k. interior {x:real^N | x$k <= a} = {x | x$k < a}`,
6343 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
6345 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6346 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] INTERIOR_HALFSPACE_LE) THEN
6347 ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);;
6349 let INTERIOR_HALFSPACE_COMPONENT_GE = prove
6350 (`!a k. interior {x:real^N | x$k >= a} = {x | x$k > a}`,
6352 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
6354 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6355 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] INTERIOR_HALFSPACE_GE) THEN
6356 ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);;
6358 let CLOSURE_HALFSPACE_LT = prove
6360 ~(a = vec 0) ==> closure {x | a dot x < b} = {x | a dot x <= b}`,
6361 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSURE_INTERIOR] THEN
6362 REWRITE_TAC[SET_RULE `UNIV DIFF {x | P x} = {x | ~P x}`] THEN
6363 ASM_SIMP_TAC[REAL_ARITH `~(x < b) <=> x >= b`; INTERIOR_HALFSPACE_GE] THEN
6364 REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNIV; IN_ELIM_THM] THEN REAL_ARITH_TAC);;
6366 let CLOSURE_HALFSPACE_GT = prove
6368 ~(a = vec 0) ==> closure {x | a dot x > b} = {x | a dot x >= b}`,
6369 REPEAT STRIP_TAC THEN
6370 ONCE_REWRITE_TAC[REAL_ARITH `a >= b <=> --a <= --b`;
6371 REAL_ARITH `a > b <=> --a < --b`] THEN
6372 ASM_SIMP_TAC[GSYM DOT_LNEG; CLOSURE_HALFSPACE_LT; VECTOR_NEG_EQ_0]);;
6374 let CLOSURE_HALFSPACE_COMPONENT_LT = prove
6375 (`!a k. closure {x:real^N | x$k < a} = {x | x$k <= a}`,
6377 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
6379 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6380 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSURE_HALFSPACE_LT) THEN
6381 ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);;
6383 let CLOSURE_HALFSPACE_COMPONENT_GT = prove
6384 (`!a k. closure {x:real^N | x$k > a} = {x | x$k >= a}`,
6386 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
6388 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6389 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] CLOSURE_HALFSPACE_GT) THEN
6390 ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);;
6392 let INTERIOR_HYPERPLANE = prove
6393 (`!a b. ~(a = vec 0) ==> interior {x | a dot x = b} = {}`,
6394 REWRITE_TAC[REAL_ARITH `x = y <=> x <= y /\ x >= y`] THEN
6395 REWRITE_TAC[SET_RULE `{x | p x /\ q x} = {x | p x} INTER {x | q x}`] THEN
6396 REWRITE_TAC[INTERIOR_INTER] THEN
6397 ASM_SIMP_TAC[INTERIOR_HALFSPACE_LE; INTERIOR_HALFSPACE_GE] THEN
6398 REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM; NOT_IN_EMPTY] THEN
6401 let FRONTIER_HALFSPACE_LE = prove
6402 (`!a:real^N b. ~(a = vec 0 /\ b = &0)
6403 ==> frontier {x | a dot x <= b} = {x | a dot x = b}`,
6404 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN
6405 ASM_SIMP_TAC[DOT_LZERO] THENL
6406 [ASM_CASES_TAC `&0 <= b` THEN
6407 ASM_REWRITE_TAC[UNIV_GSPEC; FRONTIER_UNIV; EMPTY_GSPEC; FRONTIER_EMPTY];
6408 ASM_SIMP_TAC[frontier; INTERIOR_HALFSPACE_LE; CLOSURE_CLOSED;
6409 CLOSED_HALFSPACE_LE] THEN
6410 REWRITE_TAC[EXTENSION; IN_DIFF; IN_ELIM_THM] THEN REAL_ARITH_TAC]);;
6412 let FRONTIER_HALFSPACE_GE = prove
6413 (`!a:real^N b. ~(a = vec 0 /\ b = &0)
6414 ==> frontier {x | a dot x >= b} = {x | a dot x = b}`,
6415 REPEAT STRIP_TAC THEN
6416 MP_TAC(ISPECL [`--a:real^N`; `--b:real`] FRONTIER_HALFSPACE_LE) THEN
6417 ASM_REWRITE_TAC[VECTOR_NEG_EQ_0; REAL_NEG_EQ_0; DOT_LNEG] THEN
6418 REWRITE_TAC[REAL_LE_NEG2; REAL_EQ_NEG2; real_ge]);;
6420 let FRONTIER_HALFSPACE_LT = prove
6421 (`!a:real^N b. ~(a = vec 0 /\ b = &0)
6422 ==> frontier {x | a dot x < b} = {x | a dot x = b}`,
6423 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN
6424 ASM_SIMP_TAC[DOT_LZERO] THENL
6425 [ASM_CASES_TAC `&0 < b` THEN
6426 ASM_REWRITE_TAC[UNIV_GSPEC; FRONTIER_UNIV; EMPTY_GSPEC; FRONTIER_EMPTY];
6427 ASM_SIMP_TAC[frontier; CLOSURE_HALFSPACE_LT; INTERIOR_OPEN;
6428 OPEN_HALFSPACE_LT] THEN
6429 REWRITE_TAC[EXTENSION; IN_DIFF; IN_ELIM_THM] THEN REAL_ARITH_TAC]);;
6431 let FRONTIER_HALFSPACE_GT = prove
6432 (`!a:real^N b. ~(a = vec 0 /\ b = &0)
6433 ==> frontier {x | a dot x > b} = {x | a dot x = b}`,
6434 REPEAT STRIP_TAC THEN
6435 MP_TAC(ISPECL [`--a:real^N`; `--b:real`] FRONTIER_HALFSPACE_LT) THEN
6436 ASM_REWRITE_TAC[VECTOR_NEG_EQ_0; REAL_NEG_EQ_0; DOT_LNEG] THEN
6437 REWRITE_TAC[REAL_LT_NEG2; REAL_EQ_NEG2; real_gt]);;
6439 let INTERIOR_STANDARD_HYPERPLANE = prove
6440 (`!k a. interior {x:real^N | x$k = a} = {}`,
6442 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !x:real^N. x$k = x$i`
6444 [ASM_REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6445 MP_TAC(ISPECL [`basis i:real^N`; `a:real`] INTERIOR_HYPERPLANE) THEN
6446 ASM_SIMP_TAC[DOT_BASIS; BASIS_NONZERO]);;
6448 let EMPTY_INTERIOR_LOWDIM = prove
6449 (`!s:real^N->bool. dim(s) < dimindex(:N) ==> interior s = {}`,
6450 GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP LOWDIM_SUBSET_HYPERPLANE) THEN
6451 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
6452 MATCH_MP_TAC(SET_RULE
6453 `!t u. s SUBSET t /\ t SUBSET u /\ u = {} ==> s = {}`) THEN
6454 MAP_EVERY EXISTS_TAC
6455 [`interior(span(s):real^N->bool)`;
6456 `interior({x:real^N | a dot x = &0})`] THEN
6457 ASM_SIMP_TAC[SUBSET_INTERIOR; SPAN_INC; INTERIOR_HYPERPLANE]);;
6459 (* ------------------------------------------------------------------------- *)
6460 (* Unboundedness of halfspaces. *)
6461 (* ------------------------------------------------------------------------- *)
6463 let UNBOUNDED_HALFSPACE_COMPONENT_LE = prove
6464 (`!a k. ~bounded {x:real^N | x$k <= a}`,
6466 SUBGOAL_THEN `?i. 1 <= i /\ i <= dimindex(:N) /\ !z:real^N. z$k = z$i`
6467 CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
6468 ASM_REWRITE_TAC[bounded; FORALL_IN_GSPEC] THEN
6469 DISCH_THEN(X_CHOOSE_THEN `B:real` MP_TAC) THEN
6470 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
6471 EXISTS_TAC `--(&1 + max (abs B) (abs a)) % basis i:real^N` THEN
6472 ASM_SIMP_TAC[NORM_MUL; NORM_BASIS; BASIS_COMPONENT;
6473 VECTOR_MUL_COMPONENT] THEN
6476 let UNBOUNDED_HALFSPACE_COMPONENT_GE = prove
6477 (`!a k. ~bounded {x:real^N | x$k >= a}`,
6478 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_NEGATIONS) THEN
6479 MP_TAC(SPECL [`--a:real`; `k:num`] UNBOUNDED_HALFSPACE_COMPONENT_LE) THEN
6480 REWRITE_TAC[CONTRAPOS_THM] THEN MATCH_MP_TAC EQ_IMP THEN
6481 AP_TERM_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN CONJ_TAC THENL
6482 [MESON_TAC[VECTOR_NEG_NEG];
6483 REWRITE_TAC[IN_ELIM_THM; VECTOR_NEG_COMPONENT] THEN REAL_ARITH_TAC]);;
6485 let UNBOUNDED_HALFSPACE_COMPONENT_LT = prove
6486 (`!a k. ~bounded {x:real^N | x$k < a}`,
6487 ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN
6488 REWRITE_TAC[CLOSURE_HALFSPACE_COMPONENT_LT;
6489 UNBOUNDED_HALFSPACE_COMPONENT_LE]);;
6491 let UNBOUNDED_HALFSPACE_COMPONENT_GT = prove
6492 (`!a k. ~bounded {x:real^N | x$k > a}`,
6493 ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN
6494 REWRITE_TAC[CLOSURE_HALFSPACE_COMPONENT_GT;
6495 UNBOUNDED_HALFSPACE_COMPONENT_GE]);;
6497 let BOUNDED_HALFSPACE_LE = prove
6498 (`!a:real^N b. bounded {x | a dot x <= b} <=> a = vec 0 /\ b < &0`,
6499 GEOM_BASIS_MULTIPLE_TAC 1 `a:real^N` THEN
6500 SIMP_TAC[DOT_LMUL; DOT_BASIS; VECTOR_MUL_EQ_0; DIMINDEX_GE_1; LE_REFL;
6502 X_GEN_TAC `a:real` THEN ASM_CASES_TAC `a = &0` THEN ASM_REWRITE_TAC[] THEN
6503 DISCH_TAC THEN X_GEN_TAC `b:real` THENL
6504 [REWRITE_TAC[REAL_MUL_LZERO; DOT_LZERO; GSYM REAL_NOT_LE] THEN
6505 ASM_CASES_TAC `&0 <= b` THEN
6506 ASM_REWRITE_TAC[BOUNDED_EMPTY; NOT_BOUNDED_UNIV;
6507 SET_RULE `{x | T} = UNIV`; EMPTY_GSPEC];
6508 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
6509 ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_LT_LE;
6510 UNBOUNDED_HALFSPACE_COMPONENT_LE]]);;
6512 let BOUNDED_HALFSPACE_GE = prove
6513 (`!a:real^N b. bounded {x | a dot x >= b} <=> a = vec 0 /\ &0 < b`,
6514 REWRITE_TAC[REAL_ARITH `a >= b <=> --a <= --b`] THEN
6515 REWRITE_TAC[GSYM DOT_LNEG; BOUNDED_HALFSPACE_LE] THEN
6516 REWRITE_TAC[VECTOR_NEG_EQ_0; REAL_ARITH `--b < &0 <=> &0 < b`]);;
6518 let BOUNDED_HALFSPACE_LT = prove
6519 (`!a:real^N b. bounded {x | a dot x < b} <=> a = vec 0 /\ b <= &0`,
6520 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = vec 0` THEN
6521 ASM_REWRITE_TAC[] THENL
6522 [REWRITE_TAC[DOT_LZERO; GSYM REAL_NOT_LE] THEN ASM_CASES_TAC `b <= &0` THEN
6523 ASM_REWRITE_TAC[BOUNDED_EMPTY; NOT_BOUNDED_UNIV;
6524 SET_RULE `{x | T} = UNIV`; EMPTY_GSPEC];
6525 ONCE_REWRITE_TAC[GSYM BOUNDED_CLOSURE_EQ] THEN
6526 ASM_SIMP_TAC[CLOSURE_HALFSPACE_LT; BOUNDED_HALFSPACE_LE]]);;
6528 let BOUNDED_HALFSPACE_GT = prove
6529 (`!a:real^N b. bounded {x | a dot x > b} <=> a = vec 0 /\ &0 <= b`,
6530 REWRITE_TAC[REAL_ARITH `a > b <=> --a < --b`] THEN
6531 REWRITE_TAC[GSYM DOT_LNEG; BOUNDED_HALFSPACE_LT] THEN
6532 REWRITE_TAC[VECTOR_NEG_EQ_0; REAL_ARITH `--b <= &0 <=> &0 <= b`]);;
6534 (* ------------------------------------------------------------------------- *)
6535 (* Equality of continuous functions on closure and related results. *)
6536 (* ------------------------------------------------------------------------- *)
6538 let FORALL_IN_CLOSURE = prove
6539 (`!f:real^M->real^N s t.
6540 closed t /\ f continuous_on (closure s) /\
6541 (!x. x IN s ==> f x IN t)
6542 ==> (!x. x IN closure s ==> f x IN t)`,
6543 REWRITE_TAC[SET_RULE `(!x. x IN s ==> f x IN t) <=>
6544 s SUBSET {x | x IN s /\ f x IN t}`] THEN
6545 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_MINIMAL THEN
6546 ASM_REWRITE_TAC[CLOSED_CLOSURE] THEN CONJ_TAC THENL
6547 [MP_TAC(ISPEC `s:real^M->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[];
6548 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN
6549 ASM_REWRITE_TAC[CLOSED_CLOSURE]]);;
6551 let CONTINUOUS_LE_ON_CLOSURE = prove
6552 (`!f:real^M->real s a.
6553 (lift o f) continuous_on closure(s) /\ (!x. x IN s ==> f(x) <= a)
6554 ==> !x. x IN closure(s) ==> f(x) <= a`,
6556 (`x IN s ==> f x <= a <=> x IN s ==> (lift o f) x IN {y | y$1 <= a}`,
6557 REWRITE_TAC[IN_ELIM_THM; o_THM; GSYM drop; LIFT_DROP]) in
6558 REWRITE_TAC[lemma] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
6559 MATCH_MP_TAC FORALL_IN_CLOSURE THEN
6560 ASM_REWRITE_TAC[ETA_AX; CLOSED_HALFSPACE_COMPONENT_LE]);;
6562 let CONTINUOUS_GE_ON_CLOSURE = prove
6563 (`!f:real^M->real s a.
6564 (lift o f) continuous_on closure(s) /\ (!x. x IN s ==> a <= f(x))
6565 ==> !x. x IN closure(s) ==> a <= f(x)`,
6567 (`x IN s ==> a <= f x <=> x IN s ==> (lift o f) x IN {y | y$1 >= a}`,
6568 REWRITE_TAC[IN_ELIM_THM; o_THM; GSYM drop; real_ge; LIFT_DROP]) in
6569 REWRITE_TAC[lemma] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
6570 MATCH_MP_TAC FORALL_IN_CLOSURE THEN
6571 ASM_REWRITE_TAC[ETA_AX; CLOSED_HALFSPACE_COMPONENT_GE]);;
6573 let CONTINUOUS_CONSTANT_ON_CLOSURE = prove
6574 (`!f:real^M->real^N s a.
6575 f continuous_on closure(s) /\ (!x. x IN s ==> f(x) = a)
6576 ==> !x. x IN closure(s) ==> f(x) = a`,
6577 REWRITE_TAC[SET_RULE
6578 `x IN s ==> f x = a <=> x IN s ==> f x IN {a}`] THEN
6579 REPEAT GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC FORALL_IN_CLOSURE THEN
6580 ASM_REWRITE_TAC[CLOSED_SING]);;
6582 let CONTINUOUS_AGREE_ON_CLOSURE = prove
6583 (`!g h:real^M->real^N.
6584 g continuous_on closure s /\ h continuous_on closure s /\
6585 (!x. x IN s ==> g x = h x)
6586 ==> !x. x IN closure s ==> g x = h x`,
6587 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN STRIP_TAC THEN
6588 MATCH_MP_TAC CONTINUOUS_CONSTANT_ON_CLOSURE THEN
6589 ASM_SIMP_TAC[CONTINUOUS_ON_SUB]);;
6591 let CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT = prove
6592 (`!f:real^M->real^N s a.
6594 ==> closed_in (subtopology euclidean s) {x | x IN s /\ f x = a}`,
6595 REPEAT STRIP_TAC THEN
6596 ONCE_REWRITE_TAC[SET_RULE
6597 `{x | x IN s /\ f(x) = a} = {x | x IN s /\ f(x) IN {a}}`] THEN
6598 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN
6599 ASM_REWRITE_TAC[CLOSED_SING]);;
6601 let CONTINUOUS_CLOSED_PREIMAGE_CONSTANT = prove
6602 (`!f:real^M->real^N s.
6603 f continuous_on s /\ closed s ==> closed {x | x IN s /\ f(x) = a}`,
6604 REPEAT STRIP_TAC THEN
6605 ASM_CASES_TAC `{x | x IN s /\ (f:real^M->real^N)(x) = a} = {}` THEN
6606 ASM_REWRITE_TAC[CLOSED_EMPTY] THEN ONCE_REWRITE_TAC[SET_RULE
6607 `{x | x IN s /\ f(x) = a} = {x | x IN s /\ f(x) IN {a}}`] THEN
6608 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE THEN
6609 ASM_REWRITE_TAC[CLOSED_SING] THEN ASM SET_TAC[]);;
6611 (* ------------------------------------------------------------------------- *)
6612 (* Theorems relating continuity and uniform continuity to closures. *)
6613 (* ------------------------------------------------------------------------- *)
6615 let CONTINUOUS_ON_CLOSURE = prove
6616 (`!f:real^M->real^N s.
6617 f continuous_on closure s <=>
6618 !x e. x IN closure s /\ &0 < e
6620 !y. y IN s /\ dist(y,x) < d ==> dist(f y,f x) < e`,
6621 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on] THEN
6622 EQ_TAC THENL [MESON_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET]; ALL_TAC] THEN
6623 DISCH_TAC THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
6624 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6625 FIRST_ASSUM(MP_TAC o SPECL [`x:real^M`; `e / &2`]) THEN
6626 ANTS_TAC THENL [ASM_REWRITE_TAC[REAL_HALF]; ALL_TAC] THEN
6627 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
6628 EXISTS_TAC `d / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN
6629 X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN
6630 FIRST_X_ASSUM(MP_TAC o SPECL [`y:real^M`; `e / &2`]) THEN
6631 ASM_REWRITE_TAC[REAL_HALF] THEN
6632 DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
6633 MP_TAC(ISPECL [`y:real^M`; `s:real^M->bool`] CLOSURE_APPROACHABLE) THEN
6634 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `min k (d / &2)`) THEN
6635 ASM_REWRITE_TAC[REAL_HALF; REAL_LT_MIN] THEN
6636 ASM_MESON_TAC[DIST_SYM; NORM_ARITH
6637 `dist(a,b) < e / &2 /\ dist(b,c) < e / &2 ==> dist(a,c) < e`]);;
6639 let CONTINUOUS_ON_CLOSURE_SEQUENTIALLY = prove
6640 (`!f:real^M->real^N s.
6641 f continuous_on closure s <=>
6642 !x a. a IN closure s /\ (!n. x n IN s) /\ (x --> a) sequentially
6643 ==> ((f o x) --> f a) sequentially`,
6644 REWRITE_TAC[CONTINUOUS_ON_CLOSURE] THEN
6645 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
6646 REWRITE_TAC[IMP_IMP; GSYM continuous_within] THEN
6647 REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY] THEN MESON_TAC[]);;
6649 let UNIFORMLY_CONTINUOUS_ON_CLOSURE = prove
6650 (`!f:real^M->real^N s.
6651 f uniformly_continuous_on s /\ f continuous_on closure s
6652 ==> f uniformly_continuous_on closure s`,
6654 REWRITE_TAC[uniformly_continuous_on] THEN STRIP_TAC THEN
6655 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6656 FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN
6657 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
6658 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
6659 EXISTS_TAC `d / &3` THEN CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
6660 MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^M`] THEN STRIP_TAC THEN
6661 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [continuous_on]) THEN
6662 DISCH_THEN(fun th ->
6663 MP_TAC(SPEC `y:real^M` th) THEN MP_TAC(SPEC `x:real^M` th)) THEN
6664 ASM_REWRITE_TAC[] THEN
6665 DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
6666 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
6667 DISCH_THEN(X_CHOOSE_THEN `d1:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
6668 MP_TAC(ISPECL [`x:real^M`; `s:real^M->bool`] CLOSURE_APPROACHABLE) THEN
6669 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `min d1 (d / &3)`) THEN
6670 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[REAL_LT_MIN]] THEN
6671 DISCH_THEN(X_CHOOSE_THEN `x':real^M` STRIP_ASSUME_TAC) THEN
6672 DISCH_THEN(MP_TAC o SPEC `x':real^M`) THEN
6673 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN DISCH_TAC THEN
6674 DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
6675 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
6676 DISCH_THEN(X_CHOOSE_THEN `d2:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
6677 MP_TAC(ISPECL [`y:real^M`; `s:real^M->bool`] CLOSURE_APPROACHABLE) THEN
6678 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `min d2 (d / &3)`) THEN
6679 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[REAL_LT_MIN]] THEN
6680 DISCH_THEN(X_CHOOSE_THEN `y':real^M` STRIP_ASSUME_TAC) THEN
6681 DISCH_THEN(MP_TAC o SPEC `y':real^M`) THEN
6682 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN DISCH_TAC THEN
6683 FIRST_X_ASSUM(MP_TAC o SPECL [`x':real^M`; `y':real^M`]) THEN
6684 ASM_MESON_TAC[DIST_SYM; NORM_ARITH
6685 `dist(y,x) < d / &3 /\ dist(x',x) < d / &3 /\ dist(y',y) < d / &3
6686 ==> dist(y',x') < d`]);;
6688 (* ------------------------------------------------------------------------- *)
6689 (* Continuity properties for square roots. We get other forms of this *)
6690 (* later (transcendentals.ml and realanalysis.ml) but it's nice to have *)
6691 (* them around earlier. *)
6692 (* ------------------------------------------------------------------------- *)
6694 let CONTINUOUS_AT_SQRT = prove
6695 (`!a s. &0 < drop a ==> (lift o sqrt o drop) continuous (at a)`,
6696 REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_at; o_THM; DIST_LIFT] THEN
6697 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6698 EXISTS_TAC `min (drop a) (e * sqrt(drop a))` THEN
6699 ASM_SIMP_TAC[REAL_LT_MIN; SQRT_POS_LT; REAL_LT_MUL; DIST_REAL] THEN
6700 X_GEN_TAC `b:real^1` THEN REWRITE_TAC[GSYM drop] THEN STRIP_TAC THEN
6701 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_ARITH
6702 `abs(b - a) < a ==> &0 < b`)) THEN
6704 `sqrt(drop b) - sqrt(drop a) =
6705 (drop b - drop a) / (sqrt(drop a) + sqrt(drop b))`
6707 [MATCH_MP_TAC(REAL_FIELD
6708 `sa pow 2 = a /\ sb pow 2 = b /\ &0 < sa /\ &0 < sb
6709 ==> sb - sa = (b - a) / (sa + sb)`) THEN
6710 ASM_SIMP_TAC[SQRT_POS_LT; SQRT_POW_2; REAL_LT_IMP_LE];
6711 ASM_SIMP_TAC[REAL_ABS_DIV; SQRT_POS_LT; REAL_LT_ADD; REAL_LT_LDIV_EQ;
6712 REAL_ARITH `&0 < x ==> abs x = x`] THEN
6713 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
6714 REAL_LTE_TRANS)) THEN
6715 ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LE_ADDR; SQRT_POS_LE;
6718 let CONTINUOUS_WITHIN_LIFT_SQRT = prove
6719 (`!a s. (!x. x IN s ==> &0 <= drop x)
6720 ==> (lift o sqrt o drop) continuous (at a within s)`,
6721 REPEAT STRIP_TAC THEN
6722 REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC
6723 (REAL_ARITH `drop a < &0 \/ drop a = &0 \/ &0 < drop a`)
6725 [MATCH_MP_TAC CONTINUOUS_WITHIN_SUBSET THEN
6726 EXISTS_TAC `{x | &0 <= drop x}` THEN
6727 ASM_SIMP_TAC[SUBSET; IN_ELIM_THM] THEN
6728 MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN
6729 ASM_REWRITE_TAC[IN_ELIM_THM; REAL_NOT_LE] THEN
6730 REWRITE_TAC[drop; REWRITE_RULE[real_ge] CLOSED_HALFSPACE_COMPONENT_GE];
6731 RULE_ASSUM_TAC(REWRITE_RULE[GSYM LIFT_EQ; LIFT_DROP; LIFT_NUM]) THEN
6732 ASM_REWRITE_TAC[continuous_within; o_THM; DROP_VEC; SQRT_0; LIFT_NUM] THEN
6733 REWRITE_TAC[DIST_0; NORM_LIFT; NORM_REAL; GSYM drop] THEN
6734 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6735 EXISTS_TAC `(e:real) pow 2` THEN ASM_SIMP_TAC[REAL_POW_LT] THEN
6736 X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN
6737 ASM_SIMP_TAC[real_abs; SQRT_POS_LE] THEN
6738 SUBGOAL_THEN `e = sqrt(e pow 2)` SUBST1_TAC THENL
6739 [ASM_SIMP_TAC[POW_2_SQRT; REAL_LT_IMP_LE];
6740 MATCH_MP_TAC SQRT_MONO_LT THEN ASM_SIMP_TAC[] THEN ASM_REAL_ARITH_TAC];
6741 MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN
6742 MATCH_MP_TAC CONTINUOUS_AT_SQRT THEN ASM_REWRITE_TAC[]]);;
6744 let CONTINUOUS_WITHIN_SQRT_COMPOSE = prove
6746 (\x. lift(f x)) continuous (at a within s) /\
6747 (&0 < f a \/ !x. x IN s ==> &0 <= f x)
6748 ==> (\x. lift(sqrt(f x))) continuous (at a within s)`,
6751 `(\x:real^N. lift(sqrt(f x))) = (lift o sqrt o drop) o (lift o f)`
6752 SUBST1_TAC THENL [REWRITE_TAC[o_DEF; LIFT_DROP]; ALL_TAC] THEN
6753 REPEAT STRIP_TAC THEN
6754 (MATCH_MP_TAC CONTINUOUS_WITHIN_COMPOSE THEN
6755 CONJ_TAC THENL [ASM_REWRITE_TAC[o_DEF]; ALL_TAC])
6757 [MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN
6758 MATCH_MP_TAC CONTINUOUS_AT_SQRT THEN ASM_REWRITE_TAC[o_DEF; LIFT_DROP];
6759 MATCH_MP_TAC CONTINUOUS_WITHIN_LIFT_SQRT THEN
6760 ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_DEF; LIFT_DROP]]);;
6762 let CONTINUOUS_AT_SQRT_COMPOSE = prove
6764 (\x. lift(f x)) continuous (at a) /\ (&0 < f a \/ !x. &0 <= f x)
6765 ==> (\x. lift(sqrt(f x))) continuous (at a)`,
6767 MP_TAC(ISPECL [`f:real^N->real`; `(:real^N)`; `a:real^N`]
6768 CONTINUOUS_WITHIN_SQRT_COMPOSE) THEN
6769 REWRITE_TAC[WITHIN_UNIV; IN_UNIV]);;
6771 let CONTINUOUS_ON_LIFT_SQRT = prove
6772 (`!s. (!x. x IN s ==> &0 <= drop x)
6773 ==> (lift o sqrt o drop) continuous_on s`,
6774 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_WITHIN_LIFT_SQRT]);;
6776 let CONTINUOUS_ON_LIFT_SQRT_COMPOSE = prove
6777 (`!f:real^N->real s.
6778 (lift o f) continuous_on s /\ (!x. x IN s ==> &0 <= f x)
6779 ==> (\x. lift(sqrt(f x))) continuous_on s`,
6780 REPEAT STRIP_TAC THEN
6782 `(\x:real^N. lift(sqrt(f x))) = (lift o sqrt o drop) o (lift o f)`
6784 [REWRITE_TAC[o_DEF; LIFT_DROP];
6785 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN
6786 MATCH_MP_TAC CONTINUOUS_ON_LIFT_SQRT THEN
6787 ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP]]);;
6789 (* ------------------------------------------------------------------------- *)
6790 (* Cauchy continuity, and the extension of functions to closures. *)
6791 (* ------------------------------------------------------------------------- *)
6793 let UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS = prove
6794 (`!f:real^M->real^N s.
6795 f uniformly_continuous_on s
6796 ==> (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))`,
6797 REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on; cauchy; o_DEF] THEN
6800 let CONTINUOUS_CLOSED_IMP_CAUCHY_CONTINUOUS = prove
6801 (`!f:real^M->real^N s.
6802 f continuous_on s /\ closed s
6803 ==> (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))`,
6804 REWRITE_TAC[GSYM COMPLETE_EQ_CLOSED; CONTINUOUS_ON_SEQUENTIALLY] THEN
6805 REWRITE_TAC[complete] THEN MESON_TAC[CONVERGENT_IMP_CAUCHY]);;
6807 let CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA = prove
6808 (`!f:real^M->real^N s.
6809 (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))
6810 ==> !a x. (!n. (x n) IN s) /\ (x --> a) sequentially
6811 ==> ?l. ((f o x) --> l) sequentially /\
6812 !y. (!n. (y n) IN s) /\ (y --> a) sequentially
6813 ==> ((f o y) --> l) sequentially`,
6814 REPEAT STRIP_TAC THEN
6815 FIRST_ASSUM(MP_TAC o SPEC `x:num->real^M`) THEN
6816 ANTS_TAC THENL [ASM_MESON_TAC[CONVERGENT_IMP_CAUCHY]; ALL_TAC] THEN
6817 REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN MATCH_MP_TAC MONO_EXISTS THEN
6818 X_GEN_TAC `l:real^N` THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
6819 X_GEN_TAC `y:num->real^M` THEN STRIP_TAC THEN
6820 FIRST_ASSUM(MP_TAC o SPEC `y:num->real^M`) THEN
6821 ANTS_TAC THENL [ASM_MESON_TAC[CONVERGENT_IMP_CAUCHY]; ALL_TAC] THEN
6822 REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN
6823 DISCH_THEN(X_CHOOSE_THEN `m:real^N` STRIP_ASSUME_TAC) THEN
6824 SUBGOAL_THEN `l:real^N = m` (fun th -> ASM_REWRITE_TAC[th]) THEN
6825 ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
6826 MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
6827 EXISTS_TAC `\n:num. (f:real^M->real^N)(x n) - f(y n)` THEN
6828 RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN
6829 ASM_SIMP_TAC[LIM_SUB; TRIVIAL_LIMIT_SEQUENTIALLY] THEN
6830 FIRST_X_ASSUM(MP_TAC o SPEC
6831 `\n. if EVEN n then x(n DIV 2):real^M else y(n DIV 2)`) THEN
6832 REWRITE_TAC[cauchy; o_THM; LIM_SEQUENTIALLY] THEN ANTS_TAC THENL
6833 [CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
6834 X_GEN_TAC `e:real` THEN DISCH_TAC THEN MAP_EVERY UNDISCH_TAC
6835 [`((y:num->real^M) --> a) sequentially`;
6836 `((x:num->real^M) --> a) sequentially`] THEN
6837 REPEAT(FIRST_X_ASSUM(K ALL_TAC o check (is_forall o concl))) THEN
6838 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
6839 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
6840 DISCH_THEN(X_CHOOSE_TAC `N1:num`) THEN
6841 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
6842 DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN
6843 EXISTS_TAC `2 * (N1 + N2)` THEN
6844 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN
6845 REPEAT(FIRST_X_ASSUM(fun th ->
6846 MP_TAC(SPEC `m DIV 2` th) THEN MP_TAC(SPEC `n DIV 2` th))) THEN
6847 REPEAT(ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_TAC]) THEN
6848 REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN
6849 REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_NOT_LE])) THEN
6850 CONV_TAC NORM_ARITH;
6851 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
6852 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
6853 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN
6854 X_GEN_TAC `n:num` THEN DISCH_TAC THEN
6855 FIRST_X_ASSUM(MP_TAC o SPECL [`2 * n`; `2 * n + 1`]) THEN
6856 ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
6857 REWRITE_TAC[EVEN_ADD; EVEN_MULT; ARITH_EVEN] THEN
6858 REWRITE_TAC[ARITH_RULE `(2 * n) DIV 2 = n /\ (2 * n + 1) DIV 2 = n`] THEN
6859 REWRITE_TAC[dist; VECTOR_SUB_RZERO]]);;
6861 let CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE = prove
6862 (`!f:real^M->real^N s.
6863 (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))
6864 ==> ?g. g continuous_on closure s /\ (!x. x IN s ==> g x = f x)`,
6865 REPEAT STRIP_TAC THEN
6868 a IN closure s ==> (!n. x n IN s) /\ (x --> a) sequentially`
6869 MP_TAC THENL [MESON_TAC[CLOSURE_SEQUENTIAL]; ALL_TAC] THEN
6870 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
6871 X_GEN_TAC `X:real^M->num->real^M` THEN DISCH_TAC THEN
6872 FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_CONTINUOUS_UNIQUENESS_LEMMA) THEN
6873 DISCH_THEN(MP_TAC o GEN `a:real^M` o
6874 SPECL [`a:real^M`; `(X:real^M->num->real^M) a`]) THEN
6875 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[]
6876 `(!a. P a ==> Q a) ==> ((!a. P a ==> R a) ==> p)
6877 ==> ((!a. Q a ==> R a) ==> p)`)) THEN
6878 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
6879 REWRITE_TAC[SKOLEM_THM] THEN
6880 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^M->real^N` THEN
6882 MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
6883 [X_GEN_TAC `a:real^M` THEN DISCH_TAC THEN
6884 FIRST_X_ASSUM(MP_TAC o SPEC `a:real^M`) THEN
6885 ASM_SIMP_TAC[REWRITE_RULE[SUBSET] CLOSURE_SUBSET] THEN
6886 DISCH_THEN(MP_TAC o SPEC `(\n. a):num->real^M` o CONJUNCT2) THEN
6887 ASM_SIMP_TAC[LIM_CONST_EQ; o_DEF; TRIVIAL_LIMIT_SEQUENTIALLY];
6889 ASM_SIMP_TAC[CONTINUOUS_ON_CLOSURE_SEQUENTIALLY] THEN
6890 MAP_EVERY X_GEN_TAC [`x:num->real^M`; `a:real^M`] THEN STRIP_TAC THEN
6891 MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
6892 EXISTS_TAC `(f:real^M->real^N) o (x:num->real^M)` THEN ASM_SIMP_TAC[] THEN
6893 MATCH_MP_TAC ALWAYS_EVENTUALLY THEN ASM_SIMP_TAC[o_THM]);;
6895 let UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE = prove
6896 (`!f:real^M->real^N s.
6897 f uniformly_continuous_on s
6898 ==> ?g. g uniformly_continuous_on closure s /\ (!x. x IN s ==> g x = f x) /\
6899 !h. h continuous_on closure s /\ (!x. x IN s ==> h x = f x)
6900 ==> !x. x IN closure s ==> h x = g x`,
6901 REPEAT STRIP_TAC THEN
6902 FIRST_ASSUM(MP_TAC o MATCH_MP CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE o
6903 MATCH_MP UNIFORMLY_CONTINUOUS_IMP_CAUCHY_CONTINUOUS) THEN
6904 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^M->real^N` THEN
6905 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
6906 [ASM_MESON_TAC[UNIFORMLY_CONTINUOUS_ON_CLOSURE; UNIFORMLY_CONTINUOUS_ON_EQ];
6907 ASM_MESON_TAC[CONTINUOUS_AGREE_ON_CLOSURE]]);;
6909 let CAUCHY_CONTINUOUS_IMP_CONTINUOUS = prove
6910 (`!f:real^M->real^N s.
6911 (!x. cauchy x /\ (!n. (x n) IN s) ==> cauchy(f o x))
6912 ==> f continuous_on s`,
6913 REPEAT STRIP_TAC THEN
6914 FIRST_ASSUM(CHOOSE_TAC o MATCH_MP CAUCHY_CONTINUOUS_EXTENDS_TO_CLOSURE) THEN
6915 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; CLOSURE_SUBSET; CONTINUOUS_ON_EQ]);;
6917 (* ------------------------------------------------------------------------- *)
6918 (* Linear functions are (uniformly) continuous on any set. *)
6919 (* ------------------------------------------------------------------------- *)
6921 let LINEAR_LIM_0 = prove
6922 (`!f. linear f ==> (f --> vec 0) (at (vec 0))`,
6923 REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_AT] THEN
6924 FIRST_X_ASSUM(MP_TAC o MATCH_MP LINEAR_BOUNDED_POS) THEN
6925 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
6926 X_GEN_TAC `e:real` THEN DISCH_TAC THEN EXISTS_TAC `e / B` THEN
6927 ASM_SIMP_TAC[REAL_LT_DIV] THEN REWRITE_TAC[dist; VECTOR_SUB_RZERO] THEN
6928 ASM_MESON_TAC[REAL_MUL_SYM; REAL_LET_TRANS; REAL_LT_RDIV_EQ]);;
6930 let LINEAR_CONTINUOUS_AT = prove
6931 (`!f:real^M->real^N a. linear f ==> f continuous (at a)`,
6932 REPEAT STRIP_TAC THEN
6933 MP_TAC(ISPEC `\x. (f:real^M->real^N) (a + x) - f(a)` LINEAR_LIM_0) THEN
6935 [POP_ASSUM MP_TAC THEN SIMP_TAC[linear] THEN
6936 REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC;
6938 REWRITE_TAC[GSYM LIM_NULL; CONTINUOUS_AT] THEN
6939 GEN_REWRITE_TAC RAND_CONV [LIM_AT_ZERO] THEN SIMP_TAC[]);;
6941 let LINEAR_CONTINUOUS_WITHIN = prove
6942 (`!f:real^M->real^N s x. linear f ==> f continuous (at x within s)`,
6943 SIMP_TAC[CONTINUOUS_AT_WITHIN; LINEAR_CONTINUOUS_AT]);;
6945 let LINEAR_CONTINUOUS_ON = prove
6946 (`!f:real^M->real^N s. linear f ==> f continuous_on s`,
6947 MESON_TAC[LINEAR_CONTINUOUS_AT; CONTINUOUS_AT_IMP_CONTINUOUS_ON]);;
6949 let LINEAR_CONTINUOUS_COMPOSE = prove
6950 (`!net f:A->real^N g:real^N->real^P.
6951 f continuous net /\ linear g ==> (\x. g(f x)) continuous net`,
6952 REWRITE_TAC[continuous; LIM_LINEAR]);;
6954 let LINEAR_CONTINUOUS_ON_COMPOSE = prove
6955 (`!f:real^M->real^N g:real^N->real^P s.
6956 f continuous_on s /\ linear g ==> (\x. g(f x)) continuous_on s`,
6957 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
6958 LINEAR_CONTINUOUS_COMPOSE]);;
6960 let CONTINUOUS_LIFT_COMPONENT_COMPOSE = prove
6961 (`!net f:A->real^N i. f continuous net ==> (\x. lift(f x$i)) continuous net`,
6963 SUBGOAL_THEN `linear(\x:real^N. lift (x$i))` MP_TAC THENL
6964 [REWRITE_TAC[LINEAR_LIFT_COMPONENT]; REWRITE_TAC[GSYM IMP_CONJ_ALT]] THEN
6965 REWRITE_TAC[LINEAR_CONTINUOUS_COMPOSE]);;
6967 let CONTINUOUS_ON_LIFT_COMPONENT_COMPOSE = prove
6968 (`!f:real^M->real^N s.
6970 ==> (\x. lift (f x$i)) continuous_on s`,
6971 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
6972 CONTINUOUS_LIFT_COMPONENT_COMPOSE]);;
6974 (* ------------------------------------------------------------------------- *)
6975 (* Also bilinear functions, in composition form. *)
6976 (* ------------------------------------------------------------------------- *)
6978 let BILINEAR_CONTINUOUS_COMPOSE = prove
6979 (`!net f:A->real^M g:A->real^N h:real^M->real^N->real^P.
6980 f continuous net /\ g continuous net /\ bilinear h
6981 ==> (\x. h (f x) (g x)) continuous net`,
6982 REWRITE_TAC[continuous; LIM_BILINEAR]);;
6984 let BILINEAR_CONTINUOUS_ON_COMPOSE = prove
6985 (`!f g h s. f continuous_on s /\ g continuous_on s /\ bilinear h
6986 ==> (\x. h (f x) (g x)) continuous_on s`,
6987 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
6988 BILINEAR_CONTINUOUS_COMPOSE]);;
6990 let BILINEAR_DOT = prove
6991 (`bilinear (\x y:real^N. lift(x dot y))`,
6992 REWRITE_TAC[bilinear; linear; DOT_LADD; DOT_RADD; DOT_LMUL; DOT_RMUL] THEN
6993 REWRITE_TAC[LIFT_ADD; LIFT_CMUL]);;
6995 let CONTINUOUS_LIFT_DOT2 = prove
6996 (`!net f g:A->real^N.
6997 f continuous net /\ g continuous net
6998 ==> (\x. lift(f x dot g x)) continuous net`,
6999 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE
7000 [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`]
7001 BILINEAR_CONTINUOUS_COMPOSE) BILINEAR_DOT)) THEN REWRITE_TAC[]);;
7003 let CONTINUOUS_ON_LIFT_DOT2 = prove
7004 (`!f:real^M->real^N g s.
7005 f continuous_on s /\ g continuous_on s
7006 ==> (\x. lift(f x dot g x)) continuous_on s`,
7007 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (MATCH_MP (REWRITE_RULE
7008 [TAUT `p /\ q /\ r ==> s <=> r ==> p /\ q ==> s`]
7009 BILINEAR_CONTINUOUS_ON_COMPOSE) BILINEAR_DOT)) THEN REWRITE_TAC[]);;
7011 (* ------------------------------------------------------------------------- *)
7012 (* Occasionally useful invariance properties. *)
7013 (* ------------------------------------------------------------------------- *)
7015 let CONTINUOUS_AT_COMPOSE_EQ = prove
7016 (`!f:real^M->real^N g:real^M->real^M h:real^M->real^M.
7017 g continuous at x /\ h continuous at (g x) /\
7018 (!y. g(h y) = y) /\ h(g x) = x
7019 ==> (f continuous at (g x) <=> (\x. f(g x)) continuous at x)`,
7020 REPEAT STRIP_TAC THEN EQ_TAC THEN
7021 ASM_SIMP_TAC[REWRITE_RULE[o_DEF] CONTINUOUS_AT_COMPOSE] THEN
7024 `((f:real^M->real^N) o (g:real^M->real^M) o (h:real^M->real^M))
7025 continuous at (g(x:real^M))`
7027 [REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE THEN
7028 ASM_REWRITE_TAC[o_DEF];
7030 ASM_REWRITE_TAC[o_DEF; ETA_AX]]);;
7032 let CONTINUOUS_AT_TRANSLATION = prove
7033 (`!a z f:real^M->real^N.
7034 f continuous at (a + z) <=> (\x. f(a + x)) continuous at z`,
7035 REPEAT GEN_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_COMPOSE_EQ THEN
7036 EXISTS_TAC `\x:real^M. x - a` THEN
7037 SIMP_TAC[CONTINUOUS_ADD; CONTINUOUS_SUB;
7038 CONTINUOUS_AT_ID; CONTINUOUS_CONST] THEN
7041 add_translation_invariants [CONTINUOUS_AT_TRANSLATION];;
7043 let CONTINUOUS_AT_LINEAR_IMAGE = prove
7044 (`!h:real^M->real^M z f:real^M->real^N.
7045 linear h /\ (!x. norm(h x) = norm x)
7046 ==> (f continuous at (h z) <=> (\x. f(h x)) continuous at z)`,
7047 REPEAT GEN_TAC THEN DISCH_TAC THEN
7048 FIRST_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I
7049 [GSYM ORTHOGONAL_TRANSFORMATION]) THEN
7050 FIRST_ASSUM(X_CHOOSE_TAC `g:real^M->real^M` o MATCH_MP
7051 ORTHOGONAL_TRANSFORMATION_INVERSE) THEN
7052 MATCH_MP_TAC CONTINUOUS_AT_COMPOSE_EQ THEN
7053 EXISTS_TAC `g:real^M->real^M` THEN
7054 RULE_ASSUM_TAC(REWRITE_RULE[ORTHOGONAL_TRANSFORMATION]) THEN
7055 ASM_SIMP_TAC[LINEAR_CONTINUOUS_AT]);;
7057 add_linear_invariants [CONTINUOUS_AT_LINEAR_IMAGE];;
7059 (* ------------------------------------------------------------------------- *)
7060 (* Interior of an injective image. *)
7061 (* ------------------------------------------------------------------------- *)
7063 let INTERIOR_IMAGE_SUBSET = prove
7064 (`!f:real^M->real^N s.
7065 (!x. f continuous at x) /\ (!x y. f x = f y ==> x = y)
7066 ==> interior(IMAGE f s) SUBSET IMAGE f (interior s)`,
7067 REPEAT STRIP_TAC THEN REWRITE_TAC[SUBSET] THEN
7068 REWRITE_TAC[interior; IN_ELIM_THM] THEN
7069 X_GEN_TAC `y:real^N` THEN
7070 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
7071 REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN
7072 SUBGOAL_THEN `y IN IMAGE (f:real^M->real^N) s` MP_TAC THENL
7073 [ASM SET_TAC[]; ALL_TAC] THEN
7074 REWRITE_TAC[IN_IMAGE] THEN
7075 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN
7076 ASM_REWRITE_TAC[IN_ELIM_THM] THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN
7077 EXISTS_TAC `{x | (f:real^M->real^N)(x) IN t}` THEN
7078 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN CONJ_TAC THENL
7079 [MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE_UNIV THEN ASM_MESON_TAC[];
7082 (* ------------------------------------------------------------------------- *)
7083 (* Making a continuous function avoid some value in a neighbourhood. *)
7084 (* ------------------------------------------------------------------------- *)
7086 let CONTINUOUS_WITHIN_AVOID = prove
7087 (`!f:real^M->real^N x s a.
7088 f continuous (at x within s) /\ x IN s /\ ~(f x = a)
7089 ==> ?e. &0 < e /\ !y. y IN s /\ dist(x,y) < e ==> ~(f y = a)`,
7090 REPEAT STRIP_TAC THEN
7091 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [continuous_within]) THEN
7092 DISCH_THEN(MP_TAC o SPEC `norm((f:real^M->real^N) x - a)`) THEN
7093 ASM_REWRITE_TAC[NORM_POS_LT; VECTOR_SUB_EQ] THEN
7094 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN MATCH_MP_TAC MONO_AND THEN
7095 REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN
7096 GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN SIMP_TAC[] THEN NORM_ARITH_TAC);;
7098 let CONTINUOUS_AT_AVOID = prove
7099 (`!f:real^M->real^N x a.
7100 f continuous (at x) /\ ~(f x = a)
7101 ==> ?e. &0 < e /\ !y. dist(x,y) < e ==> ~(f y = a)`,
7102 MP_TAC CONTINUOUS_WITHIN_AVOID THEN
7103 REPLICATE_TAC 2 (MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
7104 DISCH_THEN(MP_TAC o SPEC `(:real^M)`) THEN
7105 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
7106 REWRITE_TAC[WITHIN_UNIV; IN_UNIV]);;
7108 let CONTINUOUS_ON_AVOID = prove
7109 (`!f:real^M->real^N x s a.
7110 f continuous_on s /\ x IN s /\ ~(f x = a)
7111 ==> ?e. &0 < e /\ !y. y IN s /\ dist(x,y) < e ==> ~(f y = a)`,
7112 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
7113 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_WITHIN_AVOID THEN
7116 let CONTINUOUS_ON_OPEN_AVOID = prove
7117 (`!f:real^M->real^N x s a.
7118 f continuous_on s /\ open s /\ x IN s /\ ~(f x = a)
7119 ==> ?e. &0 < e /\ !y. dist(x,y) < e ==> ~(f y = a)`,
7120 REPEAT GEN_TAC THEN ASM_CASES_TAC `open(s:real^M->bool)` THEN
7121 ASM_SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT] THEN
7122 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_AVOID THEN
7125 (* ------------------------------------------------------------------------- *)
7126 (* Proving a function is constant by proving open-ness of level set. *)
7127 (* ------------------------------------------------------------------------- *)
7129 let CONTINUOUS_LEVELSET_OPEN_IN_CASES = prove
7130 (`!f:real^M->real^N s a.
7132 f continuous_on s /\
7133 open_in (subtopology euclidean s) {x | x IN s /\ f x = a}
7134 ==> (!x. x IN s ==> ~(f x = a)) \/ (!x. x IN s ==> f x = a)`,
7135 REWRITE_TAC[SET_RULE `(!x. x IN s ==> ~(f x = a)) <=>
7136 {x | x IN s /\ f x = a} = {}`;
7137 SET_RULE `(!x. x IN s ==> f x = a) <=>
7138 {x | x IN s /\ f x = a} = s`] THEN
7139 REWRITE_TAC[CONNECTED_CLOPEN] THEN REPEAT STRIP_TAC THEN
7140 FIRST_X_ASSUM MATCH_MP_TAC THEN
7141 ASM_SIMP_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_CONSTANT]);;
7143 let CONTINUOUS_LEVELSET_OPEN_IN = prove
7144 (`!f:real^M->real^N s a.
7146 f continuous_on s /\
7147 open_in (subtopology euclidean s) {x | x IN s /\ f x = a} /\
7148 (?x. x IN s /\ f x = a)
7149 ==> (!x. x IN s ==> f x = a)`,
7150 MESON_TAC[CONTINUOUS_LEVELSET_OPEN_IN_CASES]);;
7152 let CONTINUOUS_LEVELSET_OPEN = prove
7153 (`!f:real^M->real^N s a.
7155 f continuous_on s /\
7156 open {x | x IN s /\ f x = a} /\
7157 (?x. x IN s /\ f x = a)
7158 ==> (!x. x IN s ==> f x = a)`,
7159 REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
7160 MATCH_MP_TAC CONTINUOUS_LEVELSET_OPEN_IN THEN
7161 ASM_REWRITE_TAC[OPEN_IN_OPEN] THEN
7162 EXISTS_TAC `{x | x IN s /\ (f:real^M->real^N) x = a}` THEN
7163 ASM_REWRITE_TAC[] THEN SET_TAC[]);;
7165 (* ------------------------------------------------------------------------- *)
7166 (* Some arithmetical combinations (more to prove). *)
7167 (* ------------------------------------------------------------------------- *)
7169 let OPEN_SCALING = prove
7170 (`!s:real^N->bool c. ~(c = &0) /\ open s ==> open(IMAGE (\x. c % x) s)`,
7171 REPEAT GEN_TAC THEN REWRITE_TAC[open_def; FORALL_IN_IMAGE] THEN
7172 STRIP_TAC THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7173 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
7174 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
7175 EXISTS_TAC `e * abs(c)` THEN ASM_SIMP_TAC[REAL_LT_MUL; GSYM REAL_ABS_NZ] THEN
7176 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_IMAGE] THEN
7177 EXISTS_TAC `inv(c) % y:real^N` THEN
7178 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; VECTOR_MUL_LID] THEN
7179 FIRST_X_ASSUM MATCH_MP_TAC THEN
7180 SUBGOAL_THEN `x = inv(c) % c % x:real^N` SUBST1_TAC THENL
7181 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID];
7182 REWRITE_TAC[dist; GSYM VECTOR_SUB_LDISTRIB; NORM_MUL] THEN
7183 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[REAL_ABS_INV] THEN
7184 ASM_SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ; GSYM REAL_ABS_NZ] THEN
7185 ASM_REWRITE_TAC[GSYM dist]]);;
7187 let OPEN_NEGATIONS = prove
7188 (`!s:real^N->bool. open s ==> open (IMAGE (--) s)`,
7189 SUBGOAL_THEN `(--) = \x:real^N. --(&1) % x`
7190 (fun th -> SIMP_TAC[th; OPEN_SCALING; REAL_ARITH `~(--(&1) = &0)`]) THEN
7191 REWRITE_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC);;
7193 let OPEN_TRANSLATION = prove
7194 (`!s a:real^N. open s ==> open(IMAGE (\x. a + x) s)`,
7195 REPEAT STRIP_TAC THEN
7196 MP_TAC(ISPECL [`\x:real^N. x - a`; `s:real^N->bool`]
7197 CONTINUOUS_OPEN_PREIMAGE_UNIV) THEN
7198 ASM_SIMP_TAC[CONTINUOUS_SUB; CONTINUOUS_AT_ID; CONTINUOUS_CONST] THEN
7199 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
7200 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; IN_UNIV] THEN
7201 ASM_MESON_TAC[VECTOR_ARITH `(a + x) - a = x:real^N`;
7202 VECTOR_ARITH `a + (x - a) = x:real^N`]);;
7204 let OPEN_TRANSLATION_EQ = prove
7205 (`!a s. open (IMAGE (\x:real^N. a + x) s) <=> open s`,
7206 REWRITE_TAC[open_def] THEN GEOM_TRANSLATE_TAC[]);;
7208 add_translation_invariants [OPEN_TRANSLATION_EQ];;
7210 let OPEN_AFFINITY = prove
7212 open s /\ ~(c = &0) ==> open (IMAGE (\x. a + c % x) s)`,
7213 REPEAT STRIP_TAC THEN
7214 SUBGOAL_THEN `(\x:real^N. a + c % x) = (\x. a + x) o (\x. c % x)`
7215 SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
7216 ASM_SIMP_TAC[IMAGE_o; OPEN_TRANSLATION; OPEN_SCALING]);;
7218 let INTERIOR_TRANSLATION = prove
7220 interior (IMAGE (\x. a + x) s) = IMAGE (\x. a + x) (interior s)`,
7221 REWRITE_TAC[interior] THEN GEOM_TRANSLATE_TAC[]);;
7223 add_translation_invariants [INTERIOR_TRANSLATION];;
7225 let OPEN_SUMS = prove
7226 (`!s t:real^N->bool.
7227 open s \/ open t ==> open {x + y | x IN s /\ y IN t}`,
7228 REPEAT GEN_TAC THEN REWRITE_TAC[open_def] THEN STRIP_TAC THEN
7229 REWRITE_TAC[FORALL_IN_GSPEC] THEN
7230 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THENL
7231 [FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`);
7232 FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`)] THEN
7233 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN
7234 X_GEN_TAC `e:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
7235 X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
7236 ASM_MESON_TAC[VECTOR_ADD_SYM; VECTOR_ARITH `(z - y) + y:real^N = z`;
7237 NORM_ARITH `dist(z:real^N,x + y) < e ==> dist(z - y,x) < e`]);;
7239 (* ------------------------------------------------------------------------- *)
7240 (* Preservation of compactness and connectedness under continuous function. *)
7241 (* ------------------------------------------------------------------------- *)
7243 let COMPACT_CONTINUOUS_IMAGE = prove
7244 (`!f:real^M->real^N s.
7245 f continuous_on s /\ compact s ==> compact(IMAGE f s)`,
7246 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on; compact] THEN
7247 STRIP_TAC THEN X_GEN_TAC `y:num->real^N` THEN
7248 REWRITE_TAC[IN_IMAGE; SKOLEM_THM; FORALL_AND_THM] THEN
7249 DISCH_THEN(X_CHOOSE_THEN `x:num->real^M` STRIP_ASSUME_TAC) THEN
7250 FIRST_X_ASSUM(MP_TAC o SPEC `x:num->real^M`) THEN ASM_REWRITE_TAC[] THEN
7251 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
7252 X_GEN_TAC `r:num->num` THEN
7253 DISCH_THEN(X_CHOOSE_THEN `l:real^M` STRIP_ASSUME_TAC) THEN
7254 EXISTS_TAC `(f:real^M->real^N) l` THEN ASM_REWRITE_TAC[] THEN
7255 CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
7256 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
7257 FIRST_X_ASSUM(MP_TAC o SPEC `l:real^M`) THEN
7258 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
7259 DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
7260 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
7261 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
7262 DISCH_THEN(MP_TAC o SPEC `d:real`) THEN ASM_REWRITE_TAC[o_THM] THEN
7265 let COMPACT_CONTINUOUS_IMAGE_EQ = prove
7266 (`!f:real^M->real^N s.
7267 (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y)
7268 ==> (f continuous_on s <=>
7269 !t. compact t /\ t SUBSET s ==> compact(IMAGE f t))`,
7270 REPEAT STRIP_TAC THEN EQ_TAC THENL
7271 [MESON_TAC[COMPACT_CONTINUOUS_IMAGE; CONTINUOUS_ON_SUBSET]; DISCH_TAC] THEN
7272 FIRST_X_ASSUM(X_CHOOSE_TAC `g:real^N->real^M` o
7273 GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN
7274 REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN
7275 X_GEN_TAC `u:real^N->bool` THEN DISCH_TAC THEN
7276 MP_TAC(ISPECL [`g:real^N->real^M`; `IMAGE (f:real^M->real^N) s`;
7277 `s:real^M->bool`] PROPER_MAP) THEN
7278 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7279 MATCH_MP_TAC(TAUT `(q ==> s) /\ p ==> (p <=> q /\ r) ==> s`) THEN
7280 REPEAT STRIP_TAC THENL
7282 `{x | x IN s /\ (f:real^M->real^N) x IN u} = IMAGE g u`
7283 (fun th -> ASM_MESON_TAC[th]);
7285 `{x | x IN IMAGE f s /\ (g:real^N->real^M) x IN k} = IMAGE f k`
7286 (fun th -> ASM_SIMP_TAC[th])] THEN
7287 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN ASM SET_TAC[]);;
7289 let COMPACT_LINEAR_IMAGE = prove
7290 (`!f:real^M->real^N s. compact s /\ linear f ==> compact(IMAGE f s)`,
7291 SIMP_TAC[LINEAR_CONTINUOUS_ON; COMPACT_CONTINUOUS_IMAGE]);;
7293 let COMPACT_LINEAR_IMAGE_EQ = prove
7294 (`!f s. linear f /\ (!x y. f x = f y ==> x = y)
7295 ==> (compact (IMAGE f s) <=> compact s)`,
7296 MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE COMPACT_LINEAR_IMAGE));;
7298 add_linear_invariants [COMPACT_LINEAR_IMAGE_EQ];;
7300 let CONNECTED_CONTINUOUS_IMAGE = prove
7301 (`!f:real^M->real^N s.
7302 f continuous_on s /\ connected s ==> connected(IMAGE f s)`,
7303 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_ON_OPEN] THEN
7304 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
7305 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
7306 REWRITE_TAC[CONNECTED_CLOPEN; NOT_FORALL_THM; NOT_IMP; DE_MORGAN_THM] THEN
7307 REWRITE_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
7308 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
7309 FIRST_X_ASSUM(fun th -> MP_TAC(SPEC `t:real^N->bool` th) THEN
7310 MP_TAC(SPEC `IMAGE (f:real^M->real^N) s DIFF t` th)) THEN
7311 ASM_REWRITE_TAC[] THEN
7312 SUBGOAL_THEN `{x | x IN s /\ (f:real^M->real^N) x IN IMAGE f s DIFF t} =
7313 s DIFF {x | x IN s /\ f x IN t}`
7315 [UNDISCH_TAC `t SUBSET IMAGE (f:real^M->real^N) s` THEN
7316 REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DIFF; IN_ELIM_THM; SUBSET] THEN
7318 REPEAT STRIP_TAC THEN
7319 EXISTS_TAC `{x | x IN s /\ (f:real^M->real^N) x IN t}` THEN
7320 ASM_REWRITE_TAC[] THEN POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
7321 REWRITE_TAC[IN_IMAGE; SUBSET; IN_ELIM_THM; NOT_IN_EMPTY; EXTENSION] THEN
7324 let CONNECTED_TRANSLATION = prove
7325 (`!a s. connected s ==> connected (IMAGE (\x:real^N. a + x) s)`,
7326 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN
7327 ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_ID; CONTINUOUS_ON_CONST]);;
7329 let CONNECTED_TRANSLATION_EQ = prove
7330 (`!a s. connected (IMAGE (\x:real^N. a + x) s) <=> connected s`,
7331 REWRITE_TAC[connected] THEN GEOM_TRANSLATE_TAC[]);;
7333 add_translation_invariants [CONNECTED_TRANSLATION_EQ];;
7335 let CONNECTED_LINEAR_IMAGE = prove
7336 (`!f:real^M->real^N s. connected s /\ linear f ==> connected(IMAGE f s)`,
7337 SIMP_TAC[LINEAR_CONTINUOUS_ON; CONNECTED_CONTINUOUS_IMAGE]);;
7339 let CONNECTED_LINEAR_IMAGE_EQ = prove
7340 (`!f s. linear f /\ (!x y. f x = f y ==> x = y)
7341 ==> (connected (IMAGE f s) <=> connected s)`,
7342 MATCH_ACCEPT_TAC(LINEAR_INVARIANT_RULE CONNECTED_LINEAR_IMAGE));;
7344 add_linear_invariants [CONNECTED_LINEAR_IMAGE_EQ];;
7346 let BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE = prove
7347 (`!f:real^M->real^N s.
7348 f uniformly_continuous_on s /\ bounded s ==> bounded(IMAGE f s)`,
7349 REPEAT STRIP_TAC THEN FIRST_ASSUM
7350 (MP_TAC o MATCH_MP UNIFORMLY_CONTINUOUS_EXTENDS_TO_CLOSURE) THEN
7351 DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN
7352 MATCH_MP_TAC BOUNDED_SUBSET THEN
7353 EXISTS_TAC `IMAGE (g:real^M->real^N) (closure s)` THEN CONJ_TAC THENL
7354 [ASM_MESON_TAC[COMPACT_CLOSURE; UNIFORMLY_CONTINUOUS_IMP_CONTINUOUS;
7355 COMPACT_IMP_BOUNDED; COMPACT_CONTINUOUS_IMAGE];
7356 MP_TAC(ISPEC `s:real^M->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]]);;
7358 (* ------------------------------------------------------------------------- *)
7359 (* Connected components, considered as a "connectedness" relation or a set. *)
7360 (* ------------------------------------------------------------------------- *)
7362 let connected_component = new_definition
7363 `connected_component s x y <=>
7364 ?t. connected t /\ t SUBSET s /\ x IN t /\ y IN t`;;
7366 let CONNECTED_COMPONENT_IN = prove
7367 (`!s x y. connected_component s x y ==> x IN s /\ y IN s`,
7368 REWRITE_TAC[connected_component] THEN SET_TAC[]);;
7370 let CONNECTED_COMPONENT_REFL = prove
7371 (`!s x:real^N. x IN s ==> connected_component s x x`,
7372 REWRITE_TAC[connected_component] THEN REPEAT STRIP_TAC THEN
7373 EXISTS_TAC `{x:real^N}` THEN REWRITE_TAC[CONNECTED_SING] THEN
7376 let CONNECTED_COMPONENT_REFL_EQ = prove
7377 (`!s x:real^N. connected_component s x x <=> x IN s`,
7378 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[CONNECTED_COMPONENT_REFL] THEN
7379 REWRITE_TAC[connected_component] THEN SET_TAC[]);;
7381 let CONNECTED_COMPONENT_SYM = prove
7382 (`!s x y:real^N. connected_component s x y ==> connected_component s y x`,
7383 REWRITE_TAC[connected_component] THEN MESON_TAC[]);;
7385 let CONNECTED_COMPONENT_TRANS = prove
7387 connected_component s x y /\ connected_component s y z
7388 ==> connected_component s x z`,
7389 REPEAT GEN_TAC THEN REWRITE_TAC[connected_component] THEN
7390 DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `t:real^N->bool`)
7391 (X_CHOOSE_TAC `u:real^N->bool`)) THEN
7392 EXISTS_TAC `t UNION u:real^N->bool` THEN
7393 ASM_REWRITE_TAC[IN_UNION; UNION_SUBSET] THEN
7394 MATCH_MP_TAC CONNECTED_UNION THEN ASM SET_TAC[]);;
7396 let CONNECTED_COMPONENT_OF_SUBSET = prove
7397 (`!s t x. s SUBSET t /\ connected_component s x y
7398 ==> connected_component t x y`,
7399 REWRITE_TAC[connected_component] THEN SET_TAC[]);;
7401 let CONNECTED_COMPONENT_SET = prove
7402 (`!s x. connected_component s x =
7403 { y | ?t. connected t /\ t SUBSET s /\ x IN t /\ y IN t}`,
7404 REWRITE_TAC[IN_ELIM_THM; EXTENSION] THEN
7405 REWRITE_TAC[IN; connected_component] THEN MESON_TAC[]);;
7407 let CONNECTED_COMPONENT_UNIONS = prove
7408 (`!s x. connected_component s x =
7409 UNIONS {t | connected t /\ x IN t /\ t SUBSET s}`,
7410 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);;
7412 let CONNECTED_COMPONENT_SUBSET = prove
7413 (`!s x. (connected_component s x) SUBSET s`,
7414 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);;
7416 let CONNECTED_CONNECTED_COMPONENT_SET = prove
7417 (`!s. connected s <=> !x:real^N. x IN s ==> connected_component s x = s`,
7418 GEN_TAC THEN REWRITE_TAC[CONNECTED_COMPONENT_UNIONS] THEN EQ_TAC THENL
7419 [SET_TAC[]; ALL_TAC] THEN
7420 ASM_CASES_TAC `s:real^N->bool = {}` THEN
7421 ASM_REWRITE_TAC[CONNECTED_EMPTY] THEN
7422 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
7423 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
7424 DISCH_THEN(MP_TAC o SPEC `a:real^N`) THEN ASM_REWRITE_TAC[] THEN
7425 DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC CONNECTED_UNIONS THEN
7428 let CONNECTED_COMPONENT_EQ_SELF = prove
7429 (`!s x. connected s /\ x IN s ==> connected_component s x = s`,
7430 MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET]);;
7432 let CONNECTED_IFF_CONNECTED_COMPONENT = prove
7433 (`!s. connected s <=>
7434 !x y. x IN s /\ y IN s ==> connected_component s x y`,
7435 REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT_SET] THEN
7436 REWRITE_TAC[EXTENSION] THEN MESON_TAC[IN; CONNECTED_COMPONENT_IN]);;
7438 let CONNECTED_COMPONENT_MAXIMAL = prove
7440 x IN t /\ connected t /\ t SUBSET s
7441 ==> t SUBSET (connected_component s x)`,
7442 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);;
7444 let CONNECTED_COMPONENT_MONO = prove
7445 (`!s t x. s SUBSET t
7446 ==> (connected_component s x) SUBSET (connected_component t x)`,
7447 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]);;
7449 let CONNECTED_CONNECTED_COMPONENT = prove
7450 (`!s x. connected(connected_component s x)`,
7451 REWRITE_TAC[CONNECTED_COMPONENT_UNIONS] THEN
7452 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_UNIONS THEN SET_TAC[]);;
7454 let CONNECTED_COMPONENT_EQ_EMPTY = prove
7455 (`!s x:real^N. connected_component s x = {} <=> ~(x IN s)`,
7456 REPEAT GEN_TAC THEN EQ_TAC THENL
7457 [REWRITE_TAC[EXTENSION; NOT_IN_EMPTY] THEN
7458 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
7459 REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ];
7460 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SET_TAC[]]);;
7462 let CONNECTED_COMPONENT_EMPTY = prove
7463 (`!x. connected_component {} x = {}`,
7464 REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY; NOT_IN_EMPTY]);;
7466 let CONNECTED_COMPONENT_EQ = prove
7467 (`!s x y. y IN connected_component s x
7468 ==> (connected_component s y = connected_component s x)`,
7469 REWRITE_TAC[EXTENSION; IN] THEN
7470 MESON_TAC[CONNECTED_COMPONENT_SYM; CONNECTED_COMPONENT_TRANS]);;
7472 let CLOSED_CONNECTED_COMPONENT = prove
7473 (`!s x:real^N. closed s ==> closed(connected_component s x)`,
7474 REPEAT STRIP_TAC THEN
7475 ASM_CASES_TAC `(x:real^N) IN s` THENL
7476 [ALL_TAC; ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY; CLOSED_EMPTY]] THEN
7477 REWRITE_TAC[GSYM CLOSURE_EQ] THEN
7478 MATCH_MP_TAC SUBSET_ANTISYM THEN REWRITE_TAC[CLOSURE_SUBSET] THEN
7479 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
7480 SIMP_TAC[CONNECTED_CLOSURE; CONNECTED_CONNECTED_COMPONENT] THEN
7482 [MATCH_MP_TAC(REWRITE_RULE[SUBSET] CLOSURE_SUBSET) THEN
7483 ASM_REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ];
7484 MATCH_MP_TAC CLOSURE_MINIMAL THEN
7485 ASM_REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]]);;
7487 let CONNECTED_COMPONENT_DISJOINT = prove
7488 (`!s a b. DISJOINT (connected_component s a) (connected_component s b) <=>
7489 ~(a IN connected_component s b)`,
7490 REWRITE_TAC[DISJOINT; EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN
7491 REWRITE_TAC[IN] THEN
7492 MESON_TAC[CONNECTED_COMPONENT_SYM; CONNECTED_COMPONENT_TRANS]);;
7494 let CONNECTED_COMPONENT_NONOVERLAP = prove
7496 (connected_component s a) INTER (connected_component s b) = {} <=>
7497 ~(a IN s) \/ ~(b IN s) \/
7498 ~(connected_component s a = connected_component s b)`,
7500 ASM_CASES_TAC `(a:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN
7501 RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN
7502 ASM_REWRITE_TAC[INTER_EMPTY] THEN
7503 ASM_CASES_TAC `(b:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN
7504 RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN
7505 ASM_REWRITE_TAC[INTER_EMPTY] THEN ASM_CASES_TAC
7506 `connected_component s (a:real^N) = connected_component s b` THEN
7507 ASM_REWRITE_TAC[INTER_IDEMPOT; CONNECTED_COMPONENT_EQ_EMPTY] THEN
7508 FIRST_X_ASSUM(MP_TAC o check(is_neg o concl)) THEN
7509 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
7510 REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN
7511 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [GSYM DISJOINT]) THEN
7512 REWRITE_TAC[CONNECTED_COMPONENT_DISJOINT]);;
7514 let CONNECTED_COMPONENT_OVERLAP = prove
7516 ~((connected_component s a) INTER (connected_component s b) = {}) <=>
7518 connected_component s a = connected_component s b`,
7519 REWRITE_TAC[CONNECTED_COMPONENT_NONOVERLAP; DE_MORGAN_THM]);;
7521 let CONNECTED_COMPONENT_SYM_EQ = prove
7522 (`!s x y. connected_component s x y <=> connected_component s y x`,
7523 MESON_TAC[CONNECTED_COMPONENT_SYM]);;
7525 let CONNECTED_COMPONENT_EQ_EQ = prove
7527 connected_component s x = connected_component s y <=>
7528 ~(x IN s) /\ ~(y IN s) \/
7529 x IN s /\ y IN s /\ connected_component s x y`,
7530 REPEAT GEN_TAC THEN ASM_CASES_TAC `(y:real^N) IN s` THENL
7531 [ASM_CASES_TAC `(x:real^N) IN s` THEN ASM_REWRITE_TAC[] THENL
7532 [REWRITE_TAC[FUN_EQ_THM] THEN
7533 ASM_MESON_TAC[CONNECTED_COMPONENT_TRANS; CONNECTED_COMPONENT_REFL;
7534 CONNECTED_COMPONENT_SYM];
7535 ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]];
7536 RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONNECTED_COMPONENT_EQ_EMPTY]) THEN
7537 ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY] THEN
7538 ONCE_REWRITE_TAC[CONNECTED_COMPONENT_SYM_EQ] THEN
7539 ASM_REWRITE_TAC[EMPTY] THEN ASM_MESON_TAC[CONNECTED_COMPONENT_EQ_EMPTY]]);;
7541 let CONNECTED_EQ_CONNECTED_COMPONENT_EQ = prove
7542 (`!s. connected s <=>
7543 !x y. x IN s /\ y IN s
7544 ==> connected_component s x = connected_component s y`,
7545 SIMP_TAC[CONNECTED_COMPONENT_EQ_EQ] THEN
7546 REWRITE_TAC[CONNECTED_IFF_CONNECTED_COMPONENT]);;
7548 let CONNECTED_COMPONENT_IDEMP = prove
7549 (`!s x:real^N. connected_component (connected_component s x) x =
7550 connected_component s x`,
7551 REWRITE_TAC[FUN_EQ_THM; connected_component] THEN
7552 REPEAT GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN EQ_TAC THEN
7553 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
7554 ASM_MESON_TAC[CONNECTED_COMPONENT_MAXIMAL; SUBSET_TRANS;
7555 CONNECTED_COMPONENT_SUBSET]);;
7557 let CONNECTED_COMPONENT_UNIQUE = prove
7559 x IN c /\ c SUBSET s /\ connected c /\
7560 (!c'. x IN c' /\ c' SUBSET s /\ connected c'
7562 ==> connected_component s x = c`,
7563 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
7564 [FIRST_X_ASSUM MATCH_MP_TAC THEN
7565 REWRITE_TAC[CONNECTED_COMPONENT_SUBSET; CONNECTED_CONNECTED_COMPONENT] THEN
7566 REWRITE_TAC[IN] THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN
7568 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN ASM_REWRITE_TAC[]]);;
7570 let JOINABLE_CONNECTED_COMPONENT_EQ = prove
7572 connected t /\ t SUBSET s /\
7573 ~(connected_component s x INTER t = {}) /\
7574 ~(connected_component s y INTER t = {})
7575 ==> connected_component s x = connected_component s y`,
7577 REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
7578 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN DISCH_THEN(CONJUNCTS_THEN2
7579 (X_CHOOSE_THEN `w:real^N` STRIP_ASSUME_TAC)
7580 (X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC)) THEN
7581 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONNECTED_COMPONENT_EQ THEN
7582 REWRITE_TAC[IN] THEN
7583 MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN
7584 EXISTS_TAC `z:real^N` THEN CONJ_TAC THENL [ASM_MESON_TAC[IN]; ALL_TAC] THEN
7585 MATCH_MP_TAC CONNECTED_COMPONENT_TRANS THEN
7586 EXISTS_TAC `w:real^N` THEN CONJ_TAC THENL
7587 [REWRITE_TAC[connected_component] THEN
7588 EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[];
7589 ASM_MESON_TAC[IN; CONNECTED_COMPONENT_SYM]]);;
7591 let CONNECTED_COMPONENT_TRANSLATION = prove
7592 (`!a s x. connected_component (IMAGE (\x. a + x) s) (a + x) =
7593 IMAGE (\x. a + x) (connected_component s x)`,
7594 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN GEOM_TRANSLATE_TAC[]);;
7596 add_translation_invariants [CONNECTED_COMPONENT_TRANSLATION];;
7598 let CONNECTED_COMPONENT_LINEAR_IMAGE = prove
7599 (`!f s x. linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
7600 ==> connected_component (IMAGE f s) (f x) =
7601 IMAGE f (connected_component s x)`,
7602 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN
7603 GEOM_TRANSFORM_TAC[]);;
7605 add_linear_invariants [CONNECTED_COMPONENT_LINEAR_IMAGE];;
7607 let UNIONS_CONNECTED_COMPONENT = prove
7608 (`!s:real^N->bool. UNIONS {connected_component s x |x| x IN s} = s`,
7609 GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
7610 REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC; CONNECTED_COMPONENT_SUBSET] THEN
7611 REWRITE_TAC[SUBSET; UNIONS_GSPEC; IN_ELIM_THM] THEN
7612 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN EXISTS_TAC `x:real^N` THEN
7613 ASM_REWRITE_TAC[] THEN REWRITE_TAC[IN] THEN
7614 ASM_REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ]);;
7616 let CLOSED_IN_CONNECTED_COMPONENT = prove
7617 (`!s x:real^N. closed_in (subtopology euclidean s) (connected_component s x)`,
7619 ASM_CASES_TAC `connected_component s (x:real^N) = {}` THEN
7620 ASM_REWRITE_TAC[CLOSED_IN_EMPTY] THEN
7621 RULE_ASSUM_TAC(REWRITE_RULE[CONNECTED_COMPONENT_EQ_EMPTY]) THEN
7622 REWRITE_TAC[CLOSED_IN_CLOSED] THEN
7623 EXISTS_TAC `closure(connected_component s x):real^N->bool` THEN
7624 REWRITE_TAC[CLOSED_CLOSURE] THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
7625 REWRITE_TAC[SUBSET_INTER; CONNECTED_COMPONENT_SUBSET; CLOSURE_SUBSET] THEN
7626 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN REWRITE_TAC[INTER_SUBSET] THEN
7628 [ASM_REWRITE_TAC[IN_INTER] THEN
7629 MATCH_MP_TAC(REWRITE_RULE[SUBSET] CLOSURE_SUBSET) THEN
7630 ASM_REWRITE_TAC[IN; CONNECTED_COMPONENT_REFL_EQ];
7631 MATCH_MP_TAC CONNECTED_INTERMEDIATE_CLOSURE THEN
7632 EXISTS_TAC `connected_component s (x:real^N)` THEN
7633 REWRITE_TAC[INTER_SUBSET; CONNECTED_CONNECTED_COMPONENT;
7634 SUBSET_INTER; CONNECTED_COMPONENT_SUBSET; CLOSURE_SUBSET]]);;
7636 let OPEN_IN_CONNECTED_COMPONENT = prove
7638 FINITE {connected_component s x |x| x IN s}
7639 ==> open_in (subtopology euclidean s) (connected_component s x)`,
7640 REPEAT STRIP_TAC THEN
7642 `connected_component s (x:real^N) =
7643 s DIFF (UNIONS {connected_component s y |y| y IN s} DIFF
7644 connected_component s x)`
7646 [REWRITE_TAC[UNIONS_CONNECTED_COMPONENT] THEN
7647 MATCH_MP_TAC(SET_RULE `t SUBSET s ==> t = s DIFF (s DIFF t)`) THEN
7648 REWRITE_TAC[CONNECTED_COMPONENT_SUBSET];
7649 MATCH_MP_TAC OPEN_IN_DIFF THEN
7650 REWRITE_TAC[OPEN_IN_SUBTOPOLOGY_REFL; TOPSPACE_EUCLIDEAN; SUBSET_UNIV] THEN
7651 REWRITE_TAC[UNIONS_DIFF] THEN
7652 MATCH_MP_TAC CLOSED_IN_UNIONS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN
7653 ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN
7654 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
7656 `connected_component s y DIFF connected_component s x =
7657 connected_component s y \/
7658 connected_component s (y:real^N) DIFF connected_component s x = {}`
7659 (DISJ_CASES_THEN SUBST1_TAC)
7661 [MATCH_MP_TAC(SET_RULE
7662 `(~(s INTER t = {}) ==> s = t) ==> s DIFF t = s \/ s DIFF t = {}`) THEN
7663 SIMP_TAC[CONNECTED_COMPONENT_OVERLAP];
7664 REWRITE_TAC[CLOSED_IN_CONNECTED_COMPONENT];
7665 REWRITE_TAC[CLOSED_IN_EMPTY]]]);;
7667 let CONNECTED_COMPONENT_EQUIVALENCE_RELATION = prove
7668 (`!R s:real^N->bool.
7669 (!x y. R x y ==> R y x) /\
7670 (!x y z. R x y /\ R y z ==> R x z) /\
7672 ==> ?t. open_in (subtopology euclidean s) t /\ a IN t /\
7673 !x. x IN t ==> R a x)
7674 ==> !a b. connected_component s a b ==> R a b`,
7675 REPEAT STRIP_TAC THEN
7676 MP_TAC(ISPECL [`R:real^N->real^N->bool`; `connected_component s (a:real^N)`]
7677 CONNECTED_EQUIVALENCE_RELATION) THEN
7678 ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN ANTS_TAC THENL
7679 [X_GEN_TAC `c:real^N` THEN DISCH_TAC THEN
7680 FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N`) THEN ANTS_TAC THENL
7681 [ASM_MESON_TAC[CONNECTED_COMPONENT_SUBSET; SUBSET]; ALL_TAC] THEN
7682 DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
7683 EXISTS_TAC `t INTER connected_component s (a:real^N)` THEN
7684 ASM_SIMP_TAC[IN_INTER; OPEN_IN_OPEN] THEN
7685 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_IN_OPEN]) THEN
7686 MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN
7687 MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`]
7688 CONNECTED_COMPONENT_SUBSET) THEN
7690 DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN] THEN
7691 REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN
7692 ASM_MESON_TAC[CONNECTED_COMPONENT_IN]]);;
7694 (* ------------------------------------------------------------------------- *)
7695 (* The set of connected components of a set. *)
7696 (* ------------------------------------------------------------------------- *)
7698 let components = new_definition
7699 `components s = {connected_component s x | x | x:real^N IN s}`;;
7701 let COMPONENTS_TRANSLATION = prove
7702 (`!a s. components(IMAGE (\x. a + x) s) =
7703 IMAGE (IMAGE (\x. a + x)) (components s)`,
7704 REWRITE_TAC[components] THEN GEOM_TRANSLATE_TAC[] THEN SET_TAC[]);;
7706 add_translation_invariants [COMPONENTS_TRANSLATION];;
7708 let COMPONENTS_LINEAR_IMAGE = prove
7709 (`!f s. linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
7710 ==> components(IMAGE f s) = IMAGE (IMAGE f) (components s)`,
7711 REWRITE_TAC[components] THEN GEOM_TRANSFORM_TAC[] THEN SET_TAC[]);;
7713 add_linear_invariants [COMPONENTS_LINEAR_IMAGE];;
7715 let IN_COMPONENTS = prove
7716 (`!u:real^N->bool s. s IN components u
7717 <=> ?x. x IN u /\ s = connected_component u x`,
7718 REPEAT GEN_TAC THEN REWRITE_TAC[components] THEN EQ_TAC
7719 THENL [SET_TAC[];STRIP_TAC THEN ASM_SIMP_TAC[] THEN
7720 UNDISCH_TAC `x:real^N IN u` THEN SET_TAC[]]);;
7722 let UNIONS_COMPONENTS = prove
7723 (`!u:real^N->bool. u = UNIONS (components u)`,
7724 REWRITE_TAC[EXTENSION] THEN REPEAT GEN_TAC THEN EQ_TAC
7725 THENL[DISCH_TAC THEN REWRITE_TAC[IN_UNIONS] THEN
7726 EXISTS_TAC `connected_component (u:real^N->bool) x` THEN CONJ_TAC THENL
7727 [REWRITE_TAC[components] THEN SET_TAC[ASSUME `x:real^N IN u`];
7728 REWRITE_TAC[CONNECTED_COMPONENT_SET] THEN SUBGOAL_THEN
7729 `?s:real^N->bool. connected s /\ s SUBSET u /\ x IN s` MP_TAC
7730 THENL[EXISTS_TAC `{x:real^N}` THEN ASM_REWRITE_TAC[CONNECTED_SING] THEN
7731 POP_ASSUM MP_TAC THEN SET_TAC[]; SET_TAC[]]];
7732 REWRITE_TAC[IN_UNIONS] THEN STRIP_TAC THEN
7733 MATCH_MP_TAC (SET_RULE `!x:real^N s u. x IN s /\ s SUBSET u ==> x IN u`) THEN
7734 EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[] THEN STRIP_ASSUME_TAC
7735 (MESON[IN_COMPONENTS;ASSUME `t:real^N->bool IN components u`]
7736 `?y. t:real^N->bool = connected_component u y`) THEN
7737 ASM_REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]]);;
7739 let PAIRWISE_DISJOINT_COMPONENTS = prove
7740 (`!u:real^N->bool. pairwise DISJOINT (components u)`,
7741 GEN_TAC THEN REWRITE_TAC[pairwise;DISJOINT] THEN
7742 MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `t:real^N->bool`] THEN STRIP_TAC THEN
7743 ASSERT_TAC `(?a. s:real^N->bool = connected_component u a) /\
7744 ?b. t:real^N->bool = connected_component u b`
7745 THENL [ASM_MESON_TAC[IN_COMPONENTS];
7746 ASM_MESON_TAC[CONNECTED_COMPONENT_NONOVERLAP]]);;
7748 let IN_COMPONENTS_NONEMPTY = prove
7749 (`!s c. c IN components s ==> ~(c = {})`,
7750 REPEAT GEN_TAC THEN REWRITE_TAC[components; IN_ELIM_THM] THEN
7751 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY]);;
7753 let IN_COMPONENTS_SUBSET = prove
7754 (`!s c. c IN components s ==> c SUBSET s`,
7755 REPEAT GEN_TAC THEN REWRITE_TAC[components; IN_ELIM_THM] THEN
7756 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]);;
7758 let IN_COMPONENTS_CONNECTED = prove
7759 (`!s c. c IN components s ==> connected c`,
7760 REPEAT GEN_TAC THEN REWRITE_TAC[components; IN_ELIM_THM] THEN
7761 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT]);;
7763 let IN_COMPONENTS_MAXIMAL = prove
7764 (`!s c:real^N->bool.
7765 c IN components s <=>
7766 ~(c = {}) /\ c SUBSET s /\ connected c /\
7767 !c'. ~(c' = {}) /\ c SUBSET c' /\ c' SUBSET s /\ connected c'
7769 REPEAT GEN_TAC THEN REWRITE_TAC[components; IN_ELIM_THM] THEN EQ_TAC THENL
7770 [DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN
7771 ASM_REWRITE_TAC[CONNECTED_COMPONENT_EQ_EMPTY; CONNECTED_COMPONENT_SUBSET;
7772 CONNECTED_CONNECTED_COMPONENT] THEN
7773 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
7774 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
7775 ASM_MESON_TAC[CONNECTED_COMPONENT_REFL; IN; SUBSET];
7777 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
7778 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN
7779 DISCH_TAC THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7780 MATCH_MP_TAC(GSYM CONNECTED_COMPONENT_UNIQUE) THEN
7781 ASM_REWRITE_TAC[] THEN X_GEN_TAC `c':real^N->bool` THEN STRIP_TAC THEN
7782 REWRITE_TAC[SET_RULE `c' SUBSET c <=> c' UNION c = c`] THEN
7783 FIRST_X_ASSUM MATCH_MP_TAC THEN
7784 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
7785 MATCH_MP_TAC CONNECTED_UNION THEN ASM SET_TAC[]]);;
7787 let JOINABLE_COMPONENTS_EQ = prove
7789 connected t /\ t SUBSET s /\
7790 c1 IN components s /\ c2 IN components s /\
7791 ~(c1 INTER t = {}) /\ ~(c2 INTER t = {})
7793 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; components; FORALL_IN_GSPEC] THEN
7794 MESON_TAC[JOINABLE_CONNECTED_COMPONENT_EQ]);;
7796 let CLOSED_COMPONENTS = prove
7797 (`!s c. closed s /\ c IN components s ==> closed c`,
7798 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; components; FORALL_IN_GSPEC] THEN
7799 SIMP_TAC[CLOSED_CONNECTED_COMPONENT]);;
7801 let CONTINUOUS_ON_COMPONENTS_GEN = prove
7802 (`!f:real^M->real^N s.
7803 (!c. c IN components s
7804 ==> open_in (subtopology euclidean s) c /\ f continuous_on c)
7805 ==> f continuous_on s`,
7806 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_OPEN_IN_PREIMAGE_EQ] THEN
7807 DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN DISCH_TAC THEN
7809 `{x | x IN s /\ (f:real^M->real^N) x IN t} =
7810 UNIONS {{x | x IN c /\ f x IN t} | c IN components s}`
7812 [CONV_TAC(LAND_CONV(SUBS_CONV
7813 [ISPEC `s:real^M->bool` UNIONS_COMPONENTS])) THEN
7814 REWRITE_TAC[UNIONS_GSPEC; IN_UNIONS] THEN SET_TAC[];
7815 MATCH_MP_TAC OPEN_IN_UNIONS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN
7816 ASM_MESON_TAC[OPEN_IN_TRANS]]);;
7818 let CONTINUOUS_ON_COMPONENTS_CLOSED_GEN = prove
7819 (`!f:real^M->real^N s.
7820 FINITE(components s) /\
7821 (!c. c IN components s
7822 ==> closed_in (subtopology euclidean s) c /\ f continuous_on c)
7823 ==> f continuous_on s`,
7824 REPEAT GEN_TAC THEN REWRITE_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE_EQ] THEN
7825 DISCH_TAC THEN X_GEN_TAC `t:real^N->bool` THEN DISCH_TAC THEN
7827 `{x | x IN s /\ (f:real^M->real^N) x IN t} =
7828 UNIONS {{x | x IN c /\ f x IN t} | c IN components s}`
7830 [CONV_TAC(LAND_CONV(SUBS_CONV
7831 [ISPEC `s:real^M->bool` UNIONS_COMPONENTS])) THEN
7832 REWRITE_TAC[UNIONS_GSPEC; IN_UNIONS] THEN SET_TAC[];
7833 MATCH_MP_TAC CLOSED_IN_UNIONS THEN
7834 ASM_SIMP_TAC[SIMPLE_IMAGE; FINITE_IMAGE; FORALL_IN_IMAGE] THEN
7835 ASM_MESON_TAC[CLOSED_IN_TRANS]]);;
7837 let CONTINUOUS_ON_COMPONENTS_CLOSED = prove
7838 (`!f:real^M->real^N s.
7839 closed s /\ FINITE(components s) /\
7840 (!c. c IN components s ==> f continuous_on c)
7841 ==> f continuous_on s`,
7842 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_COMPONENTS_CLOSED_GEN THEN
7843 ASM_SIMP_TAC[] THEN REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSED_SUBSET THEN
7844 ASM_MESON_TAC[CLOSED_COMPONENTS; IN_COMPONENTS_SUBSET]);;
7846 let COMPONENTS_NONOVERLAP = prove
7847 (`!s c c'. c IN components s /\ c' IN components s
7848 ==> (c INTER c' = {} <=> ~(c = c'))`,
7849 REWRITE_TAC[components; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
7850 ASM_SIMP_TAC[CONNECTED_COMPONENT_NONOVERLAP]);;
7852 let COMPONENTS_EQ = prove
7853 (`!s c c'. c IN components s /\ c' IN components s
7854 ==> (c = c' <=> ~(c INTER c' = {}))`,
7855 MESON_TAC[COMPONENTS_NONOVERLAP]);;
7857 let COMPONENTS_EQ_EMPTY = prove
7858 (`!s. components s = {} <=> s = {}`,
7859 GEN_TAC THEN REWRITE_TAC[EXTENSION] THEN
7860 REWRITE_TAC[components; connected_component; IN_ELIM_THM] THEN
7863 let CONNECTED_EQ_CONNECTED_COMPONENTS_EQ = prove
7864 (`!s. connected s <=>
7865 !c c'. c IN components s /\ c' IN components s ==> c = c'`,
7866 REWRITE_TAC[components; IN_ELIM_THM] THEN
7867 MESON_TAC[CONNECTED_EQ_CONNECTED_COMPONENT_EQ]);;
7869 let COMPONENTS_EQ_SING,COMPONENTS_EQ_SING_EXISTS = (CONJ_PAIR o prove)
7870 (`(!s:real^N->bool. components s = {s} <=> connected s /\ ~(s = {})) /\
7871 (!s:real^N->bool. (?a. components s = {a}) <=> connected s /\ ~(s = {}))`,
7872 REWRITE_TAC[AND_FORALL_THM] THEN X_GEN_TAC `s:real^N->bool` THEN
7873 MATCH_MP_TAC(TAUT `(p ==> q) /\ (q ==> r) /\ (r ==> p)
7874 ==> (p <=> r) /\ (q <=> r)`) THEN
7875 REPEAT CONJ_TAC THENL
7877 STRIP_TAC THEN ASM_REWRITE_TAC[CONNECTED_EQ_CONNECTED_COMPONENTS_EQ] THEN
7878 ASM_MESON_TAC[IN_SING; COMPONENTS_EQ_EMPTY; NOT_INSERT_EMPTY];
7879 STRIP_TAC THEN ONCE_REWRITE_TAC[EXTENSION] THEN
7880 REWRITE_TAC[IN_SING] THEN
7881 REWRITE_TAC[components; IN_ELIM_THM] THEN
7882 ASM_MESON_TAC[CONNECTED_CONNECTED_COMPONENT_SET; MEMBER_NOT_EMPTY]]);;
7884 let IN_COMPONENTS_SELF = prove
7885 (`!s:real^N->bool. s IN components s <=> connected s /\ ~(s = {})`,
7886 GEN_TAC THEN EQ_TAC THENL
7887 [MESON_TAC[IN_COMPONENTS_NONEMPTY; IN_COMPONENTS_CONNECTED];
7888 SIMP_TAC[GSYM COMPONENTS_EQ_SING; IN_SING]]);;
7890 let COMPONENTS_MAXIMAL = prove
7891 (`!s t c:real^N->bool.
7892 c IN components s /\ connected t /\ t SUBSET s /\ ~(c INTER t = {})
7894 REWRITE_TAC[IMP_CONJ; components; FORALL_IN_GSPEC] THEN
7895 REPEAT STRIP_TAC THEN
7896 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
7897 REWRITE_TAC[IN_INTER; LEFT_IMP_EXISTS_THM] THEN
7898 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
7899 FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP CONNECTED_COMPONENT_EQ) THEN
7900 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN ASM_REWRITE_TAC[]);;
7902 let COMPONENTS_UNIQUE = prove
7903 (`!s:real^N->bool k.
7906 ==> connected c /\ ~(c = {}) /\
7907 !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> c' = c)
7908 ==> components s = k`,
7909 REPEAT STRIP_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN
7910 X_GEN_TAC `c:real^N->bool` THEN REWRITE_TAC[IN_COMPONENTS] THEN
7912 [DISCH_THEN(X_CHOOSE_THEN `x:real^N`
7913 (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN
7914 FIRST_ASSUM(MP_TAC o SPEC `x:real^N` o GEN_REWRITE_RULE I [EXTENSION]) THEN
7915 REWRITE_TAC[IN_UNIONS] THEN ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
7916 X_GEN_TAC `c:real^N->bool` THEN STRIP_TAC THEN
7917 SUBGOAL_THEN `connected_component s (x:real^N) = c`
7918 (fun th -> ASM_REWRITE_TAC[th]) THEN
7919 MATCH_MP_TAC CONNECTED_COMPONENT_UNIQUE THEN
7920 FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N->bool`) THEN
7921 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
7922 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
7923 X_GEN_TAC `c':real^N->bool` THEN STRIP_TAC THEN
7924 REWRITE_TAC[SET_RULE `c' SUBSET c <=> c' UNION c = c`] THEN
7925 FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THENL
7926 [MATCH_MP_TAC CONNECTED_UNION; ASM SET_TAC[]] THEN
7928 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N->bool`) THEN
7929 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
7930 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
7931 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN
7932 CONJ_TAC THENL [ASM SET_TAC[]; CONV_TAC SYM_CONV] THEN
7933 FIRST_X_ASSUM MATCH_MP_TAC THEN
7934 REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT; CONNECTED_COMPONENT_SUBSET] THEN
7935 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
7936 ASM_REWRITE_TAC[] THEN ASM SET_TAC[]]);;
7938 let COMPONENTS_UNIQUE_EQ = prove
7939 (`!s:real^N->bool k.
7940 components s = k <=>
7943 ==> connected c /\ ~(c = {}) /\
7944 !c'. connected c' /\ c SUBSET c' /\ c' SUBSET s ==> c' = c)`,
7945 REPEAT GEN_TAC THEN EQ_TAC THENL
7946 [DISCH_THEN(SUBST1_TAC o SYM); REWRITE_TAC[COMPONENTS_UNIQUE]] THEN
7947 REWRITE_TAC[GSYM UNIONS_COMPONENTS] THEN
7948 X_GEN_TAC `c:real^N->bool` THEN DISCH_TAC THEN REPEAT CONJ_TAC THENL
7949 [ASM_MESON_TAC[IN_COMPONENTS_CONNECTED];
7950 ASM_MESON_TAC[IN_COMPONENTS_NONEMPTY];
7951 RULE_ASSUM_TAC(REWRITE_RULE[IN_COMPONENTS_MAXIMAL]) THEN
7952 ASM_MESON_TAC[SUBSET_EMPTY]]);;
7954 (* ------------------------------------------------------------------------- *)
7955 (* Continuity implies uniform continuity on a compact domain. *)
7956 (* ------------------------------------------------------------------------- *)
7958 let COMPACT_UNIFORMLY_EQUICONTINUOUS = prove
7959 (`!(fs:(real^M->real^N)->bool) s.
7960 (!x e. x IN s /\ &0 < e
7962 (!f x'. f IN fs /\ x' IN s /\ dist (x',x) < d
7963 ==> dist (f x',f x) < e)) /\
7967 !f x x'. f IN fs /\ x IN s /\ x' IN s /\ dist (x',x) < d
7968 ==> dist(f x',f x) < e`,
7969 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
7970 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
7971 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
7972 X_GEN_TAC `d:real^M->real->real` THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN
7973 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o MATCH_MP HEINE_BOREL_LEMMA) THEN
7974 DISCH_THEN(MP_TAC o SPEC
7975 `{ ball(x:real^M,d x (e / &2)) | x IN s}`) THEN
7976 SIMP_TAC[FORALL_IN_GSPEC; OPEN_BALL; UNIONS_GSPEC; SUBSET; IN_ELIM_THM] THEN
7977 ANTS_TAC THENL [ASM_MESON_TAC[CENTRE_IN_BALL; REAL_HALF]; ALL_TAC] THEN
7978 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real` THEN STRIP_TAC THEN
7979 ASM_REWRITE_TAC[] THEN
7980 MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `u:real^M`; `v:real^M`] THEN
7981 STRIP_TAC THEN FIRST_X_ASSUM(fun th -> MP_TAC(SPEC `v:real^M` th) THEN
7982 ASM_REWRITE_TAC[] THEN DISCH_THEN(CHOOSE_THEN MP_TAC)) THEN
7983 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
7984 DISCH_THEN(fun th ->
7985 MP_TAC(SPEC `u:real^M` th) THEN MP_TAC(SPEC `v:real^M` th)) THEN
7986 ASM_REWRITE_TAC[DIST_REFL] THEN
7987 FIRST_X_ASSUM(X_CHOOSE_THEN `w:real^M` (CONJUNCTS_THEN2 ASSUME_TAC
7988 SUBST_ALL_TAC)) THEN
7989 ASM_REWRITE_TAC[CENTRE_IN_BALL] THEN ASM_REWRITE_TAC[IN_BALL] THEN
7990 ONCE_REWRITE_TAC[DIST_SYM] THEN REPEAT STRIP_TAC THEN
7991 FIRST_X_ASSUM(MP_TAC o SPECL [`w:real^M`; `e / &2`]) THEN
7992 ASM_REWRITE_TAC[REAL_HALF] THEN
7993 DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o CONJUNCT2) THEN
7994 DISCH_THEN(fun th -> MP_TAC(SPEC `u:real^M` th) THEN
7995 MP_TAC(SPEC `v:real^M` th)) THEN
7996 ASM_REWRITE_TAC[] THEN CONV_TAC NORM_ARITH);;
7998 let COMPACT_UNIFORMLY_CONTINUOUS = prove
7999 (`!f:real^M->real^N s.
8000 f continuous_on s /\ compact s ==> f uniformly_continuous_on s`,
8001 REPEAT GEN_TAC THEN REWRITE_TAC[continuous_on; uniformly_continuous_on] THEN
8003 MP_TAC(ISPECL [`{f:real^M->real^N}`; `s:real^M->bool`]
8004 COMPACT_UNIFORMLY_EQUICONTINUOUS) THEN
8005 REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; IN_SING; FORALL_UNWIND_THM2] THEN
8008 (* ------------------------------------------------------------------------- *)
8009 (* A uniformly convergent limit of continuous functions is continuous. *)
8010 (* ------------------------------------------------------------------------- *)
8012 let CONTINUOUS_UNIFORM_LIMIT = prove
8013 (`!net f:A->real^M->real^N g s.
8014 ~(trivial_limit net) /\
8015 eventually (\n. (f n) continuous_on s) net /\
8017 ==> eventually (\n. !x. x IN s ==> norm(f n x - g x) < e) net)
8018 ==> g continuous_on s`,
8019 REWRITE_TAC[continuous_on] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
8020 X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN
8021 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8022 FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN
8023 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
8024 FIRST_X_ASSUM(fun th -> MP_TAC th THEN REWRITE_TAC[IMP_IMP] THEN
8025 GEN_REWRITE_TAC LAND_CONV [GSYM EVENTUALLY_AND]) THEN
8026 DISCH_THEN(MP_TAC o MATCH_MP EVENTUALLY_HAPPENS) THEN
8027 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `a:A` THEN
8028 DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `x:real^M`) ASSUME_TAC) THEN
8029 ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
8030 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
8031 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN
8032 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
8033 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `y:real^M` THEN
8034 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
8035 FIRST_X_ASSUM(fun th ->
8036 MP_TAC(SPEC `x:real^M` th) THEN MP_TAC(SPEC `y:real^M` th)) THEN
8037 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
8039 ==> x < e / &3 ==> y < e / &3 ==> z < e / &3 ==> w < e`) THEN
8040 REWRITE_TAC[dist] THEN
8041 SUBST1_TAC(VECTOR_ARITH
8042 `(g:real^M->real^N) y - g x =
8043 --(f (a:A) y - g y) + (f a x - g x) + (f a y - f a x)`) THEN
8044 MATCH_MP_TAC NORM_TRIANGLE_LE THEN REWRITE_TAC[NORM_NEG; REAL_LE_LADD] THEN
8045 MATCH_MP_TAC NORM_TRIANGLE_LE THEN REWRITE_TAC[NORM_NEG; REAL_LE_REFL]);;
8047 (* ------------------------------------------------------------------------- *)
8048 (* Topological stuff lifted from and dropped to R *)
8049 (* ------------------------------------------------------------------------- *)
8051 let OPEN_LIFT = prove
8052 (`!s. open(IMAGE lift s) <=>
8053 !x. x IN s ==> ?e. &0 < e /\ !x'. abs(x' - x) < e ==> x' IN s`,
8054 REWRITE_TAC[open_def; FORALL_LIFT; LIFT_IN_IMAGE_LIFT; DIST_LIFT]);;
8056 let LIMPT_APPROACHABLE_LIFT = prove
8057 (`!x s. (lift x) limit_point_of (IMAGE lift s) <=>
8058 !e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ abs(x' - x) < e`,
8059 REWRITE_TAC[LIMPT_APPROACHABLE; EXISTS_LIFT; LIFT_IN_IMAGE_LIFT;
8060 LIFT_EQ; DIST_LIFT]);;
8062 let CLOSED_LIFT = prove
8063 (`!s. closed (IMAGE lift s) <=>
8064 !x. (!e. &0 < e ==> ?x'. x' IN s /\ ~(x' = x) /\ abs(x' - x) < e)
8066 GEN_TAC THEN REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE] THEN
8067 ONCE_REWRITE_TAC[FORALL_LIFT] THEN
8068 REWRITE_TAC[LIMPT_APPROACHABLE_LIFT; LIFT_EQ; DIST_LIFT;
8069 EXISTS_LIFT; LIFT_IN_IMAGE_LIFT]);;
8071 let CONTINUOUS_AT_LIFT_RANGE = prove
8072 (`!f x. (lift o f) continuous (at x) <=>
8075 (!x'. norm(x' - x) < d
8076 ==> abs(f x' - f x) < e)`,
8077 REWRITE_TAC[continuous_at; o_THM; DIST_LIFT] THEN REWRITE_TAC[dist]);;
8079 let CONTINUOUS_ON_LIFT_RANGE = prove
8080 (`!f s. (lift o f) continuous_on s <=>
8084 (!x'. x' IN s /\ norm(x' - x) < d
8085 ==> abs(f x' - f x) < e)`,
8086 REWRITE_TAC[continuous_on; o_THM; DIST_LIFT] THEN REWRITE_TAC[dist]);;
8088 let CONTINUOUS_LIFT_NORM_COMPOSE = prove
8091 ==> (\x. lift(norm(f x))) continuous net`,
8092 REPEAT GEN_TAC THEN REWRITE_TAC[continuous; tendsto] THEN
8093 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
8095 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
8096 REWRITE_TAC[DIST_REAL; GSYM drop; LIFT_DROP] THEN
8099 let CONTINUOUS_ON_LIFT_NORM_COMPOSE = prove
8100 (`!f:real^M->real^N s.
8102 ==> (\x. lift(norm(f x))) continuous_on s`,
8103 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_LIFT_NORM_COMPOSE]);;
8105 let CONTINUOUS_AT_LIFT_NORM = prove
8106 (`!x. (lift o norm) continuous (at x)`,
8107 REWRITE_TAC[CONTINUOUS_AT_LIFT_RANGE; NORM_LIFT] THEN
8108 MESON_TAC[REAL_ABS_SUB_NORM; REAL_LET_TRANS]);;
8110 let CONTINUOUS_ON_LIFT_NORM = prove
8111 (`!s. (lift o norm) continuous_on s`,
8112 REWRITE_TAC[CONTINUOUS_ON_LIFT_RANGE; NORM_LIFT] THEN
8113 MESON_TAC[REAL_ABS_SUB_NORM; REAL_LET_TRANS]);;
8115 let CONTINUOUS_AT_LIFT_COMPONENT = prove
8116 (`!i a. 1 <= i /\ i <= dimindex(:N)
8117 ==> (\x:real^N. lift(x$i)) continuous (at a)`,
8118 SIMP_TAC[continuous_at; DIST_LIFT; GSYM VECTOR_SUB_COMPONENT] THEN
8119 MESON_TAC[dist; REAL_LET_TRANS; COMPONENT_LE_NORM]);;
8121 let CONTINUOUS_ON_LIFT_COMPONENT = prove
8122 (`!i s. 1 <= i /\ i <= dimindex(:N)
8123 ==> (\x:real^N. lift(x$i)) continuous_on s`,
8124 SIMP_TAC[continuous_on; DIST_LIFT; GSYM VECTOR_SUB_COMPONENT] THEN
8125 MESON_TAC[dist; REAL_LET_TRANS; COMPONENT_LE_NORM]);;
8127 let CONTINUOUS_AT_LIFT_INFNORM = prove
8128 (`!x:real^N. (lift o infnorm) continuous (at x)`,
8129 REWRITE_TAC[CONTINUOUS_AT; LIM_AT; o_THM; DIST_LIFT] THEN
8130 MESON_TAC[REAL_LET_TRANS; dist; REAL_ABS_SUB_INFNORM; INFNORM_LE_NORM]);;
8132 let CONTINUOUS_AT_LIFT_DIST = prove
8133 (`!a:real^N x. (lift o (\x. dist(a,x))) continuous (at x)`,
8134 REWRITE_TAC[CONTINUOUS_AT_LIFT_RANGE] THEN
8135 MESON_TAC[NORM_ARITH `abs(dist(a:real^N,x) - dist(a,y)) <= norm(x - y)`;
8138 let CONTINUOUS_ON_LIFT_DIST = prove
8139 (`!a s. (lift o (\x. dist(a,x))) continuous_on s`,
8140 REWRITE_TAC[CONTINUOUS_ON_LIFT_RANGE] THEN
8141 MESON_TAC[NORM_ARITH `abs(dist(a:real^N,x) - dist(a,y)) <= norm(x - y)`;
8144 (* ------------------------------------------------------------------------- *)
8145 (* Hence some handy theorems on distance, diameter etc. of/from a set. *)
8146 (* ------------------------------------------------------------------------- *)
8148 let COMPACT_ATTAINS_SUP = prove
8149 (`!s. compact (IMAGE lift s) /\ ~(s = {})
8150 ==> ?x. x IN s /\ !y. y IN s ==> y <= x`,
8151 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN REPEAT STRIP_TAC THEN
8152 MP_TAC(SPEC `s:real->bool` BOUNDED_HAS_SUP) THEN ASM_REWRITE_TAC[] THEN
8153 STRIP_TAC THEN EXISTS_TAC `sup s` THEN ASM_REWRITE_TAC[] THEN
8154 ASM_MESON_TAC[CLOSED_LIFT; REAL_ARITH `s <= s - e <=> ~(&0 < e)`;
8155 REAL_ARITH `x <= s /\ ~(x <= s - e) ==> abs(x - s) < e`]);;
8157 let COMPACT_ATTAINS_INF = prove
8158 (`!s. compact (IMAGE lift s) /\ ~(s = {})
8159 ==> ?x. x IN s /\ !y. y IN s ==> x <= y`,
8160 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN REPEAT STRIP_TAC THEN
8161 MP_TAC(SPEC `s:real->bool` BOUNDED_HAS_INF) THEN ASM_REWRITE_TAC[] THEN
8162 STRIP_TAC THEN EXISTS_TAC `inf s` THEN ASM_REWRITE_TAC[] THEN
8163 ASM_MESON_TAC[CLOSED_LIFT; REAL_ARITH `s + e <= s <=> ~(&0 < e)`;
8164 REAL_ARITH `s <= x /\ ~(s + e <= x) ==> abs(x - s) < e`]);;
8166 let CONTINUOUS_ATTAINS_SUP = prove
8167 (`!f:real^N->real s.
8168 compact s /\ ~(s = {}) /\ (lift o f) continuous_on s
8169 ==> ?x. x IN s /\ !y. y IN s ==> f(y) <= f(x)`,
8170 REPEAT STRIP_TAC THEN
8171 MP_TAC(SPEC `IMAGE (f:real^N->real) s` COMPACT_ATTAINS_SUP) THEN
8172 ASM_SIMP_TAC[GSYM IMAGE_o; COMPACT_CONTINUOUS_IMAGE; IMAGE_EQ_EMPTY] THEN
8173 MESON_TAC[IN_IMAGE]);;
8175 let CONTINUOUS_ATTAINS_INF = prove
8176 (`!f:real^N->real s.
8177 compact s /\ ~(s = {}) /\ (lift o f) continuous_on s
8178 ==> ?x. x IN s /\ !y. y IN s ==> f(x) <= f(y)`,
8179 REPEAT STRIP_TAC THEN
8180 MP_TAC(SPEC `IMAGE (f:real^N->real) s` COMPACT_ATTAINS_INF) THEN
8181 ASM_SIMP_TAC[GSYM IMAGE_o; COMPACT_CONTINUOUS_IMAGE; IMAGE_EQ_EMPTY] THEN
8182 MESON_TAC[IN_IMAGE]);;
8184 let DISTANCE_ATTAINS_SUP = prove
8185 (`!s a. compact s /\ ~(s = {})
8186 ==> ?x. x IN s /\ !y. y IN s ==> dist(a,y) <= dist(a,x)`,
8187 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ATTAINS_SUP THEN
8188 ASM_REWRITE_TAC[CONTINUOUS_ON_LIFT_RANGE] THEN REWRITE_TAC[dist] THEN
8189 ASM_MESON_TAC[REAL_LET_TRANS; REAL_ABS_SUB_NORM; NORM_NEG;
8190 VECTOR_ARITH `(a - x) - (a - y) = --(x - y):real^N`]);;
8192 (* ------------------------------------------------------------------------- *)
8193 (* For *minimal* distance, we only need closure, not compactness. *)
8194 (* ------------------------------------------------------------------------- *)
8196 let DISTANCE_ATTAINS_INF = prove
8198 closed s /\ ~(s = {})
8199 ==> ?x. x IN s /\ !y. y IN s ==> dist(a,x) <= dist(a,y)`,
8200 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
8201 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
8202 DISCH_THEN(X_CHOOSE_TAC `b:real^N`) THEN
8203 MP_TAC(ISPECL [`\x:real^N. dist(a,x)`; `cball(a:real^N,dist(b,a)) INTER s`]
8204 CONTINUOUS_ATTAINS_INF) THEN
8206 [ASM_SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_INTER; BOUNDED_INTER;
8207 BOUNDED_CBALL; CLOSED_CBALL; GSYM MEMBER_NOT_EMPTY] THEN
8208 REWRITE_TAC[dist; CONTINUOUS_ON_LIFT_RANGE; IN_INTER; IN_CBALL] THEN
8209 ASM_MESON_TAC[REAL_LET_TRANS; REAL_ABS_SUB_NORM; NORM_NEG; REAL_LE_REFL;
8210 NORM_SUB; VECTOR_ARITH `(a - x) - (a - y) = --(x - y):real^N`];
8211 MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[IN_INTER; IN_CBALL] THEN
8212 ASM_MESON_TAC[DIST_SYM; REAL_LE_TOTAL; REAL_LE_TRANS]]);;
8214 (* ------------------------------------------------------------------------- *)
8215 (* We can now extend limit compositions to consider the scalar multiplier. *)
8216 (* ------------------------------------------------------------------------- *)
8219 (`!net:(A)net f l:real^N c d.
8220 ((lift o c) --> lift d) net /\ (f --> l) net
8221 ==> ((\x. c(x) % f(x)) --> (d % l)) net`,
8222 REPEAT STRIP_TAC THEN
8223 MP_TAC(ISPECL [`net:(A)net`; `\x (y:real^N). drop x % y`;
8224 `lift o (c:A->real)`; `f:A->real^N`; `lift d`; `l:real^N`] LIM_BILINEAR) THEN
8225 ASM_REWRITE_TAC[LIFT_DROP; o_THM] THEN DISCH_THEN MATCH_MP_TAC THEN
8226 REWRITE_TAC[bilinear; linear; DROP_ADD; DROP_CMUL] THEN
8227 REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
8229 let LIM_VMUL = prove
8230 (`!net:(A)net c d v:real^N.
8231 ((lift o c) --> lift d) net ==> ((\x. c(x) % v) --> d % v) net`,
8232 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_MUL THEN ASM_REWRITE_TAC[LIM_CONST]);;
8234 let CONTINUOUS_VMUL = prove
8235 (`!net c v. (lift o c) continuous net ==> (\x. c(x) % v) continuous net`,
8236 REWRITE_TAC[continuous; LIM_VMUL; o_THM]);;
8238 let CONTINUOUS_MUL = prove
8239 (`!net f c. (lift o c) continuous net /\ f continuous net
8240 ==> (\x. c(x) % f(x)) continuous net`,
8241 REWRITE_TAC[continuous; LIM_MUL; o_THM]);;
8243 let CONTINUOUS_ON_VMUL = prove
8244 (`!s c v. (lift o c) continuous_on s ==> (\x. c(x) % v) continuous_on s`,
8245 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
8246 SIMP_TAC[CONTINUOUS_VMUL]);;
8248 let CONTINUOUS_ON_MUL = prove
8249 (`!s c f. (lift o c) continuous_on s /\ f continuous_on s
8250 ==> (\x. c(x) % f(x)) continuous_on s`,
8251 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
8252 SIMP_TAC[CONTINUOUS_MUL]);;
8254 let CONTINUOUS_LIFT_POW = prove
8256 (\x. lift(f x)) continuous net
8257 ==> (\x. lift(f x pow n)) continuous net`,
8258 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
8259 INDUCT_TAC THEN ASM_REWRITE_TAC[LIFT_CMUL; real_pow; CONTINUOUS_CONST] THEN
8260 MATCH_MP_TAC CONTINUOUS_MUL THEN ASM_REWRITE_TAC[o_DEF]);;
8262 let CONTINUOUS_ON_LIFT_POW = prove
8263 (`!f:real^N->real s n.
8264 (\x. lift(f x)) continuous_on s
8265 ==> (\x. lift(f x pow n)) continuous_on s`,
8266 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN REPEAT GEN_TAC THEN
8267 DISCH_TAC THEN INDUCT_TAC THEN
8268 ASM_REWRITE_TAC[LIFT_CMUL; real_pow; CONTINUOUS_ON_CONST] THEN
8269 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN ASM_REWRITE_TAC[o_DEF]);;
8271 let CONTINUOUS_LIFT_PRODUCT = prove
8272 (`!net:(A)net f (t:B->bool).
8274 (!i. i IN t ==> (\x. lift(f x i)) continuous net)
8275 ==> (\x. lift(product t (f x))) continuous net`,
8276 GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
8277 MATCH_MP_TAC FINITE_INDUCT_STRONG THEN SIMP_TAC[PRODUCT_CLAUSES] THEN
8278 REWRITE_TAC[CONTINUOUS_CONST; LIFT_CMUL; FORALL_IN_INSERT] THEN
8279 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_MUL THEN
8280 ASM_SIMP_TAC[o_DEF]);;
8282 let CONTINUOUS_ON_LIFT_PRODUCT = prove
8283 (`!f:real^N->A->real s t.
8286 (!i. i IN t ==> (\x. lift(f x i)) continuous_on s)
8287 ==> (\x. lift(product t (f x))) continuous_on s`,
8288 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_LIFT_PRODUCT]);;
8290 (* ------------------------------------------------------------------------- *)
8291 (* And so we have continuity of inverse. *)
8292 (* ------------------------------------------------------------------------- *)
8296 ((lift o f) --> lift l) net /\ ~(l = &0)
8297 ==> ((lift o inv o f) --> lift(inv l)) net`,
8298 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
8299 ASM_CASES_TAC `trivial_limit(net:(A)net)` THEN ASM_REWRITE_TAC[] THEN
8300 REWRITE_TAC[o_THM; DIST_LIFT] THEN STRIP_TAC THEN
8301 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8302 FIRST_X_ASSUM(MP_TAC o SPEC `min (abs(l) / &2) ((l pow 2 * e) / &2)`) THEN
8303 REWRITE_TAC[REAL_LT_MIN] THEN ANTS_TAC THENL
8304 [ASM_SIMP_TAC[GSYM REAL_ABS_NZ; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
8305 MATCH_MP_TAC REAL_LT_DIV THEN REWRITE_TAC[REAL_OF_NUM_LT; ARITH] THEN
8306 ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN
8307 ASM_SIMP_TAC[REAL_LT_MUL; GSYM REAL_ABS_NZ; REAL_POW_LT];
8309 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:A` THEN
8310 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
8311 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `b:A` THEN
8312 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
8313 SIMP_TAC[REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN STRIP_TAC THEN
8314 FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REAL_ARITH
8315 `abs(x - l) * &2 < abs l ==> ~(x = &0)`)) THEN
8316 ASM_SIMP_TAC[REAL_SUB_INV; REAL_ABS_DIV; REAL_LT_LDIV_EQ;
8317 GSYM REAL_ABS_NZ; REAL_ENTIRE] THEN
8318 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
8319 `abs(x - y) * &2 < b * c ==> c * b <= d * &2 ==> abs(y - x) < d`)) THEN
8320 ASM_SIMP_TAC[GSYM REAL_MUL_ASSOC; REAL_LE_LMUL_EQ] THEN
8321 ONCE_REWRITE_TAC[GSYM REAL_POW2_ABS] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
8322 ASM_SIMP_TAC[REAL_ABS_MUL; REAL_POW_2; REAL_MUL_ASSOC; GSYM REAL_ABS_NZ;
8323 REAL_LE_RMUL_EQ] THEN
8324 ASM_SIMP_TAC[REAL_ARITH `abs(x - y) * &2 < abs y ==> abs y <= &2 * abs x`]);;
8326 let CONTINUOUS_INV = prove
8327 (`!net f. (lift o f) continuous net /\ ~(f(netlimit net) = &0)
8328 ==> (lift o inv o f) continuous net`,
8329 REWRITE_TAC[continuous; LIM_INV; o_THM]);;
8331 let CONTINUOUS_AT_WITHIN_INV = prove
8333 (lift o f) continuous (at a within s) /\ ~(f a = &0)
8334 ==> (lift o inv o f) continuous (at a within s)`,
8336 ASM_CASES_TAC `trivial_limit (at (a:real^N) within s)` THENL
8337 [ASM_REWRITE_TAC[continuous; LIM];
8338 ASM_SIMP_TAC[NETLIMIT_WITHIN; CONTINUOUS_INV]]);;
8340 let CONTINUOUS_AT_INV = prove
8341 (`!f a. (lift o f) continuous at a /\ ~(f a = &0)
8342 ==> (lift o inv o f) continuous at a`,
8343 ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
8344 REWRITE_TAC[CONTINUOUS_AT_WITHIN_INV]);;
8346 let CONTINUOUS_ON_INV = prove
8347 (`!f s. (lift o f) continuous_on s /\ (!x. x IN s ==> ~(f x = &0))
8348 ==> (lift o inv o f) continuous_on s`,
8349 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_AT_WITHIN_INV]);;
8351 (* ------------------------------------------------------------------------- *)
8352 (* Preservation properties for pasted sets (Cartesian products). *)
8353 (* ------------------------------------------------------------------------- *)
8355 let BOUNDED_PCROSS_EQ = prove
8356 (`!s:real^M->bool t:real^N->bool.
8357 bounded (s PCROSS t) <=>
8358 s = {} \/ t = {} \/ bounded s /\ bounded t`,
8359 REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN
8360 ASM_CASES_TAC `s:real^M->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
8361 ASM_CASES_TAC `t:real^N->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
8362 REWRITE_TAC[SET_RULE `{f x y |x,y| F} = {}`; BOUNDED_EMPTY] THEN
8363 RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN
8364 REWRITE_TAC[bounded; FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN
8365 ASM_MESON_TAC[NORM_LE_PASTECART; REAL_LE_TRANS; NORM_PASTECART_LE;
8368 let BOUNDED_PCROSS = prove
8369 (`!s:real^M->bool t:real^N->bool.
8370 bounded s /\ bounded t ==> bounded (s PCROSS t)`,
8371 SIMP_TAC[BOUNDED_PCROSS_EQ]);;
8373 let CLOSED_PCROSS_EQ = prove
8374 (`!s:real^M->bool t:real^N->bool.
8375 closed (s PCROSS t) <=>
8376 s = {} \/ t = {} \/ closed s /\ closed t`,
8377 REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN MAP_EVERY ASM_CASES_TAC
8378 [`s:real^M->bool = {}`; `t:real^N->bool = {}`] THEN
8379 ASM_REWRITE_TAC[NOT_IN_EMPTY; CLOSED_EMPTY; SET_RULE
8380 `{f x y |x,y| F} = {}`] THEN
8381 REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS; LIM_SEQUENTIALLY] THEN
8382 REWRITE_TAC[FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN
8383 REWRITE_TAC[IN_ELIM_THM; SKOLEM_THM; FORALL_AND_THM] THEN
8384 ONCE_REWRITE_TAC[GSYM FUN_EQ_THM] THEN
8385 REWRITE_TAC[LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN
8386 SIMP_TAC[TAUT `((p /\ q) /\ r) /\ s ==> t <=> r ==> p /\ q /\ s ==> t`] THEN
8387 ONCE_REWRITE_TAC[MESON[]
8388 `(!a b c d e. P a b c d e) <=> (!d e b c a. P a b c d e)`] THEN
8389 REWRITE_TAC[FORALL_UNWIND_THM2] THEN
8390 RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN EQ_TAC THENL
8391 [GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV)
8392 [TAUT `p ==> q /\ r <=> (p ==> q) /\ (p ==> r)`; FORALL_AND_THM] THEN
8393 MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
8394 [ALL_TAC; GEN_REWRITE_TAC LAND_CONV [SWAP_FORALL_THM]] THEN
8395 MATCH_MP_TAC MONO_FORALL THEN REPEAT STRIP_TAC THEN
8396 FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC(MESON[]
8397 `(?x. P x (\n. x)) ==> (?s x. P x s)`) THEN
8398 ASM_MESON_TAC[DIST_PASTECART_CANCEL];
8399 ONCE_REWRITE_TAC[MESON[]
8400 `(!x l. P x l) /\ (!y m. Q y m) <=> (!x y l m. P x l /\ Q y m)`] THEN
8401 REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
8402 REWRITE_TAC[dist; PASTECART_SUB] THEN
8403 ASM_MESON_TAC[NORM_LE_PASTECART; REAL_LET_TRANS]]);;
8405 let CLOSED_PCROSS = prove
8406 (`!s:real^M->bool t:real^N->bool.
8407 closed s /\ closed t ==> closed (s PCROSS t)`,
8408 SIMP_TAC[CLOSED_PCROSS_EQ]);;
8410 let COMPACT_PCROSS_EQ = prove
8411 (`!s:real^M->bool t:real^N->bool.
8412 compact (s PCROSS t) <=>
8413 s = {} \/ t = {} \/ compact s /\ compact t`,
8414 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_PCROSS_EQ;
8415 BOUNDED_PCROSS_EQ] THEN
8418 let COMPACT_PCROSS = prove
8419 (`!s:real^M->bool t:real^N->bool.
8420 compact s /\ compact t ==> compact (s PCROSS t)`,
8421 SIMP_TAC[COMPACT_PCROSS_EQ]);;
8423 let OPEN_PCROSS_EQ = prove
8424 (`!s:real^M->bool t:real^N->bool.
8425 open (s PCROSS t) <=>
8426 s = {} \/ t = {} \/ open s /\ open t`,
8427 REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN
8428 ASM_CASES_TAC `s:real^M->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
8429 ASM_CASES_TAC `t:real^N->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
8430 REWRITE_TAC[SET_RULE `{f x y |x,y| F} = {}`; OPEN_EMPTY] THEN
8431 RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN
8433 [REWRITE_TAC[open_def; FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN
8434 ASM_MESON_TAC[DIST_PASTECART_CANCEL];
8435 REWRITE_TAC[OPEN_CLOSED] THEN STRIP_TAC THEN
8437 `UNIV DIFF {pastecart x y | x IN s /\ y IN t} =
8438 {pastecart x y | x IN ((:real^M) DIFF s) /\ y IN (:real^N)} UNION
8439 {pastecart x y | x IN (:real^M) /\ y IN ((:real^N) DIFF t)}`
8441 [REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNION; FORALL_PASTECART; IN_UNIV] THEN
8442 REWRITE_TAC[IN_ELIM_THM; PASTECART_EQ; FSTCART_PASTECART;
8443 SNDCART_PASTECART] THEN MESON_TAC[];
8444 SIMP_TAC[GSYM PCROSS] THEN MATCH_MP_TAC CLOSED_UNION THEN CONJ_TAC THEN
8445 MATCH_MP_TAC CLOSED_PCROSS THEN ASM_REWRITE_TAC[CLOSED_UNIV]]]);;
8447 let OPEN_PCROSS = prove
8448 (`!s:real^M->bool t:real^N->bool.
8449 open s /\ open t ==> open (s PCROSS t)`,
8450 SIMP_TAC[OPEN_PCROSS_EQ]);;
8452 let OPEN_IN_PCROSS = prove
8453 (`!s s':real^M->bool t t':real^N->bool.
8454 open_in (subtopology euclidean s) s' /\
8455 open_in (subtopology euclidean t) t'
8456 ==> open_in (subtopology euclidean (s PCROSS t)) (s' PCROSS t')`,
8457 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN DISCH_THEN(CONJUNCTS_THEN2
8458 (X_CHOOSE_THEN `s'':real^M->bool` STRIP_ASSUME_TAC)
8459 (X_CHOOSE_THEN `t'':real^N->bool` STRIP_ASSUME_TAC)) THEN
8460 EXISTS_TAC `(s'':real^M->bool) PCROSS (t'':real^N->bool)` THEN
8461 ASM_SIMP_TAC[OPEN_PCROSS; EXTENSION; FORALL_PASTECART] THEN
8462 REWRITE_TAC[IN_INTER; PASTECART_IN_PCROSS] THEN ASM SET_TAC[]);;
8464 let PASTECART_IN_INTERIOR_SUBTOPOLOGY = prove
8465 (`!s t u x:real^M y:real^N.
8466 pastecart x y IN u /\ open_in (subtopology euclidean (s PCROSS t)) u
8467 ==> ?v w. open_in (subtopology euclidean s) v /\ x IN v /\
8468 open_in (subtopology euclidean t) w /\ y IN w /\
8469 (v PCROSS w) SUBSET u`,
8470 REWRITE_TAC[open_in; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN
8471 REPEAT STRIP_TAC THEN
8472 FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `y:real^N`]) THEN
8473 ASM_REWRITE_TAC[] THEN
8474 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
8475 EXISTS_TAC `ball(x:real^M,e / &2) INTER s` THEN
8476 EXISTS_TAC `ball(y:real^N,e / &2) INTER t` THEN
8477 SUBGOAL_THEN `(x:real^M) IN s /\ (y:real^N) IN t` STRIP_ASSUME_TAC THENL
8478 [ASM_MESON_TAC[SUBSET; PASTECART_IN_PCROSS]; ALL_TAC] THEN
8479 ASM_SIMP_TAC[INTER_SUBSET; IN_INTER; CENTRE_IN_BALL; REAL_HALF] THEN
8480 REWRITE_TAC[IN_BALL] THEN REPEAT(CONJ_TAC THENL
8481 [MESON_TAC[REAL_SUB_LT; NORM_ARITH
8482 `dist(x,y) < e /\ dist(z,y) < e - dist(x,y)
8483 ==> dist(x:real^N,z) < e`];
8485 REWRITE_TAC[SUBSET; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN
8486 REWRITE_TAC[IN_BALL; IN_INTER] THEN REPEAT STRIP_TAC THEN
8487 FIRST_X_ASSUM MATCH_MP_TAC THEN
8488 ASM_REWRITE_TAC[dist; PASTECART_SUB] THEN
8489 W(MP_TAC o PART_MATCH lhand NORM_PASTECART_LE o lhand o snd) THEN
8490 REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[DIST_SYM] dist)] THEN
8491 ASM_REAL_ARITH_TAC);;
8493 let OPEN_IN_PCROSS_EQ = prove
8494 (`!s s':real^M->bool t t':real^N->bool.
8495 open_in (subtopology euclidean (s PCROSS t)) (s' PCROSS t') <=>
8496 s' = {} \/ t' = {} \/
8497 open_in (subtopology euclidean s) s' /\
8498 open_in (subtopology euclidean t) t'`,
8500 ASM_CASES_TAC `s':real^M->bool = {}` THEN
8501 ASM_REWRITE_TAC[PCROSS_EMPTY; OPEN_IN_EMPTY] THEN
8502 ASM_CASES_TAC `t':real^N->bool = {}` THEN
8503 ASM_REWRITE_TAC[PCROSS_EMPTY; OPEN_IN_EMPTY] THEN
8504 EQ_TAC THEN REWRITE_TAC[OPEN_IN_PCROSS] THEN REPEAT STRIP_TAC THENL
8505 [ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN
8506 X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
8507 UNDISCH_TAC `~(t':real^N->bool = {})` THEN
8508 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
8509 DISCH_THEN(X_CHOOSE_TAC `y:real^N`);
8510 ONCE_REWRITE_TAC[OPEN_IN_SUBOPEN] THEN
8511 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
8512 UNDISCH_TAC `~(s':real^M->bool = {})` THEN
8513 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
8514 DISCH_THEN(X_CHOOSE_TAC `x:real^M`)] THEN
8516 [`s:real^M->bool`; `t:real^N->bool`;
8517 `(s':real^M->bool) PCROSS (t':real^N->bool)`;
8518 `x:real^M`; `y:real^N`] PASTECART_IN_INTERIOR_SUBTOPOLOGY) THEN
8519 ASM_REWRITE_TAC[SUBSET; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN
8522 let INTERIOR_PCROSS = prove
8523 (`!s:real^M->bool t:real^N->bool.
8524 interior (s PCROSS t) = (interior s) PCROSS (interior t)`,
8525 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
8526 [REWRITE_TAC[SUBSET; FORALL_PASTECART; PASTECART_IN_PCROSS] THEN
8527 MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^N`] THEN DISCH_TAC THEN
8528 MP_TAC(ISPECL [`(:real^M)`; `(:real^N)`;
8529 `interior((s:real^M->bool) PCROSS (t:real^N->bool))`;
8530 `x:real^M`; `y:real^N`] PASTECART_IN_INTERIOR_SUBTOPOLOGY) THEN
8531 REWRITE_TAC[UNIV_PCROSS_UNIV; SUBTOPOLOGY_UNIV; GSYM OPEN_IN] THEN
8532 ASM_REWRITE_TAC[OPEN_INTERIOR] THEN STRIP_TAC THEN
8533 FIRST_ASSUM(MP_TAC o MATCH_MP (MESON[INTERIOR_SUBSET; SUBSET_TRANS]
8534 `s SUBSET interior t ==> s SUBSET t`)) THEN
8535 REWRITE_TAC[SUBSET_PCROSS] THEN
8536 ASM_MESON_TAC[NOT_IN_EMPTY; INTERIOR_MAXIMAL; SUBSET];
8537 MATCH_MP_TAC INTERIOR_MAXIMAL THEN
8538 SIMP_TAC[OPEN_PCROSS; OPEN_INTERIOR; PCROSS_MONO; INTERIOR_SUBSET]]);;
8540 let LIM_PASTECART = prove
8541 (`!net f:A->real^M g:A->real^N.
8542 (f --> a) net /\ (g --> b) net
8543 ==> ((\x. pastecart (f x) (g x)) --> pastecart a b) net`,
8544 REPEAT GEN_TAC THEN REWRITE_TAC[LIM] THEN
8545 ASM_CASES_TAC `trivial_limit(net:(A)net)` THEN ASM_REWRITE_TAC[] THEN
8546 REWRITE_TAC[AND_FORALL_THM] THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN
8547 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
8548 ASM_REWRITE_TAC[REAL_HALF] THEN
8549 DISCH_THEN(MP_TAC o MATCH_MP NET_DILEMMA) THEN
8550 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN MATCH_MP_TAC MONO_AND THEN
8551 REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
8552 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
8553 REWRITE_TAC[dist; PASTECART_SUB] THEN
8554 MATCH_MP_TAC(REAL_ARITH
8555 `z <= x + y ==> x < e / &2 /\ y < e / &2 ==> z < e`) THEN
8556 REWRITE_TAC[NORM_PASTECART_LE]);;
8558 let LIM_PASTECART_EQ = prove
8559 (`!net f:A->real^M g:A->real^N.
8560 ((\x. pastecart (f x) (g x)) --> pastecart a b) net <=>
8561 (f --> a) net /\ (g --> b) net`,
8562 REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[LIM_PASTECART] THEN
8563 REPEAT STRIP_TAC THENL
8564 [FIRST_ASSUM(MP_TAC o ISPEC `fstcart:real^(M,N)finite_sum->real^M` o
8565 MATCH_MP (REWRITE_RULE[IMP_CONJ] LIM_LINEAR)) THEN
8566 REWRITE_TAC[LINEAR_FSTCART; FSTCART_PASTECART; ETA_AX];
8567 FIRST_ASSUM(MP_TAC o ISPEC `sndcart:real^(M,N)finite_sum->real^N` o
8568 MATCH_MP (REWRITE_RULE[IMP_CONJ] LIM_LINEAR)) THEN
8569 REWRITE_TAC[LINEAR_SNDCART; SNDCART_PASTECART; ETA_AX]]);;
8571 let CONTINUOUS_PASTECART = prove
8572 (`!net f:A->real^M g:A->real^N.
8573 f continuous net /\ g continuous net
8574 ==> (\x. pastecart (f x) (g x)) continuous net`,
8575 REWRITE_TAC[continuous; LIM_PASTECART]);;
8577 let CONTINUOUS_ON_PASTECART = prove
8578 (`!f:real^M->real^N g:real^M->real^P s.
8579 f continuous_on s /\ g continuous_on s
8580 ==> (\x. pastecart (f x) (g x)) continuous_on s`,
8581 SIMP_TAC[CONTINUOUS_ON; LIM_PASTECART]);;
8583 let CONNECTED_PCROSS = prove
8584 (`!s:real^M->bool t:real^N->bool.
8585 connected s /\ connected t
8586 ==> connected (s PCROSS t)`,
8588 REWRITE_TAC[PCROSS; CONNECTED_IFF_CONNECTED_COMPONENT] THEN
8589 DISCH_TAC THEN REWRITE_TAC[FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN
8590 MAP_EVERY X_GEN_TAC [`x1:real^M`; `y1:real^N`; `x2:real^M`; `y2:real^N`] THEN
8591 STRIP_TAC THEN FIRST_X_ASSUM(CONJUNCTS_THEN2
8592 (MP_TAC o SPECL [`x1:real^M`; `x2:real^M`])
8593 (MP_TAC o SPECL [`y1:real^N`; `y2:real^N`])) THEN
8594 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; connected_component] THEN
8595 X_GEN_TAC `c2:real^N->bool` THEN STRIP_TAC THEN
8596 X_GEN_TAC `c1:real^M->bool` THEN STRIP_TAC THEN
8598 `IMAGE (\x:real^M. pastecart x y1) c1 UNION
8599 IMAGE (\y:real^N. pastecart x2 y) c2` THEN
8600 REWRITE_TAC[IN_UNION] THEN REPEAT CONJ_TAC THENL
8601 [MATCH_MP_TAC CONNECTED_UNION THEN
8602 ASM_SIMP_TAC[CONNECTED_CONTINUOUS_IMAGE; CONTINUOUS_ON_PASTECART;
8603 CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN
8604 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER; EXISTS_IN_IMAGE] THEN
8605 EXISTS_TAC `x2:real^M` THEN ASM SET_TAC[];
8606 REWRITE_TAC[SUBSET; IN_UNION; FORALL_AND_THM; FORALL_IN_IMAGE;
8607 TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
8612 let CONNECTED_PCROSS_EQ = prove
8613 (`!s:real^M->bool t:real^N->bool.
8614 connected (s PCROSS t) <=>
8615 s = {} \/ t = {} \/ connected s /\ connected t`,
8617 ASM_CASES_TAC `s:real^M->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
8618 ASM_CASES_TAC `t:real^N->bool = {}` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
8619 REWRITE_TAC[PCROSS_EMPTY; CONNECTED_EMPTY] THEN
8620 EQ_TAC THEN SIMP_TAC[CONNECTED_PCROSS] THEN
8621 REWRITE_TAC[PCROSS] THEN REPEAT STRIP_TAC THENL
8622 [SUBGOAL_THEN `connected (IMAGE fstcart
8623 {pastecart (x:real^M) (y:real^N) | x IN s /\ y IN t})`
8624 MP_TAC THENL [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE; ALL_TAC];
8625 SUBGOAL_THEN `connected (IMAGE sndcart
8626 {pastecart (x:real^M) (y:real^N) | x IN s /\ y IN t})`
8627 MP_TAC THENL [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE; ALL_TAC]] THEN
8628 ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON; LINEAR_FSTCART; LINEAR_SNDCART] THEN
8629 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
8630 REWRITE_TAC[EXTENSION; IN_IMAGE; EXISTS_PASTECART; IN_ELIM_PASTECART_THM;
8631 FSTCART_PASTECART; SNDCART_PASTECART] THEN
8634 let CLOSURE_PCROSS = prove
8635 (`!s:real^M->bool t:real^N->bool.
8636 closure (s PCROSS t) = (closure s) PCROSS (closure t)`,
8637 REWRITE_TAC[EXTENSION; PCROSS; FORALL_PASTECART] THEN REPEAT GEN_TAC THEN
8638 REWRITE_TAC[CLOSURE_APPROACHABLE; EXISTS_PASTECART; FORALL_PASTECART] THEN
8639 REWRITE_TAC[IN_ELIM_PASTECART_THM; PASTECART_INJ] THEN
8640 REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN
8641 REWRITE_TAC[dist; PASTECART_SUB] THEN EQ_TAC THENL
8642 [MESON_TAC[NORM_LE_PASTECART; REAL_LET_TRANS]; DISCH_TAC] THEN
8643 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8644 FIRST_X_ASSUM(CONJUNCTS_THEN (MP_TAC o SPEC `e / &2`)) THEN
8645 ASM_MESON_TAC[REAL_HALF; NORM_PASTECART_LE; REAL_ARITH
8646 `z <= x + y /\ x < e / &2 /\ y < e / &2 ==> z < e`]);;
8648 let LIMPT_PCROSS = prove
8649 (`!s:real^M->bool t:real^N->bool x y.
8650 x limit_point_of s /\ y limit_point_of t
8651 ==> (pastecart x y) limit_point_of (s PCROSS t)`,
8653 REWRITE_TAC[PCROSS; LIMPT_APPROACHABLE; EXISTS_PASTECART] THEN
8654 REWRITE_TAC[IN_ELIM_PASTECART_THM; PASTECART_INJ; dist; PASTECART_SUB] THEN
8655 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8656 FIRST_X_ASSUM(CONJUNCTS_THEN (MP_TAC o SPEC `e / &2`)) THEN
8657 ASM_MESON_TAC[REAL_HALF; NORM_PASTECART_LE; REAL_ARITH
8658 `z <= x + y /\ x < e / &2 /\ y < e / &2 ==> z < e`]);;
8660 (* ------------------------------------------------------------------------- *)
8661 (* Hence some useful properties follow quite easily. *)
8662 (* ------------------------------------------------------------------------- *)
8664 let CONNECTED_SCALING = prove
8665 (`!s:real^N->bool c. connected s ==> connected (IMAGE (\x. c % x) s)`,
8666 REPEAT STRIP_TAC THEN
8667 MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
8668 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
8669 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
8670 REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
8672 let CONNECTED_NEGATIONS = prove
8673 (`!s:real^N->bool. connected s ==> connected (IMAGE (--) s)`,
8674 REPEAT STRIP_TAC THEN
8675 MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
8676 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
8677 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
8678 REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
8680 let CONNECTED_SUMS = prove
8681 (`!s t:real^N->bool.
8682 connected s /\ connected t ==> connected {x + y | x IN s /\ y IN t}`,
8683 REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CONNECTED_PCROSS) THEN
8684 DISCH_THEN(MP_TAC o ISPEC
8685 `\z. (fstcart z + sndcart z:real^N)` o
8686 MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] CONNECTED_CONTINUOUS_IMAGE)) THEN
8687 SIMP_TAC[CONTINUOUS_ON_ADD; LINEAR_CONTINUOUS_ON; LINEAR_FSTCART;
8688 LINEAR_SNDCART; PCROSS] THEN
8689 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
8690 REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM; EXISTS_PASTECART] THEN
8691 REWRITE_TAC[PASTECART_INJ; FSTCART_PASTECART; SNDCART_PASTECART] THEN
8694 let COMPACT_SCALING = prove
8695 (`!s:real^N->bool c. compact s ==> compact (IMAGE (\x. c % x) s)`,
8696 REPEAT STRIP_TAC THEN
8697 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
8698 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
8699 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
8700 REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
8702 let COMPACT_NEGATIONS = prove
8703 (`!s:real^N->bool. compact s ==> compact (IMAGE (--) s)`,
8704 REPEAT STRIP_TAC THEN
8705 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
8706 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
8707 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
8708 REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
8710 let COMPACT_SUMS = prove
8711 (`!s:real^N->bool t.
8712 compact s /\ compact t ==> compact {x + y | x IN s /\ y IN t}`,
8713 REPEAT STRIP_TAC THEN
8714 SUBGOAL_THEN `{x + y | x IN s /\ y IN t} =
8715 IMAGE (\z. fstcart z + sndcart z :real^N) (s PCROSS t)`
8717 [REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; PCROSS] THEN
8718 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
8719 ASM_MESON_TAC[FSTCART_PASTECART; SNDCART_PASTECART; PASTECART_FST_SND];
8721 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
8722 ASM_SIMP_TAC[COMPACT_PCROSS] THEN
8723 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
8724 REPEAT STRIP_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
8725 REWRITE_TAC[linear; FSTCART_ADD; FSTCART_CMUL; SNDCART_ADD;
8727 CONJ_TAC THEN VECTOR_ARITH_TAC);;
8729 let COMPACT_DIFFERENCES = prove
8730 (`!s:real^N->bool t.
8731 compact s /\ compact t ==> compact {x - y | x IN s /\ y IN t}`,
8732 REPEAT STRIP_TAC THEN
8733 SUBGOAL_THEN `{x - y | x:real^N IN s /\ y IN t} =
8734 {x + y | x IN s /\ y IN (IMAGE (--) t)}`
8735 (fun th -> ASM_SIMP_TAC[th; COMPACT_SUMS; COMPACT_NEGATIONS]) THEN
8736 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE] THEN
8737 ONCE_REWRITE_TAC[VECTOR_ARITH `(x:real^N = --y) <=> (y = --x)`] THEN
8738 SIMP_TAC[VECTOR_SUB; GSYM CONJ_ASSOC; UNWIND_THM2] THEN
8739 MESON_TAC[VECTOR_NEG_NEG]);;
8741 let COMPACT_TRANSLATION_EQ = prove
8742 (`!a s. compact (IMAGE (\x:real^N. a + x) s) <=> compact s`,
8743 REWRITE_TAC[COMPACT_EQ_HEINE_BOREL] THEN GEOM_TRANSLATE_TAC[]);;
8745 let COMPACT_TRANSLATION = prove
8746 (`!s a:real^N. compact s ==> compact (IMAGE (\x. a + x) s)`,
8747 REWRITE_TAC[COMPACT_TRANSLATION_EQ]);;
8749 add_translation_invariants [COMPACT_TRANSLATION_EQ];;
8751 let COMPACT_AFFINITY = prove
8753 compact s ==> compact (IMAGE (\x. a + c % x) s)`,
8754 REPEAT STRIP_TAC THEN
8755 SUBGOAL_THEN `(\x:real^N. a + c % x) = (\x. a + x) o (\x. c % x)`
8756 SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
8757 ASM_SIMP_TAC[IMAGE_o; COMPACT_TRANSLATION; COMPACT_SCALING]);;
8759 (* ------------------------------------------------------------------------- *)
8760 (* Hence we get the following. *)
8761 (* ------------------------------------------------------------------------- *)
8763 let COMPACT_SUP_MAXDISTANCE = prove
8765 compact s /\ ~(s = {})
8766 ==> ?x y. x IN s /\ y IN s /\
8767 !u v. u IN s /\ v IN s ==> norm(u - v) <= norm(x - y)`,
8768 REPEAT STRIP_TAC THEN
8769 MP_TAC(ISPECL [`{x - y:real^N | x IN s /\ y IN s}`; `vec 0:real^N`]
8770 DISTANCE_ATTAINS_SUP) THEN
8772 [ASM_SIMP_TAC[COMPACT_DIFFERENCES] THEN
8773 REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN
8774 ASM_MESON_TAC[MEMBER_NOT_EMPTY];
8775 REWRITE_TAC[IN_ELIM_THM; dist; VECTOR_SUB_RZERO; VECTOR_SUB_LZERO;
8779 (* ------------------------------------------------------------------------- *)
8780 (* We can state this in terms of diameter of a set. *)
8781 (* ------------------------------------------------------------------------- *)
8783 let diameter = new_definition
8786 else sup {norm(x - y) | x IN s /\ y IN s}`;;
8788 let DIAMETER_BOUNDED = prove
8790 ==> (!x:real^N y. x IN s /\ y IN s ==> norm(x - y) <= diameter s) /\
8791 (!d. &0 <= d /\ d < diameter s
8792 ==> ?x y. x IN s /\ y IN s /\ norm(x - y) > d)`,
8793 GEN_TAC THEN DISCH_TAC THEN
8794 ASM_CASES_TAC `s:real^N->bool = {}` THEN
8795 ASM_REWRITE_TAC[diameter; NOT_IN_EMPTY; REAL_LET_ANTISYM] THEN
8796 MP_TAC(SPEC `{norm(x - y:real^N) | x IN s /\ y IN s}` SUP) THEN
8797 ABBREV_TAC `b = sup {norm(x - y:real^N) | x IN s /\ y IN s}` THEN
8798 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
8799 REWRITE_TAC[NOT_IN_EMPTY; real_gt] THEN ANTS_TAC THENL
8800 [CONJ_TAC THENL [ASM_MESON_TAC[MEMBER_NOT_EMPTY]; ALL_TAC];
8801 MESON_TAC[REAL_NOT_LE]] THEN
8802 SIMP_TAC[VECTOR_SUB; LEFT_IMP_EXISTS_THM] THEN
8803 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
8804 MESON_TAC[REAL_ARITH `x <= y + z /\ y <= b /\ z<= b ==> x <= b + b`;
8805 NORM_TRIANGLE; NORM_NEG]);;
8807 let DIAMETER_BOUNDED_BOUND = prove
8808 (`!s x y. bounded s /\ x IN s /\ y IN s ==> norm(x - y) <= diameter s`,
8809 MESON_TAC[DIAMETER_BOUNDED]);;
8811 let DIAMETER_COMPACT_ATTAINED = prove
8813 compact s /\ ~(s = {})
8814 ==> ?x y. x IN s /\ y IN s /\ (norm(x - y) = diameter s)`,
8815 GEN_TAC THEN DISCH_TAC THEN
8816 FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_SUP_MAXDISTANCE) THEN
8817 REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
8818 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
8819 MP_TAC(SPEC `s:real^N->bool` DIAMETER_BOUNDED) THEN
8820 RULE_ASSUM_TAC(REWRITE_RULE[COMPACT_EQ_BOUNDED_CLOSED]) THEN
8821 ASM_REWRITE_TAC[real_gt] THEN STRIP_TAC THEN
8822 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
8823 ASM_MESON_TAC[NORM_POS_LE; REAL_NOT_LT]);;
8825 let DIAMETER_TRANSLATION = prove
8826 (`!a s. diameter (IMAGE (\x. a + x) s) = diameter s`,
8827 REWRITE_TAC[diameter] THEN GEOM_TRANSLATE_TAC[]);;
8829 add_translation_invariants [DIAMETER_TRANSLATION];;
8831 let DIAMETER_LINEAR_IMAGE = prove
8832 (`!f:real^M->real^N s.
8833 linear f /\ (!x. norm(f x) = norm x)
8834 ==> diameter(IMAGE f s) = diameter s`,
8835 REWRITE_TAC[diameter] THEN
8836 REPEAT STRIP_TAC THEN REWRITE_TAC[diameter; IMAGE_EQ_EMPTY] THEN
8837 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN
8838 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
8839 REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM; EXISTS_IN_IMAGE] THEN
8840 ASM_MESON_TAC[LINEAR_SUB]);;
8842 add_linear_invariants [DIAMETER_LINEAR_IMAGE];;
8844 let DIAMETER_EMPTY = prove
8845 (`diameter {} = &0`,
8846 REWRITE_TAC[diameter]);;
8848 let DIAMETER_SING = prove
8849 (`!a. diameter {a} = &0`,
8850 REWRITE_TAC[diameter; NOT_INSERT_EMPTY; IN_SING] THEN
8851 REWRITE_TAC[SET_RULE `{f x y | x = a /\ y = a} = {f a a }`] THEN
8852 REWRITE_TAC[SUP_SING; VECTOR_SUB_REFL; NORM_0]);;
8854 let DIAMETER_POS_LE = prove
8855 (`!s:real^N->bool. bounded s ==> &0 <= diameter s`,
8856 REPEAT STRIP_TAC THEN REWRITE_TAC[diameter] THEN
8857 COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN
8858 MP_TAC(SPEC `{norm(x - y:real^N) | x IN s /\ y IN s}` SUP) THEN
8859 REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL
8860 [CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
8861 FIRST_X_ASSUM(X_CHOOSE_TAC `B:real` o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
8862 EXISTS_TAC `&2 * B` THEN
8863 ASM_SIMP_TAC[NORM_ARITH
8864 `norm x <= B /\ norm y <= B ==> norm(x - y) <= &2 * B`];
8865 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
8866 DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN
8867 DISCH_THEN(MP_TAC o SPECL [`a:real^N`; `a:real^N`] o CONJUNCT1) THEN
8868 ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0]]);;
8870 let DIAMETER_SUBSET = prove
8871 (`!s t:real^N->bool. s SUBSET t /\ bounded t ==> diameter s <= diameter t`,
8872 REPEAT STRIP_TAC THEN
8873 ASM_CASES_TAC `s:real^N->bool = {}` THEN
8874 ASM_SIMP_TAC[DIAMETER_EMPTY; DIAMETER_POS_LE] THEN
8875 ASM_REWRITE_TAC[diameter] THEN
8876 COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
8877 MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN
8878 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
8879 REWRITE_TAC[FORALL_IN_GSPEC] THEN
8880 FIRST_X_ASSUM(X_CHOOSE_TAC `B:real` o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
8881 EXISTS_TAC `&2 * B` THEN
8882 ASM_SIMP_TAC[NORM_ARITH
8883 `norm x <= B /\ norm y <= B ==> norm(x - y) <= &2 * B`]);;
8885 let DIAMETER_CLOSURE = prove
8886 (`!s:real^N->bool. bounded s ==> diameter(closure s) = diameter s`,
8887 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN REPEAT STRIP_TAC THEN
8888 ASM_SIMP_TAC[DIAMETER_SUBSET; BOUNDED_CLOSURE; CLOSURE_SUBSET] THEN
8889 REWRITE_TAC[GSYM REAL_NOT_LT] THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN
8890 DISCH_TAC THEN MP_TAC(ISPEC `closure s:real^N->bool` DIAMETER_BOUNDED) THEN
8891 ABBREV_TAC `d = diameter(closure s) - diameter(s:real^N->bool)` THEN
8892 ASM_SIMP_TAC[BOUNDED_CLOSURE] THEN DISCH_THEN(MP_TAC o
8893 SPEC `diameter(closure(s:real^N->bool)) - d / &2` o CONJUNCT2) THEN
8894 REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC; NOT_EXISTS_THM] THEN
8895 FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIAMETER_POS_LE) THEN
8896 REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
8897 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN
8898 REWRITE_TAC[CLOSURE_APPROACHABLE; CONJ_ASSOC; AND_FORALL_THM] THEN
8899 DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `d / &4`) ASSUME_TAC) THEN
8900 ASM_REWRITE_TAC[REAL_ARITH `&0 < d / &4 <=> &0 < d`] THEN
8901 DISCH_THEN(CONJUNCTS_THEN2
8902 (X_CHOOSE_THEN `u:real^N` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC))
8903 (X_CHOOSE_THEN `v:real^N` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC))) THEN
8904 FIRST_ASSUM(MP_TAC o MATCH_MP DIAMETER_BOUNDED) THEN
8905 DISCH_THEN(MP_TAC o SPECL [`u:real^N`; `v:real^N`] o CONJUNCT1) THEN
8906 ASM_REWRITE_TAC[] THEN REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC);;
8908 let DIAMETER_SUBSET_CBALL_NONEMPTY = prove
8910 bounded s /\ ~(s = {}) ==> ?z. z IN s /\ s SUBSET cball(z,diameter s)`,
8911 REPEAT STRIP_TAC THEN
8912 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
8913 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN
8914 DISCH_TAC THEN ASM_REWRITE_TAC[SUBSET] THEN X_GEN_TAC `b:real^N` THEN
8915 DISCH_TAC THEN REWRITE_TAC[IN_CBALL; dist] THEN
8916 ASM_MESON_TAC[DIAMETER_BOUNDED]);;
8918 let DIAMETER_SUBSET_CBALL = prove
8919 (`!s:real^N->bool. bounded s ==> ?z. s SUBSET cball(z,diameter s)`,
8920 REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN
8921 ASM_MESON_TAC[DIAMETER_SUBSET_CBALL_NONEMPTY; EMPTY_SUBSET]);;
8923 let DIAMETER_EQ_0 = prove
8925 bounded s ==> (diameter s = &0 <=> s = {} \/ ?a. s = {a})`,
8926 REPEAT STRIP_TAC THEN EQ_TAC THEN STRIP_TAC THEN
8927 ASM_REWRITE_TAC[DIAMETER_EMPTY; DIAMETER_SING] THEN
8928 REWRITE_TAC[SET_RULE
8929 `s = {} \/ (?a. s = {a}) <=> !a b. a IN s /\ b IN s ==> a = b`] THEN
8930 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN STRIP_TAC THEN
8931 MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`; `b:real^N`]
8932 DIAMETER_BOUNDED_BOUND) THEN
8933 ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);;
8935 let DIAMETER_LE = prove
8937 (~(s = {}) \/ &0 <= d) /\
8938 (!x y. x IN s /\ y IN s ==> norm(x - y) <= d) ==> diameter s <= d`,
8939 GEN_TAC THEN REWRITE_TAC[diameter] THEN
8940 COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN
8941 STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_LE THEN
8942 CONJ_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[FORALL_IN_GSPEC]]);;
8944 let DIAMETER_CBALL = prove
8945 (`!a:real^N r. diameter(cball(a,r)) = if r < &0 then &0 else &2 * r`,
8946 REPEAT GEN_TAC THEN COND_CASES_TAC THENL
8947 [ASM_MESON_TAC[CBALL_EQ_EMPTY; DIAMETER_EMPTY]; ALL_TAC] THEN
8948 RULE_ASSUM_TAC(REWRITE_RULE[REAL_NOT_LT]) THEN
8949 REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
8950 [MATCH_MP_TAC DIAMETER_LE THEN
8951 ASM_SIMP_TAC[CBALL_EQ_EMPTY; REAL_LE_MUL; REAL_POS; REAL_NOT_LT] THEN
8952 REWRITE_TAC[IN_CBALL] THEN NORM_ARITH_TAC;
8953 MATCH_MP_TAC REAL_LE_TRANS THEN
8954 EXISTS_TAC `norm((a + r % basis 1) - (a - r % basis 1):real^N)` THEN
8956 [REWRITE_TAC[VECTOR_ARITH `(a + r % b) - (a - r % b:real^N) =
8958 SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN
8960 MATCH_MP_TAC DIAMETER_BOUNDED_BOUND THEN
8961 REWRITE_TAC[BOUNDED_CBALL; IN_CBALL] THEN
8962 REWRITE_TAC[NORM_ARITH
8963 `dist(a:real^N,a + b) = norm b /\ dist(a,a - b) = norm b`] THEN
8964 SIMP_TAC[NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN
8965 ASM_REAL_ARITH_TAC]]);;
8967 let DIAMETER_BALL = prove
8968 (`!a:real^N r. diameter(ball(a,r)) = if r < &0 then &0 else &2 * r`,
8969 REPEAT GEN_TAC THEN COND_CASES_TAC THENL
8970 [ASM_SIMP_TAC[BALL_EMPTY; REAL_LT_IMP_LE; DIAMETER_EMPTY]; ALL_TAC] THEN
8971 ASM_CASES_TAC `r = &0` THEN
8972 ASM_SIMP_TAC[BALL_EMPTY; REAL_LE_REFL; DIAMETER_EMPTY; REAL_MUL_RZERO] THEN
8973 MATCH_MP_TAC EQ_TRANS THEN
8974 EXISTS_TAC `diameter(cball(a:real^N,r))` THEN CONJ_TAC THENL
8975 [SUBGOAL_THEN `&0 < r` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
8976 ASM_SIMP_TAC[GSYM CLOSURE_BALL; DIAMETER_CLOSURE; BOUNDED_BALL];
8977 ASM_SIMP_TAC[DIAMETER_CBALL]]);;
8979 let LEBESGUE_COVERING_LEMMA = prove
8980 (`!s:real^N->bool c.
8981 compact s /\ ~(c = {}) /\ s SUBSET UNIONS c /\ (!b. b IN c ==> open b)
8983 !t. t SUBSET s /\ diameter t <= d
8984 ==> ?b. b IN c /\ t SUBSET b`,
8985 REPEAT STRIP_TAC THEN
8986 FIRST_ASSUM(MP_TAC o MATCH_MP HEINE_BOREL_LEMMA) THEN
8987 DISCH_THEN(MP_TAC o SPEC `c:(real^N->bool)->bool`) THEN ASM_SIMP_TAC[] THEN
8988 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `e:real` THEN
8989 STRIP_TAC THEN EXISTS_TAC `e / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN
8990 X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN
8991 ASM_CASES_TAC `t:real^N->bool = {}` THENL [ASM SET_TAC[]; ALL_TAC] THEN
8992 MP_TAC(ISPEC `t:real^N->bool` DIAMETER_SUBSET_CBALL_NONEMPTY) THEN
8994 [ASM_MESON_TAC[BOUNDED_SUBSET; COMPACT_IMP_BOUNDED]; ALL_TAC] THEN
8995 DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN
8996 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
8997 ANTS_TAC THENL [ASM SET_TAC[]; MATCH_MP_TAC MONO_EXISTS] THEN
8998 X_GEN_TAC `b:real^N->bool` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
8999 MATCH_MP_TAC SUBSET_TRANS THEN
9000 EXISTS_TAC `cball(x:real^N,diameter(t:real^N->bool))` THEN
9001 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC SUBSET_TRANS THEN
9002 EXISTS_TAC `ball(x:real^N,e)` THEN ASM_REWRITE_TAC[] THEN
9003 REWRITE_TAC[SUBSET; IN_CBALL; IN_BALL] THEN
9004 MAP_EVERY UNDISCH_TAC [`&0 < e`; `diameter(t:real^N->bool) <= e / &2`] THEN
9007 (* ------------------------------------------------------------------------- *)
9008 (* Related results with closure as the conclusion. *)
9009 (* ------------------------------------------------------------------------- *)
9011 let CLOSED_SCALING = prove
9012 (`!s:real^N->bool c. closed s ==> closed (IMAGE (\x. c % x) s)`,
9014 ASM_CASES_TAC `s :real^N->bool = {}` THEN
9015 ASM_REWRITE_TAC[CLOSED_EMPTY; IMAGE_CLAUSES] THEN
9016 ASM_CASES_TAC `c = &0` THENL
9017 [SUBGOAL_THEN `IMAGE (\x:real^N. c % x) s = {(vec 0)}`
9018 (fun th -> REWRITE_TAC[th; CLOSED_SING]) THEN
9019 ASM_REWRITE_TAC[EXTENSION; IN_IMAGE; IN_SING; VECTOR_MUL_LZERO] THEN
9020 ASM_MESON_TAC[MEMBER_NOT_EMPTY];
9022 REWRITE_TAC[CLOSED_SEQUENTIAL_LIMITS; IN_IMAGE; SKOLEM_THM] THEN
9023 STRIP_TAC THEN X_GEN_TAC `x:num->real^N` THEN X_GEN_TAC `l:real^N` THEN
9024 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
9025 DISCH_THEN(X_CHOOSE_THEN `y:num->real^N` MP_TAC) THEN
9026 REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN
9027 EXISTS_TAC `inv(c) % l :real^N` THEN
9028 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; VECTOR_MUL_LID] THEN
9029 FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `\n:num. inv(c) % x n:real^N` THEN
9030 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
9031 [ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; VECTOR_MUL_LID];
9032 MATCH_MP_TAC LIM_CMUL THEN
9033 FIRST_ASSUM(fun th -> REWRITE_TAC[SYM(SPEC_ALL th)]) THEN
9034 ASM_REWRITE_TAC[ETA_AX]]);;
9036 let CLOSED_NEGATIONS = prove
9037 (`!s:real^N->bool. closed s ==> closed (IMAGE (--) s)`,
9039 SUBGOAL_THEN `IMAGE (--) s = IMAGE (\x:real^N. --(&1) % x) s`
9040 SUBST1_TAC THEN SIMP_TAC[CLOSED_SCALING] THEN
9041 REWRITE_TAC[VECTOR_ARITH `--(&1) % x = --x`] THEN REWRITE_TAC[ETA_AX]);;
9043 let COMPACT_CLOSED_SUMS = prove
9044 (`!s:real^N->bool t.
9045 compact s /\ closed t ==> closed {x + y | x IN s /\ y IN t}`,
9047 REWRITE_TAC[compact; IN_ELIM_THM; CLOSED_SEQUENTIAL_LIMITS] THEN
9048 STRIP_TAC THEN X_GEN_TAC `f:num->real^N` THEN X_GEN_TAC `l:real^N` THEN
9049 REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM] THEN
9050 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
9051 DISCH_THEN(X_CHOOSE_THEN `a:num->real^N` MP_TAC) THEN
9052 DISCH_THEN(X_CHOOSE_THEN `b:num->real^N` STRIP_ASSUME_TAC) THEN
9053 FIRST_X_ASSUM(MP_TAC o check(is_imp o concl) o SPEC `a:num->real^N`) THEN
9054 ASM_REWRITE_TAC[] THEN
9055 DISCH_THEN(X_CHOOSE_THEN `la:real^N` (X_CHOOSE_THEN `sub:num->num`
9056 STRIP_ASSUME_TAC)) THEN
9057 MAP_EVERY EXISTS_TAC [`la:real^N`; `l - la:real^N`] THEN
9058 ASM_REWRITE_TAC[VECTOR_ARITH `a + (b - a) = b:real^N`] THEN
9059 FIRST_X_ASSUM MATCH_MP_TAC THEN
9060 EXISTS_TAC `\n. (f o (sub:num->num)) n - (a o sub) n:real^N` THEN
9061 CONJ_TAC THENL [ASM_REWRITE_TAC[VECTOR_ADD_SUB; o_THM]; ALL_TAC] THEN
9062 MATCH_MP_TAC LIM_SUB THEN ASM_SIMP_TAC[LIM_SUBSEQUENCE; ETA_AX]);;
9064 let CLOSED_COMPACT_SUMS = prove
9065 (`!s:real^N->bool t.
9066 closed s /\ compact t ==> closed {x + y | x IN s /\ y IN t}`,
9068 SUBGOAL_THEN `{x + y:real^N | x IN s /\ y IN t} = {y + x | y IN t /\ x IN s}`
9069 SUBST1_TAC THEN SIMP_TAC[COMPACT_CLOSED_SUMS] THEN
9070 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN MESON_TAC[VECTOR_ADD_SYM]);;
9072 let COMPACT_CLOSED_DIFFERENCES = prove
9073 (`!s:real^N->bool t.
9074 compact s /\ closed t ==> closed {x - y | x IN s /\ y IN t}`,
9075 REPEAT STRIP_TAC THEN
9076 SUBGOAL_THEN `{x - y | x:real^N IN s /\ y IN t} =
9077 {x + y | x IN s /\ y IN (IMAGE (--) t)}`
9078 (fun th -> ASM_SIMP_TAC[th; COMPACT_CLOSED_SUMS; CLOSED_NEGATIONS]) THEN
9079 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE] THEN
9080 ONCE_REWRITE_TAC[VECTOR_ARITH `(x:real^N = --y) <=> (y = --x)`] THEN
9081 SIMP_TAC[VECTOR_SUB; GSYM CONJ_ASSOC; UNWIND_THM2] THEN
9082 MESON_TAC[VECTOR_NEG_NEG]);;
9084 let CLOSED_COMPACT_DIFFERENCES = prove
9085 (`!s:real^N->bool t.
9086 closed s /\ compact t ==> closed {x - y | x IN s /\ y IN t}`,
9087 REPEAT STRIP_TAC THEN
9088 SUBGOAL_THEN `{x - y | x:real^N IN s /\ y IN t} =
9089 {x + y | x IN s /\ y IN (IMAGE (--) t)}`
9090 (fun th -> ASM_SIMP_TAC[th; CLOSED_COMPACT_SUMS; COMPACT_NEGATIONS]) THEN
9091 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE] THEN
9092 ONCE_REWRITE_TAC[VECTOR_ARITH `(x:real^N = --y) <=> (y = --x)`] THEN
9093 SIMP_TAC[VECTOR_SUB; GSYM CONJ_ASSOC; UNWIND_THM2] THEN
9094 MESON_TAC[VECTOR_NEG_NEG]);;
9096 let CLOSED_TRANSLATION_EQ = prove
9097 (`!a s. closed (IMAGE (\x:real^N. a + x) s) <=> closed s`,
9098 REWRITE_TAC[closed] THEN GEOM_TRANSLATE_TAC[]);;
9100 let CLOSED_TRANSLATION = prove
9101 (`!s a:real^N. closed s ==> closed (IMAGE (\x. a + x) s)`,
9102 REWRITE_TAC[CLOSED_TRANSLATION_EQ]);;
9104 add_translation_invariants [CLOSED_TRANSLATION_EQ];;
9106 let COMPLETE_TRANSLATION_EQ = prove
9107 (`!a s. complete(IMAGE (\x:real^N. a + x) s) <=> complete s`,
9108 REWRITE_TAC[COMPLETE_EQ_CLOSED; CLOSED_TRANSLATION_EQ]);;
9110 add_translation_invariants [COMPLETE_TRANSLATION_EQ];;
9112 let TRANSLATION_UNIV = prove
9113 (`!a. IMAGE (\x. a + x) (:real^N) = (:real^N)`,
9114 CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN GEOM_TRANSLATE_TAC[]);;
9116 let TRANSLATION_DIFF = prove
9117 (`!s t:real^N->bool.
9118 IMAGE (\x. a + x) (s DIFF t) =
9119 (IMAGE (\x. a + x) s) DIFF (IMAGE (\x. a + x) t)`,
9120 REWRITE_TAC[EXTENSION; IN_DIFF; IN_IMAGE] THEN
9121 ONCE_REWRITE_TAC[VECTOR_ARITH `x:real^N = a + y <=> y = x - a`] THEN
9122 REWRITE_TAC[UNWIND_THM2]);;
9124 let CLOSURE_TRANSLATION = prove
9125 (`!a s. closure(IMAGE (\x:real^N. a + x) s) = IMAGE (\x. a + x) (closure s)`,
9126 REWRITE_TAC[CLOSURE_INTERIOR] THEN GEOM_TRANSLATE_TAC[]);;
9128 add_translation_invariants [CLOSURE_TRANSLATION];;
9130 let FRONTIER_TRANSLATION = prove
9131 (`!a s. frontier(IMAGE (\x:real^N. a + x) s) = IMAGE (\x. a + x) (frontier s)`,
9132 REWRITE_TAC[frontier] THEN GEOM_TRANSLATE_TAC[]);;
9134 add_translation_invariants [FRONTIER_TRANSLATION];;
9136 (* ------------------------------------------------------------------------- *)
9137 (* Separation between points and sets. *)
9138 (* ------------------------------------------------------------------------- *)
9140 let SEPARATE_POINT_CLOSED = prove
9142 closed s /\ ~(a IN s)
9143 ==> ?d. &0 < d /\ !x. x IN s ==> d <= dist(a,x)`,
9144 REPEAT STRIP_TAC THEN
9145 ASM_CASES_TAC `s:real^N->bool = {}` THENL
9146 [EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY; REAL_LT_01];
9148 MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`] DISTANCE_ATTAINS_INF) THEN
9149 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN X_GEN_TAC `b:real^N` THEN
9150 STRIP_TAC THEN EXISTS_TAC `dist(a:real^N,b)` THEN
9151 ASM_MESON_TAC[DIST_POS_LT]);;
9153 let SEPARATE_COMPACT_CLOSED = prove
9154 (`!s t:real^N->bool.
9155 compact s /\ closed t /\ s INTER t = {}
9156 ==> ?d. &0 < d /\ !x y. x IN s /\ y IN t ==> d <= dist(x,y)`,
9157 REPEAT STRIP_TAC THEN
9158 MP_TAC(ISPECL [`{x - y:real^N | x IN s /\ y IN t}`; `vec 0:real^N`]
9159 SEPARATE_POINT_CLOSED) THEN
9160 ASM_SIMP_TAC[COMPACT_CLOSED_DIFFERENCES; IN_ELIM_THM] THEN
9161 REWRITE_TAC[VECTOR_ARITH `vec 0 = x - y <=> x = y`] THEN
9162 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
9163 MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[LEFT_IMP_EXISTS_THM] THEN
9164 MESON_TAC[NORM_ARITH `dist(vec 0,x - y) = dist(x,y)`]);;
9166 let SEPARATE_CLOSED_COMPACT = prove
9167 (`!s t:real^N->bool.
9168 closed s /\ compact t /\ s INTER t = {}
9169 ==> ?d. &0 < d /\ !x y. x IN s /\ y IN t ==> d <= dist(x,y)`,
9170 ONCE_REWRITE_TAC[DIST_SYM; INTER_COMM] THEN
9171 MESON_TAC[SEPARATE_COMPACT_CLOSED]);;
9173 (* ------------------------------------------------------------------------- *)
9174 (* Representing sets as the union of a chain of compact sets. *)
9175 (* ------------------------------------------------------------------------- *)
9177 let CLOSED_UNION_COMPACT_SUBSETS = prove
9179 ==> ?f:num->real^N->bool.
9180 (!n. compact(f n)) /\
9181 (!n. (f n) SUBSET s) /\
9182 (!n. (f n) SUBSET f(n + 1)) /\
9183 UNIONS {f n | n IN (:num)} = s /\
9184 (!k. compact k /\ k SUBSET s
9185 ==> ?N. !n. n >= N ==> k SUBSET (f n))`,
9186 REPEAT STRIP_TAC THEN
9187 EXISTS_TAC `\n. s INTER cball(vec 0:real^N,&n)` THEN
9188 ASM_SIMP_TAC[INTER_SUBSET; COMPACT_CBALL; CLOSED_INTER_COMPACT] THEN
9189 REPEAT CONJ_TAC THENL
9190 [GEN_TAC THEN MATCH_MP_TAC(SET_RULE
9191 `t SUBSET u ==> s INTER t SUBSET s INTER u`) THEN
9192 REWRITE_TAC[SUBSET_BALLS; DIST_REFL; GSYM REAL_OF_NUM_ADD] THEN
9194 REWRITE_TAC[EXTENSION; UNIONS_GSPEC; IN_ELIM_THM; IN_UNIV; IN_INTER] THEN
9195 X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_CBALL_0] THEN
9196 MESON_TAC[REAL_ARCH_SIMPLE];
9197 X_GEN_TAC `k:real^N->bool` THEN SIMP_TAC[SUBSET_INTER] THEN
9198 REPEAT STRIP_TAC THEN
9199 FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN DISCH_THEN
9200 (MP_TAC o SPEC `vec 0:real^N` o MATCH_MP BOUNDED_SUBSET_CBALL) THEN
9201 DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN
9202 MP_TAC(ISPEC `r:real` REAL_ARCH_SIMPLE) THEN MATCH_MP_TAC MONO_EXISTS THEN
9203 X_GEN_TAC `N:num` THEN REWRITE_TAC[GSYM REAL_OF_NUM_GE] THEN
9205 REPEAT STRIP_TAC THEN
9206 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
9208 REWRITE_TAC[SUBSET_BALLS; DIST_REFL] THEN ASM_REAL_ARITH_TAC]);;
9210 let OPEN_UNION_COMPACT_SUBSETS = prove
9212 ==> ?f:num->real^N->bool.
9213 (!n. compact(f n)) /\
9214 (!n. (f n) SUBSET s) /\
9215 (!n. (f n) SUBSET interior(f(n + 1))) /\
9216 UNIONS {f n | n IN (:num)} = s /\
9217 (!k. compact k /\ k SUBSET s
9218 ==> ?N. !n. n >= N ==> k SUBSET (f n))`,
9219 GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL
9220 [DISCH_TAC THEN EXISTS_TAC `(\n. {}):num->real^N->bool` THEN
9221 ASM_SIMP_TAC[EMPTY_SUBSET; SUBSET_EMPTY; COMPACT_EMPTY] THEN
9222 REWRITE_TAC[EXTENSION; UNIONS_GSPEC; IN_ELIM_THM; NOT_IN_EMPTY];
9223 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
9224 DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN STRIP_TAC] THEN
9225 MATCH_MP_TAC(MESON[]
9226 `(!f. p1 f /\ p3 f /\ p4 f ==> p5 f) /\
9227 (?f. p1 f /\ p2 f /\ p3 f /\ (p2 f ==> p4 f))
9228 ==> ?f. p1 f /\ p2 f /\ p3 f /\ p4 f /\ p5 f`) THEN
9230 [X_GEN_TAC `f:num->real^N->bool` THEN STRIP_TAC THEN
9231 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
9232 X_GEN_TAC `k:real^N->bool` THEN STRIP_TAC THEN
9233 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL]) THEN
9234 DISCH_THEN(MP_TAC o SPEC `{interior(f n):real^N->bool | n IN (:num)}`) THEN
9235 REWRITE_TAC[FORALL_IN_GSPEC; OPEN_INTERIOR] THEN ANTS_TAC THENL
9236 [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
9238 REWRITE_TAC[SUBSET; UNIONS_GSPEC; IN_ELIM_THM] THEN ASM SET_TAC[];
9239 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
9240 REWRITE_TAC[SIMPLE_IMAGE; EXISTS_FINITE_SUBSET_IMAGE] THEN
9241 REWRITE_TAC[SUBSET_UNIV] THEN
9242 DISCH_THEN(X_CHOOSE_THEN `i:num->bool` STRIP_ASSUME_TAC) THEN
9243 FIRST_ASSUM(MP_TAC o SPEC `\n:num. n` o
9244 MATCH_MP UPPER_BOUND_FINITE_SET) THEN
9245 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
9246 REWRITE_TAC[GE] THEN DISCH_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
9247 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
9249 REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_IMAGE] THEN
9250 X_GEN_TAC `m:num` THEN DISCH_TAC THEN MATCH_MP_TAC SUBSET_TRANS THEN
9251 EXISTS_TAC `(f:num->real^N->bool) m` THEN
9252 REWRITE_TAC[INTERIOR_SUBSET] THEN
9253 SUBGOAL_THEN `!m n. m <= n ==> (f:num->real^N->bool) m SUBSET f n`
9254 (fun th -> ASM_MESON_TAC[th; LE_TRANS]) THEN
9255 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
9256 ASM_MESON_TAC[SUBSET; ADD1; INTERIOR_SUBSET]];
9258 `\n. cball(a,&n) DIFF
9259 {x + e | x IN (:real^N) DIFF s /\ e IN ball(vec 0,inv(&n + &1))}` THEN
9260 REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
9261 [X_GEN_TAC `n:num` THEN MATCH_MP_TAC COMPACT_DIFF THEN
9262 SIMP_TAC[COMPACT_CBALL; OPEN_SUMS; OPEN_BALL];
9263 GEN_TAC THEN MATCH_MP_TAC(SET_RULE
9264 `(UNIV DIFF s) SUBSET t ==> c DIFF t SUBSET s`) THEN
9265 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
9266 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
9267 MAP_EVERY EXISTS_TAC [`x:real^N`; `vec 0:real^N`] THEN
9268 ASM_REWRITE_TAC[VECTOR_ADD_RID; CENTRE_IN_BALL; REAL_LT_INV_EQ] THEN
9270 GEN_TAC THEN REWRITE_TAC[INTERIOR_DIFF] THEN MATCH_MP_TAC(SET_RULE
9271 `s SUBSET s' /\ t' SUBSET t ==> (s DIFF t) SUBSET (s' DIFF t')`) THEN
9273 [REWRITE_TAC[INTERIOR_CBALL; SUBSET; IN_BALL; IN_CBALL] THEN
9274 REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC;
9275 MATCH_MP_TAC SUBSET_TRANS THEN
9276 EXISTS_TAC `{x + e | x IN (:real^N) DIFF s /\
9277 e IN cball(vec 0,inv(&n + &2))}` THEN
9279 [MATCH_MP_TAC CLOSURE_MINIMAL THEN
9280 ASM_SIMP_TAC[CLOSED_COMPACT_SUMS; COMPACT_CBALL;
9281 GSYM OPEN_CLOSED] THEN
9282 MATCH_MP_TAC(SET_RULE
9284 ==> {f x y | x IN s /\ y IN t} SUBSET
9285 {f x y | x IN s /\ y IN t'}`) THEN
9286 REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL; GSYM REAL_OF_NUM_ADD] THEN
9288 MATCH_MP_TAC(SET_RULE
9290 ==> {f x y | x IN s /\ y IN t} SUBSET
9291 {f x y | x IN s /\ y IN t'}`) THEN
9292 REWRITE_TAC[SUBSET; IN_BALL; IN_CBALL; GSYM REAL_OF_NUM_ADD] THEN
9293 GEN_TAC THEN MATCH_MP_TAC(REAL_ARITH
9294 `a < b ==> x <= a ==> x < b`) THEN
9295 MATCH_MP_TAC REAL_LT_INV2 THEN REAL_ARITH_TAC]];
9296 DISCH_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
9297 ASM_REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC] THEN
9298 REWRITE_TAC[SUBSET; UNIONS_GSPEC; IN_UNIV; IN_ELIM_THM] THEN
9299 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_DIFF] THEN
9300 REWRITE_TAC[IN_ELIM_THM; IN_UNIV; IN_BALL_0] THEN
9301 REWRITE_TAC[VECTOR_ARITH `x:real^N = y + e <=> e = x - y`] THEN
9302 REWRITE_TAC[TAUT `(p /\ q) /\ r <=> r /\ p /\ q`; UNWIND_THM2] THEN
9303 REWRITE_TAC[MESON[] `~(?x. ~P x /\ Q x) <=> !x. Q x ==> P x`] THEN
9304 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN
9305 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
9306 ASM_REWRITE_TAC[SUBSET; IN_BALL; dist] THEN
9307 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
9308 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN
9309 DISCH_THEN(X_CHOOSE_THEN `N1:num` STRIP_ASSUME_TAC) THEN
9310 MP_TAC(ISPEC `norm(x - a:real^N)` REAL_ARCH_SIMPLE) THEN
9311 DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN EXISTS_TAC `N1 + N2:num` THEN
9313 [REWRITE_TAC[IN_CBALL] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
9314 UNDISCH_TAC `norm(x - a:real^N) <= &N2` THEN
9315 REWRITE_TAC[dist; GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC;
9316 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
9317 SUBGOAL_THEN `inv(&(N1 + N2) + &1) <= inv(&N1)` MP_TAC THENL
9318 [MATCH_MP_TAC REAL_LE_INV2 THEN
9319 ASM_SIMP_TAC[REAL_OF_NUM_LT; LE_1] THEN
9320 REWRITE_TAC[GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC;
9321 ASM_REAL_ARITH_TAC]]]]);;
9323 (* ------------------------------------------------------------------------- *)
9324 (* A cute way of denoting open and closed intervals using overloading. *)
9325 (* ------------------------------------------------------------------------- *)
9327 let open_interval = new_definition
9328 `open_interval(a:real^N,b:real^N) =
9329 {x:real^N | !i. 1 <= i /\ i <= dimindex(:N)
9330 ==> a$i < x$i /\ x$i < b$i}`;;
9332 let closed_interval = new_definition
9333 `closed_interval(l:(real^N#real^N)list) =
9334 {x:real^N | !i. 1 <= i /\ i <= dimindex(:N)
9335 ==> FST(HD l)$i <= x$i /\ x$i <= SND(HD l)$i}`;;
9337 make_overloadable "interval" `:A`;;
9339 overload_interface("interval",`open_interval`);;
9340 overload_interface("interval",`closed_interval`);;
9342 let interval = prove
9343 (`(interval (a,b) = {x:real^N | !i. 1 <= i /\ i <= dimindex(:N)
9344 ==> a$i < x$i /\ x$i < b$i}) /\
9345 (interval [a,b] = {x:real^N | !i. 1 <= i /\ i <= dimindex(:N)
9346 ==> a$i <= x$i /\ x$i <= b$i})`,
9347 REWRITE_TAC[open_interval; closed_interval; HD; FST; SND]);;
9349 let IN_INTERVAL = prove
9351 x IN interval (a,b) <=>
9352 !i. 1 <= i /\ i <= dimindex(:N)
9353 ==> a$i < x$i /\ x$i < b$i) /\
9355 x IN interval [a,b] <=>
9356 !i. 1 <= i /\ i <= dimindex(:N)
9357 ==> a$i <= x$i /\ x$i <= b$i)`,
9358 REWRITE_TAC[interval; IN_ELIM_THM]);;
9360 let IN_INTERVAL_REFLECT = prove
9361 (`(!a b x. (--x) IN interval[--b,--a] <=> x IN interval[a,b]) /\
9362 (!a b x. (--x) IN interval(--b,--a) <=> x IN interval(a,b))`,
9363 SIMP_TAC[IN_INTERVAL; REAL_LT_NEG2; REAL_LE_NEG2; VECTOR_NEG_COMPONENT] THEN
9366 let REFLECT_INTERVAL = prove
9367 (`(!a b:real^N. IMAGE (--) (interval[a,b]) = interval[--b,--a]) /\
9368 (!a b:real^N. IMAGE (--) (interval(a,b)) = interval(--b,--a))`,
9369 REPEAT STRIP_TAC THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
9370 REWRITE_TAC[IN_INTERVAL_REFLECT] THEN MESON_TAC[VECTOR_NEG_NEG]);;
9372 let INTERVAL_EQ_EMPTY = prove
9373 (`((interval [a:real^N,b] = {}) <=>
9374 ?i. 1 <= i /\ i <= dimindex(:N) /\ b$i < a$i) /\
9375 ((interval (a:real^N,b) = {}) <=>
9376 ?i. 1 <= i /\ i <= dimindex(:N) /\ b$i <= a$i)`,
9377 REWRITE_TAC[EXTENSION; IN_INTERVAL; NOT_IN_EMPTY] THEN
9378 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; GSYM CONJ_ASSOC] THEN
9379 CONJ_TAC THEN EQ_TAC THENL
9380 [MESON_TAC[REAL_LE_REFL; REAL_NOT_LE];
9381 MESON_TAC[REAL_LE_TRANS; REAL_NOT_LE];
9383 MESON_TAC[REAL_LT_TRANS; REAL_NOT_LT]] THEN
9384 SUBGOAL_THEN `!a b. ?c. a < b ==> a < c /\ c < b`
9385 (MP_TAC o REWRITE_RULE[SKOLEM_THM]) THENL
9386 [MESON_TAC[REAL_LT_BETWEEN]; ALL_TAC] THEN
9387 DISCH_THEN(X_CHOOSE_TAC `mid:real->real->real`) THEN
9388 DISCH_THEN(MP_TAC o SPEC
9389 `(lambda i. mid ((a:real^N)$i) ((b:real^N)$i)):real^N`) THEN
9390 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> ~(a /\ b ==> ~c)`] THEN
9391 SIMP_TAC[LAMBDA_BETA] THEN ASM_MESON_TAC[REAL_NOT_LT]);;
9393 let INTERVAL_NE_EMPTY = prove
9394 (`(~(interval [a:real^N,b] = {}) <=>
9395 !i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= b$i) /\
9396 (~(interval (a:real^N,b) = {}) <=>
9397 !i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i)`,
9398 REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN MESON_TAC[REAL_NOT_LE]);;
9400 let SUBSET_INTERVAL_IMP = prove
9401 (`((!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i)
9402 ==> interval[c,d] SUBSET interval[a:real^N,b]) /\
9403 ((!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < c$i /\ d$i < b$i)
9404 ==> interval[c,d] SUBSET interval(a:real^N,b)) /\
9405 ((!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i)
9406 ==> interval(c,d) SUBSET interval[a:real^N,b]) /\
9407 ((!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i)
9408 ==> interval(c,d) SUBSET interval(a:real^N,b))`,
9409 REWRITE_TAC[SUBSET; IN_INTERVAL] THEN REPEAT CONJ_TAC THEN
9410 DISCH_TAC THEN GEN_TAC THEN POP_ASSUM MP_TAC THEN
9411 REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN
9412 GEN_TAC THEN DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
9413 ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;
9415 let INTERVAL_SING = prove
9416 (`interval[a,a] = {a} /\ interval(a,a) = {}`,
9417 REWRITE_TAC[EXTENSION; IN_SING; NOT_IN_EMPTY; IN_INTERVAL] THEN
9418 REWRITE_TAC[REAL_LE_ANTISYM; REAL_LT_ANTISYM; CART_EQ; EQ_SYM_EQ] THEN
9419 MESON_TAC[DIMINDEX_GE_1; LE_REFL]);;
9421 let SUBSET_INTERVAL = prove
9422 (`(interval[c,d] SUBSET interval[a:real^N,b] <=>
9423 (!i. 1 <= i /\ i <= dimindex(:N) ==> c$i <= d$i)
9424 ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i)) /\
9425 (interval[c,d] SUBSET interval(a:real^N,b) <=>
9426 (!i. 1 <= i /\ i <= dimindex(:N) ==> c$i <= d$i)
9427 ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < c$i /\ d$i < b$i)) /\
9428 (interval(c,d) SUBSET interval[a:real^N,b] <=>
9429 (!i. 1 <= i /\ i <= dimindex(:N) ==> c$i < d$i)
9430 ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i)) /\
9431 (interval(c,d) SUBSET interval(a:real^N,b) <=>
9432 (!i. 1 <= i /\ i <= dimindex(:N) ==> c$i < d$i)
9433 ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= c$i /\ d$i <= b$i))`,
9435 (`(!x:real^N. (!i. 1 <= i /\ i <= dimindex(:N) ==> Q i (x$i))
9436 ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> R i (x$i)))
9437 ==> (!i. 1 <= i /\ i <= dimindex(:N) ==> ?y. Q i y)
9438 ==> !i y. 1 <= i /\ i <= dimindex(:N) /\ Q i y ==> R i y`,
9439 DISCH_TAC THEN REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
9440 DISCH_THEN(X_CHOOSE_THEN `f:num->real` STRIP_ASSUME_TAC) THEN
9441 REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o
9442 SPEC `(lambda j. if j = i then y else f j):real^N`) THEN
9443 SIMP_TAC[LAMBDA_BETA] THEN ASM_MESON_TAC[]) in
9444 REPEAT STRIP_TAC THEN
9446 `(~q ==> p) /\ (q ==> (p <=> r)) ==> (p <=> q ==> r)`) THEN
9448 [DISCH_TAC THEN MATCH_MP_TAC(SET_RULE `s = {} ==> s SUBSET t`) THEN
9449 REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN ASM_MESON_TAC[REAL_NOT_LT];
9451 DISCH_TAC THEN EQ_TAC THEN REWRITE_TAC[SUBSET_INTERVAL_IMP] THEN
9452 REWRITE_TAC[SUBSET; IN_INTERVAL] THEN
9453 DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN ANTS_TAC THENL
9454 [ASM_MESON_TAC[REAL_LT_BETWEEN; REAL_LE_BETWEEN]; ALL_TAC] THEN
9455 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN
9456 DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
9457 FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
9458 ASM_REWRITE_TAC[] THEN POP_ASSUM_LIST(K ALL_TAC) THEN STRIP_TAC)
9460 [ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL];
9461 ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL];
9462 ALL_TAC; ALL_TAC] THEN
9463 (REPEAT STRIP_TAC THENL
9464 [FIRST_X_ASSUM(MP_TAC o SPEC
9465 `((c:real^N)$i + min ((a:real^N)$i) ((d:real^N)$i)) / &2`) THEN
9466 POP_ASSUM MP_TAC THEN REAL_ARITH_TAC;
9467 FIRST_X_ASSUM(MP_TAC o SPEC
9468 `(max ((b:real^N)$i) ((c:real^N)$i) + (d:real^N)$i) / &2`) THEN
9469 POP_ASSUM MP_TAC THEN REAL_ARITH_TAC]));;
9471 let DISJOINT_INTERVAL = prove
9473 (interval[a,b] INTER interval[c,d] = {} <=>
9474 ?i. 1 <= i /\ i <= dimindex(:N) /\
9475 (b$i < a$i \/ d$i < c$i \/ b$i < c$i \/ d$i < a$i)) /\
9476 (interval[a,b] INTER interval(c,d) = {} <=>
9477 ?i. 1 <= i /\ i <= dimindex(:N) /\
9478 (b$i < a$i \/ d$i <= c$i \/ b$i <= c$i \/ d$i <= a$i)) /\
9479 (interval(a,b) INTER interval[c,d] = {} <=>
9480 ?i. 1 <= i /\ i <= dimindex(:N) /\
9481 (b$i <= a$i \/ d$i < c$i \/ b$i <= c$i \/ d$i <= a$i)) /\
9482 (interval(a,b) INTER interval(c,d) = {} <=>
9483 ?i. 1 <= i /\ i <= dimindex(:N) /\
9484 (b$i <= a$i \/ d$i <= c$i \/ b$i <= c$i \/ d$i <= a$i))`,
9485 REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL; NOT_IN_EMPTY] THEN
9486 REWRITE_TAC[AND_FORALL_THM; NOT_FORALL_THM] THEN
9487 REWRITE_TAC[TAUT `~((p ==> q) /\ (p ==> r)) <=> p /\ (~q \/ ~r)`] THEN
9488 REWRITE_TAC[DE_MORGAN_THM] THEN REPEAT STRIP_TAC THEN
9490 [DISCH_THEN(MP_TAC o SPEC
9491 `(lambda i. (max ((a:real^N)$i) ((c:real^N)$i) +
9492 min ((b:real^N)$i) ((d:real^N)$i)) / &2):real^N`) THEN
9493 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
9494 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
9495 ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC;
9496 DISCH_THEN(fun th -> GEN_TAC THEN MP_TAC th) THEN
9497 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN SIMP_TAC[] THEN
9500 let ENDS_IN_INTERVAL = prove
9501 (`(!a b. a IN interval[a,b] <=> ~(interval[a,b] = {})) /\
9502 (!a b. b IN interval[a,b] <=> ~(interval[a,b] = {})) /\
9503 (!a b. ~(a IN interval(a,b))) /\
9504 (!a b. ~(b IN interval(a,b)))`,
9505 REWRITE_TAC[IN_INTERVAL; INTERVAL_NE_EMPTY] THEN
9506 REWRITE_TAC[REAL_LE_REFL; REAL_LT_REFL] THEN
9507 MESON_TAC[DIMINDEX_GE_1; LE_REFL]);;
9509 let ENDS_IN_UNIT_INTERVAL = prove
9510 (`vec 0 IN interval[vec 0,vec 1] /\
9511 vec 1 IN interval[vec 0,vec 1] /\
9512 ~(vec 0 IN interval(vec 0,vec 1)) /\
9513 ~(vec 1 IN interval(vec 0,vec 1))`,
9514 REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY; VEC_COMPONENT] THEN
9515 REWRITE_TAC[REAL_POS]);;
9517 let INTER_INTERVAL = prove
9518 (`interval[a,b] INTER interval[c,d] =
9519 interval[(lambda i. max (a$i) (c$i)),(lambda i. min (b$i) (d$i))]`,
9520 REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL] THEN
9521 SIMP_TAC[LAMBDA_BETA; REAL_MAX_LE; REAL_LE_MIN] THEN MESON_TAC[]);;
9523 let INTERVAL_OPEN_SUBSET_CLOSED = prove
9524 (`!a b. interval(a,b) SUBSET interval[a,b]`,
9525 REWRITE_TAC[SUBSET; IN_INTERVAL] THEN MESON_TAC[REAL_LT_IMP_LE]);;
9527 let OPEN_INTERVAL_LEMMA = prove
9528 (`!a b x. a < x /\ x < b
9529 ==> ?d. &0 < d /\ !x'. abs(x' - x) < d ==> a < x' /\ x' < b`,
9530 REPEAT STRIP_TAC THEN
9531 EXISTS_TAC `min (x - a) (b - x)` THEN REWRITE_TAC[REAL_LT_MIN] THEN
9532 ASM_REAL_ARITH_TAC);;
9534 let OPEN_INTERVAL = prove
9535 (`!a:real^N b. open(interval (a,b))`,
9536 REPEAT GEN_TAC THEN REWRITE_TAC[open_def; interval; IN_ELIM_THM] THEN
9537 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
9538 SUBGOAL_THEN `!i. 1 <= i /\ i <= dimindex(:N)
9540 !x'. abs(x' - (x:real^N)$i) < d
9541 ==> (a:real^N)$i < x' /\ x' < (b:real^N)$i`
9542 MP_TAC THENL [ASM_SIMP_TAC[OPEN_INTERVAL_LEMMA]; ALL_TAC] THEN
9543 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
9544 REWRITE_TAC[SKOLEM_THM] THEN
9545 DISCH_THEN(X_CHOOSE_THEN `d:num->real` STRIP_ASSUME_TAC) THEN
9546 EXISTS_TAC `inf (IMAGE d (1..dimindex(:N)))` THEN
9547 SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; FINITE_NUMSEG;
9548 IMAGE_EQ_EMPTY; NOT_INSERT_EMPTY; NUMSEG_EMPTY;
9549 ARITH_RULE `n < 1 <=> (n = 0)`; DIMINDEX_NONZERO] THEN
9550 REWRITE_TAC[FORALL_IN_IMAGE; IN_NUMSEG; dist] THEN
9551 ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LET_TRANS; VECTOR_SUB_COMPONENT]);;
9553 let CLOSED_INTERVAL = prove
9554 (`!a:real^N b. closed(interval [a,b])`,
9555 REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE; IN_INTERVAL] THEN
9556 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THENL
9557 [FIRST_X_ASSUM(MP_TAC o SPEC `(a:real^N)$i - (x:real^N)$i`);
9558 FIRST_X_ASSUM(MP_TAC o SPEC `(x:real^N)$i - (b:real^N)$i`)] THEN
9559 ASM_REWRITE_TAC[REAL_SUB_LT] THEN
9560 DISCH_THEN(X_CHOOSE_THEN `z:real^N` MP_TAC) THEN
9561 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
9562 REWRITE_TAC[dist; REAL_NOT_LT] THEN
9563 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((z - x :real^N)$i)` THEN
9564 ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
9565 ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
9566 ASM_SIMP_TAC[REAL_ARITH `x < a /\ a <= z ==> a - x <= abs(z - x)`;
9567 REAL_ARITH `z <= b /\ b < x ==> x - b <= abs(z - x)`]);;
9569 let INTERIOR_CLOSED_INTERVAL = prove
9570 (`!a:real^N b. interior(interval [a,b]) = interval (a,b)`,
9571 REPEAT GEN_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
9573 MATCH_MP_TAC INTERIOR_MAXIMAL THEN
9574 REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED; OPEN_INTERVAL]] THEN
9575 REWRITE_TAC[interior; SUBSET; IN_INTERVAL; IN_ELIM_THM] THEN
9576 X_GEN_TAC `x:real^N` THEN
9577 DISCH_THEN(X_CHOOSE_THEN `s:real^N->bool` STRIP_ASSUME_TAC) THEN
9578 X_GEN_TAC `i:num` THEN STRIP_TAC THEN
9579 ASM_SIMP_TAC[REAL_LT_LE] THEN REPEAT STRIP_TAC THEN
9580 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [open_def]) THEN
9581 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
9582 DISCH_THEN(X_CHOOSE_THEN `e:real` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THENL
9583 [(let t = `x - (e / &2) % basis i :real^N` in
9584 DISCH_THEN(MP_TAC o SPEC t) THEN FIRST_X_ASSUM(MP_TAC o SPEC t));
9585 (let t = `x + (e / &2) % basis i :real^N` in
9586 DISCH_THEN(MP_TAC o SPEC t) THEN FIRST_X_ASSUM(MP_TAC o SPEC t))] THEN
9587 REWRITE_TAC[dist; VECTOR_ADD_SUB; VECTOR_ARITH `x - y - x = --y:real^N`] THEN
9588 ASM_SIMP_TAC[NORM_MUL; NORM_BASIS; NORM_NEG; REAL_MUL_RID;
9589 REAL_ARITH `&0 < e ==> abs(e / &2) < e`] THEN
9590 MATCH_MP_TAC(TAUT `~b ==> (a ==> b) ==> ~a`) THEN
9591 REWRITE_TAC[NOT_FORALL_THM] THEN EXISTS_TAC `i:num` THEN
9592 ASM_SIMP_TAC[DE_MORGAN_THM; VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT] THENL
9593 [DISJ1_TAC THEN REWRITE_TAC[REAL_ARITH `a <= a - b <=> ~(&0 < b)`];
9594 DISJ2_TAC THEN REWRITE_TAC[REAL_ARITH `a + b <= a <=> ~(&0 < b)`]] THEN
9595 ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; basis; LAMBDA_BETA; REAL_MUL_RID] THEN
9596 ASM_REWRITE_TAC[REAL_HALF]);;
9598 let INTERIOR_INTERVAL = prove
9599 (`(!a b. interior(interval[a,b]) = interval(a,b)) /\
9600 (!a b. interior(interval(a,b)) = interval(a,b))`,
9601 SIMP_TAC[INTERIOR_CLOSED_INTERVAL; INTERIOR_OPEN; OPEN_INTERVAL]);;
9603 let BOUNDED_CLOSED_INTERVAL = prove
9604 (`!a b:real^N. bounded (interval [a,b])`,
9605 REPEAT STRIP_TAC THEN REWRITE_TAC[bounded; interval] THEN
9606 EXISTS_TAC `sum(1..dimindex(:N))
9607 (\i. abs((a:real^N)$i) + abs((b:real^N)$i))` THEN
9608 X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_ELIM_THM] THEN
9609 STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
9610 EXISTS_TAC `sum(1..dimindex(:N)) (\i. abs((x:real^N)$i))` THEN
9611 REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_LE THEN
9612 ASM_SIMP_TAC[FINITE_NUMSEG; IN_NUMSEG; REAL_ARITH
9613 `a <= x /\ x <= b ==> abs(x) <= abs(a) + abs(b)`]);;
9615 let BOUNDED_INTERVAL = prove
9616 (`(!a b. bounded (interval [a,b])) /\ (!a b. bounded (interval (a,b)))`,
9617 MESON_TAC[BOUNDED_CLOSED_INTERVAL; BOUNDED_SUBSET;
9618 INTERVAL_OPEN_SUBSET_CLOSED]);;
9620 let NOT_INTERVAL_UNIV = prove
9621 (`(!a b. ~(interval[a,b] = UNIV)) /\
9622 (!a b. ~(interval(a,b) = UNIV))`,
9623 MESON_TAC[BOUNDED_INTERVAL; NOT_BOUNDED_UNIV]);;
9625 let COMPACT_INTERVAL = prove
9626 (`!a b. compact (interval [a,b])`,
9627 SIMP_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_INTERVAL; CLOSED_INTERVAL]);;
9629 let OPEN_INTERVAL_MIDPOINT = prove
9631 ~(interval(a,b) = {}) ==> (inv(&2) % (a + b)) IN interval(a,b)`,
9632 REWRITE_TAC[INTERVAL_NE_EMPTY; IN_INTERVAL] THEN
9633 SIMP_TAC[VECTOR_MUL_COMPONENT; VECTOR_ADD_COMPONENT] THEN
9634 REPEAT GEN_TAC THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
9635 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN REAL_ARITH_TAC);;
9637 let OPEN_CLOSED_INTERVAL_CONVEX = prove
9638 (`!a b x y:real^N e.
9639 x IN interval(a,b) /\ y IN interval[a,b] /\ &0 < e /\ e <= &1
9640 ==> (e % x + (&1 - e) % y) IN interval(a,b)`,
9641 REPEAT GEN_TAC THEN MATCH_MP_TAC(TAUT
9642 `(c /\ d ==> a /\ b ==> e) ==> a /\ b /\ c /\ d ==> e`) THEN
9643 STRIP_TAC THEN REWRITE_TAC[IN_INTERVAL; AND_FORALL_THM] THEN
9644 SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
9645 MATCH_MP_TAC MONO_FORALL THEN
9646 GEN_TAC THEN DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
9647 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
9648 SUBST1_TAC(REAL_ARITH `(a:real^N)$i = e * a$i + (&1 - e) * a$i`) THEN
9649 SUBST1_TAC(REAL_ARITH `(b:real^N)$i = e * b$i + (&1 - e) * b$i`) THEN
9650 CONJ_TAC THEN MATCH_MP_TAC REAL_LTE_ADD2 THEN
9651 ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_LE_LMUL; REAL_SUB_LE]);;
9653 let CLOSURE_OPEN_INTERVAL = prove
9655 ~(interval(a,b) = {}) ==> closure(interval(a,b)) = interval[a,b]`,
9656 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
9657 [MATCH_MP_TAC CLOSURE_MINIMAL THEN
9658 REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED; CLOSED_INTERVAL];
9660 REWRITE_TAC[SUBSET; closure; IN_UNION] THEN X_GEN_TAC `x:real^N` THEN
9661 DISCH_TAC THEN MATCH_MP_TAC(TAUT `(~b ==> c) ==> b \/ c`) THEN DISCH_TAC THEN
9662 REWRITE_TAC[IN_ELIM_THM; LIMPT_SEQUENTIAL] THEN
9663 ABBREV_TAC `(c:real^N) = inv(&2) % (a + b)` THEN
9664 EXISTS_TAC `\n. (x:real^N) + inv(&n + &1) % (c - x)` THEN CONJ_TAC THENL
9665 [X_GEN_TAC `n:num` THEN REWRITE_TAC[IN_DELETE] THEN
9666 REWRITE_TAC[VECTOR_ARITH `x + a = x <=> a = vec 0`] THEN
9667 REWRITE_TAC[VECTOR_MUL_EQ_0; REAL_INV_EQ_0] THEN
9668 REWRITE_TAC[VECTOR_SUB_EQ; REAL_ARITH `~(&n + &1 = &0)`] THEN
9669 CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[OPEN_INTERVAL_MIDPOINT]] THEN
9670 REWRITE_TAC[VECTOR_ARITH `x + a % (y - x) = a % y + (&1 - a) % x`] THEN
9671 MATCH_MP_TAC OPEN_CLOSED_INTERVAL_CONVEX THEN
9672 CONJ_TAC THENL [ASM_MESON_TAC[OPEN_INTERVAL_MIDPOINT]; ALL_TAC] THEN
9673 ASM_REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
9674 MATCH_MP_TAC REAL_INV_LE_1 THEN REAL_ARITH_TAC;
9676 GEN_REWRITE_TAC LAND_CONV [VECTOR_ARITH `x:real^N = x + &0 % (c - x)`] THEN
9677 MATCH_MP_TAC LIM_ADD THEN REWRITE_TAC[LIM_CONST] THEN
9678 MATCH_MP_TAC LIM_VMUL THEN REWRITE_TAC[LIM_CONST] THEN
9679 REWRITE_TAC[LIM_SEQUENTIALLY; o_THM; DIST_LIFT; REAL_SUB_RZERO] THEN
9680 X_GEN_TAC `e:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_ARCH_INV] THEN
9681 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
9682 STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
9683 REWRITE_TAC[REAL_ABS_INV] THEN MATCH_MP_TAC REAL_LET_TRANS THEN
9684 EXISTS_TAC `inv(&N)` THEN ASM_REWRITE_TAC[] THEN
9685 MATCH_MP_TAC REAL_LE_INV2 THEN UNDISCH_TAC `N:num <= n` THEN
9686 UNDISCH_TAC `~(N = 0)` THEN
9687 REWRITE_TAC[GSYM LT_NZ; GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_LT] THEN
9690 let CLOSURE_INTERVAL = prove
9691 (`(!a b. closure(interval[a,b]) = interval[a,b]) /\
9692 (!a b. closure(interval(a,b)) =
9693 if interval(a,b) = {} then {} else interval[a,b])`,
9694 SIMP_TAC[CLOSURE_CLOSED; CLOSED_INTERVAL] THEN REPEAT GEN_TAC THEN
9695 COND_CASES_TAC THEN ASM_SIMP_TAC[CLOSURE_OPEN_INTERVAL; CLOSURE_EMPTY]);;
9697 let BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC = prove
9698 (`!s:real^N->bool. bounded s ==> ?a. s SUBSET interval(--a,a)`,
9699 REWRITE_TAC[BOUNDED_POS; LEFT_IMP_EXISTS_THM] THEN
9700 MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `B:real`] THEN STRIP_TAC THEN
9701 EXISTS_TAC `(lambda i. B + &1):real^N` THEN
9702 REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
9703 SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; REAL_BOUNDS_LT; VECTOR_NEG_COMPONENT] THEN
9704 ASM_MESON_TAC[COMPONENT_LE_NORM;
9705 REAL_ARITH `x <= y ==> a <= x ==> a < y + &1`]);;
9707 let BOUNDED_SUBSET_OPEN_INTERVAL = prove
9708 (`!s:real^N->bool. bounded s ==> ?a b. s SUBSET interval(a,b)`,
9709 MESON_TAC[BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC]);;
9711 let BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC = prove
9712 (`!s:real^N->bool. bounded s ==> ?a. s SUBSET interval[--a,a]`,
9714 DISCH_THEN(MP_TAC o MATCH_MP BOUNDED_SUBSET_OPEN_INTERVAL_SYMMETRIC) THEN
9715 MATCH_MP_TAC MONO_EXISTS THEN
9716 SIMP_TAC[IN_BALL; IN_INTERVAL; SUBSET; REAL_LT_IMP_LE]);;
9718 let BOUNDED_SUBSET_CLOSED_INTERVAL = prove
9719 (`!s:real^N->bool. bounded s ==> ?a b. s SUBSET interval[a,b]`,
9720 MESON_TAC[BOUNDED_SUBSET_CLOSED_INTERVAL_SYMMETRIC]);;
9722 let FRONTIER_CLOSED_INTERVAL = prove
9723 (`!a b. frontier(interval[a,b]) = interval[a,b] DIFF interval(a,b)`,
9724 SIMP_TAC[frontier; INTERIOR_CLOSED_INTERVAL; CLOSURE_CLOSED;
9727 let FRONTIER_OPEN_INTERVAL = prove
9728 (`!a b. frontier(interval(a,b)) =
9729 if interval(a,b) = {} then {}
9730 else interval[a,b] DIFF interval(a,b)`,
9731 REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[FRONTIER_EMPTY] THEN
9732 ASM_SIMP_TAC[frontier; CLOSURE_OPEN_INTERVAL; INTERIOR_OPEN;
9735 let INTER_INTERVAL_MIXED_EQ_EMPTY = prove
9737 ~(interval(c,d) = {})
9738 ==> (interval(a,b) INTER interval[c,d] = {} <=>
9739 interval(a,b) INTER interval(c,d) = {})`,
9740 SIMP_TAC[GSYM CLOSURE_OPEN_INTERVAL; OPEN_INTER_CLOSURE_EQ_EMPTY;
9743 let INTERVAL_TRANSLATION = prove
9744 (`(!c a b. interval[c + a,c + b] = IMAGE (\x. c + x) (interval[a,b])) /\
9745 (!c a b. interval(c + a,c + b) = IMAGE (\x. c + x) (interval(a,b)))`,
9746 REWRITE_TAC[interval] THEN CONJ_TAC THEN GEOM_TRANSLATE_TAC[] THEN
9747 REWRITE_TAC[VECTOR_ADD_COMPONENT; REAL_LT_LADD; REAL_LE_LADD]);;
9749 add_translation_invariants
9750 [CONJUNCT1 INTERVAL_TRANSLATION; CONJUNCT2 INTERVAL_TRANSLATION];;
9752 let EMPTY_AS_INTERVAL = prove
9753 (`{} = interval[vec 1,vec 0]`,
9754 SIMP_TAC[EXTENSION; NOT_IN_EMPTY; IN_INTERVAL; VEC_COMPONENT] THEN
9755 GEN_TAC THEN DISCH_THEN(MP_TAC o SPEC `1`) THEN
9756 REWRITE_TAC[LE_REFL; DIMINDEX_GE_1] THEN REAL_ARITH_TAC);;
9758 let UNIT_INTERVAL_NONEMPTY = prove
9759 (`~(interval[vec 0:real^N,vec 1] = {}) /\
9760 ~(interval(vec 0:real^N,vec 1) = {})`,
9761 SIMP_TAC[INTERVAL_NE_EMPTY; VEC_COMPONENT; REAL_LT_01; REAL_POS]);;
9763 let IMAGE_STRETCH_INTERVAL = prove
9765 IMAGE (\x. lambda k. m(k) * x$k) (interval[a,b]) =
9766 if interval[a,b] = {} then {}
9767 else interval[(lambda k. min (m(k) * a$k) (m(k) * b$k)):real^N,
9768 (lambda k. max (m(k) * a$k) (m(k) * b$k))]`,
9769 REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[IMAGE_CLAUSES] THEN
9770 ASM_SIMP_TAC[EXTENSION; IN_IMAGE; CART_EQ; IN_INTERVAL; AND_FORALL_THM;
9771 TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`;
9772 LAMBDA_BETA; GSYM LAMBDA_SKOLEM] THEN
9773 X_GEN_TAC `x:real^N` THEN MATCH_MP_TAC(MESON[]
9774 `(!x. p x ==> (q x <=> r x))
9775 ==> ((!x. p x ==> q x) <=> (!x. p x ==> r x))`) THEN
9776 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INTERVAL_NE_EMPTY]) THEN
9777 MATCH_MP_TAC MONO_FORALL THEN
9778 X_GEN_TAC `k:num` THEN ASM_CASES_TAC `1 <= k /\ k <= dimindex(:N)` THEN
9779 ASM_REWRITE_TAC[] THEN ASM_CASES_TAC `(m:num->real) k = &0` THENL
9780 [ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MAX_ACI; REAL_MIN_ACI] THEN
9781 ASM_MESON_TAC[REAL_LE_ANTISYM; REAL_LE_REFL];
9783 ASM_SIMP_TAC[REAL_FIELD `~(m = &0) ==> (x = m * y <=> y = x / m)`] THEN
9784 REWRITE_TAC[UNWIND_THM2] THEN FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP
9785 (REAL_ARITH `~(z = &0) ==> &0 < z \/ &0 < --z`))
9788 ONCE_REWRITE_TAC[GSYM REAL_LE_NEG2] THEN
9789 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
9790 REWRITE_TAC[REAL_ARITH `--(max a b) = min (--a) (--b)`;
9791 REAL_ARITH `--(min a b) = max (--a) (--b)`; real_div;
9792 GSYM REAL_MUL_RNEG; GSYM REAL_INV_NEG] THEN
9793 REWRITE_TAC[GSYM real_div]] THEN
9794 ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ] THEN
9795 ASM_SIMP_TAC[real_min; real_max; REAL_LE_LMUL_EQ; REAL_LE_RMUL_EQ] THEN
9798 let INTERVAL_IMAGE_STRETCH_INTERVAL = prove
9799 (`!a b:real^N m. ?u v:real^N.
9800 IMAGE (\x. lambda k. m k * x$k) (interval[a,b]) = interval[u,v]`,
9801 REWRITE_TAC[IMAGE_STRETCH_INTERVAL] THEN MESON_TAC[EMPTY_AS_INTERVAL]);;
9803 let CLOSED_INTERVAL_IMAGE_UNIT_INTERVAL = prove
9805 ~(interval[a,b] = {})
9806 ==> interval[a,b] = IMAGE (\x:real^N. a + x)
9807 (IMAGE (\x. (lambda i. (b$i - a$i) * x$i))
9808 (interval[vec 0:real^N,vec 1]))`,
9809 REWRITE_TAC[INTERVAL_NE_EMPTY] THEN REPEAT STRIP_TAC THEN
9810 REWRITE_TAC[IMAGE_STRETCH_INTERVAL; UNIT_INTERVAL_NONEMPTY] THEN
9811 REWRITE_TAC[GSYM INTERVAL_TRANSLATION] THEN
9812 REWRITE_TAC[EXTENSION; IN_INTERVAL] THEN
9813 SIMP_TAC[LAMBDA_BETA; VECTOR_ADD_COMPONENT; VEC_COMPONENT] THEN
9814 GEN_TAC THEN REWRITE_TAC[REAL_MUL_RZERO; REAL_MUL_RID] THEN
9815 MATCH_MP_TAC(MESON[] `(!x. P x <=> Q x) ==> ((!x. P x) <=> (!x. Q x))`) THEN
9816 POP_ASSUM MP_TAC THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN
9817 ASM_CASES_TAC `1 <= i /\ i <= dimindex(:N)` THEN ASM_REWRITE_TAC[] THEN
9820 let SUMS_INTERVALS = prove
9822 ~(interval[a,b] = {}) /\ ~(interval[c,d] = {})
9823 ==> {x + y | x IN interval[a,b] /\ y IN interval[c,d]} =
9824 interval[a+c,b+d]) /\
9826 ~(interval(a,b) = {}) /\ ~(interval(c,d) = {})
9827 ==> {x + y | x IN interval(a,b) /\ y IN interval(c,d)} =
9828 interval(a+c,b+d))`,
9829 CONJ_TAC THEN REPEAT GEN_TAC THEN REWRITE_TAC[INTERVAL_NE_EMPTY] THEN
9830 STRIP_TAC THEN REWRITE_TAC[EXTENSION; IN_INTERVAL; IN_ELIM_THM] THEN
9831 REWRITE_TAC[TAUT `(a /\ b) /\ c <=> c /\ a /\ b`] THEN
9832 REWRITE_TAC[VECTOR_ARITH `x:real^N = y + z <=> z = x - y`] THEN
9833 REWRITE_TAC[UNWIND_THM2; VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT] THEN
9834 (X_GEN_TAC `x:real^N` THEN EQ_TAC THENL
9835 [DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC);
9837 REWRITE_TAC[AND_FORALL_THM; GSYM LAMBDA_SKOLEM;
9838 TAUT `(p ==> q) /\ (p ==> r) <=> p ==> q /\ r`] THEN
9839 REWRITE_TAC[REAL_ARITH
9840 `((a <= y /\ y <= b) /\ c <= x - y /\ x - y <= d <=>
9841 max a (x - d) <= y /\ y <= min b (x - c)) /\
9842 ((a < y /\ y < b) /\ c < x - y /\ x - y < d <=>
9843 max a (x - d) < y /\ y < min b (x - c))`] THEN
9844 REWRITE_TAC[GSYM REAL_LE_BETWEEN; GSYM REAL_LT_BETWEEN]] THEN
9845 X_GEN_TAC `i:num` THEN STRIP_TAC THEN
9846 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN
9847 ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC));;
9849 let PCROSS_INTERVAL = prove
9850 (`!a b:real^M c d:real^N.
9851 interval[a,b] PCROSS interval[c,d] =
9852 interval[pastecart a c,pastecart b d]`,
9853 REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN
9854 REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_PASTECART_THM] THEN
9855 SIMP_TAC[IN_INTERVAL; pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM] THEN
9856 MAP_EVERY X_GEN_TAC [`x:real^M`; `y:real^N`] THEN EQ_TAC THEN STRIP_TAC THENL
9857 [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
9858 COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN
9859 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC;
9860 CONJ_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THENL
9861 [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
9862 DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC;
9863 FIRST_X_ASSUM(MP_TAC o SPEC `i + dimindex(:M)`) THEN
9864 COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD_SUB] THENL
9866 DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC]]]);;
9868 let OPEN_CONTAINS_INTERVAL,OPEN_CONTAINS_OPEN_INTERVAL = (CONJ_PAIR o prove)
9871 !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval[a,b] SUBSET s) /\
9874 !x. x IN s ==> ?a b. x IN interval(a,b) /\ interval(a,b) SUBSET s)`,
9875 REWRITE_TAC[AND_FORALL_THM] THEN GEN_TAC THEN
9877 `(q ==> r) /\ (r ==> p) /\ (p ==> q) ==> (p <=> q) /\ (p <=> r)`) THEN
9878 REPEAT CONJ_TAC THENL
9879 [MESON_TAC[SUBSET_TRANS; INTERVAL_OPEN_SUBSET_CLOSED];
9880 DISCH_TAC THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN
9881 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
9882 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
9883 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
9884 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN STRIP_TAC THEN
9885 MP_TAC(ISPEC `interval(a:real^N,b)` OPEN_CONTAINS_BALL) THEN
9886 REWRITE_TAC[OPEN_INTERVAL] THEN
9887 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
9888 MATCH_MP_TAC MONO_EXISTS THEN
9889 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9890 ASM_MESON_TAC[SUBSET_TRANS; INTERVAL_OPEN_SUBSET_CLOSED];
9891 DISCH_TAC THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
9892 FIRST_ASSUM(MP_TAC o SPEC `x:real^N` o
9893 GEN_REWRITE_RULE I [OPEN_CONTAINS_CBALL]) THEN
9894 ASM_REWRITE_TAC[] THEN
9895 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
9896 EXISTS_TAC `x - e / &(dimindex(:N)) % vec 1:real^N` THEN
9897 EXISTS_TAC `x + e / &(dimindex(:N)) % vec 1:real^N` THEN
9898 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
9899 `b SUBSET s ==> x IN i /\ j SUBSET b ==> x IN i /\ j SUBSET s`)) THEN
9900 SIMP_TAC[IN_INTERVAL; VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; IN_CBALL;
9901 VEC_COMPONENT; VECTOR_ADD_COMPONENT; SUBSET; REAL_MUL_RID] THEN
9902 REWRITE_TAC[REAL_ARITH `x - e < x /\ x < x + e <=> &0 < e`;
9903 REAL_ARITH `x - e <= y /\ y <= x + e <=> abs(x - y) <= e`] THEN
9904 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1] THEN
9905 X_GEN_TAC `y:real^N` THEN REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT] THEN
9906 DISCH_TAC THEN REWRITE_TAC[dist] THEN
9907 MATCH_MP_TAC REAL_LE_TRANS THEN
9908 EXISTS_TAC `sum(1..dimindex(:N)) (\i. abs((x - y:real^N)$i))` THEN
9909 REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_BOUND_GEN THEN
9910 ASM_SIMP_TAC[CARD_NUMSEG_1; IN_NUMSEG; FINITE_NUMSEG] THEN
9911 REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1]]);;
9913 let DIAMETER_INTERVAL = prove
9915 diameter(interval[a,b]) =
9916 if interval[a,b] = {} then &0 else norm(b - a)) /\
9918 diameter(interval(a,b)) =
9919 if interval(a,b) = {} then &0 else norm(b - a))`,
9920 REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN
9921 ASM_CASES_TAC `interval[a:real^N,b] = {}` THENL
9922 [ASM_MESON_TAC[INTERVAL_OPEN_SUBSET_CLOSED; SUBSET_EMPTY; DIAMETER_EMPTY];
9923 ASM_REWRITE_TAC[]] THEN
9924 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
9925 [REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
9926 ASM_SIMP_TAC[DIAMETER_BOUNDED_BOUND;
9927 ENDS_IN_INTERVAL; BOUNDED_INTERVAL] THEN
9928 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
9929 `diameter(cball(inv(&2) % (a + b):real^N,norm(b - a) / &2))` THEN
9931 [MATCH_MP_TAC DIAMETER_SUBSET THEN REWRITE_TAC[BOUNDED_CBALL] THEN
9932 REWRITE_TAC[SUBSET; IN_INTERVAL; IN_CBALL] THEN
9933 GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[dist] THEN
9934 REWRITE_TAC[GSYM NORM_MUL; REAL_ARITH `x / &2 = abs(inv(&2)) * x`] THEN
9935 MATCH_MP_TAC NORM_LE_COMPONENTWISE THEN
9936 X_GEN_TAC `i:num` THEN DISCH_TAC THEN
9937 FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
9938 ASM_REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_SUB_COMPONENT;
9939 VECTOR_MUL_COMPONENT] THEN
9941 REWRITE_TAC[DIAMETER_CBALL] THEN NORM_ARITH_TAC];
9942 DISCH_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[DIAMETER_EMPTY] THEN
9943 SUBGOAL_THEN `interval[a:real^N,b] = closure(interval(a,b))`
9944 SUBST_ALL_TAC THEN ASM_REWRITE_TAC[CLOSURE_INTERVAL] THEN
9945 ASM_MESON_TAC[DIAMETER_CLOSURE; BOUNDED_INTERVAL]]);;
9947 (* ------------------------------------------------------------------------- *)
9948 (* Some special cases for intervals in R^1. *)
9949 (* ------------------------------------------------------------------------- *)
9951 let INTERVAL_CASES_1 = prove
9952 (`!x:real^1. x IN interval[a,b] ==> x IN interval(a,b) \/ (x = a) \/ (x = b)`,
9953 REWRITE_TAC[CART_EQ; IN_INTERVAL; FORALL_DIMINDEX_1] THEN REAL_ARITH_TAC);;
9955 let IN_INTERVAL_1 = prove
9957 (x IN interval[a,b] <=> drop a <= drop x /\ drop x <= drop b) /\
9958 (x IN interval(a,b) <=> drop a < drop x /\ drop x < drop b)`,
9959 REWRITE_TAC[IN_INTERVAL; drop; CONJ_ASSOC; DIMINDEX_1; LE_ANTISYM] THEN
9962 let INTERVAL_EQ_EMPTY_1 = prove
9964 (interval[a,b] = {} <=> drop b < drop a) /\
9965 (interval(a,b) = {} <=> drop b <= drop a)`,
9966 REWRITE_TAC[INTERVAL_EQ_EMPTY; drop; CONJ_ASSOC; DIMINDEX_1; LE_ANTISYM] THEN
9969 let INTERVAL_NE_EMPTY_1 = prove
9970 (`(!a b:real^1. ~(interval[a,b] = {}) <=> drop a <= drop b) /\
9971 (!a b:real^1. ~(interval(a,b) = {}) <=> drop a < drop b)`,
9972 REWRITE_TAC[INTERVAL_EQ_EMPTY_1] THEN REAL_ARITH_TAC);;
9974 let SUBSET_INTERVAL_1 = prove
9976 (interval[a,b] SUBSET interval[c,d] <=>
9978 drop c <= drop a /\ drop a <= drop b /\ drop b <= drop d) /\
9979 (interval[a,b] SUBSET interval(c,d) <=>
9981 drop c < drop a /\ drop a <= drop b /\ drop b < drop d) /\
9982 (interval(a,b) SUBSET interval[c,d] <=>
9984 drop c <= drop a /\ drop a < drop b /\ drop b <= drop d) /\
9985 (interval(a,b) SUBSET interval(c,d) <=>
9987 drop c <= drop a /\ drop a < drop b /\ drop b <= drop d)`,
9988 REWRITE_TAC[SUBSET_INTERVAL; FORALL_1; DIMINDEX_1; drop] THEN
9991 let EQ_INTERVAL_1 = prove
9993 (interval[a,b] = interval[c,d] <=>
9994 drop b < drop a /\ drop d < drop c \/
9995 drop a = drop c /\ drop b = drop d)`,
9996 REWRITE_TAC[SET_RULE `s = t <=> s SUBSET t /\ t SUBSET s`] THEN
9997 REWRITE_TAC[SUBSET_INTERVAL_1] THEN REAL_ARITH_TAC);;
9999 let DISJOINT_INTERVAL_1 = prove
10001 (interval[a,b] INTER interval[c,d] = {} <=>
10002 drop b < drop a \/ drop d < drop c \/
10003 drop b < drop c \/ drop d < drop a) /\
10004 (interval[a,b] INTER interval(c,d) = {} <=>
10005 drop b < drop a \/ drop d <= drop c \/
10006 drop b <= drop c \/ drop d <= drop a) /\
10007 (interval(a,b) INTER interval[c,d] = {} <=>
10008 drop b <= drop a \/ drop d < drop c \/
10009 drop b <= drop c \/ drop d <= drop a) /\
10010 (interval(a,b) INTER interval(c,d) = {} <=>
10011 drop b <= drop a \/ drop d <= drop c \/
10012 drop b <= drop c \/ drop d <= drop a)`,
10013 REWRITE_TAC[DISJOINT_INTERVAL; CONJ_ASSOC; DIMINDEX_1; LE_ANTISYM;
10014 UNWIND_THM1; drop]);;
10016 let OPEN_CLOSED_INTERVAL_1 = prove
10017 (`!a b:real^1. interval(a,b) = interval[a,b] DIFF {a,b}`,
10018 REWRITE_TAC[EXTENSION; IN_INTERVAL_1; IN_DIFF; IN_INSERT; NOT_IN_EMPTY] THEN
10019 REWRITE_TAC[GSYM DROP_EQ] THEN REAL_ARITH_TAC);;
10021 let CLOSED_OPEN_INTERVAL_1 = prove
10022 (`!a b:real^1. drop a <= drop b ==> interval[a,b] = interval(a,b) UNION {a,b}`,
10023 REWRITE_TAC[EXTENSION; IN_INTERVAL_1; IN_UNION; IN_INSERT; NOT_IN_EMPTY] THEN
10024 REWRITE_TAC[GSYM DROP_EQ] THEN REAL_ARITH_TAC);;
10027 (`!x:real^1 r. cball(x,r) = interval[x - lift r,x + lift r] /\
10028 ball(x,r) = interval(x - lift r,x + lift r)`,
10029 REWRITE_TAC[EXTENSION; IN_BALL; IN_CBALL; IN_INTERVAL_1] THEN
10030 REWRITE_TAC[dist; NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP; DROP_ADD] THEN
10033 let SPHERE_1 = prove
10034 (`!a:real^1 r. sphere(a,r) = if r < &0 then {} else {a - lift r,a + lift r}`,
10035 REPEAT GEN_TAC THEN REWRITE_TAC[sphere] THEN COND_CASES_TAC THEN
10036 REWRITE_TAC[DIST_REAL; GSYM drop; FORALL_DROP] THEN
10037 REWRITE_TAC[EXTENSION; IN_INSERT; NOT_IN_EMPTY; IN_ELIM_THM] THEN
10038 REWRITE_TAC[GSYM DROP_EQ; DROP_ADD; DROP_SUB; LIFT_DROP] THEN
10039 ASM_REAL_ARITH_TAC);;
10041 let FINITE_SPHERE_1 = prove
10042 (`!a:real^1 r. FINITE(sphere(a,r))`,
10043 REPEAT GEN_TAC THEN REWRITE_TAC[SPHERE_1] THEN
10044 MESON_TAC[FINITE_INSERT; FINITE_EMPTY]);;
10046 let FINITE_INTERVAL_1 = prove
10047 (`(!a b. FINITE(interval[a,b]) <=> drop b <= drop a) /\
10048 (!a b. FINITE(interval(a,b)) <=> drop b <= drop a)`,
10049 REWRITE_TAC[OPEN_CLOSED_INTERVAL_1] THEN
10050 REWRITE_TAC[SET_RULE `s DIFF {a,b} = s DELETE a DELETE b`] THEN
10051 REWRITE_TAC[FINITE_DELETE] THEN REPEAT GEN_TAC THEN
10052 SUBGOAL_THEN `interval[a,b] = IMAGE lift {x | drop a <= x /\ x <= drop b}`
10054 [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
10055 CONJ_TAC THENL [MESON_TAC[LIFT_DROP]; ALL_TAC] THEN
10056 REWRITE_TAC[IN_INTERVAL_1; IN_ELIM_THM; LIFT_DROP];
10057 SIMP_TAC[FINITE_IMAGE_INJ_EQ; LIFT_EQ; FINITE_REAL_INTERVAL]]);;
10059 let BALL_INTERVAL = prove
10060 (`!x:real^1 e. ball(x,e) = interval(x - lift e,x + lift e)`,
10061 REWRITE_TAC[EXTENSION; IN_BALL; IN_INTERVAL_1; DIST_REAL] THEN
10062 REWRITE_TAC[GSYM drop; DROP_SUB; DROP_ADD; LIFT_DROP] THEN REAL_ARITH_TAC);;
10064 let CBALL_INTERVAL = prove
10065 (`!x:real^1 e. cball(x,e) = interval[x - lift e,x + lift e]`,
10066 REWRITE_TAC[EXTENSION; IN_CBALL; IN_INTERVAL_1; DIST_REAL] THEN
10067 REWRITE_TAC[GSYM drop; DROP_SUB; DROP_ADD; LIFT_DROP] THEN REAL_ARITH_TAC);;
10069 let BALL_INTERVAL_0 = prove
10070 (`!e. ball(vec 0:real^1,e) = interval(--lift e,lift e)`,
10071 GEN_TAC THEN REWRITE_TAC[BALL_INTERVAL] THEN AP_TERM_TAC THEN
10072 BINOP_TAC THEN VECTOR_ARITH_TAC);;
10074 let CBALL_INTERVAL_0 = prove
10075 (`!e. cball(vec 0:real^1,e) = interval[--lift e,lift e]`,
10076 GEN_TAC THEN REWRITE_TAC[CBALL_INTERVAL] THEN AP_TERM_TAC THEN
10077 AP_THM_TAC THEN AP_TERM_TAC THEN BINOP_TAC THEN VECTOR_ARITH_TAC);;
10079 let INTER_INTERVAL_1 = prove
10081 interval[a,b] INTER interval[c,d] =
10082 interval[lift(max (drop a) (drop c)),lift(min (drop b) (drop d))]`,
10083 REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL_1; real_max; real_min] THEN
10084 REPEAT GEN_TAC THEN
10085 REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[LIFT_DROP]) THEN
10086 ASM_REAL_ARITH_TAC);;
10088 let CLOSED_DIFF_OPEN_INTERVAL_1 = prove
10090 interval[a,b] DIFF interval(a,b) =
10091 if interval[a,b] = {} then {} else {a,b}`,
10092 REWRITE_TAC[EXTENSION; IN_DIFF; INTERVAL_EQ_EMPTY_1; IN_INTERVAL_1] THEN
10093 REPEAT GEN_TAC THEN COND_CASES_TAC THEN
10094 ASM_REWRITE_TAC[NOT_IN_EMPTY; IN_INSERT; NOT_IN_EMPTY] THEN
10095 REWRITE_TAC[GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC);;
10097 (* ------------------------------------------------------------------------- *)
10098 (* Intervals in general, including infinite and mixtures of open and closed. *)
10099 (* ------------------------------------------------------------------------- *)
10101 let is_interval = new_definition
10102 `is_interval(s:real^N->bool) <=>
10103 !a b x. a IN s /\ b IN s /\
10104 (!i. 1 <= i /\ i <= dimindex(:N)
10105 ==> (a$i <= x$i /\ x$i <= b$i) \/
10106 (b$i <= x$i /\ x$i <= a$i))
10109 let IS_INTERVAL_INTERVAL = prove
10110 (`!a:real^N b. is_interval(interval (a,b)) /\ is_interval(interval [a,b])`,
10111 REWRITE_TAC[is_interval; IN_INTERVAL] THEN
10112 MESON_TAC[REAL_LT_TRANS; REAL_LE_TRANS; REAL_LET_TRANS; REAL_LTE_TRANS]);;
10114 let IS_INTERVAL_EMPTY = prove
10116 REWRITE_TAC[is_interval; NOT_IN_EMPTY]);;
10118 let IS_INTERVAL_UNIV = prove
10119 (`is_interval(UNIV:real^N->bool)`,
10120 REWRITE_TAC[is_interval; IN_UNIV]);;
10122 let IS_INTERVAL_TRANSLATION_EQ = prove
10123 (`!a:real^N s. is_interval(IMAGE (\x. a + x) s) <=> is_interval s`,
10124 REWRITE_TAC[is_interval] THEN GEOM_TRANSLATE_TAC[] THEN
10125 REWRITE_TAC[VECTOR_ADD_COMPONENT; REAL_LT_LADD; REAL_LE_LADD]);;
10127 add_translation_invariants [IS_INTERVAL_TRANSLATION_EQ];;
10129 let IS_INTERVAL_TRANSLATION = prove
10130 (`!s a:real^N. is_interval s ==> is_interval(IMAGE (\x. a + x) s)`,
10131 REWRITE_TAC[IS_INTERVAL_TRANSLATION_EQ]);;
10133 let IS_INTERVAL_POINTWISE = prove
10134 (`!s:real^N->bool x.
10136 (!i. 1 <= i /\ i <= dimindex(:N) ==> ?a. a IN s /\ a$i = x$i)
10138 REWRITE_TAC[is_interval] THEN REPEAT STRIP_TAC THEN
10140 `!n. ?y:real^N. (!i. 1 <= i /\ i <= n ==> y$i = (x:real^N)$i) /\ y IN s`
10142 [INDUCT_TAC THEN REWRITE_TAC[ARITH_RULE `~(1 <= i /\ i <= 0)`] THENL
10143 [ASM_MESON_TAC[DIMINDEX_GE_1; LE_REFL]; ALL_TAC] THEN
10144 FIRST_X_ASSUM(X_CHOOSE_TAC `y:real^N`) THEN
10145 ASM_CASES_TAC `SUC n <= dimindex(:N)` THENL
10146 [FIRST_X_ASSUM(MP_TAC o SPEC `SUC n`) THEN
10147 ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
10148 DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
10150 `(lambda i. if i <= n then (y:real^N)$i else (z:real^N)$i):real^N` THEN
10152 [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
10153 SUBGOAL_THEN `i <= dimindex(:N)` ASSUME_TAC THENL
10154 [ASM_ARITH_TAC; ASM_SIMP_TAC[LAMBDA_BETA]] THEN
10155 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
10156 SUBGOAL_THEN `i = SUC n` (fun th -> ASM_REWRITE_TAC[th]) THEN
10158 FIRST_X_ASSUM(ASSUME_TAC o CONJUNCT2) THEN
10159 FIRST_X_ASSUM MATCH_MP_TAC THEN
10160 MAP_EVERY EXISTS_TAC [`y:real^N`; `z:real^N`] THEN
10161 ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC];
10162 EXISTS_TAC `y:real^N` THEN ASM_REWRITE_TAC[] THEN
10163 SUBGOAL_THEN `y:real^N = x` (fun th -> REWRITE_TAC[th]) THEN
10164 REWRITE_TAC[CART_EQ] THEN
10165 ASM_MESON_TAC[ARITH_RULE `i <= N /\ ~(SUC n <= N) ==> i <= n`]];
10166 DISCH_THEN(MP_TAC o SPEC `dimindex(:N)`) THEN
10167 REWRITE_TAC[GSYM CART_EQ] THEN MESON_TAC[]]);;
10169 let IS_INTERVAL_COMPACT = prove
10170 (`!s:real^N->bool. is_interval s /\ compact s <=> ?a b. s = interval[a,b]`,
10171 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN
10172 ASM_SIMP_TAC[IS_INTERVAL_INTERVAL; COMPACT_INTERVAL] THEN
10173 ASM_CASES_TAC `s:real^N->bool = {}` THENL
10174 [ASM_MESON_TAC[EMPTY_AS_INTERVAL]; ALL_TAC] THEN
10175 EXISTS_TAC `(lambda i. inf { (x:real^N)$i | x IN s}):real^N` THEN
10176 EXISTS_TAC `(lambda i. sup { (x:real^N)$i | x IN s}):real^N` THEN
10177 SIMP_TAC[EXTENSION; IN_INTERVAL; LAMBDA_BETA] THEN X_GEN_TAC `x:real^N` THEN
10179 [DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
10180 MP_TAC(ISPEC `{ (x:real^N)$i | x IN s}` INF) THEN
10181 MP_TAC(ISPEC `{ (x:real^N)$i | x IN s}` SUP) THEN
10182 ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10183 ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN
10184 FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN
10185 REWRITE_TAC[bounded] THEN
10186 ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS; MEMBER_NOT_EMPTY;
10187 REAL_ARITH `abs(x) <= B ==> --B <= x /\ x <= B`];
10188 DISCH_TAC THEN MATCH_MP_TAC IS_INTERVAL_POINTWISE THEN
10189 ASM_REWRITE_TAC[] THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
10191 `?a b:real^N. a IN s /\ b IN s /\ a$i <= (x:real^N)$i /\ x$i <= b$i`
10192 STRIP_ASSUME_TAC THENL
10193 [MP_TAC(ISPECL [`\x:real^N. x$i`; `s:real^N->bool`]
10194 CONTINUOUS_ATTAINS_INF) THEN
10195 ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; o_DEF] THEN
10196 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN
10197 MP_TAC(ISPECL [`\x:real^N. x$i`; `s:real^N->bool`]
10198 CONTINUOUS_ATTAINS_SUP) THEN
10199 ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; o_DEF] THEN
10200 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN
10201 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THENL
10202 [EXISTS_TAC `inf {(x:real^N)$i | x IN s}` THEN ASM_SIMP_TAC[] THEN
10203 MATCH_MP_TAC REAL_LE_INF THEN ASM SET_TAC[];
10204 EXISTS_TAC `sup {(x:real^N)$i | x IN s}` THEN ASM_SIMP_TAC[] THEN
10205 MATCH_MP_TAC REAL_SUP_LE THEN ASM SET_TAC[]];
10207 `(lambda j. if j = i then (x:real^N)$i else (a:real^N)$j):real^N` THEN
10208 ASM_SIMP_TAC[LAMBDA_BETA] THEN
10209 FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[is_interval]) THEN
10210 MAP_EVERY EXISTS_TAC
10212 `(lambda j. if j = i then (b:real^N)$i else (a:real^N)$j):real^N`] THEN
10213 ASM_SIMP_TAC[LAMBDA_BETA] THEN CONJ_TAC THENL
10214 [FIRST_X_ASSUM(MATCH_MP_TAC o REWRITE_RULE[is_interval]) THEN
10215 MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real^N`] THEN
10216 ASM_SIMP_TAC[LAMBDA_BETA];
10218 GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
10219 ASM_REAL_ARITH_TAC]]);;
10221 let IS_INTERVAL_1 = prove
10224 !a b x. a IN s /\ b IN s /\ drop a <= drop x /\ drop x <= drop b
10226 REWRITE_TAC[is_interval; DIMINDEX_1; FORALL_1; GSYM drop] THEN
10227 REWRITE_TAC[FORALL_LIFT; LIFT_DROP] THEN MESON_TAC[]);;
10229 let IS_INTERVAL_1_CASES = prove
10234 (?a. s = {x | a < drop x}) \/
10235 (?a. s = {x | a <= drop x}) \/
10236 (?b. s = {x | drop x <= b}) \/
10237 (?b. s = {x | drop x < b}) \/
10238 (?a b. s = {x | a < drop x /\ drop x < b}) \/
10239 (?a b. s = {x | a < drop x /\ drop x <= b}) \/
10240 (?a b. s = {x | a <= drop x /\ drop x < b}) \/
10241 (?a b. s = {x | a <= drop x /\ drop x <= b})`,
10242 GEN_TAC THEN REWRITE_TAC[IS_INTERVAL_1] THEN EQ_TAC THENL
10244 STRIP_TAC THEN ASM_REWRITE_TAC[IN_ELIM_THM; IN_UNIV; NOT_IN_EMPTY] THEN
10245 REAL_ARITH_TAC] THEN
10246 ASM_CASES_TAC `s:real^1->bool = {}` THEN ASM_REWRITE_TAC[] THEN
10247 MP_TAC(ISPEC `IMAGE drop s` SUP) THEN
10248 MP_TAC(ISPEC `IMAGE drop s` INF) THEN
10249 ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN
10250 ASM_CASES_TAC `?a. !x. x IN s ==> a <= drop x` THEN
10251 ASM_CASES_TAC `?b. !x. x IN s ==> drop x <= b` THEN
10252 ASM_REWRITE_TAC[] THENL
10253 [STRIP_TAC THEN STRIP_TAC THEN
10254 MAP_EVERY ASM_CASES_TAC
10255 [`inf(IMAGE drop s) IN IMAGE drop s`; `sup(IMAGE drop s) IN IMAGE drop s`]
10257 [REPLICATE_TAC 8 DISJ2_TAC;
10258 REPLICATE_TAC 7 DISJ2_TAC THEN DISJ1_TAC;
10259 REPLICATE_TAC 6 DISJ2_TAC THEN DISJ1_TAC;
10260 REPLICATE_TAC 5 DISJ2_TAC THEN DISJ1_TAC] THEN
10261 MAP_EVERY EXISTS_TAC [`inf(IMAGE drop s)`; `sup(IMAGE drop s)`];
10262 STRIP_TAC THEN ASM_CASES_TAC `inf(IMAGE drop s) IN IMAGE drop s` THENL
10263 [REPLICATE_TAC 2 DISJ2_TAC THEN DISJ1_TAC;
10264 DISJ2_TAC THEN DISJ1_TAC] THEN
10265 EXISTS_TAC `inf(IMAGE drop s)`;
10266 STRIP_TAC THEN ASM_CASES_TAC `sup(IMAGE drop s) IN IMAGE drop s` THENL
10267 [REPLICATE_TAC 3 DISJ2_TAC THEN DISJ1_TAC;
10268 REPLICATE_TAC 4 DISJ2_TAC THEN DISJ1_TAC] THEN
10269 EXISTS_TAC `sup(IMAGE drop s)`;
10271 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_UNIV] THEN
10272 RULE_ASSUM_TAC(REWRITE_RULE[IN_IMAGE]) THEN
10273 REWRITE_TAC[GSYM REAL_NOT_LE] THEN
10274 ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL; REAL_LE_ANTISYM]);;
10276 let IS_INTERVAL_PCROSS = prove
10277 (`!s:real^M->bool t:real^N->bool.
10278 is_interval s /\ is_interval t ==> is_interval(s PCROSS t)`,
10279 REWRITE_TAC[is_interval; DIMINDEX_FINITE_SUM] THEN
10280 REWRITE_TAC[FORALL_PASTECART; PASTECART_IN_PCROSS] THEN
10281 REPEAT GEN_TAC THEN
10282 MATCH_MP_TAC(MESON[]
10283 `(!a b a' b' x x'. P a b x /\ Q a' b' x' ==> R a b x a' b' x')
10284 ==> (!a b x. P a b x) /\ (!a' b' x'. Q a' b' x')
10285 ==> (!a a' b b' x x'. R a b x a' b' x')`) THEN
10286 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
10287 ASM_REWRITE_TAC[] THEN X_GEN_TAC `i:num` THEN STRIP_TAC THENL
10288 [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
10289 ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM;
10290 ARITH_RULE `x:num <= m ==> x <= m + n`];
10291 FIRST_X_ASSUM(MP_TAC o SPEC `dimindex(:M) + i`) THEN
10292 ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM;
10293 ARITH_RULE `x:num <= n ==> m + x <= m + n`;
10294 ARITH_RULE `1 <= x ==> 1 <= m + x`] THEN
10295 COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD_SUB2] THEN ASM_ARITH_TAC]);;
10297 let IS_INTERVAL_PCROSS_EQ = prove
10298 (`!s:real^M->bool t:real^N->bool.
10299 is_interval(s PCROSS t) <=>
10300 s = {} \/ t = {} \/ is_interval s /\ is_interval t`,
10301 REPEAT GEN_TAC THEN
10302 ASM_CASES_TAC `s:real^M->bool = {}` THEN
10303 ASM_REWRITE_TAC[PCROSS_EMPTY; IS_INTERVAL_EMPTY] THEN
10304 ASM_CASES_TAC `t:real^N->bool = {}` THEN
10305 ASM_REWRITE_TAC[PCROSS_EMPTY; IS_INTERVAL_EMPTY] THEN
10306 EQ_TAC THEN REWRITE_TAC[IS_INTERVAL_PCROSS] THEN
10307 REWRITE_TAC[is_interval] THEN
10308 REWRITE_TAC[FORALL_PASTECART; PASTECART_IN_PCROSS] THEN
10309 STRIP_TAC THEN CONJ_TAC THENL
10310 [MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `x:real^M`] THEN
10311 STRIP_TAC THEN UNDISCH_TAC `~(t:real^N->bool = {})` THEN
10312 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
10313 DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN
10314 FIRST_X_ASSUM(MP_TAC o SPECL
10315 [`a:real^M`; `y:real^N`; `b:real^M`;
10316 `y:real^N`; `x:real^M`; `y:real^N`]);
10317 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `x:real^N`] THEN
10318 STRIP_TAC THEN UNDISCH_TAC `~(s:real^M->bool = {})` THEN
10319 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
10320 DISCH_THEN(X_CHOOSE_TAC `w:real^M`) THEN
10321 FIRST_X_ASSUM(MP_TAC o SPECL
10322 [`w:real^M`; `a:real^N`; `w:real^M`;
10323 `b:real^N`; `w:real^M`; `x:real^N`])] THEN
10324 ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN
10325 SIMP_TAC[pastecart; LAMBDA_BETA] THEN
10326 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN
10327 ASM_MESON_TAC[DIMINDEX_FINITE_SUM; ARITH_RULE
10328 `1 <= i /\ i <= m + n /\ ~(i <= m) ==> 1 <= i - m /\ i - m <= n`]);;
10330 let IS_INTERVAL_INTER = prove
10331 (`!s t:real^N->bool.
10332 is_interval s /\ is_interval t ==> is_interval(s INTER t)`,
10333 REWRITE_TAC[is_interval; IN_INTER] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
10334 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `x:real^N`] THEN
10335 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
10336 MAP_EVERY EXISTS_TAC [`a:real^N`; `b:real^N`] THEN ASM_REWRITE_TAC[]);;
10338 let INTERVAL_SUBSET_IS_INTERVAL = prove
10341 ==> (interval[a,b] SUBSET s <=> interval[a,b] = {} \/ a IN s /\ b IN s)`,
10342 REWRITE_TAC[is_interval] THEN REPEAT STRIP_TAC THEN
10343 ASM_CASES_TAC `interval[a:real^N,b] = {}` THEN
10344 ASM_REWRITE_TAC[EMPTY_SUBSET] THEN
10345 EQ_TAC THENL [ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET]; ALL_TAC] THEN
10346 REWRITE_TAC[SUBSET; IN_INTERVAL] THEN ASM_MESON_TAC[]);;
10348 let INTERVAL_CONTAINS_COMPACT_NEIGHBOURHOOD = prove
10350 is_interval s /\ x IN s
10351 ==> ?a b d. &0 < d /\ x IN interval[a,b] /\
10352 interval[a,b] SUBSET s /\
10353 ball(x,d) INTER s SUBSET interval[a,b]`,
10354 REPEAT STRIP_TAC THEN ASM_SIMP_TAC[INTERVAL_SUBSET_IS_INTERVAL] THEN
10356 `!i. 1 <= i /\ i <= dimindex(:N)
10357 ==> ?a. (?y. y IN s /\ y$i = a) /\
10358 (a < x$i \/ a = (x:real^N)$i /\
10359 !y:real^N. y IN s ==> a <= y$i)`
10360 MP_TAC THENL [ASM_MESON_TAC[REAL_NOT_LT]; REWRITE_TAC[LAMBDA_SKOLEM]] THEN
10361 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN STRIP_TAC THEN
10363 `!i. 1 <= i /\ i <= dimindex(:N)
10364 ==> ?b. (?y. y IN s /\ y$i = b) /\
10365 (x$i < b \/ b = (x:real^N)$i /\
10366 !y:real^N. y IN s ==> y$i <= b)`
10367 MP_TAC THENL [ASM_MESON_TAC[REAL_NOT_LT]; REWRITE_TAC[LAMBDA_SKOLEM]] THEN
10368 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN STRIP_TAC THEN
10369 EXISTS_TAC `min (inf (IMAGE (\i. if a$i < x$i
10370 then (x:real^N)$i - (a:real^N)$i else &1)
10371 (1..dimindex(:N))))
10372 (inf (IMAGE (\i. if x$i < b$i
10373 then (b:real^N)$i - x$i else &1)
10374 (1..dimindex(:N))))` THEN
10375 REWRITE_TAC[REAL_LT_MIN; SUBSET; IN_BALL; IN_INTER] THEN
10376 SIMP_TAC[REAL_LT_INF_FINITE; IMAGE_EQ_EMPTY; FINITE_IMAGE;
10377 FINITE_NUMSEG; NUMSEG_EMPTY; GSYM NOT_LE; DIMINDEX_GE_1] THEN
10378 REWRITE_TAC[FORALL_IN_IMAGE; IN_INTERVAL] THEN REPEAT CONJ_TAC THENL
10379 [MESON_TAC[REAL_SUB_LT; REAL_LT_01];
10380 MESON_TAC[REAL_SUB_LT; REAL_LT_01];
10381 ASM_MESON_TAC[REAL_LE_LT];
10382 DISJ2_TAC THEN CONJ_TAC THEN MATCH_MP_TAC IS_INTERVAL_POINTWISE THEN
10384 X_GEN_TAC `y:real^N` THEN
10385 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
10386 REWRITE_TAC[AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN
10387 X_GEN_TAC `i:num` THEN DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
10388 ASM_REWRITE_TAC[IN_NUMSEG] THEN MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN
10389 (COND_CASES_TAC THENL [REWRITE_TAC[dist]; ASM_MESON_TAC[]]) THEN
10390 DISCH_TAC THEN MP_TAC(ISPECL [`x - y:real^N`; `i:num`]
10391 COMPONENT_LE_NORM) THEN
10392 ASM_REWRITE_TAC[VECTOR_SUB_COMPONENT] THEN ASM_REAL_ARITH_TAC]);;
10394 let IS_INTERVAL_SUMS = prove
10395 (`!s t:real^N->bool.
10396 is_interval s /\ is_interval t
10397 ==> is_interval {x + y | x IN s /\ y IN t}`,
10398 REPEAT GEN_TAC THEN REWRITE_TAC[is_interval] THEN
10399 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
10400 REWRITE_TAC[FORALL_IN_GSPEC] THEN
10401 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
10402 REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
10403 MAP_EVERY X_GEN_TAC
10404 [`a:real^N`; `a':real^N`; `b:real^N`; `b':real^N`; `y:real^N`] THEN
10405 DISCH_THEN(CONJUNCTS_THEN2
10406 (MP_TAC o SPECL [`a:real^N`; `b:real^N`]) MP_TAC) THEN
10407 DISCH_THEN(CONJUNCTS_THEN2
10408 (MP_TAC o SPECL [`a':real^N`; `b':real^N`]) STRIP_ASSUME_TAC) THEN
10409 ASM_REWRITE_TAC[IMP_IMP; IN_ELIM_THM] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
10410 ONCE_REWRITE_TAC[VECTOR_ARITH `z:real^N = x + y <=> y = z - x`] THEN
10411 REWRITE_TAC[UNWIND_THM2] THEN MATCH_MP_TAC(MESON[]
10412 `(?x. P x /\ Q(f x))
10413 ==> (!x. P x ==> x IN s) /\ (!x. Q x ==> x IN t)
10414 ==> ?x. x IN s /\ f x IN t`) THEN
10415 REWRITE_TAC[VECTOR_SUB_COMPONENT; AND_FORALL_THM;
10416 TAUT `(p ==> q) /\ (p ==> r) <=> p ==> q /\ r`] THEN
10417 REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN
10418 X_GEN_TAC `i:num` THEN STRIP_TAC THEN
10419 FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
10420 ASM_REWRITE_TAC[VECTOR_ADD_COMPONENT] THEN
10421 REWRITE_TAC[REAL_ARITH
10422 `c <= y - x /\ y - x <= d <=> y - d <= x /\ x <= y - c`] THEN
10423 REWRITE_TAC[REAL_ARITH
10424 `a <= x /\ x <= b \/ b <= x /\ x <= a <=> min a b <= x /\ x <= max a b`] THEN
10425 ONCE_REWRITE_TAC[TAUT `(p /\ q) /\ (r /\ s) <=> (p /\ r) /\ (q /\ s)`] THEN
10426 REWRITE_TAC[GSYM REAL_LE_MIN; GSYM REAL_MAX_LE] THEN
10427 REWRITE_TAC[GSYM REAL_LE_BETWEEN] THEN REAL_ARITH_TAC);;
10429 let IS_INTERVAL_SING = prove
10430 (`!a:real^N. is_interval {a}`,
10431 SIMP_TAC[is_interval; IN_SING; IMP_CONJ; CART_EQ; REAL_LE_ANTISYM]);;
10433 let IS_INTERVAL_SCALING = prove
10434 (`!s:real^N->bool c. is_interval s ==> is_interval(IMAGE (\x. c % x) s)`,
10435 REPEAT GEN_TAC THEN ASM_CASES_TAC `c = &0` THENL
10436 [ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN
10437 SUBGOAL_THEN `IMAGE ((\x. vec 0):real^N->real^N) s = {} \/
10438 IMAGE ((\x. vec 0):real^N->real^N) s = {vec 0}`
10439 STRIP_ASSUME_TAC THENL
10441 ASM_REWRITE_TAC[IS_INTERVAL_EMPTY];
10442 ASM_REWRITE_TAC[IS_INTERVAL_SING]];
10443 REWRITE_TAC[is_interval; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
10444 REWRITE_TAC[FORALL_IN_IMAGE] THEN
10445 GEN_REWRITE_TAC (BINOP_CONV o REDEPTH_CONV) [RIGHT_IMP_FORALL_THM] THEN
10446 REWRITE_TAC[IMP_IMP; VECTOR_MUL_COMPONENT] THEN
10447 MAP_EVERY (fun t -> MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC t)
10448 [`a:real^N`; `b:real^N`] THEN
10449 DISCH_THEN(fun th -> X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN
10450 MP_TAC(SPEC `inv(c) % x:real^N` th)) THEN
10451 ASM_REWRITE_TAC[VECTOR_MUL_COMPONENT; IN_IMAGE] THEN ANTS_TAC THENL
10452 [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
10453 FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
10454 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN
10455 FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH
10456 `~(c = &0) ==> &0 < c \/ &0 < --c`)) THEN
10457 ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ] THEN
10458 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM REAL_LE_NEG2] THEN
10459 ASM_SIMP_TAC[GSYM REAL_MUL_RNEG; GSYM REAL_LE_RDIV_EQ; GSYM
10460 REAL_LE_LDIV_EQ] THEN
10461 REWRITE_TAC[real_div; REAL_INV_NEG] THEN REAL_ARITH_TAC;
10462 DISCH_TAC THEN EXISTS_TAC `inv c % x:real^N` THEN
10463 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; VECTOR_MUL_LID]]]);;
10465 let IS_INTERVAL_SCALING_EQ = prove
10466 (`!s:real^N->bool c.
10467 is_interval(IMAGE (\x. c % x) s) <=> c = &0 \/ is_interval s`,
10468 REPEAT GEN_TAC THEN ASM_CASES_TAC `c = &0` THENL
10469 [ASM_REWRITE_TAC[VECTOR_MUL_LZERO] THEN
10470 SUBGOAL_THEN `IMAGE ((\x. vec 0):real^N->real^N) s = {} \/
10471 IMAGE ((\x. vec 0):real^N->real^N) s = {vec 0}`
10472 STRIP_ASSUME_TAC THENL
10474 ASM_REWRITE_TAC[IS_INTERVAL_EMPTY];
10475 ASM_REWRITE_TAC[IS_INTERVAL_SING]];
10476 ASM_REWRITE_TAC[] THEN EQ_TAC THEN REWRITE_TAC[IS_INTERVAL_SCALING] THEN
10477 DISCH_THEN(MP_TAC o SPEC `inv c:real` o MATCH_MP IS_INTERVAL_SCALING) THEN
10478 ASM_SIMP_TAC[GSYM IMAGE_o; VECTOR_MUL_ASSOC; o_DEF; REAL_MUL_LINV;
10479 VECTOR_MUL_LID; IMAGE_ID]]);;
10483 ==> !s:real^N->bool. is_interval(IMAGE (\x. c % x) s) <=>
10485 SIMP_TAC[IS_INTERVAL_SCALING_EQ; REAL_LT_IMP_NZ]) in
10486 add_scaling_theorems [lemma];;
10488 (* ------------------------------------------------------------------------- *)
10489 (* Line segments, with same open/closed overloading as for intervals. *)
10490 (* ------------------------------------------------------------------------- *)
10492 let closed_segment = define
10493 `closed_segment[a,b] = {(&1 - u) % a + u % b | &0 <= u /\ u <= &1}`;;
10495 let open_segment = new_definition
10496 `open_segment(a,b) = closed_segment[a,b] DIFF {a,b}`;;
10498 let OPEN_SEGMENT_ALT = prove
10501 ==> open_segment(a,b) = {(&1 - u) % a + u % b | &0 < u /\ u < &1}`,
10502 REPEAT STRIP_TAC THEN REWRITE_TAC[open_segment; closed_segment] THEN
10503 REWRITE_TAC[EXTENSION; IN_DIFF; IN_INSERT; NOT_IN_EMPTY; IN_ELIM_THM] THEN
10504 X_GEN_TAC `x:real^N` THEN REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN
10505 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN
10506 X_GEN_TAC `u:real` THEN ASM_CASES_TAC `x:real^N = (&1 - u) % a + u % b` THEN
10507 ASM_REWRITE_TAC[REAL_LE_LT;
10508 VECTOR_ARITH `(&1 - u) % a + u % b = a <=> u % (b - a) = vec 0`;
10509 VECTOR_ARITH `(&1 - u) % a + u % b = b <=> (&1 - u) % (b - a) = vec 0`;
10510 VECTOR_MUL_EQ_0; REAL_SUB_0; VECTOR_SUB_EQ] THEN
10513 make_overloadable "segment" `:A`;;
10515 overload_interface("segment",`open_segment`);;
10516 overload_interface("segment",`closed_segment`);;
10518 let segment = prove
10519 (`segment[a,b] = {(&1 - u) % a + u % b | &0 <= u /\ u <= &1} /\
10520 segment(a,b) = segment[a,b] DIFF {a,b}`,
10521 REWRITE_TAC[open_segment; closed_segment]);;
10523 let SEGMENT_REFL = prove
10524 (`(!a. segment[a,a] = {a}) /\
10525 (!a. segment(a,a) = {})`,
10526 REWRITE_TAC[segment; VECTOR_ARITH `(&1 - u) % a + u % a = a`] THEN
10527 SET_TAC[REAL_POS]);;
10529 let IN_SEGMENT = prove
10531 (x IN segment[a,b] <=>
10532 ?u. &0 <= u /\ u <= &1 /\ x = (&1 - u) % a + u % b) /\
10533 (x IN segment(a,b) <=>
10534 ~(a = b) /\ ?u. &0 < u /\ u < &1 /\ x = (&1 - u) % a + u % b)`,
10535 REPEAT STRIP_TAC THENL
10536 [REWRITE_TAC[segment; IN_ELIM_THM; CONJ_ASSOC]; ALL_TAC] THEN
10537 ASM_CASES_TAC `a:real^N = b` THEN
10538 ASM_REWRITE_TAC[SEGMENT_REFL; NOT_IN_EMPTY] THEN
10539 ASM_SIMP_TAC[OPEN_SEGMENT_ALT; IN_ELIM_THM; CONJ_ASSOC]);;
10541 let SEGMENT_SYM = prove
10542 (`(!a b:real^N. segment[a,b] = segment[b,a]) /\
10543 (!a b:real^N. segment(a,b) = segment(b,a))`,
10544 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN
10545 SIMP_TAC[open_segment] THEN
10546 CONJ_TAC THENL [ALL_TAC; SIMP_TAC[INSERT_AC]] THEN
10547 REWRITE_TAC[EXTENSION; IN_SEGMENT] THEN REPEAT GEN_TAC THEN EQ_TAC THEN
10548 DISCH_THEN(X_CHOOSE_TAC `u:real`) THEN EXISTS_TAC `&1 - u` THEN
10549 ASM_REWRITE_TAC[] THEN
10550 REPEAT CONJ_TAC THEN TRY ASM_ARITH_TAC THEN VECTOR_ARITH_TAC);;
10552 let ENDS_IN_SEGMENT = prove
10553 (`!a b. a IN segment[a,b] /\ b IN segment[a,b]`,
10554 REPEAT STRIP_TAC THEN REWRITE_TAC[segment; IN_ELIM_THM] THENL
10555 [EXISTS_TAC `&0`; EXISTS_TAC `&1`] THEN
10556 (CONJ_TAC THENL [REAL_ARITH_TAC; VECTOR_ARITH_TAC]));;
10558 let ENDS_NOT_IN_SEGMENT = prove
10559 (`!a b. ~(a IN segment(a,b)) /\ ~(b IN segment(a,b))`,
10560 REWRITE_TAC[open_segment] THEN SET_TAC[]);;
10562 let SEGMENT_CLOSED_OPEN = prove
10563 (`!a b. segment[a,b] = segment(a,b) UNION {a,b}`,
10564 REPEAT GEN_TAC THEN REWRITE_TAC[open_segment] THEN MATCH_MP_TAC(SET_RULE
10565 `a IN s /\ b IN s ==> s = (s DIFF {a,b}) UNION {a,b}`) THEN
10566 REWRITE_TAC[ENDS_IN_SEGMENT]);;
10568 let MIDPOINT_IN_SEGMENT = prove
10569 (`(!a b:real^N. midpoint(a,b) IN segment[a,b]) /\
10570 (!a b:real^N. midpoint(a,b) IN segment(a,b) <=> ~(a = b))`,
10571 REWRITE_TAC[IN_SEGMENT] THEN REPEAT STRIP_TAC THENL
10572 [ALL_TAC; ASM_CASES_TAC `a:real^N = b` THEN ASM_REWRITE_TAC[]] THEN
10573 EXISTS_TAC `&1 / &2` THEN REWRITE_TAC[midpoint] THEN
10574 CONV_TAC REAL_RAT_REDUCE_CONV THEN VECTOR_ARITH_TAC);;
10576 let BETWEEN_IN_SEGMENT = prove
10577 (`!x a b:real^N. between x (a,b) <=> x IN segment[a,b]`,
10578 REPEAT GEN_TAC THEN REWRITE_TAC[between] THEN
10579 ASM_CASES_TAC `a:real^N = b` THEN
10580 ASM_REWRITE_TAC[SEGMENT_REFL; IN_SING] THENL [NORM_ARITH_TAC; ALL_TAC] THEN
10581 REWRITE_TAC[segment; IN_ELIM_THM] THEN EQ_TAC THENL
10582 [DISCH_THEN(ASSUME_TAC o SYM) THEN
10583 EXISTS_TAC `dist(a:real^N,x) / dist(a,b)` THEN
10584 ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; DIST_POS_LT] THEN CONJ_TAC
10585 THENL [FIRST_ASSUM(SUBST1_TAC o SYM) THEN NORM_ARITH_TAC; ALL_TAC] THEN
10586 MATCH_MP_TAC VECTOR_MUL_LCANCEL_IMP THEN EXISTS_TAC `dist(a:real^N,b)` THEN
10587 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; VECTOR_ADD_LDISTRIB; REAL_SUB_LDISTRIB;
10588 REAL_DIV_LMUL; DIST_EQ_0] THEN
10589 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DIST_TRIANGLE_EQ] o SYM) THEN
10590 FIRST_ASSUM(SUBST1_TAC o SYM) THEN
10591 REWRITE_TAC[dist; REAL_ARITH `(a + b) * &1 - a = b`] THEN
10593 STRIP_TAC THEN ASM_REWRITE_TAC[dist] THEN
10594 REWRITE_TAC[VECTOR_ARITH `a - ((&1 - u) % a + u % b) = u % (a - b)`;
10595 VECTOR_ARITH `((&1 - u) % a + u % b) - b = (&1 - u) % (a - b)`;
10596 NORM_MUL; GSYM REAL_ADD_LDISTRIB] THEN
10597 REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD]);;
10599 let IN_SEGMENT_COMPONENT = prove
10601 x IN segment[a,b] /\ 1 <= i /\ i <= dimindex(:N)
10602 ==> min (a$i) (b$i) <= x$i /\ x$i <= max (a$i) (b$i)`,
10603 REPEAT STRIP_TAC THEN
10604 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SEGMENT]) THEN
10605 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
10606 FIRST_X_ASSUM(X_CHOOSE_THEN `t:real` STRIP_ASSUME_TAC) THEN
10607 ASM_REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
10608 SIMP_TAC[REAL_ARITH `c <= u * a + t * b <=> u * --a + t * --b <= --c`] THEN
10609 MATCH_MP_TAC REAL_CONVEX_BOUND_LE THEN ASM_REAL_ARITH_TAC);;
10611 let SEGMENT_1 = prove
10612 (`(!a b. segment[a,b] =
10613 if drop a <= drop b then interval[a,b] else interval[b,a]) /\
10614 (!a b. segment(a,b) =
10615 if drop a <= drop b then interval(a,b) else interval(b,a))`,
10616 CONJ_TAC THEN REPEAT GEN_TAC THEN REWRITE_TAC[open_segment] THEN
10617 COND_CASES_TAC THEN
10618 REWRITE_TAC[IN_DIFF; IN_INSERT; NOT_IN_EMPTY;
10619 EXTENSION; GSYM BETWEEN_IN_SEGMENT; between; IN_INTERVAL_1] THEN
10620 REWRITE_TAC[GSYM DROP_EQ; DIST_REAL; GSYM drop] THEN ASM_REAL_ARITH_TAC);;
10622 let OPEN_SEGMENT_1 = prove
10623 (`!a b:real^1. open(segment(a,b))`,
10624 REPEAT GEN_TAC THEN REWRITE_TAC[SEGMENT_1] THEN
10625 COND_CASES_TAC THEN REWRITE_TAC[OPEN_INTERVAL]);;
10627 let SEGMENT_TRANSLATION = prove
10628 (`(!c a b. segment[c + a,c + b] = IMAGE (\x. c + x) (segment[a,b])) /\
10629 (!c a b. segment(c + a,c + b) = IMAGE (\x. c + x) (segment(a,b)))`,
10630 REWRITE_TAC[EXTENSION; IN_SEGMENT; IN_IMAGE] THEN
10631 REWRITE_TAC[VECTOR_ARITH `(&1 - u) % (c + a) + u % (c + b) =
10632 c + (&1 - u) % a + u % b`] THEN
10633 REWRITE_TAC[VECTOR_ARITH `c + a:real^N = c + b <=> a = b`] THEN
10636 add_translation_invariants
10637 [CONJUNCT1 SEGMENT_TRANSLATION; CONJUNCT2 SEGMENT_TRANSLATION];;
10639 let CLOSED_SEGMENT_LINEAR_IMAGE = prove
10641 ==> segment[f a,f b] = IMAGE f (segment[a,b])`,
10642 REPEAT STRIP_TAC THEN REWRITE_TAC[EXTENSION; IN_IMAGE; IN_SEGMENT] THEN
10643 FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_CMUL th)]) THEN
10644 FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_ADD th)]) THEN
10647 add_linear_invariants [CLOSED_SEGMENT_LINEAR_IMAGE];;
10649 let OPEN_SEGMENT_LINEAR_IMAGE = prove
10650 (`!f:real^M->real^N a b.
10651 linear f /\ (!x y. f x = f y ==> x = y)
10652 ==> segment(f a,f b) = IMAGE f (segment(a,b))`,
10653 REWRITE_TAC[open_segment] THEN GEOM_TRANSFORM_TAC[]);;
10655 add_linear_invariants [OPEN_SEGMENT_LINEAR_IMAGE];;
10657 let IN_OPEN_SEGMENT = prove
10659 x IN segment(a,b) <=> x IN segment[a,b] /\ ~(x = a) /\ ~(x = b)`,
10660 REPEAT GEN_TAC THEN REWRITE_TAC[open_segment; IN_DIFF] THEN SET_TAC[]);;
10662 let IN_OPEN_SEGMENT_ALT = prove
10664 x IN segment(a,b) <=>
10665 x IN segment[a,b] /\ ~(x = a) /\ ~(x = b) /\ ~(a = b)`,
10666 REPEAT GEN_TAC THEN ASM_CASES_TAC `a:real^N = b` THEN
10667 ASM_REWRITE_TAC[SEGMENT_REFL; IN_SING; NOT_IN_EMPTY] THEN
10668 ASM_MESON_TAC[IN_OPEN_SEGMENT]);;
10670 let COLLINEAR_DIST_IN_CLOSED_SEGMENT = prove
10671 (`!a b x. collinear {x,a,b} /\
10672 dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)
10673 ==> x IN segment[a,b]`,
10674 REWRITE_TAC[GSYM BETWEEN_IN_SEGMENT; COLLINEAR_DIST_BETWEEN]);;
10676 let COLLINEAR_DIST_IN_OPEN_SEGMENT = prove
10677 (`!a b x. collinear {x,a,b} /\
10678 dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b)
10679 ==> x IN segment(a,b)`,
10680 REWRITE_TAC[IN_OPEN_SEGMENT] THEN
10681 MESON_TAC[COLLINEAR_DIST_IN_CLOSED_SEGMENT; REAL_LT_LE; DIST_SYM]);;
10683 let SEGMENT_SCALAR_MULTIPLE = prove
10684 (`(!a b v. segment[a % v,b % v] =
10685 {x % v:real^N | a <= x /\ x <= b \/ b <= x /\ x <= a}) /\
10686 (!a b v. ~(v = vec 0)
10687 ==> segment(a % v,b % v) =
10688 {x % v:real^N | a < x /\ x < b \/ b < x /\ x < a})`,
10689 MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN REPEAT STRIP_TAC THENL
10690 [REPEAT GEN_TAC THEN
10691 MP_TAC(SPECL [`a % basis 1:real^1`; `b % basis 1:real^1`]
10692 (CONJUNCT1 SEGMENT_1)) THEN
10693 REWRITE_TAC[segment; VECTOR_MUL_ASSOC; GSYM VECTOR_ADD_RDISTRIB] THEN
10694 REWRITE_TAC[SET_RULE `{f x % b | p x} = IMAGE (\a. a % b) {f x | p x}`] THEN
10695 DISCH_TAC THEN AP_TERM_TAC THEN
10696 FIRST_X_ASSUM(MP_TAC o AP_TERM `IMAGE drop`) THEN
10697 REWRITE_TAC[GSYM IMAGE_o; o_DEF; DROP_CMUL] THEN
10698 SIMP_TAC[drop; BASIS_COMPONENT; DIMINDEX_GE_1; LE_REFL] THEN
10699 REWRITE_TAC[REAL_MUL_RID; IMAGE_ID] THEN DISCH_THEN SUBST1_TAC THEN
10700 MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
10701 CONJ_TAC THENL [MESON_TAC[LIFT_DROP]; ALL_TAC] THEN
10702 REWRITE_TAC[FORALL_LIFT; LIFT_DROP] THEN GEN_TAC THEN
10703 COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL_1; LIFT_DROP] THEN
10704 SIMP_TAC[drop; VECTOR_MUL_COMPONENT; BASIS_COMPONENT; DIMINDEX_GE_1;
10705 LE_REFL; IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC;
10706 ASM_REWRITE_TAC[open_segment] THEN
10707 ASM_SIMP_TAC[VECTOR_MUL_RCANCEL; SET_RULE
10708 `(!x y. x % v = y % v <=> x = y)
10709 ==> {x % v | P x} DIFF {a % v,b % v} =
10710 {x % v | P x /\ ~(x = a) /\ ~(x = b)}`] THEN
10711 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN AP_TERM_TAC THEN
10712 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN REAL_ARITH_TAC]);;
10714 let FINITE_INTER_COLLINEAR_OPEN_SEGMENTS = prove
10717 ==> (FINITE(segment(a,b) INTER segment(c,d)) <=>
10718 segment(a,b) INTER segment(c,d) = {})`,
10719 REPEAT GEN_TAC THEN ABBREV_TAC `m:real^N = b - a` THEN POP_ASSUM MP_TAC THEN
10720 GEOM_NORMALIZE_TAC `m:real^N` THEN
10721 SIMP_TAC[VECTOR_SUB_EQ; SEGMENT_REFL; INTER_EMPTY; FINITE_EMPTY] THEN
10722 X_GEN_TAC `m:real^N` THEN DISCH_TAC THEN REPEAT GEN_TAC THEN
10723 DISCH_THEN(SUBST_ALL_TAC o SYM) THEN POP_ASSUM MP_TAC THEN
10724 GEOM_ORIGIN_TAC `a:real^N` THEN GEOM_BASIS_MULTIPLE_TAC 1 `b:real^N` THEN
10725 X_GEN_TAC `b:real` THEN DISCH_TAC THEN
10726 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN
10727 SIMP_TAC[VECTOR_SUB_RZERO; NORM_MUL; NORM_BASIS; DIMINDEX_GE_1; LE_REFL] THEN
10728 ASM_REWRITE_TAC[real_abs; REAL_MUL_RID] THEN DISCH_THEN SUBST_ALL_TAC THEN
10729 POP_ASSUM(K ALL_TAC) THEN
10730 ASM_CASES_TAC `collinear{vec 0:real^N,&1 % basis 1,y}` THENL
10731 [POP_ASSUM MP_TAC THEN
10732 SIMP_TAC[COLLINEAR_LEMMA_ALT; BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL] THEN
10734 `~a /\ (b ==> c ==> d) ==> a \/ b ==> a \/ c ==> d`) THEN
10736 [SIMP_TAC[VECTOR_MUL_LID; BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL];
10737 REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN
10738 X_GEN_TAC `b:real` THEN DISCH_THEN SUBST_ALL_TAC THEN
10739 X_GEN_TAC `a:real` THEN DISCH_THEN SUBST_ALL_TAC THEN
10740 REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RID] THEN
10741 SUBST1_TAC(VECTOR_ARITH `vec 0:real^N = &0 % basis 1`) THEN
10742 SIMP_TAC[SEGMENT_SCALAR_MULTIPLE; BASIS_NONZERO; DIMINDEX_GE_1; LE_REFL;
10743 VECTOR_MUL_RCANCEL; IMAGE_EQ_EMPTY; FINITE_IMAGE_INJ_EQ; SET_RULE
10744 `(!x y. x % v = y % v <=> x = y)
10745 ==> {x % v | P x} INTER {x % v | Q x} =
10746 IMAGE (\x. x % v) {x | P x /\ Q x}`] THEN
10747 REWRITE_TAC[REAL_ARITH `(&0 < x /\ x < &1 \/ &1 < x /\ x < &0) /\
10748 (b < x /\ x < a \/ a < x /\ x < b) <=>
10749 max (&0) (min a b) < x /\ x < min (&1) (max a b)`] THEN
10750 SIMP_TAC[FINITE_REAL_INTERVAL; EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM] THEN
10751 SIMP_TAC[GSYM REAL_LT_BETWEEN; GSYM NOT_EXISTS_THM] THEN REAL_ARITH_TAC;
10752 DISCH_TAC THEN ASM_CASES_TAC
10753 `segment(vec 0:real^N,&1 % basis 1) INTER segment (x,y) = {}` THEN
10754 ASM_REWRITE_TAC[FINITE_EMPTY] THEN DISCH_THEN(K ALL_TAC) THEN
10755 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
10756 REWRITE_TAC[open_segment; IN_DIFF; NOT_IN_EMPTY;
10757 DE_MORGAN_THM; IN_INTER; IN_INSERT] THEN
10758 DISCH_THEN(X_CHOOSE_THEN `p:real^N` STRIP_ASSUME_TAC) THEN
10759 UNDISCH_TAC `~collinear{vec 0:real^N,&1 % basis 1, y}` THEN
10760 RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_MUL_LID]) THEN
10761 REWRITE_TAC[VECTOR_MUL_LID] THEN
10762 MATCH_MP_TAC COLLINEAR_SUBSET THEN
10763 EXISTS_TAC `{p,x:real^N, y, vec 0, basis 1}` THEN
10764 CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN
10765 MP_TAC(ISPECL [`{y:real^N,vec 0,basis 1}`; `p:real^N`; `x:real^N`]
10766 COLLINEAR_TRIPLES) THEN
10767 ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN
10768 REWRITE_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY] THEN CONJ_TAC THENL
10769 [ONCE_REWRITE_TAC[SET_RULE `{p,x,y} = {x,p,y}`] THEN
10770 MATCH_MP_TAC BETWEEN_IMP_COLLINEAR THEN
10771 ASM_REWRITE_TAC[BETWEEN_IN_SEGMENT];
10773 ASM_SIMP_TAC[GSYM COLLINEAR_4_3] THEN
10774 ONCE_REWRITE_TAC[SET_RULE `{p,x,z,w} = {w,z,p,x}`] THEN
10775 SIMP_TAC[COLLINEAR_4_3; BASIS_NONZERO; DIMINDEX_GE_1; ARITH] THEN
10776 REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP BETWEEN_IMP_COLLINEAR o
10777 GEN_REWRITE_RULE I [GSYM BETWEEN_IN_SEGMENT])) THEN
10778 REPEAT(POP_ASSUM MP_TAC) THEN SIMP_TAC[INSERT_AC]]);;
10780 let DIST_IN_CLOSED_SEGMENT,DIST_IN_OPEN_SEGMENT = (CONJ_PAIR o prove)
10782 x IN segment[a,b] ==> dist(x,a) <= dist(a,b) /\ dist(x,b) <= dist(a,b)) /\
10784 x IN segment(a,b) ==> dist(x,a) < dist(a,b) /\ dist(x,b) < dist(a,b))`,
10785 SIMP_TAC[IN_SEGMENT; RIGHT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM; dist;
10787 `((&1 - u) % a + u % b) - a:real^N = u % (b - a) /\
10788 ((&1 - u) % a + u % b) - b = --(&1 - u) % (b - a)`] THEN
10789 REWRITE_TAC[NORM_MUL; REAL_ABS_NEG; NORM_SUB] THEN CONJ_TAC THEN
10790 REPEAT GEN_TAC THEN STRIP_TAC THENL
10791 [REWRITE_TAC[REAL_ARITH `x * y <= y <=> x * y <= &1 * y`] THEN
10792 CONJ_TAC THEN MATCH_MP_TAC REAL_LE_RMUL THEN
10793 REWRITE_TAC[NORM_POS_LE] THEN ASM_REAL_ARITH_TAC;
10794 REWRITE_TAC[REAL_ARITH `x * y < y <=> x * y < &1 * y`] THEN
10795 ASM_SIMP_TAC[REAL_LT_RMUL_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN
10796 ASM_REAL_ARITH_TAC]);;
10798 (* ------------------------------------------------------------------------- *)
10799 (* Limit component bounds. *)
10800 (* ------------------------------------------------------------------------- *)
10802 let LIM_COMPONENT_UBOUND = prove
10803 (`!net:(A)net f (l:real^N) b k.
10804 ~(trivial_limit net) /\ (f --> l) net /\
10805 eventually (\x. (f x)$k <= b) net /\
10806 1 <= k /\ k <= dimindex(:N)
10808 REPEAT STRIP_TAC THEN MP_TAC(ISPECL
10809 [`net:(A)net`; `f:A->real^N`; `{y:real^N | basis k dot y <= b}`; `l:real^N`]
10810 LIM_IN_CLOSED_SET) THEN
10811 ASM_SIMP_TAC[CLOSED_HALFSPACE_LE; IN_ELIM_THM; DOT_BASIS]);;
10813 let LIM_COMPONENT_LBOUND = prove
10814 (`!net:(A)net f (l:real^N) b k.
10815 ~(trivial_limit net) /\ (f --> l) net /\
10816 eventually (\x. b <= (f x)$k) net /\
10817 1 <= k /\ k <= dimindex(:N)
10819 REPEAT STRIP_TAC THEN MP_TAC(ISPECL
10820 [`net:(A)net`; `f:A->real^N`; `{y:real^N | b <= basis k dot y}`; `l:real^N`]
10821 LIM_IN_CLOSED_SET) THEN
10822 ASM_SIMP_TAC[REWRITE_RULE[real_ge] CLOSED_HALFSPACE_GE;
10823 IN_ELIM_THM; DOT_BASIS]);;
10825 let LIM_COMPONENT_EQ = prove
10826 (`!net f:A->real^N i l b.
10827 (f --> l) net /\ 1 <= i /\ i <= dimindex(:N) /\
10828 ~(trivial_limit net) /\ eventually (\x. f(x)$i = b) net
10830 REWRITE_TAC[GSYM REAL_LE_ANTISYM; EVENTUALLY_AND] THEN
10831 MESON_TAC[LIM_COMPONENT_UBOUND; LIM_COMPONENT_LBOUND]);;
10833 let LIM_COMPONENT_LE = prove
10834 (`!net:(A)net f:A->real^N g:A->real^N k l m.
10835 ~(trivial_limit net) /\ (f --> l) net /\ (g --> m) net /\
10836 eventually (\x. (f x)$k <= (g x)$k) net /\
10837 1 <= k /\ k <= dimindex(:N)
10839 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LE] THEN
10840 REWRITE_TAC[GSYM VECTOR_SUB_COMPONENT; LIM_COMPONENT_LBOUND] THEN
10841 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
10842 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> b /\ a ==> c ==> d`] THEN
10843 DISCH_THEN(MP_TAC o MATCH_MP LIM_SUB) THEN POP_ASSUM MP_TAC THEN
10844 REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; LIM_COMPONENT_LBOUND]);;
10846 let LIM_DROP_LE = prove
10847 (`!net:(A)net f g l m.
10848 ~(trivial_limit net) /\ (f --> l) net /\ (g --> m) net /\
10849 eventually (\x. drop(f x) <= drop(g x)) net
10850 ==> drop l <= drop m`,
10851 REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN
10852 MATCH_MP_TAC(ISPEC `net:(A)net` LIM_COMPONENT_LE) THEN
10853 MAP_EVERY EXISTS_TAC [`f:A->real^1`; `g:A->real^1`] THEN
10854 ASM_REWRITE_TAC[DIMINDEX_1; LE_REFL]);;
10856 let LIM_DROP_UBOUND = prove
10857 (`!net f:A->real^1 l b.
10859 ~(trivial_limit net) /\ eventually (\x. drop(f x) <= b) net
10861 SIMP_TAC[drop] THEN REPEAT STRIP_TAC THEN
10862 MATCH_MP_TAC LIM_COMPONENT_UBOUND THEN
10863 REWRITE_TAC[LE_REFL; DIMINDEX_1] THEN ASM_MESON_TAC[]);;
10865 let LIM_DROP_LBOUND = prove
10866 (`!net f:A->real^1 l b.
10868 ~(trivial_limit net) /\ eventually (\x. b <= drop(f x)) net
10870 SIMP_TAC[drop] THEN REPEAT STRIP_TAC THEN
10871 MATCH_MP_TAC LIM_COMPONENT_LBOUND THEN
10872 REWRITE_TAC[LE_REFL; DIMINDEX_1] THEN ASM_MESON_TAC[]);;
10874 (* ------------------------------------------------------------------------- *)
10875 (* Also extending closed bounds to closures. *)
10876 (* ------------------------------------------------------------------------- *)
10878 let IMAGE_CLOSURE_SUBSET = prove
10879 (`!f (s:real^N->bool) (t:real^M->bool).
10880 f continuous_on closure s /\ closed t /\ IMAGE f s SUBSET t
10881 ==> IMAGE f (closure s) SUBSET t`,
10882 REPEAT STRIP_TAC THEN
10883 SUBGOAL_THEN `closure s SUBSET {x | (f:real^N->real^M) x IN t}` MP_TAC
10884 THENL [MATCH_MP_TAC SUBSET_TRANS; SET_TAC []] THEN
10885 EXISTS_TAC `{x | x IN closure s /\ (f:real^N->real^M) x IN t}` THEN
10887 [MATCH_MP_TAC CLOSURE_MINIMAL; SET_TAC[]] THEN
10888 ASM_SIMP_TAC[CONTINUOUS_CLOSED_PREIMAGE; CLOSED_CLOSURE] THEN
10889 MP_TAC (ISPEC `s:real^N->bool` CLOSURE_SUBSET) THEN ASM SET_TAC[]);;
10891 let CLOSURE_IMAGE_CLOSURE = prove
10892 (`!f:real^M->real^N s.
10893 f continuous_on closure s
10894 ==> closure(IMAGE f (closure s)) = closure(IMAGE f s)`,
10895 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ] THEN
10896 SIMP_TAC[SUBSET_CLOSURE; IMAGE_SUBSET; CLOSURE_SUBSET] THEN
10897 SIMP_TAC[CLOSURE_MINIMAL_EQ; CLOSED_CLOSURE] THEN
10898 MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN
10899 ASM_REWRITE_TAC[CLOSED_CLOSURE; CLOSURE_SUBSET]);;
10901 let CONTINUOUS_ON_CLOSURE_NORM_LE = prove
10902 (`!f:real^N->real^M s x b.
10903 f continuous_on (closure s) /\
10904 (!y. y IN s ==> norm(f y) <= b) /\
10906 ==> norm(f x) <= b`,
10907 REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN
10908 SUBGOAL_THEN `IMAGE (f:real^N->real^M) (closure s) SUBSET cball(vec 0,b)`
10910 [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET; ASM SET_TAC []] THEN
10911 ASM_REWRITE_TAC [CLOSED_CBALL] THEN ASM SET_TAC []);;
10913 let CONTINUOUS_ON_CLOSURE_COMPONENT_LE = prove
10914 (`!f:real^N->real^M s x b k.
10915 f continuous_on (closure s) /\
10916 (!y. y IN s ==> (f y)$k <= b) /\
10919 REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN
10920 SUBGOAL_THEN `IMAGE (f:real^N->real^M) (closure s) SUBSET {x | x$k <= b}`
10922 [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET; ASM SET_TAC []] THEN
10923 ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE] THEN ASM SET_TAC[]);;
10925 let CONTINUOUS_ON_CLOSURE_COMPONENT_GE = prove
10926 (`!f:real^N->real^M s x b k.
10927 f continuous_on (closure s) /\
10928 (!y. y IN s ==> b <= (f y)$k) /\
10931 REWRITE_TAC [GSYM IN_CBALL_0] THEN REPEAT STRIP_TAC THEN
10932 SUBGOAL_THEN `IMAGE (f:real^N->real^M) (closure s) SUBSET {x | x$k >= b}`
10934 [MATCH_MP_TAC IMAGE_CLOSURE_SUBSET; ASM SET_TAC [real_ge]] THEN
10935 ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_GE] THEN ASM SET_TAC[real_ge]);;
10937 (* ------------------------------------------------------------------------- *)
10938 (* Limits relative to a union. *)
10939 (* ------------------------------------------------------------------------- *)
10941 let LIM_WITHIN_UNION = prove
10942 (`(f --> l) (at x within (s UNION t)) <=>
10943 (f --> l) (at x within s) /\ (f --> l) (at x within t)`,
10944 REWRITE_TAC[LIM_WITHIN; IN_UNION; AND_FORALL_THM] THEN
10945 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN
10946 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
10947 EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN DISCH_THEN
10948 (CONJUNCTS_THEN2 (X_CHOOSE_TAC `d:real`) (X_CHOOSE_TAC `k:real`)) THEN
10949 EXISTS_TAC `min d k` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
10952 let CONTINUOUS_ON_UNION = prove
10953 (`!f s t. closed s /\ closed t /\ f continuous_on s /\ f continuous_on t
10954 ==> f continuous_on (s UNION t)`,
10955 REWRITE_TAC[CONTINUOUS_ON; CLOSED_LIMPT; IN_UNION; LIM_WITHIN_UNION] THEN
10956 MESON_TAC[LIM; TRIVIAL_LIMIT_WITHIN]);;
10958 let CONTINUOUS_ON_CASES = prove
10959 (`!P f g:real^M->real^N s t.
10960 closed s /\ closed t /\ f continuous_on s /\ g continuous_on t /\
10961 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x)
10962 ==> (\x. if P x then f x else g x) continuous_on (s UNION t)`,
10963 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION THEN
10964 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL
10965 [EXISTS_TAC `f:real^M->real^N`; EXISTS_TAC `g:real^M->real^N`] THEN
10966 ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;
10968 let CONTINUOUS_ON_UNION_LOCAL = prove
10969 (`!f:real^M->real^N s.
10970 closed_in (subtopology euclidean (s UNION t)) s /\
10971 closed_in (subtopology euclidean (s UNION t)) t /\
10972 f continuous_on s /\ f continuous_on t
10973 ==> f continuous_on (s UNION t)`,
10974 REWRITE_TAC[CONTINUOUS_ON; CLOSED_IN_LIMPT; IN_UNION; LIM_WITHIN_UNION] THEN
10975 MESON_TAC[LIM; TRIVIAL_LIMIT_WITHIN]);;
10977 let CONTINUOUS_ON_CASES_LOCAL = prove
10978 (`!P f g:real^M->real^N s t.
10979 closed_in (subtopology euclidean (s UNION t)) s /\
10980 closed_in (subtopology euclidean (s UNION t)) t /\
10981 f continuous_on s /\ g continuous_on t /\
10982 (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x)
10983 ==> (\x. if P x then f x else g x) continuous_on (s UNION t)`,
10984 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_UNION_LOCAL THEN
10985 ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_EQ THENL
10986 [EXISTS_TAC `f:real^M->real^N`; EXISTS_TAC `g:real^M->real^N`] THEN
10987 ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;
10989 let CONTINUOUS_ON_CASES_LE = prove
10990 (`!f g:real^M->real^N h s a.
10991 f continuous_on {t | t IN s /\ h t <= a} /\
10992 g continuous_on {t | t IN s /\ a <= h t} /\
10993 (lift o h) continuous_on s /\
10994 (!t. t IN s /\ h t = a ==> f t = g t)
10995 ==> (\t. if h t <= a then f(t) else g(t)) continuous_on s`,
10996 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC
10997 `{t | t IN s /\ (h:real^M->real) t <= a} UNION
10998 {t | t IN s /\ a <= h t}` THEN
11000 [ALL_TAC; SIMP_TAC[SUBSET; IN_UNION; IN_ELIM_THM; REAL_LE_TOTAL]] THEN
11001 MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN ASM_REWRITE_TAC[] THEN
11002 REWRITE_TAC[IN_ELIM_THM; GSYM CONJ_ASSOC; REAL_LE_ANTISYM] THEN
11003 REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL
11004 [ALL_TAC; ASM_MESON_TAC[]] THEN
11007 `{t | t IN s /\ (h:real^M->real) t <= a} =
11008 {t | t IN ({t | t IN s /\ h t <= a} UNION {t | t IN s /\ a <= h t}) /\
11009 (lift o h) t IN {x | x$1 <= a}}`
11010 (fun th -> GEN_REWRITE_TAC RAND_CONV [th])
11012 [REWRITE_TAC[GSYM drop; o_THM; IN_ELIM_THM; LIFT_DROP; EXTENSION;
11014 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
11015 ASM_REAL_ARITH_TAC;
11016 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN
11017 ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE; ETA_AX] THEN
11018 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
11019 CONTINUOUS_ON_SUBSET)) THEN
11022 `{t | t IN s /\ a <= (h:real^M->real) t} =
11023 {t | t IN ({t | t IN s /\ h t <= a} UNION {t | t IN s /\ a <= h t}) /\
11024 (lift o h) t IN {x | x$1 >= a}}`
11025 (fun th -> GEN_REWRITE_TAC RAND_CONV [th])
11027 [REWRITE_TAC[GSYM drop; o_THM; IN_ELIM_THM; LIFT_DROP; EXTENSION;
11029 GEN_TAC THEN EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
11030 ASM_REAL_ARITH_TAC;
11031 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN
11032 ASM_REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_GE; ETA_AX] THEN
11033 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
11034 CONTINUOUS_ON_SUBSET)) THEN
11037 let CONTINUOUS_ON_CASES_1 = prove
11038 (`!f g:real^1->real^N s a.
11039 f continuous_on {t | t IN s /\ drop t <= a} /\
11040 g continuous_on {t | t IN s /\ a <= drop t} /\
11041 (lift a IN s ==> f(lift a) = g(lift a))
11042 ==> (\t. if drop t <= a then f(t) else g(t)) continuous_on s`,
11043 REPEAT STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LE THEN
11044 ASM_REWRITE_TAC[o_DEF; LIFT_DROP; CONTINUOUS_ON_ID] THEN
11045 REWRITE_TAC[GSYM LIFT_EQ; LIFT_DROP] THEN ASM_MESON_TAC[]);;
11047 (* ------------------------------------------------------------------------- *)
11048 (* Componentwise limits and continuity. *)
11049 (* ------------------------------------------------------------------------- *)
11051 let LIM_COMPONENTWISE_LIFT = prove
11052 (`!net f:A->real^N.
11054 !i. 1 <= i /\ i <= dimindex(:N)
11055 ==> ((\x. lift((f x)$i)) --> lift(l$i)) net`,
11056 REPEAT GEN_TAC THEN REWRITE_TAC[tendsto] THEN EQ_TAC THENL
11057 [DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
11058 X_GEN_TAC `e:real` THEN
11059 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN
11060 ASM_SIMP_TAC[GSYM VECTOR_SUB_COMPONENT] THEN
11061 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
11062 GEN_TAC THEN REWRITE_TAC[dist] THEN MATCH_MP_TAC(REAL_ARITH
11063 `y <= x ==> x < e ==> y < e`) THEN
11064 ASM_SIMP_TAC[COMPONENT_LE_NORM; GSYM LIFT_SUB; NORM_LIFT;
11065 GSYM VECTOR_SUB_COMPONENT];
11066 GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [RIGHT_IMP_FORALL_THM] THEN
11067 ONCE_REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[IMP_CONJ_ALT] THEN
11068 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
11069 REWRITE_TAC[GSYM IN_NUMSEG; RIGHT_FORALL_IMP_THM] THEN
11070 SIMP_TAC[FORALL_EVENTUALLY; FINITE_NUMSEG; NUMSEG_EMPTY;
11071 GSYM NOT_LE; DIMINDEX_GE_1] THEN
11072 REWRITE_TAC[DIST_LIFT; GSYM VECTOR_SUB_COMPONENT] THEN
11073 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11074 FIRST_X_ASSUM(MP_TAC o SPEC `e / &(dimindex(:N))`) THEN
11075 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1] THEN
11076 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
11077 X_GEN_TAC `x:A` THEN SIMP_TAC[GSYM VECTOR_SUB_COMPONENT; dist] THEN
11078 DISCH_TAC THEN W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN
11079 MATCH_MP_TAC(REAL_ARITH `s < e ==> n <= s ==> n < e`) THEN
11080 MATCH_MP_TAC SUM_BOUND_LT_GEN THEN
11081 ASM_SIMP_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; GSYM NOT_LE; DIMINDEX_GE_1;
11082 CARD_NUMSEG_1; GSYM IN_NUMSEG]]);;
11084 let CONTINUOUS_COMPONENTWISE_LIFT = prove
11085 (`!net f:A->real^N.
11086 f continuous net <=>
11087 !i. 1 <= i /\ i <= dimindex(:N)
11088 ==> (\x. lift((f x)$i)) continuous net`,
11089 REWRITE_TAC[continuous; GSYM LIM_COMPONENTWISE_LIFT]);;
11091 let CONTINUOUS_ON_COMPONENTWISE_LIFT = prove
11092 (`!f:real^M->real^N s.
11093 f continuous_on s <=>
11094 !i. 1 <= i /\ i <= dimindex(:N)
11095 ==> (\x. lift((f x)$i)) continuous_on s`,
11096 REPEAT GEN_TAC THEN
11097 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
11098 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
11099 [CONTINUOUS_COMPONENTWISE_LIFT] THEN
11102 (* ------------------------------------------------------------------------- *)
11103 (* Some more convenient intermediate-value theorem formulations. *)
11104 (* ------------------------------------------------------------------------- *)
11106 let CONNECTED_IVT_HYPERPLANE = prove
11107 (`!s x y:real^N a b.
11109 x IN s /\ y IN s /\ a dot x <= b /\ b <= a dot y
11110 ==> ?z. z IN s /\ a dot z = b`,
11111 REPEAT STRIP_TAC THEN
11112 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [connected]) THEN
11113 REWRITE_TAC[NOT_EXISTS_THM] THEN DISCH_THEN(MP_TAC o SPECL
11114 [`{x:real^N | a dot x < b}`; `{x:real^N | a dot x > b}`]) THEN
11115 REWRITE_TAC[OPEN_HALFSPACE_LT; OPEN_HALFSPACE_GT] THEN
11116 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN STRIP_TAC THEN
11117 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; NOT_IN_EMPTY; SUBSET;
11118 IN_UNION; REAL_LT_LE; real_gt] THEN
11119 ASM_MESON_TAC[REAL_LE_TOTAL; REAL_LE_ANTISYM]);;
11121 let CONNECTED_IVT_COMPONENT = prove
11122 (`!s x y:real^N a k.
11123 connected s /\ x IN s /\ y IN s /\
11124 1 <= k /\ k <= dimindex(:N) /\ x$k <= a /\ a <= y$k
11125 ==> ?z. z IN s /\ z$k = a`,
11126 REPEAT STRIP_TAC THEN MP_TAC(ISPECL
11127 [`s:real^N->bool`; `x:real^N`; `y:real^N`; `(basis k):real^N`;
11128 `a:real`] CONNECTED_IVT_HYPERPLANE) THEN
11129 ASM_SIMP_TAC[DOT_BASIS]);;
11131 (* ------------------------------------------------------------------------- *)
11132 (* Also more convenient formulations of monotone convergence. *)
11133 (* ------------------------------------------------------------------------- *)
11135 let BOUNDED_INCREASING_CONVERGENT = prove
11137 bounded {s n | n IN (:num)} /\ (!n. drop(s n) <= drop(s(SUC n)))
11138 ==> ?l. (s --> l) sequentially`,
11140 REWRITE_TAC[bounded; IN_ELIM_THM; ABS_DROP; LIM_SEQUENTIALLY; dist;
11141 DROP_SUB; IN_UNIV; GSYM EXISTS_DROP] THEN
11142 DISCH_TAC THEN MATCH_MP_TAC CONVERGENT_BOUNDED_MONOTONE THEN
11143 REWRITE_TAC[LEFT_EXISTS_AND_THM] THEN
11144 CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
11145 DISJ1_TAC THEN MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
11146 ASM_REWRITE_TAC[REAL_LE_TRANS; REAL_LE_REFL]);;
11148 let BOUNDED_DECREASING_CONVERGENT = prove
11150 bounded {s n | n IN (:num)} /\ (!n. drop(s(SUC n)) <= drop(s(n)))
11151 ==> ?l. (s --> l) sequentially`,
11152 GEN_TAC THEN REWRITE_TAC[bounded; FORALL_IN_GSPEC] THEN
11153 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
11154 MP_TAC(ISPEC `\n. --((s:num->real^1) n)` BOUNDED_INCREASING_CONVERGENT) THEN
11155 ASM_SIMP_TAC[bounded; FORALL_IN_GSPEC; NORM_NEG; DROP_NEG; REAL_LE_NEG2] THEN
11156 GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [GSYM LIM_NEG_EQ] THEN
11157 REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX] THEN MESON_TAC[]);;
11159 (* ------------------------------------------------------------------------- *)
11160 (* Since we'll use some cardinality reasoning, add invariance theorems. *)
11161 (* ------------------------------------------------------------------------- *)
11163 let card_translation_invariants = (CONJUNCTS o prove)
11164 (`(!a (s:real^N->bool) (t:A->bool).
11165 IMAGE (\x. a + x) s =_c t <=> s =_c t) /\
11166 (!a (s:A->bool) (t:real^N->bool).
11167 s =_c IMAGE (\x. a + x) t <=> s =_c t) /\
11168 (!a (s:real^N->bool) (t:A->bool).
11169 IMAGE (\x. a + x) s <_c t <=> s <_c t) /\
11170 (!a (s:A->bool) (t:real^N->bool).
11171 s <_c IMAGE (\x. a + x) t <=> s <_c t) /\
11172 (!a (s:real^N->bool) (t:A->bool).
11173 IMAGE (\x. a + x) s <=_c t <=> s <=_c t) /\
11174 (!a (s:A->bool) (t:real^N->bool).
11175 s <=_c IMAGE (\x. a + x) t <=> s <=_c t) /\
11176 (!a (s:real^N->bool) (t:A->bool).
11177 IMAGE (\x. a + x) s >_c t <=> s >_c t) /\
11178 (!a (s:A->bool) (t:real^N->bool).
11179 s >_c IMAGE (\x. a + x) t <=> s >_c t) /\
11180 (!a (s:real^N->bool) (t:A->bool).
11181 IMAGE (\x. a + x) s >=_c t <=> s >=_c t) /\
11182 (!a (s:A->bool) (t:real^N->bool).
11183 s >=_c IMAGE (\x. a + x) t <=> s >=_c t)`,
11184 REWRITE_TAC[gt_c; ge_c] THEN REPEAT STRIP_TAC THENL
11185 [MATCH_MP_TAC CARD_EQ_CONG;
11186 MATCH_MP_TAC CARD_EQ_CONG;
11187 MATCH_MP_TAC CARD_LT_CONG;
11188 MATCH_MP_TAC CARD_LT_CONG;
11189 MATCH_MP_TAC CARD_LE_CONG;
11190 MATCH_MP_TAC CARD_LE_CONG;
11191 MATCH_MP_TAC CARD_LT_CONG;
11192 MATCH_MP_TAC CARD_LT_CONG;
11193 MATCH_MP_TAC CARD_LE_CONG;
11194 MATCH_MP_TAC CARD_LE_CONG] THEN
11195 REWRITE_TAC[CARD_EQ_REFL] THEN MATCH_MP_TAC CARD_EQ_IMAGE THEN
11196 SIMP_TAC[VECTOR_ARITH `a + x:real^N = a + y <=> x = y`]) in
11197 add_translation_invariants card_translation_invariants;;
11199 let card_linear_invariants = (CONJUNCTS o prove)
11200 (`(!(f:real^M->real^N) s (t:A->bool).
11201 linear f /\ (!x y. f x = f y ==> x = y)
11202 ==> (IMAGE f s =_c t <=> s =_c t)) /\
11203 (!(f:real^M->real^N) (s:A->bool) t.
11204 linear f /\ (!x y. f x = f y ==> x = y)
11205 ==> (s =_c IMAGE f t <=> s =_c t)) /\
11206 (!(f:real^M->real^N) s (t:A->bool).
11207 linear f /\ (!x y. f x = f y ==> x = y)
11208 ==> (IMAGE f s <_c t <=> s <_c t)) /\
11209 (!(f:real^M->real^N) (s:A->bool) t.
11210 linear f /\ (!x y. f x = f y ==> x = y)
11211 ==> (s <_c IMAGE f t <=> s <_c t)) /\
11212 (!(f:real^M->real^N) s (t:A->bool).
11213 linear f /\ (!x y. f x = f y ==> x = y)
11214 ==> (IMAGE f s <=_c t <=> s <=_c t)) /\
11215 (!(f:real^M->real^N) (s:A->bool) t.
11216 linear f /\ (!x y. f x = f y ==> x = y)
11217 ==> (s <=_c IMAGE f t <=> s <=_c t)) /\
11218 (!(f:real^M->real^N) s (t:A->bool).
11219 linear f /\ (!x y. f x = f y ==> x = y)
11220 ==> (IMAGE f s >_c t <=> s >_c t)) /\
11221 (!(f:real^M->real^N) (s:A->bool) t.
11222 linear f /\ (!x y. f x = f y ==> x = y)
11223 ==> (s >_c IMAGE f t <=> s >_c t)) /\
11224 (!(f:real^M->real^N) s (t:A->bool).
11225 linear f /\ (!x y. f x = f y ==> x = y)
11226 ==> (IMAGE f s >=_c t <=> s >=_c t)) /\
11227 (!(f:real^M->real^N) (s:A->bool) t.
11228 linear f /\ (!x y. f x = f y ==> x = y)
11229 ==> (s >=_c IMAGE f t <=> s >=_c t))`,
11230 REWRITE_TAC[gt_c; ge_c] THEN REPEAT STRIP_TAC THENL
11231 [MATCH_MP_TAC CARD_EQ_CONG;
11232 MATCH_MP_TAC CARD_EQ_CONG;
11233 MATCH_MP_TAC CARD_LT_CONG;
11234 MATCH_MP_TAC CARD_LT_CONG;
11235 MATCH_MP_TAC CARD_LE_CONG;
11236 MATCH_MP_TAC CARD_LE_CONG;
11237 MATCH_MP_TAC CARD_LT_CONG;
11238 MATCH_MP_TAC CARD_LT_CONG;
11239 MATCH_MP_TAC CARD_LE_CONG;
11240 MATCH_MP_TAC CARD_LE_CONG] THEN
11241 REWRITE_TAC[CARD_EQ_REFL] THEN MATCH_MP_TAC CARD_EQ_IMAGE THEN
11242 ASM_MESON_TAC[]) in
11243 add_linear_invariants card_linear_invariants;;
11245 (* ------------------------------------------------------------------------- *)
11246 (* Basic homeomorphism definitions. *)
11247 (* ------------------------------------------------------------------------- *)
11249 let homeomorphism = new_definition
11250 `homeomorphism (s,t) (f,g) <=>
11251 (!x. x IN s ==> (g(f(x)) = x)) /\ (IMAGE f s = t) /\ f continuous_on s /\
11252 (!y. y IN t ==> (f(g(y)) = y)) /\ (IMAGE g t = s) /\ g continuous_on t`;;
11254 parse_as_infix("homeomorphic",(12,"right"));;
11256 let homeomorphic = new_definition
11257 `s homeomorphic t <=> ?f g. homeomorphism (s,t) (f,g)`;;
11259 let HOMEOMORPHISM = prove
11260 (`!s:real^M->bool t:real^N->bool f g.
11261 homeomorphism (s,t) (f,g) <=>
11262 f continuous_on s /\ IMAGE f s SUBSET t /\
11263 g continuous_on t /\ IMAGE g t SUBSET s /\
11264 (!x. x IN s ==> g (f x) = x) /\
11265 (!y. y IN t ==> f (g y) = y)`,
11266 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphism] THEN
11267 EQ_TAC THEN SIMP_TAC[] THEN SET_TAC[]);;
11269 let HOMEOMORPHISM_OF_SUBSETS = prove
11271 homeomorphism (s,t) (f,g) /\ s' SUBSET s /\ t' SUBSET t /\ IMAGE f s' = t'
11272 ==> homeomorphism (s',t') (f,g)`,
11273 REWRITE_TAC[homeomorphism] THEN
11274 REPEAT STRIP_TAC THEN
11275 TRY(MATCH_MP_TAC CONTINUOUS_ON_SUBSET) THEN ASM SET_TAC[]);;
11277 let HOMEOMORPHISM_ID = prove
11278 (`!s:real^N->bool. homeomorphism (s,s) ((\x. x),(\x. x))`,
11279 REWRITE_TAC[homeomorphism; IMAGE_ID; CONTINUOUS_ON_ID]);;
11281 let HOMEOMORPHISM_I = prove
11282 (`!s:real^N->bool. homeomorphism (s,s) (I,I)`,
11283 REWRITE_TAC[I_DEF; HOMEOMORPHISM_ID]);;
11285 let HOMEOMORPHIC_REFL = prove
11286 (`!s:real^N->bool. s homeomorphic s`,
11287 REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_I]);;
11289 let HOMEOMORPHISM_SYM = prove
11290 (`!f:real^M->real^N g s t.
11291 homeomorphism (s,t) (f,g) <=> homeomorphism (t,s) (g,f)`,
11292 REWRITE_TAC[homeomorphism] THEN MESON_TAC[]);;
11294 let HOMEOMORPHIC_SYM = prove
11295 (`!s t. s homeomorphic t <=> t homeomorphic s`,
11296 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; homeomorphism] THEN
11297 GEN_REWRITE_TAC RAND_CONV [SWAP_EXISTS_THM] THEN
11298 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN CONV_TAC TAUT);;
11300 let HOMEOMORPHISM_COMPOSE = prove
11301 (`!f:real^M->real^N g h:real^N->real^P k s t u.
11302 homeomorphism (s,t) (f,g) /\ homeomorphism (t,u) (h,k)
11303 ==> homeomorphism (s,u) (h o f,g o k)`,
11304 SIMP_TAC[homeomorphism; CONTINUOUS_ON_COMPOSE; IMAGE_o; o_THM] THEN
11307 let HOMEOMORPHIC_TRANS = prove
11308 (`!s:real^M->bool t:real^N->bool u:real^P->bool.
11309 s homeomorphic t /\ t homeomorphic u ==> s homeomorphic u`,
11310 REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_COMPOSE]);;
11312 let HOMEOMORPHIC_IMP_CARD_EQ = prove
11313 (`!s:real^M->bool t:real^N->bool. s homeomorphic t ==> s =_c t`,
11314 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; homeomorphism; eq_c] THEN
11315 MATCH_MP_TAC MONO_EXISTS THEN SET_TAC[]);;
11317 let HOMEOMORPHIC_EMPTY = prove
11318 (`(!s. (s:real^N->bool) homeomorphic ({}:real^M->bool) <=> s = {}) /\
11319 (!s. ({}:real^M->bool) homeomorphic (s:real^N->bool) <=> s = {})`,
11320 REWRITE_TAC[homeomorphic; homeomorphism; IMAGE_CLAUSES; IMAGE_EQ_EMPTY] THEN
11321 REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN
11322 ASM_REWRITE_TAC[continuous_on; NOT_IN_EMPTY]);;
11324 let HOMEOMORPHIC_MINIMAL = prove
11325 (`!s t. s homeomorphic t <=>
11326 ?f g. (!x. x IN s ==> f(x) IN t /\ (g(f(x)) = x)) /\
11327 (!y. y IN t ==> g(y) IN s /\ (f(g(y)) = y)) /\
11328 f continuous_on s /\ g continuous_on t`,
11329 REWRITE_TAC[homeomorphic; homeomorphism; EXTENSION; IN_IMAGE] THEN
11330 REPEAT GEN_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN MESON_TAC[]);;
11332 let HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF = prove
11333 (`!f:real^M->real^N s.
11334 linear f /\ (!x y. f x = f y ==> x = y)
11335 ==> (IMAGE f s) homeomorphic s`,
11336 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
11337 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_LEFT_INVERSE]) THEN
11338 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN DISCH_TAC THEN
11339 EXISTS_TAC `f:real^M->real^N` THEN
11340 ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON; FORALL_IN_IMAGE; FUN_IN_IMAGE] THEN
11341 ASM_SIMP_TAC[continuous_on; IMP_CONJ; FORALL_IN_IMAGE] THEN
11342 X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
11343 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11344 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_BOUNDED_BELOW_POS) THEN
11345 ASM_REWRITE_TAC[] THEN
11346 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
11347 EXISTS_TAC `e * B:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN
11348 X_GEN_TAC `y:real^M` THEN ASM_SIMP_TAC[dist; GSYM LINEAR_SUB] THEN
11349 DISCH_TAC THEN ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ] THEN
11350 MATCH_MP_TAC(REAL_ARITH `a <= b ==> b < x ==> a < x`) THEN
11351 ASM_SIMP_TAC[REAL_LE_RDIV_EQ]);;
11353 let HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ = prove
11354 (`!f:real^M->real^N s t.
11355 linear f /\ (!x y. f x = f y ==> x = y)
11356 ==> ((IMAGE f s) homeomorphic t <=> s homeomorphic t)`,
11357 REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o SPEC `s:real^M->bool` o
11358 MATCH_MP HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_SELF) THEN
11360 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HOMEOMORPHIC_SYM]);
11361 POP_ASSUM MP_TAC] THEN
11362 REWRITE_TAC[IMP_IMP; HOMEOMORPHIC_TRANS]);;
11364 let HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ = prove
11365 (`!f:real^M->real^N s t.
11366 linear f /\ (!x y. f x = f y ==> x = y)
11367 ==> (s homeomorphic (IMAGE f t) <=> s homeomorphic t)`,
11368 ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN
11369 REWRITE_TAC[HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ]);;
11371 add_linear_invariants
11372 [HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ;
11373 HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ];;
11375 let HOMEOMORPHIC_TRANSLATION_SELF = prove
11376 (`!a:real^N s. (IMAGE (\x. a + x) s) homeomorphic s`,
11377 REPEAT GEN_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
11378 EXISTS_TAC `\x:real^N. x - a` THEN
11379 EXISTS_TAC `\x:real^N. a + x` THEN
11380 SIMP_TAC[FORALL_IN_IMAGE; CONTINUOUS_ON_SUB; CONTINUOUS_ON_ID;
11381 CONTINUOUS_ON_CONST; CONTINUOUS_ON_ADD; VECTOR_ADD_SUB] THEN
11382 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[]);;
11384 let HOMEOMORPHIC_TRANSLATION_LEFT_EQ = prove
11386 (IMAGE (\x. a + x) s) homeomorphic t <=> s homeomorphic t`,
11387 MESON_TAC[HOMEOMORPHIC_TRANSLATION_SELF;
11388 HOMEOMORPHIC_SYM; HOMEOMORPHIC_TRANS]);;
11390 let HOMEOMORPHIC_TRANSLATION_RIGHT_EQ = prove
11392 s homeomorphic (IMAGE (\x. a + x) t) <=> s homeomorphic t`,
11393 ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN
11394 REWRITE_TAC[HOMEOMORPHIC_TRANSLATION_LEFT_EQ]);;
11396 add_translation_invariants
11397 [HOMEOMORPHIC_TRANSLATION_LEFT_EQ;
11398 HOMEOMORPHIC_TRANSLATION_RIGHT_EQ];;
11400 let HOMEOMORPHISM_IMP_QUOTIENT_MAP = prove
11401 (`!f:real^M->real^N g s t.
11402 homeomorphism (s,t) (f,g)
11404 ==> (open_in (subtopology euclidean s) {x | x IN s /\ f x IN u} <=>
11405 open_in (subtopology euclidean t) u)`,
11406 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphism] THEN
11407 STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_RIGHT_INVERSE_IMP_QUOTIENT_MAP THEN
11408 EXISTS_TAC `g:real^N->real^M` THEN ASM_REWRITE_TAC[SUBSET_REFL]);;
11410 let HOMEOMORPHIC_PCROSS = prove
11411 (`!s:real^M->bool t:real^N->bool s':real^P->bool t':real^Q->bool.
11412 s homeomorphic s' /\ t homeomorphic t'
11413 ==> (s PCROSS t) homeomorphic (s' PCROSS t')`,
11414 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN
11415 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
11416 DISCH_THEN(CONJUNCTS_THEN2
11417 (X_CHOOSE_THEN `f:real^M->real^P`
11418 (X_CHOOSE_THEN `f':real^P->real^M` STRIP_ASSUME_TAC))
11419 (X_CHOOSE_THEN `g:real^N->real^Q`
11420 (X_CHOOSE_THEN `g':real^Q->real^N` STRIP_ASSUME_TAC))) THEN
11421 MAP_EVERY EXISTS_TAC
11422 [`(\z. pastecart (f(fstcart z)) (g(sndcart z)))
11423 :real^(M,N)finite_sum->real^(P,Q)finite_sum`;
11424 `(\z. pastecart (f'(fstcart z)) (g'(sndcart z)))
11425 :real^(P,Q)finite_sum->real^(M,N)finite_sum`] THEN
11426 ASM_SIMP_TAC[FORALL_IN_PCROSS; FSTCART_PASTECART; SNDCART_PASTECART;
11427 SUBSET; FORALL_IN_IMAGE; PASTECART_IN_PCROSS] THEN
11428 CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_PASTECART THEN
11429 CONJ_TAC THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN
11430 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
11431 SIMP_TAC[LINEAR_FSTCART; LINEAR_SNDCART; LINEAR_CONTINUOUS_ON] THEN
11432 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
11433 CONTINUOUS_ON_SUBSET)) THEN
11434 REWRITE_TAC[FORALL_IN_IMAGE; FORALL_IN_PCROSS; SUBSET] THEN
11435 SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART]);;
11437 let HOMEOMORPHIC_PCROSS_SYM = prove
11438 (`!s:real^M->bool t:real^N->bool. (s PCROSS t) homeomorphic (t PCROSS s)`,
11439 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; homeomorphism] THEN
11440 EXISTS_TAC `(\z. pastecart (sndcart z) (fstcart z))
11441 :real^(M,N)finite_sum->real^(N,M)finite_sum` THEN
11442 EXISTS_TAC `(\z. pastecart (sndcart z) (fstcart z))
11443 :real^(N,M)finite_sum->real^(M,N)finite_sum` THEN
11444 REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET; FORALL_IN_IMAGE] THEN
11445 SIMP_TAC[CONTINUOUS_ON_PASTECART; LINEAR_CONTINUOUS_ON;
11446 LINEAR_FSTCART; LINEAR_SNDCART] THEN
11447 REWRITE_TAC[FORALL_IN_PCROSS; FSTCART_PASTECART; SNDCART_PASTECART;
11448 IN_IMAGE; EXISTS_PASTECART; PASTECART_INJ; PASTECART_IN_PCROSS] THEN
11451 let HOMEOMORPHIC_PCROSS_ASSOC = prove
11452 (`!s:real^M->bool t:real^N->bool u:real^P->bool.
11453 (s PCROSS (t PCROSS u)) homeomorphic ((s PCROSS t) PCROSS u)`,
11454 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN
11455 MAP_EVERY EXISTS_TAC
11456 [`\z:real^(M,(N,P)finite_sum)finite_sum.
11457 pastecart (pastecart (fstcart z) (fstcart(sndcart z)))
11458 (sndcart(sndcart z))`;
11459 `\z:real^((M,N)finite_sum,P)finite_sum.
11460 pastecart (fstcart(fstcart z))
11461 (pastecart (sndcart(fstcart z)) (sndcart z))`] THEN
11462 REWRITE_TAC[FORALL_IN_PCROSS; SUBSET; FORALL_IN_IMAGE;
11463 RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN
11464 SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART; PASTECART_IN_PCROSS] THEN
11465 CONJ_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN
11466 REPEAT(MATCH_MP_TAC LINEAR_PASTECART THEN CONJ_TAC) THEN
11467 TRY(GEN_REWRITE_TAC RAND_CONV [GSYM o_DEF] THEN
11468 MATCH_MP_TAC LINEAR_COMPOSE) THEN
11469 REWRITE_TAC[LINEAR_FSTCART; LINEAR_SNDCART]);;
11471 let HOMEOMORPHIC_SCALING_LEFT = prove
11473 ==> !s t. (IMAGE (\x. c % x) s) homeomorphic t <=> s homeomorphic t`,
11474 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
11475 MATCH_MP_TAC HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_LEFT_EQ THEN
11476 ASM_SIMP_TAC[VECTOR_MUL_LCANCEL; REAL_LT_IMP_NZ; LINEAR_SCALING]);;
11478 let HOMEOMORPHIC_SCALING_RIGHT = prove
11480 ==> !s t. s homeomorphic (IMAGE (\x. c % x) t) <=> s homeomorphic t`,
11481 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
11482 MATCH_MP_TAC HOMEOMORPHIC_INJECTIVE_LINEAR_IMAGE_RIGHT_EQ THEN
11483 ASM_SIMP_TAC[VECTOR_MUL_LCANCEL; REAL_LT_IMP_NZ; LINEAR_SCALING]);;
11485 let HOMEOMORPHIC_SUBSPACES = prove
11486 (`!s:real^M->bool t:real^N->bool.
11487 subspace s /\ subspace t /\ dim s = dim t ==> s homeomorphic t`,
11488 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN
11489 DISCH_THEN(MP_TAC o MATCH_MP ISOMETRIES_SUBSPACES) THEN
11490 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f:real^M->real^N` THEN
11491 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN
11492 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTER; IN_CBALL_0] THEN
11493 SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN ASM SET_TAC[]);;
11495 let HOMEOMORPHIC_FINITE = prove
11496 (`!s:real^M->bool t:real^N->bool.
11497 FINITE s /\ FINITE t ==> (s homeomorphic t <=> CARD s = CARD t)`,
11498 REPEAT STRIP_TAC THEN EQ_TAC THENL
11499 [DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN
11500 ASM_SIMP_TAC[CARD_EQ_CARD];
11501 STRIP_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN
11502 MP_TAC(ISPECL [`s:real^M->bool`; `t:real^N->bool`]
11503 CARD_EQ_BIJECTIONS) THEN
11504 ASM_REWRITE_TAC[] THEN
11505 REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
11506 ASM_SIMP_TAC[CONTINUOUS_ON_FINITE] THEN ASM SET_TAC[]]);;
11508 let HOMEOMORPHIC_FINITE_STRONG = prove
11509 (`!s:real^M->bool t:real^N->bool.
11510 FINITE s \/ FINITE t
11511 ==> (s homeomorphic t <=> FINITE s /\ FINITE t /\ CARD s = CARD t)`,
11512 REPEAT GEN_TAC THEN DISCH_TAC THEN EQ_TAC THEN
11513 SIMP_TAC[HOMEOMORPHIC_FINITE] THEN DISCH_TAC THEN
11514 FIRST_ASSUM(MP_TAC o MATCH_MP CARD_FINITE_CONG o MATCH_MP
11515 HOMEOMORPHIC_IMP_CARD_EQ) THEN
11516 FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
11517 ASM_MESON_TAC[HOMEOMORPHIC_FINITE]);;
11519 let HOMEOMORPHIC_SING = prove
11520 (`!a:real^M b:real^N. {a} homeomorphic {b}`,
11521 SIMP_TAC[HOMEOMORPHIC_FINITE; FINITE_SING; CARD_SING]);;
11523 let HOMEOMORPHIC_PCROSS_SING = prove
11524 (`(!s:real^M->bool a:real^N. s homeomorphic (s PCROSS {a})) /\
11525 (!s:real^M->bool a:real^N. s homeomorphic ({a} PCROSS s))`,
11526 MATCH_MP_TAC(TAUT `(p ==> q) /\ p ==> p /\ q`) THEN CONJ_TAC THENL
11527 [MESON_TAC[HOMEOMORPHIC_PCROSS_SYM; HOMEOMORPHIC_TRANS]; ALL_TAC] THEN
11528 REPEAT GEN_TAC THEN REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN
11529 EXISTS_TAC `\x. (pastecart x a:real^(M,N)finite_sum)` THEN
11530 EXISTS_TAC `fstcart:real^(M,N)finite_sum->real^M` THEN
11531 SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN
11532 SIMP_TAC[LINEAR_FSTCART; LINEAR_CONTINUOUS_ON; SUBSET; FORALL_IN_IMAGE] THEN
11533 REWRITE_TAC[FORALL_IN_PCROSS; PASTECART_IN_PCROSS; IN_SING] THEN
11534 SIMP_TAC[FSTCART_PASTECART]);;
11536 (* ------------------------------------------------------------------------- *)
11537 (* Inverse function property for open/closed maps. *)
11538 (* ------------------------------------------------------------------------- *)
11540 let CONTINUOUS_ON_INVERSE_OPEN_MAP = prove
11541 (`!f:real^M->real^N g s t.
11542 f continuous_on s /\ IMAGE f s = t /\ (!x. x IN s ==> g(f x) = x) /\
11543 (!u. open_in (subtopology euclidean s) u
11544 ==> open_in (subtopology euclidean t) (IMAGE f u))
11545 ==> g continuous_on t`,
11546 REPEAT STRIP_TAC THEN
11547 MP_TAC(ISPECL [`g:real^N->real^M`; `t:real^N->bool`; `s:real^M->bool`]
11548 CONTINUOUS_ON_OPEN_GEN) THEN
11549 ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN SUBST1_TAC] THEN
11550 X_GEN_TAC `u:real^M->bool` THEN DISCH_TAC THEN
11551 FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M->bool`) THEN ASM_REWRITE_TAC[] THEN
11552 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
11553 FIRST_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [open_in]) THEN
11556 let CONTINUOUS_ON_INVERSE_CLOSED_MAP = prove
11557 (`!f:real^M->real^N g s t.
11558 f continuous_on s /\ IMAGE f s = t /\ (!x. x IN s ==> g(f x) = x) /\
11559 (!u. closed_in (subtopology euclidean s) u
11560 ==> closed_in (subtopology euclidean t) (IMAGE f u))
11561 ==> g continuous_on t`,
11562 REPEAT STRIP_TAC THEN
11563 MP_TAC(ISPECL [`g:real^N->real^M`; `t:real^N->bool`; `s:real^M->bool`]
11564 CONTINUOUS_ON_CLOSED_GEN) THEN
11565 ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN SUBST1_TAC] THEN
11566 X_GEN_TAC `u:real^M->bool` THEN DISCH_TAC THEN
11567 FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M->bool`) THEN ASM_REWRITE_TAC[] THEN
11568 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
11569 FIRST_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [closed_in]) THEN
11570 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM SET_TAC[]);;
11572 let HOMEOMORPHISM_INJECTIVE_OPEN_MAP = prove
11573 (`!f:real^M->real^N s t.
11574 f continuous_on s /\ IMAGE f s = t /\
11575 (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\
11576 (!u. open_in (subtopology euclidean s) u
11577 ==> open_in (subtopology euclidean t) (IMAGE f u))
11578 ==> ?g. homeomorphism (s,t) (f,g)`,
11579 REPEAT STRIP_TAC THEN
11580 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN
11581 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN
11582 DISCH_TAC THEN ASM_SIMP_TAC[homeomorphism] THEN
11583 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
11584 MATCH_MP_TAC CONTINUOUS_ON_INVERSE_OPEN_MAP THEN ASM_MESON_TAC[]);;
11586 let HOMEOMORPHISM_INJECTIVE_CLOSED_MAP = prove
11587 (`!f:real^M->real^N s t.
11588 f continuous_on s /\ IMAGE f s = t /\
11589 (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\
11590 (!u. closed_in (subtopology euclidean s) u
11591 ==> closed_in (subtopology euclidean t) (IMAGE f u))
11592 ==> ?g. homeomorphism (s,t) (f,g)`,
11593 REPEAT STRIP_TAC THEN
11594 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN
11595 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^M` THEN
11596 DISCH_TAC THEN ASM_SIMP_TAC[homeomorphism] THEN
11597 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
11598 MATCH_MP_TAC CONTINUOUS_ON_INVERSE_CLOSED_MAP THEN ASM_MESON_TAC[]);;
11600 let HOMEOMORPHISM_IMP_OPEN_MAP = prove
11601 (`!f:real^M->real^N g s t u.
11602 homeomorphism (s,t) (f,g) /\ open_in (subtopology euclidean s) u
11603 ==> open_in (subtopology euclidean t) (IMAGE f u)`,
11604 REWRITE_TAC[homeomorphism] THEN REPEAT STRIP_TAC THEN
11605 SUBGOAL_THEN `IMAGE (f:real^M->real^N) u =
11606 {y | y IN t /\ g(y) IN u}`
11608 [FIRST_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [open_in]) THEN
11610 MATCH_MP_TAC CONTINUOUS_ON_IMP_OPEN_IN THEN ASM_REWRITE_TAC[]]);;
11612 let HOMEOMORPHISM_IMP_CLOSED_MAP = prove
11613 (`!f:real^M->real^N g s t u.
11614 homeomorphism (s,t) (f,g) /\ closed_in (subtopology euclidean s) u
11615 ==> closed_in (subtopology euclidean t) (IMAGE f u)`,
11616 REWRITE_TAC[homeomorphism] THEN REPEAT STRIP_TAC THEN
11617 SUBGOAL_THEN `IMAGE (f:real^M->real^N) u =
11618 {y | y IN t /\ g(y) IN u}`
11620 [FIRST_ASSUM(MP_TAC o CONJUNCT1 o GEN_REWRITE_RULE I [closed_in]) THEN
11621 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM SET_TAC[];
11622 MATCH_MP_TAC CONTINUOUS_ON_IMP_CLOSED_IN THEN ASM_REWRITE_TAC[]]);;
11624 let HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ = prove
11625 (`!f:real^M->real^N s t.
11626 f continuous_on s /\ IMAGE f s = t /\
11627 (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y)
11628 ==> ((?g. homeomorphism (s,t) (f,g)) <=>
11629 !u. open_in (subtopology euclidean s) u
11630 ==> open_in (subtopology euclidean t) (IMAGE f u))`,
11631 REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
11632 [MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN ASM_MESON_TAC[];
11633 MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN
11634 ASM_REWRITE_TAC[]]);;
11636 let HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ = prove
11637 (`!f:real^M->real^N s t.
11638 f continuous_on s /\ IMAGE f s = t /\
11639 (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y)
11640 ==> ((?g. homeomorphism (s,t) (f,g)) <=>
11641 !u. closed_in (subtopology euclidean s) u
11642 ==> closed_in (subtopology euclidean t) (IMAGE f u))`,
11643 REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
11644 [MATCH_MP_TAC HOMEOMORPHISM_IMP_CLOSED_MAP THEN ASM_MESON_TAC[];
11645 MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_CLOSED_MAP THEN
11646 ASM_REWRITE_TAC[]]);;
11648 let INJECTIVE_MAP_OPEN_IFF_CLOSED = prove
11649 (`!f:real^M->real^N s t.
11650 f continuous_on s /\ IMAGE f s = t /\
11651 (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y)
11652 ==> ((!u. open_in (subtopology euclidean s) u
11653 ==> open_in (subtopology euclidean t) (IMAGE f u)) <=>
11654 (!u. closed_in (subtopology euclidean s) u
11655 ==> closed_in (subtopology euclidean t) (IMAGE f u)))`,
11656 REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
11657 EXISTS_TAC `?g:real^N->real^M. homeomorphism (s,t) (f,g)` THEN
11659 [CONV_TAC SYM_CONV THEN MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP_EQ;
11660 MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_CLOSED_MAP_EQ] THEN
11661 ASM_REWRITE_TAC[]);;
11663 (* ------------------------------------------------------------------------- *)
11664 (* Relatively weak hypotheses if the domain of the function is compact. *)
11665 (* ------------------------------------------------------------------------- *)
11667 let CONTINUOUS_IMP_CLOSED_MAP = prove
11668 (`!f:real^M->real^N s t.
11669 f continuous_on s /\ IMAGE f s = t /\ compact s
11670 ==> !u. closed_in (subtopology euclidean s) u
11671 ==> closed_in (subtopology euclidean t) (IMAGE f u)`,
11672 SIMP_TAC[CLOSED_IN_CLOSED_EQ; COMPACT_IMP_CLOSED] THEN
11673 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSED_CLOSED_IN_TRANS THEN
11674 EXPAND_TAC "t" THEN REWRITE_TAC[CONJ_ASSOC] THEN
11675 CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
11676 CONJ_TAC THEN MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
11677 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN ASM_REWRITE_TAC[] THEN
11678 ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_IN_CLOSED_TRANS;
11679 BOUNDED_SUBSET; CONTINUOUS_ON_SUBSET]);;
11681 let CONTINUOUS_ON_INVERSE = prove
11682 (`!f:real^M->real^N g s.
11683 f continuous_on s /\ compact s /\ (!x. x IN s ==> (g(f(x)) = x))
11684 ==> g continuous_on (IMAGE f s)`,
11685 REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_CLOSED] THEN
11686 SUBGOAL_THEN `IMAGE g (IMAGE (f:real^M->real^N) s) = s` SUBST1_TAC THENL
11687 [REWRITE_TAC[EXTENSION; IN_IMAGE] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
11688 X_GEN_TAC `t:real^M->bool` THEN DISCH_TAC THEN
11689 REWRITE_TAC[CLOSED_IN_CLOSED] THEN
11690 EXISTS_TAC `IMAGE (f:real^M->real^N) t` THEN CONJ_TAC THENL
11691 [MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
11692 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
11693 FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET) THEN
11694 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
11695 ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_IN_CLOSED_TRANS;
11696 BOUNDED_SUBSET; CONTINUOUS_ON_SUBSET];
11697 REWRITE_TAC[EXTENSION; IN_INTER; IN_ELIM_THM; IN_IMAGE] THEN
11698 ASM_MESON_TAC[CLOSED_IN_SUBSET; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY; SUBSET]]);;
11700 let HOMEOMORPHISM_COMPACT = prove
11701 (`!s f t. compact s /\ f continuous_on s /\ (IMAGE f s = t) /\
11702 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y))
11703 ==> ?g. homeomorphism(s,t) (f,g)`,
11704 REWRITE_TAC[INJECTIVE_ON_LEFT_INVERSE] THEN REPEAT GEN_TAC THEN
11705 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
11706 MATCH_MP_TAC MONO_EXISTS THEN ASM_SIMP_TAC[EXTENSION; homeomorphism] THEN
11707 FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
11708 ASM_MESON_TAC[CONTINUOUS_ON_INVERSE; IN_IMAGE]);;
11710 let HOMEOMORPHIC_COMPACT = prove
11711 (`!s f t. compact s /\ f continuous_on s /\ (IMAGE f s = t) /\
11712 (!x y. x IN s /\ y IN s /\ (f x = f y) ==> (x = y))
11713 ==> s homeomorphic t`,
11714 REWRITE_TAC[homeomorphic] THEN MESON_TAC[HOMEOMORPHISM_COMPACT]);;
11716 (* ------------------------------------------------------------------------- *)
11717 (* Lemmas about composition of homeomorphisms. *)
11718 (* ------------------------------------------------------------------------- *)
11720 let HOMEOMORPHISM_FROM_COMPOSITION_SURJECTIVE = prove
11721 (`!f:real^M->real^N g:real^N->real^P s t u.
11722 f continuous_on s /\ IMAGE f s = t /\
11723 g continuous_on t /\ IMAGE g t SUBSET u /\
11724 (?h. homeomorphism (s,u) (g o f,h))
11725 ==> (?f'. homeomorphism (s,t) (f,f')) /\
11726 (?g'. homeomorphism (t,u) (g,g'))`,
11727 REPEAT GEN_TAC THEN STRIP_TAC THEN
11728 RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism; o_THM]) THEN
11729 MATCH_MP_TAC(TAUT `q /\ (q ==> p) ==> p /\ q`) THEN CONJ_TAC THENL
11730 [MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN
11731 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
11732 MATCH_MP_TAC OPEN_MAP_FROM_COMPOSITION_SURJECTIVE THEN
11733 MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `s:real^M->bool`] THEN
11734 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
11735 MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN
11736 MAP_EVERY EXISTS_TAC [`h:real^P->real^M`; `s:real^M->bool`] THEN
11737 ASM_REWRITE_TAC[homeomorphism; o_THM];
11738 REWRITE_TAC[homeomorphism; o_THM] THEN
11739 DISCH_THEN(X_CHOOSE_THEN `g':real^P->real^N` STRIP_ASSUME_TAC) THEN
11740 EXISTS_TAC `(h:real^P->real^M) o (g:real^N->real^P)` THEN
11741 ASM_SIMP_TAC[o_THM; IMAGE_o] THEN
11742 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
11743 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
11744 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]);;
11746 let HOMEOMORPHISM_FROM_COMPOSITION_INJECTIVE = prove
11747 (`!f:real^M->real^N g:real^N->real^P s t u.
11748 f continuous_on s /\ IMAGE f s SUBSET t /\
11749 g continuous_on t /\ IMAGE g t SUBSET u /\
11750 (!x y. x IN t /\ y IN t /\ g x = g y ==> x = y) /\
11751 (?h. homeomorphism (s,u) (g o f,h))
11752 ==> (?f'. homeomorphism (s,t) (f,f')) /\
11753 (?g'. homeomorphism (t,u) (g,g'))`,
11754 REPEAT GEN_TAC THEN STRIP_TAC THEN
11755 RULE_ASSUM_TAC(REWRITE_RULE[homeomorphism; o_THM]) THEN
11756 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
11757 [MATCH_MP_TAC HOMEOMORPHISM_INJECTIVE_OPEN_MAP THEN
11758 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
11759 MATCH_MP_TAC OPEN_MAP_FROM_COMPOSITION_INJECTIVE THEN
11760 MAP_EVERY EXISTS_TAC [`g:real^N->real^P`; `u:real^P->bool`] THEN
11761 ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
11762 MATCH_MP_TAC HOMEOMORPHISM_IMP_OPEN_MAP THEN
11763 MAP_EVERY EXISTS_TAC [`h:real^P->real^M`; `s:real^M->bool`] THEN
11764 ASM_REWRITE_TAC[homeomorphism; o_THM];
11765 REWRITE_TAC[homeomorphism; o_THM] THEN
11766 DISCH_THEN(X_CHOOSE_THEN `f':real^N->real^M` STRIP_ASSUME_TAC) THEN
11767 EXISTS_TAC `(f:real^M->real^N) o (h:real^P->real^M)` THEN
11768 ASM_SIMP_TAC[o_THM; IMAGE_o] THEN
11769 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
11770 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
11771 ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]]);;
11773 (* ------------------------------------------------------------------------- *)
11774 (* Preservation of topological properties. *)
11775 (* ------------------------------------------------------------------------- *)
11777 let HOMEOMORPHIC_COMPACTNESS = prove
11778 (`!s t. s homeomorphic t ==> (compact s <=> compact t)`,
11779 REWRITE_TAC[homeomorphic; homeomorphism] THEN
11780 MESON_TAC[COMPACT_CONTINUOUS_IMAGE]);;
11782 let HOMEOMORPHIC_CONNECTEDNESS = prove
11783 (`!s t. s homeomorphic t ==> (connected s <=> connected t)`,
11784 REWRITE_TAC[homeomorphic; homeomorphism] THEN
11785 MESON_TAC[CONNECTED_CONTINUOUS_IMAGE]);;
11787 (* ------------------------------------------------------------------------- *)
11788 (* Results on translation, scaling etc. *)
11789 (* ------------------------------------------------------------------------- *)
11791 let HOMEOMORPHIC_SCALING = prove
11792 (`!s:real^N->bool c. ~(c = &0) ==> s homeomorphic (IMAGE (\x. c % x) s)`,
11793 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
11794 MAP_EVERY EXISTS_TAC [`\x:real^N. c % x`; `\x:real^N. inv(c) % x`] THEN
11795 ASM_SIMP_TAC[CONTINUOUS_ON_CMUL; CONTINUOUS_ON_ID; FORALL_IN_IMAGE] THEN
11796 ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_RINV] THEN
11797 SIMP_TAC[VECTOR_MUL_LID; IN_IMAGE; REAL_MUL_LID] THEN MESON_TAC[]);;
11799 let HOMEOMORPHIC_TRANSLATION = prove
11800 (`!s a:real^N. s homeomorphic (IMAGE (\x. a + x) s)`,
11801 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
11802 MAP_EVERY EXISTS_TAC [`\x:real^N. a + x`; `\x:real^N. --a + x`] THEN
11803 ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID] THEN
11804 SIMP_TAC[VECTOR_ADD_ASSOC; VECTOR_ADD_LINV; VECTOR_ADD_RINV;
11805 FORALL_IN_IMAGE; VECTOR_ADD_LID] THEN
11806 REWRITE_TAC[IN_IMAGE] THEN MESON_TAC[]);;
11808 let HOMEOMORPHIC_AFFINITY = prove
11809 (`!s a:real^N c. ~(c = &0) ==> s homeomorphic (IMAGE (\x. a + c % x) s)`,
11810 REPEAT STRIP_TAC THEN
11811 MATCH_MP_TAC HOMEOMORPHIC_TRANS THEN
11812 EXISTS_TAC `IMAGE (\x:real^N. c % x) s` THEN
11813 ASM_SIMP_TAC[HOMEOMORPHIC_SCALING] THEN
11814 SUBGOAL_THEN `(\x:real^N. a + c % x) = (\x. a + x) o (\x. c % x)`
11815 SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
11816 REWRITE_TAC[IMAGE_o; HOMEOMORPHIC_TRANSLATION]);;
11818 let [HOMEOMORPHIC_BALLS; HOMEOMORPHIC_CBALLS; HOMEOMORPHIC_SPHERES] =
11819 (CONJUNCTS o prove)
11820 (`(!a:real^N b:real^N d e.
11821 &0 < d /\ &0 < e ==> ball(a,d) homeomorphic ball(b,e)) /\
11822 (!a:real^N b:real^N d e.
11823 &0 < d /\ &0 < e ==> cball(a,d) homeomorphic cball(b,e)) /\
11824 (!a:real^N b:real^N d e.
11825 &0 < d /\ &0 < e ==> sphere(a,d) homeomorphic sphere(b,e))`,
11826 REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
11827 EXISTS_TAC `\x:real^N. b + (e / d) % (x - a)` THEN
11828 EXISTS_TAC `\x:real^N. a + (d / e) % (x - b)` THEN
11829 ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_SUB; CONTINUOUS_ON_CMUL;
11830 CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID; IN_BALL; IN_CBALL; IN_SPHERE] THEN
11831 REWRITE_TAC[dist; VECTOR_ARITH `a - (a + b) = --b:real^N`; NORM_NEG] THEN
11832 REWRITE_TAC[real_div; VECTOR_ARITH
11833 `a + d % ((b + e % (x - a)) - b) = (&1 - d * e) % a + (d * e) % x`] THEN
11834 ONCE_REWRITE_TAC[REAL_ARITH
11835 `(e * d') * (d * e') = (d * d') * (e * e')`] THEN
11836 ASM_SIMP_TAC[REAL_MUL_RINV; REAL_LT_IMP_NZ; REAL_MUL_LID; REAL_SUB_REFL] THEN
11837 REWRITE_TAC[NORM_MUL; VECTOR_MUL_LZERO; VECTOR_MUL_LID; VECTOR_ADD_LID] THEN
11838 ASM_SIMP_TAC[REAL_ABS_MUL; REAL_ABS_INV; REAL_ARITH
11839 `&0 < x ==> (abs x = x)`] THEN
11840 GEN_REWRITE_TAC(BINOP_CONV o BINDER_CONV o funpow 2 RAND_CONV)
11841 [GSYM REAL_MUL_RID] THEN
11842 ONCE_REWRITE_TAC[AC REAL_MUL_AC `(a * b) * c = (a * c) * b`] THEN
11843 ASM_SIMP_TAC[REAL_LE_LMUL_EQ; GSYM real_div; REAL_LE_LDIV_EQ; REAL_MUL_LID;
11844 GSYM REAL_MUL_ASSOC; REAL_LT_LMUL_EQ; REAL_LT_LDIV_EQ; NORM_SUB] THEN
11845 ASM_SIMP_TAC[REAL_DIV_REFL; REAL_LT_IMP_NZ; REAL_MUL_RID]);;
11847 (* ------------------------------------------------------------------------- *)
11848 (* Homeomorphism of one-point compactifications. *)
11849 (* ------------------------------------------------------------------------- *)
11851 let HOMEOMORPHIC_ONE_POINT_COMPACTIFICATIONS = prove
11852 (`!s:real^M->bool t:real^N->bool a b.
11853 compact s /\ compact t /\ a IN s /\ b IN t /\
11854 (s DELETE a) homeomorphic (t DELETE b)
11855 ==> s homeomorphic t`,
11856 REPEAT STRIP_TAC THEN MATCH_MP_TAC HOMEOMORPHIC_COMPACT THEN
11857 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [homeomorphic]) THEN
11858 REWRITE_TAC[HOMEOMORPHISM; LEFT_IMP_EXISTS_THM] THEN
11859 MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^N->real^M`] THEN
11861 EXISTS_TAC `\x. if x = a then b else (f:real^M->real^N) x` THEN
11862 ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
11863 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
11864 X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
11865 ASM_CASES_TAC `x:real^M = a` THEN ASM_REWRITE_TAC[] THENL
11866 [REWRITE_TAC[continuous_within] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11867 MP_TAC(ISPECL [`b:real^N`; `e:real`] CENTRE_IN_BALL) THEN
11868 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
11870 `closed_in (subtopology euclidean s)
11871 { x | x IN (s DELETE a) /\
11872 (f:real^M->real^N)(x) IN t DIFF ball(b,e)}`
11874 [MATCH_MP_TAC CLOSED_SUBSET THEN CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
11875 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN SUBGOAL_THEN
11876 `{x | x IN s DELETE a /\ f x IN t DIFF ball(b,e)} =
11877 IMAGE (g:real^N->real^M) (t DIFF ball (b,e))`
11878 SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
11879 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
11880 ASM_SIMP_TAC[COMPACT_DIFF; OPEN_BALL] THEN
11881 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
11882 CONTINUOUS_ON_SUBSET)) THEN ASM SET_TAC[];
11883 REWRITE_TAC[closed_in; open_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
11884 DISCH_THEN(MP_TAC o SPEC `a:real^M` o last o CONJUNCTS) THEN
11885 ASM_REWRITE_TAC[IN_ELIM_THM; IN_DIFF; IN_DELETE] THEN
11886 SIMP_TAC[IMP_CONJ; DE_MORGAN_THM] THEN
11887 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN
11888 ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN
11889 ASM_REWRITE_TAC[DIST_REFL] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
11890 RULE_ASSUM_TAC(REWRITE_RULE[IN_BALL]) THEN ASM SET_TAC[]];
11891 UNDISCH_TAC `(f:real^M->real^N) continuous_on (s DELETE a)` THEN
11892 REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
11893 DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[IN_DELETE] THEN
11894 REWRITE_TAC[continuous_within] THEN
11895 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
11896 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[IN_DELETE] THEN
11897 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
11898 EXISTS_TAC `min d (dist(a:real^M,x))` THEN
11899 ASM_REWRITE_TAC[REAL_LT_MIN; GSYM DIST_NZ] THEN
11900 ASM_MESON_TAC[REAL_LT_REFL]]);;
11902 (* ------------------------------------------------------------------------- *)
11903 (* Homeomorphisms between open intervals in real^1 and then in real^N. *)
11904 (* Could prove similar things for closed intervals, but they drop out of *)
11905 (* later stuff in "convex.ml" even more easily. *)
11906 (* ------------------------------------------------------------------------- *)
11908 let HOMEOMORPHIC_OPEN_INTERVALS_1 = prove
11910 drop a < drop b /\ drop c < drop d
11911 ==> interval(a,b) homeomorphic interval(c,d)`,
11913 `!a b. drop a < drop b
11914 ==> interval(vec 0:real^1,vec 1) homeomorphic interval(a,b)`
11916 [REPEAT STRIP_TAC THEN REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
11917 EXISTS_TAC `(\x. a + drop x % (b - a)):real^1->real^1` THEN
11918 EXISTS_TAC `(\x. inv(drop b - drop a) % (x - a)):real^1->real^1` THEN
11919 ASM_REWRITE_TAC[IN_INTERVAL_1; GSYM DROP_EQ] THEN
11920 REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_NEG; DROP_VEC; DROP_SUB] THEN
11921 REWRITE_TAC[REAL_ARITH `inv b * a:real = a / b`] THEN
11922 ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ; REAL_SUB_LT;
11923 REAL_LT_ADDR; REAL_EQ_LDIV_EQ; REAL_DIV_RMUL; REAL_LT_IMP_NZ;
11924 REAL_LT_MUL; REAL_MUL_LZERO; REAL_ADD_SUB; REAL_LT_RMUL_EQ;
11925 REAL_ARITH `a + x < b <=> x < &1 * (b - a)`] THEN
11926 REPEAT CONJ_TAC THENL
11928 MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
11929 MATCH_MP_TAC CONTINUOUS_ON_VMUL THEN
11930 REWRITE_TAC[o_DEF; LIFT_DROP; CONTINUOUS_ON_ID];
11931 MATCH_MP_TAC CONTINUOUS_ON_CMUL THEN
11932 ASM_SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]];
11933 REPEAT STRIP_TAC THEN
11934 FIRST_ASSUM(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN
11935 FIRST_X_ASSUM(MP_TAC o SPECL [`c:real^1`; `d:real^1`]) THEN
11936 ASM_REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN
11937 GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [HOMEOMORPHIC_SYM] THEN
11938 REWRITE_TAC[HOMEOMORPHIC_TRANS]]);;
11940 let HOMEOMORPHIC_OPEN_INTERVAL_UNIV_1 = prove
11941 (`!a b. drop a < drop b ==> interval(a,b) homeomorphic (:real^1)`,
11942 REPEAT STRIP_TAC THEN
11943 MP_TAC(SPECL [`a:real^1`; `b:real^1`; `--vec 1:real^1`; `vec 1:real^1`]
11944 HOMEOMORPHIC_OPEN_INTERVALS_1) THEN
11945 ASM_REWRITE_TAC[DROP_VEC; DROP_NEG] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
11946 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] HOMEOMORPHIC_TRANS) THEN
11947 POP_ASSUM_LIST(K ALL_TAC) THEN
11948 REWRITE_TAC[HOMEOMORPHIC_MINIMAL; IN_UNIV] THEN
11949 EXISTS_TAC `\x:real^1. inv(&1 - norm x) % x` THEN
11950 EXISTS_TAC `\y. if &0 <= drop y then inv(&1 + drop y) % y
11951 else inv(&1 - drop y) % y` THEN
11952 REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
11953 [X_GEN_TAC `x:real^1` THEN REWRITE_TAC[IN_INTERVAL_1] THEN
11954 REWRITE_TAC[DROP_NEG; DROP_VEC; DROP_CMUL; NORM_REAL; GSYM drop] THEN
11955 SIMP_TAC[REAL_LE_MUL_EQ; REAL_LT_INV_EQ; REAL_LE_MUL_EQ; REAL_ARITH
11956 `--a < x /\ x < a ==> &0 < a - abs x`] THEN
11957 SIMP_TAC[real_abs; VECTOR_MUL_ASSOC] THEN
11958 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
11959 GEN_REWRITE_TAC RAND_CONV [GSYM VECTOR_MUL_LID] THEN
11960 AP_THM_TAC THEN AP_TERM_TAC THEN
11961 REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD;
11962 X_GEN_TAC `y:real^1` THEN COND_CASES_TAC THEN
11963 ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_NEG; DROP_VEC; REAL_BOUNDS_LT] THEN
11964 REWRITE_TAC[DROP_CMUL; REAL_ABS_MUL; REAL_ABS_INV] THEN
11965 REWRITE_TAC[GSYM(ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div)] THEN
11966 ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 <= x ==> &0 < abs(&1 + x)`;
11967 REAL_ARITH `~(&0 <= x) ==> &0 < abs(&1 - x)`] THEN
11968 (CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
11969 REWRITE_TAC[NORM_REAL; VECTOR_MUL_ASSOC] THEN
11970 REWRITE_TAC[GSYM drop; DROP_CMUL; REAL_ABS_MUL] THEN
11971 ASM_REWRITE_TAC[real_abs; REAL_LE_INV_EQ] THEN
11972 ASM_SIMP_TAC[REAL_ARITH `&0 <= x ==> &0 <= &1 + x`;
11973 REAL_ARITH `~(&0 <= x) ==> &0 <= &1 - x`] THEN
11974 GEN_REWRITE_TAC RAND_CONV [GSYM VECTOR_MUL_LID] THEN
11975 AP_THM_TAC THEN AP_TERM_TAC THEN
11976 REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD;
11977 MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
11978 X_GEN_TAC `x:real^1` THEN
11979 REWRITE_TAC[IN_INTERVAL_1; DROP_NEG; DROP_VEC] THEN
11980 DISCH_TAC THEN MATCH_MP_TAC CONTINUOUS_MUL THEN
11981 REWRITE_TAC[CONTINUOUS_AT_ID] THEN
11982 ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN
11983 REWRITE_TAC[NETLIMIT_AT; o_DEF; LIFT_SUB; LIFT_DROP] THEN
11985 [MATCH_MP_TAC CONTINUOUS_SUB THEN
11986 SIMP_TAC[CONTINUOUS_CONST; REWRITE_RULE[o_DEF] CONTINUOUS_AT_LIFT_NORM];
11987 REWRITE_TAC[NORM_REAL; GSYM drop] THEN ASM_REAL_ARITH_TAC];
11988 SUBGOAL_THEN `(:real^1) = {x | x$1 >= &0} UNION {x | x$1 <= &0}`
11990 [REWRITE_TAC[EXTENSION; IN_UNION; IN_UNION; IN_ELIM_THM; IN_UNIV] THEN
11992 MATCH_MP_TAC CONTINUOUS_ON_CASES THEN
11993 REWRITE_TAC[CLOSED_HALFSPACE_COMPONENT_LE; CLOSED_HALFSPACE_COMPONENT_GE;
11995 REWRITE_TAC[GSYM drop; REAL_NOT_LE; real_ge; REAL_LET_ANTISYM] THEN
11996 SIMP_TAC[REAL_LE_ANTISYM; REAL_SUB_RZERO; REAL_ADD_RID] THEN
11997 CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
11998 X_GEN_TAC `y:real^1` THEN REWRITE_TAC[IN_ELIM_THM; real_ge] THEN
11999 DISCH_TAC THEN MATCH_MP_TAC CONTINUOUS_MUL THEN
12000 REWRITE_TAC[CONTINUOUS_AT_ID] THEN
12001 ONCE_REWRITE_TAC[GSYM o_DEF] THEN MATCH_MP_TAC CONTINUOUS_INV THEN
12002 REWRITE_TAC[NETLIMIT_AT; o_DEF; LIFT_ADD; LIFT_SUB; LIFT_DROP] THEN
12003 ASM_SIMP_TAC[CONTINUOUS_ADD; CONTINUOUS_AT_ID; CONTINUOUS_SUB;
12004 CONTINUOUS_CONST] THEN
12005 ASM_REAL_ARITH_TAC]]);;
12007 let HOMEOMORPHIC_OPEN_INTERVALS = prove
12008 (`!a b:real^N c d:real^N.
12009 (interval(a,b) = {} <=> interval(c,d) = {})
12010 ==> interval(a,b) homeomorphic interval(c,d)`,
12011 REPEAT GEN_TAC THEN ASM_CASES_TAC `interval(c:real^N,d) = {}` THEN
12012 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN ASM_REWRITE_TAC[HOMEOMORPHIC_REFL] THEN
12014 `!i. 1 <= i /\ i <= dimindex(:N)
12015 ==> interval(lift((a:real^N)$i),lift((b:real^N)$i)) homeomorphic
12016 interval(lift((c:real^N)$i),lift((d:real^N)$i))`
12018 [RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN
12019 ASM_SIMP_TAC[HOMEOMORPHIC_OPEN_INTERVALS_1; LIFT_DROP];
12021 REWRITE_TAC[HOMEOMORPHIC_MINIMAL; IN_INTERVAL_1; LIFT_DROP] THEN
12022 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
12023 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
12024 MAP_EVERY X_GEN_TAC [`f:num->real^1->real^1`; `g:num->real^1->real^1`] THEN
12028 drop((f:num->real^1->real^1) i (lift(x$i)))):real^N->real^N` THEN
12031 drop((g:num->real^1->real^1) i (lift(x$i)))):real^N->real^N` THEN
12032 ASM_SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; CART_EQ; LIFT_DROP] THEN
12033 ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN
12034 SIMP_TAC[LAMBDA_BETA; LIFT_DROP] THEN CONJ_TAC THEN REPEAT STRIP_TAC THEN
12035 ONCE_REWRITE_TAC[GSYM o_DEF] THEN
12036 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
12037 ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT] THEN
12038 MATCH_MP_TAC CONTINUOUS_ON_SUBSET THENL
12039 [EXISTS_TAC `interval(lift((a:real^N)$i),lift((b:real^N)$i))`;
12040 EXISTS_TAC `interval(lift((c:real^N)$i),lift((d:real^N)$i))`] THEN
12041 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1] THEN
12042 ASM_SIMP_TAC[LIFT_DROP; IN_INTERVAL]);;
12044 let HOMEOMORPHIC_OPEN_INTERVAL_UNIV = prove
12046 ~(interval(a,b) = {})
12047 ==> interval(a,b) homeomorphic (:real^N)`,
12048 REPEAT STRIP_TAC THEN
12050 `!i. 1 <= i /\ i <= dimindex(:N)
12051 ==> interval(lift((a:real^N)$i),lift((b:real^N)$i)) homeomorphic
12054 [RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN
12055 ASM_SIMP_TAC[HOMEOMORPHIC_OPEN_INTERVAL_UNIV_1; LIFT_DROP];
12057 REWRITE_TAC[HOMEOMORPHIC_MINIMAL; IN_INTERVAL_1; LIFT_DROP] THEN
12058 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
12059 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; IN_UNIV] THEN
12060 MAP_EVERY X_GEN_TAC [`f:num->real^1->real^1`; `g:num->real^1->real^1`] THEN
12064 drop((f:num->real^1->real^1) i (lift(x$i)))):real^N->real^N` THEN
12067 drop((g:num->real^1->real^1) i (lift(x$i)))):real^N->real^N` THEN
12068 ASM_SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; CART_EQ; LIFT_DROP; IN_UNIV] THEN
12069 ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN
12070 SIMP_TAC[LAMBDA_BETA; LIFT_DROP] THEN CONJ_TAC THEN REPEAT STRIP_TAC THEN
12071 ONCE_REWRITE_TAC[GSYM o_DEF] THEN
12072 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
12073 ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT] THEN
12074 MATCH_MP_TAC CONTINUOUS_ON_SUBSET THENL
12075 [EXISTS_TAC `interval(lift((a:real^N)$i),lift((b:real^N)$i))`;
12076 EXISTS_TAC `(:real^1)`] THEN
12077 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; IN_UNIV] THEN
12078 ASM_SIMP_TAC[LIFT_DROP; IN_INTERVAL]);;
12080 let HOMEOMORPHIC_BALL_UNIV = prove
12081 (`!a:real^N r. &0 < r ==> ball(a,r) homeomorphic (:real^N)`,
12082 REPEAT GEN_TAC THEN GEOM_ORIGIN_TAC `a:real^N` THEN REPEAT STRIP_TAC THEN
12083 SUBGOAL_THEN `?y:real^N. r = norm(y)` (CHOOSE_THEN SUBST_ALL_TAC) THENL
12084 [ASM_MESON_TAC[VECTOR_CHOOSE_SIZE; REAL_LT_IMP_LE]; POP_ASSUM MP_TAC] THEN
12085 REWRITE_TAC[NORM_POS_LT] THEN GEOM_NORMALIZE_TAC `y:real^N` THEN
12086 SIMP_TAC[] THEN GEN_TAC THEN REPEAT(DISCH_THEN(K ALL_TAC)) THEN
12087 REWRITE_TAC[HOMEOMORPHIC_MINIMAL] THEN
12088 EXISTS_TAC `\z:real^N. inv(&1 - norm(z)) % z` THEN
12089 EXISTS_TAC `\z:real^N. inv(&1 + norm(z)) % z` THEN
12090 REWRITE_TAC[IN_BALL; IN_UNIV; DIST_0; VECTOR_MUL_ASSOC; VECTOR_MUL_EQ_0;
12091 VECTOR_ARITH `a % x:real^N = x <=> (a - &1) % x = vec 0`] THEN
12092 REPEAT CONJ_TAC THENL
12093 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN DISJ1_TAC THEN
12094 REWRITE_TAC[GSYM REAL_INV_MUL; REAL_SUB_0; REAL_INV_EQ_1] THEN
12095 REWRITE_TAC[NORM_MUL; REAL_ABS_INV] THEN
12096 ASM_SIMP_TAC[REAL_ARITH `x < &1 ==> abs(&1 - x) = &1 - x`] THEN
12097 POP_ASSUM MP_TAC THEN CONV_TAC REAL_FIELD;
12098 X_GEN_TAC `y:real^N` THEN REWRITE_TAC[NORM_MUL; REAL_ABS_INV] THEN
12099 ASM_SIMP_TAC[NORM_POS_LE; REAL_ARITH
12100 `&0 <= y ==> inv(abs(&1 + y)) * z = z / (&1 + y)`] THEN
12101 ASM_SIMP_TAC[NORM_POS_LE; REAL_LT_LDIV_EQ; REAL_ARITH
12102 `&0 <= y ==> &0 < &1 + y`] THEN
12103 CONJ_TAC THENL [REAL_ARITH_TAC; DISJ1_TAC] THEN
12104 REWRITE_TAC[GSYM REAL_INV_MUL; REAL_SUB_0; REAL_INV_EQ_1] THEN
12105 MP_TAC(ISPEC `y:real^N` NORM_POS_LE) THEN CONV_TAC REAL_FIELD;
12106 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[CONTINUOUS_ON_ID] THEN
12107 GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM o_DEF] THEN
12108 MATCH_MP_TAC CONTINUOUS_ON_INV THEN
12109 SIMP_TAC[IN_BALL_0; REAL_SUB_0; REAL_ARITH `x < &1 ==> ~(&1 = x)`] THEN
12110 REWRITE_TAC[o_DEF; LIFT_SUB] THEN MATCH_MP_TAC CONTINUOUS_ON_SUB THEN
12111 REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
12112 MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN
12113 REWRITE_TAC[CONTINUOUS_ON_ID];
12114 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN REWRITE_TAC[CONTINUOUS_ON_ID] THEN
12115 GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM o_DEF] THEN
12116 MATCH_MP_TAC CONTINUOUS_ON_INV THEN
12117 SIMP_TAC[NORM_POS_LE; REAL_ARITH `&0 <= x ==> ~(&1 + x = &0)`] THEN
12118 REWRITE_TAC[o_DEF; LIFT_ADD] THEN MATCH_MP_TAC CONTINUOUS_ON_ADD THEN
12119 REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
12120 MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN
12121 REWRITE_TAC[CONTINUOUS_ON_ID]]);;
12123 (* ------------------------------------------------------------------------- *)
12124 (* Cardinalities of various useful sets. *)
12125 (* ------------------------------------------------------------------------- *)
12127 let CARD_EQ_EUCLIDEAN = prove
12128 (`(:real^N) =_c (:real)`,
12129 MATCH_MP_TAC CARD_EQ_CART THEN REWRITE_TAC[real_INFINITE]);;
12131 let UNCOUNTABLE_EUCLIDEAN = prove
12132 (`~COUNTABLE(:real^N)`,
12133 MATCH_MP_TAC CARD_EQ_REAL_IMP_UNCOUNTABLE THEN
12134 REWRITE_TAC[CARD_EQ_EUCLIDEAN]);;
12136 let CARD_EQ_INTERVAL = prove
12137 (`(!a b:real^N. ~(interval(a,b) = {}) ==> interval[a,b] =_c (:real)) /\
12138 (!a b:real^N. ~(interval(a,b) = {}) ==> interval(a,b) =_c (:real))`,
12139 REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN
12140 ASM_CASES_TAC `interval(a:real^N,b) = {}` THEN ASM_REWRITE_TAC[] THEN
12141 CONJ_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
12142 [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN
12143 REWRITE_TAC[CARD_LE_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN
12144 REWRITE_TAC[CARD_EQ_EUCLIDEAN];
12145 TRANS_TAC CARD_LE_TRANS `interval(a:real^N,b)` THEN
12146 SIMP_TAC[CARD_LE_SUBSET; INTERVAL_OPEN_SUBSET_CLOSED];
12147 TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN
12148 REWRITE_TAC[CARD_LE_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN
12149 REWRITE_TAC[CARD_EQ_EUCLIDEAN];
12151 TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN
12152 SIMP_TAC[ONCE_REWRITE_RULE[CARD_EQ_SYM] CARD_EQ_IMP_LE;
12153 CARD_EQ_EUCLIDEAN] THEN
12154 FIRST_X_ASSUM(MP_TAC o MATCH_MP HOMEOMORPHIC_OPEN_INTERVAL_UNIV) THEN
12155 DISCH_THEN(MP_TAC o MATCH_MP HOMEOMORPHIC_IMP_CARD_EQ) THEN
12156 MESON_TAC[CARD_EQ_IMP_LE; CARD_EQ_SYM]);;
12158 let UNCOUNTABLE_INTERVAL = prove
12159 (`(!a b. ~(interval(a,b) = {}) ==> ~COUNTABLE(interval[a,b])) /\
12160 (!a b. ~(interval(a,b) = {}) ==> ~COUNTABLE(interval(a,b)))`,
12161 SIMP_TAC[CARD_EQ_REAL_IMP_UNCOUNTABLE; CARD_EQ_INTERVAL]);;
12163 let COUNTABLE_OPEN_INTERVAL = prove
12164 (`!a b. COUNTABLE(interval(a,b)) <=> interval(a,b) = {}`,
12165 MESON_TAC[COUNTABLE_EMPTY; UNCOUNTABLE_INTERVAL]);;
12167 let CARD_EQ_OPEN = prove
12168 (`!s:real^N->bool. open s /\ ~(s = {}) ==> s =_c (:real)`,
12169 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
12170 [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN
12171 REWRITE_TAC[CARD_LE_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN
12172 REWRITE_TAC[CARD_EQ_EUCLIDEAN];
12173 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_INTERVAL]) THEN
12174 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
12175 DISCH_THEN(X_CHOOSE_TAC `c:real^N`) THEN
12176 DISCH_THEN(MP_TAC o SPEC `c:real^N`) THEN
12177 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
12178 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
12179 ASM_CASES_TAC `interval(a:real^N,b) = {}` THEN
12180 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN STRIP_TAC THEN
12181 TRANS_TAC CARD_LE_TRANS `interval[a:real^N,b]` THEN
12182 ASM_SIMP_TAC[CARD_LE_SUBSET] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN
12183 ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN ASM_SIMP_TAC[CARD_EQ_INTERVAL]]);;
12185 let UNCOUNTABLE_OPEN = prove
12186 (`!s:real^N->bool. open s /\ ~(s = {}) ==> ~(COUNTABLE s)`,
12187 SIMP_TAC[CARD_EQ_OPEN; CARD_EQ_REAL_IMP_UNCOUNTABLE]);;
12189 let CARD_EQ_BALL = prove
12190 (`!a:real^N r. &0 < r ==> ball(a,r) =_c (:real)`,
12191 SIMP_TAC[CARD_EQ_OPEN; OPEN_BALL; BALL_EQ_EMPTY; GSYM REAL_NOT_LT]);;
12193 let CARD_EQ_CBALL = prove
12194 (`!a:real^N r. &0 < r ==> cball(a,r) =_c (:real)`,
12195 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
12196 [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN
12197 REWRITE_TAC[CARD_LE_UNIV] THEN MATCH_MP_TAC CARD_EQ_IMP_LE THEN
12198 REWRITE_TAC[CARD_EQ_EUCLIDEAN];
12199 TRANS_TAC CARD_LE_TRANS `ball(a:real^N,r)` THEN
12200 SIMP_TAC[CARD_LE_SUBSET; BALL_SUBSET_CBALL] THEN
12201 MATCH_MP_TAC CARD_EQ_IMP_LE THEN
12202 ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN ASM_SIMP_TAC[CARD_EQ_BALL]]);;
12204 let FINITE_IMP_NOT_OPEN = prove
12205 (`!s:real^N->bool. FINITE s /\ ~(s = {}) ==> ~(open s)`,
12206 MESON_TAC[UNCOUNTABLE_OPEN; FINITE_IMP_COUNTABLE]);;
12208 let OPEN_IMP_INFINITE = prove
12209 (`!s. open s ==> s = {} \/ INFINITE s`,
12210 MESON_TAC[FINITE_IMP_NOT_OPEN; INFINITE]);;
12212 let EMPTY_INTERIOR_FINITE = prove
12213 (`!s:real^N->bool. FINITE s ==> interior s = {}`,
12214 REPEAT STRIP_TAC THEN MP_TAC(ISPEC `s:real^N->bool` OPEN_INTERIOR) THEN
12215 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
12216 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] FINITE_IMP_NOT_OPEN) THEN
12217 MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `s:real^N->bool` THEN
12218 ASM_REWRITE_TAC[INTERIOR_SUBSET]);;
12220 let CARD_EQ_CONNECTED = prove
12222 connected s /\ a IN s /\ b IN s /\ ~(a = b) ==> s =_c (:real)`,
12223 GEOM_ORIGIN_TAC `b:real^N` THEN GEOM_NORMALIZE_TAC `a:real^N` THEN
12224 REWRITE_TAC[NORM_EQ_SQUARE; REAL_POS; REAL_POW_ONE] THEN
12225 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
12226 [TRANS_TAC CARD_LE_TRANS `(:real^N)` THEN
12227 SIMP_TAC[CARD_LE_UNIV; CARD_EQ_EUCLIDEAN; CARD_EQ_IMP_LE];
12228 TRANS_TAC CARD_LE_TRANS `interval[vec 0:real^1,vec 1]` THEN CONJ_TAC THENL
12229 [MATCH_MP_TAC(ONCE_REWRITE_RULE[CARD_EQ_SYM] CARD_EQ_IMP_LE) THEN
12230 SIMP_TAC[UNIT_INTERVAL_NONEMPTY; CARD_EQ_INTERVAL];
12231 REWRITE_TAC[LE_C] THEN EXISTS_TAC `\x:real^N. lift(a dot x)` THEN
12232 SIMP_TAC[FORALL_LIFT; LIFT_EQ; IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN
12233 X_GEN_TAC `t:real` THEN STRIP_TAC THEN
12234 MATCH_MP_TAC CONNECTED_IVT_HYPERPLANE THEN
12235 MAP_EVERY EXISTS_TAC [`vec 0:real^N`; `a:real^N`] THEN
12236 ASM_REWRITE_TAC[DOT_RZERO]]]);;
12238 let UNCOUNTABLE_CONNECTED = prove
12240 connected s /\ a IN s /\ b IN s /\ ~(a = b) ==> ~COUNTABLE s`,
12241 REPEAT GEN_TAC THEN STRIP_TAC THEN
12242 MATCH_MP_TAC CARD_EQ_REAL_IMP_UNCOUNTABLE THEN
12243 MATCH_MP_TAC CARD_EQ_CONNECTED THEN
12246 let CARD_LT_IMP_DISCONNECTED = prove
12247 (`!s x:real^N. s <_c (:real) /\ x IN s ==> connected_component s x = {x}`,
12248 REPEAT STRIP_TAC THEN REWRITE_TAC[SET_RULE
12249 `s = {a} <=> a IN s /\ !a b. a IN s /\ b IN s /\ ~(a = b) ==> F`] THEN
12250 REPEAT STRIP_TAC THEN REWRITE_TAC[IN] THEN
12251 ASM_REWRITE_TAC[CONNECTED_COMPONENT_REFL_EQ] THEN
12252 MP_TAC(ISPECL [`connected_component s (x:real^N)`; `a:real^N`; `b:real^N`]
12253 CARD_EQ_CONNECTED) THEN
12254 ASM_REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN
12255 DISCH_TAC THEN UNDISCH_TAC `(s:real^N->bool) <_c (:real)` THEN
12256 REWRITE_TAC[CARD_NOT_LT] THEN
12257 TRANS_TAC CARD_LE_TRANS `connected_component s (x:real^N)` THEN
12258 ASM_SIMP_TAC[ONCE_REWRITE_RULE[CARD_EQ_SYM] CARD_EQ_IMP_LE] THEN
12259 MATCH_MP_TAC CARD_LE_SUBSET THEN REWRITE_TAC[CONNECTED_COMPONENT_SUBSET]);;
12261 let COUNTABLE_IMP_DISCONNECTED = prove
12262 (`!s x:real^N. COUNTABLE s /\ x IN s ==> connected_component s x = {x}`,
12263 SIMP_TAC[CARD_LT_IMP_DISCONNECTED; COUNTABLE_IMP_CARD_LT_REAL]);;
12265 let CONNECTED_CARD_EQ_IFF_NONTRIVIAL = prove
12267 connected s ==> (s =_c (:real) <=> ~(?a. s SUBSET {a}))`,
12268 REPEAT STRIP_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
12269 [ALL_TAC; MATCH_MP_TAC CARD_EQ_CONNECTED THEN ASM SET_TAC[]] THEN
12270 FIRST_ASSUM(MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ_ALT] FINITE_SUBSET)) THEN
12271 REWRITE_TAC[FINITE_SING] THEN
12272 ASM_MESON_TAC[CARD_EQ_REAL_IMP_UNCOUNTABLE; FINITE_IMP_COUNTABLE]);;
12274 (* ------------------------------------------------------------------------- *)
12275 (* "Iff" forms of constancy of function from connected set into a set that *)
12276 (* is smaller than R, or countable, or finite, or disconnected, or discrete. *)
12277 (* ------------------------------------------------------------------------- *)
12279 let [CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ;
12280 CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ;
12281 CONTINUOUS_FINITE_RANGE_CONSTANT_EQ] = (CONJUNCTS o prove)
12282 (`(!s. connected s <=>
12283 !f:real^M->real^N t.
12284 f continuous_on s /\ IMAGE f s SUBSET t /\
12285 (!y. y IN t ==> connected_component t y = {y})
12286 ==> ?a. !x. x IN s ==> f x = a) /\
12287 (!s. connected s <=>
12289 f continuous_on s /\
12292 !y. y IN s /\ ~(f y = f x) ==> e <= norm(f y - f x))
12293 ==> ?a. !x. x IN s ==> f x = a) /\
12294 (!s. connected s <=>
12296 f continuous_on s /\ FINITE(IMAGE f s)
12297 ==> ?a. !x. x IN s ==> f x = a)`,
12298 REWRITE_TAC[AND_FORALL_THM] THEN X_GEN_TAC `s:real^M->bool` THEN
12300 `(s ==> t) /\ (t ==> u) /\ (u ==> v) /\ (v ==> s)
12301 ==> (s <=> t) /\ (s <=> u) /\ (s <=> v)`) THEN
12302 REPEAT CONJ_TAC THENL
12303 [REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^M->bool = {}` THEN
12304 ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN
12305 FIRST_X_ASSUM(X_CHOOSE_TAC `x:real^M` o
12306 GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
12307 EXISTS_TAC `(f:real^M->real^N) x` THEN
12308 MATCH_MP_TAC(SET_RULE
12309 `IMAGE f s SUBSET {a} ==> !y. y IN s ==> f y = a`) THEN
12310 FIRST_X_ASSUM(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN
12311 ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN(SUBST1_TAC o SYM)] THEN
12312 MATCH_MP_TAC CONNECTED_COMPONENT_MAXIMAL THEN
12313 ASM_SIMP_TAC[CONNECTED_CONTINUOUS_IMAGE] THEN ASM SET_TAC[];
12314 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
12315 EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN
12316 ASM_REWRITE_TAC[FORALL_IN_IMAGE; SUBSET_REFL] THEN
12317 X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
12318 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN
12319 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
12320 MATCH_MP_TAC(SET_RULE
12321 `(!y. y IN s /\ f y IN connected_component (IMAGE f s) a ==> f y = a) /\
12322 connected_component (IMAGE f s) a SUBSET (IMAGE f s) /\
12323 connected_component (IMAGE f s) a a
12324 ==> connected_component (IMAGE f s) a = {a}`) THEN
12325 REWRITE_TAC[CONNECTED_COMPONENT_SUBSET; CONNECTED_COMPONENT_REFL_EQ] THEN
12326 ASM_SIMP_TAC[FUN_IN_IMAGE] THEN X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN
12327 MP_TAC(ISPEC `connected_component (IMAGE (f:real^M->real^N) s) (f x)`
12328 CONNECTED_CLOSED) THEN
12329 REWRITE_TAC[CONNECTED_CONNECTED_COMPONENT] THEN
12330 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
12331 ASM_REWRITE_TAC[] THEN MAP_EVERY EXISTS_TAC
12332 [`cball((f:real^M->real^N) x,e / &2)`;
12333 `(:real^N) DIFF ball((f:real^M->real^N) x,e)`] THEN
12334 REWRITE_TAC[GSYM OPEN_CLOSED; OPEN_BALL; CLOSED_CBALL] THEN
12335 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN REPEAT CONJ_TAC THENL
12336 [REWRITE_TAC[SUBSET; IN_CBALL; IN_UNION; IN_DIFF; IN_BALL; IN_UNIV] THEN
12337 MATCH_MP_TAC(MESON[SUBSET; CONNECTED_COMPONENT_SUBSET]
12338 `(!x. x IN s ==> P x)
12339 ==> (!x. x IN connected_component s y ==> P x)`) THEN
12340 REWRITE_TAC[FORALL_IN_IMAGE] THEN X_GEN_TAC `z:real^M` THEN
12341 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `z:real^M`) THEN
12342 ASM_REWRITE_TAC[] THEN CONV_TAC NORM_ARITH;
12343 MATCH_MP_TAC(SET_RULE
12344 `(!x. x IN s /\ x IN t ==> F) ==> s INTER t INTER u = {}`) THEN
12345 REWRITE_TAC[IN_BALL; IN_CBALL; IN_DIFF; IN_UNIV] THEN
12346 UNDISCH_TAC `&0 < e` THEN CONV_TAC NORM_ARITH;
12347 EXISTS_TAC `(f:real^M->real^N) x` THEN
12348 ASM_SIMP_TAC[CENTRE_IN_CBALL; REAL_HALF; REAL_LT_IMP_LE; IN_INTER] THEN
12349 REWRITE_TAC[IN] THEN
12350 ASM_SIMP_TAC[CONNECTED_COMPONENT_REFL_EQ; FUN_IN_IMAGE];
12351 EXISTS_TAC `(f:real^M->real^N) y` THEN
12352 ASM_REWRITE_TAC[IN_INTER; IN_DIFF; IN_UNIV; IN_BALL; REAL_NOT_LT] THEN
12353 ASM_SIMP_TAC[ONCE_REWRITE_RULE[DIST_SYM] dist]];
12354 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `f:real^M->real^N` THEN
12355 DISCH_THEN(fun th -> STRIP_TAC THEN MATCH_MP_TAC th) THEN
12356 ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
12357 ASM_CASES_TAC `IMAGE (f:real^M->real^N) s DELETE (f x) = {}` THENL
12358 [EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN ASM SET_TAC[];
12361 `inf{norm(z - f x) |z| z IN IMAGE (f:real^M->real^N) s DELETE (f x)}` THEN
12362 REWRITE_TAC[SIMPLE_IMAGE] THEN
12363 ASM_SIMP_TAC[REAL_LT_INF_FINITE; REAL_INF_LE_FINITE; FINITE_DELETE;
12364 FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
12365 REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN
12366 REWRITE_TAC[IN_DELETE; NORM_POS_LT; VECTOR_SUB_EQ; IN_IMAGE] THEN
12367 MESON_TAC[REAL_LE_REFL];
12368 REWRITE_TAC[CONNECTED_CLOSED_IN_EQ] THEN
12369 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
12370 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
12371 MAP_EVERY X_GEN_TAC [`t:real^M->bool`; `u:real^M->bool`] THEN
12372 STRIP_TAC THEN DISCH_THEN(MP_TAC o SPEC
12373 `(\x. if x IN t then vec 0 else basis 1):real^M->real^N`) THEN
12374 REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL
12375 [EXPAND_TAC "s" THEN MATCH_MP_TAC CONTINUOUS_ON_CASES_LOCAL THEN
12376 ASM_REWRITE_TAC[CONTINUOUS_ON_CONST] THEN ASM SET_TAC[];
12377 MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `{vec 0:real^N,basis 1}` THEN
12378 REWRITE_TAC[FINITE_INSERT; FINITE_EMPTY] THEN SET_TAC[];
12379 SUBGOAL_THEN `?a b:real^M. a IN s /\ a IN t /\ b IN s /\ ~(b IN t)`
12380 STRIP_ASSUME_TAC THENL
12381 [ASM SET_TAC[]; DISCH_THEN(CHOOSE_THEN MP_TAC)] THEN
12382 DISCH_THEN(fun th -> MP_TAC(SPEC `a:real^M` th) THEN
12383 MP_TAC(SPEC `b:real^M` th)) THEN
12384 ASM_REWRITE_TAC[] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
12385 CONV_TAC(RAND_CONV SYM_CONV) THEN
12386 SIMP_TAC[BASIS_NONZERO; LE_REFL; DIMINDEX_GE_1; REAL_LE_REFL]]]);;
12388 let CONTINUOUS_DISCONNECTED_RANGE_CONSTANT = prove
12389 (`!f:real^M->real^N s.
12391 f continuous_on s /\ IMAGE f s SUBSET t /\
12392 (!y. y IN t ==> connected_component t y = {y})
12393 ==> ?a. !x. x IN s ==> f x = a`,
12394 MESON_TAC[CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ]);;
12396 let CONTINUOUS_DISCRETE_RANGE_CONSTANT = prove
12397 (`!f:real^M->real^N s.
12399 f continuous_on s /\
12402 !y. y IN s /\ ~(f y = f x) ==> e <= norm(f y - f x))
12403 ==> ?a. !x. x IN s ==> f x = a`,
12404 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
12405 REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN
12406 REWRITE_TAC[IMP_IMP; GSYM CONTINUOUS_DISCRETE_RANGE_CONSTANT_EQ]);;
12408 let CONTINUOUS_FINITE_RANGE_CONSTANT = prove
12409 (`!f:real^M->real^N s.
12411 f continuous_on s /\
12413 ==> ?a. !x. x IN s ==> f x = a`,
12414 MESON_TAC[CONTINUOUS_FINITE_RANGE_CONSTANT_EQ]);;
12416 let CONTINUOUS_COUNTABLE_RANGE_CONSTANT_EQ = prove
12417 (`!s. connected s <=>
12419 f continuous_on s /\ COUNTABLE(IMAGE f s)
12420 ==> ?a. !x. x IN s ==> f x = a`,
12421 GEN_TAC THEN EQ_TAC THENL
12422 [REWRITE_TAC[CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ];
12423 REWRITE_TAC[CONTINUOUS_FINITE_RANGE_CONSTANT_EQ]] THEN
12424 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
12425 ASM_SIMP_TAC[FINITE_IMP_COUNTABLE] THEN
12426 EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN
12427 ASM_SIMP_TAC[COUNTABLE_IMP_DISCONNECTED; SUBSET_REFL]);;
12429 let CONTINUOUS_CARD_LT_RANGE_CONSTANT_EQ = prove
12430 (`!s. connected s <=>
12432 f continuous_on s /\ (IMAGE f s) <_c (:real)
12433 ==> ?a. !x. x IN s ==> f x = a`,
12434 GEN_TAC THEN EQ_TAC THENL
12435 [REWRITE_TAC[CONTINUOUS_DISCONNECTED_RANGE_CONSTANT_EQ];
12436 REWRITE_TAC[CONTINUOUS_COUNTABLE_RANGE_CONSTANT_EQ]] THEN
12437 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
12438 ASM_SIMP_TAC[COUNTABLE_IMP_CARD_LT_REAL] THEN
12439 EXISTS_TAC `IMAGE (f:real^M->real^N) s` THEN
12440 ASM_SIMP_TAC[CARD_LT_IMP_DISCONNECTED; SUBSET_REFL]);;
12442 let CONTINUOUS_COUNTABLE_RANGE_CONSTANT = prove
12443 (`!f:real^M->real^N s.
12444 connected s /\ f continuous_on s /\ COUNTABLE(IMAGE f s)
12445 ==> ?a. !x. x IN s ==> f x = a`,
12446 MESON_TAC[CONTINUOUS_COUNTABLE_RANGE_CONSTANT_EQ]);;
12448 let CONTINUOUS_CARD_LT_RANGE_CONSTANT = prove
12449 (`!f:real^M->real^N s.
12450 connected s /\ f continuous_on s /\ (IMAGE f s) <_c (:real)
12451 ==> ?a. !x. x IN s ==> f x = a`,
12452 MESON_TAC[CONTINUOUS_CARD_LT_RANGE_CONSTANT_EQ]);;
12454 (* ------------------------------------------------------------------------- *)
12455 (* Homeomorphism of hyperplanes. *)
12456 (* ------------------------------------------------------------------------- *)
12458 let HOMEOMORPHIC_HYPERPLANES = prove
12459 (`!a:real^N b c:real^N d.
12460 ~(a = vec 0) /\ ~(c = vec 0)
12461 ==> {x | a dot x = b} homeomorphic {x | c dot x = d}`,
12464 ==> {x:real^N | a dot x = b} homeomorphic {x:real^N | x$1 = &0}`,
12465 REPEAT STRIP_TAC THEN SUBGOAL_THEN `?c:real^N. a dot c = b`
12466 STRIP_ASSUME_TAC THENL
12467 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CART_EQ]) THEN
12468 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; VEC_COMPONENT] THEN
12469 DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN
12470 EXISTS_TAC `b / (a:real^N)$k % basis k:real^N` THEN
12471 ASM_SIMP_TAC[DOT_RMUL; DOT_BASIS; REAL_DIV_RMUL];
12472 FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
12473 ABBREV_TAC `p = {x:real^N | x$1 = &0}` THEN
12474 GEOM_ORIGIN_TAC `c:real^N` THEN
12475 REWRITE_TAC[VECTOR_ADD_RID; DOT_RADD; DOT_RZERO; REAL_EQ_ADD_LCANCEL_0;
12477 REPEAT STRIP_TAC THEN UNDISCH_TAC `~(a:real^N = vec 0)` THEN
12478 GEOM_BASIS_MULTIPLE_TAC 1 `a:real^N` THEN
12479 SIMP_TAC[VECTOR_MUL_EQ_0; DE_MORGAN_THM; DOT_LMUL; REAL_ENTIRE] THEN
12480 SIMP_TAC[DOT_BASIS; LE_REFL; DIMINDEX_GE_1] THEN
12481 EXPAND_TAC "p" THEN REWRITE_TAC[HOMEOMORPHIC_REFL]]) in
12482 REPEAT STRIP_TAC THEN
12483 TRANS_TAC HOMEOMORPHIC_TRANS `{x:real^N | x$1 = &0}` THEN
12484 ASM_SIMP_TAC[lemma] THEN ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN
12485 ASM_SIMP_TAC[lemma]);;
12487 let HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE = prove
12489 ~(a = vec 0) /\ 1 <= k /\ k <= dimindex(:N)
12490 ==> {x | a dot x = b} homeomorphic {x:real^N | x$k = c}`,
12491 REPEAT STRIP_TAC THEN
12492 SUBGOAL_THEN `{x:real^N | x$k = c} = {x | basis k dot x = c}` SUBST1_TAC
12493 THENL [ASM_SIMP_TAC[DOT_BASIS]; MATCH_MP_TAC HOMEOMORPHIC_HYPERPLANES] THEN
12494 ASM_SIMP_TAC[BASIS_NONZERO]);;
12496 let HOMEOMORPHIC_STANDARD_HYPERPLANE_HYPERPLANE = prove
12498 ~(a = vec 0) /\ 1 <= k /\ k <= dimindex(:N)
12499 ==> {x:real^N | x$k = c} homeomorphic {x | a dot x = b}`,
12500 ONCE_REWRITE_TAC[HOMEOMORPHIC_SYM] THEN
12501 REWRITE_TAC[HOMEOMORPHIC_HYPERPLANE_STANDARD_HYPERPLANE]);;
12503 let HOMEOMORPHIC_HYPERPLANE_UNIV = prove
12504 (`!a b. ~(a = vec 0) /\ dimindex(:N) = dimindex(:M) + 1
12505 ==> {x:real^N | a dot x = b} homeomorphic (:real^M)`,
12506 REPEAT STRIP_TAC THEN TRANS_TAC HOMEOMORPHIC_TRANS
12507 `{x:real^N | basis(dimindex(:N)) dot x = &0}` THEN
12508 ASM_SIMP_TAC[HOMEOMORPHIC_HYPERPLANES; BASIS_NONZERO;
12509 LE_REFL; DIMINDEX_GE_1] THEN
12510 REWRITE_TAC[homeomorphic; HOMEOMORPHISM] THEN
12511 EXISTS_TAC `(\x. lambda i. x$i):real^N->real^M` THEN
12512 EXISTS_TAC `(\x. lambda i. if i <= dimindex(:M) then x$i else &0)
12513 :real^M->real^N` THEN
12514 REPEAT CONJ_TAC THENL
12515 [MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN
12516 SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
12517 VECTOR_MUL_COMPONENT];
12518 REWRITE_TAC[SUBSET_UNIV];
12519 MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN
12520 SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; VECTOR_ADD_COMPONENT;
12521 VECTOR_MUL_COMPONENT] THEN
12522 REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
12524 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM; IN_UNIV] THEN
12525 ASM_SIMP_TAC[DOT_BASIS; LAMBDA_BETA; LE_REFL; ARITH_RULE `1 <= n + 1`;
12526 ARITH_RULE `~(m + 1 <= m)`];
12527 ASM_SIMP_TAC[IN_ELIM_THM; LAMBDA_BETA; DOT_BASIS; LE_REFL; CART_EQ;
12528 ARITH_RULE `1 <= n + 1`] THEN
12529 GEN_TAC THEN DISCH_TAC THEN X_GEN_TAC `i:num` THEN
12530 ASM_CASES_TAC `i = dimindex(:M) + 1` THEN ASM_REWRITE_TAC[COND_ID] THEN
12531 COND_CASES_TAC THEN REWRITE_TAC[] THEN ASM_ARITH_TAC;
12532 ASM_SIMP_TAC[LAMBDA_BETA; CART_EQ; IN_UNIV; LE_REFL;
12533 ARITH_RULE `i <= n ==> i <= n + 1`]]);;
12535 (* ------------------------------------------------------------------------- *)
12536 (* "Isometry" (up to constant bounds) of injective linear map etc. *)
12537 (* ------------------------------------------------------------------------- *)
12539 let CAUCHY_ISOMETRIC = prove
12541 &0 < e /\ subspace s /\
12542 linear f /\ (!x. x IN s ==> norm(f x) >= e * norm(x)) /\
12543 (!n. x(n) IN s) /\ cauchy(f o x)
12545 REPEAT GEN_TAC THEN REWRITE_TAC[real_ge] THEN
12546 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
12547 REWRITE_TAC[CAUCHY; dist; o_THM] THEN
12548 FIRST_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_SUB th)]) THEN
12549 DISCH_THEN(fun th -> X_GEN_TAC `d:real` THEN DISCH_TAC THEN MP_TAC th) THEN
12550 DISCH_THEN(MP_TAC o SPEC `d * e`) THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN
12551 ASM_MESON_TAC[REAL_LE_RDIV_EQ; REAL_MUL_SYM; REAL_LET_TRANS; SUBSPACE_SUB;
12552 REAL_LT_LDIV_EQ]);;
12554 let COMPLETE_ISOMETRIC_IMAGE = prove
12555 (`!f:real^M->real^N s e.
12556 &0 < e /\ subspace s /\
12557 linear f /\ (!x. x IN s ==> norm(f x) >= e * norm(x)) /\
12559 ==> complete(IMAGE f s)`,
12560 REPEAT GEN_TAC THEN REWRITE_TAC[complete; EXISTS_IN_IMAGE] THEN
12561 STRIP_TAC THEN X_GEN_TAC `g:num->real^N` THEN
12562 REWRITE_TAC[IN_IMAGE; SKOLEM_THM; FORALL_AND_THM] THEN
12563 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
12564 DISCH_THEN(X_CHOOSE_THEN `x:num->real^M` MP_TAC) THEN
12565 GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM FUN_EQ_THM] THEN
12566 REWRITE_TAC[GSYM o_DEF] THEN
12567 DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN
12568 FIRST_X_ASSUM(MP_TAC o SPEC `x:num->real^M`) THEN
12569 ASM_MESON_TAC[CAUCHY_ISOMETRIC; LINEAR_CONTINUOUS_AT;
12570 CONTINUOUS_AT_SEQUENTIALLY]);;
12572 let INJECTIVE_IMP_ISOMETRIC = prove
12573 (`!f:real^M->real^N s.
12574 closed s /\ subspace s /\
12575 linear f /\ (!x. x IN s /\ (f x = vec 0) ==> (x = vec 0))
12576 ==> ?e. &0 < e /\ !x. x IN s ==> norm(f x) >= e * norm(x)`,
12577 REPEAT STRIP_TAC THEN
12578 ASM_CASES_TAC `s SUBSET {vec 0 :real^M}` THENL
12579 [EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01; REAL_MUL_LID; real_ge] THEN
12580 ASM_MESON_TAC[SUBSET; IN_SING; NORM_0; LINEAR_0; REAL_LE_REFL];
12582 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [SUBSET]) THEN
12583 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; IN_SING] THEN
12584 DISCH_THEN(X_CHOOSE_THEN `a:real^M` STRIP_ASSUME_TAC) THEN
12586 [`{(f:real^M->real^N) x | x IN s /\ norm(x) = norm(a:real^M)}`;
12587 `vec 0:real^N`] DISTANCE_ATTAINS_INF) THEN
12589 [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
12590 CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
12591 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
12592 SUBST1_TAC(SET_RULE
12593 `{f x | x IN s /\ norm(x) = norm(a:real^M)} =
12594 IMAGE (f:real^M->real^N) (s INTER {x | norm x = norm a})`) THEN
12595 MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
12596 ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN
12597 MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN
12599 `{x:real^M | norm x = norm(a:real^M)} = frontier(cball(vec 0,norm a))`
12601 [ASM_SIMP_TAC[FRONTIER_CBALL; NORM_POS_LT; dist; VECTOR_SUB_LZERO;
12603 ASM_SIMP_TAC[COMPACT_FRONTIER; COMPACT_CBALL]];
12605 ONCE_REWRITE_TAC[SET_RULE `{f x | P x} = IMAGE f {x | P x}`] THEN
12606 REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN
12607 DISCH_THEN(X_CHOOSE_THEN `b:real^M` MP_TAC) THEN
12608 REWRITE_TAC[IN_ELIM_THM; dist; VECTOR_SUB_LZERO; NORM_NEG] THEN
12609 STRIP_TAC THEN REWRITE_TAC[CLOSED_LIMPT; LIMPT_APPROACHABLE] THEN
12610 EXISTS_TAC `norm((f:real^M->real^N) b) / norm(b)` THEN CONJ_TAC THENL
12611 [ASM_MESON_TAC[REAL_LT_DIV; NORM_POS_LT; NORM_EQ_0]; ALL_TAC] THEN
12612 X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
12613 ASM_CASES_TAC `x:real^M = vec 0` THENL
12614 [FIRST_ASSUM(fun th -> ASM_REWRITE_TAC[MATCH_MP LINEAR_0 th]) THEN
12615 REWRITE_TAC[NORM_0; REAL_MUL_RZERO; real_ge; REAL_LE_REFL];
12617 FIRST_X_ASSUM(MP_TAC o SPEC `(norm(a:real^M) / norm(x)) % x:real^M`) THEN
12619 [ASM_SIMP_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN
12620 ASM_SIMP_TAC[REAL_DIV_RMUL; NORM_EQ_0] THEN ASM_MESON_TAC[subspace];
12622 FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP LINEAR_CMUL th]) THEN
12623 ASM_REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM; real_ge] THEN
12624 ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ; NORM_POS_LT] THEN
12625 REWRITE_TAC[real_div; REAL_MUL_AC]);;
12627 let CLOSED_INJECTIVE_IMAGE_SUBSPACE = prove
12628 (`!f s. subspace s /\
12630 (!x. x IN s /\ f(x) = vec 0 ==> x = vec 0) /\
12632 ==> closed(IMAGE f s)`,
12633 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM COMPLETE_EQ_CLOSED] THEN
12634 MATCH_MP_TAC COMPLETE_ISOMETRIC_IMAGE THEN
12635 ASM_REWRITE_TAC[COMPLETE_EQ_CLOSED] THEN
12636 MATCH_MP_TAC INJECTIVE_IMP_ISOMETRIC THEN
12637 ASM_REWRITE_TAC[]);;
12639 (* ------------------------------------------------------------------------- *)
12640 (* Relating linear images to open/closed/interior/closure. *)
12641 (* ------------------------------------------------------------------------- *)
12643 let OPEN_SURJECTIVE_LINEAR_IMAGE = prove
12644 (`!f:real^M->real^N.
12645 linear f /\ (!y. ?x. f x = y)
12646 ==> !s. open s ==> open(IMAGE f s)`,
12647 GEN_TAC THEN STRIP_TAC THEN
12648 REWRITE_TAC[open_def; FORALL_IN_IMAGE] THEN
12649 FIRST_ASSUM(MP_TAC o GEN `k:num` o SPEC `basis k:real^N`) THEN
12650 REWRITE_TAC[SKOLEM_THM] THEN
12651 DISCH_THEN(X_CHOOSE_THEN `b:num->real^M` STRIP_ASSUME_TAC) THEN
12652 SUBGOAL_THEN `bounded(IMAGE (b:num->real^M) (1..dimindex(:N)))` MP_TAC THENL
12653 [SIMP_TAC[FINITE_IMP_BOUNDED; FINITE_IMAGE; FINITE_NUMSEG]; ALL_TAC] THEN
12654 REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; IN_NUMSEG] THEN
12655 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
12656 X_GEN_TAC `s:real^M->bool` THEN MATCH_MP_TAC MONO_FORALL THEN
12657 X_GEN_TAC `x:real^M` THEN ASM_CASES_TAC `(x:real^M) IN s` THEN
12658 ASM_REWRITE_TAC[] THEN
12659 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
12660 EXISTS_TAC `e / B / &(dimindex(:N))` THEN
12661 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1] THEN
12662 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN REWRITE_TAC[IN_IMAGE] THEN
12663 ABBREV_TAC `u = y - (f:real^M->real^N) x` THEN
12664 EXISTS_TAC `x + vsum(1..dimindex(:N)) (\i. (u:real^N)$i % b i):real^M` THEN
12665 ASM_SIMP_TAC[LINEAR_ADD; LINEAR_VSUM; FINITE_NUMSEG; o_DEF;
12666 LINEAR_CMUL; BASIS_EXPANSION] THEN
12667 CONJ_TAC THENL [EXPAND_TAC "u" THEN VECTOR_ARITH_TAC; ALL_TAC] THEN
12668 FIRST_X_ASSUM MATCH_MP_TAC THEN
12669 REWRITE_TAC[NORM_ARITH `dist(x + y,x) = norm y`] THEN
12670 MATCH_MP_TAC REAL_LET_TRANS THEN
12671 EXISTS_TAC `(dist(y,(f:real^M->real^N) x) * &(dimindex(:N))) * B` THEN
12672 ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1] THEN
12673 MATCH_MP_TAC VSUM_NORM_TRIANGLE THEN REWRITE_TAC[FINITE_NUMSEG] THEN
12674 ONCE_REWRITE_TAC[REAL_ARITH `(a * b) * c:real = b * a * c`] THEN
12675 GEN_REWRITE_TAC(RAND_CONV o LAND_CONV o RAND_CONV) [GSYM CARD_NUMSEG_1] THEN
12676 MATCH_MP_TAC SUM_BOUND THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
12677 X_GEN_TAC `k:num` THEN STRIP_TAC THEN REWRITE_TAC[NORM_MUL; dist] THEN
12678 MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[REAL_ABS_POS; NORM_POS_LE] THEN
12679 ASM_SIMP_TAC[COMPONENT_LE_NORM]);;
12681 let OPEN_BIJECTIVE_LINEAR_IMAGE_EQ = prove
12682 (`!f:real^M->real^N s.
12683 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
12684 ==> (open(IMAGE f s) <=> open s)`,
12685 REPEAT STRIP_TAC THEN EQ_TAC THENL
12686 [DISCH_TAC; ASM_MESON_TAC[OPEN_SURJECTIVE_LINEAR_IMAGE]] THEN
12687 SUBGOAL_THEN `s = {x | (f:real^M->real^N) x IN IMAGE f s}`
12688 SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
12689 MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE_UNIV THEN
12690 ASM_SIMP_TAC[LINEAR_CONTINUOUS_AT]);;
12692 add_linear_invariants [OPEN_BIJECTIVE_LINEAR_IMAGE_EQ];;
12694 let CLOSED_INJECTIVE_LINEAR_IMAGE = prove
12695 (`!f:real^M->real^N.
12696 linear f /\ (!x y. f x = f y ==> x = y)
12697 ==> !s. closed s ==> closed(IMAGE f s)`,
12698 REPEAT STRIP_TAC THEN
12699 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_LEFT_INVERSE) THEN
12700 ASM_REWRITE_TAC[] THEN
12701 DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^M` STRIP_ASSUME_TAC) THEN
12702 MATCH_MP_TAC CLOSED_IN_CLOSED_TRANS THEN
12703 EXISTS_TAC `IMAGE (f:real^M->real^N) (:real^M)` THEN
12705 [MP_TAC(ISPECL [`g:real^N->real^M`; `IMAGE (f:real^M->real^N) (:real^M)`;
12706 `IMAGE (g:real^N->real^M) (IMAGE (f:real^M->real^N) s)`]
12707 CONTINUOUS_CLOSED_IN_PREIMAGE) THEN
12708 ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN ANTS_TAC THENL
12709 [ASM_REWRITE_TAC[GSYM IMAGE_o; IMAGE_I]; ALL_TAC] THEN
12710 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
12711 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FUN_EQ_THM]) THEN
12712 REWRITE_TAC[EXTENSION; o_THM; I_THM] THEN SET_TAC[];
12713 MATCH_MP_TAC CLOSED_INJECTIVE_IMAGE_SUBSPACE THEN
12714 ASM_REWRITE_TAC[IN_UNIV; SUBSPACE_UNIV; CLOSED_UNIV] THEN
12715 X_GEN_TAC `x:real^M` THEN
12716 DISCH_THEN(MP_TAC o AP_TERM `g:real^N->real^M`) THEN
12717 RULE_ASSUM_TAC(REWRITE_RULE[FUN_EQ_THM; I_THM; o_THM]) THEN
12718 ASM_MESON_TAC[LINEAR_0]]);;
12720 let CLOSED_INJECTIVE_LINEAR_IMAGE_EQ = prove
12721 (`!f:real^M->real^N s.
12722 linear f /\ (!x y. f x = f y ==> x = y)
12723 ==> (closed(IMAGE f s) <=> closed s)`,
12724 REPEAT STRIP_TAC THEN EQ_TAC THENL
12725 [DISCH_TAC; ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE]] THEN
12726 SUBGOAL_THEN `s = {x | (f:real^M->real^N) x IN IMAGE f s}`
12727 SUBST1_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
12728 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN
12729 ASM_SIMP_TAC[LINEAR_CONTINUOUS_AT]);;
12731 add_linear_invariants [CLOSED_INJECTIVE_LINEAR_IMAGE_EQ];;
12733 let CLOSURE_LINEAR_IMAGE_SUBSET = prove
12734 (`!f:real^M->real^N s.
12735 linear f ==> IMAGE f (closure s) SUBSET closure(IMAGE f s)`,
12736 REPEAT STRIP_TAC THEN
12737 MATCH_MP_TAC IMAGE_CLOSURE_SUBSET THEN
12738 ASM_SIMP_TAC[CLOSED_CLOSURE; CLOSURE_SUBSET; LINEAR_CONTINUOUS_ON]);;
12740 let CLOSURE_INJECTIVE_LINEAR_IMAGE = prove
12741 (`!f:real^M->real^N s.
12742 linear f /\ (!x y. f x = f y ==> x = y)
12743 ==> closure(IMAGE f s) = IMAGE f (closure s)`,
12744 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
12745 ASM_SIMP_TAC[CLOSURE_LINEAR_IMAGE_SUBSET] THEN
12746 MATCH_MP_TAC CLOSURE_MINIMAL THEN
12747 SIMP_TAC[CLOSURE_SUBSET; IMAGE_SUBSET] THEN
12748 ASM_MESON_TAC[CLOSED_INJECTIVE_LINEAR_IMAGE; CLOSED_CLOSURE]);;
12750 add_linear_invariants [CLOSURE_INJECTIVE_LINEAR_IMAGE];;
12752 let CLOSURE_BOUNDED_LINEAR_IMAGE = prove
12753 (`!f:real^M->real^N s.
12754 linear f /\ bounded s
12755 ==> closure(IMAGE f s) = IMAGE f (closure s)`,
12756 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN
12757 ASM_SIMP_TAC[CLOSURE_LINEAR_IMAGE_SUBSET] THEN
12758 MATCH_MP_TAC CLOSURE_MINIMAL THEN
12759 SIMP_TAC[CLOSURE_SUBSET; IMAGE_SUBSET] THEN
12760 MATCH_MP_TAC COMPACT_IMP_CLOSED THEN
12761 MATCH_MP_TAC COMPACT_LINEAR_IMAGE THEN
12762 ASM_REWRITE_TAC[COMPACT_CLOSURE]);;
12764 let LINEAR_INTERIOR_IMAGE_SUBSET = prove
12765 (`!f:real^M->real^N s.
12766 linear f /\ (!x y. f x = f y ==> x = y)
12767 ==> interior(IMAGE f s) SUBSET IMAGE f (interior s)`,
12768 MESON_TAC[INTERIOR_IMAGE_SUBSET; LINEAR_CONTINUOUS_AT]);;
12770 let LINEAR_IMAGE_SUBSET_INTERIOR = prove
12771 (`!f:real^M->real^N s.
12772 linear f /\ (!y. ?x. f x = y)
12773 ==> IMAGE f (interior s) SUBSET interior(IMAGE f s)`,
12774 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_MAXIMAL THEN
12775 ASM_SIMP_TAC[OPEN_SURJECTIVE_LINEAR_IMAGE; OPEN_INTERIOR;
12776 IMAGE_SUBSET; INTERIOR_SUBSET]);;
12778 let INTERIOR_BIJECTIVE_LINEAR_IMAGE = prove
12779 (`!f:real^M->real^N s.
12780 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
12781 ==> interior(IMAGE f s) = IMAGE f (interior s)`,
12782 REWRITE_TAC[interior] THEN GEOM_TRANSFORM_TAC[]);;
12784 add_linear_invariants [INTERIOR_BIJECTIVE_LINEAR_IMAGE];;
12786 let FRONTIER_BIJECTIVE_LINEAR_IMAGE = prove
12787 (`!f:real^M->real^N s.
12788 linear f /\ (!x y. f x = f y ==> x = y) /\ (!y. ?x. f x = y)
12789 ==> frontier(IMAGE f s) = IMAGE f (frontier s)`,
12790 REWRITE_TAC[frontier] THEN GEOM_TRANSFORM_TAC[]);;
12792 add_linear_invariants [FRONTIER_BIJECTIVE_LINEAR_IMAGE];;
12794 (* ------------------------------------------------------------------------- *)
12795 (* Corollaries, reformulations and special cases for M = N. *)
12796 (* ------------------------------------------------------------------------- *)
12798 let IN_INTERIOR_LINEAR_IMAGE = prove
12799 (`!f:real^M->real^N g s x.
12800 linear f /\ linear g /\ (f o g = I) /\ x IN interior s
12801 ==> (f x) IN interior (IMAGE f s)`,
12802 REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN REPEAT STRIP_TAC THEN
12803 MP_TAC(ISPECL [`f:real^M->real^N`; `s:real^M->bool`]
12804 LINEAR_IMAGE_SUBSET_INTERIOR) THEN
12805 ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
12808 let LINEAR_OPEN_MAPPING = prove
12809 (`!f:real^M->real^N g.
12810 linear f /\ linear g /\ (f o g = I)
12811 ==> !s. open s ==> open(IMAGE f s)`,
12812 REPEAT GEN_TAC THEN REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN DISCH_TAC THEN
12813 MATCH_MP_TAC OPEN_SURJECTIVE_LINEAR_IMAGE THEN
12816 let INTERIOR_INJECTIVE_LINEAR_IMAGE = prove
12817 (`!f:real^N->real^N s.
12818 linear f /\ (!x y. f x = f y ==> x = y)
12819 ==> interior(IMAGE f s) = IMAGE f (interior s)`,
12820 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_BIJECTIVE_LINEAR_IMAGE THEN
12821 ASM_MESON_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE]);;
12823 let INTERIOR_SURJECTIVE_LINEAR_IMAGE = prove
12824 (`!f:real^N->real^N s.
12825 linear f /\ (!y. ?x. f x = y)
12826 ==> interior(IMAGE f s) = IMAGE f (interior s)`,
12827 REPEAT STRIP_TAC THEN MATCH_MP_TAC INTERIOR_BIJECTIVE_LINEAR_IMAGE THEN
12828 ASM_MESON_TAC[LINEAR_SURJECTIVE_IMP_INJECTIVE]);;
12830 let CLOSURE_SURJECTIVE_LINEAR_IMAGE = prove
12831 (`!f:real^N->real^N s.
12832 linear f /\ (!y. ?x. f x = y)
12833 ==> closure(IMAGE f s) = IMAGE f (closure s)`,
12834 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_INJECTIVE_LINEAR_IMAGE THEN
12835 ASM_MESON_TAC[LINEAR_SURJECTIVE_IMP_INJECTIVE]);;
12837 let FRONTIER_INJECTIVE_LINEAR_IMAGE = prove
12838 (`!f:real^N->real^N s.
12839 linear f /\ (!x y. f x = f y ==> x = y)
12840 ==> frontier(IMAGE f s) = IMAGE f (frontier s)`,
12841 REPEAT STRIP_TAC THEN MATCH_MP_TAC FRONTIER_BIJECTIVE_LINEAR_IMAGE THEN
12842 ASM_MESON_TAC[LINEAR_INJECTIVE_IMP_SURJECTIVE]);;
12844 let FRONTIER_SURJECTIVE_LINEAR_IMAGE = prove
12845 (`!f:real^N->real^N.
12846 linear f /\ (!y. ?x. f x = y)
12847 ==> frontier(IMAGE f s) = IMAGE f (frontier s)`,
12848 REPEAT STRIP_TAC THEN MATCH_MP_TAC FRONTIER_BIJECTIVE_LINEAR_IMAGE THEN
12849 ASM_MESON_TAC[LINEAR_SURJECTIVE_IMP_INJECTIVE]);;
12851 let COMPLETE_INJECTIVE_LINEAR_IMAGE = prove
12852 (`!f:real^M->real^N.
12853 linear f /\ (!x y. f x = f y ==> x = y)
12854 ==> !s. complete s ==> complete(IMAGE f s)`,
12855 REWRITE_TAC[COMPLETE_EQ_CLOSED; CLOSED_INJECTIVE_LINEAR_IMAGE]);;
12857 let COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ = prove
12858 (`!f:real^M->real^N s.
12859 linear f /\ (!x y. f x = f y ==> x = y)
12860 ==> (complete(IMAGE f s) <=> complete s)`,
12861 REWRITE_TAC[COMPLETE_EQ_CLOSED; CLOSED_INJECTIVE_LINEAR_IMAGE_EQ]);;
12863 add_linear_invariants [COMPLETE_INJECTIVE_LINEAR_IMAGE_EQ];;
12865 let LIMPT_INJECTIVE_LINEAR_IMAGE_EQ = prove
12866 (`!f:real^M->real^N s.
12867 linear f /\ (!x y. f x = f y ==> x = y)
12868 ==> ((f x) limit_point_of (IMAGE f s) <=> x limit_point_of s)`,
12869 REWRITE_TAC[LIMPT_APPROACHABLE; EXISTS_IN_IMAGE] THEN
12870 REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN
12872 [MP_TAC(ISPEC `f:real^M->real^N` LINEAR_INJECTIVE_BOUNDED_BELOW_POS);
12873 MP_TAC(ISPEC `f:real^M->real^N` LINEAR_BOUNDED_POS)] THEN
12874 ASM_REWRITE_TAC[] THEN
12875 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THENL
12876 [FIRST_X_ASSUM(MP_TAC o SPEC `e * B:real`);
12877 FIRST_X_ASSUM(MP_TAC o SPEC `e / B:real`)] THEN
12878 ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; dist; GSYM LINEAR_SUB] THEN
12879 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
12880 REPEAT(MATCH_MP_TAC MONO_AND THEN
12881 CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN
12882 ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; REAL_LT_RDIV_EQ] THEN
12883 MATCH_MP_TAC(REAL_ARITH `a <= b ==> b < x ==> a < x`) THEN
12884 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_SIMP_TAC[REAL_LE_RDIV_EQ]);;
12886 add_linear_invariants [LIMPT_INJECTIVE_LINEAR_IMAGE_EQ];;
12888 let LIMPT_TRANSLATION_EQ = prove
12889 (`!a s x. (a + x) limit_point_of (IMAGE (\y. a + y) s) <=> x limit_point_of s`,
12890 REWRITE_TAC[limit_point_of] THEN GEOM_TRANSLATE_TAC[]);;
12892 add_translation_invariants [LIMPT_TRANSLATION_EQ];;
12894 let OPEN_OPEN_LEFT_PROJECTION = prove
12895 (`!s t:real^(M,N)finite_sum->bool.
12896 open s /\ open t ==> open {x | x IN s /\ ?y. pastecart x y IN t}`,
12897 REPEAT STRIP_TAC THEN
12899 `{x | x IN s /\ ?y. (pastecart x y:real^(M,N)finite_sum) IN t} =
12900 s INTER IMAGE fstcart t`
12902 [REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; IN_IMAGE] THEN
12903 MESON_TAC[FSTCART_PASTECART; PASTECART_FST_SND];
12904 MATCH_MP_TAC OPEN_INTER THEN ASM_REWRITE_TAC[] THEN
12905 MATCH_MP_TAC(REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM]
12906 OPEN_SURJECTIVE_LINEAR_IMAGE) THEN
12907 ASM_REWRITE_TAC[LINEAR_FSTCART] THEN MESON_TAC[FSTCART_PASTECART]]);;
12909 let OPEN_OPEN_RIGHT_PROJECTION = prove
12910 (`!s t:real^(M,N)finite_sum->bool.
12911 open s /\ open t ==> open {y | y IN s /\ ?x. pastecart x y IN t}`,
12912 REPEAT STRIP_TAC THEN
12914 `{y | y IN s /\ ?x. (pastecart x y:real^(M,N)finite_sum) IN t} =
12915 s INTER IMAGE sndcart t`
12917 [REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; IN_IMAGE] THEN
12918 MESON_TAC[SNDCART_PASTECART; PASTECART_FST_SND];
12919 MATCH_MP_TAC OPEN_INTER THEN ASM_REWRITE_TAC[] THEN
12920 MATCH_MP_TAC(REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM]
12921 OPEN_SURJECTIVE_LINEAR_IMAGE) THEN
12922 ASM_REWRITE_TAC[LINEAR_SNDCART] THEN MESON_TAC[SNDCART_PASTECART]]);;
12924 (* ------------------------------------------------------------------------- *)
12925 (* Even more special cases. *)
12926 (* ------------------------------------------------------------------------- *)
12928 let INTERIOR_NEGATIONS = prove
12929 (`!s. interior(IMAGE (--) s) = IMAGE (--) (interior s)`,
12930 GEN_TAC THEN MATCH_MP_TAC INTERIOR_INJECTIVE_LINEAR_IMAGE THEN
12931 REWRITE_TAC[linear] THEN REPEAT CONJ_TAC THEN VECTOR_ARITH_TAC);;
12933 let SYMMETRIC_INTERIOR = prove
12935 (!x. x IN s ==> --x IN s)
12936 ==> !x. x IN interior s ==> (--x) IN interior s`,
12937 REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
12938 DISCH_THEN(MP_TAC o MATCH_MP(ISPEC `(--):real^N->real^N` FUN_IN_IMAGE)) THEN
12939 REWRITE_TAC[GSYM INTERIOR_NEGATIONS] THEN
12940 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
12941 REWRITE_TAC[EXTENSION; IN_IMAGE] THEN ASM_MESON_TAC[VECTOR_NEG_NEG]);;
12943 let CLOSURE_NEGATIONS = prove
12944 (`!s. closure(IMAGE (--) s) = IMAGE (--) (closure s)`,
12945 GEN_TAC THEN MATCH_MP_TAC CLOSURE_INJECTIVE_LINEAR_IMAGE THEN
12946 REWRITE_TAC[linear] THEN REPEAT CONJ_TAC THEN VECTOR_ARITH_TAC);;
12948 let SYMMETRIC_CLOSURE = prove
12950 (!x. x IN s ==> --x IN s)
12951 ==> !x. x IN closure s ==> (--x) IN closure s`,
12952 REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
12953 DISCH_THEN(MP_TAC o MATCH_MP(ISPEC `(--):real^N->real^N` FUN_IN_IMAGE)) THEN
12954 REWRITE_TAC[GSYM CLOSURE_NEGATIONS] THEN
12955 MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
12956 REWRITE_TAC[EXTENSION; IN_IMAGE] THEN ASM_MESON_TAC[VECTOR_NEG_NEG]);;
12958 (* ------------------------------------------------------------------------- *)
12959 (* Some properties of a canonical subspace. *)
12960 (* ------------------------------------------------------------------------- *)
12962 let SUBSPACE_SUBSTANDARD = prove
12964 {x:real^N | !i. d < i /\ i <= dimindex(:N) ==> x$i = &0}`,
12965 GEN_TAC THEN ASM_CASES_TAC `d <= dimindex(:N)` THENL
12966 [MP_TAC(ARITH_RULE `!i. d < i ==> 1 <= i`) THEN
12967 SIMP_TAC[subspace; IN_ELIM_THM; REAL_MUL_RZERO; REAL_ADD_LID;
12968 VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT];
12969 ASM_SIMP_TAC[ARITH_RULE `~(d:num <= e) ==> (d < i /\ i <= e <=> F)`] THEN
12970 REWRITE_TAC[SET_RULE `{x | T} = UNIV`; SUBSPACE_UNIV]]);;
12972 let CLOSED_SUBSTANDARD = prove
12974 {x:real^N | !i. d < i /\ i <= dimindex(:N) ==> x$i = &0}`,
12977 `{x:real^N | !i. d < i /\ i <= dimindex(:N) ==> x$i = &0} =
12978 INTERS {{x | basis i dot x = &0} | d < i /\ i <= dimindex(:N)}`
12981 SIMP_TAC[CLOSED_INTERS; CLOSED_HYPERPLANE; IN_ELIM_THM;
12982 LEFT_IMP_EXISTS_THM]] THEN
12983 GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_INTERS; IN_ELIM_THM] THEN
12984 SIMP_TAC[LEFT_IMP_EXISTS_THM; IN_ELIM_THM] THEN
12985 MP_TAC(ARITH_RULE `!i. d < i ==> 1 <= i`) THEN
12986 SIMP_TAC[DOT_BASIS] THEN MESON_TAC[]);;
12988 let DIM_SUBSTANDARD = prove
12989 (`!d. d <= dimindex(:N)
12990 ==> (dim {x:real^N | !i. d < i /\ i <= dimindex(:N)
12993 REPEAT STRIP_TAC THEN MATCH_MP_TAC DIM_UNIQUE THEN
12994 EXISTS_TAC `IMAGE (basis:num->real^N) (1..d)` THEN REPEAT CONJ_TAC THENL
12995 [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM; IN_NUMSEG] THEN
12996 MESON_TAC[BASIS_COMPONENT; ARITH_RULE `d < i ==> 1 <= i`; NOT_LT];
12998 MATCH_MP_TAC INDEPENDENT_MONO THEN
12999 EXISTS_TAC `{basis i :real^N | 1 <= i /\ i <= dimindex(:N)}` THEN
13000 REWRITE_TAC[INDEPENDENT_STDBASIS]THEN
13001 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM; IN_NUMSEG] THEN
13002 ASM_MESON_TAC[LE_TRANS];
13003 MATCH_MP_TAC HAS_SIZE_IMAGE_INJ THEN REWRITE_TAC[HAS_SIZE_NUMSEG_1] THEN
13004 REWRITE_TAC[IN_NUMSEG] THEN ASM_MESON_TAC[LE_TRANS; BASIS_INJ]] THEN
13005 POP_ASSUM MP_TAC THEN SPEC_TAC(`d:num`,`d:num`) THEN
13007 [REWRITE_TAC[ARITH_RULE `0 < i <=> 1 <= i`; SPAN_STDBASIS] THEN
13008 SUBGOAL_THEN `IMAGE basis (1 .. 0) :real^N->bool = {}` SUBST1_TAC THENL
13009 [REWRITE_TAC[IMAGE_EQ_EMPTY; NUMSEG_EMPTY; ARITH]; ALL_TAC] THEN
13010 DISCH_TAC THEN REWRITE_TAC[SPAN_EMPTY; SUBSET; IN_ELIM_THM; IN_SING] THEN
13011 SIMP_TAC[CART_EQ; VEC_COMPONENT];
13013 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o check (is_imp o concl)) THEN
13014 ASM_SIMP_TAC[ARITH_RULE `SUC d <= n ==> d <= n`] THEN
13015 REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN DISCH_TAC THEN
13016 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
13017 FIRST_X_ASSUM(MP_TAC o SPEC `x - (x$(SUC d)) % basis(SUC d) :real^N`) THEN
13019 [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
13020 FIRST_ASSUM(ASSUME_TAC o MATCH_MP(ARITH_RULE `d < i ==> 1 <= i`)) THEN
13021 ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT] THEN
13022 ASM_SIMP_TAC[BASIS_COMPONENT] THEN COND_CASES_TAC THEN
13023 ASM_REWRITE_TAC[REAL_MUL_RID; REAL_SUB_REFL] THEN
13024 ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_SUB_RZERO] THEN
13025 ASM_MESON_TAC[ARITH_RULE `d < i /\ ~(i = SUC d) ==> SUC d < i`];
13028 SUBST1_TAC(VECTOR_ARITH
13029 `x = (x - (x$(SUC d)) % basis(SUC d)) +
13030 x$(SUC d) % basis(SUC d) :real^N`) THEN
13031 MATCH_MP_TAC SPAN_ADD THEN CONJ_TAC THENL
13032 [ASM_MESON_TAC[SPAN_MONO; SUBSET_IMAGE; SUBSET; SUBSET_NUMSEG; LE_REFL; LE];
13033 MATCH_MP_TAC SPAN_MUL THEN MATCH_MP_TAC SPAN_SUPERSET THEN
13034 REWRITE_TAC[IN_IMAGE; IN_NUMSEG] THEN
13035 MESON_TAC[LE_REFL; ARITH_RULE `1 <= SUC d`]]);;
13037 (* ------------------------------------------------------------------------- *)
13038 (* Hence closure and completeness of all subspaces. *)
13039 (* ------------------------------------------------------------------------- *)
13041 let CLOSED_SUBSPACE = prove
13042 (`!s:real^N->bool. subspace s ==> closed s`,
13043 REPEAT STRIP_TAC THEN ABBREV_TAC `d = dim(s:real^N->bool)` THEN
13044 MP_TAC(MATCH_MP DIM_SUBSTANDARD
13045 (ISPEC `s:real^N->bool` DIM_SUBSET_UNIV)) THEN
13046 ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
13048 [`{x:real^N | !i. d < i /\ i <= dimindex(:N)
13050 `s:real^N->bool`] SUBSPACE_ISOMORPHISM) THEN
13051 ASM_REWRITE_TAC[SUBSPACE_SUBSTANDARD] THEN
13052 DISCH_THEN(X_CHOOSE_THEN `f:real^N->real^N` MP_TAC) THEN
13053 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
13054 DISCH_THEN(CONJUNCTS_THEN2 (SUBST_ALL_TAC o SYM) STRIP_ASSUME_TAC) THEN
13055 MATCH_MP_TAC(ISPEC `f:real^N->real^N` CLOSED_INJECTIVE_IMAGE_SUBSPACE) THEN
13056 ASM_REWRITE_TAC[SUBSPACE_SUBSTANDARD; CLOSED_SUBSTANDARD] THEN
13057 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
13058 ASM_REWRITE_TAC[] THEN
13059 CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LINEAR_0]] THEN
13060 REWRITE_TAC[IN_ELIM_THM] THEN
13061 ASM_MESON_TAC[VEC_COMPONENT; ARITH_RULE `d < i ==> 1 <= i`]);;
13063 let COMPLETE_SUBSPACE = prove
13064 (`!s:real^N->bool. subspace s ==> complete s`,
13065 REWRITE_TAC[COMPLETE_EQ_CLOSED; CLOSED_SUBSPACE]);;
13067 let CLOSED_SPAN = prove
13068 (`!s. closed(span s)`,
13069 SIMP_TAC[CLOSED_SUBSPACE; SUBSPACE_SPAN]);;
13071 let DIM_CLOSURE = prove
13072 (`!s:real^N->bool. dim(closure s) = dim s`,
13073 GEN_TAC THEN REWRITE_TAC[GSYM LE_ANTISYM] THEN CONJ_TAC THENL
13074 [GEN_REWRITE_TAC RAND_CONV [GSYM DIM_SPAN]; ALL_TAC] THEN
13075 MATCH_MP_TAC DIM_SUBSET THEN REWRITE_TAC[CLOSURE_SUBSET] THEN
13076 MATCH_MP_TAC CLOSURE_MINIMAL THEN
13077 SIMP_TAC[CLOSED_SUBSPACE; SUBSPACE_SPAN; SPAN_INC]);;
13079 let CLOSED_BOUNDEDPREIM_CONTINUOUS_IMAGE = prove
13080 (`!f:real^M->real^N s.
13081 closed s /\ f continuous_on s /\
13082 (!e. bounded {x | x IN s /\ norm(f x) <= e})
13083 ==> closed(IMAGE f s)`,
13084 REPEAT STRIP_TAC THEN REWRITE_TAC[CLOSED_INTERS_COMPACT] THEN
13085 REWRITE_TAC[SET_RULE
13086 `cball(vec 0,e) INTER IMAGE (f:real^M->real^N) s =
13087 IMAGE f (s INTER {x | x IN s /\ f x IN cball(vec 0,e)})`] THEN
13088 X_GEN_TAC `e:real` THEN MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE THEN
13090 [MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `s:real^M->bool` THEN
13091 ASM_REWRITE_TAC[] THEN SET_TAC[];
13092 MATCH_MP_TAC CLOSED_INTER_COMPACT THEN ASM_REWRITE_TAC[] THEN
13093 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN CONJ_TAC THENL
13094 [ASM_REWRITE_TAC[IN_CBALL_0];
13095 ASM_SIMP_TAC[CONTINUOUS_CLOSED_PREIMAGE; CLOSED_CBALL]]]);;
13097 let CLOSED_INJECTIVE_IMAGE_SUBSET_SUBSPACE = prove
13098 (`!f:real^M->real^N s t.
13099 closed s /\ s SUBSET t /\ subspace t /\
13101 (!x. x IN t /\ f(x) = vec 0 ==> x = vec 0)
13102 ==> closed(IMAGE f s)`,
13103 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSED_BOUNDEDPREIM_CONTINUOUS_IMAGE THEN
13104 ASM_SIMP_TAC[LINEAR_CONTINUOUS_ON] THEN
13105 MP_TAC(ISPECL [`f:real^M->real^N`; `t:real^M->bool`]
13106 INJECTIVE_IMP_ISOMETRIC) THEN
13107 ASM_SIMP_TAC[CLOSED_SUBSPACE; real_ge] THEN
13108 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
13109 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
13110 X_GEN_TAC `e:real` THEN MATCH_MP_TAC BOUNDED_SUBSET THEN
13111 EXISTS_TAC `cball(vec 0:real^M,e / B)` THEN
13112 REWRITE_TAC[BOUNDED_CBALL] THEN
13113 ASM_SIMP_TAC[SUBSET; IN_ELIM_THM; IN_CBALL_0; REAL_LE_RDIV_EQ] THEN
13114 ASM_MESON_TAC[SUBSET; REAL_LE_TRANS]);;
13116 let BASIS_COORDINATES_LIPSCHITZ = prove
13121 ==> abs(c v) <= B * norm(vsum b (\v. c(v) % v))`,
13122 X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
13123 FIRST_ASSUM(STRIP_ASSUME_TAC o MATCH_MP INDEPENDENT_BOUND) THEN
13124 FIRST_ASSUM(X_CHOOSE_THEN `b:num->real^N` STRIP_ASSUME_TAC o
13125 GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN
13126 ABBREV_TAC `n = CARD(k:real^N->bool)` THEN
13128 [`(\x. vsum(1..n) (\i. x$i % b i)):real^N->real^N`;
13129 `span(IMAGE basis (1..n)):real^N->bool`]
13130 INJECTIVE_IMP_ISOMETRIC) THEN
13131 REWRITE_TAC[SUBSPACE_SPAN] THEN ANTS_TAC THENL
13132 [CONJ_TAC THENL [SIMP_TAC[CLOSED_SUBSPACE; SUBSPACE_SPAN]; ALL_TAC] THEN
13134 [MATCH_MP_TAC LINEAR_COMPOSE_VSUM THEN
13135 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN REPEAT STRIP_TAC THEN
13136 MATCH_MP_TAC LINEAR_VMUL_COMPONENT THEN
13137 SIMP_TAC[LINEAR_ID] THEN ASM_ARITH_TAC;
13139 X_GEN_TAC `x:real^N` THEN
13140 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
13141 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_SPAN_IMAGE_BASIS]) THEN
13142 REWRITE_TAC[IN_NUMSEG] THEN DISCH_TAC THEN
13143 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN
13144 DISCH_THEN(X_CHOOSE_TAC `c:real^N->num`) THEN
13146 `vsum(1..n) (\i. (x:real^N)$i % b i:real^N) = vsum k (\v. x$(c v) % v)`
13148 [MATCH_MP_TAC VSUM_EQ_GENERAL_INVERSES THEN
13149 MAP_EVERY EXISTS_TAC [`b:num->real^N`; `c:real^N->num`] THEN
13153 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INDEPENDENT_EXPLICIT]) THEN
13154 DISCH_THEN(MP_TAC o SPEC `\v:real^N. (x:real^N)$(c v)` o CONJUNCT2) THEN
13155 ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
13156 REWRITE_TAC[CART_EQ; FORALL_IN_IMAGE; VEC_COMPONENT] THEN
13157 ASM_MESON_TAC[IN_NUMSEG];
13159 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
13160 EXISTS_TAC `inv(B:real)` THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN
13161 ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_NUMSEG] THEN
13162 MAP_EVERY X_GEN_TAC [`c:real^N->real`; `j:num`] THEN STRIP_TAC THEN
13163 ONCE_REWRITE_TAC[REAL_ARITH `inv B * x = x / B`] THEN
13164 ASM_SIMP_TAC[REAL_LE_RDIV_EQ] THEN
13165 W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o rand o rand o snd) THEN
13166 ASM_REWRITE_TAC[FINITE_NUMSEG] THEN DISCH_THEN SUBST1_TAC THEN
13167 FIRST_X_ASSUM(MP_TAC o SPEC
13168 `(lambda i. if 1 <= i /\ i <= n then c(b i:real^N) else &0):real^N`) THEN
13169 SIMP_TAC[IN_SPAN_IMAGE_BASIS; LAMBDA_BETA] THEN
13170 ANTS_TAC THENL [MESON_TAC[IN_NUMSEG]; ALL_TAC] THEN
13171 MATCH_MP_TAC(REAL_ARITH `x = v /\ u <= y ==> x >= y ==> u <= v`) THEN
13173 [AP_TERM_TAC THEN MATCH_MP_TAC VSUM_EQ_NUMSEG THEN
13174 SUBGOAL_THEN `!i. i <= n ==> i <= dimindex(:N)` MP_TAC THENL
13175 [ASM_ARITH_TAC; SIMP_TAC[LAMBDA_BETA] THEN DISCH_THEN(K ALL_TAC)] THEN
13176 REWRITE_TAC[o_THM];
13177 GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN
13178 ASM_SIMP_TAC[REAL_LE_RMUL_EQ] THEN
13180 [`(lambda i. if 1 <= i /\ i <= n then c(b i:real^N) else &0):real^N`;
13181 `j:num`] COMPONENT_LE_NORM) THEN
13182 SIMP_TAC[LAMBDA_BETA] THEN ASM_REWRITE_TAC[] THEN
13183 DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC]);;
13185 let BASIS_COORDINATES_CONTINUOUS = prove
13186 (`!b:real^N->bool e.
13187 independent b /\ &0 < e
13189 !c. norm(vsum b (\v. c(v) % v)) < d
13190 ==> !v. v IN b ==> abs(c v) < e`,
13191 REPEAT STRIP_TAC THEN
13192 FIRST_X_ASSUM(MP_TAC o MATCH_MP BASIS_COORDINATES_LIPSCHITZ) THEN
13193 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
13194 EXISTS_TAC `e / B:real` THEN ASM_SIMP_TAC[REAL_LT_DIV] THEN
13195 X_GEN_TAC `c:real^N->real` THEN DISCH_TAC THEN
13196 X_GEN_TAC `v:real^N` THEN DISCH_TAC THEN
13197 MATCH_MP_TAC REAL_LET_TRANS THEN
13198 EXISTS_TAC `B * norm(vsum b (\v:real^N. c v % v))` THEN
13199 ASM_SIMP_TAC[] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
13200 ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ]);;
13202 (* ------------------------------------------------------------------------- *)
13203 (* Affine transformations of intervals. *)
13204 (* ------------------------------------------------------------------------- *)
13206 let AFFINITY_INVERSES = prove
13208 ==> (\x. m % x + c) o (\x. inv(m) % x + (--(inv(m) % c))) = I /\
13209 (\x. inv(m) % x + (--(inv(m) % c))) o (\x. m % x + c) = I`,
13210 REWRITE_TAC[FUN_EQ_THM; o_THM; I_THM] THEN
13211 REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_RNEG] THEN
13212 SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_RINV] THEN
13213 REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC);;
13215 let REAL_AFFINITY_LE = prove
13216 (`!m c x y. &0 < m ==> (m * x + c <= y <=> x <= inv(m) * y + --(c / m))`,
13217 REWRITE_TAC[REAL_ARITH `m * x + c <= y <=> x * m <= y - c`] THEN
13218 SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN REAL_ARITH_TAC);;
13220 let REAL_LE_AFFINITY = prove
13221 (`!m c x y. &0 < m ==> (y <= m * x + c <=> inv(m) * y + --(c / m) <= x)`,
13222 REWRITE_TAC[REAL_ARITH `y <= m * x + c <=> y - c <= x * m`] THEN
13223 SIMP_TAC[GSYM REAL_LE_LDIV_EQ] THEN REAL_ARITH_TAC);;
13225 let REAL_AFFINITY_LT = prove
13226 (`!m c x y. &0 < m ==> (m * x + c < y <=> x < inv(m) * y + --(c / m))`,
13227 SIMP_TAC[REAL_LE_AFFINITY; GSYM REAL_NOT_LE]);;
13229 let REAL_LT_AFFINITY = prove
13230 (`!m c x y. &0 < m ==> (y < m * x + c <=> inv(m) * y + --(c / m) < x)`,
13231 SIMP_TAC[REAL_AFFINITY_LE; GSYM REAL_NOT_LE]);;
13233 let REAL_AFFINITY_EQ = prove
13234 (`!m c x y. ~(m = &0) ==> (m * x + c = y <=> x = inv(m) * y + --(c / m))`,
13235 CONV_TAC REAL_FIELD);;
13237 let REAL_EQ_AFFINITY = prove
13238 (`!m c x y. ~(m = &0) ==> (y = m * x + c <=> inv(m) * y + --(c / m) = x)`,
13239 CONV_TAC REAL_FIELD);;
13241 let VECTOR_AFFINITY_EQ = prove
13242 (`!m c x y. ~(m = &0)
13243 ==> (m % x + c = y <=> x = inv(m) % y + --(inv(m) % c))`,
13244 SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
13245 real_div; VECTOR_NEG_COMPONENT; REAL_AFFINITY_EQ] THEN
13246 REWRITE_TAC[REAL_MUL_AC]);;
13248 let VECTOR_EQ_AFFINITY = prove
13249 (`!m c x y. ~(m = &0)
13250 ==> (y = m % x + c <=> inv(m) % y + --(inv(m) % c) = x)`,
13251 SIMP_TAC[CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
13252 real_div; VECTOR_NEG_COMPONENT; REAL_EQ_AFFINITY] THEN
13253 REWRITE_TAC[REAL_MUL_AC]);;
13255 let IMAGE_AFFINITY_INTERVAL = prove
13257 IMAGE (\x. m % x + c) (interval[a,b]) =
13258 if interval[a,b] = {} then {}
13259 else if &0 <= m then interval[m % a + c,m % b + c]
13260 else interval[m % b + c,m % a + c]`,
13261 REPEAT GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[IMAGE_CLAUSES] THEN
13262 ASM_CASES_TAC `m = &0` THEN ASM_REWRITE_TAC[REAL_LE_LT] THENL
13263 [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID; COND_ID] THEN
13264 REWRITE_TAC[INTERVAL_SING] THEN ASM SET_TAC[];
13266 FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH
13267 `~(x = &0) ==> &0 < x \/ &0 < --x`)) THEN
13268 ASM_SIMP_TAC[EXTENSION; IN_IMAGE; REAL_ARITH `&0 < --x ==> ~(&0 < x)`] THENL
13270 ONCE_REWRITE_TAC[VECTOR_ARITH `x = m % y + c <=> c = (--m) % y + x`]] THEN
13271 ASM_SIMP_TAC[VECTOR_EQ_AFFINITY; REAL_LT_IMP_NZ; UNWIND_THM1] THEN
13272 SIMP_TAC[IN_INTERVAL; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
13273 VECTOR_NEG_COMPONENT] THEN
13274 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_LT_INV_EQ]) THEN
13275 SIMP_TAC[REAL_AFFINITY_LE; REAL_LE_AFFINITY; real_div] THEN
13276 DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[REAL_INV_INV] THEN
13277 REWRITE_TAC[REAL_MUL_LNEG; REAL_NEGNEG] THEN
13278 ASM_SIMP_TAC[REAL_FIELD `&0 < m ==> (inv m * x) * m = x`] THEN
13279 GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN AP_TERM_TAC THEN REAL_ARITH_TAC);;
13281 (* ------------------------------------------------------------------------- *)
13282 (* Existence of eigenvectors. The proof is only in this file because it uses *)
13283 (* a few simple results about continuous functions (at least *)
13284 (* CONTINUOUS_ON_LIFT_DOT2, CONTINUOUS_ATTAINS_SUP and CLOSED_SUBSPACE). *)
13285 (* ------------------------------------------------------------------------- *)
13287 let SELF_ADJOINT_HAS_EIGENVECTOR_IN_SUBSPACE = prove
13288 (`!f:real^N->real^N s.
13289 linear f /\ adjoint f = f /\
13290 subspace s /\ ~(s = {vec 0}) /\ (!x. x IN s ==> f x IN s)
13291 ==> ?v c. v IN s /\ norm(v) = &1 /\ f(v) = c % v`,
13293 (`!a b. (!x. a * x <= b * x pow 2) ==> &0 <= b ==> a = &0`,
13294 REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[REAL_LE_LT] THEN
13295 ASM_CASES_TAC `b = &0` THEN ASM_REWRITE_TAC[] THENL
13296 [FIRST_X_ASSUM(fun t -> MP_TAC(SPEC `&1` t) THEN
13297 MP_TAC(SPEC `-- &1` t)) THEN ASM_REAL_ARITH_TAC;
13298 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `a / &2 / b`) THEN
13299 ASM_SIMP_TAC[REAL_FIELD
13300 `&0 < b ==> (b * (a / b) pow 2) = a pow 2 / b`] THEN
13301 REWRITE_TAC[real_div; REAL_MUL_ASSOC] THEN SIMP_TAC[GSYM real_div] THEN
13302 ASM_SIMP_TAC[REAL_LE_DIV2_EQ] THEN
13303 REWRITE_TAC[REAL_LT_SQUARE; REAL_ARITH
13304 `(a * a) / &2 <= (a / &2) pow 2 <=> ~(&0 < a * a)`]]) in
13305 REPEAT STRIP_TAC THEN
13306 MP_TAC(ISPECL [`\x:real^N. (f x) dot x`;
13307 `s INTER sphere(vec 0:real^N,&1)`]
13308 CONTINUOUS_ATTAINS_SUP) THEN
13309 REWRITE_TAC[EXISTS_IN_GSPEC; FORALL_IN_GSPEC; o_DEF] THEN ANTS_TAC THENL
13310 [ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_DOT2; LINEAR_CONTINUOUS_ON;
13311 CONTINUOUS_ON_ID] THEN
13312 ASM_SIMP_TAC[COMPACT_SPHERE; CLOSED_INTER_COMPACT; CLOSED_SUBSPACE] THEN
13313 FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE
13314 `~(s = {a}) ==> a IN s ==> ?b. ~(b = a) /\ b IN s`)) THEN
13315 ASM_SIMP_TAC[SUBSPACE_0; IN_SPHERE_0; GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN
13316 DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN
13317 EXISTS_TAC `inv(norm x) % x:real^N` THEN
13318 ASM_REWRITE_TAC[IN_ELIM_THM; VECTOR_SUB_RZERO; NORM_MUL] THEN
13319 ASM_SIMP_TAC[SUBSPACE_MUL; REAL_ABS_INV; REAL_ABS_NORM] THEN
13320 ASM_SIMP_TAC[REAL_MUL_LINV; NORM_EQ_0];
13321 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `v:real^N` THEN
13322 REWRITE_TAC[IN_INTER; IN_SPHERE_0] THEN STRIP_TAC THEN
13323 ABBREV_TAC `c = (f:real^N->real^N) v dot v` THEN
13324 EXISTS_TAC `c:real` THEN ASM_REWRITE_TAC[]] THEN
13325 ABBREV_TAC `p = \x y:real^N. c * (x dot y) - (f x) dot y` THEN
13326 SUBGOAL_THEN `!x:real^N. x IN s ==> &0 <= p x x` (LABEL_TAC "POSDEF") THENL
13327 [X_GEN_TAC `x:real^N` THEN EXPAND_TAC "p" THEN REWRITE_TAC[] THEN
13328 ASM_CASES_TAC `x:real^N = vec 0` THEN DISCH_TAC THEN
13329 ASM_REWRITE_TAC[DOT_RZERO; REAL_MUL_RZERO; REAL_SUB_LE; REAL_LE_REFL] THEN
13330 FIRST_X_ASSUM(MP_TAC o SPEC `inv(norm x) % x:real^N`) THEN
13331 ASM_SIMP_TAC[SUBSPACE_MUL] THEN
13332 ASM_SIMP_TAC[LINEAR_CMUL; NORM_MUL; REAL_ABS_INV; DOT_RMUL] THEN
13333 ASM_SIMP_TAC[REAL_ABS_NORM; REAL_MUL_LINV; NORM_EQ_0; DOT_LMUL] THEN
13334 ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; DOT_POS_LT] THEN
13335 REWRITE_TAC[GSYM NORM_POW_2; real_div; REAL_INV_POW] THEN REAL_ARITH_TAC;
13337 SUBGOAL_THEN `!y:real^N. y IN s ==> !a. p v y * a <= p y y * a pow 2`
13339 [REPEAT STRIP_TAC THEN
13340 REMOVE_THEN "POSDEF" (MP_TAC o SPEC `v - (&2 * a) % y:real^N`) THEN
13341 EXPAND_TAC "p" THEN ASM_SIMP_TAC[SUBSPACE_SUB; SUBSPACE_MUL] THEN
13342 ASM_SIMP_TAC[LINEAR_SUB; LINEAR_CMUL] THEN
13343 REWRITE_TAC[DOT_LSUB; DOT_LMUL] THEN
13344 REWRITE_TAC[DOT_RSUB; DOT_RMUL] THEN
13345 SUBGOAL_THEN `f y dot (v:real^N) = f v dot y` SUBST1_TAC THENL
13346 [ASM_MESON_TAC[ADJOINT_CLAUSES; DOT_SYM]; ALL_TAC] THEN
13347 ASM_REWRITE_TAC[GSYM NORM_POW_2] THEN REWRITE_TAC[NORM_POW_2] THEN
13348 MATCH_MP_TAC(REAL_ARITH
13349 `&4 * (z - y) = x ==> &0 <= x ==> y <= z`) THEN
13350 REWRITE_TAC[DOT_SYM] THEN CONV_TAC REAL_RING;
13351 DISCH_THEN(MP_TAC o GEN `y:real^N` o DISCH `(y:real^N) IN s` o
13352 MATCH_MP lemma o C MP (ASSUME `(y:real^N) IN s`) o SPEC `y:real^N`) THEN
13353 ASM_SIMP_TAC[] THEN EXPAND_TAC "p" THEN
13354 REWRITE_TAC[GSYM DOT_LMUL; GSYM DOT_LSUB] THEN
13355 DISCH_THEN(MP_TAC o SPEC `c % v - f v:real^N`) THEN
13356 ASM_SIMP_TAC[SUBSPACE_MUL; SUBSPACE_SUB; DOT_EQ_0; VECTOR_SUB_EQ]]);;
13358 let SELF_ADJOINT_HAS_EIGENVECTOR = prove
13359 (`!f:real^N->real^N.
13360 linear f /\ adjoint f = f ==> ?v c. norm(v) = &1 /\ f(v) = c % v`,
13361 REPEAT STRIP_TAC THEN
13362 MP_TAC(ISPECL [`f:real^N->real^N`; `(:real^N)`]
13363 SELF_ADJOINT_HAS_EIGENVECTOR_IN_SUBSPACE) THEN
13364 ASM_REWRITE_TAC[SUBSPACE_UNIV; IN_UNIV] THEN DISCH_THEN MATCH_MP_TAC THEN
13365 MATCH_MP_TAC(SET_RULE `!a. ~(a IN s) ==> ~(UNIV = s)`) THEN
13366 EXISTS_TAC `vec 1:real^N` THEN
13367 REWRITE_TAC[IN_SING; VEC_EQ; ARITH_EQ]);;
13369 let SELF_ADJOINT_HAS_EIGENVECTOR_BASIS_OF_SUBSPACE = prove
13370 (`!f:real^N->real^N s.
13371 linear f /\ adjoint f = f /\
13372 subspace s /\ (!x. x IN s ==> f x IN s)
13373 ==> ?b. b SUBSET s /\
13374 pairwise orthogonal b /\
13375 (!x. x IN b ==> norm x = &1 /\ ?c. f(x) = c % x) /\
13380 (`!f:real^N->real^N s.
13381 linear f /\ adjoint f = f /\ subspace s /\ (!x. x IN s ==> f x IN s)
13382 ==> ?b. b SUBSET s /\ b HAS_SIZE dim s /\
13383 pairwise orthogonal b /\
13384 (!x. x IN b ==> norm x = &1 /\ ?c. f(x) = c % x)`,
13385 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN REWRITE_TAC[IMP_IMP] THEN
13386 GEN_TAC THEN STRIP_TAC THEN GEN_TAC THEN
13387 WF_INDUCT_TAC `dim(s:real^N->bool)` THEN STRIP_TAC THEN
13388 ASM_CASES_TAC `dim(s:real^N->bool) = 0` THENL
13389 [EXISTS_TAC `{}:real^N->bool` THEN
13390 ASM_SIMP_TAC[HAS_SIZE_CLAUSES; NOT_IN_EMPTY;
13391 PAIRWISE_EMPTY; EMPTY_SUBSET];
13393 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [DIM_EQ_0]) THEN
13394 DISCH_THEN(ASSUME_TAC o MATCH_MP (SET_RULE
13395 `~(s SUBSET {a}) ==> ~(s = {a})`)) THEN
13396 MP_TAC(ISPECL [`f:real^N->real^N`; `s:real^N->bool`]
13397 SELF_ADJOINT_HAS_EIGENVECTOR_IN_SUBSPACE) THEN
13398 ASM_REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN
13399 DISCH_THEN(X_CHOOSE_THEN `v:real^N` MP_TAC) THEN
13400 ASM_CASES_TAC `v:real^N = vec 0` THEN ASM_REWRITE_TAC[NORM_0] THEN
13401 CONV_TAC REAL_RAT_REDUCE_CONV THEN
13402 DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
13403 FIRST_X_ASSUM(MP_TAC o SPEC `{y:real^N | y IN s /\ orthogonal v y}`) THEN
13404 REWRITE_TAC[SUBSPACE_ORTHOGONAL_TO_VECTOR; IN_ELIM_THM] THEN
13405 MP_TAC(ISPECL [`span {v:real^N}`; `s:real^N->bool`]
13406 DIM_SUBSPACE_ORTHOGONAL_TO_VECTORS) THEN
13407 REWRITE_TAC[ONCE_REWRITE_RULE[ORTHOGONAL_SYM] ORTHOGONAL_TO_SPAN_EQ] THEN
13408 ASM_REWRITE_TAC[SUBSPACE_SPAN; IN_SING; FORALL_UNWIND_THM2] THEN
13410 [MATCH_MP_TAC SPAN_SUBSET_SUBSPACE THEN ASM SET_TAC[];
13411 DISCH_THEN(SUBST1_TAC o SYM)] THEN
13412 ASM_REWRITE_TAC[DIM_SPAN; DIM_SING; ARITH_RULE `n < n + 1`] THEN
13414 [REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
13415 ASM_SIMP_TAC[SUBSPACE_INTER; SUBSPACE_ORTHOGONAL_TO_VECTOR] THEN
13416 REWRITE_TAC[orthogonal] THEN X_GEN_TAC `x:real^N` THEN STRIP_TAC THEN
13417 MATCH_MP_TAC EQ_TRANS THEN
13418 EXISTS_TAC `(f:real^N->real^N) v dot x` THEN CONJ_TAC THENL
13419 [ASM_MESON_TAC[ADJOINT_CLAUSES];
13420 ASM_MESON_TAC[DOT_LMUL; REAL_MUL_RZERO]];
13421 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` STRIP_ASSUME_TAC) THEN
13422 EXISTS_TAC `(v:real^N) INSERT b` THEN
13423 ASM_REWRITE_TAC[FORALL_IN_INSERT] THEN
13424 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
13425 ASM_REWRITE_TAC[PAIRWISE_INSERT] THEN
13426 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE; SUBSET; IN_ELIM_THM]) THEN
13428 [ASM_SIMP_TAC[HAS_SIZE; FINITE_INSERT; CARD_CLAUSES] THEN
13429 COND_CASES_TAC THEN ASM_REWRITE_TAC[ADD1] THEN
13430 ASM_MESON_TAC[ORTHOGONAL_REFL];
13431 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_ELIM_THM]) THEN
13432 ASM_MESON_TAC[ORTHOGONAL_SYM]]]) in
13433 REPEAT STRIP_TAC THEN
13434 MP_TAC(ISPECL [`f:real^N->real^N`; `s:real^N->bool`] lemma) THEN
13435 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN
13436 X_GEN_TAC `b:real^N->bool` THEN
13437 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
13438 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
13439 [MATCH_MP_TAC PAIRWISE_ORTHOGONAL_INDEPENDENT THEN
13440 ASM_MESON_TAC[NORM_ARITH `~(norm(vec 0:real^N) = &1)`];
13441 DISCH_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
13442 [ASM_MESON_TAC[SPAN_SUBSET_SUBSPACE];
13443 MATCH_MP_TAC CARD_GE_DIM_INDEPENDENT THEN
13444 RULE_ASSUM_TAC(REWRITE_RULE[HAS_SIZE]) THEN
13445 ASM_REWRITE_TAC[LE_REFL]]]);;
13447 let SELF_ADJOINT_HAS_EIGENVECTOR_BASIS = prove
13448 (`!f:real^N->real^N.
13449 linear f /\ adjoint f = f
13450 ==> ?b. pairwise orthogonal b /\
13451 (!x. x IN b ==> norm x = &1 /\ ?c. f(x) = c % x) /\
13453 span b = (:real^N) /\
13454 b HAS_SIZE (dimindex(:N))`,
13455 REPEAT STRIP_TAC THEN
13456 MP_TAC(ISPECL [`f:real^N->real^N`; `(:real^N)`]
13457 SELF_ADJOINT_HAS_EIGENVECTOR_BASIS_OF_SUBSPACE) THEN
13458 ASM_REWRITE_TAC[SUBSPACE_UNIV; IN_UNIV; DIM_UNIV; SUBSET_UNIV]);;
13460 (* ------------------------------------------------------------------------- *)
13461 (* Diagonalization of symmetric matrix. *)
13462 (* ------------------------------------------------------------------------- *)
13464 let SYMMETRIC_MATRIX_DIAGONALIZABLE_EXPLICIT = prove
13467 ==> ?P d. orthogonal_matrix P /\
13468 transp P ** A ** P = (lambda i j. if i = j then d i else &0)`,
13470 (`!A:real^N^N P:real^N^N d.
13471 A ** P = P ** (lambda i j. if i = j then d i else &0) <=>
13472 !i. 1 <= i /\ i <= dimindex(:N)
13473 ==> A ** column i P = d i % column i P`,
13474 SIMP_TAC[CART_EQ; matrix_mul; matrix_vector_mul; LAMBDA_BETA;
13475 column; VECTOR_MUL_COMPONENT] THEN
13476 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[COND_RAND] THEN
13477 SIMP_TAC[REAL_MUL_RZERO; SUM_DELTA; IN_NUMSEG] THEN
13478 EQ_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC[] THEN
13479 REWRITE_TAC[REAL_MUL_SYM]) in
13481 (`!A:real^N^N P:real^N^N d.
13482 orthogonal_matrix P /\
13483 transp P ** A ** P = (lambda i j. if i = j then d i else &0) <=>
13484 orthogonal_matrix P /\
13485 !i. 1 <= i /\ i <= dimindex(:N)
13486 ==> A ** column i P = d i % column i P`,
13487 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM lemma1; orthogonal_matrix] THEN
13488 ABBREV_TAC `D:real^N^N = lambda i j. if i = j then d i else &0` THEN
13489 MESON_TAC[MATRIX_MUL_ASSOC; MATRIX_MUL_LID]) in
13490 REPEAT STRIP_TAC THEN
13491 REWRITE_TAC[lemma2] THEN REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN
13492 REWRITE_TAC[GSYM SKOLEM_THM] THEN
13493 MP_TAC(ISPEC `\x:real^N. (A:real^N^N) ** x`
13494 SELF_ADJOINT_HAS_EIGENVECTOR_BASIS) THEN
13495 ASM_SIMP_TAC[MATRIX_SELF_ADJOINT; MATRIX_VECTOR_MUL_LINEAR;
13496 MATRIX_OF_MATRIX_VECTOR_MUL] THEN
13497 DISCH_THEN(X_CHOOSE_THEN `b:real^N->bool` MP_TAC) THEN
13498 REWRITE_TAC[CONJ_ASSOC] THEN ONCE_REWRITE_TAC[IMP_CONJ_ALT] THEN
13499 REWRITE_TAC[HAS_SIZE] THEN STRIP_TAC THEN
13500 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN
13501 ASM_REWRITE_TAC[IN_NUMSEG; TAUT
13502 `p /\ q /\ x = y ==> a = b <=> p /\ q /\ ~(a = b) ==> ~(x = y)`] THEN
13503 DISCH_THEN(X_CHOOSE_THEN `f:num->real^N` STRIP_ASSUME_TAC) THEN
13504 ASM_REWRITE_TAC[PAIRWISE_IMAGE; FORALL_IN_IMAGE] THEN
13505 ASM_SIMP_TAC[pairwise; IN_NUMSEG] THEN STRIP_TAC THEN
13506 EXISTS_TAC `transp(lambda i. f i):real^N^N` THEN
13507 SIMP_TAC[COLUMN_TRANSP; ORTHOGONAL_MATRIX_TRANSP] THEN
13508 SIMP_TAC[ORTHOGONAL_MATRIX_ORTHONORMAL_ROWS_INDEXED; row] THEN
13509 SIMP_TAC[LAMBDA_ETA; LAMBDA_BETA; pairwise; IN_NUMSEG] THEN
13512 let SYMMETRIC_MATRIX_IMP_DIAGONALIZABLE = prove
13515 ==> ?P. orthogonal_matrix P /\ diagonal_matrix(transp P ** A ** P)`,
13517 DISCH_THEN(MP_TAC o MATCH_MP SYMMETRIC_MATRIX_DIAGONALIZABLE_EXPLICIT) THEN
13518 MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
13519 SIMP_TAC[diagonal_matrix; LAMBDA_BETA]);;
13521 let SYMMETRIC_MATRIX_EQ_DIAGONALIZABLE = prove
13524 ?P. orthogonal_matrix P /\ diagonal_matrix(transp P ** A ** P)`,
13525 GEN_TAC THEN EQ_TAC THEN
13526 REWRITE_TAC[SYMMETRIC_MATRIX_IMP_DIAGONALIZABLE] THEN
13527 REWRITE_TAC[orthogonal_matrix] THEN
13528 DISCH_THEN(X_CHOOSE_THEN `P:real^N^N` STRIP_ASSUME_TAC) THEN
13529 ABBREV_TAC `D:real^N^N = transp P ** (A:real^N^N) ** P` THEN
13530 SUBGOAL_THEN `A:real^N^N = P ** (D:real^N^N) ** transp P` SUBST1_TAC THENL
13531 [EXPAND_TAC "D" THEN REWRITE_TAC[MATRIX_MUL_ASSOC] THEN
13532 ASM_REWRITE_TAC[MATRIX_MUL_LID] THEN
13533 ASM_REWRITE_TAC[GSYM MATRIX_MUL_ASSOC; MATRIX_MUL_RID];
13534 REWRITE_TAC[MATRIX_TRANSP_MUL; TRANSP_TRANSP; MATRIX_MUL_ASSOC] THEN
13535 ASM_MESON_TAC[TRANSP_DIAGONAL_MATRIX]]);;
13537 (* ------------------------------------------------------------------------- *)
13538 (* Some matrix identities are easier to deduce for invertible matrices. We *)
13539 (* can then extend by continuity, which is why this material needs to be *)
13540 (* here after basic topological notions have been defined. *)
13541 (* ------------------------------------------------------------------------- *)
13543 let CONTINUOUS_LIFT_DET = prove
13544 (`!(A:A->real^N^N) net.
13545 (!i j. 1 <= i /\ i <= dimindex(:N) /\
13546 1 <= j /\ j <= dimindex(:N)
13547 ==> (\x. lift(A x$i$j)) continuous net)
13548 ==> (\x. lift(det(A x))) continuous net`,
13549 REPEAT STRIP_TAC THEN REWRITE_TAC[det] THEN
13550 SIMP_TAC[LIFT_SUM; FINITE_PERMUTATIONS; FINITE_NUMSEG; o_DEF] THEN
13551 MATCH_MP_TAC CONTINUOUS_VSUM THEN
13552 SIMP_TAC[FINITE_PERMUTATIONS; FINITE_NUMSEG; LIFT_CMUL; IN_ELIM_THM] THEN
13553 X_GEN_TAC `p:num->num` THEN DISCH_TAC THEN
13554 MATCH_MP_TAC CONTINUOUS_CMUL THEN
13555 MATCH_MP_TAC CONTINUOUS_LIFT_PRODUCT THEN
13556 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
13557 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
13558 FIRST_ASSUM(MP_TAC o MATCH_MP PERMUTES_IMAGE) THEN
13559 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE `s = t ==> s SUBSET t`)) THEN
13560 ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG]);;
13562 let CONTINUOUS_ON_LIFT_DET = prove
13563 (`!A:real^M->real^N^N s.
13564 (!i j. 1 <= i /\ i <= dimindex(:N) /\
13565 1 <= j /\ j <= dimindex(:N)
13566 ==> (\x. lift(A x$i$j)) continuous_on s)
13567 ==> (\x. lift(det(A x))) continuous_on s`,
13568 SIMP_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; CONTINUOUS_LIFT_DET]);;
13570 let NEARBY_INVERTIBLE_MATRIX = prove
13572 ?e. &0 < e /\ !x. ~(x = &0) /\ abs x < e ==> invertible(A + x %% mat 1)`,
13573 GEN_TAC THEN MP_TAC(ISPEC `A:real^N^N` CHARACTERISTIC_POLYNOMIAL) THEN
13574 DISCH_THEN(X_CHOOSE_THEN `a:num->real` STRIP_ASSUME_TAC) THEN
13575 MP_TAC(ISPECL [`dimindex(:N)`; `a:num->real`] REAL_POLYFUN_FINITE_ROOTS) THEN
13576 MATCH_MP_TAC(TAUT `q /\ (p ==> r) ==> (p <=> q) ==> r`) THEN CONJ_TAC THENL
13577 [EXISTS_TAC `dimindex(:N)` THEN ASM_REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC;
13579 DISCH_THEN(MP_TAC o ISPEC `lift` o MATCH_MP FINITE_IMAGE) THEN
13580 DISCH_THEN(MP_TAC o MATCH_MP LIMIT_POINT_FINITE) THEN
13581 DISCH_THEN(MP_TAC o SPEC `lift(&0)`) THEN
13582 REWRITE_TAC[LIMPT_APPROACHABLE; EXISTS_IN_IMAGE; EXISTS_IN_GSPEC] THEN
13583 REWRITE_TAC[DIST_LIFT; LIFT_EQ; REAL_SUB_RZERO; NOT_FORALL_THM; NOT_IMP] THEN
13584 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN
13585 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN
13586 DISCH_THEN(fun th -> X_GEN_TAC `x:real` THEN STRIP_TAC THEN
13587 MP_TAC(SPEC `--x:real` th)) THEN
13588 FIRST_X_ASSUM(SUBST1_TAC o SYM o SPEC `--x:real`) THEN
13589 ASM_REWRITE_TAC[REAL_NEG_EQ_0; REAL_ABS_NEG] THEN
13590 ONCE_REWRITE_TAC[GSYM INVERTIBLE_NEG] THEN
13591 REWRITE_TAC[INVERTIBLE_DET_NZ; CONTRAPOS_THM] THEN
13592 REWRITE_TAC[MATRIX_SUB; MATRIX_NEG_MINUS1] THEN
13593 ONCE_REWRITE_TAC[REAL_ARITH `--x = -- &1 * x`] THEN
13594 REWRITE_TAC[GSYM MATRIX_CMUL_ADD_LDISTRIB; GSYM MATRIX_CMUL_ASSOC] THEN
13595 REWRITE_TAC[MATRIX_CMUL_LID; MATRIX_ADD_SYM]);;
13597 let MATRIX_WLOG_INVERTIBLE = prove
13598 (`!P. (!A:real^N^N. invertible A ==> P A) /\
13599 (!A:real^N^N. ?d. &0 < d /\
13600 closed {x | x IN cball(vec 0,d) /\
13601 P(A + drop x %% mat 1)})
13602 ==> !A:real^N^N. P A`,
13603 REPEAT GEN_TAC THEN
13604 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
13605 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
13606 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
13607 FIRST_ASSUM(MP_TAC o SPEC `vec 0:real^1` o
13608 GEN_REWRITE_RULE I [CLOSED_LIMPT]) THEN
13609 ASM_SIMP_TAC[IN_ELIM_THM; DROP_VEC; MATRIX_CMUL_LZERO; MATRIX_ADD_RID] THEN
13610 ANTS_TAC THENL [ALL_TAC; CONV_TAC TAUT] THEN
13611 MP_TAC(ISPEC `A:real^N^N` NEARBY_INVERTIBLE_MATRIX) THEN
13612 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
13613 REWRITE_TAC[LIMPT_APPROACHABLE] THEN X_GEN_TAC `k:real` THEN
13614 DISCH_TAC THEN REWRITE_TAC[EXISTS_LIFT; IN_ELIM_THM] THEN
13615 REWRITE_TAC[GSYM LIFT_NUM; IN_CBALL_0; NORM_LIFT; DIST_LIFT] THEN
13616 REWRITE_TAC[REAL_SUB_RZERO; LIFT_EQ; LIFT_DROP] THEN
13617 EXISTS_TAC `min d ((min e k) / &2)` THEN
13618 CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC] THEN
13619 CONJ_TAC THENL [ASM_REAL_ARITH_TAC; FIRST_X_ASSUM MATCH_MP_TAC] THEN
13620 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC);;
13622 let SYLVESTER_DETERMINANT_IDENTITY = prove
13623 (`!A:real^N^M B:real^M^N. det(mat 1 + A ** B) = det(mat 1 + B ** A)`,
13625 (`!A:real^N^N B:real^N^N. det(mat 1 + A ** B) = det(mat 1 + B ** A)`,
13626 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN GEN_TAC THEN
13627 MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN CONJ_TAC THENL
13628 [REPEAT STRIP_TAC THEN
13629 SUBGOAL_THEN `det((mat 1 + A ** B) ** A:real^N^N) =
13630 det(A ** (mat 1 + B ** A))`
13632 [REWRITE_TAC[MATRIX_ADD_RDISTRIB; MATRIX_ADD_LDISTRIB] THEN
13633 REWRITE_TAC[MATRIX_MUL_LID; MATRIX_MUL_RID; MATRIX_MUL_ASSOC];
13634 REWRITE_TAC[DET_MUL] THEN
13635 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INVERTIBLE_DET_NZ]) THEN
13636 CONV_TAC REAL_RING];
13637 X_GEN_TAC `A:real^N^N` THEN EXISTS_TAC `&1` THEN
13638 REWRITE_TAC[REAL_LT_01; SET_RULE
13639 `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
13640 MATCH_MP_TAC CLOSED_INTER THEN REWRITE_TAC[CLOSED_CBALL] THEN
13641 ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN
13642 REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN
13643 REWRITE_TAC[SET_RULE `{x | f x = a} = {x | f x IN {a}}`] THEN
13644 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN
13645 REWRITE_TAC[CLOSED_SING; LIFT_SUB] THEN X_GEN_TAC `x:real^1` THEN
13646 REWRITE_TAC[o_DEF; LIFT_SUB] THEN MATCH_MP_TAC CONTINUOUS_SUB THEN
13647 CONJ_TAC THEN MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN
13648 MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN STRIP_TAC THEN
13649 ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; LIFT_ADD] THEN
13650 MATCH_MP_TAC CONTINUOUS_ADD THEN
13651 ASM_SIMP_TAC[matrix_mul; LAMBDA_BETA; CONTINUOUS_CONST] THEN
13652 SIMP_TAC[LIFT_SUM; FINITE_NUMSEG; o_DEF] THEN
13653 MATCH_MP_TAC CONTINUOUS_VSUM THEN
13654 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN X_GEN_TAC `k:num` THEN
13655 DISCH_TAC THENL [ONCE_REWRITE_TAC[REAL_MUL_SYM]; ALL_TAC] THEN
13656 REWRITE_TAC[LIFT_CMUL] THEN MATCH_MP_TAC CONTINUOUS_CMUL THEN
13657 REWRITE_TAC[MATRIX_ADD_COMPONENT; MATRIX_CMUL_COMPONENT; LIFT_ADD] THEN
13658 MATCH_MP_TAC CONTINUOUS_ADD THEN REWRITE_TAC[CONTINUOUS_CONST] THEN
13659 REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] LIFT_CMUL] THEN
13660 MATCH_MP_TAC CONTINUOUS_CMUL THEN
13661 REWRITE_TAC[LIFT_DROP; CONTINUOUS_AT_ID]]) in
13663 (`!A:real^N^M B:real^M^N.
13664 dimindex(:M) <= dimindex(:N)
13665 ==> det(mat 1 + A ** B) = det(mat 1 + B ** A)`,
13666 REPEAT STRIP_TAC THEN
13667 MAP_EVERY ABBREV_TAC
13669 lambda i j. if i <= dimindex(:M) then (A:real^N^M)$i$j
13672 lambda i j. if j <= dimindex(:M) then (B:real^M^N)$i$j
13674 MP_TAC(ISPECL [`A':real^N^N`; `B':real^N^N`] lemma1) THEN
13676 `(B':real^N^N) ** (A':real^N^N) = (B:real^M^N) ** (A:real^N^M)`
13678 [MAP_EVERY EXPAND_TAC ["A'"; "B'"] THEN
13679 SIMP_TAC[CART_EQ; LAMBDA_BETA; matrix_mul] THEN REPEAT STRIP_TAC THEN
13680 MATCH_MP_TAC SUM_EQ_SUPERSET THEN
13681 ASM_SIMP_TAC[IN_NUMSEG; REAL_MUL_LZERO; FINITE_NUMSEG; SUBSET_NUMSEG;
13682 LE_REFL; TAUT `(p /\ q) /\ ~(p /\ r) <=> p /\ q /\ ~r`];
13683 DISCH_THEN(SUBST1_TAC o SYM)] THEN
13684 REWRITE_TAC[det] THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC
13685 `sum {p | p permutes 1..dimindex(:N) /\ !i. dimindex(:M) < i ==> p i = i}
13686 (\p. sign p * product (1..dimindex(:N))
13687 (\i. (mat 1 + (A':real^N^N) ** (B':real^N^N))$i$p i))` THEN
13690 CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_SUPERSET THEN
13691 CONJ_TAC THENL [SET_TAC[]; SIMP_TAC[IN_ELIM_THM; IMP_CONJ]] THEN
13692 X_GEN_TAC `p:num->num` THEN REPEAT STRIP_TAC THEN
13693 REWRITE_TAC[REAL_ENTIRE; PRODUCT_EQ_0_NUMSEG] THEN DISJ2_TAC THEN
13694 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN
13695 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:num` THEN
13696 REWRITE_TAC[NOT_IMP] THEN STRIP_TAC THEN
13697 FIRST_ASSUM(MP_TAC o SPEC `k:num` o CONJUNCT1 o
13698 GEN_REWRITE_RULE I [permutes]) THEN
13699 ASM_REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
13700 FIRST_ASSUM(MP_TAC o MATCH_MP PERMUTES_IMAGE) THEN
13701 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE `s = t ==> s SUBSET t`)) THEN
13702 ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG] THEN
13703 DISCH_THEN(MP_TAC o SPEC `k:num`) THEN ASM_SIMP_TAC[] THEN STRIP_TAC THEN
13704 ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MAT_COMPONENT; REAL_ADD_LID] THEN
13705 ASM_SIMP_TAC[matrix_mul; LAMBDA_BETA] THEN
13706 MATCH_MP_TAC SUM_EQ_0_NUMSEG THEN REPEAT STRIP_TAC THEN
13707 REWRITE_TAC[REAL_ENTIRE] THEN DISJ1_TAC THEN EXPAND_TAC "A'" THEN
13708 ASM_SIMP_TAC[LAMBDA_BETA; GSYM NOT_LT]] THEN
13709 CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_EQ_GENERAL THEN
13710 EXISTS_TAC `\f:num->num. f` THEN REWRITE_TAC[IN_ELIM_THM] THEN
13711 CONJ_TAC THEN X_GEN_TAC `p:num->num` THEN STRIP_TAC THENL
13712 [REWRITE_TAC[MESON[] `(?!x. P x /\ x = y) <=> P y`] THEN CONJ_TAC THENL
13713 [MATCH_MP_TAC PERMUTES_SUBSET THEN
13714 EXISTS_TAC `1..dimindex(:M)` THEN
13715 ASM_REWRITE_TAC[SUBSET_NUMSEG; LE_REFL];
13716 X_GEN_TAC `k:num` THEN DISCH_TAC THEN
13717 FIRST_X_ASSUM(MATCH_MP_TAC o CONJUNCT1 o
13718 GEN_REWRITE_RULE I [permutes]) THEN
13719 ASM_REWRITE_TAC[IN_NUMSEG; DE_MORGAN_THM; NOT_LE]];
13720 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
13721 [MATCH_MP_TAC PERMUTES_SUPERSET THEN
13722 EXISTS_TAC `1..dimindex(:N)` THEN
13723 ASM_REWRITE_TAC[IN_DIFF; IN_NUMSEG] THEN ASM_MESON_TAC[NOT_LE];
13725 AP_TERM_TAC THEN FIRST_ASSUM(SUBST1_TAC o MATCH_MP (ARITH_RULE
13726 `m:num <= n ==> n = m + (n - m)`)) THEN
13727 SIMP_TAC[PRODUCT_ADD_SPLIT; ARITH_RULE `1 <= n + 1`] THEN
13728 MATCH_MP_TAC(REAL_RING `x = y /\ z = &1 ==> x = y * z`) THEN
13730 [MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN
13731 X_GEN_TAC `i:num` THEN STRIP_TAC THEN
13732 SUBGOAL_THEN `i <= dimindex(:N)` ASSUME_TAC THENL
13733 [ASM_ARITH_TAC; ALL_TAC] THEN
13734 MP_TAC(ISPECL [`p:num->num`; `1..dimindex(:M)`] PERMUTES_IMAGE) THEN
13735 ASM_REWRITE_TAC[] THEN
13736 DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE `s = t ==> s SUBSET t`)) THEN
13737 ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG] THEN
13738 DISCH_THEN(MP_TAC o SPEC `i:num`) THEN
13739 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
13740 SUBGOAL_THEN `(p:num->num) i <= dimindex(:N)` ASSUME_TAC THENL
13741 [ASM_ARITH_TAC; ALL_TAC] THEN
13742 ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MAT_COMPONENT] THEN
13743 AP_TERM_TAC THEN ASM_SIMP_TAC[matrix_mul; LAMBDA_BETA] THEN
13744 MATCH_MP_TAC SUM_EQ_NUMSEG THEN REPEAT STRIP_TAC THEN
13745 MAP_EVERY EXPAND_TAC ["A'"; "B'"] THEN
13746 ASM_SIMP_TAC[LAMBDA_BETA];
13747 MATCH_MP_TAC PRODUCT_EQ_1_NUMSEG THEN
13748 ASM_SIMP_TAC[ARITH_RULE `n + 1 <= i ==> n < i`] THEN
13749 ASM_SIMP_TAC[ARITH_RULE `m:num <= n ==> m + (n - m) = n`] THEN
13750 X_GEN_TAC `i:num` THEN STRIP_TAC THEN
13751 SUBGOAL_THEN `1 <= i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
13752 ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MAT_COMPONENT] THEN
13753 ASM_SIMP_TAC[REAL_EQ_ADD_LCANCEL_0; matrix_mul; LAMBDA_BETA] THEN
13754 MATCH_MP_TAC SUM_EQ_0_NUMSEG THEN REPEAT STRIP_TAC THEN
13755 REWRITE_TAC[REAL_ENTIRE] THEN DISJ1_TAC THEN EXPAND_TAC "A'" THEN
13756 ASM_SIMP_TAC[LAMBDA_BETA; ARITH_RULE `m + 1 <= i ==> ~(i <= m)`]]]) in
13757 REPEAT GEN_TAC THEN DISJ_CASES_TAC (ARITH_RULE
13758 `dimindex(:M) <= dimindex(:N) \/ dimindex(:N) <= dimindex(:M)`)
13759 THENL [ALL_TAC; CONV_TAC SYM_CONV] THEN
13760 MATCH_MP_TAC lemma2 THEN ASM_REWRITE_TAC[]);;
13762 let COFACTOR_MATRIX_MUL = prove
13763 (`!A B:real^N^N. cofactor(A ** B) = cofactor(A) ** cofactor(B)`,
13764 MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN CONJ_TAC THENL
13765 [GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN
13767 [ASM_SIMP_TAC[COFACTOR_MATRIX_INV; GSYM INVERTIBLE_DET_NZ;
13768 INVERTIBLE_MATRIX_MUL] THEN
13769 REWRITE_TAC[DET_MUL; MATRIX_MUL_LMUL] THEN
13770 REWRITE_TAC[MATRIX_MUL_RMUL; MATRIX_CMUL_ASSOC;
13771 GSYM MATRIX_TRANSP_MUL] THEN
13772 ASM_SIMP_TAC[MATRIX_INV_MUL];
13773 GEN_TAC THEN EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01]];
13774 X_GEN_TAC `A:real^N^N` THEN EXISTS_TAC `&1` THEN
13775 REWRITE_TAC[REAL_LT_01] THEN REWRITE_TAC[RIGHT_AND_FORALL_THM] THEN
13776 MATCH_MP_TAC CLOSED_FORALL THEN GEN_TAC] THEN
13777 REWRITE_TAC[SET_RULE
13778 `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
13779 MATCH_MP_TAC CLOSED_INTER THEN REWRITE_TAC[CLOSED_CBALL] THEN
13780 REWRITE_TAC[CART_EQ] THEN
13781 MATCH_MP_TAC CLOSED_FORALL_IN THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
13782 MATCH_MP_TAC CLOSED_FORALL_IN THEN X_GEN_TAC `j:num` THEN STRIP_TAC THEN
13783 ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN
13784 REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN
13785 REWRITE_TAC[SET_RULE `{x | f x = a} = {x | f x IN {a}}`] THEN
13786 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN
13787 REWRITE_TAC[CLOSED_SING; LIFT_SUB] THEN X_GEN_TAC `x:real^1` THEN
13788 ASM_SIMP_TAC[matrix_mul; LAMBDA_BETA; cofactor; LIFT_SUM;
13789 FINITE_NUMSEG; o_DEF] THEN
13790 (MATCH_MP_TAC CONTINUOUS_SUB THEN CONJ_TAC THENL
13792 MATCH_MP_TAC CONTINUOUS_VSUM THEN
13793 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
13794 X_GEN_TAC `k:num` THEN STRIP_TAC THEN
13795 REWRITE_TAC[LIFT_CMUL] THEN MATCH_MP_TAC CONTINUOUS_MUL THEN
13796 REWRITE_TAC[o_DEF] THEN CONJ_TAC]) THEN
13797 MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN
13798 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN
13799 ASM_SIMP_TAC[LAMBDA_BETA; CONTINUOUS_CONST] THEN
13800 REPEAT(W(fun (asl,w) ->
13801 let t = find_term is_cond w in
13802 ASM_CASES_TAC (lhand(rator t)) THEN ASM_REWRITE_TAC[CONTINUOUS_CONST])) THEN
13803 SIMP_TAC[LIFT_SUM; FINITE_NUMSEG; o_DEF] THEN
13804 TRY(MATCH_MP_TAC CONTINUOUS_VSUM THEN REWRITE_TAC[FINITE_NUMSEG] THEN
13805 REWRITE_TAC[IN_NUMSEG] THEN X_GEN_TAC `p:num` THEN STRIP_TAC) THEN
13806 REWRITE_TAC[LIFT_CMUL] THEN
13807 TRY(MATCH_MP_TAC CONTINUOUS_MUL THEN
13808 REWRITE_TAC[o_DEF; CONTINUOUS_CONST]) THEN
13809 REWRITE_TAC[MATRIX_ADD_COMPONENT; LIFT_ADD] THEN
13810 MATCH_MP_TAC CONTINUOUS_ADD THEN REWRITE_TAC[CONTINUOUS_CONST] THEN
13811 REWRITE_TAC[MATRIX_CMUL_COMPONENT; LIFT_CMUL; o_DEF] THEN
13812 MATCH_MP_TAC CONTINUOUS_MUL THEN
13813 REWRITE_TAC[CONTINUOUS_CONST; o_DEF; LIFT_DROP; CONTINUOUS_AT_ID]);;
13815 let DET_COFACTOR = prove
13816 (`!A:real^N^N. det(cofactor A) = det(A) pow (dimindex(:N) - 1)`,
13817 MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN CONJ_TAC THEN
13818 X_GEN_TAC `A:real^N^N` THENL
13819 [REWRITE_TAC[INVERTIBLE_DET_NZ] THEN STRIP_TAC THEN
13820 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_FIELD
13821 `~(a = &0) ==> a * x = a * y ==> x = y`)) THEN
13822 GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM DET_TRANSP] THEN
13823 REWRITE_TAC[GSYM DET_MUL; MATRIX_MUL_RIGHT_COFACTOR] THEN
13824 REWRITE_TAC[DET_CMUL; GSYM(CONJUNCT2 real_pow); DET_I; REAL_MUL_RID] THEN
13825 SIMP_TAC[DIMINDEX_GE_1; ARITH_RULE `1 <= n ==> SUC(n - 1) = n`];
13827 EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
13828 REWRITE_TAC[SET_RULE
13829 `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
13830 MATCH_MP_TAC CLOSED_INTER THEN REWRITE_TAC[CLOSED_CBALL] THEN
13831 ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN
13832 REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN
13833 REWRITE_TAC[SET_RULE `{x | f x = a} = {x | f x IN {a}}`] THEN
13834 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN
13835 REWRITE_TAC[CLOSED_SING; LIFT_SUB] THEN X_GEN_TAC `x:real^1` THEN
13836 MATCH_MP_TAC CONTINUOUS_SUB THEN
13837 CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC CONTINUOUS_LIFT_POW] THEN
13838 MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN
13839 MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN STRIP_TAC THEN
13840 ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MATRIX_CMUL_COMPONENT; LIFT_ADD;
13841 LIFT_CMUL; LIFT_DROP; CONTINUOUS_ADD; CONTINUOUS_CONST;
13842 CONTINUOUS_MUL; o_DEF; LIFT_DROP; CONTINUOUS_AT_ID] THEN
13843 ASM_SIMP_TAC[cofactor; LAMBDA_BETA] THEN
13844 MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN
13845 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN STRIP_TAC THEN
13846 ASM_SIMP_TAC[LAMBDA_BETA] THEN
13847 REPEAT(W(fun (asl,w) ->
13848 let t = find_term is_cond w in
13849 ASM_CASES_TAC (lhand(rator t)) THEN ASM_REWRITE_TAC[CONTINUOUS_CONST])) THEN
13850 ASM_SIMP_TAC[MATRIX_ADD_COMPONENT; MATRIX_CMUL_COMPONENT; LIFT_ADD;
13851 LIFT_CMUL; LIFT_DROP; CONTINUOUS_ADD; CONTINUOUS_CONST;
13852 CONTINUOUS_MUL; o_DEF; LIFT_DROP; CONTINUOUS_AT_ID]);;
13854 let INVERTIBLE_COFACTOR = prove
13855 (`!A:real^N^N. invertible(cofactor A) <=> dimindex(:N) = 1 \/ invertible A`,
13856 SIMP_TAC[DET_COFACTOR; INVERTIBLE_DET_NZ; REAL_POW_EQ_0; DE_MORGAN_THM;
13857 DIMINDEX_GE_1; ARITH_RULE `1 <= n ==> (n - 1 = 0 <=> n = 1)`;
13860 let COFACTOR_COFACTOR = prove
13863 ==> cofactor(cofactor A) = (det(A) pow (dimindex(:N) - 2)) %% A`,
13864 REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN DISCH_TAC THEN
13865 MATCH_MP_TAC MATRIX_WLOG_INVERTIBLE THEN CONJ_TAC THEN
13866 X_GEN_TAC `A:real^N^N` THENL
13867 [REWRITE_TAC[INVERTIBLE_DET_NZ] THEN DISCH_TAC THEN
13868 MP_TAC(ISPECL [`A:real^N^N`; `transp(cofactor A):real^N^N`]
13869 COFACTOR_MATRIX_MUL) THEN
13870 REWRITE_TAC[MATRIX_MUL_RIGHT_COFACTOR; COFACTOR_CMUL; COFACTOR_I] THEN
13871 REWRITE_TAC[COFACTOR_TRANSP] THEN
13872 DISCH_THEN(MP_TAC o AP_TERM `transp:real^N^N->real^N^N`) THEN
13873 REWRITE_TAC[MATRIX_TRANSP_MUL; TRANSP_TRANSP; TRANSP_MATRIX_CMUL] THEN
13874 REWRITE_TAC[TRANSP_MAT] THEN
13875 DISCH_THEN(MP_TAC o AP_TERM `(\x. x ** A):real^N^N->real^N^N`) THEN
13876 REWRITE_TAC[GSYM MATRIX_MUL_ASSOC; MATRIX_MUL_LEFT_COFACTOR] THEN
13877 REWRITE_TAC[MATRIX_MUL_LMUL; MATRIX_MUL_RMUL] THEN
13878 REWRITE_TAC[MATRIX_MUL_LID; MATRIX_MUL_RID] THEN
13879 DISCH_THEN(MP_TAC o AP_TERM `\x:real^N^N. inv(det(A:real^N^N)) %% x`) THEN
13880 ASM_SIMP_TAC[MATRIX_CMUL_ASSOC; REAL_MUL_LINV; MATRIX_CMUL_LID] THEN
13881 DISCH_THEN(SUBST1_TAC o SYM) THEN AP_THM_TAC THEN AP_TERM_TAC THEN
13882 ASM_SIMP_TAC[REAL_POW_SUB; ARITH_RULE `2 <= n ==> 1 <= n`] THEN
13883 REWRITE_TAC[REAL_POW_2; real_div; REAL_INV_POW] THEN REAL_ARITH_TAC;
13884 POP_ASSUM(K ALL_TAC)] THEN
13885 EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
13886 REWRITE_TAC[SET_RULE
13887 `{x | x IN s /\ P x} = s INTER {x | P x}`] THEN
13888 MATCH_MP_TAC CLOSED_INTER THEN REWRITE_TAC[CLOSED_CBALL] THEN
13889 REWRITE_TAC[CART_EQ] THEN
13890 MATCH_MP_TAC CLOSED_FORALL_IN THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
13891 MATCH_MP_TAC CLOSED_FORALL_IN THEN X_GEN_TAC `j:num` THEN STRIP_TAC THEN
13892 ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN
13893 REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN
13894 REWRITE_TAC[SET_RULE `{x | f x = a} = {x | f x IN {a}}`] THEN
13895 MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN
13896 REWRITE_TAC[CLOSED_SING; LIFT_SUB] THEN X_GEN_TAC `x:real^1` THEN
13897 MATCH_MP_TAC CONTINUOUS_SUB THEN CONJ_TAC THENL
13899 (ONCE_REWRITE_TAC[cofactor] THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN
13900 MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN REPEAT STRIP_TAC THEN
13901 ASM_SIMP_TAC[LAMBDA_BETA] THEN
13902 REPEAT(W(fun (asl,w) ->
13903 let t = find_term is_cond w in
13904 ASM_CASES_TAC (lhand(rator t)) THEN
13905 ASM_REWRITE_TAC[CONTINUOUS_CONST])));
13906 REWRITE_TAC[MATRIX_CMUL_COMPONENT; LIFT_CMUL] THEN
13907 MATCH_MP_TAC CONTINUOUS_MUL THEN REWRITE_TAC[o_DEF] THEN CONJ_TAC THENL
13908 [MATCH_MP_TAC CONTINUOUS_LIFT_POW THEN
13909 MATCH_MP_TAC CONTINUOUS_LIFT_DET THEN REPEAT STRIP_TAC;
13911 REWRITE_TAC[MATRIX_ADD_COMPONENT; MATRIX_CMUL_COMPONENT] THEN
13912 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
13913 REWRITE_TAC[LIFT_ADD; LIFT_CMUL; LIFT_DROP] THEN
13914 SIMP_TAC[CONTINUOUS_ADD; CONTINUOUS_CONST; CONTINUOUS_CMUL;
13915 CONTINUOUS_AT_ID]);;
13917 (* ------------------------------------------------------------------------- *)
13918 (* Infinite sums of vectors. Allow general starting point (and more). *)
13919 (* ------------------------------------------------------------------------- *)
13921 parse_as_infix("sums",(12,"right"));;
13923 let sums = new_definition
13924 `(f sums l) s = ((\n. vsum(s INTER (0..n)) f) --> l) sequentially`;;
13926 let infsum = new_definition
13927 `infsum s f = @l. (f sums l) s`;;
13929 let summable = new_definition
13930 `summable s f = ?l. (f sums l) s`;;
13932 let SUMS_SUMMABLE = prove
13933 (`!f l s. (f sums l) s ==> summable s f`,
13934 REWRITE_TAC[summable] THEN MESON_TAC[]);;
13936 let SUMS_INFSUM = prove
13937 (`!f s. (f sums (infsum s f)) s <=> summable s f`,
13938 REWRITE_TAC[infsum; summable] THEN MESON_TAC[]);;
13940 let SUMS_LIM = prove
13941 (`!f:num->real^N s.
13942 (f sums lim sequentially (\n. vsum (s INTER (0..n)) f)) s
13944 GEN_TAC THEN GEN_TAC THEN EQ_TAC THENL [MESON_TAC[summable];
13945 REWRITE_TAC[summable; sums] THEN STRIP_TAC THEN REWRITE_TAC[lim] THEN
13946 ASM_MESON_TAC[]]);;
13948 let FINITE_INTER_NUMSEG = prove
13949 (`!s m n. FINITE(s INTER (m..n))`,
13950 MESON_TAC[FINITE_SUBSET; FINITE_NUMSEG; INTER_SUBSET]);;
13952 let SERIES_FROM = prove
13953 (`!f l k. (f sums l) (from k) = ((\n. vsum(k..n) f) --> l) sequentially`,
13954 REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN
13955 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
13956 AP_THM_TAC THEN AP_TERM_TAC THEN
13957 REWRITE_TAC[EXTENSION; numseg; from; IN_ELIM_THM; IN_INTER] THEN ARITH_TAC);;
13959 let SERIES_UNIQUE = prove
13960 (`!f:num->real^N l l' s. (f sums l) s /\ (f sums l') s ==> (l = l')`,
13961 REWRITE_TAC[sums] THEN MESON_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; LIM_UNIQUE]);;
13963 let INFSUM_UNIQUE = prove
13964 (`!f:num->real^N l s. (f sums l) s ==> infsum s f = l`,
13965 MESON_TAC[SERIES_UNIQUE; SUMS_INFSUM; summable]);;
13967 let SERIES_FINITE = prove
13968 (`!f s. FINITE s ==> (f sums (vsum s f)) s`,
13969 REPEAT GEN_TAC THEN REWRITE_TAC[num_FINITE; LEFT_IMP_EXISTS_THM] THEN
13970 X_GEN_TAC `n:num` THEN REWRITE_TAC[sums; LIM_SEQUENTIALLY] THEN
13971 DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN EXISTS_TAC `n:num` THEN
13972 X_GEN_TAC `m:num` THEN DISCH_TAC THEN
13973 SUBGOAL_THEN `s INTER (0..m) = s`
13974 (fun th -> ASM_REWRITE_TAC[th; DIST_REFL]) THEN
13975 REWRITE_TAC[EXTENSION; IN_INTER; IN_NUMSEG; LE_0] THEN
13976 ASM_MESON_TAC[LE_TRANS]);;
13978 let SERIES_LINEAR = prove
13979 (`!f h l s. (f sums l) s /\ linear h ==> ((\n. h(f n)) sums h l) s`,
13980 SIMP_TAC[sums; LIM_LINEAR; FINITE_INTER; FINITE_NUMSEG;
13981 GSYM(REWRITE_RULE[o_DEF] LINEAR_VSUM)]);;
13983 let SERIES_0 = prove
13984 (`!s. ((\n. vec 0) sums (vec 0)) s`,
13985 REWRITE_TAC[sums; VSUM_0; LIM_CONST]);;
13987 let SERIES_ADD = prove
13989 (x sums x0) s /\ (y sums y0) s ==> ((\n. x n + y n) sums (x0 + y0)) s`,
13990 SIMP_TAC[sums; FINITE_INTER_NUMSEG; VSUM_ADD; LIM_ADD]);;
13992 let SERIES_SUB = prove
13994 (x sums x0) s /\ (y sums y0) s ==> ((\n. x n - y n) sums (x0 - y0)) s`,
13995 SIMP_TAC[sums; FINITE_INTER_NUMSEG; VSUM_SUB; LIM_SUB]);;
13997 let SERIES_CMUL = prove
13998 (`!x x0 c s. (x sums x0) s ==> ((\n. c % x n) sums (c % x0)) s`,
13999 SIMP_TAC[sums; FINITE_INTER_NUMSEG; VSUM_LMUL; LIM_CMUL]);;
14001 let SERIES_NEG = prove
14002 (`!x x0 s. (x sums x0) s ==> ((\n. --(x n)) sums (--x0)) s`,
14003 SIMP_TAC[sums; FINITE_INTER_NUMSEG; VSUM_NEG; LIM_NEG]);;
14005 let SUMS_IFF = prove
14006 (`!f g k. (!x. x IN k ==> f x = g x) ==> ((f sums l) k <=> (g sums l) k)`,
14007 REPEAT STRIP_TAC THEN REWRITE_TAC[sums] THEN
14008 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
14009 MATCH_MP_TAC VSUM_EQ THEN ASM_SIMP_TAC[IN_INTER]);;
14011 let SUMS_EQ = prove
14012 (`!f g k. (!x. x IN k ==> f x = g x) /\ (f sums l) k ==> (g sums l) k`,
14013 MESON_TAC[SUMS_IFF]);;
14016 (`!f:num->real^N s. (!n. n IN s ==> f n = vec 0) ==> (f sums vec 0) s`,
14017 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMS_EQ THEN
14018 EXISTS_TAC `\n:num. vec 0:real^N` THEN ASM_SIMP_TAC[SERIES_0]);;
14020 let SERIES_FINITE_SUPPORT = prove
14021 (`!f:num->real^N s k.
14022 FINITE (s INTER k) /\ (!x. ~(x IN s INTER k) ==> f x = vec 0)
14023 ==> (f sums vsum (s INTER k) f) k`,
14024 REWRITE_TAC[sums; LIM_SEQUENTIALLY] THEN REPEAT STRIP_TAC THEN
14025 FIRST_ASSUM(MP_TAC o ISPEC `\x:num. x` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN
14026 REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
14027 STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
14028 SUBGOAL_THEN `vsum (k INTER (0..n)) (f:num->real^N) = vsum(s INTER k) f`
14029 (fun th -> ASM_REWRITE_TAC[DIST_REFL; th]) THEN
14030 MATCH_MP_TAC VSUM_SUPERSET THEN
14031 ASM_SIMP_TAC[SUBSET; IN_INTER; IN_NUMSEG; LE_0] THEN
14032 ASM_MESON_TAC[IN_INTER; LE_TRANS]);;
14034 let SERIES_COMPONENT = prove
14035 (`!f s l:real^N k. (f sums l) s /\ 1 <= k /\ k <= dimindex(:N)
14036 ==> ((\i. lift(f(i)$k)) sums lift(l$k)) s`,
14037 REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN STRIP_TAC THEN
14038 ONCE_REWRITE_TAC[GSYM o_DEF] THEN
14039 ASM_SIMP_TAC[GSYM LIFT_SUM; GSYM VSUM_COMPONENT;
14040 FINITE_INTER; FINITE_NUMSEG] THEN
14041 ASM_SIMP_TAC[o_DEF; LIM_COMPONENT]);;
14043 let SERIES_DIFFS = prove
14044 (`!f:num->real^N k.
14045 (f --> vec 0) sequentially
14046 ==> ((\n. f(n) - f(n + 1)) sums f(k)) (from k)`,
14047 REWRITE_TAC[sums; FROM_INTER_NUMSEG; VSUM_DIFFS] THEN
14048 REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM_EVENTUALLY THEN
14049 EXISTS_TAC `\n. (f:num->real^N) k - f(n + 1)` THEN CONJ_TAC THENL
14050 [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `k:num` THEN
14052 GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_SUB_RZERO] THEN
14053 MATCH_MP_TAC LIM_SUB THEN REWRITE_TAC[LIM_CONST] THEN
14054 MATCH_MP_TAC SEQ_OFFSET THEN ASM_REWRITE_TAC[]]);;
14056 let SERIES_TRIVIAL = prove
14057 (`!f. (f sums vec 0) {}`,
14058 REWRITE_TAC[sums; INTER_EMPTY; VSUM_CLAUSES; LIM_CONST]);;
14060 let SERIES_RESTRICT = prove
14062 ((\n. if n IN k then f(n) else vec 0) sums l) (:num) <=>
14064 REPEAT GEN_TAC THEN REWRITE_TAC[sums] THEN
14065 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
14066 REWRITE_TAC[FUN_EQ_THM; INTER_UNIV] THEN GEN_TAC THEN
14067 MATCH_MP_TAC(MESON[] `vsum s f = vsum t f /\ vsum t f = vsum t g
14068 ==> vsum s f = vsum t g`) THEN
14070 [MATCH_MP_TAC VSUM_SUPERSET THEN SET_TAC[];
14071 MATCH_MP_TAC VSUM_EQ THEN SIMP_TAC[IN_INTER]]);;
14073 let SERIES_VSUM = prove
14074 (`!f l k s. FINITE s /\ s SUBSET k /\ (!x. ~(x IN s) ==> f x = vec 0) /\
14075 vsum s f = l ==> (f sums l) k`,
14076 REPEAT STRIP_TAC THEN EXPAND_TAC "l" THEN
14077 SUBGOAL_THEN `s INTER k = s:num->bool` ASSUME_TAC THENL
14078 [ASM SET_TAC []; ASM_MESON_TAC [SERIES_FINITE_SUPPORT]]);;
14080 let SUMS_REINDEX = prove
14081 (`!k a l n. ((\x. a(x + k)) sums l) (from n) <=> (a sums l) (from(n + k))`,
14082 REPEAT GEN_TAC THEN REWRITE_TAC[sums; FROM_INTER_NUMSEG] THEN
14083 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM VSUM_OFFSET] THEN
14084 REWRITE_TAC[LIM_SEQUENTIALLY] THEN
14085 ASM_MESON_TAC[ARITH_RULE `N + k:num <= n ==> n = (n - k) + k /\ N <= n - k`;
14086 ARITH_RULE `N + k:num <= n ==> N <= n + k`]);;
14088 (* ------------------------------------------------------------------------- *)
14089 (* Similar combining theorems just for summability. *)
14090 (* ------------------------------------------------------------------------- *)
14092 let SUMMABLE_LINEAR = prove
14093 (`!f h s. summable s f /\ linear h ==> summable s (\n. h(f n))`,
14094 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_LINEAR]);;
14096 let SUMMABLE_0 = prove
14097 (`!s. summable s (\n. vec 0)`,
14098 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_0]);;
14100 let SUMMABLE_ADD = prove
14101 (`!x y s. summable s x /\ summable s y ==> summable s (\n. x n + y n)`,
14102 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_ADD]);;
14104 let SUMMABLE_SUB = prove
14105 (`!x y s. summable s x /\ summable s y ==> summable s (\n. x n - y n)`,
14106 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_SUB]);;
14108 let SUMMABLE_CMUL = prove
14109 (`!s x c. summable s x ==> summable s (\n. c % x n)`,
14110 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_CMUL]);;
14112 let SUMMABLE_NEG = prove
14113 (`!x s. summable s x ==> summable s (\n. --(x n))`,
14114 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_NEG]);;
14116 let SUMMABLE_IFF = prove
14117 (`!f g k. (!x. x IN k ==> f x = g x) ==> (summable k f <=> summable k g)`,
14118 REWRITE_TAC[summable] THEN MESON_TAC[SUMS_IFF]);;
14120 let SUMMABLE_EQ = prove
14121 (`!f g k. (!x. x IN k ==> f x = g x) /\ summable k f ==> summable k g`,
14122 REWRITE_TAC[summable] THEN MESON_TAC[SUMS_EQ]);;
14124 let SUMMABLE_COMPONENT = prove
14125 (`!f:num->real^N s k.
14126 summable s f /\ 1 <= k /\ k <= dimindex(:N)
14127 ==> summable s (\i. lift(f(i)$k))`,
14128 REPEAT STRIP_TAC THEN
14129 FIRST_X_ASSUM(X_CHOOSE_TAC `l:real^N` o REWRITE_RULE[summable]) THEN
14130 REWRITE_TAC[summable] THEN EXISTS_TAC `lift((l:real^N)$k)` THEN
14131 ASM_SIMP_TAC[SERIES_COMPONENT]);;
14133 let SERIES_SUBSET = prove
14136 ((\i. if i IN s then x i else vec 0) sums l) t
14138 REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
14139 REWRITE_TAC[sums] THEN MATCH_MP_TAC EQ_IMP THEN
14140 AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
14141 ASM_SIMP_TAC[GSYM VSUM_RESTRICT_SET; FINITE_INTER_NUMSEG] THEN
14142 AP_THM_TAC THEN AP_TERM_TAC THEN POP_ASSUM MP_TAC THEN SET_TAC[]);;
14144 let SUMMABLE_SUBSET = prove
14147 summable t (\i. if i IN s then x i else vec 0)
14149 REWRITE_TAC[summable] THEN MESON_TAC[SERIES_SUBSET]);;
14151 let SUMMABLE_TRIVIAL = prove
14152 (`!f:num->real^N. summable {} f`,
14153 GEN_TAC THEN REWRITE_TAC[summable] THEN EXISTS_TAC `vec 0:real^N` THEN
14154 REWRITE_TAC[SERIES_TRIVIAL]);;
14156 let SUMMABLE_RESTRICT = prove
14157 (`!f:num->real^N k.
14158 summable (:num) (\n. if n IN k then f(n) else vec 0) <=>
14160 REWRITE_TAC[summable; SERIES_RESTRICT]);;
14162 let SUMS_FINITE_DIFF = prove
14163 (`!f:num->real^N t s l.
14164 t SUBSET s /\ FINITE t /\ (f sums l) s
14165 ==> (f sums (l - vsum t f)) (s DIFF t)`,
14166 REPEAT GEN_TAC THEN
14167 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
14168 FIRST_ASSUM(MP_TAC o ISPEC `f:num->real^N` o MATCH_MP SERIES_FINITE) THEN
14169 ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN
14170 REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
14171 DISCH_THEN(MP_TAC o MATCH_MP SERIES_SUB) THEN
14172 MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
14173 REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `x:num` THEN REWRITE_TAC[IN_DIFF] THEN
14174 FIRST_ASSUM(MP_TAC o SPEC `x:num` o GEN_REWRITE_RULE I [SUBSET]) THEN
14175 MAP_EVERY ASM_CASES_TAC [`(x:num) IN s`; `(x:num) IN t`] THEN
14176 ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);;
14178 let SUMS_FINITE_UNION = prove
14179 (`!f:num->real^N s t l.
14180 FINITE t /\ (f sums l) s
14181 ==> (f sums (l + vsum (t DIFF s) f)) (s UNION t)`,
14182 REPEAT GEN_TAC THEN
14183 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
14184 FIRST_ASSUM(MP_TAC o SPEC `s:num->bool` o MATCH_MP FINITE_DIFF) THEN
14185 DISCH_THEN(MP_TAC o ISPEC `f:num->real^N` o MATCH_MP SERIES_FINITE) THEN
14186 ONCE_REWRITE_TAC[GSYM SERIES_RESTRICT] THEN
14187 REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
14188 DISCH_THEN(MP_TAC o MATCH_MP SERIES_ADD) THEN
14189 MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
14190 REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `x:num` THEN
14191 REWRITE_TAC[IN_DIFF; IN_UNION] THEN
14192 MAP_EVERY ASM_CASES_TAC [`(x:num) IN s`; `(x:num) IN t`] THEN
14193 ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);;
14195 let SUMS_OFFSET = prove
14196 (`!f:num->real^N l m n.
14197 (f sums l) (from m) /\ m < n
14198 ==> (f sums (l - vsum(m..(n-1)) f)) (from n)`,
14199 REPEAT STRIP_TAC THEN
14200 SUBGOAL_THEN `from n = from m DIFF (m..(n-1))` SUBST1_TAC THENL
14201 [REWRITE_TAC[EXTENSION; IN_FROM; IN_DIFF; IN_NUMSEG] THEN ASM_ARITH_TAC;
14202 MATCH_MP_TAC SUMS_FINITE_DIFF THEN ASM_REWRITE_TAC[FINITE_NUMSEG] THEN
14203 SIMP_TAC[SUBSET; IN_FROM; IN_NUMSEG]]);;
14205 let SUMS_OFFSET_REV = prove
14206 (`!f:num->real^N l m n.
14207 (f sums l) (from m) /\ n < m
14208 ==> (f sums (l + vsum(n..m-1) f)) (from n)`,
14209 REPEAT STRIP_TAC THEN
14210 MP_TAC(ISPECL [`f:num->real^N`; `from m`; `n..m-1`; `l:real^N`]
14211 SUMS_FINITE_UNION) THEN
14212 ASM_REWRITE_TAC[FINITE_NUMSEG] THEN MATCH_MP_TAC EQ_IMP THEN
14213 BINOP_TAC THENL [AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC; ALL_TAC] THEN
14214 REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNION; IN_FROM; IN_NUMSEG] THEN
14217 let SUMMABLE_REINDEX = prove
14218 (`!k a n. summable (from n) (\x. a (x + k)) <=> summable (from(n + k)) a`,
14219 REWRITE_TAC[summable; GSYM SUMS_REINDEX]);;
14221 (* ------------------------------------------------------------------------- *)
14222 (* Similar combining theorems for infsum. *)
14223 (* ------------------------------------------------------------------------- *)
14225 let INFSUM_LINEAR = prove
14226 (`!f h s. summable s f /\ linear h
14227 ==> infsum s (\n. h(f n)) = h(infsum s f)`,
14228 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
14229 MATCH_MP_TAC SERIES_LINEAR THEN ASM_REWRITE_TAC[SUMS_INFSUM]);;
14231 let INFSUM_0 = prove
14232 (`infsum s (\i. vec 0) = vec 0`,
14233 MATCH_MP_TAC INFSUM_UNIQUE THEN REWRITE_TAC[SERIES_0]);;
14235 let INFSUM_ADD = prove
14236 (`!x y s. summable s x /\ summable s y
14237 ==> infsum s (\i. x i + y i) = infsum s x + infsum s y`,
14238 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
14239 MATCH_MP_TAC SERIES_ADD THEN ASM_REWRITE_TAC[SUMS_INFSUM]);;
14241 let INFSUM_SUB = prove
14242 (`!x y s. summable s x /\ summable s y
14243 ==> infsum s (\i. x i - y i) = infsum s x - infsum s y`,
14244 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
14245 MATCH_MP_TAC SERIES_SUB THEN ASM_REWRITE_TAC[SUMS_INFSUM]);;
14247 let INFSUM_CMUL = prove
14248 (`!s x c. summable s x ==> infsum s (\n. c % x n) = c % infsum s x`,
14249 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
14250 MATCH_MP_TAC SERIES_CMUL THEN ASM_REWRITE_TAC[SUMS_INFSUM]);;
14252 let INFSUM_NEG = prove
14253 (`!s x. summable s x ==> infsum s (\n. --(x n)) = --(infsum s x)`,
14254 REPEAT STRIP_TAC THEN MATCH_MP_TAC INFSUM_UNIQUE THEN
14255 MATCH_MP_TAC SERIES_NEG THEN ASM_REWRITE_TAC[SUMS_INFSUM]);;
14257 let INFSUM_EQ = prove
14258 (`!f g k. summable k f /\ summable k g /\ (!x. x IN k ==> f x = g x)
14259 ==> infsum k f = infsum k g`,
14260 REPEAT STRIP_TAC THEN REWRITE_TAC[infsum] THEN
14261 AP_TERM_TAC THEN ABS_TAC THEN ASM_MESON_TAC[SUMS_EQ; SUMS_INFSUM]);;
14263 let INFSUM_RESTRICT = prove
14264 (`!k a:num->real^N.
14265 infsum (:num) (\n. if n IN k then a n else vec 0) = infsum k a`,
14266 REPEAT GEN_TAC THEN
14267 MP_TAC(ISPECL [`a:num->real^N`; `k:num->bool`] SUMMABLE_RESTRICT) THEN
14268 ASM_CASES_TAC `summable k (a:num->real^N)` THEN ASM_REWRITE_TAC[] THEN
14270 [MATCH_MP_TAC INFSUM_UNIQUE THEN
14271 ASM_REWRITE_TAC[SERIES_RESTRICT; SUMS_INFSUM];
14272 RULE_ASSUM_TAC(REWRITE_RULE[summable; NOT_EXISTS_THM]) THEN
14273 ASM_REWRITE_TAC[infsum]]);;
14275 let PARTIAL_SUMS_COMPONENT_LE_INFSUM = prove
14276 (`!f:num->real^N s k n.
14277 1 <= k /\ k <= dimindex(:N) /\
14278 (!i. i IN s ==> &0 <= (f i)$k) /\
14280 ==> (vsum (s INTER (0..n)) f)$k <= (infsum s f)$k`,
14281 REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUMS_INFSUM] THEN
14282 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
14283 REWRITE_TAC[sums; LIM_SEQUENTIALLY] THEN DISCH_TAC THEN
14284 REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
14285 FIRST_X_ASSUM(MP_TAC o SPEC
14286 `vsum (s INTER (0..n)) (f:num->real^N)$k - (infsum s f)$k`) THEN
14287 ASM_REWRITE_TAC[REAL_SUB_LT] THEN
14288 DISCH_THEN(X_CHOOSE_THEN `N:num` (MP_TAC o SPEC `N + n:num`)) THEN
14289 REWRITE_TAC[LE_ADD; REAL_NOT_LT; dist] THEN
14290 MATCH_MP_TAC REAL_LE_TRANS THEN
14291 EXISTS_TAC `abs((vsum (s INTER (0..N + n)) f - infsum s f:real^N)$k)` THEN
14292 ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN REWRITE_TAC[VECTOR_SUB_COMPONENT] THEN
14293 MATCH_MP_TAC(REAL_ARITH `s < a /\ a <= b ==> a - s <= abs(b - s)`) THEN
14294 ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[ADD_SYM] THEN
14295 SIMP_TAC[NUMSEG_ADD_SPLIT; LE_0; UNION_OVER_INTER] THEN
14296 W(MP_TAC o PART_MATCH (lhs o rand) VSUM_UNION o lhand o rand o snd) THEN
14298 [SIMP_TAC[FINITE_INTER; FINITE_NUMSEG; DISJOINT; EXTENSION] THEN
14299 REWRITE_TAC[IN_INTER; NOT_IN_EMPTY; IN_NUMSEG] THEN ARITH_TAC;
14300 DISCH_THEN SUBST1_TAC THEN
14301 REWRITE_TAC[REAL_LE_ADDR; VECTOR_ADD_COMPONENT] THEN
14302 ASM_SIMP_TAC[VSUM_COMPONENT] THEN MATCH_MP_TAC SUM_POS_LE THEN
14303 ASM_SIMP_TAC[FINITE_INTER; IN_INTER; FINITE_NUMSEG]]);;
14305 let PARTIAL_SUMS_DROP_LE_INFSUM = prove
14307 (!i. i IN s ==> &0 <= drop(f i)) /\
14309 ==> drop(vsum (s INTER (0..n)) f) <= drop(infsum s f)`,
14310 REPEAT STRIP_TAC THEN REWRITE_TAC[drop] THEN
14311 MATCH_MP_TAC PARTIAL_SUMS_COMPONENT_LE_INFSUM THEN
14312 ASM_REWRITE_TAC[DIMINDEX_1; LE_REFL; GSYM drop]);;
14314 (* ------------------------------------------------------------------------- *)
14315 (* Cauchy criterion for series. *)
14316 (* ------------------------------------------------------------------------- *)
14318 let SEQUENCE_CAUCHY_WLOG = prove
14319 (`!P s. (!m n:num. P m /\ P n ==> dist(s m,s n) < e) <=>
14320 (!m n. P m /\ P n /\ m <= n ==> dist(s m,s n) < e)`,
14321 MESON_TAC[DIST_SYM; LE_CASES]);;
14323 let VSUM_DIFF_LEMMA = prove
14324 (`!f:num->real^N k m n.
14326 ==> vsum(k INTER (0..n)) f - vsum(k INTER (0..m)) f =
14327 vsum(k INTER (m+1..n)) f`,
14328 REPEAT STRIP_TAC THEN
14329 MP_TAC(ISPECL [`f:num->real^N`; `k INTER (0..n)`; `k INTER (0..m)`]
14332 [SIMP_TAC[FINITE_INTER; FINITE_NUMSEG] THEN MATCH_MP_TAC
14333 (SET_RULE `s SUBSET t ==> (u INTER s SUBSET u INTER t)`) THEN
14334 REWRITE_TAC[SUBSET; IN_NUMSEG] THEN POP_ASSUM MP_TAC THEN ARITH_TAC;
14335 DISCH_THEN(SUBST1_TAC o SYM) THEN AP_THM_TAC THEN AP_TERM_TAC THEN
14336 REWRITE_TAC[SET_RULE
14337 `(k INTER s) DIFF (k INTER t) = k INTER (s DIFF t)`] THEN
14338 AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_DIFF; IN_NUMSEG] THEN
14339 POP_ASSUM MP_TAC THEN ARITH_TAC]);;
14341 let NORM_VSUM_TRIVIAL_LEMMA = prove
14342 (`!e. &0 < e ==> (P ==> norm(vsum(s INTER (m..n)) f) < e <=>
14343 P ==> n < m \/ norm(vsum(s INTER (m..n)) f) < e)`,
14344 REPEAT STRIP_TAC THEN ASM_CASES_TAC `n:num < m` THEN ASM_REWRITE_TAC[] THEN
14345 FIRST_X_ASSUM(SUBST1_TAC o GEN_REWRITE_RULE I [GSYM NUMSEG_EMPTY]) THEN
14346 ASM_REWRITE_TAC[VSUM_CLAUSES; NORM_0; INTER_EMPTY]);;
14348 let SERIES_CAUCHY = prove
14349 (`!f s. (?l. (f sums l) s) =
14351 ==> ?N. !m n. m >= N
14352 ==> norm(vsum(s INTER (m..n)) f) < e`,
14353 REPEAT GEN_TAC THEN REWRITE_TAC[sums; CONVERGENT_EQ_CAUCHY; cauchy] THEN
14354 REWRITE_TAC[SEQUENCE_CAUCHY_WLOG] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
14355 SIMP_TAC[dist; VSUM_DIFF_LEMMA; NORM_VSUM_TRIVIAL_LEMMA] THEN
14356 REWRITE_TAC[GE; TAUT `a ==> b \/ c <=> a /\ ~b ==> c`] THEN
14357 REWRITE_TAC[NOT_LT; ARITH_RULE
14358 `(N <= m /\ N <= n /\ m <= n) /\ m + 1 <= n <=>
14359 N + 1 <= m + 1 /\ m + 1 <= n`] THEN
14360 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN
14361 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
14362 EQ_TAC THEN DISCH_THEN(X_CHOOSE_TAC `N:num`) THENL
14363 [EXISTS_TAC `N + 1`; EXISTS_TAC `N:num`] THEN
14364 REPEAT STRIP_TAC THEN
14365 ASM_SIMP_TAC[ARITH_RULE `N + 1 <= m + 1 ==> N <= m + 1`] THEN
14366 FIRST_X_ASSUM(MP_TAC o SPECL [`m - 1`; `n:num`]) THEN
14367 SUBGOAL_THEN `m - 1 + 1 = m` SUBST_ALL_TAC THENL
14368 [ALL_TAC; ANTS_TAC THEN SIMP_TAC[]] THEN
14371 let SUMMABLE_CAUCHY = prove
14372 (`!f s. summable s f <=>
14374 ==> ?N. !m n. m >= N ==> norm(vsum(s INTER (m..n)) f) < e`,
14375 REWRITE_TAC[summable; GSYM SERIES_CAUCHY]);;
14377 let SUMMABLE_IFF_EVENTUALLY = prove
14378 (`!f g k. (?N. !n. N <= n /\ n IN k ==> f n = g n)
14379 ==> (summable k f <=> summable k g)`,
14380 REWRITE_TAC[summable; SERIES_CAUCHY] THEN REPEAT GEN_TAC THEN
14381 DISCH_THEN(X_CHOOSE_THEN `N0:num` STRIP_ASSUME_TAC) THEN
14382 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN
14383 AP_TERM_TAC THEN EQ_TAC THEN
14384 DISCH_THEN(X_CHOOSE_THEN `N1:num`
14385 (fun th -> EXISTS_TAC `N0 + N1:num` THEN MP_TAC th)) THEN
14386 REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
14387 DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
14388 (ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC]) THEN
14389 MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
14390 MATCH_MP_TAC VSUM_EQ THEN ASM_SIMP_TAC[IN_INTER; IN_NUMSEG] THEN
14391 REPEAT STRIP_TAC THENL [ALL_TAC; CONV_TAC SYM_CONV] THEN
14392 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
14395 let SUMMABLE_EQ_EVENTUALLY = prove
14396 (`!f g k. (?N. !n. N <= n /\ n IN k ==> f n = g n) /\ summable k f
14398 MESON_TAC[SUMMABLE_IFF_EVENTUALLY]);;
14400 let SUMMABLE_IFF_COFINITE = prove
14401 (`!f s t. FINITE((s DIFF t) UNION (t DIFF s))
14402 ==> (summable s f <=> summable t f)`,
14403 REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM SUMMABLE_RESTRICT] THEN
14404 MATCH_MP_TAC SUMMABLE_IFF_EVENTUALLY THEN
14405 FIRST_ASSUM(MP_TAC o ISPEC `\x:num.x` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN
14406 DISCH_THEN(X_CHOOSE_THEN `N:num` MP_TAC) THEN REWRITE_TAC[IN_UNIV] THEN
14407 DISCH_TAC THEN EXISTS_TAC `N + 1` THEN
14408 REWRITE_TAC[ARITH_RULE `N + 1 <= n <=> ~(n <= N)`] THEN ASM SET_TAC[]);;
14410 let SUMMABLE_EQ_COFINITE = prove
14411 (`!f s t. FINITE((s DIFF t) UNION (t DIFF s)) /\ summable s f
14413 MESON_TAC[SUMMABLE_IFF_COFINITE]);;
14415 let SUMMABLE_FROM_ELSEWHERE = prove
14416 (`!f m n. summable (from m) f ==> summable (from n) f`,
14417 REPEAT GEN_TAC THEN
14418 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] SUMMABLE_EQ_COFINITE) THEN
14419 MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `0..(m+n)` THEN
14420 SIMP_TAC[FINITE_NUMSEG; SUBSET; IN_NUMSEG; IN_UNION; IN_DIFF; IN_FROM] THEN
14423 (* ------------------------------------------------------------------------- *)
14424 (* Uniform vesion of Cauchy criterion. *)
14425 (* ------------------------------------------------------------------------- *)
14427 let SERIES_CAUCHY_UNIFORM = prove
14428 (`!P f:A->num->real^N k.
14430 ==> ?N. !n x. N <= n /\ P x
14431 ==> dist(vsum(k INTER (0..n)) (f x),
14433 (!e. &0 < e ==> ?N. !m n x. N <= m /\ P x
14434 ==> norm(vsum(k INTER (m..n)) (f x)) < e)`,
14435 REPEAT GEN_TAC THEN
14436 REWRITE_TAC[sums; UNIFORMLY_CONVERGENT_EQ_CAUCHY; cauchy] THEN
14437 ONCE_REWRITE_TAC[MESON[]
14438 `(!m n:num y. N <= m /\ N <= n /\ P y ==> Q m n y) <=>
14439 (!y. P y ==> !m n. N <= m /\ N <= n ==> Q m n y)`] THEN
14440 REWRITE_TAC[SEQUENCE_CAUCHY_WLOG] THEN ONCE_REWRITE_TAC[DIST_SYM] THEN
14441 SIMP_TAC[dist; VSUM_DIFF_LEMMA; NORM_VSUM_TRIVIAL_LEMMA] THEN
14442 REWRITE_TAC[GE; TAUT `a ==> b \/ c <=> a /\ ~b ==> c`] THEN
14443 REWRITE_TAC[NOT_LT; ARITH_RULE
14444 `(N <= m /\ N <= n /\ m <= n) /\ m + 1 <= n <=>
14445 N + 1 <= m + 1 /\ m + 1 <= n`] THEN
14446 AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN
14447 ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
14448 EQ_TAC THEN DISCH_THEN(X_CHOOSE_TAC `N:num`) THENL
14449 [EXISTS_TAC `N + 1`; EXISTS_TAC `N:num`] THEN
14450 REPEAT STRIP_TAC THEN
14451 ASM_SIMP_TAC[ARITH_RULE `N + 1 <= m + 1 ==> N <= m + 1`] THEN
14452 FIRST_X_ASSUM(MP_TAC o SPEC `x:A`) THEN ASM_REWRITE_TAC[] THEN
14453 DISCH_THEN(MP_TAC o SPECL [`m - 1`; `n:num`]) THEN
14454 SUBGOAL_THEN `m - 1 + 1 = m` SUBST_ALL_TAC THENL
14455 [ALL_TAC; ANTS_TAC THEN SIMP_TAC[]] THEN
14458 (* ------------------------------------------------------------------------- *)
14459 (* So trivially, terms of a convergent series go to zero. *)
14460 (* ------------------------------------------------------------------------- *)
14462 let SERIES_GOESTOZERO = prove
14463 (`!s x. summable s x
14465 ==> eventually (\n. n IN s ==> norm(x n) < e) sequentially`,
14466 REPEAT GEN_TAC THEN REWRITE_TAC[summable; SERIES_CAUCHY] THEN
14467 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
14468 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
14469 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN
14470 X_GEN_TAC `n:num` THEN REPEAT STRIP_TAC THEN
14471 FIRST_X_ASSUM(MP_TAC o SPECL [`n:num`; `n:num`]) THEN
14472 ASM_SIMP_TAC[NUMSEG_SING; GE; SET_RULE `n IN s ==> s INTER {n} = {n}`] THEN
14473 REWRITE_TAC[VSUM_SING]);;
14475 let SUMMABLE_IMP_TOZERO = prove
14476 (`!f:num->real^N k.
14478 ==> ((\n. if n IN k then f(n) else vec 0) --> vec 0) sequentially`,
14479 REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM SUMMABLE_RESTRICT] THEN
14480 REWRITE_TAC[summable; LIM_SEQUENTIALLY; INTER_UNIV; sums] THEN
14481 DISCH_THEN(X_CHOOSE_TAC `l:real^N`) THEN X_GEN_TAC `e:real` THEN
14482 DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
14483 ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN
14484 X_GEN_TAC `N:num` THEN DISCH_TAC THEN EXISTS_TAC `N + 1` THEN
14485 X_GEN_TAC `n:num` THEN DISCH_TAC THEN
14486 FIRST_X_ASSUM(fun th ->
14487 MP_TAC(SPEC `n - 1` th) THEN MP_TAC(SPEC `n:num` th)) THEN
14488 ASM_SIMP_TAC[ARITH_RULE `N + 1 <= n ==> N <= n /\ N <= n - 1`] THEN
14489 ABBREV_TAC `m = n - 1` THEN
14490 SUBGOAL_THEN `n = SUC m` SUBST1_TAC THENL
14491 [ASM_ARITH_TAC; ALL_TAC] THEN
14492 REWRITE_TAC[VSUM_CLAUSES_NUMSEG; LE_0] THEN
14493 REWRITE_TAC[NORM_ARITH `dist(x,vec 0) = norm x`] THEN
14494 COND_CASES_TAC THEN ASM_REWRITE_TAC[NORM_0] THEN CONV_TAC NORM_ARITH);;
14496 let SUMMABLE_IMP_BOUNDED = prove
14497 (`!f:num->real^N k. summable k f ==> bounded (IMAGE f k)`,
14498 REPEAT GEN_TAC THEN
14499 DISCH_THEN(MP_TAC o MATCH_MP SUMMABLE_IMP_TOZERO) THEN
14500 DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN
14501 REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; IN_UNIV] THEN
14502 MATCH_MP_TAC MONO_EXISTS THEN MESON_TAC[REAL_LT_IMP_LE; NORM_0]);;
14504 let SUMMABLE_IMP_SUMS_BOUNDED = prove
14505 (`!f:num->real^N k.
14506 summable (from k) f ==> bounded { vsum(k..n) f | n IN (:num) }`,
14507 REWRITE_TAC[summable; sums; LEFT_IMP_EXISTS_THM] THEN REPEAT GEN_TAC THEN
14508 DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN
14509 REWRITE_TAC[FROM_INTER_NUMSEG; SIMPLE_IMAGE]);;
14511 (* ------------------------------------------------------------------------- *)
14512 (* Comparison test. *)
14513 (* ------------------------------------------------------------------------- *)
14515 let SERIES_COMPARISON = prove
14516 (`!f g s. (?l. ((lift o g) sums l) s) /\
14517 (?N. !n. n >= N /\ n IN s ==> norm(f n) <= g n)
14518 ==> ?l:real^N. (f sums l) s`,
14519 REPEAT GEN_TAC THEN REWRITE_TAC[SERIES_CAUCHY] THEN
14520 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC `N1:num`)) THEN
14521 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
14522 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
14523 DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN
14524 EXISTS_TAC `N1 + N2:num` THEN
14525 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN
14526 MATCH_MP_TAC REAL_LET_TRANS THEN
14527 EXISTS_TAC `norm (vsum (s INTER (m .. n)) (lift o g))` THEN CONJ_TAC THENL
14528 [SIMP_TAC[GSYM LIFT_SUM; FINITE_INTER_NUMSEG; NORM_LIFT] THEN
14529 MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs(a)`) THEN
14530 MATCH_MP_TAC VSUM_NORM_LE THEN
14531 REWRITE_TAC[FINITE_INTER_NUMSEG; IN_INTER; IN_NUMSEG] THEN
14532 ASM_MESON_TAC[ARITH_RULE `m >= N1 + N2:num /\ m <= x ==> x >= N1`];
14533 ASM_MESON_TAC[ARITH_RULE `m >= N1 + N2:num ==> m >= N2`]]);;
14535 let SUMMABLE_COMPARISON = prove
14536 (`!f g s. summable s (lift o g) /\
14537 (?N. !n. n >= N /\ n IN s ==> norm(f n) <= g n)
14539 REWRITE_TAC[summable; SERIES_COMPARISON]);;
14541 let SERIES_LIFT_ABSCONV_IMP_CONV = prove
14542 (`!x:num->real^N k. summable k (\n. lift(norm(x n))) ==> summable k x`,
14543 REWRITE_TAC[summable] THEN REPEAT STRIP_TAC THEN
14544 MATCH_MP_TAC SERIES_COMPARISON THEN
14545 EXISTS_TAC `\n:num. norm(x n:real^N)` THEN
14546 ASM_REWRITE_TAC[o_DEF; REAL_LE_REFL] THEN ASM_MESON_TAC[]);;
14548 let SUMMABLE_SUBSET_ABSCONV = prove
14549 (`!x:num->real^N s t.
14550 summable s (\n. lift(norm(x n))) /\ t SUBSET s
14551 ==> summable t (\n. lift(norm(x n)))`,
14552 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMMABLE_SUBSET THEN
14553 EXISTS_TAC `s:num->bool` THEN ASM_REWRITE_TAC[] THEN
14554 REWRITE_TAC[summable] THEN MATCH_MP_TAC SERIES_COMPARISON THEN
14555 EXISTS_TAC `\n:num. norm(x n:real^N)` THEN
14556 ASM_REWRITE_TAC[o_DEF; GSYM summable] THEN
14557 EXISTS_TAC `0` THEN REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
14558 REWRITE_TAC[REAL_LE_REFL; NORM_LIFT; REAL_ABS_NORM; NORM_0; NORM_POS_LE]);;
14560 (* ------------------------------------------------------------------------- *)
14561 (* Uniform version of comparison test. *)
14562 (* ------------------------------------------------------------------------- *)
14564 let SERIES_COMPARISON_UNIFORM = prove
14565 (`!f g P s. (?l. ((lift o g) sums l) s) /\
14566 (?N. !n x. N <= n /\ n IN s /\ P x ==> norm(f x n) <= g n)
14569 ==> ?N. !n x. N <= n /\ P x
14570 ==> dist(vsum(s INTER (0..n)) (f x),
14572 REPEAT GEN_TAC THEN SIMP_TAC[GE; SERIES_CAUCHY; SERIES_CAUCHY_UNIFORM] THEN
14573 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC `N1:num`)) THEN
14574 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
14575 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
14576 DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN
14577 EXISTS_TAC `N1 + N2:num` THEN
14578 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`; `x:A`] THEN DISCH_TAC THEN
14579 MATCH_MP_TAC REAL_LET_TRANS THEN
14580 EXISTS_TAC `norm (vsum (s INTER (m .. n)) (lift o g))` THEN CONJ_TAC THENL
14581 [SIMP_TAC[GSYM LIFT_SUM; FINITE_INTER_NUMSEG; NORM_LIFT] THEN
14582 MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs(a)`) THEN
14583 MATCH_MP_TAC VSUM_NORM_LE THEN
14584 REWRITE_TAC[FINITE_INTER_NUMSEG; IN_INTER; IN_NUMSEG] THEN
14585 ASM_MESON_TAC[ARITH_RULE `N1 + N2:num <= m /\ m <= x ==> N1 <= x`];
14586 ASM_MESON_TAC[ARITH_RULE `N1 + N2:num <= m ==> N2 <= m`]]);;
14588 (* ------------------------------------------------------------------------- *)
14590 (* ------------------------------------------------------------------------- *)
14592 let SERIES_RATIO = prove
14595 (!n. n >= N ==> norm(a(SUC n)) <= c * norm(a(n)))
14596 ==> ?l:real^N. (a sums l) s`,
14597 REWRITE_TAC[GE] THEN REPEAT STRIP_TAC THEN
14598 MATCH_MP_TAC SERIES_COMPARISON THEN
14599 DISJ_CASES_TAC(REAL_ARITH `c <= &0 \/ &0 < c`) THENL
14600 [EXISTS_TAC `\n:num. &0` THEN REWRITE_TAC[o_DEF; LIFT_NUM] THEN
14601 CONJ_TAC THENL [MESON_TAC[SERIES_0]; ALL_TAC] THEN
14602 EXISTS_TAC `N + 1` THEN REWRITE_TAC[GE] THEN REPEAT STRIP_TAC THEN
14603 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `c * norm(a(n - 1):real^N)` THEN
14605 [ASM_MESON_TAC[ARITH_RULE `N + 1 <= n ==> SUC(n - 1) = n /\ N <= n - 1`];
14607 MATCH_MP_TAC(REAL_ARITH `&0 <= --c * x ==> c * x <= &0`) THEN
14608 MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[NORM_POS_LE] THEN
14609 UNDISCH_TAC `c <= &0` THEN REAL_ARITH_TAC;
14610 ASSUME_TAC(MATCH_MP REAL_LT_IMP_LE (ASSUME `&0 < c`))] THEN
14611 EXISTS_TAC `\n. norm(a(N):real^N) * c pow (n - N)` THEN
14612 REWRITE_TAC[] THEN CONJ_TAC THENL
14614 EXISTS_TAC `N:num` THEN
14615 SIMP_TAC[GE; LE_EXISTS; IMP_CONJ; ADD_SUB2; LEFT_IMP_EXISTS_THM] THEN
14616 SUBGOAL_THEN `!d:num. norm(a(N + d):real^N) <= norm(a N) * c pow d`
14617 (fun th -> MESON_TAC[th]) THEN INDUCT_TAC THEN
14618 REWRITE_TAC[ADD_CLAUSES; real_pow; REAL_MUL_RID; REAL_LE_REFL] THEN
14619 MATCH_MP_TAC REAL_LE_TRANS THEN
14620 EXISTS_TAC `c * norm((a:num->real^N) (N + d))` THEN
14621 ASM_SIMP_TAC[LE_ADD] THEN ASM_MESON_TAC[REAL_LE_LMUL; REAL_MUL_AC]] THEN
14622 GEN_REWRITE_TAC I [SERIES_CAUCHY] THEN X_GEN_TAC `e:real` THEN
14623 SIMP_TAC[GSYM LIFT_SUM; FINITE_INTER; NORM_LIFT; FINITE_NUMSEG] THEN
14624 DISCH_TAC THEN SIMP_TAC[SUM_LMUL; FINITE_INTER; FINITE_NUMSEG] THEN
14625 ASM_CASES_TAC `(a:num->real^N) N = vec 0` THENL
14626 [ASM_REWRITE_TAC[NORM_0; REAL_MUL_LZERO; REAL_ABS_NUM]; ALL_TAC] THEN
14627 MP_TAC(SPECL [`c:real`; `((&1 - c) * e) / norm((a:num->real^N) N)`]
14628 REAL_ARCH_POW_INV) THEN
14629 ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; REAL_SUB_LT; NORM_POS_LT; GE] THEN
14630 DISCH_THEN(X_CHOOSE_TAC `M:num`) THEN EXISTS_TAC `N + M:num` THEN
14631 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN
14632 MATCH_MP_TAC REAL_LET_TRANS THEN
14633 EXISTS_TAC `abs(norm((a:num->real^N) N) *
14634 sum(m..n) (\i. c pow (i - N)))` THEN
14636 [REWRITE_TAC[REAL_ABS_MUL] THEN MATCH_MP_TAC REAL_LE_LMUL THEN
14637 REWRITE_TAC[REAL_ABS_POS] THEN
14638 MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= y ==> abs x <= abs y`) THEN
14639 ASM_SIMP_TAC[SUM_POS_LE; FINITE_INTER_NUMSEG; REAL_POW_LE] THEN
14640 MATCH_MP_TAC SUM_SUBSET THEN ASM_SIMP_TAC[REAL_POW_LE] THEN
14641 REWRITE_TAC[FINITE_INTER_NUMSEG; FINITE_NUMSEG] THEN
14642 REWRITE_TAC[IN_INTER; IN_DIFF] THEN MESON_TAC[];
14644 REWRITE_TAC[REAL_ABS_MUL; REAL_ABS_NORM] THEN
14645 DISJ_CASES_TAC(ARITH_RULE `n:num < m \/ m <= n`) THENL
14646 [ASM_SIMP_TAC[SUM_TRIV_NUMSEG; REAL_ABS_NUM; REAL_MUL_RZERO]; ALL_TAC] THEN
14647 SUBGOAL_THEN `m = 0 + m /\ n = (n - m) + m` (CONJUNCTS_THEN SUBST1_TAC) THENL
14648 [UNDISCH_TAC `m:num <= n` THEN ARITH_TAC; ALL_TAC] THEN
14649 REWRITE_TAC[SUM_OFFSET] THEN UNDISCH_TAC `N + M:num <= m` THEN
14650 SIMP_TAC[LE_EXISTS] THEN DISCH_THEN(X_CHOOSE_THEN `d:num` SUBST_ALL_TAC) THEN
14651 REWRITE_TAC[ARITH_RULE `(i + (N + M) + d) - N:num = (M + d) + i`] THEN
14652 ONCE_REWRITE_TAC[REAL_POW_ADD] THEN REWRITE_TAC[SUM_LMUL; SUM_GP] THEN
14653 ASM_SIMP_TAC[LT; REAL_LT_IMP_NE] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
14654 ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; NORM_POS_LT; REAL_ABS_MUL] THEN
14655 REWRITE_TAC[REAL_ABS_POW] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
14656 ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_ABS_DIV; REAL_POW_LT; REAL_ARITH
14657 `&0 < c /\ c < &1 ==> &0 < abs c /\ &0 < abs(&1 - c)`; REAL_LT_LDIV_EQ] THEN
14658 MATCH_MP_TAC(REAL_ARITH
14659 `&0 < x /\ x <= &1 /\ &1 <= e ==> abs(c pow 0 - x) < e`) THEN
14660 ASM_SIMP_TAC[REAL_POW_LT; REAL_POW_1_LE; REAL_LT_IMP_LE] THEN
14661 ASM_SIMP_TAC[REAL_ARITH `c < &1 ==> x * abs(&1 - c) = (&1 - c) * x`] THEN
14662 REWRITE_TAC[real_div; REAL_INV_MUL; REAL_POW_ADD; REAL_MUL_ASSOC] THEN
14663 REWRITE_TAC[REAL_ARITH
14664 `(((a * b) * c) * d) * e = (e * ((a * b) * c)) * d`] THEN
14665 ASM_SIMP_TAC[GSYM real_div; REAL_LE_RDIV_EQ; REAL_POW_LT; REAL_MUL_LID;
14666 REAL_ARITH `&0 < c ==> abs c = c`] THEN
14667 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
14668 `xm < e ==> &0 <= (d - &1) * e ==> xm <= d * e`)) THEN
14669 MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THENL
14670 [REWRITE_TAC[REAL_SUB_LE; GSYM REAL_POW_INV] THEN
14671 MATCH_MP_TAC REAL_POW_LE_1 THEN
14672 MATCH_MP_TAC REAL_INV_1_LE THEN ASM_SIMP_TAC[REAL_LT_IMP_LE];
14673 MATCH_MP_TAC REAL_LT_IMP_LE THEN
14674 ASM_SIMP_TAC[REAL_SUB_LT; REAL_LT_MUL; REAL_LT_DIV; NORM_POS_LT]]);;
14676 (* ------------------------------------------------------------------------- *)
14677 (* Ostensibly weaker versions of the boundedness of partial sums. *)
14678 (* ------------------------------------------------------------------------- *)
14680 let BOUNDED_PARTIAL_SUMS = prove
14681 (`!f:num->real^N k.
14682 bounded { vsum(k..n) f | n IN (:num) }
14683 ==> bounded { vsum(m..n) f | m IN (:num) /\ n IN (:num) }`,
14684 REPEAT STRIP_TAC THEN
14685 SUBGOAL_THEN `bounded { vsum(0..n) f:real^N | n IN (:num) }` MP_TAC THENL
14686 [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
14687 REWRITE_TAC[bounded] THEN
14688 REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; IN_UNIV] THEN
14689 DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
14690 EXISTS_TAC `sum { i:num | i < k} (\i. norm(f i:real^N)) + B` THEN
14691 X_GEN_TAC `i:num` THEN ASM_CASES_TAC `i:num < k` THENL
14692 [MATCH_MP_TAC(REAL_ARITH
14693 `!y. x <= y /\ y <= a /\ &0 < b ==> x <= a + b`) THEN
14694 EXISTS_TAC `sum (0..i) (\i. norm(f i:real^N))` THEN
14695 ASM_SIMP_TAC[VSUM_NORM; FINITE_NUMSEG] THEN
14696 MATCH_MP_TAC SUM_SUBSET THEN
14697 REWRITE_TAC[FINITE_NUMSEG; FINITE_NUMSEG_LT; NORM_POS_LE] THEN
14698 REWRITE_TAC[IN_DIFF; IN_NUMSEG; IN_ELIM_THM] THEN ASM_ARITH_TAC;
14700 ASM_CASES_TAC `k = 0` THENL
14701 [FIRST_X_ASSUM SUBST_ALL_TAC THEN MATCH_MP_TAC(REAL_ARITH
14702 `x <= B /\ &0 <= b ==> x <= b + B`) THEN
14703 ASM_SIMP_TAC[SUM_POS_LE; FINITE_NUMSEG_LT; NORM_POS_LE];
14705 MP_TAC(ISPECL [`f:num->real^N`; `0`; `k:num`; `i:num`]
14706 VSUM_COMBINE_L) THEN
14707 ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
14708 DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[NUMSEG_LT] THEN
14709 MATCH_MP_TAC(NORM_ARITH
14710 `norm(x) <= a /\ norm(y) <= b ==> norm(x + y) <= a + b`) THEN
14711 ASM_SIMP_TAC[VSUM_NORM; FINITE_NUMSEG];
14713 DISCH_THEN(fun th ->
14714 MP_TAC(MATCH_MP BOUNDED_DIFFS (W CONJ th)) THEN MP_TAC th) THEN
14715 REWRITE_TAC[IMP_IMP; GSYM BOUNDED_UNION] THEN
14716 MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b ==> c <=> b ==> a ==> c`]
14717 BOUNDED_SUBSET) THEN
14718 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNION; LEFT_IMP_EXISTS_THM; IN_UNIV] THEN
14719 MAP_EVERY X_GEN_TAC [`x:real^N`; `m:num`; `n:num`] THEN
14720 DISCH_THEN SUBST1_TAC THEN
14721 ASM_CASES_TAC `m = 0` THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
14722 ASM_CASES_TAC `n:num < m` THENL
14723 [DISJ2_TAC THEN REPEAT(EXISTS_TAC `vsum(0..0) (f:num->real^N)`) THEN
14724 ASM_SIMP_TAC[VSUM_TRIV_NUMSEG; VECTOR_SUB_REFL] THEN MESON_TAC[];
14726 DISJ2_TAC THEN MAP_EVERY EXISTS_TAC
14727 [`vsum(0..n) (f:num->real^N)`; `vsum(0..(m-1)) (f:num->real^N)`] THEN
14728 CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
14729 MP_TAC(ISPECL [`f:num->real^N`; `0`; `m:num`; `n:num`]
14730 VSUM_COMBINE_L) THEN
14731 ANTS_TAC THENL [ASM_ARITH_TAC; VECTOR_ARITH_TAC]);;
14733 (* ------------------------------------------------------------------------- *)
14734 (* General Dirichlet convergence test (could make this uniform on a set). *)
14735 (* ------------------------------------------------------------------------- *)
14737 let SUMMABLE_BILINEAR_PARTIAL_PRE = prove
14738 (`!f g h:real^M->real^N->real^P l k.
14740 ((\n. h (f(n + 1)) (g(n))) --> l) sequentially /\
14741 summable (from k) (\n. h (f(n + 1) - f(n)) (g(n)))
14742 ==> summable (from k) (\n. h (f n) (g(n) - g(n - 1)))`,
14743 REPEAT GEN_TAC THEN
14744 REWRITE_TAC[summable; sums; FROM_INTER_NUMSEG] THEN
14745 REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
14746 FIRST_ASSUM(fun th ->
14747 REWRITE_TAC[MATCH_MP BILINEAR_VSUM_PARTIAL_PRE th]) THEN
14748 DISCH_THEN(X_CHOOSE_TAC `l':real^P`) THEN
14749 EXISTS_TAC `l - (h:real^M->real^N->real^P) (f k) (g(k - 1)) - l'` THEN
14750 REWRITE_TAC[LIM_CASES_SEQUENTIALLY] THEN
14751 REPEAT(MATCH_MP_TAC LIM_SUB THEN ASM_REWRITE_TAC[LIM_CONST]));;
14753 let SERIES_DIRICHLET_BILINEAR = prove
14754 (`!f g h:real^M->real^N->real^P k m p l.
14756 bounded { vsum (m..n) f | n IN (:num)} /\
14757 summable (from p) (\n. lift(norm(g(n + 1) - g(n)))) /\
14758 ((\n. h (g(n + 1)) (vsum(1..n) f)) --> l) sequentially
14759 ==> summable (from k) (\n. h (g n) (f n))`,
14760 REPEAT STRIP_TAC THEN MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE THEN
14761 EXISTS_TAC `1` THEN
14762 FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP BOUNDED_PARTIAL_SUMS) THEN
14763 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
14764 SIMP_TAC[IN_ELIM_THM; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN
14765 REWRITE_TAC[MESON[] `(!x a b. x = f a b ==> p a b) <=> (!a b. p a b)`] THEN
14766 X_GEN_TAC `B:real` THEN STRIP_TAC THEN
14767 FIRST_ASSUM(MP_TAC o MATCH_MP BILINEAR_BOUNDED_POS) THEN
14768 DISCH_THEN(X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC) THEN
14769 MATCH_MP_TAC SUMMABLE_EQ THEN
14770 EXISTS_TAC `\n. (h:real^M->real^N->real^P)
14771 (g n) (vsum (1..n) f - vsum (1..n-1) f)` THEN
14772 SIMP_TAC[IN_FROM; GSYM NUMSEG_RREC] THEN
14773 SIMP_TAC[VSUM_CLAUSES; FINITE_NUMSEG; IN_NUMSEG;
14774 ARITH_RULE `1 <= n ==> ~(n <= n - 1)`] THEN
14776 [REPEAT STRIP_TAC THEN ASM_SIMP_TAC[BILINEAR_RADD; BILINEAR_RSUB] THEN
14779 MATCH_MP_TAC SUMMABLE_FROM_ELSEWHERE THEN EXISTS_TAC `p:num` THEN
14780 MP_TAC(ISPECL [`g:num->real^M`; `\n. vsum(1..n) f:real^N`;
14781 `h:real^M->real^N->real^P`; `l:real^P`; `p:num`]
14782 SUMMABLE_BILINEAR_PARTIAL_PRE) THEN
14783 REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN
14784 ASM_REWRITE_TAC[] THEN
14786 `summable (from p) (lift o (\n. C * B * norm(g(n + 1) - g(n):real^M)))`
14787 MP_TAC THENL [ASM_SIMP_TAC[o_DEF; LIFT_CMUL; SUMMABLE_CMUL]; ALL_TAC] THEN
14788 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] SUMMABLE_COMPARISON) THEN
14789 EXISTS_TAC `0` THEN REWRITE_TAC[IN_FROM; GE; LE_0] THEN
14790 REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
14791 `C * norm(g(n + 1) - g(n):real^M) * norm(vsum (1..n) f:real^N)` THEN
14792 ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN
14793 GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN
14794 ASM_SIMP_TAC[REAL_LE_LMUL; NORM_POS_LE]);;
14796 let SERIES_DIRICHLET = prove
14797 (`!f:num->real^N g N k m.
14798 bounded { vsum (m..n) f | n IN (:num)} /\
14799 (!n. N <= n ==> g(n + 1) <= g(n)) /\
14800 ((lift o g) --> vec 0) sequentially
14801 ==> summable (from k) (\n. g(n) % f(n))`,
14802 REPEAT STRIP_TAC THEN
14803 MP_TAC(ISPECL [`f:num->real^N`; `lift o (g:num->real)`;
14804 `\x y:real^N. drop x % y`] SERIES_DIRICHLET_BILINEAR) THEN
14805 REWRITE_TAC[o_THM; LIFT_DROP] THEN DISCH_THEN MATCH_MP_TAC THEN
14806 MAP_EVERY EXISTS_TAC [`m:num`; `N:num`; `vec 0:real^N`] THEN CONJ_TAC THENL
14807 [REWRITE_TAC[bilinear; linear; DROP_ADD; DROP_CMUL] THEN
14808 REPEAT STRIP_TAC THEN VECTOR_ARITH_TAC;
14810 ASM_REWRITE_TAC[GSYM LIFT_SUB; NORM_LIFT] THEN
14811 FIRST_ASSUM(MP_TAC o SPEC `1` o MATCH_MP SEQ_OFFSET) THEN
14812 REWRITE_TAC[o_THM] THEN DISCH_TAC THEN CONJ_TAC THENL
14813 [MATCH_MP_TAC SUMMABLE_EQ_EVENTUALLY THEN
14814 EXISTS_TAC `\n. lift(g(n) - g(n + 1))` THEN REWRITE_TAC[] THEN
14816 [ASM_MESON_TAC[REAL_ARITH `b <= a ==> abs(b - a) = a - b`];
14817 REWRITE_TAC[summable; sums; FROM_INTER_NUMSEG; VSUM_DIFFS; LIFT_SUB] THEN
14818 REWRITE_TAC[LIM_CASES_SEQUENTIALLY] THEN
14819 EXISTS_TAC `lift(g(N:num)) - vec 0` THEN
14820 MATCH_MP_TAC LIM_SUB THEN ASM_REWRITE_TAC[LIM_CONST]];
14821 MATCH_MP_TAC LIM_NULL_VMUL_BOUNDED THEN ASM_REWRITE_TAC[o_DEF] THEN
14822 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
14823 FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP BOUNDED_PARTIAL_SUMS) THEN
14824 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
14825 SIMP_TAC[IN_ELIM_THM; IN_UNIV] THEN MESON_TAC[]]);;
14827 (* ------------------------------------------------------------------------- *)
14828 (* Rearranging absolutely convergent series. *)
14829 (* ------------------------------------------------------------------------- *)
14831 let SERIES_INJECTIVE_IMAGE_STRONG = prove
14832 (`!x:num->real^N s f.
14833 summable (IMAGE f s) (\n. lift(norm(x n))) /\
14834 (!m n. m IN s /\ n IN s /\ f m = f n ==> m = n)
14835 ==> ((\n. vsum (IMAGE f s INTER (0..n)) x -
14836 vsum (s INTER (0..n)) (x o f)) --> vec 0)
14839 (`!f:A->real^N s t.
14840 FINITE s /\ FINITE t
14841 ==> vsum s f - vsum t f = vsum (s DIFF t) f - vsum (t DIFF s) f`,
14842 REPEAT STRIP_TAC THEN
14843 ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s DIFF (s INTER t)`] THEN
14844 ASM_SIMP_TAC[VSUM_DIFF; INTER_SUBSET] THEN
14845 REWRITE_TAC[INTER_COMM] THEN VECTOR_ARITH_TAC) in
14846 REPEAT STRIP_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY] THEN
14847 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
14848 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUMMABLE_CAUCHY]) THEN
14849 SIMP_TAC[VSUM_REAL; FINITE_INTER; FINITE_NUMSEG] THEN
14850 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [o_DEF] THEN
14851 REWRITE_TAC[NORM_LIFT; LIFT_DROP] THEN
14852 SIMP_TAC[real_abs; SUM_POS_LE; NORM_POS_LE; FINITE_INTER; FINITE_NUMSEG] THEN
14853 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
14854 ASM_REWRITE_TAC[dist; GE; VECTOR_SUB_RZERO; REAL_HALF] THEN
14855 DISCH_THEN(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC) THEN
14856 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [INJECTIVE_ON_LEFT_INVERSE]) THEN
14857 DISCH_THEN(X_CHOOSE_TAC `g:num->num`) THEN
14858 MP_TAC(ISPECL [`g:num->num`; `0..N`] UPPER_BOUND_FINITE_SET) THEN
14859 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG; LE_0] THEN
14860 DISCH_THEN(X_CHOOSE_TAC `P:num`) THEN
14861 EXISTS_TAC `MAX N P` THEN X_GEN_TAC `n:num` THEN
14862 SIMP_TAC[ARITH_RULE `MAX a b <= c <=> a <= c /\ b <= c`] THEN DISCH_TAC THEN
14863 W(MP_TAC o PART_MATCH (rand o rand) VSUM_IMAGE o rand o
14864 rand o lhand o snd) THEN
14866 [ASM_MESON_TAC[FINITE_INTER; FINITE_NUMSEG; IN_INTER];
14867 DISCH_THEN(SUBST1_TAC o SYM)] THEN
14868 W(MP_TAC o PART_MATCH (lhand o rand) lemma o rand o lhand o snd) THEN
14869 SIMP_TAC[FINITE_INTER; FINITE_IMAGE; FINITE_NUMSEG] THEN
14870 DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC(NORM_ARITH
14871 `norm a < e / &2 /\ norm b < e / &2 ==> norm(a - b:real^N) < e`) THEN
14873 W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
14874 SIMP_TAC[FINITE_DIFF; FINITE_IMAGE; FINITE_INTER; FINITE_NUMSEG] THEN
14875 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LET_TRANS) THEN
14876 MATCH_MP_TAC REAL_LET_TRANS THENL
14878 `sum(IMAGE (f:num->num) s INTER (N..n)) (\i. norm(x i :real^N))` THEN
14879 ASM_SIMP_TAC[LE_REFL] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
14880 SIMP_TAC[NORM_POS_LE; FINITE_INTER; FINITE_NUMSEG] THEN
14881 MATCH_MP_TAC(SET_RULE
14882 `(!x. x IN s /\ f(x) IN n /\ ~(x IN m) ==> f x IN t)
14883 ==> (IMAGE f s INTER n) DIFF (IMAGE f (s INTER m)) SUBSET
14884 IMAGE f s INTER t`) THEN
14885 ASM_SIMP_TAC[IN_NUMSEG; LE_0; NOT_LE] THEN
14886 X_GEN_TAC `i:num` THEN STRIP_TAC THEN
14887 MATCH_MP_TAC LT_IMP_LE THEN ONCE_REWRITE_TAC[GSYM NOT_LE] THEN
14888 FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE BINDER_CONV
14889 [GSYM CONTRAPOS_THM]) THEN
14890 ASM_SIMP_TAC[] THEN ASM_ARITH_TAC;
14891 MP_TAC(ISPECL [`f:num->num`; `0..n`] UPPER_BOUND_FINITE_SET) THEN
14892 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG; LE_0] THEN
14893 DISCH_THEN(X_CHOOSE_TAC `p:num`) THEN
14895 `sum(IMAGE (f:num->num) s INTER (N..p)) (\i. norm(x i :real^N))` THEN
14896 ASM_SIMP_TAC[LE_REFL] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
14897 SIMP_TAC[NORM_POS_LE; FINITE_INTER; FINITE_NUMSEG] THEN
14898 MATCH_MP_TAC(SET_RULE
14899 `(!x. x IN s /\ x IN n /\ ~(f x IN m) ==> f x IN t)
14900 ==> (IMAGE f (s INTER n) DIFF (IMAGE f s) INTER m) SUBSET
14901 (IMAGE f s INTER t)`) THEN
14902 ASM_SIMP_TAC[IN_NUMSEG; LE_0] THEN ASM_ARITH_TAC]);;
14904 let SERIES_INJECTIVE_IMAGE = prove
14905 (`!x:num->real^N s f l.
14906 summable (IMAGE f s) (\n. lift(norm(x n))) /\
14907 (!m n. m IN s /\ n IN s /\ f m = f n ==> m = n)
14908 ==> (((x o f) sums l) s <=> (x sums l) (IMAGE f s))`,
14909 REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN REWRITE_TAC[sums] THEN
14910 MATCH_MP_TAC LIM_TRANSFORM_EQ THEN REWRITE_TAC[] THEN
14911 MATCH_MP_TAC SERIES_INJECTIVE_IMAGE_STRONG THEN
14912 ASM_REWRITE_TAC[]);;
14914 let SERIES_REARRANGE_EQ = prove
14915 (`!x:num->real^N s p l.
14916 summable s (\n. lift(norm(x n))) /\ p permutes s
14917 ==> (((x o p) sums l) s <=> (x sums l) s)`,
14918 REPEAT STRIP_TAC THEN
14919 MP_TAC(ISPECL [`x:num->real^N`; `s:num->bool`; `p:num->num`; `l:real^N`]
14920 SERIES_INJECTIVE_IMAGE) THEN
14921 ASM_SIMP_TAC[PERMUTES_IMAGE] THEN
14922 ASM_MESON_TAC[PERMUTES_INJECTIVE]);;
14924 let SERIES_REARRANGE = prove
14925 (`!x:num->real^N s p l.
14926 summable s (\n. lift(norm(x n))) /\ p permutes s /\ (x sums l) s
14927 ==> ((x o p) sums l) s`,
14928 MESON_TAC[SERIES_REARRANGE_EQ]);;
14930 let SUMMABLE_REARRANGE = prove
14932 summable s (\n. lift(norm(x n))) /\ p permutes s
14933 ==> summable s (x o p)`,
14934 MESON_TAC[SERIES_LIFT_ABSCONV_IMP_CONV; summable; SERIES_REARRANGE]);;
14936 (* ------------------------------------------------------------------------- *)
14937 (* Banach fixed point theorem (not really topological...) *)
14938 (* ------------------------------------------------------------------------- *)
14940 let BANACH_FIX = prove
14941 (`!f s c. complete s /\ ~(s = {}) /\
14942 &0 <= c /\ c < &1 /\
14943 (IMAGE f s) SUBSET s /\
14944 (!x y. x IN s /\ y IN s ==> dist(f(x),f(y)) <= c * dist(x,y))
14945 ==> ?!x:real^N. x IN s /\ (f x = x)`,
14946 REPEAT STRIP_TAC THEN REWRITE_TAC[EXISTS_UNIQUE_THM] THEN CONJ_TAC THENL
14948 MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
14949 SUBGOAL_THEN `dist((f:real^N->real^N) x,f y) <= c * dist(x,y)` MP_TAC THENL
14950 [ASM_MESON_TAC[]; ALL_TAC] THEN
14951 ASM_REWRITE_TAC[REAL_ARITH `a <= c * a <=> &0 <= --a * (&1 - c)`] THEN
14952 ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; REAL_SUB_LT; real_div] THEN
14953 REWRITE_TAC[REAL_MUL_LZERO; REAL_ARITH `&0 <= --x <=> ~(&0 < x)`] THEN
14954 MESON_TAC[DIST_POS_LT]] THEN
14955 STRIP_ASSUME_TAC(prove_recursive_functions_exist num_RECURSION
14956 `(z 0 = @x:real^N. x IN s) /\ (!n. z(SUC n) = f(z n))`) THEN
14957 SUBGOAL_THEN `!n. (z:num->real^N) n IN s` ASSUME_TAC THENL
14958 [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN
14959 ASM_MESON_TAC[MEMBER_NOT_EMPTY; SUBSET; IN_IMAGE];
14961 UNDISCH_THEN `z 0 = @x:real^N. x IN s` (K ALL_TAC) THEN
14962 SUBGOAL_THEN `?x:real^N. x IN s /\ (z --> x) sequentially` MP_TAC THENL
14964 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN
14965 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
14966 ABBREV_TAC `e = dist(f(a:real^N),a)` THEN
14967 SUBGOAL_THEN `~(&0 < e)` (fun th -> ASM_MESON_TAC[th; DIST_POS_LT]) THEN
14969 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
14970 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
14971 ASM_REWRITE_TAC[REAL_HALF] THEN DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
14973 `dist(f(z N),a:real^N) < e / &2 /\ dist(f(z(N:num)),f(a)) < e / &2`
14974 (fun th -> ASM_MESON_TAC[th; DIST_TRIANGLE_HALF_R; REAL_LT_REFL]) THEN
14975 CONJ_TAC THENL [ASM_MESON_TAC[ARITH_RULE `N <= SUC N`]; ALL_TAC] THEN
14976 MATCH_MP_TAC REAL_LET_TRANS THEN
14977 EXISTS_TAC `c * dist((z:num->real^N) N,a)` THEN ASM_SIMP_TAC[] THEN
14978 MATCH_MP_TAC(REAL_ARITH `x < y /\ c * x <= &1 * x ==> c * x < y`) THEN
14979 ASM_SIMP_TAC[LE_REFL; REAL_LE_RMUL; DIST_POS_LE; REAL_LT_IMP_LE]] THEN
14980 FIRST_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [complete]) THEN
14981 ASM_REWRITE_TAC[CAUCHY] THEN
14982 SUBGOAL_THEN `!n. dist(z(n):real^N,z(SUC n)) <= c pow n * dist(z(0),z(1))`
14985 REWRITE_TAC[real_pow; ARITH; REAL_MUL_LID; REAL_LE_REFL] THEN
14986 MATCH_MP_TAC REAL_LE_TRANS THEN
14987 EXISTS_TAC `c * dist(z(n):real^N,z(SUC n))` THEN
14988 CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
14989 REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN ASM_SIMP_TAC[REAL_LE_LMUL];
14992 `!m n:num. (&1 - c) * dist(z(m):real^N,z(m+n))
14993 <= c pow m * dist(z(0),z(1)) * (&1 - c pow n)`
14995 [GEN_TAC THEN INDUCT_TAC THENL
14996 [REWRITE_TAC[ADD_CLAUSES; DIST_REFL; REAL_MUL_RZERO] THEN
14997 MATCH_MP_TAC REAL_LE_MUL THEN
14998 ASM_SIMP_TAC[REAL_LE_MUL; REAL_POW_LE; DIST_POS_LE; REAL_SUB_LE;
14999 REAL_POW_1_LE; REAL_LT_IMP_LE];
15001 MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
15002 `(&1 - c) * (dist(z m:real^N,z(m + n)) + dist(z(m + n),z(m + SUC n)))` THEN
15003 ASM_SIMP_TAC[REAL_LE_LMUL; REAL_SUB_LE; REAL_LT_IMP_LE; DIST_TRIANGLE] THEN
15004 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
15005 `c * x <= y ==> c * x' + y <= y' ==> c * (x + x') <= y'`)) THEN
15006 REWRITE_TAC[REAL_ARITH
15007 `q + a * b * (&1 - x) <= a * b * (&1 - y) <=> q <= a * b * (x - y)`] THEN
15008 REWRITE_TAC[ADD_CLAUSES; real_pow] THEN
15009 REWRITE_TAC[REAL_ARITH `a * b * (d - c * d) = (&1 - c) * a * d * b`] THEN
15010 MATCH_MP_TAC REAL_LE_LMUL THEN
15011 ASM_SIMP_TAC[REAL_SUB_LE; REAL_LT_IMP_LE] THEN
15012 REWRITE_TAC[GSYM REAL_POW_ADD; REAL_MUL_ASSOC] THEN ASM_MESON_TAC[];
15014 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
15015 ASM_CASES_TAC `(z:num->real^N) 0 = z 1` THENL
15016 [FIRST_X_ASSUM SUBST_ALL_TAC THEN EXISTS_TAC `0` THEN
15017 REWRITE_TAC[GE; LE_0] THEN X_GEN_TAC `n:num` THEN
15018 FIRST_X_ASSUM(MP_TAC o SPECL [`0`; `n:num`]) THEN
15019 REWRITE_TAC[ADD_CLAUSES; DIST_REFL; REAL_MUL_LZERO; REAL_MUL_RZERO] THEN
15020 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
15021 ASM_CASES_TAC `(z:num->real^N) 0 = z n` THEN
15022 ASM_REWRITE_TAC[DIST_REFL; REAL_NOT_LE] THEN
15023 ASM_SIMP_TAC[REAL_LT_MUL; DIST_POS_LT; REAL_SUB_LT];
15025 MP_TAC(SPECL [`c:real`; `e * (&1 - c) / dist((z:num->real^N) 0,z 1)`]
15026 REAL_ARCH_POW_INV) THEN
15027 ASM_SIMP_TAC[REAL_LT_MUL; REAL_LT_DIV; REAL_SUB_LT; DIST_POS_LT] THEN
15028 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
15029 REWRITE_TAC[real_div; GE; REAL_MUL_ASSOC] THEN
15030 ASM_SIMP_TAC[REAL_LT_RDIV_EQ; GSYM real_div; DIST_POS_LT] THEN
15031 ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; REAL_SUB_LT] THEN DISCH_TAC THEN
15032 REWRITE_TAC[LE_EXISTS; LEFT_IMP_EXISTS_THM] THEN
15033 GEN_TAC THEN X_GEN_TAC `d:num` THEN DISCH_THEN SUBST_ALL_TAC THEN
15034 ONCE_REWRITE_TAC[DIST_SYM] THEN
15035 FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(REAL_ARITH
15036 `d < e ==> x <= d ==> x < e`)) THEN
15037 ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN
15038 FIRST_X_ASSUM(MP_TAC o SPECL [`N:num`; `d:num`]) THEN
15039 MATCH_MP_TAC(REAL_ARITH
15040 `(c * d) * e <= (c * d) * &1 ==> x * y <= c * d * e ==> y * x <= c * d`) THEN
15041 MATCH_MP_TAC REAL_LE_LMUL THEN
15042 ASM_SIMP_TAC[REAL_LE_MUL; REAL_POW_LE; DIST_POS_LE; REAL_ARITH
15043 `&0 <= x ==> &1 - x <= &1`]);;
15045 (* ------------------------------------------------------------------------- *)
15046 (* Edelstein fixed point theorem. *)
15047 (* ------------------------------------------------------------------------- *)
15049 let EDELSTEIN_FIX = prove
15050 (`!f s. compact s /\ ~(s = {}) /\ (IMAGE f s) SUBSET s /\
15051 (!x y. x IN s /\ y IN s /\ ~(x = y) ==> dist(f(x),f(y)) < dist(x,y))
15052 ==> ?!x:real^N. x IN s /\ f x = x`,
15053 MAP_EVERY X_GEN_TAC [`g:real^N->real^N`; `s:real^N->bool`] THEN
15054 REPEAT STRIP_TAC THEN REWRITE_TAC[EXISTS_UNIQUE_THM] THEN CONJ_TAC THENL
15055 [ALL_TAC; ASM_MESON_TAC[REAL_LT_REFL]] THEN
15057 `!x y. x IN s /\ y IN s ==> dist((g:real^N->real^N)(x),g(y)) <= dist(x,y)`
15059 [REPEAT STRIP_TAC THEN ASM_CASES_TAC `x:real^N = y` THEN
15060 ASM_SIMP_TAC[DIST_REFL; REAL_LE_LT];
15062 ASM_CASES_TAC `?x:real^N. x IN s /\ ~(g x = x)` THENL
15063 [ALL_TAC; ASM SET_TAC[]] THEN
15064 FIRST_X_ASSUM(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN
15065 ABBREV_TAC `y = (g:real^N->real^N) x` THEN
15066 SUBGOAL_THEN `(y:real^N) IN s` ASSUME_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
15067 FIRST_ASSUM(MP_TAC o MATCH_MP COMPACT_PCROSS o W CONJ) THEN
15068 REWRITE_TAC[compact; PCROSS] THEN
15069 (STRIP_ASSUME_TAC o prove_general_recursive_function_exists)
15070 `?f:num->real^N->real^N.
15071 (!z. f 0 z = z) /\ (!z n. f (SUC n) z = g(f n z))` THEN
15072 SUBGOAL_THEN `!n z. z IN s ==> (f:num->real^N->real^N) n z IN s`
15073 STRIP_ASSUME_TAC THENL [INDUCT_TAC THEN ASM SET_TAC[]; ALL_TAC] THEN
15075 `!m n w z. m <= n /\ w IN s /\ z IN s
15076 ==> dist((f:num->real^N->real^N) n w,f n z) <= dist(f m w,f m z)`
15078 [REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ] THEN
15079 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
15080 RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; FORALL_IN_IMAGE]) THEN
15081 ASM_SIMP_TAC[REAL_LE_REFL] THEN MESON_TAC[REAL_LE_TRANS];
15083 DISCH_THEN(MP_TAC o SPEC
15084 `\n:num. pastecart (f n (x:real^N)) (f n y:real^N)`) THEN
15085 ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[LEFT_IMP_EXISTS_THM]] THEN
15086 MAP_EVERY X_GEN_TAC [`l:real^(N,N)finite_sum`; `s:num->num`] THEN
15087 REWRITE_TAC[o_DEF; IN_ELIM_THM] THEN
15088 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
15089 REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
15090 MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
15091 DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC SUBST_ALL_TAC) THEN
15093 `(\x:real^(N,N)finite_sum. fstcart x) continuous_on UNIV /\
15094 (\x:real^(N,N)finite_sum. sndcart x) continuous_on UNIV`
15096 [CONJ_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN
15097 REWRITE_TAC[ETA_AX; LINEAR_FSTCART; LINEAR_SNDCART];
15099 REWRITE_TAC[CONTINUOUS_ON_SEQUENTIALLY; IN_UNIV] THEN
15100 DISCH_THEN(CONJUNCTS_THEN(fun th -> FIRST_ASSUM(MP_TAC o MATCH_MP th))) THEN
15101 REWRITE_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART; IMP_IMP] THEN
15102 ONCE_REWRITE_TAC[CONJ_SYM] THEN
15103 DISCH_THEN(fun th -> CONJUNCTS_THEN2 (LABEL_TAC "A") (LABEL_TAC "B") th THEN
15104 MP_TAC(MATCH_MP LIM_SUB th)) THEN
15105 REWRITE_TAC[] THEN DISCH_THEN(LABEL_TAC "AB") THEN
15107 `!n. dist(a:real^N,b) <= dist((f:num->real^N->real^N) n x,f n y)`
15108 STRIP_ASSUME_TAC THENL
15109 [X_GEN_TAC `N:num` THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN
15110 ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN DISCH_TAC THEN
15111 USE_THEN "AB" (MP_TAC o REWRITE_RULE[LIM_SEQUENTIALLY]) THEN
15112 DISCH_THEN(fun th -> FIRST_X_ASSUM(MP_TAC o MATCH_MP th)) THEN
15113 REWRITE_TAC[NOT_EXISTS_THM] THEN X_GEN_TAC `M:num` THEN
15114 DISCH_THEN(MP_TAC o SPEC `M + N:num`) THEN REWRITE_TAC[LE_ADD] THEN
15115 MATCH_MP_TAC(NORM_ARITH
15116 `dist(fx,fy) <= dist(x,y)
15117 ==> ~(dist(fx - fy,a - b) < dist(a,b) - dist(x,y))`) THEN
15118 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
15119 FIRST_X_ASSUM(MP_TAC o SPEC `M + N:num` o MATCH_MP MONOTONE_BIGGER) THEN
15122 SUBGOAL_THEN `b:real^N = a` SUBST_ALL_TAC THENL
15123 [MATCH_MP_TAC(TAUT `(~p ==> F) ==> p`) THEN DISCH_TAC THEN
15124 ABBREV_TAC `e = dist(a,b) - dist((g:real^N->real^N) a,g b)` THEN
15125 SUBGOAL_THEN `&0 < e` ASSUME_TAC THENL
15126 [ASM_MESON_TAC[REAL_SUB_LT]; ALL_TAC] THEN
15128 `?n. dist((f:num->real^N->real^N) n x,a) < e / &2 /\
15129 dist(f n y,b) < e / &2`
15130 STRIP_ASSUME_TAC THENL
15131 [MAP_EVERY (fun s -> USE_THEN s (MP_TAC o SPEC `e / &2` o
15132 REWRITE_RULE[LIM_SEQUENTIALLY])) ["A"; "B"] THEN
15133 ASM_REWRITE_TAC[REAL_HALF] THEN
15134 DISCH_THEN(X_CHOOSE_TAC `M:num`) THEN
15135 DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
15136 EXISTS_TAC `(s:num->num) (M + N)` THEN
15137 CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC;
15139 SUBGOAL_THEN `dist(f (SUC n) x,(g:real^N->real^N) a) +
15140 dist((f:num->real^N->real^N) (SUC n) y,g b) < e`
15142 [ASM_REWRITE_TAC[] THEN
15143 MATCH_MP_TAC(REAL_ARITH `x < e / &2 /\ y < e / &2 ==> x + y < e`) THEN
15144 CONJ_TAC THEN FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
15146 ==> dist(g x,g y) <= dist(x,y) ==> dist(g x,g y) < e`)) THEN
15149 MP_TAC(SPEC `SUC n` (ASSUME
15150 `!n. dist (a:real^N,b) <=
15151 dist ((f:num->real^N->real^N) n x,f n y)`)) THEN
15152 EXPAND_TAC "e" THEN NORM_ARITH_TAC;
15154 EXISTS_TAC `a:real^N` THEN ASM_REWRITE_TAC[] THEN
15155 MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
15156 EXISTS_TAC `\n:num. (f:num->real^N->real^N) (SUC(s n)) x` THEN
15157 REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN CONJ_TAC THENL
15158 [ASM_REWRITE_TAC[] THEN
15159 SUBGOAL_THEN `(g:real^N->real^N) continuous_on s` MP_TAC THENL
15160 [REWRITE_TAC[continuous_on] THEN ASM_MESON_TAC[REAL_LET_TRANS];
15162 REWRITE_TAC[CONTINUOUS_ON_SEQUENTIALLY; o_DEF] THEN
15163 DISCH_THEN MATCH_MP_TAC THEN ASM_SIMP_TAC[];
15164 SUBGOAL_THEN `!n. (f:num->real^N->real^N) (SUC n) x = f n y`
15165 (fun th -> ASM_SIMP_TAC[th]) THEN
15166 INDUCT_TAC THEN ASM_REWRITE_TAC[]]);;
15168 (* ------------------------------------------------------------------------- *)
15169 (* Dini's theorem. *)
15170 (* ------------------------------------------------------------------------- *)
15173 (`!f:num->real^N->real^1 g s.
15174 compact s /\ (!n. (f n) continuous_on s) /\ g continuous_on s /\
15175 (!x. x IN s ==> ((\n. (f n x)) --> g x) sequentially) /\
15176 (!n x. x IN s ==> drop(f n x) <= drop(f (n + 1) x))
15178 ==> eventually (\n. !x. x IN s ==> norm(f n x - g x) < e)
15180 REPEAT STRIP_TAC THEN
15182 `!x:real^N m n:num. x IN s /\ m <= n ==> drop(f m x) <= drop(f n x)`
15184 [GEN_TAC THEN ASM_CASES_TAC `(x:real^N) IN s` THEN ASM_REWRITE_TAC[] THEN
15185 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_SIMP_TAC[ADD1] THEN
15188 SUBGOAL_THEN `!n:num x:real^N. x IN s ==> drop(f n x) <= drop(g x)`
15190 [REPEAT STRIP_TAC THEN
15191 MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LE) THEN
15192 EXISTS_TAC `\m:num. (f:num->real^N->real^1) n x` THEN
15193 EXISTS_TAC `\m:num. (f:num->real^N->real^1) m x` THEN
15194 ASM_SIMP_TAC[LIM_CONST; TRIVIAL_LIMIT_SEQUENTIALLY] THEN
15195 REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN ASM_MESON_TAC[];
15197 RULE_ASSUM_TAC(REWRITE_RULE[LIM_SEQUENTIALLY; dist]) THEN
15198 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I
15199 [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN
15200 DISCH_THEN(MP_TAC o SPEC
15201 `IMAGE (\n. { x | x IN s /\ norm((f:num->real^N->real^1) n x - g x) < e})
15203 REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN
15204 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
15205 REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE; SUBSET_UNION; UNIONS_IMAGE] THEN
15206 REWRITE_TAC[IN_UNIV; IN_ELIM_THM; EVENTUALLY_SEQUENTIALLY] THEN
15207 SIMP_TAC[SUBSET; IN_UNIV; IN_ELIM_THM] THEN ANTS_TAC THENL
15208 [CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LE_REFL]] THEN
15209 X_GEN_TAC `n:num` THEN REWRITE_TAC[GSYM IN_BALL_0] THEN
15210 MATCH_MP_TAC CONTINUOUS_OPEN_IN_PREIMAGE THEN
15211 ASM_SIMP_TAC[OPEN_BALL; CONTINUOUS_ON_SUB; ETA_AX];
15213 DISCH_THEN(X_CHOOSE_THEN `k:num->bool` (CONJUNCTS_THEN2
15214 (MP_TAC o SPEC `\n:num. n` o MATCH_MP UPPER_BOUND_FINITE_SET)
15215 (LABEL_TAC "*"))) THEN
15216 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
15217 REWRITE_TAC[] THEN STRIP_TAC THEN X_GEN_TAC `n:num` THEN
15218 DISCH_TAC THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
15219 REMOVE_THEN "*" (MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
15220 DISCH_THEN(X_CHOOSE_THEN `m:num` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
15221 REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB] THEN MATCH_MP_TAC(REAL_ARITH
15222 `m <= n /\ n <= g ==> abs(m - g) < e ==> abs(n - g) < e`) THEN
15223 ASM_MESON_TAC[LE_TRANS]]);;
15225 (* ------------------------------------------------------------------------- *)
15226 (* Closest point of a (closed) set to a point. *)
15227 (* ------------------------------------------------------------------------- *)
15229 let closest_point = new_definition
15230 `closest_point s a = @x. x IN s /\ !y. y IN s ==> dist(a,x) <= dist(a,y)`;;
15232 let CLOSEST_POINT_EXISTS = prove
15233 (`!s a. closed s /\ ~(s = {})
15234 ==> (closest_point s a) IN s /\
15235 !y. y IN s ==> dist(a,closest_point s a) <= dist(a,y)`,
15236 REWRITE_TAC[closest_point] THEN CONV_TAC(ONCE_DEPTH_CONV SELECT_CONV) THEN
15237 REWRITE_TAC[DISTANCE_ATTAINS_INF]);;
15239 let CLOSEST_POINT_IN_SET = prove
15240 (`!s a. closed s /\ ~(s = {}) ==> (closest_point s a) IN s`,
15241 MESON_TAC[CLOSEST_POINT_EXISTS]);;
15243 let CLOSEST_POINT_LE = prove
15244 (`!s a x. closed s /\ x IN s ==> dist(a,closest_point s a) <= dist(a,x)`,
15245 MESON_TAC[CLOSEST_POINT_EXISTS; MEMBER_NOT_EMPTY]);;
15247 let CLOSEST_POINT_SELF = prove
15248 (`!s x:real^N. x IN s ==> closest_point s x = x`,
15249 REPEAT STRIP_TAC THEN REWRITE_TAC[closest_point] THEN
15250 MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN GEN_TAC THEN EQ_TAC THENL
15251 [STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
15252 ASM_SIMP_TAC[DIST_LE_0; DIST_REFL];
15253 STRIP_TAC THEN ASM_REWRITE_TAC[DIST_REFL; DIST_POS_LE]]);;
15255 let CLOSEST_POINT_REFL = prove
15256 (`!s x:real^N. closed s /\ ~(s = {}) ==> (closest_point s x = x <=> x IN s)`,
15257 MESON_TAC[CLOSEST_POINT_IN_SET; CLOSEST_POINT_SELF]);;
15259 let DIST_CLOSEST_POINT_LIPSCHITZ = prove
15261 closed s /\ ~(s = {})
15262 ==> abs(dist(x,closest_point s x) - dist(y,closest_point s y))
15264 REPEAT GEN_TAC THEN DISCH_TAC THEN
15265 FIRST_ASSUM(MP_TAC o MATCH_MP CLOSEST_POINT_EXISTS) THEN
15266 DISCH_THEN(fun th ->
15267 CONJUNCTS_THEN2 ASSUME_TAC
15268 (MP_TAC o SPEC `closest_point s (y:real^N)`) (SPEC `x:real^N` th) THEN
15269 CONJUNCTS_THEN2 ASSUME_TAC
15270 (MP_TAC o SPEC `closest_point s (x:real^N)`) (SPEC `y:real^N` th)) THEN
15271 ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);;
15273 let CONTINUOUS_AT_DIST_CLOSEST_POINT = prove
15275 closed s /\ ~(s = {})
15276 ==> (\x. lift(dist(x,closest_point s x))) continuous (at x)`,
15277 REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_at; DIST_LIFT] THEN
15278 ASM_MESON_TAC[DIST_CLOSEST_POINT_LIPSCHITZ; REAL_LET_TRANS]);;
15280 let CONTINUOUS_ON_DIST_CLOSEST_POINT = prove
15281 (`!s t. closed s /\ ~(s = {})
15282 ==> (\x. lift(dist(x,closest_point s x))) continuous_on t`,
15283 MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON;
15284 CONTINUOUS_AT_DIST_CLOSEST_POINT]);;
15286 let UNIFORMLY_CONTINUOUS_ON_DIST_CLOSEST_POINT = prove
15287 (`!s t:real^N->bool.
15288 closed s /\ ~(s = {})
15289 ==> (\x. lift(dist(x,closest_point s x))) uniformly_continuous_on t`,
15290 REPEAT STRIP_TAC THEN REWRITE_TAC[uniformly_continuous_on; DIST_LIFT] THEN
15291 ASM_MESON_TAC[DIST_CLOSEST_POINT_LIPSCHITZ; REAL_LET_TRANS]);;
15293 let SEGMENT_TO_CLOSEST_POINT = prove
15295 closed s /\ ~(s = {})
15296 ==> segment(a,closest_point s a) INTER s = {}`,
15297 REPEAT STRIP_TAC THEN
15298 REWRITE_TAC[SET_RULE `s INTER t = {} <=> !x. x IN s ==> ~(x IN t)`] THEN
15299 GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP DIST_IN_OPEN_SEGMENT) THEN
15300 MATCH_MP_TAC(TAUT `(r ==> ~p) ==> p /\ q ==> ~r`) THEN
15301 ASM_MESON_TAC[CLOSEST_POINT_EXISTS; REAL_NOT_LT; DIST_SYM]);;
15303 let SEGMENT_TO_POINT_EXISTS = prove
15305 closed s /\ ~(s = {}) ==> ?b. b IN s /\ segment(a,b) INTER s = {}`,
15306 MESON_TAC[SEGMENT_TO_CLOSEST_POINT; CLOSEST_POINT_EXISTS]);;
15308 let CLOSEST_POINT_IN_INTERIOR = prove
15310 closed s /\ ~(s = {})
15311 ==> ((closest_point s x) IN interior s <=> x IN interior s)`,
15312 REPEAT STRIP_TAC THEN ASM_CASES_TAC `(x:real^N) IN s` THEN
15313 ASM_SIMP_TAC[CLOSEST_POINT_SELF] THEN
15314 MATCH_MP_TAC(TAUT `~q /\ ~p ==> (p <=> q)`) THEN
15315 CONJ_TAC THENL [ASM_MESON_TAC[INTERIOR_SUBSET; SUBSET]; STRIP_TAC] THEN
15316 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERIOR_CBALL]) THEN
15317 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
15318 SUBGOAL_THEN `closest_point s (x:real^N) IN s` ASSUME_TAC THENL
15319 [ASM_MESON_TAC[INTERIOR_SUBSET; SUBSET]; ALL_TAC] THEN
15320 SUBGOAL_THEN `~(closest_point s (x:real^N) = x)` ASSUME_TAC THENL
15321 [ASM_MESON_TAC[]; ALL_TAC] THEN
15322 MP_TAC(ISPECL [`s:real^N->bool`; `x:real^N`;
15323 `closest_point s x -
15324 (min (&1) (e / norm(closest_point s x - x))) %
15325 (closest_point s x - x):real^N`]
15326 CLOSEST_POINT_LE) THEN
15327 ASM_REWRITE_TAC[dist; NOT_IMP; VECTOR_ARITH
15328 `x - (y - e % (y - x)):real^N = (&1 - e) % (x - y)`] THEN
15330 [FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
15331 REWRITE_TAC[IN_CBALL; NORM_ARITH `dist(a:real^N,a - x) = norm x`] THEN
15332 REWRITE_TAC[NORM_MUL; REAL_ABS_DIV; REAL_ABS_NORM] THEN
15333 ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; NORM_POS_LT; VECTOR_SUB_EQ] THEN
15334 MATCH_MP_TAC(REAL_ARITH `&0 <= a ==> abs(min (&1) a) <= a`) THEN
15335 ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_DIV; NORM_POS_LE];
15336 REWRITE_TAC[NORM_MUL; REAL_ARITH
15337 `~(n <= a * n) <=> &0 < (&1 - a) * n`] THEN
15338 MATCH_MP_TAC REAL_LT_MUL THEN
15339 ASM_SIMP_TAC[NORM_POS_LT; VECTOR_SUB_EQ] THEN
15340 MATCH_MP_TAC(REAL_ARITH
15341 `&0 < e /\ e <= &1 ==> &0 < &1 - abs(&1 - e)`) THEN
15342 REWRITE_TAC[REAL_MIN_LE; REAL_LT_MIN; REAL_LT_01; REAL_LE_REFL] THEN
15343 ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ]]);;
15345 let CLOSEST_POINT_IN_FRONTIER = prove
15347 closed s /\ ~(s = {}) /\ ~(x IN interior s)
15348 ==> (closest_point s x) IN frontier s`,
15349 SIMP_TAC[frontier; IN_DIFF; CLOSEST_POINT_IN_INTERIOR] THEN
15350 SIMP_TAC[CLOSEST_POINT_IN_SET; CLOSURE_CLOSED]);;
15352 (* ------------------------------------------------------------------------- *)
15353 (* More general infimum of distance between two sets. *)
15354 (* ------------------------------------------------------------------------- *)
15356 let setdist = new_definition
15358 if s = {} \/ t = {} then &0
15359 else inf {dist(x,y) | x IN s /\ y IN t}`;;
15361 let SETDIST_EMPTY = prove
15362 (`(!t. setdist({},t) = &0) /\ (!s. setdist(s,{}) = &0)`,
15363 REWRITE_TAC[setdist]);;
15365 let SETDIST_POS_LE = prove
15366 (`!s t. &0 <= setdist(s,t)`,
15367 REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN
15368 COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN
15369 MATCH_MP_TAC REAL_LE_INF THEN
15370 REWRITE_TAC[FORALL_IN_GSPEC; DIST_POS_LE] THEN ASM SET_TAC[]);;
15372 let REAL_LE_SETDIST = prove
15373 (`!s t:real^N->bool d.
15374 ~(s = {}) /\ ~(t = {}) /\
15375 (!x y. x IN s /\ y IN t ==> d <= dist(x,y))
15376 ==> d <= setdist(s,t)`,
15377 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[setdist] THEN
15378 MP_TAC(ISPEC `{dist(x:real^N,y) | x IN s /\ y IN t}` INF) THEN
15379 REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL
15380 [CONJ_TAC THENL [ASM SET_TAC[]; MESON_TAC[DIST_POS_LE]]; ALL_TAC] THEN
15383 let SETDIST_LE_DIST = prove
15384 (`!s t x y:real^N. x IN s /\ y IN t ==> setdist(s,t) <= dist(x,y)`,
15385 REPEAT GEN_TAC THEN REWRITE_TAC[setdist] THEN
15386 COND_CASES_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
15387 MP_TAC(ISPEC `{dist(x:real^N,y) | x IN s /\ y IN t}` INF) THEN
15388 REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL
15389 [CONJ_TAC THENL [ASM SET_TAC[]; MESON_TAC[DIST_POS_LE]]; ALL_TAC] THEN
15392 let REAL_LE_SETDIST_EQ = prove
15393 (`!d s t:real^N->bool.
15394 d <= setdist(s,t) <=>
15395 (!x y. x IN s /\ y IN t ==> d <= dist(x,y)) /\
15396 (s = {} \/ t = {} ==> d <= &0)`,
15397 REPEAT GEN_TAC THEN MAP_EVERY ASM_CASES_TAC
15398 [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN
15399 ASM_REWRITE_TAC[SETDIST_EMPTY; NOT_IN_EMPTY] THEN
15400 ASM_MESON_TAC[REAL_LE_SETDIST; SETDIST_LE_DIST; REAL_LE_TRANS]);;
15402 let SETDIST_REFL = prove
15403 (`!s:real^N->bool. setdist(s,s) = &0`,
15404 GEN_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM; SETDIST_POS_LE] THEN
15405 ASM_CASES_TAC `s:real^N->bool = {}` THENL
15406 [ASM_REWRITE_TAC[setdist; REAL_LE_REFL]; ALL_TAC] THEN
15407 ASM_MESON_TAC[SETDIST_LE_DIST; MEMBER_NOT_EMPTY; DIST_REFL]);;
15409 let SETDIST_SYM = prove
15410 (`!s t. setdist(s,t) = setdist(t,s)`,
15411 REPEAT GEN_TAC THEN REWRITE_TAC[setdist; DISJ_SYM] THEN
15412 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
15413 AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
15414 MESON_TAC[DIST_SYM]);;
15416 let SETDIST_TRIANGLE = prove
15417 (`!s a t:real^N->bool.
15418 setdist(s,t) <= setdist(s,{a}) + setdist({a},t)`,
15419 REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN
15420 ASM_REWRITE_TAC[SETDIST_EMPTY; REAL_ADD_LID; SETDIST_POS_LE] THEN
15421 ASM_CASES_TAC `t:real^N->bool = {}` THEN
15422 ASM_REWRITE_TAC[SETDIST_EMPTY; REAL_ADD_RID; SETDIST_POS_LE] THEN
15423 ONCE_REWRITE_TAC[GSYM REAL_LE_SUB_RADD] THEN
15424 MATCH_MP_TAC REAL_LE_SETDIST THEN
15425 ASM_REWRITE_TAC[NOT_INSERT_EMPTY; IN_SING; IMP_CONJ;
15426 RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN
15427 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
15428 ONCE_REWRITE_TAC[REAL_ARITH `x - y <= z <=> x - z <= y`] THEN
15429 MATCH_MP_TAC REAL_LE_SETDIST THEN
15430 ASM_REWRITE_TAC[NOT_INSERT_EMPTY; IN_SING; IMP_CONJ;
15431 RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN
15432 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
15433 REWRITE_TAC[REAL_LE_SUB_RADD] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
15434 EXISTS_TAC `dist(x:real^N,y)` THEN
15435 ASM_SIMP_TAC[SETDIST_LE_DIST] THEN CONV_TAC NORM_ARITH);;
15437 let SETDIST_SINGS = prove
15438 (`!x y. setdist({x},{y}) = dist(x,y)`,
15439 REWRITE_TAC[setdist; NOT_INSERT_EMPTY] THEN
15440 REWRITE_TAC[SET_RULE `{f x y | x IN {a} /\ y IN {b}} = {f a b}`] THEN
15441 SIMP_TAC[INF_INSERT_FINITE; FINITE_EMPTY]);;
15443 let SETDIST_LIPSCHITZ = prove
15444 (`!s t x y:real^N. abs(setdist({x},s) - setdist({y},s)) <= dist(x,y)`,
15445 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM SETDIST_SINGS] THEN
15446 REWRITE_TAC[REAL_ARITH
15447 `abs(x - y) <= z <=> x <= z + y /\ y <= z + x`] THEN
15448 MESON_TAC[SETDIST_TRIANGLE; SETDIST_SYM]);;
15450 let CONTINUOUS_AT_LIFT_SETDIST = prove
15451 (`!s x:real^N. (\y. lift(setdist({y},s))) continuous (at x)`,
15452 REPEAT STRIP_TAC THEN REWRITE_TAC[continuous_at; DIST_LIFT] THEN
15453 ASM_MESON_TAC[SETDIST_LIPSCHITZ; REAL_LET_TRANS]);;
15455 let CONTINUOUS_ON_LIFT_SETDIST = prove
15456 (`!s t:real^N->bool. (\y. lift(setdist({y},s))) continuous_on t`,
15457 MESON_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON;
15458 CONTINUOUS_AT_LIFT_SETDIST]);;
15460 let UNIFORMLY_CONTINUOUS_ON_LIFT_SETDIST = prove
15461 (`!s t:real^N->bool.
15462 (\y. lift(setdist({y},s))) uniformly_continuous_on t`,
15463 REPEAT GEN_TAC THEN REWRITE_TAC[uniformly_continuous_on; DIST_LIFT] THEN
15464 ASM_MESON_TAC[SETDIST_LIPSCHITZ; REAL_LET_TRANS]);;
15466 let SETDIST_DIFFERENCES = prove
15467 (`!s t. setdist(s,t) = setdist({vec 0},{x - y:real^N | x IN s /\ y IN t})`,
15468 REPEAT GEN_TAC THEN REWRITE_TAC[setdist; NOT_INSERT_EMPTY;
15469 SET_RULE `{f x y | x IN s /\ y IN t} = {} <=> s = {} \/ t = {}`] THEN
15470 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN AP_TERM_TAC THEN
15471 REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_SING] THEN
15472 REWRITE_TAC[GSYM CONJ_ASSOC; RIGHT_EXISTS_AND_THM; UNWIND_THM2; DIST_0] THEN
15473 REWRITE_TAC[dist] THEN MESON_TAC[]);;
15475 let SETDIST_SUBSET_RIGHT = prove
15476 (`!s t u:real^N->bool.
15477 ~(t = {}) /\ t SUBSET u ==> setdist(s,u) <= setdist(s,t)`,
15478 REPEAT STRIP_TAC THEN
15479 MAP_EVERY ASM_CASES_TAC [`s:real^N->bool = {}`; `u:real^N->bool = {}`] THEN
15480 ASM_REWRITE_TAC[SETDIST_EMPTY; SETDIST_POS_LE; REAL_LE_REFL] THEN
15481 ASM_REWRITE_TAC[setdist] THEN MATCH_MP_TAC REAL_LE_INF_SUBSET THEN
15482 ASM_REWRITE_TAC[FORALL_IN_GSPEC; SUBSET] THEN
15483 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
15484 MESON_TAC[DIST_POS_LE]);;
15486 let SETDIST_SUBSET_LEFT = prove
15487 (`!s t u:real^N->bool.
15488 ~(s = {}) /\ s SUBSET t ==> setdist(t,u) <= setdist(s,u)`,
15489 MESON_TAC[SETDIST_SUBSET_RIGHT; SETDIST_SYM]);;
15491 let SETDIST_CLOSURE = prove
15492 (`(!s t:real^N->bool. setdist(closure s,t) = setdist(s,t)) /\
15493 (!s t:real^N->bool. setdist(s,closure t) = setdist(s,t))`,
15494 GEN_REWRITE_TAC RAND_CONV [SWAP_FORALL_THM] THEN
15495 GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [SETDIST_SYM] THEN
15497 REWRITE_TAC[MESON[REAL_LE_ANTISYM]
15498 `x:real = y <=> !d. d <= x <=> d <= y`] THEN
15499 REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN
15500 MAP_EVERY ASM_CASES_TAC [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN
15501 ASM_REWRITE_TAC[CLOSURE_EQ_EMPTY; CLOSURE_EMPTY; NOT_IN_EMPTY] THEN
15502 MATCH_MP_TAC(SET_RULE
15504 (!y. Q y /\ (!x. x IN s ==> P x y) ==> (!x. x IN c ==> P x y))
15505 ==> ((!x y. x IN c /\ Q y ==> P x y) <=>
15506 (!x y. x IN s /\ Q y ==> P x y))`) THEN
15507 REWRITE_TAC[CLOSURE_SUBSET] THEN GEN_TAC THEN STRIP_TAC THEN
15508 MATCH_MP_TAC CONTINUOUS_GE_ON_CLOSURE THEN
15509 ASM_REWRITE_TAC[o_DEF; dist] THEN
15510 MATCH_MP_TAC CONTINUOUS_ON_LIFT_NORM_COMPOSE THEN
15511 SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID]);;
15513 let SETDIST_COMPACT_CLOSED = prove
15514 (`!s t:real^N->bool.
15515 compact s /\ closed t /\ ~(s = {}) /\ ~(t = {})
15516 ==> ?x y. x IN s /\ y IN t /\ dist(x,y) = setdist(s,t)`,
15517 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
15518 MATCH_MP_TAC(MESON[]
15519 `(!x y. P x /\ Q y ==> S x y) /\ (?x y. P x /\ Q y /\ R x y)
15520 ==> ?x y. P x /\ Q y /\ R x y /\ S x y`) THEN
15521 SIMP_TAC[SETDIST_LE_DIST] THEN
15522 ASM_REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN
15523 MP_TAC(ISPECL [`{x - y:real^N | x IN s /\ y IN t}`; `vec 0:real^N`]
15524 DISTANCE_ATTAINS_INF) THEN
15525 ASM_SIMP_TAC[COMPACT_CLOSED_DIFFERENCES; EXISTS_IN_GSPEC; FORALL_IN_GSPEC;
15526 DIST_0; GSYM CONJ_ASSOC] THEN
15527 REWRITE_TAC[dist] THEN DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[]);;
15529 let SETDIST_CLOSED_COMPACT = prove
15530 (`!s t:real^N->bool.
15531 closed s /\ compact t /\ ~(s = {}) /\ ~(t = {})
15532 ==> ?x y. x IN s /\ y IN t /\ dist(x,y) = setdist(s,t)`,
15533 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN
15534 MATCH_MP_TAC(MESON[]
15535 `(!x y. P x /\ Q y ==> S x y) /\ (?x y. P x /\ Q y /\ R x y)
15536 ==> ?x y. P x /\ Q y /\ R x y /\ S x y`) THEN
15537 SIMP_TAC[SETDIST_LE_DIST] THEN
15538 ASM_REWRITE_TAC[REAL_LE_SETDIST_EQ] THEN
15539 MP_TAC(ISPECL [`{x - y:real^N | x IN s /\ y IN t}`; `vec 0:real^N`]
15540 DISTANCE_ATTAINS_INF) THEN
15541 ASM_SIMP_TAC[CLOSED_COMPACT_DIFFERENCES; EXISTS_IN_GSPEC; FORALL_IN_GSPEC;
15542 DIST_0; GSYM CONJ_ASSOC] THEN
15543 REWRITE_TAC[dist] THEN DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[]);;
15545 let SETDIST_EQ_0_COMPACT_CLOSED = prove
15546 (`!s t:real^N->bool.
15547 compact s /\ closed t
15548 ==> (setdist(s,t) = &0 <=> s = {} \/ t = {} \/ ~(s INTER t = {}))`,
15549 REPEAT STRIP_TAC THEN
15550 MAP_EVERY ASM_CASES_TAC [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN
15551 ASM_REWRITE_TAC[SETDIST_EMPTY] THEN EQ_TAC THENL
15552 [MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`]
15553 SETDIST_COMPACT_CLOSED) THEN ASM_REWRITE_TAC[] THEN
15554 REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN MESON_TAC[DIST_EQ_0];
15555 REWRITE_TAC[GSYM REAL_LE_ANTISYM; SETDIST_POS_LE] THEN
15556 REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN
15557 MESON_TAC[SETDIST_LE_DIST; DIST_EQ_0]]);;
15559 let SETDIST_EQ_0_CLOSED_COMPACT = prove
15560 (`!s t:real^N->bool.
15561 closed s /\ compact t
15562 ==> (setdist(s,t) = &0 <=> s = {} \/ t = {} \/ ~(s INTER t = {}))`,
15563 ONCE_REWRITE_TAC[SETDIST_SYM] THEN
15564 SIMP_TAC[SETDIST_EQ_0_COMPACT_CLOSED] THEN SET_TAC[]);;
15566 let SETDIST_EQ_0_BOUNDED = prove
15567 (`!s t:real^N->bool.
15568 (bounded s \/ bounded t)
15569 ==> (setdist(s,t) = &0 <=>
15570 s = {} \/ t = {} \/ ~(closure(s) INTER closure(t) = {}))`,
15571 REPEAT GEN_TAC THEN
15572 MAP_EVERY ASM_CASES_TAC [`s:real^N->bool = {}`; `t:real^N->bool = {}`] THEN
15573 ASM_REWRITE_TAC[SETDIST_EMPTY] THEN STRIP_TAC THEN
15574 ONCE_REWRITE_TAC[MESON[SETDIST_CLOSURE]
15575 `setdist(s,t) = setdist(closure s,closure t)`] THEN
15576 ASM_SIMP_TAC[SETDIST_EQ_0_COMPACT_CLOSED; SETDIST_EQ_0_CLOSED_COMPACT;
15577 COMPACT_CLOSURE; CLOSED_CLOSURE; CLOSURE_EQ_EMPTY]);;
15580 let SETDIST_TRANSLATION = prove
15582 setdist(IMAGE (\x. a + x) s,IMAGE (\x. a + x) t) = setdist(s,t)`,
15583 REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[SETDIST_DIFFERENCES] THEN
15584 AP_TERM_TAC THEN AP_TERM_TAC THEN
15585 REWRITE_TAC[SET_RULE
15586 `{f x y | x IN IMAGE g s /\ y IN IMAGE g t} =
15587 {f (g x) (g y) | x IN s /\ y IN t}`] THEN
15588 REWRITE_TAC[VECTOR_ARITH `(a + x) - (a + y):real^N = x - y`]);;
15590 add_translation_invariants [SETDIST_TRANSLATION];;
15592 let SETDIST_LINEAR_IMAGE = prove
15593 (`!f:real^M->real^N s t.
15594 linear f /\ (!x. norm(f x) = norm x)
15595 ==> setdist(IMAGE f s,IMAGE f t) = setdist(s,t)`,
15596 REPEAT STRIP_TAC THEN REWRITE_TAC[setdist; IMAGE_EQ_EMPTY] THEN
15597 COND_CASES_TAC THEN ASM_REWRITE_TAC[dist] THEN AP_TERM_TAC THEN
15598 REWRITE_TAC[SET_RULE
15599 `{f x y | x IN IMAGE g s /\ y IN IMAGE g t} =
15600 {f (g x) (g y) | x IN s /\ y IN t}`] THEN
15601 FIRST_X_ASSUM(fun th -> REWRITE_TAC[GSYM(MATCH_MP LINEAR_SUB th)]) THEN
15602 ASM_REWRITE_TAC[]);;
15604 add_linear_invariants [SETDIST_LINEAR_IMAGE];;
15606 let SETDIST_UNIQUE = prove
15607 (`!s t a b:real^N d.
15608 a IN s /\ b IN t /\ dist(a,b) = d /\
15609 (!x y. x IN s /\ y IN t ==> dist(a,b) <= dist(x,y))
15610 ==> setdist(s,t) = d`,
15611 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
15612 [ASM_MESON_TAC[SETDIST_LE_DIST];
15613 MATCH_MP_TAC REAL_LE_SETDIST THEN ASM SET_TAC[]]);;
15615 let SETDIST_CLOSEST_POINT = prove
15617 closed s /\ ~(s = {}) ==> setdist({a},s) = dist(a,closest_point s a)`,
15618 REPEAT STRIP_TAC THEN MATCH_MP_TAC SETDIST_UNIQUE THEN
15619 REWRITE_TAC[RIGHT_EXISTS_AND_THM; IN_SING; UNWIND_THM2] THEN
15620 EXISTS_TAC `closest_point s (a:real^N)` THEN
15621 ASM_MESON_TAC[CLOSEST_POINT_EXISTS; DIST_SYM]);;
15623 let SETDIST_EQ_0_SING = prove
15624 (`(!s x:real^N. setdist({x},s) = &0 <=> s = {} \/ x IN closure s) /\
15625 (!s x:real^N. setdist(s,{x}) = &0 <=> s = {} \/ x IN closure s)`,
15626 SIMP_TAC[SETDIST_EQ_0_BOUNDED; BOUNDED_SING; CLOSURE_SING] THEN SET_TAC[]);;
15628 (* ------------------------------------------------------------------------- *)
15629 (* Use set distance for an easy proof of separation properties. *)
15630 (* ------------------------------------------------------------------------- *)
15632 let SEPARATION_CLOSURES = prove
15633 (`!s t:real^N->bool.
15634 s INTER closure(t) = {} /\ t INTER closure(s) = {}
15635 ==> ?u v. DISJOINT u v /\ open u /\ open v /\
15636 s SUBSET u /\ t SUBSET v`,
15637 REPEAT STRIP_TAC THEN
15638 ASM_CASES_TAC `s:real^N->bool = {}` THENL
15639 [MAP_EVERY EXISTS_TAC [`{}:real^N->bool`; `(:real^N)`] THEN
15640 ASM_REWRITE_TAC[OPEN_EMPTY; OPEN_UNIV] THEN ASM SET_TAC[];
15642 ASM_CASES_TAC `t:real^N->bool = {}` THENL
15643 [MAP_EVERY EXISTS_TAC [`(:real^N)`; `{}:real^N->bool`] THEN
15644 ASM_REWRITE_TAC[OPEN_EMPTY; OPEN_UNIV] THEN ASM SET_TAC[];
15646 EXISTS_TAC `{x | x IN (:real^N) /\
15647 lift(setdist({x},t) - setdist({x},s)) IN
15648 {x | &0 < x$1}}` THEN
15649 EXISTS_TAC `{x | x IN (:real^N) /\
15650 lift(setdist({x},t) - setdist({x},s)) IN
15651 {x | x$1 < &0}}` THEN
15652 REPEAT CONJ_TAC THENL
15653 [REWRITE_TAC[SET_RULE `DISJOINT s t <=> !x. x IN s /\ x IN t ==> F`] THEN
15654 REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN REAL_ARITH_TAC;
15655 MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE THEN
15656 SIMP_TAC[REWRITE_RULE[real_gt] OPEN_HALFSPACE_COMPONENT_GT; OPEN_UNIV] THEN
15657 SIMP_TAC[LIFT_SUB; CONTINUOUS_ON_SUB; CONTINUOUS_ON_LIFT_SETDIST];
15658 MATCH_MP_TAC CONTINUOUS_OPEN_PREIMAGE THEN
15659 SIMP_TAC[OPEN_HALFSPACE_COMPONENT_LT; OPEN_UNIV] THEN
15660 SIMP_TAC[LIFT_SUB; CONTINUOUS_ON_SUB; CONTINUOUS_ON_LIFT_SETDIST];
15661 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNIV; GSYM drop; LIFT_DROP] THEN
15662 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH
15663 `&0 <= x /\ y = &0 /\ ~(x = &0) ==> &0 < x - y`);
15664 REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNIV; GSYM drop; LIFT_DROP] THEN
15665 GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH
15666 `&0 <= y /\ x = &0 /\ ~(y = &0) ==> x - y < &0`)] THEN
15667 ASM_SIMP_TAC[SETDIST_POS_LE; SETDIST_EQ_0_BOUNDED; BOUNDED_SING] THEN
15668 ASM_SIMP_TAC[CLOSED_SING; CLOSURE_CLOSED; NOT_INSERT_EMPTY;
15669 REWRITE_RULE[SUBSET] CLOSURE_SUBSET;
15670 SET_RULE `{a} INTER s = {} <=> ~(a IN s)`] THEN
15673 let SEPARATION_NORMAL = prove
15674 (`!s t:real^N->bool.
15675 closed s /\ closed t /\ s INTER t = {}
15676 ==> ?u v. open u /\ open v /\
15677 s SUBSET u /\ t SUBSET v /\ u INTER v = {}`,
15678 REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM DISJOINT] THEN
15679 ONCE_REWRITE_TAC[TAUT
15680 `a /\ b /\ c /\ d /\ e <=> e /\ a /\ b /\ c /\ d`] THEN
15681 MATCH_MP_TAC SEPARATION_CLOSURES THEN
15682 ASM_SIMP_TAC[CLOSURE_CLOSED] THEN ASM SET_TAC[]);;
15684 let SEPARATION_NORMAL_COMPACT = prove
15685 (`!s t:real^N->bool.
15686 compact s /\ closed t /\ s INTER t = {}
15687 ==> ?u v. open u /\ compact(closure u) /\ open v /\
15688 s SUBSET u /\ t SUBSET v /\ u INTER v = {}`,
15689 REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED; CLOSED_CLOSURE] THEN
15690 REPEAT STRIP_TAC THEN FIRST_ASSUM
15691 (MP_TAC o SPEC `vec 0:real^N` o MATCH_MP BOUNDED_SUBSET_BALL) THEN
15692 DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN
15693 MP_TAC(ISPECL [`s:real^N->bool`; `t UNION ((:real^N) DIFF ball(vec 0,r))`]
15694 SEPARATION_NORMAL) THEN
15695 ASM_SIMP_TAC[CLOSED_UNION; GSYM OPEN_CLOSED; OPEN_BALL] THEN
15696 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
15697 REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
15698 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
15699 CONJ_TAC THENL [MATCH_MP_TAC BOUNDED_CLOSURE; ASM SET_TAC[]] THEN
15700 MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC `ball(vec 0:real^N,r)` THEN
15701 REWRITE_TAC[BOUNDED_BALL] THEN ASM SET_TAC[]);;
15703 let SEPARATION_HAUSDORFF = prove
15706 ==> ?u v. open u /\ open v /\ x IN u /\ y IN v /\ (u INTER v = {})`,
15707 REPEAT STRIP_TAC THEN
15708 MP_TAC(SPECL [`{x:real^N}`; `{y:real^N}`] SEPARATION_NORMAL) THEN
15709 REWRITE_TAC[SING_SUBSET; CLOSED_SING] THEN
15710 DISCH_THEN MATCH_MP_TAC THEN ASM SET_TAC[]);;
15712 let SEPARATION_T2 = prove
15714 ~(x = y) <=> ?u v. open u /\ open v /\ x IN u /\ y IN v /\
15716 REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[SEPARATION_HAUSDORFF] THEN
15717 REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY] THEN MESON_TAC[]);;
15719 let SEPARATION_T1 = prove
15721 ~(x = y) <=> ?u v. open u /\ open v /\ x IN u /\ ~(y IN u) /\
15722 ~(x IN v) /\ y IN v`,
15723 REPEAT STRIP_TAC THEN EQ_TAC THENL
15724 [ASM_SIMP_TAC[SEPARATION_T2; EXTENSION; NOT_IN_EMPTY; IN_INTER];
15725 ALL_TAC] THEN MESON_TAC[]);;
15727 let SEPARATION_T0 = prove
15728 (`!x:real^N y. ~(x = y) <=> ?u. open u /\ ~(x IN u <=> y IN u)`,
15729 MESON_TAC[SEPARATION_T1]);;
15731 let CLOSED_COMPACT_PROJECTION = prove
15732 (`!s:real^M->bool t:real^(M,N)finite_sum->bool.
15733 compact s /\ closed t
15734 ==> closed {y | ?x. x IN s /\ (pastecart x y) IN t}`,
15735 REPEAT STRIP_TAC THEN
15736 ASM_CASES_TAC `s:real^M->bool = {}` THEN
15737 ASM_CASES_TAC `t:real^(M,N)finite_sum->bool = {}` THEN
15738 ASM_REWRITE_TAC[NOT_IN_EMPTY; EMPTY_GSPEC; CLOSED_EMPTY] THEN
15739 REWRITE_TAC[closed; open_def; IN_DIFF; IN_UNIV; IN_ELIM_THM] THEN
15740 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
15741 EXISTS_TAC `setdist({pastecart (x:real^M) (y:real^N) | x IN s},t)` THEN
15743 [REWRITE_TAC[REAL_LT_LE; SETDIST_POS_LE] THEN
15744 ONCE_REWRITE_TAC[EQ_SYM_EQ] THEN
15745 W(MP_TAC o PART_MATCH (lhs o rand) SETDIST_EQ_0_COMPACT_CLOSED o
15748 [REWRITE_TAC[SET_RULE
15749 `{pastecart x y | P x} = {pastecart x z | P x /\ z IN {y}}`] THEN
15750 REWRITE_TAC[GSYM PCROSS] THEN
15751 ASM_SIMP_TAC[COMPACT_PCROSS; COMPACT_SING];
15752 DISCH_THEN SUBST1_TAC THEN ASM_REWRITE_TAC[] THEN ASM SET_TAC[]];
15753 X_GEN_TAC `z:real^N` THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
15754 REWRITE_TAC[REAL_NOT_LT] THEN
15755 DISCH_THEN(X_CHOOSE_THEN `w:real^M` STRIP_ASSUME_TAC) THEN
15756 MATCH_MP_TAC REAL_LE_TRANS THEN
15757 EXISTS_TAC `dist(pastecart (w:real^M) (y:real^N),pastecart w z)` THEN
15759 [MATCH_MP_TAC SETDIST_LE_DIST THEN ASM SET_TAC[];
15760 REWRITE_TAC[DIST_PASTECART_CANCEL; REAL_LE_REFL; DIST_SYM]]]);;
15762 let CLOSED_IN_COMPACT_PROJECTION = prove
15763 (`!s:real^M->bool t:real^N->bool u.
15765 closed_in (subtopology euclidean (s PCROSS t)) u
15766 ==> closed_in (subtopology euclidean t)
15767 {y | ?x. x IN s /\ pastecart x y IN u}`,
15768 REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS; CLOSED_IN_CLOSED] THEN
15769 REWRITE_TAC[RIGHT_AND_EXISTS_THM; CONJ_ASSOC] THEN
15770 DISCH_THEN(CHOOSE_THEN(CONJUNCTS_THEN2 MP_TAC SUBST1_TAC)) THEN
15771 DISCH_THEN(MP_TAC o MATCH_MP CLOSED_COMPACT_PROJECTION) THEN
15772 MATCH_MP_TAC(MESON[]
15773 `P p==> (closed p ==> ?t. closed t /\ P t)`) THEN
15774 REWRITE_TAC[IN_ELIM_PASTECART_THM; IN_INTER] THEN SET_TAC[]);;
15776 let TUBE_LEMMA = prove
15777 (`!s:real^M->bool t:real^N->bool u a.
15778 compact s /\ ~(s = {}) /\ {pastecart x a | x IN s} SUBSET u /\
15779 open_in(subtopology euclidean (s PCROSS t)) u
15780 ==> ?v. open_in (subtopology euclidean t) v /\ a IN v /\
15781 (s PCROSS v) SUBSET u`,
15782 REPEAT GEN_TAC THEN REWRITE_TAC[PCROSS] THEN
15783 REWRITE_TAC[OPEN_IN_CLOSED_IN_EQ] THEN
15784 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
15785 REPEAT STRIP_TAC THEN
15786 FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT; PCROSS]
15787 CLOSED_IN_COMPACT_PROJECTION)) THEN
15788 ASM_REWRITE_TAC[IN_ELIM_PASTECART_THM; IN_DIFF] THEN
15789 REWRITE_TAC[GSYM CONJ_ASSOC] THEN MATCH_MP_TAC(MESON[]
15790 `(closed_in top t ==> s DIFF (s DIFF t) = t) /\
15791 s DIFF t SUBSET s /\ P(s DIFF t)
15792 ==> closed_in top t
15793 ==> ?v. v SUBSET s /\ closed_in top (s DIFF v) /\ P v`) THEN
15794 REWRITE_TAC[SET_RULE `s DIFF (s DIFF t) = t <=> t SUBSET s`] THEN
15795 REWRITE_TAC[SUBSET_DIFF] THEN
15796 SIMP_TAC[closed_in; TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN
15797 REWRITE_TAC[IN_DIFF; IN_ELIM_THM] THEN
15798 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN
15799 CONJ_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
15800 REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET])) THEN
15801 REWRITE_TAC[FORALL_IN_GSPEC; IN_SING; FORALL_PASTECART] THEN
15802 REWRITE_TAC[IN_ELIM_PASTECART_THM] THEN ASM_MESON_TAC[MEMBER_NOT_EMPTY]);;
15804 (* ------------------------------------------------------------------------- *)
15805 (* Urysohn's lemma (for real^N, where the proof is easy using distances). *)
15806 (* ------------------------------------------------------------------------- *)
15808 let URYSOHN_LOCAL_STRONG = prove
15810 closed_in (subtopology euclidean u) s /\
15811 closed_in (subtopology euclidean u) t /\
15812 s INTER t = {} /\ ~(a = b)
15813 ==> ?f:real^N->real^M.
15814 f continuous_on u /\
15815 (!x. x IN u ==> f(x) IN segment[a,b]) /\
15816 (!x. x IN u ==> (f x = a <=> x IN s)) /\
15817 (!x. x IN u ==> (f x = b <=> x IN t))`,
15820 closed_in (subtopology euclidean u) s /\
15821 closed_in (subtopology euclidean u) t /\
15822 s INTER t = {} /\ ~(s = {}) /\ ~(t = {}) /\ ~(a = b)
15823 ==> ?f:real^N->real^M.
15824 f continuous_on u /\
15825 (!x. x IN u ==> f(x) IN segment[a,b]) /\
15826 (!x. x IN u ==> (f x = a <=> x IN s)) /\
15827 (!x. x IN u ==> (f x = b <=> x IN t))`,
15828 REPEAT STRIP_TAC THEN EXISTS_TAC
15829 `\x:real^N. a + setdist({x},s) / (setdist({x},s) + setdist({x},t)) %
15830 (b - a:real^M)` THEN REWRITE_TAC[] THEN
15832 `(!x:real^N. x IN u ==> (setdist({x},s) = &0 <=> x IN s)) /\
15833 (!x:real^N. x IN u ==> (setdist({x},t) = &0 <=> x IN t))`
15834 STRIP_ASSUME_TAC THENL
15835 [ASM_REWRITE_TAC[SETDIST_EQ_0_SING] THEN CONJ_TAC THENL
15836 [MP_TAC(ISPEC `s:real^N->bool` CLOSED_IN_CLOSED);
15837 MP_TAC(ISPEC `t:real^N->bool` CLOSED_IN_CLOSED)] THEN
15838 DISCH_THEN(MP_TAC o SPEC `u:real^N->bool`) THEN
15839 ASM_REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_THEN `v:real^N->bool`
15840 (CONJUNCTS_THEN2 ASSUME_TAC SUBST_ALL_TAC)) THEN
15841 ASM_MESON_TAC[CLOSURE_CLOSED; INTER_SUBSET; SUBSET_CLOSURE; SUBSET;
15842 IN_INTER; CLOSURE_SUBSET];
15844 SUBGOAL_THEN `!x:real^N. x IN u ==> &0 < setdist({x},s) + setdist({x},t)`
15846 [REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH
15847 `&0 <= x /\ &0 <= y /\ ~(x = &0 /\ y = &0) ==> &0 < x + y`) THEN
15848 REWRITE_TAC[SETDIST_POS_LE] THEN ASM SET_TAC[];
15850 REPEAT CONJ_TAC THENL
15851 [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
15852 REWRITE_TAC[real_div; GSYM VECTOR_MUL_ASSOC] THEN
15853 REPEAT(MATCH_MP_TAC CONTINUOUS_ON_MUL THEN CONJ_TAC) THEN
15854 REWRITE_TAC[CONTINUOUS_ON_CONST; o_DEF] THEN
15855 REWRITE_TAC[CONTINUOUS_ON_LIFT_SETDIST] THEN
15856 MATCH_MP_TAC(REWRITE_RULE[o_DEF] CONTINUOUS_ON_INV) THEN
15857 ASM_SIMP_TAC[REAL_LT_IMP_NZ] THEN
15858 REWRITE_TAC[LIFT_ADD] THEN MATCH_MP_TAC CONTINUOUS_ON_ADD THEN
15859 REWRITE_TAC[CONTINUOUS_ON_LIFT_SETDIST];
15860 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
15861 REWRITE_TAC[segment; IN_ELIM_THM] THEN
15862 REWRITE_TAC[VECTOR_MUL_EQ_0; LEFT_OR_DISTRIB; VECTOR_ARITH
15863 `a + x % (b - a):real^N = (&1 - u) % a + u % b <=>
15864 (x - u) % (b - a) = vec 0`;
15865 EXISTS_OR_THM] THEN
15866 DISJ1_TAC THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
15867 REWRITE_TAC[REAL_SUB_0; UNWIND_THM1] THEN
15868 ASM_SIMP_TAC[REAL_LE_DIV; REAL_LE_ADD; SETDIST_POS_LE; REAL_LE_LDIV_EQ;
15869 REAL_ARITH `a <= &1 * (a + b) <=> &0 <= b`];
15870 REWRITE_TAC[VECTOR_ARITH `a + x:real^N = a <=> x = vec 0`];
15871 REWRITE_TAC[VECTOR_ARITH `a + x % (b - a):real^N = b <=>
15872 (x - &1) % (b - a) = vec 0`]] THEN
15873 ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ] THEN
15874 ASM_SIMP_TAC[REAL_SUB_0; REAL_EQ_LDIV_EQ;
15875 REAL_MUL_LZERO; REAL_MUL_LID] THEN
15876 REWRITE_TAC[REAL_ARITH `x:real = x + y <=> y = &0`] THEN
15877 ASM_REWRITE_TAC[]) in
15878 MATCH_MP_TAC(MESON[]
15879 `(!s t. P s t <=> P t s) /\
15880 (!s t. ~(s = {}) /\ ~(t = {}) ==> P s t) /\
15881 P {} {} /\ (!t. ~(t = {}) ==> P {} t)
15882 ==> !s t. P s t`) THEN
15883 REPEAT CONJ_TAC THENL
15884 [REPEAT GEN_TAC THEN
15885 GEN_REWRITE_TAC (RAND_CONV o BINDER_CONV) [SWAP_FORALL_THM] THEN
15886 REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
15887 REWRITE_TAC[SEGMENT_SYM; INTER_COMM; CONJ_ACI; EQ_SYM_EQ];
15889 REPEAT STRIP_TAC THEN EXISTS_TAC `(\x. midpoint(a,b)):real^N->real^M` THEN
15890 ASM_SIMP_TAC[NOT_IN_EMPTY; CONTINUOUS_ON_CONST; MIDPOINT_IN_SEGMENT] THEN
15891 REWRITE_TAC[midpoint] THEN CONJ_TAC THEN GEN_TAC THEN DISCH_TAC THEN
15892 UNDISCH_TAC `~(a:real^M = b)` THEN REWRITE_TAC[CONTRAPOS_THM] THEN
15894 REPEAT STRIP_TAC THEN ASM_CASES_TAC `t:real^N->bool = u` THENL
15895 [EXISTS_TAC `(\x. b):real^N->real^M` THEN
15896 ASM_REWRITE_TAC[NOT_IN_EMPTY; ENDS_IN_SEGMENT; IN_UNIV;
15897 CONTINUOUS_ON_CONST];
15898 SUBGOAL_THEN `?c:real^N. c IN u /\ ~(c IN t)` STRIP_ASSUME_TAC THENL
15899 [REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET)) THEN
15900 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN ASM SET_TAC[];
15902 MP_TAC(ISPECL [`{c:real^N}`; `t:real^N->bool`; `u:real^N->bool`;
15903 `midpoint(a,b):real^M`; `b:real^M`] lemma) THEN
15904 ASM_REWRITE_TAC[CLOSED_IN_SING; MIDPOINT_EQ_ENDPOINT] THEN
15905 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
15906 MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[NOT_IN_EMPTY] THEN
15907 X_GEN_TAC `f:real^N->real^M` THEN STRIP_TAC THEN CONJ_TAC THENL
15909 `segment[midpoint(a,b):real^M,b] SUBSET segment[a,b]` MP_TAC
15911 [REWRITE_TAC[SUBSET; IN_SEGMENT; midpoint] THEN GEN_TAC THEN
15912 DISCH_THEN(X_CHOOSE_THEN `u:real` STRIP_ASSUME_TAC) THEN
15913 EXISTS_TAC `(&1 + u) / &2` THEN ASM_REWRITE_TAC[] THEN
15914 REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
15917 SUBGOAL_THEN `~(a IN segment[midpoint(a,b):real^M,b])` MP_TAC THENL
15918 [ALL_TAC; ASM_MESON_TAC[]] THEN
15919 DISCH_THEN(MP_TAC o CONJUNCT2 o MATCH_MP DIST_IN_CLOSED_SEGMENT) THEN
15920 REWRITE_TAC[DIST_MIDPOINT] THEN
15921 UNDISCH_TAC `~(a:real^M = b)` THEN NORM_ARITH_TAC]]]);;
15923 let URYSOHN_LOCAL = prove
15925 closed_in (subtopology euclidean u) s /\
15926 closed_in (subtopology euclidean u) t /\
15928 ==> ?f:real^N->real^M.
15929 f continuous_on u /\
15930 (!x. x IN u ==> f(x) IN segment[a,b]) /\
15931 (!x. x IN s ==> f x = a) /\
15932 (!x. x IN t ==> f x = b)`,
15933 REPEAT STRIP_TAC THEN ASM_CASES_TAC `a:real^M = b` THENL
15934 [EXISTS_TAC `(\x. b):real^N->real^M` THEN
15935 ASM_REWRITE_TAC[ENDS_IN_SEGMENT; CONTINUOUS_ON_CONST];
15936 MP_TAC(ISPECL [`s:real^N->bool`; `t:real^N->bool`; `u:real^N->bool`;
15937 `a:real^M`; `b:real^M`] URYSOHN_LOCAL_STRONG) THEN
15938 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN
15939 REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_SUBSET)) THEN
15940 REWRITE_TAC[TOPSPACE_EUCLIDEAN_SUBTOPOLOGY] THEN SET_TAC[]]);;
15942 let URYSOHN_STRONG = prove
15944 closed s /\ closed t /\ s INTER t = {} /\ ~(a = b)
15945 ==> ?f:real^N->real^M.
15946 f continuous_on (:real^N) /\ (!x. f(x) IN segment[a,b]) /\
15947 (!x. f x = a <=> x IN s) /\ (!x. f x = b <=> x IN t)`,
15948 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN] THEN
15949 ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN
15950 DISCH_THEN(MP_TAC o MATCH_MP URYSOHN_LOCAL_STRONG) THEN
15951 REWRITE_TAC[IN_UNIV]);;
15953 let URYSOHN = prove
15955 closed s /\ closed t /\ s INTER t = {}
15956 ==> ?f:real^N->real^M.
15957 f continuous_on (:real^N) /\ (!x. f(x) IN segment[a,b]) /\
15958 (!x. x IN s ==> f x = a) /\ (!x. x IN t ==> f x = b)`,
15959 REPEAT GEN_TAC THEN REWRITE_TAC[CLOSED_IN] THEN
15960 ONCE_REWRITE_TAC[GSYM SUBTOPOLOGY_UNIV] THEN DISCH_THEN
15961 (MP_TAC o ISPECL [`a:real^M`; `b:real^M`] o MATCH_MP URYSOHN_LOCAL) THEN
15962 REWRITE_TAC[IN_UNIV]);;
15964 (* ------------------------------------------------------------------------- *)
15965 (* Tietze extension theorem, likewise just for real^N. *)
15966 (* ------------------------------------------------------------------------- *)
15968 let TIETZE_STEP = prove
15969 (`!f:real^N->real^1 u s B.
15970 &0 < B /\ closed_in (subtopology euclidean u) s /\
15971 f continuous_on s /\
15972 (!x. x IN s ==> norm(f x) <= B)
15973 ==> ?g. g continuous_on u /\
15974 (!x. x IN u ==> norm(g x) <= B / &3) /\
15975 (!x. x IN s ==> norm(f x - g x) <= &2 / &3 * B)`,
15976 REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB] THEN REPEAT STRIP_TAC THEN
15977 MP_TAC(ISPECL [`{x:real^N | x IN s /\ f x IN {y | drop y <= --(B / &3)}}`;
15978 `{x:real^N | x IN s /\ f x IN {y | drop y >= B / &3}}`;
15980 `lift(--(B / &3))`; `lift(B / &3)`] URYSOHN_LOCAL) THEN
15982 [REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL
15984 REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; IN_INTER] THEN
15985 ASM_REAL_ARITH_TAC] THEN
15986 CONJ_TAC THEN MATCH_MP_TAC CLOSED_IN_TRANS THEN
15987 EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN
15988 MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN
15989 ASM_REWRITE_TAC[] THENL
15990 [MP_TAC(ISPECL [`lift(&1)`; `--(B / &3)`] CLOSED_HALFSPACE_LE);
15991 MP_TAC(ISPECL [`lift(&1)`; `B / &3`] CLOSED_HALFSPACE_GE)] THEN
15992 REWRITE_TAC[DOT_1; GSYM drop; LIFT_DROP; REAL_MUL_LID];
15993 ASM_SIMP_TAC[SEGMENT_1; IN_ELIM_THM; LIFT_DROP; IN_INTERVAL_1;
15994 REAL_ARITH `&0 < B ==> --(B / &3) <= B / &3`] THEN
15995 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^1` THEN
15996 STRIP_TAC THEN ASM_REWRITE_TAC[NORM_REAL; GSYM drop] THEN
15997 ASM_SIMP_TAC[GSYM REAL_BOUNDS_LE] THEN X_GEN_TAC `x:real^N` THEN
15998 DISCH_TAC THEN REWRITE_TAC[DROP_SUB; REAL_BOUNDS_LE] THEN
15999 FIRST_ASSUM(ASSUME_TAC o REWRITE_RULE[SUBSET] o MATCH_MP
16000 CLOSED_IN_IMP_SUBSET) THEN
16001 REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC
16002 (REAL_ARITH `drop(f x) <= --(B / &3) \/ drop(f x) >= B / &3 \/
16003 abs(drop(f(x:real^N))) <= B / &3`)
16006 `!x:real^N. x IN s /\ drop(f x) <= --(B / &3) ==> g x = lift(--(B / &3))`
16007 (MP_TAC o SPEC `x:real^N`);
16009 `!x:real^N. x IN s /\ drop(f x) >= B / &3 ==> g x = lift(B / &3)`
16010 (MP_TAC o SPEC `x:real^N`);
16011 MATCH_MP_TAC(REAL_ARITH
16012 `abs(f) <= B / &3 /\ --(B / &3) <= g /\ g <= B / &3
16013 ==> abs(f - g) <= &2 / &3 * B`)] THEN
16014 ASM_SIMP_TAC[] THEN DISCH_THEN SUBST_ALL_TAC THEN
16015 UNDISCH_THEN `!x:real^N. x IN s ==> abs(drop(f x)) <= B`
16016 (MP_TAC o SPEC `x:real^N`) THEN
16017 ASM_REWRITE_TAC[LIFT_DROP] THEN ASM_REAL_ARITH_TAC]);;
16020 (`!f:real^N->real^1 u s B.
16022 closed_in (subtopology euclidean u) s /\
16023 f continuous_on s /\
16024 (!x. x IN s ==> norm(f x) <= B)
16025 ==> ?g. g continuous_on u /\
16026 (!x. x IN s ==> g x = f x) /\
16027 (!x. x IN u ==> norm(g x) <= B)`,
16028 REPEAT STRIP_TAC THEN
16029 FIRST_ASSUM(ASSUME_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
16030 FIRST_X_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH
16031 `&0 <= B ==> B = &0 \/ &0 < B`)) THEN
16032 DISCH_THEN(DISJ_CASES_THEN2 SUBST_ALL_TAC ASSUME_TAC) THENL
16033 [EXISTS_TAC `\x:real^N. (vec 0:real^1)` THEN
16034 ASM_SIMP_TAC[CONTINUOUS_ON_CONST; NORM_0; REAL_LE_REFL] THEN
16035 ASM_MESON_TAC[NORM_LE_0];
16037 MP_TAC(ISPECL [`f:real^N->real^1`; `u:real^N->bool`;
16038 `s:real^N->bool`; `B:real`]
16040 ASM_REWRITE_TAC[] THEN
16041 DISCH_THEN(X_CHOOSE_THEN `g0:real^N->real^1` STRIP_ASSUME_TAC) THEN
16043 `?g. (g 0 = (g0:real^N->real^1)) /\
16045 @h. h continuous_on u /\
16047 norm(h x) <= &2 pow SUC n * B / &3 pow (SUC n + 1)) /\
16048 (!x. x IN s ==> norm(f x - vsum(0..n) (\i. g i x) - h x)
16049 <= &2 pow (SUC n + 1) * B / &3 pow (SUC n + 1)))`
16050 STRIP_ASSUME_TAC THENL
16051 [SIMP_TAC[VSUM_REAL; FINITE_NUMSEG; o_DEF] THEN
16052 W(ACCEPT_TAC o prove_general_recursive_function_exists o snd);
16055 `!n. (!m. m < n ==> g m continuous_on u) /\
16056 g n continuous_on u /\
16057 (!x. x IN u ==> norm(g n x:real^1) <= &2 pow n * B / &3 pow (n + 1)) /\
16058 (!x:real^N. x IN s ==> norm(f x - vsum(0..n) (\i. g i x))
16059 <= &2 pow (n + 1) * B / &3 pow (n + 1))`
16061 [INDUCT_TAC THEN ASM_REWRITE_TAC[VSUM_CLAUSES_NUMSEG; LT] THENL
16062 [CONV_TAC NUM_REDUCE_CONV THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
16063 ASM_REWRITE_TAC[REAL_MUL_LID; REAL_ARITH `&2 * B / &3 = &2 / &3 * B`];
16065 ASM_REWRITE_TAC[MESON[] `(!m:num. m = n \/ m < n ==> P m) <=>
16066 (!m. m < n ==> P m) /\ P n`] THEN
16067 REWRITE_TAC[LE_0; VECTOR_ARITH `f - (g + h):real^1 = f - g - h`] THEN
16068 CONV_TAC SELECT_CONV THEN
16069 REWRITE_TAC[REAL_POW_ADD; REAL_ARITH
16070 `(&2 pow (SUC n) * &2 pow 1) * B = &2 * &2 pow (SUC n) * B`] THEN
16071 REWRITE_TAC[real_div; REAL_INV_MUL; REAL_POW_1] THEN
16072 REWRITE_TAC[REAL_ARITH `a * b * inv c * inv d = (a * b / c) / d`] THEN
16073 REWRITE_TAC[REAL_ARITH `&2 * x / &3 = &2 / &3 * x`] THEN
16074 MATCH_MP_TAC TIETZE_STEP THEN
16075 ASM_SIMP_TAC[REAL_LT_DIV; ADD1; REAL_LT_MUL; REAL_POW_LT;
16076 REAL_OF_NUM_LT; ARITH] THEN
16077 MATCH_MP_TAC CONTINUOUS_ON_SUB THEN ASM_REWRITE_TAC[ETA_AX] THEN
16078 MATCH_MP_TAC CONTINUOUS_ON_VSUM THEN
16079 REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG; LE_0] THEN REWRITE_TAC[LE_LT] THEN
16080 GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN
16081 EXISTS_TAC `u:real^N->bool` THEN ASM_SIMP_TAC[];
16083 ABBREV_TAC `(h:num->real^N->real^1) = \n x. vsum(0..n) (\i. g i x)` THEN
16085 `?k:real^N->real^1.
16088 N <= n /\ x IN u ==> dist(vsum (from 0 INTER (0..n))
16089 (\i. g i x),k x) < e`
16091 [REWRITE_TAC[SERIES_CAUCHY_UNIFORM]; ALL_TAC] THEN
16092 REWRITE_TAC[FROM_0; INTER_UNIV; IN_UNIV] THENL
16093 [X_GEN_TAC `e:real` THEN DISCH_TAC THEN
16094 MP_TAC(ISPECL [`&2 / &3`; `e / B`] REAL_ARCH_POW_INV) THEN
16095 ASM_SIMP_TAC[REAL_LT_DIV] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
16096 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN
16097 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`; `x:real^N`] THEN DISCH_TAC THEN
16098 MATCH_MP_TAC REAL_LET_TRANS THEN
16099 EXISTS_TAC `sum(m..n) (\i. &2 pow i * B / &3 pow (i + 1))` THEN
16100 ASM_SIMP_TAC[VSUM_NORM_LE; FINITE_NUMSEG] THEN
16101 REWRITE_TAC[REAL_POW_ADD; real_div; REAL_INV_MUL] THEN
16102 REWRITE_TAC[REAL_ARITH `x * B * inv y * inv(&3 pow 1) = B / &3 * x / y`;
16103 SUM_LMUL; GSYM REAL_POW_DIV] THEN
16104 REWRITE_TAC[SUM_GP] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
16105 COND_CASES_TAC THENL
16106 [ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO; REAL_MUL_RZERO]; ALL_TAC] THEN
16107 REWRITE_TAC[REAL_ARITH `B / &3 * x / (&1 / &3) < e <=> x * B < e`] THEN
16108 ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THEN
16109 MATCH_MP_TAC(REAL_ARITH `&0 < y /\ x < e ==> x - y < e`) THEN
16110 ASM_SIMP_TAC[REAL_POW_LT; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
16111 MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `(&2 / &3) pow N` THEN
16112 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_POW_MONO_INV THEN
16113 ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV;
16115 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^N->real^1` THEN
16116 DISCH_TAC THEN REPEAT CONJ_TAC THENL
16117 [MATCH_MP_TAC(ISPEC `sequentially` CONTINUOUS_UNIFORM_LIMIT) THEN
16118 EXISTS_TAC `\n x:real^N. vsum (0..n) (\i. g i x :real^1)` THEN
16119 ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
16120 ASM_REWRITE_TAC[IN_UNIV; IMP_IMP; RIGHT_IMP_FORALL_THM; GSYM dist] THEN
16121 EXISTS_TAC `0` THEN REPEAT STRIP_TAC THEN
16122 MATCH_MP_TAC CONTINUOUS_ON_VSUM THEN ASM_REWRITE_TAC[FINITE_NUMSEG];
16123 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
16124 MATCH_MP_TAC(NORM_ARITH `~(&0 < norm(x - y)) ==> x = y`) THEN
16126 FIRST_X_ASSUM(MP_TAC o SPEC `norm((k:real^N->real^1) x - f x) / &2`) THEN
16127 ASM_REWRITE_TAC[REAL_HALF; NOT_EXISTS_THM] THEN
16128 X_GEN_TAC `N1:num` THEN DISCH_THEN(LABEL_TAC "*") THEN
16129 MP_TAC(ISPECL [`&2 / &3`; `norm((k:real^N->real^1) x - f x) / &2 / B`]
16130 REAL_ARCH_POW_INV) THEN
16131 ASM_SIMP_TAC[REAL_LT_DIV; REAL_HALF] THEN
16132 CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_SIMP_TAC[REAL_LT_RDIV_EQ] THEN
16133 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
16134 DISCH_THEN(X_CHOOSE_THEN `N2:num` (LABEL_TAC "+")) THEN
16135 REMOVE_THEN "*" (MP_TAC o SPECL [`N1 + N2:num`; `x:real^N`]) THEN
16136 REWRITE_TAC[LE_ADD; NOT_IMP] THEN
16137 CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN MATCH_MP_TAC(NORM_ARITH
16138 `norm(f - s) < norm(k - f) / &2
16139 ==> ~(dist(s,k) < norm(k - f) / &2)`) THEN
16140 MATCH_MP_TAC REAL_LET_TRANS THEN
16141 EXISTS_TAC `B * (&2 / &3) pow N2` THEN ASM_REWRITE_TAC[] THEN
16142 MATCH_MP_TAC REAL_LE_TRANS THEN
16143 EXISTS_TAC `&2 pow ((N1 + N2) + 1) * B / &3 pow ((N1 + N2) + 1)` THEN
16144 ASM_SIMP_TAC[] THEN
16145 ONCE_REWRITE_TAC[REAL_ARITH `x * B / y = B * x / y`] THEN
16146 ASM_SIMP_TAC[REAL_LE_LMUL_EQ; GSYM REAL_POW_DIV] THEN
16147 MATCH_MP_TAC REAL_POW_MONO_INV THEN
16148 ASM_REWRITE_TAC[] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN ARITH_TAC;
16149 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
16150 MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN
16151 EXISTS_TAC `\n. vsum(0..n) (\i. (g:num->real^N->real^1) i x)` THEN
16152 REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
16154 [REWRITE_TAC[LIM_SEQUENTIALLY] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
16155 EXISTS_TAC `0` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
16156 MATCH_MP_TAC REAL_LE_TRANS THEN
16157 EXISTS_TAC `sum(0..n) (\i. &2 pow i * B / &3 pow (i + 1))` THEN
16158 ASM_SIMP_TAC[VSUM_NORM_LE; FINITE_NUMSEG] THEN
16159 REWRITE_TAC[REAL_POW_ADD; real_div; REAL_INV_MUL] THEN
16160 REWRITE_TAC[REAL_ARITH `x * B * inv y * inv(&3 pow 1) = B / &3 * x / y`;
16161 SUM_LMUL; GSYM REAL_POW_DIV] THEN
16162 REWRITE_TAC[REAL_ARITH `B / &3 * x <= B <=> B * x / &3 <= B * &1`] THEN
16163 ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
16164 REWRITE_TAC[SUM_GP] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
16165 COND_CASES_TAC THENL
16166 [SIMP_TAC[real_div; REAL_MUL_LZERO; REAL_MUL_RZERO; REAL_POS];
16168 REWRITE_TAC[REAL_ARITH `x / (&1 / &3) <= &3 <=> x <= &1`] THEN
16169 REWRITE_TAC[REAL_ARITH `&1 - x <= &1 <=> &0 <= x`] THEN
16170 MATCH_MP_TAC REAL_POW_LE THEN CONV_TAC REAL_RAT_REDUCE_CONV]);;
16172 (* ------------------------------------------------------------------------- *)
16173 (* The same result for intervals in real^1. *)
16174 (* ------------------------------------------------------------------------- *)
16176 let TIETZE_CLOSED_INTERVAL_1 = prove
16177 (`!f:real^N->real^1 u s a b.
16178 drop a <= drop b /\
16179 closed_in (subtopology euclidean u) s /\
16180 f continuous_on s /\
16181 (!x. x IN s ==> f x IN interval[a,b])
16182 ==> ?g. g continuous_on u /\
16183 (!x. x IN s ==> g x = f x) /\
16184 (!x. x IN u ==> g(x) IN interval[a,b])`,
16185 REPEAT STRIP_TAC THEN
16186 MP_TAC(ISPECL [`\x. (f:real^N->real^1)(x) - inv(&2) % (a + b)`;
16187 `u:real^N->bool`; `s:real^N->bool`; `(drop(b) - drop(a)) / &2`]
16189 ASM_SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST] THEN ANTS_TAC THENL
16190 [CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
16191 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
16192 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
16193 REWRITE_TAC[IN_INTERVAL_1; NORM_REAL; GSYM drop] THEN
16194 REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_SUB] THEN REAL_ARITH_TAC;
16196 DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^1` STRIP_ASSUME_TAC) THEN
16197 EXISTS_TAC `\x. (g:real^N->real^1)(x) + inv(&2) % (a + b)` THEN
16198 REPEAT CONJ_TAC THENL
16199 [ASM_SIMP_TAC[CONTINUOUS_ON_ADD; CONTINUOUS_ON_CONST];
16200 REPEAT STRIP_TAC THEN ASM_SIMP_TAC[] THEN VECTOR_ARITH_TAC;
16201 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN UNDISCH_TAC
16202 `!x. x IN u ==> norm((g:real^N->real^1) x) <= (drop b - drop a) / &2` THEN
16203 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
16204 REWRITE_TAC[IN_INTERVAL_1; NORM_REAL; GSYM drop] THEN
16205 REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_SUB] THEN REAL_ARITH_TAC]);;
16207 let TIETZE_OPEN_INTERVAL_1 = prove
16208 (`!f:real^N->real^1 u s a b.
16210 closed_in (subtopology euclidean u) s /\
16211 f continuous_on s /\
16212 (!x. x IN s ==> f x IN interval(a,b))
16213 ==> ?g. g continuous_on u /\
16214 (!x. x IN s ==> g x = f x) /\
16215 (!x. x IN u ==> g(x) IN interval(a,b))`,
16216 REWRITE_TAC[IN_INTERVAL_1] THEN REPEAT STRIP_TAC THEN
16217 MP_TAC(ISPECL [`f:real^N->real^1`; `u:real^N->bool`; `s:real^N->bool`;
16218 `a:real^1`; `b:real^1`] TIETZE_CLOSED_INTERVAL_1) THEN
16219 ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
16220 [ASM_MESON_TAC[IN_INTERVAL_1; REAL_LT_IMP_LE]; ALL_TAC] THEN
16221 DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^1` STRIP_ASSUME_TAC) THEN
16222 MP_TAC(ISPECL [`s:real^N->bool`;
16223 `{x | x IN u /\ (g:real^N->real^1) x IN {a,b}}`;
16225 `vec 1:real^1`; `vec 0:real^1`] URYSOHN_LOCAL) THEN
16226 ASM_REWRITE_TAC[SEGMENT_1; DROP_VEC; REAL_OF_NUM_LE; ARITH] THEN
16227 REWRITE_TAC[IN_INTERVAL_1; DROP_VEC] THEN ANTS_TAC THENL
16229 [MATCH_MP_TAC CONTINUOUS_CLOSED_IN_PREIMAGE THEN
16230 ASM_SIMP_TAC[FINITE_IMP_CLOSED; FINITE_INSERT; FINITE_EMPTY] THEN
16231 ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_UNIV; IN_UNIV];
16232 RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
16233 ASM SET_TAC[REAL_LT_REFL]];
16234 REWRITE_TAC[IN_ELIM_THM] THEN
16235 DISCH_THEN(X_CHOOSE_THEN `h:real^N->real^1` STRIP_ASSUME_TAC) THEN
16236 EXISTS_TAC `(\x. &1 / &2 % (a + b) +
16237 drop(h x) % (g x - &1 / &2 % (a + b))):real^N->real^1` THEN
16238 ASM_SIMP_TAC[DROP_CMUL; DROP_VEC; VECTOR_MUL_LID] THEN
16239 REWRITE_TAC[VECTOR_ARITH `a + x - a:real^N = x`] THEN CONJ_TAC THENL
16240 [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN REWRITE_TAC[CONTINUOUS_ON_CONST] THEN
16241 MATCH_MP_TAC CONTINUOUS_ON_MUL THEN
16242 ASM_SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; ETA_AX] THEN
16243 ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX];
16245 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
16246 REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_SUB] THEN
16247 REWRITE_TAC[REAL_ARITH
16248 `a < &1 / &2 * (a + b) + x /\ &1 / &2 * (a + b) + x < b <=>
16249 abs(x) < &1 * (b - a) / &2`] THEN
16250 ASM_CASES_TAC `(g:real^N->real^1) x IN {a,b}` THENL
16251 [ASM_SIMP_TAC[DROP_VEC; REAL_MUL_LZERO] THEN ASM_REAL_ARITH_TAC;
16252 REWRITE_TAC[REAL_ABS_MUL] THEN MATCH_MP_TAC(REAL_ARITH
16253 `y < a /\ abs(x) * y <= &1 * y ==> abs(x) * y < a`) THEN
16255 [REWRITE_TAC[REAL_MUL_LID] THEN MATCH_MP_TAC(REAL_ARITH
16256 `a < x /\ x < b ==> abs(x - &1 / &2 * (a + b)) < (b - a) / &2`) THEN
16257 RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
16258 ASM_REWRITE_TAC[REAL_LT_LE; DROP_EQ] THEN ASM SET_TAC[];
16259 MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[REAL_ABS_POS] THEN
16260 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`)) THEN
16261 FIRST_ASSUM(MP_TAC o MATCH_MP CLOSED_IN_IMP_SUBSET) THEN
16262 ASM_SIMP_TAC[SUBSET] THEN REAL_ARITH_TAC]]]);;
16264 let TIETZE_UNBOUNDED_1 = prove
16265 (`!f:real^N->real^1 u s.
16266 closed_in (subtopology euclidean u) s /\ f continuous_on s
16267 ==> ?g. g continuous_on u /\ (!x. x IN s ==> g x = f x)`,
16268 REPEAT STRIP_TAC THEN
16269 MP_TAC(ISPECL [`vec 0:real^1`; `vec 1:real^1`]
16270 HOMEOMORPHIC_OPEN_INTERVAL_UNIV) THEN
16271 REWRITE_TAC[INTERVAL_NE_EMPTY; VEC_COMPONENT; REAL_LT_01] THEN
16272 REWRITE_TAC[HOMEOMORPHIC_MINIMAL; LEFT_IMP_EXISTS_THM] THEN
16273 MAP_EVERY X_GEN_TAC [`h:real^1->real^1`; `k:real^1->real^1`] THEN
16274 REWRITE_TAC[IN_UNIV] THEN STRIP_TAC THEN
16275 MP_TAC(ISPECL [`(k:real^1->real^1) o (f:real^N->real^1)`; `u:real^N->bool`;
16276 `s:real^N->bool`; `vec 0:real^1`; `vec 1:real^1`]
16277 TIETZE_OPEN_INTERVAL_1) THEN
16278 REWRITE_TAC[] THEN ANTS_TAC THENL
16279 [ASM_REWRITE_TAC[DROP_VEC; REAL_LT_01; o_THM] THEN
16280 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
16281 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN
16282 EXISTS_TAC `(:real^1)` THEN ASM_REWRITE_TAC[SUBSET_UNIV];
16283 DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^1` STRIP_ASSUME_TAC) THEN
16284 EXISTS_TAC `(h:real^1->real^1) o (g:real^N->real^1)` THEN
16285 ASM_SIMP_TAC[o_THM] THEN
16286 MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN
16287 MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN
16288 EXISTS_TAC `interval(vec 0:real^1,vec 1)` THEN
16289 ASM_REWRITE_TAC[SUBSET_UNIV] THEN ASM SET_TAC[]]);;
16291 (* ------------------------------------------------------------------------- *)
16292 (* Now for general intervals in real^N by componentwise extension. *)
16293 (* ------------------------------------------------------------------------- *)
16295 let TIETZE_CLOSED_INTERVAL = prove
16296 (`!f:real^M->real^N u s a b.
16297 ~(interval[a,b] = {}) /\
16298 closed_in (subtopology euclidean u) s /\
16299 f continuous_on s /\
16300 (!x. x IN s ==> f x IN interval[a,b])
16301 ==> ?g. g continuous_on u /\
16302 (!x. x IN s ==> g x = f x) /\
16303 (!x. x IN u ==> g(x) IN interval[a,b])`,
16304 REWRITE_TAC[INTERVAL_NE_EMPTY] THEN REPEAT STRIP_TAC THEN
16306 `!i. 1 <= i /\ i <= dimindex(:N)
16307 ==> ?g. g continuous_on u /\
16308 (!x. x IN s ==> g x = lift((f:real^M->real^N)(x)$i)) /\
16310 g(x) IN interval[lift((a:real^N)$i),lift((b:real^N)$i)])`
16312 [REPEAT STRIP_TAC THEN MATCH_MP_TAC TIETZE_CLOSED_INTERVAL_1 THEN
16313 RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN
16314 ASM_SIMP_TAC[IN_INTERVAL_1; LIFT_DROP] THEN
16315 SUBGOAL_THEN `(\x. lift((f:real^M->real^N) x$i)) = (\x. lift(x$i)) o f`
16316 SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
16317 ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; CONTINUOUS_ON_COMPOSE];
16319 GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [RIGHT_IMP_EXISTS_THM] THEN
16320 REWRITE_TAC[SKOLEM_THM; IN_INTERVAL_1; LIFT_DROP] THEN
16321 DISCH_THEN(X_CHOOSE_TAC `g:num->real^M->real^1`) THEN
16322 EXISTS_TAC `(\x. lambda i. drop(g i x)):real^M->real^N` THEN
16323 SIMP_TAC[CART_EQ; IN_INTERVAL; LAMBDA_BETA] THEN CONJ_TAC THENL
16324 [ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN
16325 ASM_SIMP_TAC[LAMBDA_BETA; LIFT_DROP; ETA_AX];
16326 ASM_SIMP_TAC[LIFT_DROP]]);;
16328 let TIETZE_OPEN_INTERVAL = prove
16329 (`!f:real^M->real^N u s a b.
16330 ~(interval(a,b) = {}) /\
16331 closed_in (subtopology euclidean u) s /\
16332 f continuous_on s /\
16333 (!x. x IN s ==> f x IN interval(a,b))
16334 ==> ?g. g continuous_on u /\
16335 (!x. x IN s ==> g x = f x) /\
16336 (!x. x IN u ==> g(x) IN interval(a,b))`,
16337 REWRITE_TAC[INTERVAL_NE_EMPTY] THEN REPEAT STRIP_TAC THEN
16339 `!i. 1 <= i /\ i <= dimindex(:N)
16340 ==> ?g. g continuous_on u /\
16341 (!x. x IN s ==> g x = lift((f:real^M->real^N)(x)$i)) /\
16343 g(x) IN interval(lift((a:real^N)$i),lift((b:real^N)$i)))`
16345 [REPEAT STRIP_TAC THEN MATCH_MP_TAC TIETZE_OPEN_INTERVAL_1 THEN
16346 RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN
16347 ASM_SIMP_TAC[IN_INTERVAL_1; LIFT_DROP] THEN
16348 SUBGOAL_THEN `(\x. lift((f:real^M->real^N) x$i)) = (\x. lift(x$i)) o f`
16349 SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
16350 ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; CONTINUOUS_ON_COMPOSE];
16352 GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [RIGHT_IMP_EXISTS_THM] THEN
16353 REWRITE_TAC[SKOLEM_THM; IN_INTERVAL_1; LIFT_DROP] THEN
16354 DISCH_THEN(X_CHOOSE_TAC `g:num->real^M->real^1`) THEN
16355 EXISTS_TAC `(\x. lambda i. drop(g i x)):real^M->real^N` THEN
16356 SIMP_TAC[CART_EQ; IN_INTERVAL; LAMBDA_BETA] THEN CONJ_TAC THENL
16357 [ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN
16358 ASM_SIMP_TAC[LAMBDA_BETA; LIFT_DROP; ETA_AX];
16359 ASM_SIMP_TAC[LIFT_DROP]]);;
16361 let TIETZE_UNBOUNDED = prove
16362 (`!f:real^M->real^N u s.
16363 closed_in (subtopology euclidean u) s /\ f continuous_on s
16364 ==> ?g. g continuous_on u /\
16365 (!x. x IN s ==> g x = f x)`,
16366 REWRITE_TAC[INTERVAL_NE_EMPTY] THEN REPEAT STRIP_TAC THEN
16368 `!i. 1 <= i /\ i <= dimindex(:N)
16369 ==> ?g. g continuous_on u /\
16370 (!x. x IN s ==> g x = lift((f:real^M->real^N)(x)$i))`
16372 [REPEAT STRIP_TAC THEN MATCH_MP_TAC TIETZE_UNBOUNDED_1 THEN
16373 RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN
16374 ASM_SIMP_TAC[IN_INTERVAL_1; LIFT_DROP] THEN
16375 SUBGOAL_THEN `(\x. lift((f:real^M->real^N) x$i)) = (\x. lift(x$i)) o f`
16376 SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
16377 ASM_SIMP_TAC[CONTINUOUS_ON_LIFT_COMPONENT; CONTINUOUS_ON_COMPOSE];
16379 GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [RIGHT_IMP_EXISTS_THM] THEN
16380 REWRITE_TAC[SKOLEM_THM; IN_INTERVAL_1; LIFT_DROP] THEN
16381 DISCH_THEN(X_CHOOSE_TAC `g:num->real^M->real^1`) THEN
16382 EXISTS_TAC `(\x. lambda i. drop(g i x)):real^M->real^N` THEN
16383 SIMP_TAC[CART_EQ; IN_INTERVAL; LAMBDA_BETA] THEN CONJ_TAC THENL
16384 [ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN
16385 ASM_SIMP_TAC[LAMBDA_BETA; LIFT_DROP; ETA_AX];
16386 ASM_SIMP_TAC[LIFT_DROP]]);;
16388 (* ------------------------------------------------------------------------- *)
16389 (* Countability of some relevant sets. *)
16390 (* ------------------------------------------------------------------------- *)
16392 let COUNTABLE_INTEGER = prove
16393 (`COUNTABLE integer`,
16394 MATCH_MP_TAC COUNTABLE_SUBSET THEN EXISTS_TAC
16395 `IMAGE (\n. (&n:real)) (:num) UNION IMAGE (\n. --(&n)) (:num)` THEN
16396 SIMP_TAC[COUNTABLE_IMAGE; COUNTABLE_UNION; NUM_COUNTABLE] THEN
16397 REWRITE_TAC[SUBSET; IN_UNION; IN_IMAGE; IN_UNIV] THEN
16398 REWRITE_TAC[IN; INTEGER_CASES]);;
16400 let CARD_EQ_INTEGER = prove
16401 (`integer =_c (:num)`,
16402 REWRITE_TAC[GSYM CARD_LE_ANTISYM; GSYM COUNTABLE_ALT; COUNTABLE_INTEGER] THEN
16403 REWRITE_TAC[le_c] THEN EXISTS_TAC `real_of_num` THEN
16404 REWRITE_TAC[IN_UNIV; REAL_OF_NUM_EQ] THEN
16405 REWRITE_TAC[IN; INTEGER_CLOSED]);;
16407 let COUNTABLE_RATIONAL = prove
16408 (`COUNTABLE rational`,
16409 MATCH_MP_TAC COUNTABLE_SUBSET THEN
16410 EXISTS_TAC `IMAGE (\(x,y). x / y) (integer CROSS integer)` THEN
16411 SIMP_TAC[COUNTABLE_IMAGE; COUNTABLE_CROSS; COUNTABLE_INTEGER] THEN
16412 REWRITE_TAC[SUBSET; IN_IMAGE; EXISTS_PAIR_THM; IN_CROSS] THEN
16413 REWRITE_TAC[rational; IN] THEN MESON_TAC[]);;
16415 let CARD_EQ_RATIONAL = prove
16416 (`rational =_c (:num)`,
16417 REWRITE_TAC[GSYM CARD_LE_ANTISYM; GSYM COUNTABLE_ALT; COUNTABLE_RATIONAL] THEN
16418 REWRITE_TAC[le_c] THEN EXISTS_TAC `real_of_num` THEN
16419 REWRITE_TAC[IN_UNIV; REAL_OF_NUM_EQ] THEN
16420 REWRITE_TAC[IN; RATIONAL_CLOSED]);;
16422 let COUNTABLE_INTEGER_COORDINATES = prove
16423 (`COUNTABLE { x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) }`,
16424 MATCH_MP_TAC COUNTABLE_CART THEN
16425 REWRITE_TAC[SET_RULE `{x | P x} = P`; COUNTABLE_INTEGER]);;
16427 let COUNTABLE_RATIONAL_COORDINATES = prove
16428 (`COUNTABLE { x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i) }`,
16429 MATCH_MP_TAC COUNTABLE_CART THEN
16430 REWRITE_TAC[SET_RULE `{x | P x} = P`; COUNTABLE_RATIONAL]);;
16432 (* ------------------------------------------------------------------------- *)
16433 (* Density of points with rational, or just dyadic rational, coordinates. *)
16434 (* ------------------------------------------------------------------------- *)
16436 let CLOSURE_DYADIC_RATIONALS = prove
16437 (`closure { inv(&2 pow n) % x |n,x|
16438 !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) } = (:real^N)`,
16439 REWRITE_TAC[EXTENSION; CLOSURE_APPROACHABLE; IN_UNIV; EXISTS_IN_GSPEC] THEN
16440 MAP_EVERY X_GEN_TAC [`x:real^N`; `e:real`] THEN DISCH_TAC THEN
16441 MP_TAC(SPECL [`inv(&2)`; `e / &(dimindex(:N))`] REAL_ARCH_POW_INV) THEN
16442 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1;
16443 REAL_POW_INV; REAL_LT_RDIV_EQ] THEN
16444 CONV_TAC REAL_RAT_REDUCE_CONV THEN MATCH_MP_TAC MONO_EXISTS THEN
16445 ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
16446 EXISTS_TAC `(lambda i. floor(&2 pow n * (x:real^N)$i)):real^N` THEN
16447 ASM_SIMP_TAC[LAMBDA_BETA; FLOOR; dist; NORM_MUL] THEN
16448 MATCH_MP_TAC(MATCH_MP (REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS)
16449 (SPEC_ALL NORM_LE_L1)) THEN
16450 SIMP_TAC[LAMBDA_BETA; VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT] THEN
16451 MATCH_MP_TAC REAL_LET_TRANS THEN
16452 EXISTS_TAC `&(dimindex(:N)) * inv(&2 pow n)` THEN ASM_REWRITE_TAC[] THEN
16453 GEN_REWRITE_TAC (RAND_CONV o LAND_CONV o RAND_CONV) [GSYM CARD_NUMSEG_1] THEN
16454 MATCH_MP_TAC SUM_BOUND THEN REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
16455 X_GEN_TAC `k:num` THEN STRIP_TAC THEN
16456 GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_RID] THEN
16457 SIMP_TAC[REAL_ABS_MUL; REAL_POW_EQ_0; REAL_OF_NUM_EQ; ARITH;
16458 REAL_FIELD `~(a = &0) ==> inv a * b - x = inv a * (b - a * x)`] THEN
16459 MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[REAL_ABS_POS] THEN
16460 REWRITE_TAC[REAL_LE_REFL; REAL_ABS_POW; REAL_ABS_INV; REAL_ABS_NUM] THEN
16461 MP_TAC(SPEC `&2 pow n * (x:real^N)$k` FLOOR) THEN REAL_ARITH_TAC);;
16463 let CLOSURE_RATIONAL_COORDINATES = prove
16464 (`closure { x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i) } =
16466 MATCH_MP_TAC(SET_RULE `!s. s SUBSET t /\ s = UNIV ==> t = UNIV`) THEN
16468 `closure { inv(&2 pow n) % x:real^N |n,x|
16469 !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) }` THEN
16471 CONJ_TAC THENL [ALL_TAC; REWRITE_TAC[CLOSURE_DYADIC_RATIONALS]] THEN
16472 MATCH_MP_TAC SUBSET_CLOSURE THEN
16473 REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_THM; VECTOR_MUL_COMPONENT] THEN
16474 ASM_SIMP_TAC[RATIONAL_CLOSED]);;
16476 let CLOSURE_DYADIC_RATIONALS_IN_OPEN_SET = prove
16479 ==> closure(s INTER
16480 { inv(&2 pow n) % x | n,x |
16481 !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) }) =
16483 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_OPEN_INTER_SUPERSET THEN
16484 ASM_REWRITE_TAC[CLOSURE_DYADIC_RATIONALS; SUBSET_UNIV]);;
16486 let CLOSURE_RATIONALS_IN_OPEN_SET = prove
16489 ==> closure(s INTER
16490 { inv(&2 pow n) % x | n,x |
16491 !i. 1 <= i /\ i <= dimindex(:N) ==> integer(x$i) }) =
16493 REPEAT STRIP_TAC THEN MATCH_MP_TAC CLOSURE_OPEN_INTER_SUPERSET THEN
16494 ASM_REWRITE_TAC[CLOSURE_DYADIC_RATIONALS; SUBSET_UNIV]);;
16496 (* ------------------------------------------------------------------------- *)
16497 (* Various separability-type properties. *)
16498 (* ------------------------------------------------------------------------- *)
16500 let UNIV_SECOND_COUNTABLE = prove
16501 (`?b. COUNTABLE b /\ (!c. c IN b ==> open c) /\
16502 !s:real^N->bool. open s ==> ?u. u SUBSET b /\ s = UNIONS u`,
16504 `IMAGE (\(v:real^N,q). ball(v,q))
16505 ({v | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(v$i)} CROSS
16507 REPEAT CONJ_TAC THENL
16508 [MATCH_MP_TAC COUNTABLE_IMAGE THEN MATCH_MP_TAC COUNTABLE_CROSS THEN
16509 REWRITE_TAC[COUNTABLE_RATIONAL] THEN MATCH_MP_TAC COUNTABLE_CART THEN
16510 REWRITE_TAC[COUNTABLE_RATIONAL; SET_RULE `{x | P x} = P`];
16511 REWRITE_TAC[FORALL_IN_IMAGE; CROSS; FORALL_IN_GSPEC; OPEN_BALL];
16512 REPEAT STRIP_TAC THEN
16513 ASM_CASES_TAC `s:real^N->bool = {}` THENL
16514 [EXISTS_TAC `{}:(real^N->bool)->bool` THEN
16515 ASM_REWRITE_TAC[UNIONS_0; EMPTY_SUBSET];
16517 EXISTS_TAC `{c | c IN IMAGE (\(v:real^N,q). ball(v,q))
16518 ({v | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(v$i)} CROSS
16519 rational) /\ c SUBSET s}` THEN
16520 CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
16521 MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN
16522 REWRITE_TAC[SUBSET; IN_UNIONS; IN_ELIM_THM] THEN
16523 REWRITE_TAC[GSYM CONJ_ASSOC; EXISTS_IN_IMAGE] THEN
16524 REWRITE_TAC[CROSS; EXISTS_PAIR_THM; EXISTS_IN_GSPEC] THEN
16525 REWRITE_TAC[IN_ELIM_PAIR_THM] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
16526 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [OPEN_CONTAINS_BALL]) THEN
16527 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
16528 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; SUBSET; IN_BALL] THEN
16529 X_GEN_TAC `e:real` THEN STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
16530 MP_TAC(REWRITE_RULE[EXTENSION; IN_UNIV] CLOSURE_RATIONAL_COORDINATES) THEN
16531 REWRITE_TAC[CLOSURE_APPROACHABLE] THEN
16532 DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `e / &4`]) THEN
16533 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[IN_ELIM_THM]] THEN
16534 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
16535 SUBGOAL_THEN `?x. rational x /\ e / &3 < x /\ x < e / &2`
16536 (X_CHOOSE_THEN `q:real` STRIP_ASSUME_TAC)
16538 [MP_TAC(ISPECL [`&5 / &12 * e`; `e / &12`] RATIONAL_APPROXIMATION) THEN
16539 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; MATCH_MP_TAC MONO_EXISTS] THEN
16540 SIMP_TAC[] THEN REAL_ARITH_TAC;
16541 EXISTS_TAC `q:real` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
16542 [ASM_REWRITE_TAC[IN];
16543 REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
16544 REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC;
16545 ASM_REAL_ARITH_TAC]]]);;
16547 let UNIV_SECOND_COUNTABLE_SEQUENCE = prove
16548 (`?b:num->real^N->bool.
16549 (!m n. b m = b n <=> m = n) /\
16551 (!s. open s ==> ?k. s = UNIONS {b n | n IN k})`,
16552 X_CHOOSE_THEN `bb:(real^N->bool)->bool` STRIP_ASSUME_TAC
16553 UNIV_SECOND_COUNTABLE THEN
16554 MP_TAC(ISPEC `bb:(real^N->bool)->bool` COUNTABLE_AS_INJECTIVE_IMAGE) THEN
16556 [ASM_REWRITE_TAC[INFINITE] THEN DISCH_TAC THEN
16558 `INFINITE {ball(vec 0:real^N,inv(&n + &1)) | n IN (:num)}`
16560 [REWRITE_TAC[SIMPLE_IMAGE] THEN MATCH_MP_TAC(REWRITE_RULE
16561 [RIGHT_IMP_FORALL_THM; IMP_IMP] INFINITE_IMAGE_INJ) THEN
16562 REWRITE_TAC[num_INFINITE] THEN MATCH_MP_TAC WLOG_LT THEN SIMP_TAC[] THEN
16563 CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
16564 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN
16565 REWRITE_TAC[EXTENSION] THEN
16566 DISCH_THEN(MP_TAC o SPEC `inv(&n + &1) % basis 1:real^N`) THEN
16567 REWRITE_TAC[IN_BALL; DIST_0; NORM_MUL; REAL_ABS_INV] THEN
16568 SIMP_TAC[NORM_BASIS; DIMINDEX_GE_1; LE_REFL; REAL_MUL_RID] THEN
16569 ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
16570 REWRITE_TAC[REAL_ARITH `abs(&n + &1) = &n + &1`; REAL_LT_REFL] THEN
16571 MATCH_MP_TAC REAL_LT_INV2 THEN
16572 REWRITE_TAC[REAL_OF_NUM_LT; REAL_OF_NUM_ADD] THEN ASM_ARITH_TAC;
16573 REWRITE_TAC[INFINITE; SIMPLE_IMAGE] THEN
16574 MATCH_MP_TAC FINITE_SUBSET THEN
16575 EXISTS_TAC `IMAGE UNIONS {u | u SUBSET bb} :(real^N->bool)->bool` THEN
16576 ASM_SIMP_TAC[FINITE_IMAGE; FINITE_POWERSET] THEN
16577 GEN_REWRITE_TAC I [SUBSET] THEN SIMP_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN
16578 X_GEN_TAC `n:num` THEN REWRITE_TAC[IN_IMAGE; IN_ELIM_THM] THEN
16579 ASM_MESON_TAC[OPEN_BALL]];
16580 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:num->real^N->bool` THEN
16581 DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN
16582 RULE_ASSUM_TAC(REWRITE_RULE[FORALL_IN_IMAGE; IN_UNIV]) THEN
16583 REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN
16584 X_GEN_TAC `s:real^N->bool` THEN DISCH_TAC THEN
16585 FIRST_X_ASSUM(MP_TAC o SPEC `s:real^N->bool`) THEN
16586 ASM_REWRITE_TAC[SUBSET_IMAGE; LEFT_AND_EXISTS_THM; SUBSET_UNIV] THEN
16587 ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
16588 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[SIMPLE_IMAGE]]);;
16590 let SUBSET_SECOND_COUNTABLE = prove
16593 (!c. c IN b ==> ~(c = {}) /\ open_in(subtopology euclidean s) c) /\
16594 !t. open_in(subtopology euclidean s) t
16595 ==> ?u. u SUBSET b /\ t = UNIONS u`,
16598 `?b. COUNTABLE b /\
16599 (!c:real^N->bool. c IN b ==> open_in(subtopology euclidean s) c) /\
16600 !t. open_in(subtopology euclidean s) t
16601 ==> ?u. u SUBSET b /\ t = UNIONS u`
16602 STRIP_ASSUME_TAC THENL
16603 [X_CHOOSE_THEN `B:(real^N->bool)->bool` STRIP_ASSUME_TAC
16604 UNIV_SECOND_COUNTABLE THEN
16605 EXISTS_TAC `{s INTER c :real^N->bool | c IN B}` THEN
16606 ASM_SIMP_TAC[SIMPLE_IMAGE; COUNTABLE_IMAGE] THEN
16607 ASM_SIMP_TAC[FORALL_IN_IMAGE; EXISTS_SUBSET_IMAGE; OPEN_IN_OPEN_INTER] THEN
16608 REWRITE_TAC[OPEN_IN_OPEN] THEN
16609 X_GEN_TAC `t:real^N->bool` THEN
16610 DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
16611 FIRST_X_ASSUM SUBST_ALL_TAC THEN
16612 SUBGOAL_THEN `?b. b SUBSET B /\ u:real^N->bool = UNIONS b`
16613 STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
16614 FIRST_X_ASSUM SUBST_ALL_TAC THEN
16615 EXISTS_TAC `b:(real^N->bool)->bool` THEN ASM_REWRITE_TAC[] THEN
16616 REWRITE_TAC[INTER_UNIONS] THEN AP_TERM_TAC THEN SET_TAC[];
16617 EXISTS_TAC `b DELETE ({}:real^N->bool)` THEN
16618 ASM_SIMP_TAC[COUNTABLE_DELETE; IN_DELETE; SUBSET_DELETE] THEN
16619 X_GEN_TAC `t:real^N->bool` THEN DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN
16620 DISCH_THEN(X_CHOOSE_THEN `u:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
16621 EXISTS_TAC `u DELETE ({}:real^N->bool)` THEN
16622 REPEAT(CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC]) THEN
16623 FIRST_X_ASSUM SUBST_ALL_TAC THEN
16624 REWRITE_TAC[EXTENSION; IN_UNIONS] THEN
16625 GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
16626 REWRITE_TAC[IN_DELETE] THEN SET_TAC[]]);;
16628 let SEPARABLE = prove
16630 ?t. COUNTABLE t /\ t SUBSET s /\ s SUBSET closure t`,
16631 MP_TAC SUBSET_SECOND_COUNTABLE THEN
16632 MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `s:real^N->bool` THEN
16633 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; LEFT_AND_EXISTS_THM] THEN
16634 DISCH_THEN(X_CHOOSE_THEN `B:(real^N->bool)->bool`
16635 (CONJUNCTS_THEN2 ASSUME_TAC (CONJUNCTS_THEN2 MP_TAC ASSUME_TAC))) THEN
16636 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
16637 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
16638 X_GEN_TAC `f:(real^N->bool)->real^N` THEN DISCH_TAC THEN
16639 EXISTS_TAC `IMAGE (f:(real^N->bool)->real^N) B` THEN
16640 ASM_SIMP_TAC[COUNTABLE_IMAGE] THEN CONJ_TAC THENL
16641 [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
16642 X_GEN_TAC `c:real^N->bool` THEN DISCH_TAC THEN
16643 FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N->bool`) THEN
16644 ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
16645 FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_SUBSET) THEN
16646 REWRITE_TAC[TOPSPACE_SUBTOPOLOGY; TOPSPACE_EUCLIDEAN] THEN ASM SET_TAC[];
16647 REWRITE_TAC[SUBSET; CLOSURE_APPROACHABLE; EXISTS_IN_IMAGE] THEN
16648 X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
16649 X_GEN_TAC `e:real` THEN DISCH_TAC THEN
16652 open_in (subtopology euclidean s) t
16653 ==> (?u. u SUBSET B /\ t = UNIONS u)`
16654 (MP_TAC o SPEC `s INTER ball(x:real^N,e)`) THEN
16655 SIMP_TAC[OPEN_IN_OPEN_INTER; OPEN_BALL; LEFT_IMP_EXISTS_THM] THEN
16656 X_GEN_TAC `b:(real^N->bool)->bool` THEN
16657 ASM_CASES_TAC `b:(real^N->bool)->bool = {}` THENL
16658 [MATCH_MP_TAC(TAUT `~b ==> a /\ b ==> c`) THEN
16659 ASM_REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY; UNIONS_0] THEN
16660 ASM_MESON_TAC[CENTRE_IN_BALL];
16662 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
16663 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^N->bool` THEN
16664 DISCH_TAC THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
16665 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
16666 DISCH_THEN(MP_TAC o SPEC `(f:(real^N->bool)->real^N) c`) THEN
16667 ONCE_REWRITE_TAC[DIST_SYM] THEN REWRITE_TAC[IN_INTER; IN_BALL] THEN
16668 MATCH_MP_TAC(TAUT `a /\ c ==> (a /\ b <=> c) ==> b`) THEN
16669 CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
16670 FIRST_X_ASSUM(MP_TAC o SPEC `c:real^N->bool`) THEN
16671 ANTS_TAC THENL [ASM SET_TAC[]; STRIP_TAC] THEN
16672 FIRST_X_ASSUM(MP_TAC o MATCH_MP OPEN_IN_SUBSET) THEN
16673 REWRITE_TAC[TOPSPACE_SUBTOPOLOGY; TOPSPACE_EUCLIDEAN] THEN
16676 let OPEN_SET_RATIONAL_COORDINATES = prove
16677 (`!s. open s /\ ~(s = {})
16678 ==> ?x:real^N. x IN s /\
16679 !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)`,
16680 REPEAT STRIP_TAC THEN
16682 `~(closure { x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i) } INTER
16683 (s:real^N->bool) = {})`
16685 [ASM_REWRITE_TAC[CLOSURE_RATIONAL_COORDINATES; INTER_UNIV]; ALL_TAC] THEN
16686 REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; CLOSURE_APPROACHABLE; IN_INTER;
16688 DISCH_THEN(X_CHOOSE_THEN `a:real^N` STRIP_ASSUME_TAC) THEN
16689 FIRST_X_ASSUM(MP_TAC o SPEC `a:real^N` o REWRITE_RULE[open_def]) THEN
16690 ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;
16692 let OPEN_COUNTABLE_UNION_OPEN_INTERVALS,
16693 OPEN_COUNTABLE_UNION_CLOSED_INTERVALS = (CONJ_PAIR o prove)
16694 (`(!s:real^N->bool.
16696 ==> ?D. COUNTABLE D /\
16697 (!i. i IN D ==> i SUBSET s /\ ?a b. i = interval(a,b)) /\
16701 ==> ?D. COUNTABLE D /\
16702 (!i. i IN D ==> i SUBSET s /\ ?a b. i = interval[a,b]) /\
16704 REPEAT STRIP_TAC THENL
16706 `{i | i IN IMAGE (\(a:real^N,b). interval(a,b))
16707 ({x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)} CROSS
16708 {x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)}) /\
16711 `{i | i IN IMAGE (\(a:real^N,b). interval[a,b])
16712 ({x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)} CROSS
16713 {x | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i)}) /\
16715 (SIMP_TAC[COUNTABLE_RESTRICT; COUNTABLE_IMAGE; COUNTABLE_CROSS;
16716 COUNTABLE_RATIONAL_COORDINATES] THEN
16717 REWRITE_TAC[IN_ELIM_THM; UNIONS_GSPEC; IMP_CONJ; GSYM CONJ_ASSOC] THEN
16718 REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN
16719 REWRITE_TAC[FORALL_PAIR_THM; EXISTS_PAIR_THM; IN_CROSS; IN_ELIM_THM] THEN
16720 CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
16721 REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
16722 X_GEN_TAC `x:real^N` THEN EQ_TAC THENL [SET_TAC[]; DISCH_TAC] THEN
16723 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N` o REWRITE_RULE[open_def]) THEN
16724 ASM_REWRITE_TAC[] THEN
16725 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
16727 `!i. 1 <= i /\ i <= dimindex(:N)
16728 ==> ?a b. rational a /\ rational b /\
16729 a < (x:real^N)$i /\ (x:real^N)$i < b /\
16730 abs(b - a) < e / &(dimindex(:N))`
16732 [REPEAT STRIP_TAC THEN MATCH_MP_TAC RATIONAL_APPROXIMATION_STRADDLE THEN
16733 ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1];
16734 REWRITE_TAC[LAMBDA_SKOLEM]] THEN
16735 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `a:real^N` THEN
16736 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `b:real^N` THEN
16737 DISCH_TAC THEN ASM_SIMP_TAC[SUBSET; IN_INTERVAL; REAL_LT_IMP_LE] THEN
16738 X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
16739 REWRITE_TAC[dist] THEN MP_TAC(ISPEC `y - x:real^N` NORM_LE_L1) THEN
16740 MATCH_MP_TAC(REAL_ARITH `s < e ==> n <= s ==> n < e`) THEN
16741 MATCH_MP_TAC SUM_BOUND_LT_GEN THEN
16742 REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; CARD_NUMSEG_1] THEN
16743 REWRITE_TAC[DIMINDEX_GE_1; IN_NUMSEG; VECTOR_SUB_COMPONENT] THEN
16744 X_GEN_TAC `k:num` THEN STRIP_TAC THEN
16745 REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `k:num`)) THEN ASM_REWRITE_TAC[] THEN
16746 ASM_REAL_ARITH_TAC));;
16748 let LINDELOF = prove
16749 (`!f:(real^N->bool)->bool.
16750 (!s. s IN f ==> open s)
16751 ==> ?f'. f' SUBSET f /\ COUNTABLE f' /\ UNIONS f' = UNIONS f`,
16752 REPEAT STRIP_TAC THEN
16754 `?b. COUNTABLE b /\
16755 (!c:real^N->bool. c IN b ==> open c) /\
16756 (!s. open s ==> ?u. u SUBSET b /\ s = UNIONS u)`
16757 STRIP_ASSUME_TAC THENL [ASM_REWRITE_TAC[UNIV_SECOND_COUNTABLE]; ALL_TAC] THEN
16759 `d = {s:real^N->bool | s IN b /\ ?u. u IN f /\ s SUBSET u}` THEN
16761 `COUNTABLE d /\ UNIONS f :real^N->bool = UNIONS d`
16762 STRIP_ASSUME_TAC THENL
16763 [EXPAND_TAC "d" THEN ASM_SIMP_TAC[COUNTABLE_RESTRICT] THEN ASM SET_TAC[];
16766 `!s:real^N->bool. ?u. s IN d ==> u IN f /\ s SUBSET u`
16767 MP_TAC THENL [EXPAND_TAC "d" THEN SET_TAC[]; ALL_TAC] THEN
16768 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
16769 X_GEN_TAC `g:(real^N->bool)->(real^N->bool)` THEN STRIP_TAC THEN
16770 EXISTS_TAC `IMAGE (g:(real^N->bool)->(real^N->bool)) d` THEN
16771 ASM_SIMP_TAC[COUNTABLE_IMAGE; UNIONS_IMAGE] THEN
16772 REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN ASM SET_TAC[]);;
16774 let LINDELOF_OPEN_IN = prove
16775 (`!f u:real^N->bool.
16776 (!s. s IN f ==> open_in (subtopology euclidean u) s)
16777 ==> ?f'. f' SUBSET f /\ COUNTABLE f' /\ UNIONS f' = UNIONS f`,
16778 REPEAT GEN_TAC THEN REWRITE_TAC[OPEN_IN_OPEN] THEN
16779 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
16780 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
16781 X_GEN_TAC `v:(real^N->bool)->real^N->bool` THEN DISCH_TAC THEN
16782 MP_TAC(ISPEC `IMAGE (v:(real^N->bool)->real^N->bool) f` LINDELOF) THEN
16783 ASM_SIMP_TAC[FORALL_IN_IMAGE] THEN
16784 ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
16785 REWRITE_TAC[EXISTS_COUNTABLE_SUBSET_IMAGE] THEN
16786 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `f':(real^N->bool)->bool` THEN
16787 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
16789 `!f'. f' SUBSET f ==> UNIONS f' = (u:real^N->bool) INTER UNIONS (IMAGE v f')`
16790 MP_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[SUBSET_REFL]]);;
16792 let COUNTABLE_DISJOINT_OPEN_SUBSETS = prove
16793 (`!f. (!s:real^N->bool. s IN f ==> open s) /\ pairwise DISJOINT f
16795 REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP LINDELOF) THEN
16796 DISCH_THEN(X_CHOOSE_THEN `g:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
16797 MATCH_MP_TAC COUNTABLE_SUBSET THEN
16798 EXISTS_TAC `({}:real^N->bool) INSERT g` THEN
16799 ASM_REWRITE_TAC[COUNTABLE_INSERT] THEN
16800 REWRITE_TAC[SUBSET; IN_INSERT] THEN
16801 REPEAT(POP_ASSUM MP_TAC) THEN
16802 REWRITE_TAC[EXTENSION; SUBSET] THEN
16803 REWRITE_TAC[IN_UNIONS; pairwise] THEN
16804 REWRITE_TAC[SET_RULE `DISJOINT s t <=> !x. ~(x IN s /\ x IN t)`] THEN
16805 REWRITE_TAC[NOT_IN_EMPTY] THEN MESON_TAC[]);;
16807 let CARD_EQ_OPEN_SETS = prove
16808 (`{s:real^N->bool | open s} =_c (:real)`,
16809 REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
16810 [X_CHOOSE_THEN `b:(real^N->bool)->bool` STRIP_ASSUME_TAC
16811 UNIV_SECOND_COUNTABLE THEN
16812 TRANS_TAC CARD_LE_TRANS `{s:(real^N->bool)->bool | s SUBSET b}` THEN
16814 [REWRITE_TAC[LE_C] THEN
16815 EXISTS_TAC `UNIONS:((real^N->bool)->bool)->real^N->bool` THEN
16816 REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[];
16817 TRANS_TAC CARD_LE_TRANS `{s | s SUBSET (:num)}` THEN CONJ_TAC THENL
16818 [MATCH_MP_TAC CARD_LE_POWERSET THEN ASM_REWRITE_TAC[GSYM COUNTABLE_ALT];
16819 REWRITE_TAC[SUBSET_UNIV; UNIV_GSPEC] THEN
16820 MESON_TAC[CARD_EQ_IMP_LE; CARD_EQ_SYM; CARD_EQ_REAL]]];
16821 REWRITE_TAC[le_c; IN_UNIV; IN_ELIM_THM] THEN
16822 EXISTS_TAC `\x. ball(x % basis 1:real^N,&1)` THEN
16823 REWRITE_TAC[OPEN_BALL; GSYM SUBSET_ANTISYM_EQ; SUBSET_BALLS] THEN
16824 CONV_TAC REAL_RAT_REDUCE_CONV THEN
16825 REWRITE_TAC[NORM_ARITH `dist(p:real^N,q) + &1 <= &1 <=> p = q`] THEN
16826 REWRITE_TAC[VECTOR_MUL_RCANCEL; EQ_SYM_EQ] THEN
16827 SIMP_TAC[BASIS_NONZERO; DIMINDEX_GE_1; ARITH]]);;
16829 let CARD_EQ_CLOSED_SETS = prove
16830 (`{s:real^N->bool | closed s} =_c (:real)`,
16832 `{s:real^N->bool | closed s} =
16833 IMAGE (\s. (:real^N) DIFF s) {s | open s}`
16835 [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
16836 REWRITE_TAC[IN_ELIM_THM; GSYM OPEN_CLOSED] THEN
16837 MESON_TAC[SET_RULE `UNIV DIFF (UNIV DIFF s) = s`];
16838 TRANS_TAC CARD_EQ_TRANS `{s:real^N->bool | open s}` THEN
16839 REWRITE_TAC[CARD_EQ_OPEN_SETS] THEN
16840 MATCH_MP_TAC CARD_EQ_IMAGE THEN SET_TAC[]]);;
16842 let CARD_EQ_COMPACT_SETS = prove
16843 (`{s:real^N->bool | compact s} =_c (:real)`,
16844 REWRITE_TAC[GSYM CARD_LE_ANTISYM] THEN CONJ_TAC THENL
16845 [TRANS_TAC CARD_LE_TRANS `{s:real^N->bool | closed s}` THEN
16846 SIMP_TAC[CARD_EQ_IMP_LE; CARD_EQ_CLOSED_SETS] THEN
16847 MATCH_MP_TAC CARD_LE_SUBSET THEN
16848 SIMP_TAC[SUBSET; IN_ELIM_THM; COMPACT_IMP_CLOSED];
16849 REWRITE_TAC[le_c; IN_UNIV; IN_ELIM_THM] THEN
16850 EXISTS_TAC `\x. {x % basis 1:real^N}` THEN
16851 REWRITE_TAC[COMPACT_SING; SET_RULE `{x} = {y} <=> x = y`] THEN
16852 SIMP_TAC[VECTOR_MUL_RCANCEL; BASIS_NONZERO; DIMINDEX_GE_1; ARITH]]);;
16854 let COUNTABLE_NON_CONDENSATION_POINTS = prove
16855 (`!s:real^N->bool. COUNTABLE(s DIFF {x | x condensation_point_of s})`,
16856 REPEAT STRIP_TAC THEN REWRITE_TAC[condensation_point_of] THEN
16857 MATCH_MP_TAC COUNTABLE_SUBSET THEN
16858 X_CHOOSE_THEN `b:(real^N->bool)->bool` STRIP_ASSUME_TAC
16859 UNIV_SECOND_COUNTABLE THEN
16861 `s INTER UNIONS { u:real^N->bool | u IN b /\ COUNTABLE(s INTER u)}` THEN
16862 REWRITE_TAC[INTER_UNIONS; IN_ELIM_THM] THEN CONJ_TAC THENL
16863 [MATCH_MP_TAC COUNTABLE_UNIONS THEN SIMP_TAC[FORALL_IN_GSPEC] THEN
16864 ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
16865 ASM_SIMP_TAC[COUNTABLE_IMAGE; COUNTABLE_RESTRICT];
16866 SIMP_TAC[SUBSET; UNIONS_GSPEC; IN_ELIM_THM; IN_INTER; IN_DIFF] THEN
16867 X_GEN_TAC `x:real^N` THEN
16868 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
16869 REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN
16870 X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN
16871 SUBGOAL_THEN `?u:real^N->bool. x IN u /\ u IN b /\ u SUBSET t` MP_TAC THENL
16872 [ASM SET_TAC[]; MATCH_MP_TAC MONO_EXISTS] THEN
16873 REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
16874 MATCH_MP_TAC COUNTABLE_SUBSET THEN
16875 EXISTS_TAC `s INTER t:real^N->bool` THEN ASM SET_TAC[]]);;
16877 let CARD_EQ_CONDENSATION_POINTS_IN_SET = prove
16879 ~(COUNTABLE s) ==> {x | x IN s /\ x condensation_point_of s} =_c s`,
16880 REPEAT STRIP_TAC THEN
16881 TRANS_TAC CARD_EQ_TRANS
16882 `(s DIFF {x | x condensation_point_of s}) +_c
16883 {x:real^N | x IN s /\ x condensation_point_of s}` THEN
16885 [ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN MATCH_MP_TAC CARD_ADD_ABSORB THEN
16886 MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
16887 [POP_ASSUM MP_TAC THEN REWRITE_TAC[INFINITE; CONTRAPOS_THM] THEN
16888 DISCH_THEN(MP_TAC o CONJ (SPEC `s:real^N->bool`
16889 COUNTABLE_NON_CONDENSATION_POINTS) o MATCH_MP FINITE_IMP_COUNTABLE) THEN
16890 REWRITE_TAC[GSYM COUNTABLE_UNION] THEN MATCH_MP_TAC EQ_IMP THEN
16891 AP_TERM_TAC THEN SET_TAC[];
16892 REWRITE_TAC[INFINITE_CARD_LE] THEN
16893 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] CARD_LE_TRANS) THEN
16894 REWRITE_TAC[GSYM COUNTABLE_ALT; COUNTABLE_NON_CONDENSATION_POINTS]];
16895 ONCE_REWRITE_TAC[CARD_EQ_SYM] THEN
16896 W(MP_TAC o PART_MATCH (rand o rand) CARD_DISJOINT_UNION o rand o snd) THEN
16897 ANTS_TAC THENL [SET_TAC[]; ALL_TAC] THEN
16898 MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN SET_TAC[]]);;
16900 (* ------------------------------------------------------------------------- *)
16901 (* A discrete set is countable, and an uncountable set has a limit point. *)
16902 (* ------------------------------------------------------------------------- *)
16904 let DISCRETE_IMP_COUNTABLE = prove
16906 (!x. x IN s ==> ?e. &0 < e /\
16907 !y. y IN s /\ ~(y = x) ==> e <= norm(y - x))
16909 REPEAT STRIP_TAC THEN
16912 ==> ?q. (!i. 1 <= i /\ i <= dimindex(:N) ==> rational(q$i)) /\
16913 !y:real^N. y IN s /\ ~(y = x) ==> norm(x - q) < norm(y - q)`
16915 [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
16916 FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
16917 DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
16918 MP_TAC(SET_RULE `x IN (:real^N)`) THEN
16919 REWRITE_TAC[GSYM CLOSURE_RATIONAL_COORDINATES] THEN
16920 REWRITE_TAC[CLOSURE_APPROACHABLE; IN_ELIM_THM] THEN
16921 DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
16922 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `q:real^N` THEN
16923 STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
16924 X_GEN_TAC `y:real^N` THEN STRIP_TAC THEN
16925 FIRST_X_ASSUM(MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[] THEN
16926 REPEAT(POP_ASSUM MP_TAC) THEN NORM_ARITH_TAC;
16927 POP_ASSUM(K ALL_TAC) THEN
16928 REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
16929 X_GEN_TAC `q:real^N->real^N` THEN DISCH_TAC THEN
16932 `{ x:real^N | !i. 1 <= i /\ i <= dimindex(:N) ==> rational(x$i) }`;
16933 `(:num)`] CARD_LE_TRANS) THEN
16934 REWRITE_TAC[COUNTABLE; ge_c] THEN DISCH_THEN MATCH_MP_TAC THEN
16935 SIMP_TAC[REWRITE_RULE[COUNTABLE; ge_c] COUNTABLE_RATIONAL_COORDINATES] THEN
16936 REWRITE_TAC[le_c] THEN EXISTS_TAC `q:real^N->real^N` THEN
16937 ASM_SIMP_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[REAL_LT_ANTISYM]]);;
16939 let UNCOUNTABLE_CONTAINS_LIMIT_POINT = prove
16940 (`!s. ~(COUNTABLE s) ==> ?x. x IN s /\ x limit_point_of s`,
16941 GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP
16942 (ONCE_REWRITE_RULE[GSYM CONTRAPOS_THM] DISCRETE_IMP_COUNTABLE)) THEN
16943 REWRITE_TAC[LIMPT_APPROACHABLE; GSYM REAL_NOT_LT; dist] THEN
16946 (* ------------------------------------------------------------------------- *)
16947 (* The Brouwer reduction theorem. *)
16948 (* ------------------------------------------------------------------------- *)
16950 let BROUWER_REDUCTION_THEOREM_GEN = prove
16951 (`!P s:real^N->bool.
16952 (!f. (!n. closed(f n) /\ P(f n)) /\ (!n. f(SUC n) SUBSET f(n))
16953 ==> P(INTERS {f n | n IN (:num)})) /\
16955 ==> ?t. t SUBSET s /\ closed t /\ P t /\
16956 (!u. u SUBSET s /\ closed u /\ P u ==> ~(u PSUBSET t))`,
16957 REPEAT STRIP_TAC THEN
16959 `?b:num->real^N->bool.
16960 (!m n. b m = b n <=> m = n) /\
16961 (!n. open (b n)) /\
16962 (!s. open s ==> (?k. s = UNIONS {b n | n IN k}))`
16963 STRIP_ASSUME_TAC THENL
16964 [REWRITE_TAC[UNIV_SECOND_COUNTABLE_SEQUENCE]; ALL_TAC] THEN
16965 X_CHOOSE_THEN `a:num->real^N->bool` MP_TAC
16966 (prove_recursive_functions_exist num_RECURSION
16967 `a 0 = (s:real^N->bool) /\
16969 if ?u. u SUBSET a(n) /\ closed u /\ P u /\ u INTER (b n) = {}
16970 then @u. u SUBSET a(n) /\ closed u /\ P u /\ u INTER (b n) = {}
16972 DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "base") (LABEL_TAC "step")) THEN
16973 EXISTS_TAC `INTERS {a n :real^N->bool | n IN (:num)}` THEN
16974 SUBGOAL_THEN `!n. (a:num->real^N->bool)(SUC n) SUBSET a(n)` ASSUME_TAC THENL
16975 [GEN_TAC THEN ASM_REWRITE_TAC[] THEN
16976 COND_CASES_TAC THEN REWRITE_TAC[SUBSET_REFL] THEN
16977 FIRST_X_ASSUM(MP_TAC o SELECT_RULE) THEN MESON_TAC[];
16979 SUBGOAL_THEN `!n. (a:num->real^N->bool) n SUBSET s` ASSUME_TAC THENL
16980 [INDUCT_TAC THEN ASM_MESON_TAC[SUBSET_REFL; SUBSET_TRANS]; ALL_TAC] THEN
16981 SUBGOAL_THEN `!n. closed((a:num->real^N->bool) n) /\ P(a n)` ASSUME_TAC THENL
16982 [INDUCT_TAC THEN ASM_REWRITE_TAC[] THEN
16983 COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
16984 FIRST_X_ASSUM(MP_TAC o SELECT_RULE) THEN MESON_TAC[];
16986 REPEAT CONJ_TAC THENL
16988 MATCH_MP_TAC CLOSED_INTERS THEN
16989 ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV] THEN SET_TAC[];
16990 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[];
16991 X_GEN_TAC `t:real^N->bool` THEN STRIP_TAC THEN
16992 REWRITE_TAC[PSUBSET_ALT] THEN
16993 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
16994 REWRITE_TAC[INTERS_GSPEC; EXISTS_IN_GSPEC; IN_UNIV] THEN
16995 DISCH_THEN(X_CHOOSE_THEN `x:real^N` STRIP_ASSUME_TAC) THEN
16997 `?n. x IN (b:num->real^N->bool)(n) /\ t INTER b n = {}`
16998 STRIP_ASSUME_TAC THENL
16999 [MP_TAC(ISPEC `(:real^N) DIFF t` OPEN_CONTAINS_BALL) THEN
17000 ASM_REWRITE_TAC[GSYM closed] THEN
17001 DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
17002 ASM_REWRITE_TAC[IN_DIFF; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN
17003 REWRITE_TAC[SET_RULE `s SUBSET UNIV DIFF t <=> t INTER s = {}`] THEN
17004 X_GEN_TAC `e:real` THEN
17005 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
17006 MP_TAC(ISPECL [`x:real^N`; `e:real`] CENTRE_IN_BALL) THEN
17007 FIRST_X_ASSUM(MP_TAC o SPEC `ball(x:real^N,e)`) THEN
17008 ASM_REWRITE_TAC[OPEN_BALL; LEFT_IMP_EXISTS_THM] THEN
17009 X_GEN_TAC `k:num->bool` THEN DISCH_THEN SUBST1_TAC THEN
17010 REWRITE_TAC[IN_UNIONS; INTER_UNIONS; EMPTY_UNIONS; FORALL_IN_GSPEC] THEN
17012 REMOVE_THEN "step" (MP_TAC o SPEC `n:num`) THEN
17013 COND_CASES_TAC THENL
17014 [DISCH_THEN(ASSUME_TAC o SYM) THEN
17015 FIRST_X_ASSUM(MP_TAC o SELECT_RULE) THEN ASM_REWRITE_TAC[] THEN
17017 FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN
17018 DISCH_THEN(MP_TAC o SPEC `t:real^N->bool`) THEN ASM_REWRITE_TAC[] THEN
17019 ASM SET_TAC[]]]]);;
17021 let BROUWER_REDUCTION_THEOREM = prove
17022 (`!P s:real^N->bool.
17023 (!f. (!n. compact(f n) /\ ~(f n = {}) /\ P(f n)) /\
17024 (!n. f(SUC n) SUBSET f(n))
17025 ==> P(INTERS {f n | n IN (:num)})) /\
17026 compact s /\ ~(s = {}) /\ P s
17027 ==> ?t. t SUBSET s /\ compact t /\ ~(t = {}) /\ P t /\
17028 (!u. u SUBSET s /\ closed u /\ ~(u = {}) /\ P u
17029 ==> ~(u PSUBSET t))`,
17030 REPEAT STRIP_TAC THEN
17031 MP_TAC(ISPECL [`\t:real^N->bool. ~(t = {}) /\ t SUBSET s /\ P t`;
17033 BROUWER_REDUCTION_THEOREM_GEN) THEN
17034 ASM_SIMP_TAC[COMPACT_IMP_CLOSED; SUBSET_REFL] THEN ANTS_TAC THENL
17035 [GEN_TAC THEN STRIP_TAC THEN
17036 SUBGOAL_THEN `!n. compact((f:num->real^N->bool) n)` ASSUME_TAC THENL
17037 [ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_SUBSET]; ALL_TAC] THEN
17038 REPEAT CONJ_TAC THENL
17039 [MATCH_MP_TAC COMPACT_NEST THEN ASM_REWRITE_TAC[] THEN
17040 MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN ASM_SIMP_TAC[] THEN SET_TAC[];
17042 FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]];
17043 MATCH_MP_TAC MONO_EXISTS THEN ASM_SIMP_TAC[] THEN
17044 ASM_MESON_TAC[COMPACT_EQ_BOUNDED_CLOSED; BOUNDED_SUBSET]]);;
17046 (* ------------------------------------------------------------------------- *)
17047 (* The Arzela-Ascoli theorem. *)
17048 (* ------------------------------------------------------------------------- *)
17050 let SUBSEQUENCE_DIAGONALIZATION_LEMMA = prove
17051 (`!P:num->(num->A)->bool.
17052 (!i r:num->A. ?k. (!m n. m < n ==> k m < k n) /\ P i (r o k)) /\
17053 (!i r:num->A k1 k2 N.
17054 P i (r o k1) /\ (!j. N <= j ==> ?j'. j <= j' /\ k2 j = k1 j')
17056 ==> !r:num->A. ?k. (!m n. m < n ==> k m < k n) /\ (!i. P i (r o k))`,
17057 REPEAT GEN_TAC THEN
17058 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
17059 GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [SKOLEM_THM] THEN
17060 REWRITE_TAC[FORALL_AND_THM; TAUT
17061 `(p ==> q /\ r) <=> (p ==> q) /\ (p ==> r)`] THEN
17062 DISCH_THEN(X_CHOOSE_THEN
17063 `kk:num->(num->A)->num->num` STRIP_ASSUME_TAC) THEN
17064 X_GEN_TAC `r:num->A` THEN
17065 (STRIP_ASSUME_TAC o prove_recursive_functions_exist num_RECURSION)
17066 `(rr 0 = (kk:num->(num->A)->num->num) 0 r) /\
17067 (!n. rr(SUC n) = rr n o kk (SUC n) (r o rr n))` THEN
17068 EXISTS_TAC `\n. (rr:num->num->num) n n` THEN REWRITE_TAC[ETA_AX] THEN
17070 `(!i. (!m n. m < n ==> (rr:num->num->num) i m < rr i n)) /\
17071 (!i. (P:num->(num->A)->bool) i (r o rr i))`
17072 STRIP_ASSUME_TAC THENL
17073 [REWRITE_TAC[AND_FORALL_THM] THEN
17074 INDUCT_TAC THEN ASM_REWRITE_TAC[o_ASSOC] THEN
17075 REWRITE_TAC[o_THM] THEN ASM_MESON_TAC[];
17077 SUBGOAL_THEN `!i j n. i <= j ==> (rr:num->num->num) i n <= rr j n`
17079 [REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [LE_EXISTS] THEN
17080 SIMP_TAC[LEFT_IMP_EXISTS_THM] THEN SPEC_TAC(`j:num`,`j:num`) THEN
17081 ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN SIMP_TAC[FORALL_UNWIND_THM2] THEN
17082 INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES; LE_REFL] THEN
17083 ASM_REWRITE_TAC[] THEN FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP
17084 (REWRITE_RULE[IMP_CONJ] LE_TRANS)) THEN REWRITE_TAC[o_THM] THEN
17085 FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP
17088 (!m n. m < n ==> f m < f n) ==> (!m n. m <= n ==> f m <= f n)`) o
17089 SPEC `i + d:num`) THEN
17090 SPEC_TAC(`n:num`,`n:num`) THEN MATCH_MP_TAC MONOTONE_BIGGER THEN
17094 [MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN DISCH_TAC THEN
17095 MATCH_MP_TAC LET_TRANS THEN
17096 EXISTS_TAC `(rr:num->num->num) n m` THEN
17097 ASM_MESON_TAC[LT_IMP_LE];
17100 `!m n i. n <= m ==> ?j. i <= j /\ (rr:num->num->num) m i = rr n j`
17103 X_GEN_TAC `i:num` THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
17104 EXISTS_TAC `(rr:num->num->num) i` THEN ASM_REWRITE_TAC[] THEN
17105 EXISTS_TAC `i:num` THEN ASM_MESON_TAC[]] THEN
17107 `!p d i. ?j. i <= j /\ (rr:num->num->num) (p + d) i = rr p j`
17108 (fun th -> MESON_TAC[LE_EXISTS; th]) THEN
17109 X_GEN_TAC `p:num` THEN MATCH_MP_TAC num_INDUCTION THEN
17110 ASM_REWRITE_TAC[ADD_CLAUSES] THEN CONJ_TAC THENL
17111 [MESON_TAC[LE_REFL]; ALL_TAC] THEN
17112 X_GEN_TAC `d:num` THEN DISCH_THEN(LABEL_TAC "+") THEN
17113 X_GEN_TAC `i:num` THEN ASM_REWRITE_TAC[o_THM] THEN
17114 REMOVE_THEN "+" (MP_TAC o SPEC
17115 `(kk:num->(num->A)->num->num) (SUC(p + d))
17116 ((r:num->A) o (rr:num->num->num) (p + d)) i`) THEN
17117 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `j:num` THEN
17118 MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
17119 MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LE_TRANS) THEN
17120 SPEC_TAC(`i:num`,`i:num`) THEN MATCH_MP_TAC MONOTONE_BIGGER THEN
17121 ASM_REWRITE_TAC[o_THM] THEN ASM_MESON_TAC[]);;
17123 let FUNCTION_CONVERGENT_SUBSEQUENCE = prove
17124 (`!f:num->real^M->real^N s M.
17125 COUNTABLE s /\ (!n x. x IN s ==> norm(f n x) <= M)
17126 ==> ?k. (!m n:num. m < n ==> k m < k n) /\
17127 !x. x IN s ==> ?l. ((\n. f (k n) x) --> l) sequentially`,
17128 REPEAT STRIP_TAC THEN
17129 ASM_CASES_TAC `s:real^M->bool = {}` THENL
17130 [EXISTS_TAC `\n:num. n` THEN ASM_REWRITE_TAC[NOT_IN_EMPTY];
17132 MP_TAC(ISPEC `s:real^M->bool` COUNTABLE_AS_IMAGE) THEN
17133 ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
17134 X_GEN_TAC `X:num->real^M` THEN DISCH_THEN SUBST_ALL_TAC THEN
17136 `\i r. ?l. ((\n. ((f:num->real^M->real^N) o (r:num->num)) n
17137 ((X:num->real^M) i)) --> l) sequentially`
17138 SUBSEQUENCE_DIAGONALIZATION_LEMMA) THEN
17139 REWRITE_TAC[FORALL_IN_IMAGE; o_THM; IN_UNIV] THEN
17140 ANTS_TAC THENL [ALL_TAC; DISCH_THEN MATCH_ACCEPT_TAC] THEN CONJ_TAC THENL
17141 [RULE_ASSUM_TAC(REWRITE_RULE[FORALL_IN_IMAGE; IN_UNIV]) THEN
17142 MAP_EVERY X_GEN_TAC [`i:num`; `r:num->num`] THEN
17143 MP_TAC(ISPEC `cball(vec 0:real^N,M)` compact) THEN
17144 REWRITE_TAC[COMPACT_CBALL] THEN DISCH_THEN(MP_TAC o SPEC
17145 `\n. (f:num->real^M->real^N) ((r:num->num) n) (X(i:num))`) THEN
17146 ASM_REWRITE_TAC[IN_CBALL_0; o_DEF] THEN MESON_TAC[];
17147 REPEAT GEN_TAC THEN REWRITE_TAC[LIM_SEQUENTIALLY; GE] THEN
17148 DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
17149 MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
17150 MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
17151 MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
17152 ASM_MESON_TAC[LE_TRANS; ARITH_RULE `MAX a b <= c <=> a <= c /\ b <= c`]]);;
17154 let ARZELA_ASCOLI = prove
17155 (`!f:num->real^M->real^N s M.
17157 (!n x. x IN s ==> norm(f n x) <= M) /\
17158 (!x e. x IN s /\ &0 < e
17160 !n y. y IN s /\ norm(x - y) < d
17161 ==> norm(f n x - f n y) < e)
17162 ==> ?g. g continuous_on s /\
17163 ?r. (!m n:num. m < n ==> r m < r n) /\
17165 ==> ?N. !n x. n >= N /\ x IN s
17166 ==> norm(f(r n) x - g x) < e`,
17167 REPEAT STRIP_TAC THEN REWRITE_TAC[GE] THEN
17168 MATCH_MP_TAC(MESON[]
17169 `(!k g. V k g ==> N g) /\ (?k. M k /\ ?g. V k g)
17170 ==> ?g. N g /\ ?k. M k /\ V k g`) THEN
17172 [MAP_EVERY X_GEN_TAC [`k:num->num`; `g:real^M->real^N`] THEN
17173 STRIP_TAC THEN MATCH_MP_TAC(ISPEC `sequentially`
17174 CONTINUOUS_UNIFORM_LIMIT) THEN
17175 EXISTS_TAC `(f:num->real^M->real^N) o (k:num->num)` THEN
17176 ASM_SIMP_TAC[EVENTUALLY_SEQUENTIALLY; o_THM; TRIVIAL_LIMIT_SEQUENTIALLY;
17177 RIGHT_IMP_FORALL_THM; IMP_IMP] THEN
17178 EXISTS_TAC `0` THEN REWRITE_TAC[continuous_on; dist] THEN
17179 ASM_MESON_TAC[NORM_SUB];
17182 [`IMAGE (f:num->real^M->real^N) (:num)`;
17184 COMPACT_UNIFORMLY_EQUICONTINUOUS) THEN
17185 REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE; IN_UNIV] THEN
17187 [REWRITE_TAC[dist] THEN ONCE_REWRITE_TAC[NORM_SUB] THEN ASM_MESON_TAC[];
17188 ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(K ALL_TAC o SPEC `x:real^M`)] THEN
17189 REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
17190 REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; dist] THEN
17191 DISCH_THEN(ASSUME_TAC o ONCE_REWRITE_RULE[NORM_SUB]) THEN
17192 REWRITE_TAC[GSYM dist; UNIFORMLY_CONVERGENT_EQ_CAUCHY] THEN
17193 X_CHOOSE_THEN `r:real^M->bool` STRIP_ASSUME_TAC
17194 (ISPEC `s:real^M->bool` SEPARABLE) THEN
17195 MP_TAC(ISPECL [`f:num->real^M->real^N`; `r:real^M->bool`; `M:real`]
17196 FUNCTION_CONVERGENT_SUBSEQUENCE) THEN
17197 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
17198 MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:num->num` THEN
17199 REWRITE_TAC[CONVERGENT_EQ_CAUCHY; cauchy] THEN
17200 DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*")) THEN
17201 ASM_REWRITE_TAC[] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
17202 FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN
17203 ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
17204 DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
17205 FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL]) THEN
17206 DISCH_THEN(MP_TAC o SPEC `IMAGE (\x:real^M. ball(x,d)) r`) THEN
17207 REWRITE_TAC[FORALL_IN_IMAGE; OPEN_BALL] THEN
17208 ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN
17209 REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE] THEN ANTS_TAC THENL
17210 [MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `closure r:real^M->bool` THEN
17211 ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET; CLOSURE_APPROACHABLE] THEN
17212 X_GEN_TAC `x:real^M` THEN DISCH_THEN(MP_TAC o SPEC `d:real`) THEN
17213 ASM_REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM; IN_BALL];
17214 DISCH_THEN(X_CHOOSE_THEN `t:real^M->bool` STRIP_ASSUME_TAC)] THEN
17215 REMOVE_THEN "*" MP_TAC THEN REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
17216 GEN_REWRITE_TAC LAND_CONV [SWAP_FORALL_THM] THEN
17217 DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
17218 ASM_REWRITE_TAC[REAL_ARITH `&0 < e / &3 <=> &0 < e`] THEN
17219 GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
17220 REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
17221 X_GEN_TAC `M:real^M->num` THEN DISCH_THEN(LABEL_TAC "*") THEN
17222 MP_TAC(ISPECL [`M:real^M->num`; `t:real^M->bool`]
17223 UPPER_BOUND_FINITE_SET) THEN
17224 ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
17226 MAP_EVERY X_GEN_TAC [`m:num`; `n:num`; `x:real^M`] THEN STRIP_TAC THEN
17227 UNDISCH_TAC `s SUBSET UNIONS (IMAGE (\x:real^M. ball (x,d)) t)` THEN
17228 REWRITE_TAC[SUBSET; UNIONS_IMAGE; IN_ELIM_THM] THEN
17229 DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN
17230 ASM_REWRITE_TAC[IN_BALL; LEFT_IMP_EXISTS_THM; dist] THEN
17231 X_GEN_TAC `y:real^M` THEN STRIP_TAC THEN
17232 MATCH_MP_TAC(NORM_ARITH
17233 `norm(f (k(m:num)) y - f (k m) x) < e / &3 /\
17234 norm(f (k n) y - f (k n) x) < e / &3 /\
17235 norm(f (k m) y - f (k n) y) < e / &3
17236 ==> norm(f (k m) x - f (k n) x :real^M) < e`) THEN
17237 ASM_SIMP_TAC[] THEN REMOVE_THEN "*" (MP_TAC o SPEC `y:real^M`) THEN
17238 ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
17239 DISCH_THEN(MP_TAC o SPECL [`m:num`; `n:num`]) THEN
17240 ASM_REWRITE_TAC[dist; GE] THEN ASM_MESON_TAC[SUBSET; LE_TRANS]);;