Update from HH
[hl193./.git] / Multivariate / realanalysis.ml
1 (* ========================================================================= *)
2 (* Some analytic concepts for R instead of R^1.                              *)
3 (*                                                                           *)
4 (*              (c) Copyright, John Harrison 1998-2008                       *)
5 (* ========================================================================= *)
6
7 needs "Library/binomial.ml";;
8 needs "Multivariate/measure.ml";;
9 needs "Multivariate/polytope.ml";;
10 needs "Multivariate/transcendentals.ml";;
11
12 (* ------------------------------------------------------------------------- *)
13 (* Open-ness and closedness of a set of reals.                               *)
14 (* ------------------------------------------------------------------------- *)
15
16 let real_open = new_definition
17   `real_open s <=>
18       !x. x IN s ==> ?e. &0 < e /\ !x'. abs(x' - x) < e ==> x' IN s`;;
19
20 let real_closed = new_definition
21  `real_closed s <=> real_open((:real) DIFF s)`;;
22
23 let euclideanreal = new_definition
24  `euclideanreal = topology real_open`;;
25
26 let REAL_OPEN_EMPTY = prove
27  (`real_open {}`,
28   REWRITE_TAC[real_open; NOT_IN_EMPTY]);;
29
30 let REAL_OPEN_UNIV = prove
31  (`real_open(:real)`,
32   REWRITE_TAC[real_open; IN_UNIV] THEN MESON_TAC[REAL_LT_01]);;
33
34 let REAL_OPEN_INTER = prove
35  (`!s t. real_open s /\ real_open t ==> real_open (s INTER t)`,
36   REPEAT GEN_TAC THEN REWRITE_TAC[real_open; AND_FORALL_THM; IN_INTER] THEN
37   MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
38   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
39   ASM_REWRITE_TAC[] THEN DISCH_THEN(CONJUNCTS_THEN2
40    (X_CHOOSE_TAC `d1:real`) (X_CHOOSE_TAC `d2:real`)) THEN
41   MP_TAC(SPECL [`d1:real`; `d2:real`] REAL_DOWN2) THEN
42   ASM_MESON_TAC[REAL_LT_TRANS]);;
43
44 let REAL_OPEN_UNIONS = prove
45  (`(!s. s IN f ==> real_open s) ==> real_open(UNIONS f)`,
46   REWRITE_TAC[real_open; IN_UNIONS] THEN MESON_TAC[]);;
47
48 let REAL_OPEN_IN = prove
49  (`!s. real_open s <=> open_in euclideanreal s`,
50   GEN_TAC THEN REWRITE_TAC[euclideanreal] THEN CONV_TAC SYM_CONV THEN
51   AP_THM_TAC THEN REWRITE_TAC[GSYM(CONJUNCT2 topology_tybij)] THEN
52   REWRITE_TAC[REWRITE_RULE[IN] istopology] THEN
53   REWRITE_TAC[REAL_OPEN_EMPTY; REAL_OPEN_INTER; SUBSET] THEN
54   MESON_TAC[IN; REAL_OPEN_UNIONS]);;
55
56 let TOPSPACE_EUCLIDEANREAL = prove
57  (`topspace euclideanreal = (:real)`,
58   REWRITE_TAC[topspace; EXTENSION; IN_UNIV; IN_UNIONS; IN_ELIM_THM] THEN
59   MESON_TAC[REAL_OPEN_UNIV; IN_UNIV; REAL_OPEN_IN]);;
60
61 let TOPSPACE_EUCLIDEANREAL_SUBTOPOLOGY = prove
62  (`!s. topspace (subtopology euclideanreal s) = s`,
63   REWRITE_TAC[TOPSPACE_EUCLIDEANREAL; TOPSPACE_SUBTOPOLOGY; INTER_UNIV]);;
64
65 let REAL_CLOSED_IN = prove
66  (`!s. real_closed s <=> closed_in euclideanreal s`,
67   REWRITE_TAC[real_closed; closed_in; TOPSPACE_EUCLIDEANREAL;
68               REAL_OPEN_IN; SUBSET_UNIV]);;
69
70 let REAL_OPEN_UNION = prove
71  (`!s t. real_open s /\ real_open t ==> real_open(s UNION t)`,
72   REWRITE_TAC[REAL_OPEN_IN; OPEN_IN_UNION]);;
73
74 let REAL_OPEN_SUBREAL_OPEN = prove
75  (`!s. real_open s <=> !x. x IN s ==> ?t. real_open t /\ x IN t /\ t SUBSET s`,
76   REWRITE_TAC[REAL_OPEN_IN; GSYM OPEN_IN_SUBOPEN]);;
77
78 let REAL_CLOSED_EMPTY = prove
79  (`real_closed {}`,
80   REWRITE_TAC[REAL_CLOSED_IN; CLOSED_IN_EMPTY]);;
81
82 let REAL_CLOSED_UNIV = prove
83  (`real_closed(:real)`,
84   REWRITE_TAC[REAL_CLOSED_IN; GSYM TOPSPACE_EUCLIDEANREAL; CLOSED_IN_TOPSPACE]);;
85
86 let REAL_CLOSED_UNION = prove
87  (`!s t. real_closed s /\ real_closed t ==> real_closed(s UNION t)`,
88   REWRITE_TAC[REAL_CLOSED_IN; CLOSED_IN_UNION]);;
89
90 let REAL_CLOSED_INTER = prove
91  (`!s t. real_closed s /\ real_closed t ==> real_closed(s INTER t)`,
92   REWRITE_TAC[REAL_CLOSED_IN; CLOSED_IN_INTER]);;
93
94 let REAL_CLOSED_INTERS = prove
95  (`!f. (!s. s IN f ==> real_closed s) ==> real_closed(INTERS f)`,
96   REWRITE_TAC[REAL_CLOSED_IN] THEN REPEAT STRIP_TAC THEN
97   ASM_CASES_TAC `f:(real->bool)->bool = {}` THEN
98   ASM_SIMP_TAC[CLOSED_IN_INTERS; INTERS_0] THEN
99   REWRITE_TAC[GSYM TOPSPACE_EUCLIDEANREAL; CLOSED_IN_TOPSPACE]);;
100
101 let REAL_OPEN_REAL_CLOSED = prove
102  (`!s. real_open s <=> real_closed(UNIV DIFF s)`,
103   SIMP_TAC[REAL_OPEN_IN; REAL_CLOSED_IN; TOPSPACE_EUCLIDEANREAL; SUBSET_UNIV;
104            OPEN_IN_CLOSED_IN_EQ]);;
105
106 let REAL_OPEN_DIFF = prove
107  (`!s t. real_open s /\ real_closed t ==> real_open(s DIFF t)`,
108   REWRITE_TAC[REAL_OPEN_IN; REAL_CLOSED_IN; OPEN_IN_DIFF]);;
109
110 let REAL_CLOSED_DIFF = prove
111  (`!s t. real_closed s /\ real_open t ==> real_closed(s DIFF t)`,
112   REWRITE_TAC[REAL_OPEN_IN; REAL_CLOSED_IN; CLOSED_IN_DIFF]);;
113
114 let REAL_OPEN_INTERS = prove
115  (`!s. FINITE s /\ (!t. t IN s ==> real_open t) ==> real_open(INTERS s)`,
116   REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
117   REWRITE_TAC[INTERS_INSERT; INTERS_0; REAL_OPEN_UNIV; IN_INSERT] THEN
118   MESON_TAC[REAL_OPEN_INTER]);;
119
120 let REAL_CLOSED_UNIONS = prove
121  (`!s. FINITE s /\ (!t. t IN s ==> real_closed t) ==> real_closed(UNIONS s)`,
122   REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
123   REWRITE_TAC[UNIONS_INSERT; UNIONS_0; REAL_CLOSED_EMPTY; IN_INSERT] THEN
124   MESON_TAC[REAL_CLOSED_UNION]);;
125
126 let REAL_OPEN = prove
127  (`!s. real_open s <=> open(IMAGE lift s)`,
128   REWRITE_TAC[real_open; open_def; FORALL_IN_IMAGE; FORALL_LIFT; DIST_LIFT;
129               LIFT_IN_IMAGE_LIFT]);;
130
131 let REAL_CLOSED = prove
132  (`!s. real_closed s <=> closed(IMAGE lift s)`,
133   GEN_TAC THEN REWRITE_TAC[real_closed; REAL_OPEN; closed] THEN
134   AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_IMAGE; IN_DIFF; IN_UNIV] THEN
135   MESON_TAC[LIFT_DROP]);;
136
137 let REAL_CLOSED_HALFSPACE_LE = prove
138  (`!a. real_closed {x | x <= a}`,
139   GEN_TAC THEN SUBGOAL_THEN `closed {x | drop x <= a}` MP_TAC THENL
140    [REWRITE_TAC[drop; CLOSED_HALFSPACE_COMPONENT_LE]; ALL_TAC] THEN
141   MATCH_MP_TAC EQ_IMP THEN REWRITE_TAC[REAL_CLOSED] THEN AP_TERM_TAC THEN
142   REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);;
143
144 let REAL_CLOSED_HALFSPACE_GE = prove
145  (`!a. real_closed {x | x >= a}`,
146   GEN_TAC THEN SUBGOAL_THEN `closed {x | drop x >= a}` MP_TAC THENL
147    [REWRITE_TAC[drop; CLOSED_HALFSPACE_COMPONENT_GE]; ALL_TAC] THEN
148   MATCH_MP_TAC EQ_IMP THEN REWRITE_TAC[REAL_CLOSED] THEN AP_TERM_TAC THEN
149   REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);;
150
151 let REAL_OPEN_HALFSPACE_LT = prove
152  (`!a. real_open {x | x < a}`,
153   GEN_TAC THEN SUBGOAL_THEN `open {x | drop x < a}` MP_TAC THENL
154    [REWRITE_TAC[drop; OPEN_HALFSPACE_COMPONENT_LT]; ALL_TAC] THEN
155   MATCH_MP_TAC EQ_IMP THEN REWRITE_TAC[REAL_OPEN] THEN AP_TERM_TAC THEN
156   REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);;
157
158 let REAL_OPEN_HALFSPACE_GT = prove
159  (`!a. real_open {x | x > a}`,
160   GEN_TAC THEN SUBGOAL_THEN `open {x | drop x > a}` MP_TAC THENL
161    [REWRITE_TAC[drop; OPEN_HALFSPACE_COMPONENT_GT]; ALL_TAC] THEN
162   MATCH_MP_TAC EQ_IMP THEN REWRITE_TAC[REAL_OPEN] THEN AP_TERM_TAC THEN
163   REWRITE_TAC[EXTENSION; IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);;
164
165 (* ------------------------------------------------------------------------- *)
166 (* Compactness of a set of reals.                                            *)
167 (* ------------------------------------------------------------------------- *)
168
169 let real_bounded = new_definition
170  `real_bounded s <=> ?B. !x. x IN s ==> abs(x) <= B`;;
171
172 let REAL_BOUNDED = prove
173  (`real_bounded s <=> bounded(IMAGE lift s)`,
174   REWRITE_TAC[BOUNDED_LIFT; real_bounded]);;
175
176 let REAL_BOUNDED_POS = prove
177  (`!s. real_bounded s <=> ?B. &0 < B /\ !x. x IN s ==> abs(x) <= B`,
178   REWRITE_TAC[real_bounded] THEN
179   MESON_TAC[REAL_ARITH `&0 < &1 + abs B /\ (x <= B ==> x <= &1 + abs B)`]);;
180
181 let REAL_BOUNDED_POS_LT = prove
182  (`!s. real_bounded s <=> ?b. &0 < b /\ !x. x IN s ==> abs(x) < b`,
183   REWRITE_TAC[real_bounded] THEN
184   MESON_TAC[REAL_LT_IMP_LE;
185             REAL_ARITH `&0 < &1 + abs(y) /\ (x <= y ==> x < &1 + abs(y))`]);;
186
187 let REAL_BOUNDED_SUBSET = prove
188  (`!s t. real_bounded t /\ s SUBSET t ==> real_bounded s`,
189   MESON_TAC[REAL_BOUNDED; BOUNDED_SUBSET; IMAGE_SUBSET]);;
190
191 let REAL_BOUNDED_UNION = prove
192  (`!s t. real_bounded(s UNION t) <=> real_bounded s /\ real_bounded t`,
193   REWRITE_TAC[REAL_BOUNDED; IMAGE_UNION; BOUNDED_UNION]);;
194
195 let real_compact = new_definition
196  `real_compact s <=> compact(IMAGE lift s)`;;
197
198 let REAL_COMPACT_IMP_BOUNDED = prove
199  (`!s. real_compact s ==> real_bounded s`,
200   REWRITE_TAC[real_compact; REAL_BOUNDED; COMPACT_IMP_BOUNDED]);;
201
202 let REAL_COMPACT_IMP_CLOSED = prove
203  (`!s. real_compact s ==> real_closed s`,
204   REWRITE_TAC[real_compact; REAL_CLOSED; COMPACT_IMP_CLOSED]);;
205
206 let REAL_COMPACT_EQ_BOUNDED_CLOSED = prove
207  (`!s. real_compact s <=> real_bounded s /\ real_closed s`,
208   REWRITE_TAC[real_compact; REAL_BOUNDED; REAL_CLOSED] THEN
209   REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED]);;
210
211 let REAL_COMPACT_UNION = prove
212  (`!s t. real_compact s /\ real_compact t ==> real_compact(s UNION t)`,
213   REWRITE_TAC[real_compact; IMAGE_UNION; COMPACT_UNION]);;
214
215 let REAL_COMPACT_ATTAINS_INF = prove
216  (`!s. real_compact s /\ ~(s = {}) ==> ?x. x IN s /\ !y. y IN s ==> x <= y`,
217   REWRITE_TAC[real_compact; COMPACT_ATTAINS_INF]);;
218
219 let REAL_COMPACT_ATTAINS_SUP = prove
220  (`!s. real_compact s /\ ~(s = {}) ==> ?x. x IN s /\ !y. y IN s ==> y <= x`,
221   REWRITE_TAC[real_compact; COMPACT_ATTAINS_SUP]);;
222
223 (* ------------------------------------------------------------------------- *)
224 (* Limits of functions with real range.                                      *)
225 (* ------------------------------------------------------------------------- *)
226
227 parse_as_infix("--->",(12,"right"));;
228
229 let tendsto_real = new_definition
230   `(f ---> l) net <=> !e. &0 < e ==> eventually (\x. abs(f(x) - l) < e) net`;;
231
232 let reallim = new_definition
233  `reallim net f = @l. (f ---> l) net`;;
234
235 let TENDSTO_REAL = prove
236  (`(s ---> l) = ((lift o s) --> lift l)`,
237   REWRITE_TAC[FUN_EQ_THM; tendsto; tendsto_real; o_THM; DIST_LIFT]);;
238
239 let REAL_TENDSTO = prove
240  (`(s --> l) = (drop o s ---> drop l)`,
241   REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_DROP; ETA_AX]);;
242
243 let REALLIM_COMPLEX = prove
244  (`(s ---> l) = ((Cx o s) --> Cx(l))`,
245   REWRITE_TAC[FUN_EQ_THM; tendsto; tendsto_real; o_THM; dist;
246               GSYM CX_SUB; COMPLEX_NORM_CX]);;
247
248 let REALLIM_UNIQUE = prove
249  (`!net f l l'.
250          ~trivial_limit net /\ (f ---> l) net /\ (f ---> l') net ==> l = l'`,
251   REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN
252   DISCH_THEN(MP_TAC o MATCH_MP LIM_UNIQUE) THEN REWRITE_TAC[LIFT_EQ]);;
253
254 let REALLIM_CONST = prove
255  (`!net a. ((\x. a) ---> a) net`,
256   REWRITE_TAC[TENDSTO_REAL; o_DEF; LIM_CONST]);;
257
258 let REALLIM_LMUL = prove
259  (`!f l c. (f ---> l) net ==> ((\x. c * f x) ---> c * l) net`,
260   REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_CMUL; LIM_CMUL]);;
261
262 let REALLIM_RMUL = prove
263  (`!f l c. (f ---> l) net ==> ((\x. f x * c) ---> l * c) net`,
264   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[REALLIM_LMUL]);;
265
266 let REALLIM_LMUL_EQ = prove
267  (`!net f l c.
268         ~(c = &0) ==> (((\x. c * f x) ---> c * l) net <=> (f ---> l) net)`,
269   REPEAT STRIP_TAC THEN EQ_TAC THEN SIMP_TAC[REALLIM_LMUL] THEN
270   DISCH_THEN(MP_TAC o SPEC `inv c:real` o MATCH_MP REALLIM_LMUL) THEN
271   ASM_SIMP_TAC[REAL_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_LID; ETA_AX]);;
272
273 let REALLIM_RMUL_EQ = prove
274  (`!net f l c.
275         ~(c = &0) ==> (((\x. f x * c) ---> l * c) net <=> (f ---> l) net)`,
276   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[REALLIM_LMUL_EQ]);;
277
278 let REALLIM_NEG = prove
279  (`!net f l. (f ---> l) net ==> ((\x. --(f x)) ---> --l) net`,
280   REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_NEG; LIM_NEG]);;
281
282 let REALLIM_NEG_EQ = prove
283  (`!net f l. ((\x. --(f x)) ---> --l) net <=> (f ---> l) net`,
284   REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_NEG; LIM_NEG_EQ]);;
285
286 let REALLIM_ADD = prove
287  (`!net:(A)net f g l m.
288     (f ---> l) net /\ (g ---> m) net ==> ((\x. f(x) + g(x)) ---> l + m) net`,
289   REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_ADD; LIM_ADD]);;
290
291 let REALLIM_SUB = prove
292  (`!net:(A)net f g l m.
293     (f ---> l) net /\ (g ---> m) net ==> ((\x. f(x) - g(x)) ---> l - m) net`,
294   REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_SUB; LIM_SUB]);;
295
296 let REALLIM_MUL = prove
297  (`!net:(A)net f g l m.
298     (f ---> l) net /\ (g ---> m) net ==> ((\x. f(x) * g(x)) ---> l * m) net`,
299   REWRITE_TAC[REALLIM_COMPLEX; o_DEF; CX_MUL; LIM_COMPLEX_MUL]);;
300
301 let REALLIM_INV = prove
302  (`!net f l.
303          (f ---> l) net /\ ~(l = &0) ==> ((\x. inv(f x)) ---> inv l) net`,
304   REWRITE_TAC[REALLIM_COMPLEX; o_DEF; CX_INV; LIM_COMPLEX_INV; GSYM CX_INJ]);;
305
306 let REALLIM_DIV = prove
307  (`!net:(A)net f g l m.
308     (f ---> l) net /\ (g ---> m) net /\ ~(m = &0)
309     ==> ((\x. f(x) / g(x)) ---> l / m) net`,
310   SIMP_TAC[real_div; REALLIM_MUL; REALLIM_INV]);;
311
312 let REALLIM_ABS = prove
313  (`!net f l. (f ---> l) net ==> ((\x. abs(f x)) ---> abs l) net`,
314   REPEAT GEN_TAC THEN REWRITE_TAC[tendsto_real] THEN
315   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
316   DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
317   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
318   REWRITE_TAC[] THEN REAL_ARITH_TAC);;
319
320 let REALLIM_POW = prove
321  (`!net f l n. (f ---> l) net ==> ((\x. f x pow n) ---> l pow n) net`,
322   REPLICATE_TAC 3 GEN_TAC THEN
323   INDUCT_TAC THEN ASM_SIMP_TAC[real_pow; REALLIM_CONST; REALLIM_MUL]);;
324
325 let REALLIM_MAX = prove
326  (`!net:(A)net f g l m.
327     (f ---> l) net /\ (g ---> m) net
328     ==> ((\x. max (f x) (g x)) ---> max l m) net`,
329   REWRITE_TAC[REAL_ARITH `max x y = inv(&2) * ((x + y) + abs(x - y))`] THEN
330   REPEAT STRIP_TAC THEN MATCH_MP_TAC REALLIM_LMUL THEN
331   ASM_SIMP_TAC[REALLIM_ADD; REALLIM_ABS; REALLIM_SUB]);;
332
333 let REALLIM_MIN = prove
334  (`!net:(A)net f g l m.
335     (f ---> l) net /\ (g ---> m) net
336     ==> ((\x. min (f x) (g x)) ---> min l m) net`,
337   REWRITE_TAC[REAL_ARITH `min x y = inv(&2) * ((x + y) - abs(x - y))`] THEN
338   REPEAT STRIP_TAC THEN MATCH_MP_TAC REALLIM_LMUL THEN
339   ASM_SIMP_TAC[REALLIM_ADD; REALLIM_ABS; REALLIM_SUB]);;
340
341 let REALLIM_NULL = prove
342  (`!net f l. (f ---> l) net <=> ((\x. f(x) - l) ---> &0) net`,
343   REWRITE_TAC[tendsto_real; REAL_SUB_RZERO]);;
344
345 let REALLIM_NULL_ADD = prove
346  (`!net:(A)net f g.
347     (f ---> &0) net /\ (g ---> &0) net ==> ((\x. f(x) + g(x)) ---> &0) net`,
348   REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP REALLIM_ADD) THEN
349   REWRITE_TAC[REAL_ADD_LID]);;
350
351 let REALLIM_NULL_LMUL = prove
352  (`!net f c. (f ---> &0) net ==> ((\x. c * f x) ---> &0) net`,
353   REPEAT GEN_TAC THEN
354   DISCH_THEN(MP_TAC o SPEC `c:real` o MATCH_MP REALLIM_LMUL) THEN
355   REWRITE_TAC[REAL_MUL_RZERO]);;
356
357 let REALLIM_NULL_RMUL = prove
358  (`!net f c. (f ---> &0) net ==> ((\x. f x * c) ---> &0) net`,
359   REPEAT GEN_TAC THEN
360   DISCH_THEN(MP_TAC o SPEC `c:real` o MATCH_MP REALLIM_RMUL) THEN
361   REWRITE_TAC[REAL_MUL_LZERO]);;
362
363 let REALLIM_NULL_POW = prove
364  (`!net f n. (f ---> &0) net /\ ~(n = 0) ==> ((\x. f x pow n) ---> &0) net`,
365   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2
366    (MP_TAC o SPEC `n:num` o MATCH_MP REALLIM_POW) ASSUME_TAC) THEN
367   ASM_REWRITE_TAC[REAL_POW_ZERO]);;
368
369 let REALLIM_NULL_LMUL_EQ = prove
370  (`!net f c.
371         ~(c = &0) ==> (((\x. c * f x) ---> &0) net <=> (f ---> &0) net)`,
372   MESON_TAC[REALLIM_LMUL_EQ; REAL_MUL_RZERO]);;
373
374 let REALLIM_NULL_RMUL_EQ = prove
375  (`!net f c.
376         ~(c = &0) ==> (((\x. f x * c) ---> &0) net <=> (f ---> &0) net)`,
377   MESON_TAC[REALLIM_RMUL_EQ; REAL_MUL_LZERO]);;
378
379 let REALLIM_NULL_NEG = prove
380  (`!net f. ((\x. --(f x)) ---> &0) net <=> (f ---> &0) net`,
381   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[REAL_ARITH `--x = --(&1) * x`] THEN
382   MATCH_MP_TAC REALLIM_NULL_LMUL_EQ THEN CONV_TAC REAL_RAT_REDUCE_CONV);;
383
384 let REALLIM_RE = prove
385  (`!net f l. (f --> l) net ==> ((Re o f) ---> Re l) net`,
386   REWRITE_TAC[REALLIM_COMPLEX] THEN
387   REWRITE_TAC[tendsto; dist; o_THM; GSYM CX_SUB; COMPLEX_NORM_CX] THEN
388   REWRITE_TAC[GSYM RE_SUB; eventually] THEN
389   MESON_TAC[REAL_LET_TRANS; COMPLEX_NORM_GE_RE_IM]);;
390
391 let REALLIM_IM = prove
392  (`!net f l. (f --> l) net ==> ((Im o f) ---> Im l) net`,
393   REWRITE_TAC[REALLIM_COMPLEX] THEN
394   REWRITE_TAC[tendsto; dist; o_THM; GSYM CX_SUB; COMPLEX_NORM_CX] THEN
395   REWRITE_TAC[GSYM IM_SUB; eventually] THEN
396   MESON_TAC[REAL_LET_TRANS; COMPLEX_NORM_GE_RE_IM]);;
397
398 let REALLIM_TRANSFORM_EVENTUALLY = prove
399  (`!net f g l.
400         eventually (\x. f x = g x) net /\ (f ---> l) net ==> (g ---> l) net`,
401   REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN
402   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
403   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN
404   POP_ASSUM MP_TAC THEN
405   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
406   SIMP_TAC[o_THM]);;
407
408 let REALLIM_TRANSFORM = prove
409  (`!net f g l.
410         ((\x. f x - g x) ---> &0) net /\ (f ---> l) net ==> (g ---> l) net`,
411   REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN
412   REWRITE_TAC[o_DEF; LIFT_NUM; LIFT_SUB; LIM_TRANSFORM]);;
413
414 let REALLIM_TRANSFORM_EQ = prove
415  (`!net f:A->real g l.
416      ((\x. f x - g x) ---> &0) net ==> ((f ---> l) net <=> (g ---> l) net)`,
417   REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN
418   REWRITE_TAC[o_DEF; LIFT_NUM; LIFT_SUB; LIM_TRANSFORM_EQ]);;
419
420 let REAL_SEQ_OFFSET = prove
421  (`!f l k. (f ---> l) sequentially ==> ((\i. f (i + k)) ---> l) sequentially`,
422   REPEAT GEN_TAC THEN SIMP_TAC[TENDSTO_REAL; o_DEF] THEN
423   DISCH_THEN(MP_TAC o MATCH_MP SEQ_OFFSET) THEN SIMP_TAC[]);;
424
425 let REAL_SEQ_OFFSET_REV = prove
426  (`!f l k. ((\i. f (i + k)) ---> l) sequentially ==> (f ---> l) sequentially`,
427   SIMP_TAC[TENDSTO_REAL; o_DEF] THEN REPEAT STRIP_TAC THEN
428   MATCH_MP_TAC SEQ_OFFSET_REV THEN EXISTS_TAC `k:num` THEN ASM_SIMP_TAC[]);;
429
430 let REALLIM_TRANSFORM_STRADDLE = prove
431  (`!f g h a.
432         eventually (\n. f(n) <= g(n)) net /\ (f ---> a) net /\
433         eventually (\n. g(n) <= h(n)) net /\ (h ---> a) net
434         ==> (g ---> a) net`,
435   REPEAT GEN_TAC THEN
436   REWRITE_TAC[RIGHT_AND_FORALL_THM; tendsto_real; AND_FORALL_THM] THEN
437   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
438   ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
439   REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
440   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
441   REAL_ARITH_TAC);;
442
443 let REALLIM_TRANSFORM_BOUND = prove
444  (`!f g. eventually (\n. abs(f n) <= g n) net /\ (g ---> &0) net
445          ==> (f ---> &0) net`,
446   REPEAT GEN_TAC THEN
447   REWRITE_TAC[RIGHT_AND_FORALL_THM; tendsto_real; AND_FORALL_THM] THEN
448   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
449   ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
450   REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
451   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
452   REAL_ARITH_TAC);;
453
454 let REAL_CONVERGENT_IMP_BOUNDED = prove
455  (`!s l. (s ---> l) sequentially ==> real_bounded (IMAGE s (:num))`,
456   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_BOUNDED; TENDSTO_REAL] THEN
457   DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN
458   REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; IN_UNIV] THEN
459   REWRITE_TAC[o_DEF; NORM_LIFT]);;
460
461 let REALLIM = prove
462  (`(f ---> l) net <=>
463         trivial_limit net \/
464         !e. &0 < e ==> ?y. (?x. netord(net) x y) /\
465                            !x. netord(net) x y ==> abs(f(x) -l) < e`,
466   REWRITE_TAC[tendsto_real; eventually] THEN MESON_TAC[]);;
467
468 let REALLIM_NULL_ABS = prove
469  (`!net f. ((\x. abs(f x)) ---> &0) net <=> (f ---> &0) net`,
470   REWRITE_TAC[REALLIM; REAL_SUB_RZERO; REAL_ABS_ABS]);;
471
472 let REALLIM_WITHIN_LE = prove
473  (`!f:real^N->real l a s.
474         (f ---> l) (at a within s) <=>
475            !e. &0 < e ==> ?d. &0 < d /\
476                               !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) <= d
477                                    ==> abs(f(x) - l) < e`,
478   REWRITE_TAC[tendsto_real; EVENTUALLY_WITHIN_LE]);;
479
480 let REALLIM_WITHIN = prove
481  (`!f:real^N->real l a s.
482       (f ---> l) (at a within s) <=>
483         !e. &0 < e
484             ==> ?d. &0 < d /\
485                     !x. x IN s /\ &0 < dist(x,a) /\ dist(x,a) < d
486                     ==> abs(f(x) - l) < e`,
487   REWRITE_TAC[tendsto_real; EVENTUALLY_WITHIN] THEN MESON_TAC[]);;
488
489 let REALLIM_AT = prove
490  (`!f l a:real^N.
491       (f ---> l) (at a) <=>
492               !e. &0 < e
493                   ==> ?d. &0 < d /\ !x. &0 < dist(x,a) /\ dist(x,a) < d
494                           ==> abs(f(x) - l) < e`,
495   REWRITE_TAC[tendsto_real; EVENTUALLY_AT] THEN MESON_TAC[]);;
496
497 let REALLIM_AT_INFINITY = prove
498  (`!f l. (f ---> l) at_infinity <=>
499                !e. &0 < e ==> ?b. !x. norm(x) >= b ==> abs(f(x) - l) < e`,
500   REWRITE_TAC[tendsto_real; EVENTUALLY_AT_INFINITY] THEN MESON_TAC[]);;
501
502 let REALLIM_AT_INFINITY_COMPLEX_0 = prove
503  (`!f l. (f ---> l) at_infinity <=> ((f o inv) ---> l) (at(Cx(&0)))`,
504   REWRITE_TAC[REALLIM_COMPLEX; LIM_AT_INFINITY_COMPLEX_0] THEN
505   REWRITE_TAC[o_ASSOC]);;
506
507 let REALLIM_SEQUENTIALLY = prove
508  (`!s l. (s ---> l) sequentially <=>
509           !e. &0 < e ==> ?N. !n. N <= n ==> abs(s(n) - l) < e`,
510   REWRITE_TAC[tendsto_real; EVENTUALLY_SEQUENTIALLY] THEN MESON_TAC[]);;
511
512 let REALLIM_EVENTUALLY = prove
513  (`!net f l. eventually (\x. f x = l) net ==> (f ---> l) net`,
514   REWRITE_TAC[eventually; REALLIM] THEN
515   MESON_TAC[REAL_ARITH `abs(x - x) = &0`]);;
516
517 let LIM_COMPONENTWISE = prove
518  (`!net f:A->real^N.
519         (f --> l) net <=>
520         !i. 1 <= i /\ i <= dimindex(:N) ==> ((\x. (f x)$i) ---> l$i) net`,
521   ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT] THEN
522   REWRITE_TAC[TENDSTO_REAL; o_DEF]);;
523
524 let REALLIM_UBOUND = prove
525  (`!(net:A net) f l b.
526         (f ---> l) net /\
527         ~trivial_limit net /\
528         eventually (\x. f x <= b) net
529         ==> l <= b`,
530   REWRITE_TAC[FORALL_DROP; TENDSTO_REAL; LIFT_DROP] THEN
531   REPEAT STRIP_TAC THEN
532   MATCH_MP_TAC(ISPEC `net:A net` LIM_DROP_UBOUND) THEN
533   EXISTS_TAC `lift o (f:A->real)` THEN
534   ASM_REWRITE_TAC[o_THM; LIFT_DROP]);;
535
536 let REALLIM_LBOUND = prove
537  (`!(net:A net) f l b.
538         (f ---> l) net /\
539         ~trivial_limit net /\
540         eventually (\x. b <= f x) net
541         ==> b <= l`,
542   ONCE_REWRITE_TAC[GSYM REAL_LE_NEG2] THEN
543   REPEAT STRIP_TAC THEN
544   MATCH_MP_TAC(ISPEC `net:A net` REALLIM_UBOUND) THEN
545   EXISTS_TAC `\a:A. --(f a:real)` THEN
546   ASM_REWRITE_TAC[REALLIM_NEG_EQ]);;
547
548 let REALLIM_LE = prove
549  (`!net f g l m.
550            (f ---> l) net /\ (g ---> m) net /\
551            ~trivial_limit net /\
552            eventually (\x. f x <= g x) net
553            ==> l <= m`,
554   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[CONJ_ASSOC] THEN
555   DISCH_THEN(CONJUNCTS_THEN2
556    (MP_TAC o MATCH_MP REALLIM_SUB o ONCE_REWRITE_RULE[CONJ_SYM]) MP_TAC) THEN
557   ONCE_REWRITE_TAC[GSYM REAL_SUB_LE] THEN
558   REWRITE_TAC[GSYM IMP_CONJ_ALT; GSYM CONJ_ASSOC] THEN
559   DISCH_THEN(ACCEPT_TAC o MATCH_MP REALLIM_LBOUND));;
560
561 let REALLIM_CONST_EQ = prove
562  (`!net:(A net) c d. ((\x. c) ---> d) net <=> trivial_limit net \/ c = d`,
563   REWRITE_TAC[TENDSTO_REAL; LIM_CONST_EQ; o_DEF; LIFT_EQ]);;
564
565 let REALLIM_SUM = prove
566  (`!net f:A->B->real l s.
567         FINITE s /\ (!i. i IN s ==> ((f i) ---> (l i)) net)
568         ==> ((\x. sum s (\i. f i x)) ---> sum s l) net`,
569   REPLICATE_TAC 3 GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
570   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
571   SIMP_TAC[SUM_CLAUSES; REALLIM_CONST; REALLIM_ADD; IN_INSERT; ETA_AX]);;
572
573 let REALLIM_NULL_COMPARISON = prove
574  (`!net:(A)net f g.
575         eventually (\x. abs(f x) <= g x) net /\ (g ---> &0) net
576         ==> (f ---> &0) net`,
577   REWRITE_TAC[TENDSTO_REAL; LIFT_NUM; o_DEF] THEN REPEAT STRIP_TAC THEN
578   MATCH_MP_TAC LIM_NULL_COMPARISON THEN
579   EXISTS_TAC `g:A->real` THEN ASM_REWRITE_TAC[NORM_LIFT]);;
580
581 (* ------------------------------------------------------------------------- *)
582 (* Real series.                                                              *)
583 (* ------------------------------------------------------------------------- *)
584
585 parse_as_infix("real_sums",(12,"right"));;
586
587 let real_sums = new_definition
588  `(f real_sums l) s <=> ((\n. sum (s INTER (0..n)) f) ---> l) sequentially`;;
589
590 let real_infsum = new_definition
591  `real_infsum s f = @l. (f real_sums l) s`;;
592
593 let real_summable = new_definition
594  `real_summable s f = ?l. (f real_sums l) s`;;
595
596 let REAL_SUMS = prove
597  (`(f real_sums l) = ((lift o f) sums (lift l))`,
598   REWRITE_TAC[FUN_EQ_THM; sums; real_sums; TENDSTO_REAL] THEN
599   SIMP_TAC[LIFT_SUM; FINITE_INTER_NUMSEG; o_DEF]);;
600
601 let REAL_SUMS_RE = prove
602  (`!f l s. (f sums l) s ==> ((Re o f) real_sums (Re l)) s`,
603   REPEAT GEN_TAC THEN REWRITE_TAC[real_sums; sums] THEN
604   DISCH_THEN(MP_TAC o MATCH_MP REALLIM_RE) THEN
605   SIMP_TAC[o_DEF; RE_VSUM; FINITE_INTER_NUMSEG]);;
606
607 let REAL_SUMS_IM = prove
608  (`!f l s. (f sums l) s ==> ((Im o f) real_sums (Im l)) s`,
609   REPEAT GEN_TAC THEN REWRITE_TAC[real_sums; sums] THEN
610   DISCH_THEN(MP_TAC o MATCH_MP REALLIM_IM) THEN
611   SIMP_TAC[o_DEF; IM_VSUM; FINITE_INTER_NUMSEG]);;
612
613 let REAL_SUMS_COMPLEX = prove
614  (`!f l s. (f real_sums l) s <=> ((Cx o f) sums (Cx l)) s`,
615   REWRITE_TAC[real_sums; sums; REALLIM_COMPLEX] THEN
616   SIMP_TAC[o_DEF; VSUM_CX; FINITE_INTER; FINITE_NUMSEG]);;
617
618 let REAL_SUMMABLE = prove
619  (`real_summable s f <=> summable s (lift o f)`,
620   REWRITE_TAC[real_summable; summable; REAL_SUMS; GSYM EXISTS_LIFT]);;
621
622 let REAL_SUMMABLE_COMPLEX = prove
623  (`real_summable s f <=> summable s (Cx o f)`,
624   REWRITE_TAC[real_summable; summable; REAL_SUMS_COMPLEX] THEN
625   EQ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
626   DISCH_THEN(X_CHOOSE_TAC `l:complex`) THEN EXISTS_TAC `Re l` THEN
627   SUBGOAL_THEN `Cx(Re l) = l` (fun th -> ASM_REWRITE_TAC[th]) THEN
628   REWRITE_TAC[GSYM REAL] THEN MATCH_MP_TAC REAL_SERIES THEN
629   MAP_EVERY EXISTS_TAC [`Cx o (f:num->real)`; `s:num->bool`] THEN
630   ASM_REWRITE_TAC[o_THM; REAL_CX]);;
631
632 let REAL_SERIES_CAUCHY = prove
633  (`(?l. (f real_sums l) s) <=>
634    (!e. &0 < e ==> ?N. !m n. m >= N ==> abs(sum(s INTER (m..n)) f) < e)`,
635   REWRITE_TAC[REAL_SUMS; SERIES_CAUCHY; GSYM EXISTS_LIFT] THEN
636   SIMP_TAC[NORM_REAL; GSYM drop; DROP_VSUM; FINITE_INTER_NUMSEG] THEN
637   REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]);;
638
639 let REAL_SUMS_SUMMABLE = prove
640  (`!f l s. (f real_sums l) s ==> real_summable s f`,
641   REWRITE_TAC[real_summable] THEN MESON_TAC[]);;
642
643 let REAL_SUMS_INFSUM = prove
644  (`!f s. (f real_sums (real_infsum s f)) s <=> real_summable s f`,
645   REWRITE_TAC[real_infsum; real_summable] THEN MESON_TAC[]);;
646
647 let REAL_INFSUM_COMPLEX = prove
648  (`!f s. real_summable s f ==> real_infsum s f = Re(infsum s (Cx o f))`,
649   REPEAT GEN_TAC THEN
650   REWRITE_TAC[GSYM REAL_SUMS_INFSUM; REAL_SUMS_COMPLEX] THEN
651   DISCH_THEN(MP_TAC o MATCH_MP INFSUM_UNIQUE) THEN
652   MESON_TAC[RE_CX]);;
653
654 let REAL_SERIES_FROM = prove
655  (`!f l k. (f real_sums l) (from k) = ((\n. sum(k..n) f) ---> l) sequentially`,
656   REPEAT GEN_TAC THEN REWRITE_TAC[real_sums] THEN
657   AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
658   AP_THM_TAC THEN AP_TERM_TAC THEN
659   REWRITE_TAC[EXTENSION; numseg; from; IN_ELIM_THM; IN_INTER] THEN ARITH_TAC);;
660
661 let REAL_SERIES_UNIQUE = prove
662  (`!f l l' s. (f real_sums l) s /\ (f real_sums l') s ==> l = l'`,
663   REWRITE_TAC[real_sums] THEN
664   MESON_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; REALLIM_UNIQUE]);;
665
666 let REAL_INFSUM_UNIQUE = prove
667  (`!f l s. (f real_sums l) s ==> real_infsum s f = l`,
668   MESON_TAC[REAL_SERIES_UNIQUE; REAL_SUMS_INFSUM; real_summable]);;
669
670 let REAL_SERIES_FINITE = prove
671  (`!f s. FINITE s ==> (f real_sums (sum s f)) s`,
672   REPEAT GEN_TAC THEN REWRITE_TAC[num_FINITE; LEFT_IMP_EXISTS_THM] THEN
673   X_GEN_TAC `n:num` THEN REWRITE_TAC[real_sums; REALLIM_SEQUENTIALLY] THEN
674   DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN EXISTS_TAC `n:num` THEN
675   X_GEN_TAC `m:num` THEN DISCH_TAC THEN
676   SUBGOAL_THEN `s INTER (0..m) = s`
677    (fun th -> ASM_REWRITE_TAC[th; REAL_SUB_REFL; REAL_ABS_NUM]) THEN
678   REWRITE_TAC[EXTENSION; IN_INTER; IN_NUMSEG; LE_0] THEN
679   ASM_MESON_TAC[LE_TRANS]);;
680
681 let REAL_SUMMABLE_IFF_EVENTUALLY = prove
682  (`!f g k. (?N. !n. N <= n /\ n IN k ==> f n = g n)
683            ==> (real_summable k f <=> real_summable k g)`,
684   REWRITE_TAC[REAL_SUMMABLE] THEN REPEAT STRIP_TAC THEN
685   MATCH_MP_TAC SUMMABLE_IFF_EVENTUALLY THEN REWRITE_TAC[o_THM] THEN
686   ASM_MESON_TAC[]);;
687
688 let REAL_SUMMABLE_EQ_EVENTUALLY = prove
689  (`!f g k. (?N. !n. N <= n /\ n IN k ==> f n = g n) /\ real_summable k f
690            ==> real_summable k g`,
691   MESON_TAC[REAL_SUMMABLE_IFF_EVENTUALLY]);;
692
693 let REAL_SUMMABLE_IFF_COFINITE = prove
694  (`!f s t. FINITE((s DIFF t) UNION (t DIFF s))
695            ==> (real_summable s f <=> real_summable t f)`,
696   SIMP_TAC[REAL_SUMMABLE] THEN MESON_TAC[SUMMABLE_IFF_COFINITE]);;
697
698 let REAL_SUMMABLE_EQ_COFINITE = prove
699  (`!f s t. FINITE((s DIFF t) UNION (t DIFF s)) /\ real_summable s f
700            ==> real_summable t f`,
701   MESON_TAC[REAL_SUMMABLE_IFF_COFINITE]);;
702
703 let REAL_SUMMABLE_FROM_ELSEWHERE = prove
704  (`!f m n. real_summable (from m) f ==> real_summable (from n) f`,
705   REPEAT GEN_TAC THEN
706   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_SUMMABLE_EQ_COFINITE) THEN
707   MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `0..(m+n)` THEN
708   SIMP_TAC[FINITE_NUMSEG; SUBSET; IN_NUMSEG; IN_UNION; IN_DIFF; IN_FROM] THEN
709   ARITH_TAC);;
710
711 let REAL_SERIES_GOESTOZERO = prove
712  (`!s x. real_summable s x
713          ==> !e. &0 < e
714                  ==> eventually (\n. n IN s ==> abs(x n) < e) sequentially`,
715   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_SUMMABLE] THEN
716   DISCH_THEN(MP_TAC o MATCH_MP SERIES_GOESTOZERO) THEN
717   REWRITE_TAC[o_THM; NORM_LIFT]);;
718
719 let REAL_SUMMABLE_IMP_TOZERO = prove
720  (`!f:num->real k.
721        real_summable k f
722        ==> ((\n. if n IN k then f(n) else &0) ---> &0) sequentially`,
723   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_SUMMABLE] THEN
724   DISCH_THEN(MP_TAC o MATCH_MP SUMMABLE_IMP_TOZERO) THEN
725   REWRITE_TAC[TENDSTO_REAL] THEN
726   REWRITE_TAC[o_DEF; GSYM LIFT_NUM; GSYM COND_RAND]);;
727
728 let REAL_SUMMABLE_IMP_BOUNDED = prove
729  (`!f:num->real k. real_summable k f ==> real_bounded (IMAGE f k)`,
730   REWRITE_TAC[REAL_BOUNDED; REAL_SUMMABLE; GSYM IMAGE_o;
731               SUMMABLE_IMP_BOUNDED]);;
732
733 let REAL_SUMMABLE_IMP_REAL_SUMS_BOUNDED = prove
734  (`!f:num->real k.
735        real_summable (from k) f ==> real_bounded { sum(k..n) f | n IN (:num) }`,
736   REWRITE_TAC[real_summable; real_sums; LEFT_IMP_EXISTS_THM] THEN
737   REPEAT GEN_TAC THEN
738   DISCH_THEN(MP_TAC o MATCH_MP REAL_CONVERGENT_IMP_BOUNDED) THEN
739   REWRITE_TAC[FROM_INTER_NUMSEG; SIMPLE_IMAGE]);;
740
741 let REAL_SERIES_0 = prove
742  (`!s. ((\n. &0) real_sums (&0)) s`,
743   REWRITE_TAC[real_sums; SUM_0; REALLIM_CONST]);;
744
745 let REAL_SERIES_ADD = prove
746  (`!x x0 y y0 s.
747      (x real_sums x0) s /\ (y real_sums y0) s
748      ==> ((\n. x n + y n) real_sums (x0 + y0)) s`,
749   SIMP_TAC[real_sums; FINITE_INTER_NUMSEG; SUM_ADD; REALLIM_ADD]);;
750
751 let REAL_SERIES_SUB = prove
752  (`!x x0 y y0 s.
753      (x real_sums x0) s /\ (y real_sums y0) s
754      ==> ((\n. x n - y n) real_sums (x0 - y0)) s`,
755   SIMP_TAC[real_sums; FINITE_INTER_NUMSEG; SUM_SUB; REALLIM_SUB]);;
756
757 let REAL_SERIES_LMUL = prove
758  (`!x x0 c s. (x real_sums x0) s ==> ((\n. c * x n) real_sums (c * x0)) s`,
759   SIMP_TAC[real_sums; FINITE_INTER_NUMSEG; SUM_LMUL; REALLIM_LMUL]);;
760
761 let REAL_SERIES_RMUL = prove
762  (`!x x0 c s. (x real_sums x0) s ==> ((\n. x n * c) real_sums (x0 * c)) s`,
763   SIMP_TAC[real_sums; FINITE_INTER_NUMSEG; SUM_RMUL; REALLIM_RMUL]);;
764
765 let REAL_SERIES_NEG = prove
766  (`!x x0 s. (x real_sums x0) s ==> ((\n. --(x n)) real_sums (--x0)) s`,
767   SIMP_TAC[real_sums; FINITE_INTER_NUMSEG; SUM_NEG; REALLIM_NEG]);;
768
769 let REAL_SUMS_IFF = prove
770  (`!f g k. (!x. x IN k ==> f x = g x)
771            ==> ((f real_sums l) k <=> (g real_sums l) k)`,
772   REPEAT STRIP_TAC THEN REWRITE_TAC[real_sums] THEN
773   AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
774   MATCH_MP_TAC SUM_EQ THEN ASM_SIMP_TAC[IN_INTER]);;
775
776 let REAL_SUMS_EQ = prove
777  (`!f g k. (!x. x IN k ==> f x = g x) /\ (f real_sums l) k
778            ==> (g real_sums l) k`,
779   MESON_TAC[REAL_SUMS_IFF]);;
780
781 let REAL_SERIES_FINITE_SUPPORT = prove
782  (`!f s k.
783      FINITE (s INTER k) /\ (!x. ~(x IN s INTER k) ==> f x = &0)
784      ==> (f real_sums sum(s INTER k) f) k`,
785   REWRITE_TAC[real_sums; REALLIM_SEQUENTIALLY] THEN REPEAT STRIP_TAC THEN
786   FIRST_ASSUM(MP_TAC o ISPEC `\x:num. x` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN
787   REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
788   STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
789   SUBGOAL_THEN `sum (k INTER (0..n)) (f:num->real) = sum(s INTER k) f`
790    (fun th -> ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_ABS_NUM; th]) THEN
791   MATCH_MP_TAC SUM_SUPERSET THEN
792   ASM_SIMP_TAC[SUBSET; IN_INTER; IN_NUMSEG; LE_0] THEN
793   ASM_MESON_TAC[IN_INTER; LE_TRANS]);;
794
795 let REAL_SERIES_DIFFS = prove
796  (`!f k. (f ---> &0) sequentially
797          ==> ((\n. f(n) - f(n + 1)) real_sums f(k)) (from k)`,
798   REWRITE_TAC[real_sums; FROM_INTER_NUMSEG; SUM_DIFFS] THEN
799   REPEAT STRIP_TAC THEN MATCH_MP_TAC REALLIM_TRANSFORM_EVENTUALLY THEN
800   EXISTS_TAC `\n. (f:num->real) k - f(n + 1)` THEN CONJ_TAC THENL
801    [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `k:num` THEN
802     SIMP_TAC[];
803     GEN_REWRITE_TAC LAND_CONV [GSYM REAL_SUB_RZERO] THEN
804     MATCH_MP_TAC REALLIM_SUB THEN REWRITE_TAC[REALLIM_CONST] THEN
805     MATCH_MP_TAC REAL_SEQ_OFFSET THEN ASM_REWRITE_TAC[]]);;
806
807 let REAL_SERIES_TRIVIAL = prove
808  (`!f. (f real_sums &0) {}`,
809   REWRITE_TAC[real_sums; INTER_EMPTY; SUM_CLAUSES; REALLIM_CONST]);;
810
811 let REAL_SERIES_RESTRICT = prove
812  (`!f k l:real.
813         ((\n. if n IN k then f(n) else &0) real_sums l) (:num) <=>
814         (f real_sums l) k`,
815   REPEAT GEN_TAC THEN REWRITE_TAC[real_sums] THEN
816   AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
817   REWRITE_TAC[FUN_EQ_THM; INTER_UNIV] THEN GEN_TAC THEN
818   MATCH_MP_TAC(MESON[] `sum s f = sum t f /\ sum t f = sum t g
819                         ==> sum s f = sum t g`) THEN
820   CONJ_TAC THENL
821    [MATCH_MP_TAC SUM_SUPERSET THEN SET_TAC[];
822     MATCH_MP_TAC SUM_EQ THEN SIMP_TAC[IN_INTER]]);;
823
824 let REAL_SERIES_SUM = prove
825  (`!f l k s. FINITE s /\ s SUBSET k /\ (!x. ~(x IN s) ==> f x = &0) /\
826              sum s f = l ==> (f real_sums l) k`,
827   REPEAT STRIP_TAC THEN EXPAND_TAC "l" THEN
828   SUBGOAL_THEN `s INTER k = s:num->bool` ASSUME_TAC THENL
829    [ASM SET_TAC[]; ASM_MESON_TAC [REAL_SERIES_FINITE_SUPPORT]]);;
830
831 let REAL_SUMS_REINDEX = prove
832  (`!k a l n.
833      ((\x. a(x + k)) real_sums l) (from n) <=> (a real_sums l) (from(n + k))`,
834   REPEAT GEN_TAC THEN REWRITE_TAC[real_sums; FROM_INTER_NUMSEG] THEN
835   REPEAT GEN_TAC THEN REWRITE_TAC[GSYM SUM_OFFSET] THEN
836   REWRITE_TAC[REALLIM_SEQUENTIALLY] THEN
837   ASM_MESON_TAC[ARITH_RULE `N + k:num <= n ==> n = (n - k) + k /\ N <= n - k`;
838                 ARITH_RULE `N + k:num <= n ==> N <= n + k`]);;
839
840 let REAL_INFSUM = prove
841  (`!f s. real_summable s f ==> real_infsum s f = drop(infsum s (lift o f))`,
842   REPEAT GEN_TAC THEN
843   REWRITE_TAC[GSYM REAL_SUMS_INFSUM; REAL_SUMS] THEN
844   DISCH_THEN(MP_TAC o MATCH_MP INFSUM_UNIQUE) THEN
845   MESON_TAC[LIFT_DROP]);;
846
847 let REAL_PARTIAL_SUMS_LE_INFSUM = prove
848  (`!f s n.
849         (!i. i IN s ==> &0 <= f i) /\ real_summable s f
850         ==> sum (s INTER (0..n)) f <= real_infsum s f`,
851   REPEAT GEN_TAC THEN SIMP_TAC[REAL_INFSUM] THEN
852   REWRITE_TAC[REAL_SUMMABLE] THEN
853   GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o BINDER_CONV o RAND_CONV o RAND_CONV)
854    [GSYM LIFT_DROP] THEN
855   REWRITE_TAC[o_DEF] THEN DISCH_THEN(MP_TAC o MATCH_MP
856     PARTIAL_SUMS_DROP_LE_INFSUM) THEN
857   SIMP_TAC[DROP_VSUM; FINITE_INTER; FINITE_NUMSEG; o_DEF; LIFT_DROP; ETA_AX]);;
858
859 let REAL_PARTIAL_SUMS_LE_INFSUM_GEN = prove
860  (`!f s t. FINITE t /\ t SUBSET s /\
861            (!i. i IN s ==> &0 <= f i) /\ real_summable s f
862            ==> sum t f <= real_infsum s f`,
863   REPEAT STRIP_TAC THEN
864   FIRST_ASSUM(MP_TAC o SPEC `\n:num. n` o MATCH_MP UPPER_BOUND_FINITE_SET) THEN
865   REWRITE_TAC[] THEN DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN
866   TRANS_TAC REAL_LE_TRANS `sum (s INTER (0..n)) f` THEN
867   ASM_SIMP_TAC[REAL_PARTIAL_SUMS_LE_INFSUM] THEN
868   MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
869   ASM_SIMP_TAC[IN_INTER; IN_DIFF; FINITE_INTER; FINITE_NUMSEG] THEN
870   REWRITE_TAC[SUBSET; IN_NUMSEG; IN_INTER; LE_0] THEN ASM SET_TAC[]);;
871
872 let REAL_SERIES_TERMS_TOZERO = prove
873  (`!f l n. (f real_sums l) (from n) ==> (f ---> &0) sequentially`,
874   REWRITE_TAC[REAL_SUMS; TENDSTO_REAL; LIFT_NUM; SERIES_TERMS_TOZERO]);;
875
876 let REAL_SERIES_LE = prove
877  (`!f g s y z.
878         (f real_sums y) s /\ (g real_sums z) s /\
879         (!i. i IN s ==> f(i) <= g(i))
880         ==> y <= z`,
881   REWRITE_TAC[REAL_SUMS] THEN REPEAT STRIP_TAC THEN
882   ONCE_REWRITE_TAC[MESON[LIFT_DROP] `x = drop(lift x)`] THEN
883   MATCH_MP_TAC SERIES_DROP_LE THEN
884   MAP_EVERY EXISTS_TAC [`lift o (f:num->real)`; `lift o (g:num->real)`] THEN
885   ASM_SIMP_TAC[o_THM; LIFT_DROP] THEN ASM_MESON_TAC[]);;
886
887 let REAL_SERIES_POS = prove
888  (`!f s y.
889         (f real_sums y) s /\ (!i. i IN s ==> &0 <= f(i))
890         ==> &0 <= y`,
891   REWRITE_TAC[REAL_SUMS] THEN REPEAT STRIP_TAC THEN
892   GEN_REWRITE_TAC RAND_CONV [GSYM LIFT_DROP] THEN
893   MATCH_MP_TAC SERIES_DROP_POS THEN
894   EXISTS_TAC `lift o (f:num->real)` THEN
895   ASM_SIMP_TAC[o_THM; LIFT_DROP] THEN ASM_MESON_TAC[]);;
896
897 let REAL_SERIES_BOUND = prove
898  (`!f g s a b.
899         (f real_sums a) s /\ (g real_sums b) s /\
900         (!i. i IN s ==> abs(f i) <= g i)
901         ==> abs(a) <= b`,
902   REWRITE_TAC[REAL_SUMS; GSYM NORM_LIFT] THEN REPEAT STRIP_TAC THEN
903   MATCH_MP_TAC SERIES_BOUND THEN
904   EXISTS_TAC `lift o (f:num->real)` THEN
905   REWRITE_TAC[o_THM] THEN ASM_MESON_TAC[]);;
906
907 let REAL_SERIES_COMPARISON_BOUND = prove
908  (`!f g s a.
909         (g real_sums a) s /\ (!i. i IN s ==> abs(f i) <= g i)
910         ==> ?l. (f real_sums l) s /\ abs(l) <= a`,
911   REWRITE_TAC[REAL_SUMS; GSYM EXISTS_LIFT; GSYM NORM_LIFT] THEN
912   REPEAT STRIP_TAC THEN
913   GEN_REWRITE_TAC (BINDER_CONV o RAND_CONV o RAND_CONV) [GSYM LIFT_DROP] THEN
914   MATCH_MP_TAC SERIES_COMPARISON_BOUND THEN
915   EXISTS_TAC `lift o (g:num->real)` THEN
916   ASM_SIMP_TAC[o_THM; LIFT_DROP]);;
917
918 (* ------------------------------------------------------------------------- *)
919 (* Similar combining theorems just for summability.                          *)
920 (* ------------------------------------------------------------------------- *)
921
922 let REAL_SUMMABLE_0 = prove
923  (`!s. real_summable s (\n. &0)`,
924   REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_0]);;
925
926 let REAL_SUMMABLE_ADD = prove
927  (`!x y s. real_summable s x /\ real_summable s y
928            ==> real_summable s (\n. x n + y n)`,
929   REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_ADD]);;
930
931 let REAL_SUMMABLE_SUB = prove
932  (`!x y s. real_summable s x /\ real_summable s y
933            ==> real_summable s (\n. x n - y n)`,
934   REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_SUB]);;
935
936 let REAL_SUMMABLE_LMUL = prove
937  (`!s x c. real_summable s x ==> real_summable s (\n. c * x n)`,
938   REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_LMUL]);;
939
940 let REAL_SUMMABLE_RMUL = prove
941  (`!s x c. real_summable s x ==> real_summable s (\n. x n * c)`,
942   REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_RMUL]);;
943
944 let REAL_SUMMABLE_NEG = prove
945  (`!x s. real_summable s x ==> real_summable s (\n. --(x n))`,
946   REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_NEG]);;
947
948 let REAL_SUMMABLE_IFF = prove
949  (`!f g k. (!x. x IN k ==> f x = g x)
950            ==> (real_summable k f <=> real_summable k g)`,
951   REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SUMS_IFF]);;
952
953 let REAL_SUMMABLE_EQ = prove
954  (`!f g k. (!x. x IN k ==> f x = g x) /\ real_summable k f
955            ==> real_summable k g`,
956   REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SUMS_EQ]);;
957
958 let REAL_SERIES_SUBSET = prove
959  (`!x s t l.
960         s SUBSET t /\
961         ((\i. if i IN s then x i else &0) real_sums l) t
962         ==> (x real_sums l) s`,
963   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
964   REWRITE_TAC[real_sums] THEN MATCH_MP_TAC EQ_IMP THEN
965   AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN
966   ASM_SIMP_TAC[GSYM SUM_RESTRICT_SET; FINITE_INTER_NUMSEG] THEN
967   AP_THM_TAC THEN AP_TERM_TAC THEN POP_ASSUM MP_TAC THEN SET_TAC[]);;
968
969 let REAL_SUMMABLE_SUBSET = prove
970  (`!x s t.
971         s SUBSET t /\
972         real_summable t (\i. if i IN s then x i else &0)
973         ==> real_summable s x`,
974   REWRITE_TAC[real_summable] THEN MESON_TAC[REAL_SERIES_SUBSET]);;
975
976 let REAL_SUMMABLE_TRIVIAL = prove
977  (`!f. real_summable {} f`,
978   GEN_TAC THEN REWRITE_TAC[real_summable] THEN EXISTS_TAC `&0` THEN
979   REWRITE_TAC[REAL_SERIES_TRIVIAL]);;
980
981 let REAL_SUMMABLE_RESTRICT = prove
982  (`!f k.
983         real_summable (:num) (\n. if n IN k then f(n) else &0) <=>
984         real_summable k f`,
985   REWRITE_TAC[real_summable; REAL_SERIES_RESTRICT]);;
986
987 let REAL_SUMS_FINITE_DIFF = prove
988  (`!f t s l.
989         t SUBSET s /\ FINITE t /\ (f real_sums l) s
990         ==> (f real_sums (l - sum t f)) (s DIFF t)`,
991   REPEAT GEN_TAC THEN
992   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
993   FIRST_ASSUM(MP_TAC o ISPEC `f:num->real` o MATCH_MP REAL_SERIES_FINITE) THEN
994   ONCE_REWRITE_TAC[GSYM REAL_SERIES_RESTRICT] THEN
995   REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
996   DISCH_THEN(MP_TAC o MATCH_MP REAL_SERIES_SUB) THEN
997   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
998   REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `x:num` THEN REWRITE_TAC[IN_DIFF] THEN
999   FIRST_ASSUM(MP_TAC o SPEC `x:num` o GEN_REWRITE_RULE I [SUBSET]) THEN
1000   MAP_EVERY ASM_CASES_TAC [`(x:num) IN s`; `(x:num) IN t`] THEN
1001   ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;
1002
1003 let REAL_SUMS_FINITE_UNION = prove
1004  (`!f s t l.
1005         FINITE t /\ (f real_sums l) s
1006         ==> (f real_sums (l + sum (t DIFF s) f)) (s UNION t)`,
1007   REPEAT GEN_TAC THEN
1008   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
1009   FIRST_ASSUM(MP_TAC o SPEC `s:num->bool` o MATCH_MP FINITE_DIFF) THEN
1010   DISCH_THEN(MP_TAC o ISPEC `f:num->real` o MATCH_MP REAL_SERIES_FINITE) THEN
1011   ONCE_REWRITE_TAC[GSYM REAL_SERIES_RESTRICT] THEN
1012   REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
1013   DISCH_THEN(MP_TAC o MATCH_MP REAL_SERIES_ADD) THEN
1014   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
1015   REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `x:num` THEN
1016   REWRITE_TAC[IN_DIFF; IN_UNION] THEN
1017   MAP_EVERY ASM_CASES_TAC [`(x:num) IN s`; `(x:num) IN t`] THEN
1018   ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;
1019
1020 let REAL_SUMS_OFFSET = prove
1021  (`!f l m n.
1022         (f real_sums l) (from m) /\ m < n
1023         ==> (f real_sums (l - sum(m..(n-1)) f)) (from n)`,
1024   REPEAT STRIP_TAC THEN
1025   SUBGOAL_THEN `from n = from m DIFF (m..(n-1))` SUBST1_TAC THENL
1026    [REWRITE_TAC[EXTENSION; IN_FROM; IN_DIFF; IN_NUMSEG] THEN ASM_ARITH_TAC;
1027     MATCH_MP_TAC REAL_SUMS_FINITE_DIFF THEN ASM_REWRITE_TAC[FINITE_NUMSEG] THEN
1028     SIMP_TAC[SUBSET; IN_FROM; IN_NUMSEG]]);;
1029
1030 let REAL_SUMS_OFFSET_REV = prove
1031  (`!f l m n.
1032         (f real_sums l) (from m) /\ n < m
1033         ==> (f real_sums (l + sum(n..m-1) f)) (from n)`,
1034   REPEAT STRIP_TAC THEN
1035   MP_TAC(ISPECL [`f:num->real`; `from m`; `n..m-1`; `l:real`]
1036                 REAL_SUMS_FINITE_UNION) THEN
1037   ASM_REWRITE_TAC[FINITE_NUMSEG] THEN MATCH_MP_TAC EQ_IMP THEN
1038   BINOP_TAC THENL [AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC; ALL_TAC] THEN
1039   REWRITE_TAC[EXTENSION; IN_DIFF; IN_UNION; IN_FROM; IN_NUMSEG] THEN
1040   ASM_ARITH_TAC);;
1041
1042 (* ------------------------------------------------------------------------- *)
1043 (* Similar combining theorems for infsum.                                    *)
1044 (* ------------------------------------------------------------------------- *)
1045
1046 let REAL_INFSUM_0 = prove
1047  (`real_infsum s (\i. &0) = &0`,
1048   MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN REWRITE_TAC[REAL_SERIES_0]);;
1049
1050 let REAL_INFSUM_ADD = prove
1051  (`!x y s. real_summable s x /\ real_summable s y
1052            ==> real_infsum s (\i. x i + y i) =
1053                real_infsum s x + real_infsum s y`,
1054   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN
1055   MATCH_MP_TAC REAL_SERIES_ADD THEN ASM_REWRITE_TAC[REAL_SUMS_INFSUM]);;
1056
1057 let REAL_INFSUM_SUB = prove
1058  (`!x y s. real_summable s x /\ real_summable s y
1059            ==> real_infsum s (\i. x i - y i) =
1060                real_infsum s x - real_infsum s y`,
1061   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN
1062   MATCH_MP_TAC REAL_SERIES_SUB THEN ASM_REWRITE_TAC[REAL_SUMS_INFSUM]);;
1063
1064 let REAL_INFSUM_LMUL = prove
1065  (`!s x c. real_summable s x
1066            ==> real_infsum s (\n. c * x n) = c * real_infsum s x`,
1067   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN
1068   MATCH_MP_TAC REAL_SERIES_LMUL THEN ASM_REWRITE_TAC[REAL_SUMS_INFSUM]);;
1069
1070 let REAL_INFSUM_RMUL = prove
1071  (`!s x c. real_summable s x
1072            ==> real_infsum s (\n. x n * c) = real_infsum s x * c`,
1073   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN
1074   MATCH_MP_TAC REAL_SERIES_RMUL THEN ASM_REWRITE_TAC[REAL_SUMS_INFSUM]);;
1075
1076 let REAL_INFSUM_NEG = prove
1077  (`!s x. real_summable s x
1078          ==> real_infsum s (\n. --(x n)) = --(real_infsum s x)`,
1079   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN
1080   MATCH_MP_TAC REAL_SERIES_NEG THEN ASM_REWRITE_TAC[REAL_SUMS_INFSUM]);;
1081
1082 let REAL_INFSUM_EQ = prove
1083  (`!f g k. real_summable k f /\ real_summable k g /\
1084            (!x. x IN k ==> f x = g x)
1085            ==> real_infsum k f = real_infsum k g`,
1086   REPEAT STRIP_TAC THEN REWRITE_TAC[real_infsum] THEN AP_TERM_TAC THEN
1087   ABS_TAC THEN ASM_MESON_TAC[REAL_SUMS_EQ; REAL_SUMS_INFSUM]);;
1088
1089 let REAL_INFSUM_RESTRICT = prove
1090  (`!k a. real_infsum (:num) (\n. if n IN k then a n else &0) =
1091          real_infsum k a`,
1092   REPEAT GEN_TAC THEN
1093   MP_TAC(ISPECL [`a:num->real`; `k:num->bool`] REAL_SUMMABLE_RESTRICT) THEN
1094   ASM_CASES_TAC `real_summable k a` THEN ASM_REWRITE_TAC[] THEN
1095   STRIP_TAC THENL
1096    [MATCH_MP_TAC REAL_INFSUM_UNIQUE THEN
1097     ASM_REWRITE_TAC[REAL_SERIES_RESTRICT; REAL_SUMS_INFSUM];
1098     RULE_ASSUM_TAC(REWRITE_RULE[real_summable; NOT_EXISTS_THM]) THEN
1099     ASM_REWRITE_TAC[real_infsum]]);;
1100
1101 (* ------------------------------------------------------------------------- *)
1102 (* Convergence tests for real series.                                        *)
1103 (* ------------------------------------------------------------------------- *)
1104
1105 let REAL_SERIES_CAUCHY_UNIFORM = prove
1106  (`!P:A->bool f k.
1107         (?l. !e. &0 < e
1108                  ==> ?N. !n x. N <= n /\ P x
1109                                ==> abs(sum(k INTER (0..n)) (f x) -
1110                                         l x) < e) <=>
1111         (!e. &0 < e ==> ?N. !m n x. N <= m /\ P x
1112                                     ==> abs(sum(k INTER (m..n)) (f x)) < e)`,
1113   REPEAT STRIP_TAC THEN
1114   MP_TAC(ISPECL [`P:A->bool`; `\x:A n:num. lift(f x n)`; `k:num->bool`]
1115         SERIES_CAUCHY_UNIFORM) THEN
1116   SIMP_TAC[VSUM_REAL; FINITE_INTER; FINITE_NUMSEG] THEN
1117   REWRITE_TAC[NORM_LIFT; o_DEF; LIFT_DROP; ETA_AX] THEN
1118   DISCH_THEN(SUBST1_TAC o SYM) THEN EQ_TAC THENL
1119    [DISCH_THEN(X_CHOOSE_TAC `l:A->real`) THEN
1120     EXISTS_TAC `lift o (l:A->real)` THEN
1121     ASM_SIMP_TAC[o_THM; DIST_LIFT];
1122     DISCH_THEN(X_CHOOSE_TAC `l:A->real^1`) THEN
1123     EXISTS_TAC `drop o (l:A->real^1)` THEN
1124     ASM_SIMP_TAC[SUM_VSUM; FINITE_INTER; FINITE_NUMSEG] THEN
1125     REWRITE_TAC[o_THM; GSYM DROP_SUB; GSYM ABS_DROP] THEN
1126     SIMP_TAC[GSYM dist; VSUM_REAL; FINITE_INTER; FINITE_NUMSEG] THEN
1127     ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]]);;
1128
1129 let REAL_SERIES_COMPARISON = prove
1130  (`!f g s. (?l. (g real_sums l) s) /\
1131            (?N. !n. n >= N /\ n IN s ==> abs(f n) <= g n)
1132            ==> ?l. (f real_sums l) s`,
1133   REWRITE_TAC[REAL_SUMS; GSYM EXISTS_LIFT] THEN
1134   REPEAT STRIP_TAC THEN MATCH_MP_TAC SERIES_COMPARISON THEN
1135   EXISTS_TAC `g:num->real` THEN
1136   REWRITE_TAC[NORM_LIFT; o_THM] THEN ASM_MESON_TAC[]);;
1137
1138 let REAL_SUMMABLE_COMPARISON = prove
1139  (`!f g s. real_summable s g /\
1140            (?N. !n. n >= N /\ n IN s ==> abs(f n) <= g n)
1141            ==> real_summable s f`,
1142   REWRITE_TAC[real_summable; REAL_SERIES_COMPARISON]);;
1143
1144 let REAL_SERIES_COMPARISON_UNIFORM = prove
1145  (`!f g P s. (?l. (g real_sums l) s) /\
1146              (?N. !n x. N <= n /\ n IN s /\ P x ==> abs(f x n) <= g n)
1147              ==> ?l:A->real.
1148                     !e. &0 < e
1149                         ==> ?N. !n x. N <= n /\ P x
1150                                       ==> abs(sum(s INTER (0..n)) (f x) -
1151                                                l x) < e`,
1152   REPEAT GEN_TAC THEN
1153   SIMP_TAC[GE; REAL_SERIES_CAUCHY; REAL_SERIES_CAUCHY_UNIFORM] THEN
1154   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (X_CHOOSE_TAC `N1:num`)) THEN
1155   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
1156   MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
1157   DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN
1158   EXISTS_TAC `N1 + N2:num` THEN
1159   MAP_EVERY X_GEN_TAC [`m:num`; `n:num`; `x:A`] THEN DISCH_TAC THEN
1160   MATCH_MP_TAC REAL_LET_TRANS THEN
1161   EXISTS_TAC `abs (sum (s INTER (m .. n)) g)` THEN CONJ_TAC THENL
1162    [SIMP_TAC[GSYM LIFT_SUM; FINITE_INTER_NUMSEG; NORM_LIFT] THEN
1163     MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs(a)`) THEN
1164     MATCH_MP_TAC SUM_ABS_LE THEN
1165     REWRITE_TAC[FINITE_INTER_NUMSEG; IN_INTER; IN_NUMSEG] THEN
1166     ASM_MESON_TAC[ARITH_RULE `N1 + N2:num <= m /\ m <= x ==> N1 <= x`];
1167     ASM_MESON_TAC[ARITH_RULE `N1 + N2:num <= m ==> N2 <= m`]]);;
1168
1169 let REAL_SERIES_RATIO = prove
1170  (`!c a s N.
1171       c < &1 /\
1172       (!n. n >= N ==> abs(a(SUC n)) <= c * abs(a(n)))
1173       ==> ?l:real. (a real_sums l) s`,
1174   REWRITE_TAC[REAL_SUMS; GSYM EXISTS_LIFT] THEN
1175   REPEAT STRIP_TAC THEN MATCH_MP_TAC SERIES_RATIO THEN
1176   REWRITE_TAC[o_THM; NORM_LIFT] THEN ASM_MESON_TAC[]);;
1177
1178 let BOUNDED_PARTIAL_REAL_SUMS = prove
1179  (`!f:num->real k.
1180         real_bounded { sum(k..n) f | n IN (:num) }
1181         ==> real_bounded { sum(m..n) f | m IN (:num) /\ n IN (:num) }`,
1182   REWRITE_TAC[REAL_BOUNDED] THEN
1183   REWRITE_TAC[SET_RULE `IMAGE f {g x | P x} = {f(g x) | P x}`;
1184     SET_RULE `IMAGE f {g x y | P x /\ Q y} = {f(g x y) | P x /\ Q y}`] THEN
1185   SIMP_TAC[LIFT_SUM; FINITE_INTER; FINITE_NUMSEG] THEN
1186   REWRITE_TAC[BOUNDED_PARTIAL_SUMS]);;
1187
1188 let REAL_SERIES_DIRICHLET = prove
1189  (`!f:num->real g N k m.
1190         real_bounded { sum (m..n) f | n IN (:num)} /\
1191         (!n. N <= n ==> g(n + 1) <= g(n)) /\
1192         (g ---> &0) sequentially
1193         ==> real_summable (from k) (\n. g(n) * f(n))`,
1194   REWRITE_TAC[REAL_SUMMABLE; REAL_BOUNDED; TENDSTO_REAL] THEN
1195   REWRITE_TAC[LIFT_NUM; LIFT_CMUL; o_DEF] THEN
1196   REPEAT STRIP_TAC THEN MATCH_MP_TAC SERIES_DIRICHLET THEN
1197   MAP_EVERY EXISTS_TAC [`N:num`; `m:num`] THEN
1198   ASM_REWRITE_TAC[o_DEF] THEN
1199   SIMP_TAC[VSUM_REAL; FINITE_INTER; FINITE_NUMSEG] THEN
1200   ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX] THEN
1201   ASM_REWRITE_TAC[SET_RULE `{lift(f x) | P x} = IMAGE lift {f x | P x}`]);;
1202
1203 let REAL_SERIES_ABSCONV_IMP_CONV = prove
1204  (`!x:num->real k. real_summable k (\n. abs(x n)) ==> real_summable k x`,
1205   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_SUMMABLE_COMPARISON THEN
1206   EXISTS_TAC `\n:num. abs(x n)` THEN ASM_REWRITE_TAC[REAL_LE_REFL]);;
1207
1208 let REAL_SUMS_GP = prove
1209  (`!n x. abs(x) < &1
1210          ==> ((\k. x pow k) real_sums (x pow n / (&1 - x))) (from n)`,
1211   REPEAT STRIP_TAC THEN MP_TAC(SPECL [`n:num`; `Cx x`] SUMS_GP) THEN
1212   ASM_REWRITE_TAC[REAL_SUMS_COMPLEX; GSYM CX_SUB; GSYM CX_POW; GSYM CX_DIV;
1213                   o_DEF; COMPLEX_NORM_CX]);;
1214
1215 let REAL_SUMMABLE_GP = prove
1216  (`!x k. abs(x) < &1 ==> real_summable k (\n. x pow n)`,
1217   REPEAT STRIP_TAC THEN MP_TAC(SPECL [`Cx x`; `k:num->bool`] SUMMABLE_GP) THEN
1218   ASM_REWRITE_TAC[REAL_SUMMABLE_COMPLEX] THEN
1219   ASM_REWRITE_TAC[COMPLEX_NORM_CX; o_DEF; CX_POW]);;
1220
1221 let REAL_SUMMABLE_ZETA_INTEGER = prove
1222  (`!n m. 2 <= m ==> real_summable (from n) (\k. inv(&k pow m))`,
1223   REWRITE_TAC[REAL_SUMMABLE_COMPLEX; CX_INV; CX_POW;
1224               SUMMABLE_ZETA_INTEGER; o_DEF]);;
1225
1226 let REAL_ABEL_LEMMA = prove
1227  (`!a M r r0.
1228         &0 <= r /\ r < r0 /\
1229         (!n. n IN k ==> abs(a n) * r0 pow n <= M)
1230         ==> real_summable k (\n. abs(a(n)) * r pow n)`,
1231   REWRITE_TAC[REAL_SUMMABLE_COMPLEX] THEN
1232   REWRITE_TAC[o_DEF; CX_MUL; CX_ABS] THEN REWRITE_TAC[GSYM CX_MUL] THEN
1233   REPEAT STRIP_TAC THEN MATCH_MP_TAC ABEL_LEMMA THEN
1234   REWRITE_TAC[COMPLEX_NORM_CX] THEN ASM_MESON_TAC[]);;
1235
1236 let REAL_POWER_SERIES_CONV_IMP_ABSCONV = prove
1237  (`!a k w z.
1238         real_summable k (\n. a(n) * z pow n) /\ abs(w) < abs(z)
1239         ==> real_summable k (\n. abs(a(n) * w pow n))`,
1240   REWRITE_TAC[REAL_SUMMABLE_COMPLEX; o_DEF; CX_MUL; CX_ABS; CX_POW] THEN
1241   REPEAT STRIP_TAC THEN MATCH_MP_TAC POWER_SERIES_CONV_IMP_ABSCONV THEN
1242   EXISTS_TAC `Cx z` THEN ASM_REWRITE_TAC[COMPLEX_NORM_CX]);;
1243
1244 let POWER_REAL_SERIES_CONV_IMP_ABSCONV_WEAK = prove
1245  (`!a k w z.
1246         real_summable k (\n. a(n) * z pow n) /\ abs(w) < abs(z)
1247         ==> real_summable k (\n. abs(a n) * w pow n)`,
1248   REWRITE_TAC[REAL_SUMMABLE_COMPLEX; o_DEF; CX_MUL; CX_ABS; CX_POW] THEN
1249   REPEAT STRIP_TAC THEN MATCH_MP_TAC POWER_SERIES_CONV_IMP_ABSCONV_WEAK THEN
1250   EXISTS_TAC `Cx z` THEN ASM_REWRITE_TAC[COMPLEX_NORM_CX]);;
1251
1252 (* ------------------------------------------------------------------------- *)
1253 (* Nets for real limit.                                                      *)
1254 (* ------------------------------------------------------------------------- *)
1255
1256 let atreal = new_definition
1257  `atreal a = mk_net(\x y. &0 < abs(x - a) /\ abs(x - a) <= abs(y - a))`;;
1258
1259 let ATREAL = prove
1260  (`!a x y.
1261         netord(atreal a) x y <=> &0 < abs(x - a) /\ abs(x - a) <= abs(y - a)`,
1262   GEN_TAC THEN NET_PROVE_TAC[atreal] THEN
1263   MESON_TAC[REAL_LE_TOTAL; REAL_LE_REFL; REAL_LE_TRANS; REAL_LET_TRANS]);;
1264
1265 let WITHINREAL_UNIV = prove
1266  (`!x. atreal x within (:real) = atreal x`,
1267   REWRITE_TAC[within; atreal; IN_UNIV] THEN REWRITE_TAC[ETA_AX; net_tybij]);;
1268
1269 let TRIVIAL_LIMIT_ATREAL = prove
1270  (`!a. ~(trivial_limit (atreal a))`,
1271   X_GEN_TAC `a:real` THEN SIMP_TAC[trivial_limit; ATREAL; DE_MORGAN_THM] THEN
1272   CONJ_TAC THENL
1273    [DISCH_THEN(MP_TAC o SPECL [`&0`; `&1`]) THEN REAL_ARITH_TAC; ALL_TAC] THEN
1274   REWRITE_TAC[NOT_EXISTS_THM] THEN
1275   MAP_EVERY X_GEN_TAC [`b:real`; `c:real`] THEN
1276   ASM_CASES_TAC `b:real = c` THEN ASM_REWRITE_TAC[] THEN
1277   REWRITE_TAC[GSYM DE_MORGAN_THM; GSYM NOT_EXISTS_THM] THEN
1278   SUBGOAL_THEN `~(b:real = a) \/ ~(c = a)` DISJ_CASES_TAC THENL
1279    [ASM_MESON_TAC[];
1280     EXISTS_TAC `(a + b) / &2` THEN ASM_REAL_ARITH_TAC;
1281     EXISTS_TAC `(a + c) / &2` THEN ASM_REAL_ARITH_TAC]);;
1282
1283 let NETLIMIT_WITHINREAL = prove
1284  (`!a s. ~(trivial_limit (atreal a within s))
1285          ==> (netlimit (atreal a within s) = a)`,
1286   REWRITE_TAC[trivial_limit; netlimit; ATREAL; WITHIN; DE_MORGAN_THM] THEN
1287   REPEAT STRIP_TAC THEN MATCH_MP_TAC SELECT_UNIQUE THEN REWRITE_TAC[] THEN
1288   SUBGOAL_THEN
1289    `!x. ~(&0 < abs(x - a) /\ abs(x - a) <= abs(a - a) /\ x IN s)`
1290   ASSUME_TAC THENL [REAL_ARITH_TAC; ASM_MESON_TAC[]]);;
1291
1292 let NETLIMIT_ATREAL = prove
1293  (`!a. netlimit(atreal a) = a`,
1294   GEN_TAC THEN ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
1295   MATCH_MP_TAC NETLIMIT_WITHINREAL THEN
1296   SIMP_TAC[TRIVIAL_LIMIT_ATREAL; WITHINREAL_UNIV]);;
1297
1298 let EVENTUALLY_WITHINREAL_LE = prove
1299  (`!s a p.
1300      eventually p (atreal a within s) <=>
1301         ?d. &0 < d /\
1302             !x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) <= d ==> p(x)`,
1303   REWRITE_TAC[eventually; ATREAL; WITHIN; trivial_limit] THEN
1304   REWRITE_TAC[MESON[REAL_LT_01; REAL_LT_REFL] `~(!a b:real. a = b)`] THEN
1305   REPEAT GEN_TAC THEN EQ_TAC THENL
1306    [DISCH_THEN(DISJ_CASES_THEN(X_CHOOSE_THEN `b:real` MP_TAC)) THENL
1307      [DISCH_THEN(X_CHOOSE_THEN `c:real` STRIP_ASSUME_TAC) THEN
1308       FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH
1309        `~(b = c) ==> &0 < abs(b - a) \/ &0 < abs(c - a)`)) THEN
1310       ASM_MESON_TAC[];
1311       MESON_TAC[REAL_LTE_TRANS]];
1312     DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
1313     ASM_CASES_TAC `?x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) <= d` THENL
1314      [DISJ2_TAC THEN FIRST_X_ASSUM(X_CHOOSE_TAC `b:real`) THEN
1315       EXISTS_TAC `b:real` THEN ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL];
1316       DISJ1_TAC THEN MAP_EVERY EXISTS_TAC [`a + d:real`; `a:real`] THEN
1317       ASM_SIMP_TAC[REAL_ADD_SUB; REAL_EQ_ADD_LCANCEL_0; REAL_LT_IMP_NZ] THEN
1318       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN
1319       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real` THEN
1320       ASM_CASES_TAC `(x:real) IN s` THEN ASM_REWRITE_TAC[] THEN
1321       ASM_REAL_ARITH_TAC]]);;
1322
1323 let EVENTUALLY_WITHINREAL = prove
1324  (`!s a p.
1325      eventually p (atreal a within s) <=>
1326         ?d. &0 < d /\ !x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) < d ==> p(x)`,
1327   REWRITE_TAC[EVENTUALLY_WITHINREAL_LE] THEN
1328   ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] THEN
1329   REWRITE_TAC[APPROACHABLE_LT_LE]);;
1330
1331 let EVENTUALLY_ATREAL = prove
1332  (`!a p. eventually p (atreal a) <=>
1333          ?d. &0 < d /\ !x. &0 < abs(x - a) /\ abs(x - a) < d ==> p(x)`,
1334   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
1335   REWRITE_TAC[EVENTUALLY_WITHINREAL; IN_UNIV]);;
1336
1337 (* ------------------------------------------------------------------------- *)
1338 (* Usual limit results with real domain and either vector or real range.     *)
1339 (* ------------------------------------------------------------------------- *)
1340
1341 let LIM_WITHINREAL_LE = prove
1342  (`!f:real->real^N l a s.
1343         (f --> l) (atreal a within s) <=>
1344            !e. &0 < e ==> ?d. &0 < d /\
1345                               !x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) <= d
1346                                    ==> dist(f(x),l) < e`,
1347   REWRITE_TAC[tendsto; EVENTUALLY_WITHINREAL_LE]);;
1348
1349 let LIM_WITHINREAL = prove
1350  (`!f:real->real^N l a s.
1351       (f --> l) (atreal a within s) <=>
1352         !e. &0 < e
1353             ==> ?d. &0 < d /\
1354                     !x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) < d
1355                     ==> dist(f(x),l) < e`,
1356   REWRITE_TAC[tendsto; EVENTUALLY_WITHINREAL] THEN MESON_TAC[]);;
1357
1358 let LIM_ATREAL = prove
1359  (`!f l:real^N a.
1360       (f --> l) (atreal a) <=>
1361               !e. &0 < e
1362                   ==> ?d. &0 < d /\ !x. &0 < abs(x - a) /\ abs(x - a) < d
1363                           ==> dist(f(x),l) < e`,
1364   REWRITE_TAC[tendsto; EVENTUALLY_ATREAL] THEN MESON_TAC[]);;
1365
1366 let REALLIM_WITHINREAL_LE = prove
1367  (`!f l a s.
1368         (f ---> l) (atreal a within s) <=>
1369            !e. &0 < e ==> ?d. &0 < d /\
1370                               !x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) <= d
1371                                    ==> abs(f(x) - l) < e`,
1372   REWRITE_TAC[tendsto_real; EVENTUALLY_WITHINREAL_LE]);;
1373
1374 let REALLIM_WITHINREAL = prove
1375  (`!f l a s.
1376       (f ---> l) (atreal a within s) <=>
1377         !e. &0 < e
1378             ==> ?d. &0 < d /\
1379                     !x. x IN s /\ &0 < abs(x - a) /\ abs(x - a) < d
1380                     ==> abs(f(x) - l) < e`,
1381   REWRITE_TAC[tendsto_real; EVENTUALLY_WITHINREAL] THEN MESON_TAC[]);;
1382
1383 let REALLIM_ATREAL = prove
1384  (`!f l a.
1385       (f ---> l) (atreal a) <=>
1386               !e. &0 < e
1387                   ==> ?d. &0 < d /\ !x. &0 < abs(x - a) /\ abs(x - a) < d
1388                           ==> abs(f(x) - l) < e`,
1389   REWRITE_TAC[tendsto_real; EVENTUALLY_ATREAL] THEN MESON_TAC[]);;
1390
1391 let REALLIM_AT_POSINFINITY = prove
1392  (`!f l. (f ---> l) at_posinfinity <=>
1393                !e. &0 < e ==> ?b. !x. x >= b ==> abs(f(x) - l) < e`,
1394   REWRITE_TAC[tendsto_real; EVENTUALLY_AT_POSINFINITY] THEN MESON_TAC[]);;
1395
1396 let REALLIM_AT_NEGINFINITY = prove
1397  (`!f l. (f ---> l) at_neginfinity <=>
1398                !e. &0 < e ==> ?b. !x. x <= b ==> abs(f(x) - l) < e`,
1399   REWRITE_TAC[tendsto_real; EVENTUALLY_AT_NEGINFINITY] THEN MESON_TAC[]);;
1400
1401 let LIM_ATREAL_WITHINREAL = prove
1402  (`!f l a s. (f --> l) (atreal a) ==> (f --> l) (atreal a within s)`,
1403   REWRITE_TAC[LIM_ATREAL; LIM_WITHINREAL] THEN MESON_TAC[]);;
1404
1405 let REALLIM_ATREAL_WITHINREAL = prove
1406  (`!f l a s. (f ---> l) (atreal a) ==> (f ---> l) (atreal a within s)`,
1407   REWRITE_TAC[REALLIM_ATREAL; REALLIM_WITHINREAL] THEN MESON_TAC[]);;
1408
1409 let REALLIM_WITHIN_SUBSET = prove
1410  (`!f l a s t. (f ---> l) (at a within s) /\ t SUBSET s
1411                ==> (f ---> l) (at a within t)`,
1412   REWRITE_TAC[REALLIM_WITHIN; SUBSET] THEN MESON_TAC[]);;
1413
1414 let REALLIM_WITHINREAL_SUBSET = prove
1415  (`!f l a s t. (f ---> l) (atreal a within s) /\ t SUBSET s
1416                ==> (f ---> l) (atreal a within t)`,
1417   REWRITE_TAC[REALLIM_WITHINREAL; SUBSET] THEN MESON_TAC[]);;
1418
1419 let LIM_WITHINREAL_SUBSET = prove
1420  (`!f l a s t. (f --> l) (atreal a within s) /\ t SUBSET s
1421                ==> (f --> l) (atreal a within t)`,
1422   REWRITE_TAC[LIM_WITHINREAL; SUBSET] THEN MESON_TAC[]);;
1423
1424 let REALLIM_ATREAL_ID = prove
1425  (`((\x. x) ---> a) (atreal a)`,
1426   REWRITE_TAC[REALLIM_ATREAL] THEN MESON_TAC[]);;
1427
1428 let REALLIM_WITHINREAL_ID = prove
1429  (`!a. ((\x. x) ---> a) (atreal a within s)`,
1430   REWRITE_TAC[REALLIM_WITHINREAL] THEN MESON_TAC[]);;
1431
1432 let LIM_TRANSFORM_WITHINREAL_SET = prove
1433  (`!f a s t.
1434         eventually (\x. x IN s <=> x IN t) (atreal a)
1435         ==> ((f --> l) (atreal a within s) <=> (f --> l) (atreal a within t))`,
1436   REPEAT GEN_TAC THEN REWRITE_TAC[EVENTUALLY_ATREAL; LIM_WITHINREAL] THEN
1437   DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
1438   EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1439   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
1440   DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
1441   EXISTS_TAC `min d k:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
1442   ASM_MESON_TAC[]);;
1443
1444 let REALLIM_TRANSFORM_WITHIN_SET = prove
1445  (`!f a s t.
1446         eventually (\x. x IN s <=> x IN t) (at a)
1447         ==> ((f ---> l) (at a within s) <=> (f ---> l) (at a within t))`,
1448   REPEAT GEN_TAC THEN REWRITE_TAC[EVENTUALLY_AT; REALLIM_WITHIN] THEN
1449   DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
1450   EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1451   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
1452   DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
1453   EXISTS_TAC `min d k:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
1454   ASM_MESON_TAC[]);;
1455
1456 let REALLIM_TRANSFORM_WITHINREAL_SET = prove
1457  (`!f a s t.
1458         eventually (\x. x IN s <=> x IN t) (atreal a)
1459         ==> ((f ---> l) (atreal a within s) <=>
1460              (f ---> l) (atreal a within t))`,
1461   REPEAT GEN_TAC THEN REWRITE_TAC[EVENTUALLY_ATREAL; REALLIM_WITHINREAL] THEN
1462   DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
1463   EQ_TAC THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1464   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
1465   DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
1466   EXISTS_TAC `min d k:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
1467   ASM_MESON_TAC[]);;
1468
1469 let REALLIM_COMPOSE_WITHIN = prove
1470  (`!net:A net f g s y z.
1471     (f ---> y) net /\
1472     eventually (\w. f w IN s /\ (f w = y ==> g y = z)) net /\
1473     (g ---> z) (atreal y within s)
1474     ==> ((g o f) ---> z) net`,
1475   REPEAT GEN_TAC THEN REWRITE_TAC[tendsto_real; CONJ_ASSOC] THEN
1476   ONCE_REWRITE_TAC[LEFT_AND_FORALL_THM] THEN
1477   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
1478   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
1479   ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
1480   REWRITE_TAC[EVENTUALLY_WITHINREAL; GSYM DIST_NZ; o_DEF] THEN
1481   DISCH_THEN(X_CHOOSE_THEN `d:real` ASSUME_TAC) THEN
1482   FIRST_X_ASSUM(MP_TAC o SPEC `d:real`) THEN
1483   ASM_REWRITE_TAC[GSYM EVENTUALLY_AND] THEN
1484   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
1485   X_GEN_TAC `x:A` THEN
1486   ASM_CASES_TAC `(f:A->real) x = y` THEN
1487   ASM_MESON_TAC[REAL_ARITH `abs(x - y) = &0 <=> x = y`;
1488                 REAL_ARITH `&0 < abs(x - y) <=> ~(x = y)`]);;
1489
1490 let REALLIM_COMPOSE_AT = prove
1491  (`!net:A net f g y z.
1492     (f ---> y) net /\
1493     eventually (\w. f w = y ==> g y = z) net /\
1494     (g ---> z) (atreal y)
1495     ==> ((g o f) ---> z) net`,
1496   REPEAT STRIP_TAC THEN
1497   MP_TAC(ISPECL [`net:A net`; `f:A->real`; `g:real->real`;
1498                  `(:real)`; `y:real`; `z:real`]
1499         REALLIM_COMPOSE_WITHIN) THEN
1500   ASM_REWRITE_TAC[IN_UNIV; WITHINREAL_UNIV]);;
1501
1502 (* ------------------------------------------------------------------------- *)
1503 (* Some real limits involving transcendentals.                               *)
1504 (* ------------------------------------------------------------------------- *)
1505
1506 let REALLIM_1_OVER_N = prove
1507  (`((\n. inv(&n)) ---> &0) sequentially`,
1508   REWRITE_TAC[REALLIM_COMPLEX; o_DEF; CX_INV; LIM_INV_N]);;
1509
1510 let REALLIM_1_OVER_POW = prove
1511  (`!k. 1 <= k ==> ((\n. inv(&n pow k)) ---> &0) sequentially`,
1512   REPEAT STRIP_TAC THEN MATCH_MP_TAC REALLIM_NULL_COMPARISON THEN
1513   EXISTS_TAC `\n. inv(&n pow 1)` THEN CONJ_TAC THENL
1514    [REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN
1515     REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_ABS_INV; REAL_ABS_POW] THEN
1516     MATCH_MP_TAC REAL_LE_INV2 THEN REWRITE_TAC[REAL_ABS_NUM] THEN
1517     CONJ_TAC THENL [MATCH_MP_TAC REAL_POW_LT; MATCH_MP_TAC REAL_POW_MONO] THEN
1518     ASM_SIMP_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_LT; LE_1];
1519     REWRITE_TAC[REAL_POW_1; REALLIM_1_OVER_N]]);;
1520
1521 let REALLIM_LOG_OVER_N = prove
1522  (`((\n. log(&n) / &n) ---> &0) sequentially`,
1523   REWRITE_TAC[REALLIM_COMPLEX] THEN MP_TAC LIM_LOG_OVER_N THEN
1524   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN
1525   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN
1526   SIMP_TAC[o_DEF; CX_DIV; CX_LOG; REAL_OF_NUM_LT;
1527            ARITH_RULE `1 <= n ==> 0 < n`]);;
1528
1529 let REALLIM_1_OVER_LOG = prove
1530  (`((\n. inv(log(&n))) ---> &0) sequentially`,
1531   REWRITE_TAC[REALLIM_COMPLEX] THEN MP_TAC LIM_1_OVER_LOG THEN
1532   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LIM_TRANSFORM_EVENTUALLY) THEN
1533   REWRITE_TAC[o_DEF; complex_div; COMPLEX_MUL_LID; CX_INV] THEN
1534   REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN EXISTS_TAC `1` THEN
1535   SIMP_TAC[CX_LOG; REAL_OF_NUM_LT; ARITH_RULE `1 <= n ==> 0 < n`]);;
1536
1537 let REALLIM_POWN = prove
1538  (`!z. abs(z) < &1 ==> ((\n. z pow n) ---> &0) sequentially`,
1539   REWRITE_TAC[REALLIM_COMPLEX; o_DEF; CX_POW] THEN
1540   REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_POWN THEN
1541   ASM_REWRITE_TAC[COMPLEX_NORM_CX]);;
1542
1543 let REALLIM_X_TIMES_LOG = prove
1544  (`((\x. x * log x) ---> &0) (atreal(&0) within {x | &0 <= x})`,
1545   MP_TAC LIM_Z_TIMES_CLOG THEN
1546   REWRITE_TAC[REALLIM_WITHINREAL; LIM_AT] THEN
1547   REWRITE_TAC[IN_ELIM_THM; REAL_SUB_RZERO; dist; COMPLEX_SUB_RZERO] THEN
1548   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
1549   ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
1550   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN
1551   ASM_CASES_TAC `&0 < d` THEN ASM_REWRITE_TAC[] THEN
1552   DISCH_TAC THEN X_GEN_TAC `x:real` THEN
1553   ASM_CASES_TAC `x = &0` THENL [ASM_REAL_ARITH_TAC; STRIP_TAC] THEN
1554   SUBGOAL_THEN `&0 < x` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
1555   FIRST_X_ASSUM(MP_TAC o SPEC `Cx x`) THEN
1556   ASM_SIMP_TAC[COMPLEX_NORM_MUL; GSYM CX_LOG; COMPLEX_NORM_CX] THEN
1557   REWRITE_TAC[REAL_ABS_MUL]);;
1558
1559 (* ------------------------------------------------------------------------- *)
1560 (* Relations between limits at real and complex limit points.                *)
1561 (* ------------------------------------------------------------------------- *)
1562
1563 let TRIVIAL_LIMIT_WITHINREAL_WITHIN = prove
1564  (`trivial_limit(atreal x within s) <=>
1565         trivial_limit(at (lift x) within (IMAGE lift s))`,
1566   REWRITE_TAC[trivial_limit; AT; WITHIN; ATREAL] THEN
1567   REWRITE_TAC[FORALL_LIFT; EXISTS_LIFT; LIFT_EQ; DIST_LIFT] THEN
1568   REWRITE_TAC[IN_IMAGE_LIFT_DROP; LIFT_DROP]);;
1569
1570 let TRIVIAL_LIMIT_WITHINREAL_WITHINCOMPLEX = prove
1571  (`trivial_limit(atreal x within s) <=>
1572         trivial_limit(at (Cx x) within (real INTER IMAGE Cx s))`,
1573   REWRITE_TAC[trivial_limit; AT; WITHIN; ATREAL] THEN
1574   REWRITE_TAC[SET_RULE `x IN real INTER s <=> real x /\ x IN s`] THEN
1575   REWRITE_TAC[TAUT `~(p /\ x /\ q) /\ ~(r /\ x /\ s) <=>
1576                     x ==> ~(p /\ q) /\ ~(r /\ s)`] THEN
1577   REWRITE_TAC[FORALL_REAL;
1578     MESON[IN_IMAGE; CX_INJ] `Cx x IN IMAGE Cx s <=> x IN s`] THEN
1579   REWRITE_TAC[dist; GSYM CX_SUB; o_THM; RE_CX; COMPLEX_NORM_CX] THEN
1580   MATCH_MP_TAC(TAUT `~p /\ ~q /\ (r <=> s) ==> (p \/ r <=> q \/ s)`) THEN
1581   REPEAT CONJ_TAC THEN TRY EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THENL
1582    [DISCH_THEN(MP_TAC o SPECL [`&0`; `&1`]) THEN CONV_TAC REAL_RING;
1583     DISCH_THEN(MP_TAC o SPECL [`Cx(&0)`; `Cx(&1)`]) THEN
1584     CONV_TAC COMPLEX_RING;
1585     MAP_EVERY X_GEN_TAC [`a:real`; `b:real`] THEN STRIP_TAC THEN
1586     MAP_EVERY EXISTS_TAC [`Cx a`; `Cx b`] THEN ASM_REWRITE_TAC[CX_INJ] THEN
1587     ASM_REWRITE_TAC[GSYM CX_SUB; COMPLEX_NORM_CX];
1588     MAP_EVERY X_GEN_TAC [`a:complex`; `b:complex`] THEN STRIP_TAC THEN
1589     SUBGOAL_THEN
1590      `?d. &0 < d /\
1591           !z. &0 < abs(z - x) /\ abs(z - x) <= d ==> ~(z IN s)`
1592     STRIP_ASSUME_TAC THENL
1593      [MATCH_MP_TAC(MESON[] `!a b. P a \/ P b ==> ?x. P x`) THEN
1594       MAP_EVERY EXISTS_TAC [`norm(a - Cx x)`; `norm(b - Cx x)`] THEN
1595       ASM_REWRITE_TAC[TAUT `a ==> ~b <=> ~(a /\ b)`] THEN
1596       UNDISCH_TAC `~(a:complex = b)` THEN NORM_ARITH_TAC;
1597       ALL_TAC] THEN
1598     MAP_EVERY EXISTS_TAC [`x + d:real`; `x - d:real`] THEN
1599     ASM_SIMP_TAC[REAL_ARITH `&0 < d ==> ~(x + d = x - d)`;
1600                  REAL_ARITH `&0 < d ==> abs((x + d) - x) = d`;
1601                  REAL_ARITH `&0 < d ==> abs(x - d - x) = d`] THEN
1602     ASM_MESON_TAC[]]);;
1603
1604 let LIM_WITHINREAL_WITHINCOMPLEX = prove
1605  (`(f --> a) (atreal x within s) <=>
1606    ((f o Re) --> a) (at(Cx x) within (real INTER IMAGE Cx s))`,
1607   REWRITE_TAC[LIM_WITHINREAL; LIM_WITHIN] THEN
1608   REWRITE_TAC[SET_RULE `x IN real INTER s <=> real x /\ x IN s`] THEN
1609   REWRITE_TAC[IMP_CONJ; FORALL_REAL;
1610     MESON[IN_IMAGE; CX_INJ] `Cx x IN IMAGE Cx s <=> x IN s`] THEN
1611   REWRITE_TAC[dist; GSYM CX_SUB; o_THM; RE_CX; COMPLEX_NORM_CX]);;
1612
1613 let LIM_ATREAL_ATCOMPLEX = prove
1614  (`(f --> a) (atreal x) <=> ((f o Re) --> a) (at (Cx x) within real)`,
1615   REWRITE_TAC[LIM_ATREAL; LIM_WITHIN] THEN
1616   REWRITE_TAC[IMP_CONJ; FORALL_REAL; IN; dist; GSYM CX_SUB; COMPLEX_NORM_CX;
1617               o_THM; RE_CX]);;
1618
1619 (* ------------------------------------------------------------------------- *)
1620 (* Simpler theorems relating limits in real and real^1.                      *)
1621 (* ------------------------------------------------------------------------- *)
1622
1623 let LIM_WITHINREAL_WITHIN = prove
1624  (`(f --> a) (atreal x within s) <=>
1625         ((f o drop) --> a) (at (lift x) within (IMAGE lift s))`,
1626   REWRITE_TAC[LIM_WITHINREAL; LIM_WITHIN] THEN
1627   REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; DIST_LIFT; o_THM; LIFT_DROP]);;
1628
1629 let LIM_ATREAL_AT = prove
1630  (`(f --> a) (atreal x) <=> ((f o drop) --> a) (at (lift x))`,
1631   REWRITE_TAC[LIM_ATREAL; LIM_AT; FORALL_LIFT] THEN
1632   REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; DIST_LIFT; o_THM; LIFT_DROP]);;
1633
1634 let REALLIM_WITHINREAL_WITHIN = prove
1635  (`(f ---> a) (atreal x within s) <=>
1636         ((f o drop) ---> a) (at (lift x) within (IMAGE lift s))`,
1637   REWRITE_TAC[REALLIM_WITHINREAL; REALLIM_WITHIN] THEN
1638   REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; DIST_LIFT; o_THM; LIFT_DROP]);;
1639
1640 let REALLIM_ATREAL_AT = prove
1641  (`(f ---> a) (atreal x) <=> ((f o drop) ---> a) (at (lift x))`,
1642   REWRITE_TAC[REALLIM_ATREAL; REALLIM_AT; FORALL_LIFT] THEN
1643   REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; DIST_LIFT; o_THM; LIFT_DROP]);;
1644
1645 let REALLIM_WITHIN_OPEN = prove
1646  (`!f:real^N->real l a s.
1647         a IN s /\ open s
1648         ==> ((f ---> l) (at a within s) <=> (f ---> l) (at a))`,
1649   REWRITE_TAC[TENDSTO_REAL; LIM_WITHIN_OPEN]);;
1650
1651 let LIM_WITHIN_REAL_OPEN = prove
1652  (`!f:real->real^N l a s.
1653         a IN s /\ real_open s
1654         ==> ((f --> l) (atreal a within s) <=> (f --> l) (atreal a))`,
1655   REWRITE_TAC[LIM_WITHINREAL_WITHIN; LIM_ATREAL_AT; REAL_OPEN] THEN
1656   REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_WITHIN_OPEN THEN ASM SET_TAC[]);;
1657
1658 let REALLIM_WITHIN_REAL_OPEN = prove
1659  (`!f l a s.
1660         a IN s /\ real_open s
1661         ==> ((f ---> l) (atreal a within s) <=> (f ---> l) (atreal a))`,
1662   REWRITE_TAC[TENDSTO_REAL; LIM_WITHIN_REAL_OPEN]);;
1663
1664 (* ------------------------------------------------------------------------- *)
1665 (* Additional congruence rules for simplifying limits.                       *)
1666 (* ------------------------------------------------------------------------- *)
1667
1668 let LIM_CONG_WITHINREAL = prove
1669  (`(!x. ~(x = a) ==> f x = g x)
1670    ==> (((\x. f x) --> l) (atreal a within s) <=>
1671         ((g --> l) (atreal a within s)))`,
1672   SIMP_TAC[LIM_WITHINREAL; GSYM REAL_ABS_NZ; REAL_SUB_0]);;
1673
1674 let LIM_CONG_ATREAL = prove
1675  (`(!x. ~(x = a) ==> f x = g x)
1676    ==> (((\x. f x) --> l) (atreal a) <=> ((g --> l) (atreal a)))`,
1677   SIMP_TAC[LIM_ATREAL; GSYM REAL_ABS_NZ; REAL_SUB_0]);;
1678
1679 extend_basic_congs [LIM_CONG_WITHINREAL; LIM_CONG_ATREAL];;
1680
1681 let REALLIM_CONG_WITHIN = prove
1682  (`(!x. ~(x = a) ==> f x = g x)
1683    ==> (((\x. f x) ---> l) (at a within s) <=> ((g ---> l) (at a within s)))`,
1684   REWRITE_TAC[REALLIM_WITHIN; GSYM DIST_NZ] THEN SIMP_TAC[]);;
1685
1686 let REALLIM_CONG_AT = prove
1687  (`(!x. ~(x = a) ==> f x = g x)
1688    ==> (((\x. f x) ---> l) (at a) <=> ((g ---> l) (at a)))`,
1689   REWRITE_TAC[REALLIM_AT; GSYM DIST_NZ] THEN SIMP_TAC[]);;
1690
1691 extend_basic_congs [REALLIM_CONG_WITHIN; REALLIM_CONG_AT];;
1692
1693 let REALLIM_CONG_WITHINREAL = prove
1694  (`(!x. ~(x = a) ==> f x = g x)
1695    ==> (((\x. f x) ---> l) (atreal a within s) <=>
1696         ((g ---> l) (atreal a within s)))`,
1697   SIMP_TAC[REALLIM_WITHINREAL; GSYM REAL_ABS_NZ; REAL_SUB_0]);;
1698
1699 let REALLIM_CONG_ATREAL = prove
1700  (`(!x. ~(x = a) ==> f x = g x)
1701    ==> (((\x. f x) ---> l) (atreal a) <=> ((g ---> l) (atreal a)))`,
1702   SIMP_TAC[REALLIM_ATREAL; GSYM REAL_ABS_NZ; REAL_SUB_0]);;
1703
1704 extend_basic_congs [REALLIM_CONG_WITHINREAL; REALLIM_CONG_ATREAL];;
1705
1706 (* ------------------------------------------------------------------------- *)
1707 (* Real version of Abel limit theorem.                                       *)
1708 (* ------------------------------------------------------------------------- *)
1709
1710 let REAL_ABEL_LIMIT_THEOREM = prove
1711  (`!s a. real_summable s a
1712          ==> (!r. abs(r) < &1 ==> real_summable s (\i. a i * r pow i)) /\
1713              ((\r. real_infsum s  (\i. a i * r pow i)) ---> real_infsum s a)
1714              (atreal (&1) within {z | z <= &1})`,
1715   REPEAT GEN_TAC THEN STRIP_TAC THEN
1716   MP_TAC(ISPECL [`&1`; `s:num->bool`; `Cx o (a:num->real)`]
1717         ABEL_LIMIT_THEOREM) THEN
1718   ASM_REWRITE_TAC[GSYM REAL_SUMMABLE_COMPLEX; REAL_LT_01] THEN STRIP_TAC THEN
1719   MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
1720    [X_GEN_TAC `r:real` THEN STRIP_TAC THEN
1721     FIRST_X_ASSUM(MP_TAC o SPEC `Cx r`) THEN
1722     ASM_REWRITE_TAC[COMPLEX_NORM_CX; REAL_SUMMABLE_COMPLEX] THEN
1723     REWRITE_TAC[o_DEF; CX_MUL; CX_POW];
1724     DISCH_TAC] THEN
1725   REWRITE_TAC[REALLIM_COMPLEX; LIM_WITHINREAL_WITHINCOMPLEX] THEN
1726   MATCH_MP_TAC LIM_TRANSFORM_WITHIN THEN
1727   EXISTS_TAC `\z. infsum s (\i. (Cx o a) i * z pow i)` THEN
1728   EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN CONJ_TAC THENL
1729    [REWRITE_TAC[IMP_CONJ; IN_INTER; IN_ELIM_THM; IN_IMAGE] THEN
1730     REWRITE_TAC[IN; FORALL_REAL] THEN X_GEN_TAC `r:real` THEN
1731     REWRITE_TAC[CX_INJ; UNWIND_THM1; dist; GSYM CX_SUB; COMPLEX_NORM_CX] THEN
1732     DISCH_TAC THEN
1733     ASM_SIMP_TAC[REAL_ARITH `r <= &1 ==> (&0 < abs(r - &1) <=> r < &1)`] THEN
1734     REPEAT DISCH_TAC THEN SUBGOAL_THEN `abs(r) < &1` ASSUME_TAC THENL
1735      [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
1736     ASM_SIMP_TAC[REAL_INFSUM_COMPLEX; o_THM; RE_CX] THEN
1737     CONV_TAC SYM_CONV THEN REWRITE_TAC[GSYM REAL; o_DEF; CX_MUL; CX_POW] THEN
1738     MATCH_MP_TAC(ISPEC `sequentially` REAL_LIM) THEN
1739     EXISTS_TAC `\n. vsum(s INTER (0..n)) (\i. Cx(a i) * Cx r pow i)` THEN
1740     REWRITE_TAC[SEQUENTIALLY; TRIVIAL_LIMIT_SEQUENTIALLY; GSYM sums] THEN
1741     SIMP_TAC[GSYM CX_POW; GSYM CX_MUL; REAL_VSUM; FINITE_INTER; FINITE_NUMSEG;
1742              SUMS_INFSUM; REAL_CX; GE] THEN
1743     CONJ_TAC THENL [ALL_TAC; MESON_TAC[LE_REFL]] THEN
1744     ONCE_REWRITE_TAC[GSYM o_DEF] THEN
1745     ASM_SIMP_TAC[GSYM REAL_SUMMABLE_COMPLEX];
1746     ALL_TAC] THEN
1747   ASM_SIMP_TAC[REAL_INFSUM_COMPLEX] THEN
1748   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_WITHIN]) THEN
1749   REWRITE_TAC[LIM_WITHIN] THEN
1750   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
1751   ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
1752   REWRITE_TAC[REAL_MUL_LID; IN_ELIM_THM; IN_INTER; IN_IMAGE] THEN
1753   DISCH_THEN(X_CHOOSE_THEN `d:real`
1754    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*"))) THEN
1755   EXISTS_TAC `min d (&1)` THEN ASM_REWRITE_TAC[REAL_LT_MIN; REAL_LT_01] THEN
1756   REWRITE_TAC[IMP_CONJ; IN; FORALL_REAL] THEN
1757   REWRITE_TAC[CX_INJ; UNWIND_THM1; dist; GSYM CX_SUB; COMPLEX_NORM_CX] THEN
1758   X_GEN_TAC `r:real` THEN DISCH_TAC THEN
1759   ASM_SIMP_TAC[REAL_ARITH `r <= &1 ==> (&0 < abs(r - &1) <=> r < &1)`] THEN
1760   REPEAT DISCH_TAC THEN SUBGOAL_THEN `abs(r) < &1` ASSUME_TAC THENL
1761    [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
1762   REMOVE_THEN "*" (MP_TAC o SPEC `Cx r`) THEN
1763   REWRITE_TAC[CX_INJ; UNWIND_THM1; dist; GSYM CX_SUB; COMPLEX_NORM_CX] THEN
1764   ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
1765   MATCH_MP_TAC(NORM_ARITH `b = a ==> norm(x - a) < e ==> norm(x - b) < e`) THEN
1766   REWRITE_TAC[GSYM REAL] THEN
1767   MATCH_MP_TAC(ISPEC `sequentially` REAL_LIM) THEN
1768   EXISTS_TAC `\n. vsum(s INTER (0..n)) (Cx o a)` THEN
1769   REWRITE_TAC[SEQUENTIALLY; TRIVIAL_LIMIT_SEQUENTIALLY; GSYM sums] THEN
1770   SIMP_TAC[GSYM CX_POW; GSYM CX_MUL; REAL_VSUM; FINITE_INTER; FINITE_NUMSEG;
1771            SUMS_INFSUM; REAL_CX; GE; o_DEF] THEN
1772   CONJ_TAC THENL [ALL_TAC; MESON_TAC[LE_REFL]] THEN
1773   ONCE_REWRITE_TAC[GSYM o_DEF] THEN
1774   ASM_SIMP_TAC[GSYM REAL_SUMMABLE_COMPLEX]);;
1775
1776 (* ------------------------------------------------------------------------- *)
1777 (* Continuity of a function into the reals.                                  *)
1778 (* ------------------------------------------------------------------------- *)
1779
1780 parse_as_infix ("real_continuous",(12,"right"));;
1781
1782 let real_continuous = new_definition
1783   `f real_continuous net <=> (f ---> f(netlimit net)) net`;;
1784
1785 let REAL_CONTINUOUS_TRIVIAL_LIMIT = prove
1786  (`!f net. trivial_limit net ==> f real_continuous net`,
1787   SIMP_TAC[real_continuous; REALLIM]);;
1788
1789 let REAL_CONTINUOUS_WITHIN = prove
1790  (`!f x:real^N s.
1791         f real_continuous (at x within s) <=>
1792                 (f ---> f(x)) (at x within s)`,
1793   REPEAT GEN_TAC THEN REWRITE_TAC[real_continuous] THEN
1794   ASM_CASES_TAC `trivial_limit(at(x:real^N) within s)` THENL
1795    [ASM_REWRITE_TAC[REALLIM]; ASM_SIMP_TAC[NETLIMIT_WITHIN]]);;
1796
1797 let REAL_CONTINUOUS_AT = prove
1798  (`!f x. f real_continuous (at x) <=> (f ---> f(x)) (at x)`,
1799   ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
1800   REWRITE_TAC[REAL_CONTINUOUS_WITHIN; IN_UNIV]);;
1801
1802 let REAL_CONTINUOUS_WITHINREAL = prove
1803  (`!f x s. f real_continuous (atreal x within s) <=>
1804                 (f ---> f(x)) (atreal x within s)`,
1805   REPEAT GEN_TAC THEN REWRITE_TAC[real_continuous] THEN
1806   ASM_CASES_TAC `trivial_limit(atreal x within s)` THENL
1807    [ASM_REWRITE_TAC[REALLIM]; ASM_SIMP_TAC[NETLIMIT_WITHINREAL]]);;
1808
1809 let REAL_CONTINUOUS_ATREAL = prove
1810  (`!f x. f real_continuous (atreal x) <=> (f ---> f(x)) (atreal x)`,
1811   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
1812   REWRITE_TAC[REAL_CONTINUOUS_WITHINREAL; IN_UNIV]);;
1813
1814 let CONTINUOUS_WITHINREAL = prove
1815  (`!f x s. f continuous (atreal x within s) <=>
1816                  (f --> f(x)) (atreal x within s)`,
1817   REPEAT GEN_TAC THEN REWRITE_TAC[continuous] THEN
1818   ASM_CASES_TAC `trivial_limit(atreal x within s)` THENL
1819    [ASM_REWRITE_TAC[LIM]; ASM_SIMP_TAC[NETLIMIT_WITHINREAL]]);;
1820
1821 let CONTINUOUS_ATREAL = prove
1822  (`!f x. f continuous (atreal x) <=> (f --> f(x)) (atreal x)`,
1823   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
1824   REWRITE_TAC[CONTINUOUS_WITHINREAL; IN_UNIV]);;
1825
1826 let real_continuous_within = prove
1827  (`f real_continuous (at x within s) <=>
1828         !e. &0 < e
1829             ==> ?d. &0 < d /\
1830                     (!x'. x' IN s /\ dist(x',x) < d ==> abs(f x' - f x) < e)`,
1831   REWRITE_TAC[REAL_CONTINUOUS_WITHIN; REALLIM_WITHIN] THEN
1832   REWRITE_TAC[GSYM DIST_NZ] THEN
1833   EQ_TAC THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
1834   ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
1835   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
1836   MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN
1837   ASM_MESON_TAC[REAL_ARITH `abs(x - x) = &0`]);;
1838
1839 let real_continuous_at = prove
1840  (`f real_continuous (at x) <=>
1841         !e. &0 < e
1842             ==> ?d. &0 < d /\
1843                     (!x'. dist(x',x) < d ==> abs(f x' - f x) < e)`,
1844   ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
1845   REWRITE_TAC[real_continuous_within; IN_UNIV]);;
1846
1847 let real_continuous_withinreal = prove
1848  (`f real_continuous (atreal x within s) <=>
1849         !e. &0 < e
1850             ==> ?d. &0 < d /\
1851                     (!x'. x' IN s /\ abs(x' - x) < d ==> abs(f x' - f x) < e)`,
1852   REWRITE_TAC[REAL_CONTINUOUS_WITHINREAL; REALLIM_WITHINREAL] THEN
1853   REWRITE_TAC[REAL_ARITH `&0 < abs(x - y) <=> ~(x = y)`] THEN
1854   EQ_TAC THEN MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
1855   ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
1856   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
1857   MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN
1858   ASM_MESON_TAC[REAL_ARITH `abs(x - x) = &0`]);;
1859
1860 let real_continuous_atreal = prove
1861  (`f real_continuous (atreal x) <=>
1862         !e. &0 < e
1863             ==> ?d. &0 < d /\
1864                     (!x'. abs(x' - x) < d ==> abs(f x' - f x) < e)`,
1865   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
1866   REWRITE_TAC[real_continuous_withinreal; IN_UNIV]);;
1867
1868 let REAL_CONTINUOUS_AT_WITHIN = prove
1869  (`!f s x. f real_continuous (at x)
1870            ==> f real_continuous (at x within s)`,
1871   REWRITE_TAC[real_continuous_within; real_continuous_at] THEN
1872   MESON_TAC[]);;
1873
1874 let REAL_CONTINUOUS_ATREAL_WITHINREAL = prove
1875  (`!f s x. f real_continuous (atreal x)
1876            ==> f real_continuous (atreal x within s)`,
1877   REWRITE_TAC[real_continuous_withinreal; real_continuous_atreal] THEN
1878   MESON_TAC[]);;
1879
1880 let REAL_CONTINUOUS_WITHINREAL_SUBSET = prove
1881  (`!f s t. f real_continuous (atreal x within s) /\ t SUBSET s
1882              ==> f real_continuous (atreal x within t)`,
1883   REWRITE_TAC[REAL_CONTINUOUS_WITHINREAL; REALLIM_WITHINREAL_SUBSET]);;
1884
1885 let REAL_CONTINUOUS_WITHIN_SUBSET = prove
1886  (`!f s t. f real_continuous (at x within s) /\ t SUBSET s
1887              ==> f real_continuous (at x within t)`,
1888   REWRITE_TAC[REAL_CONTINUOUS_WITHIN; REALLIM_WITHIN_SUBSET]);;
1889
1890 let CONTINUOUS_WITHINREAL_SUBSET = prove
1891  (`!f s t. f continuous (atreal x within s) /\ t SUBSET s
1892              ==> f continuous (atreal x within t)`,
1893   REWRITE_TAC[CONTINUOUS_WITHINREAL; LIM_WITHINREAL_SUBSET]);;
1894
1895 let continuous_withinreal = prove
1896  (`f continuous (atreal x within s) <=>
1897         !e. &0 < e
1898             ==> ?d. &0 < d /\
1899                     (!x'. x' IN s /\ abs(x' - x) < d ==> dist(f x',f x) < e)`,
1900   REWRITE_TAC[CONTINUOUS_WITHINREAL; LIM_WITHINREAL] THEN
1901   REWRITE_TAC[REAL_ARITH `&0 < abs(x - y) <=> ~(x = y)`] THEN
1902   AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `e:real` THEN
1903   ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
1904   AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `d:real` THEN
1905   ASM_CASES_TAC `&0 < d` THEN ASM_REWRITE_TAC[] THEN
1906   AP_TERM_TAC THEN ABS_TAC THEN ASM_MESON_TAC[DIST_REFL]);;
1907
1908 let continuous_atreal = prove
1909  (`f continuous (atreal x) <=>
1910         !e. &0 < e
1911             ==> ?d. &0 < d /\
1912                     (!x'. abs(x' - x) < d ==> dist(f x',f x) < e)`,
1913   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
1914   REWRITE_TAC[continuous_withinreal; IN_UNIV]);;
1915
1916 let CONTINUOUS_ATREAL_WITHINREAL = prove
1917  (`!f x s. f continuous (atreal x) ==> f continuous (atreal x within s)`,
1918   SIMP_TAC[continuous_atreal; continuous_withinreal] THEN MESON_TAC[]);;
1919
1920 let CONTINUOUS_CX_ATREAL = prove
1921  (`!x. Cx continuous (atreal x)`,
1922   GEN_TAC THEN REWRITE_TAC[continuous_atreal; dist] THEN
1923   REWRITE_TAC[COMPLEX_NORM_CX; GSYM CX_SUB] THEN MESON_TAC[]);;
1924
1925 let CONTINUOUS_CX_WITHINREAL = prove
1926  (`!s x. Cx continuous (atreal x within s)`,
1927   SIMP_TAC[CONTINUOUS_ATREAL_WITHINREAL; CONTINUOUS_CX_ATREAL]);;
1928
1929 (* ------------------------------------------------------------------------- *)
1930 (* Arithmetic combining theorems.                                            *)
1931 (* ------------------------------------------------------------------------- *)
1932
1933 let REAL_CONTINUOUS_CONST = prove
1934  (`!net c. (\x. c) real_continuous net`,
1935   REWRITE_TAC[real_continuous; REALLIM_CONST]);;
1936
1937 let REAL_CONTINUOUS_LMUL = prove
1938  (`!f c net. f real_continuous net ==> (\x. c * f(x)) real_continuous net`,
1939   REWRITE_TAC[real_continuous; REALLIM_LMUL]);;
1940
1941 let REAL_CONTINUOUS_RMUL = prove
1942  (`!f c net. f real_continuous net ==> (\x. f(x) * c) real_continuous net`,
1943   REWRITE_TAC[real_continuous; REALLIM_RMUL]);;
1944
1945 let REAL_CONTINUOUS_NEG = prove
1946  (`!f net. f real_continuous net ==> (\x. --(f x)) real_continuous net`,
1947   REWRITE_TAC[real_continuous; REALLIM_NEG]);;
1948
1949 let REAL_CONTINUOUS_ADD = prove
1950  (`!f g net. f real_continuous net /\ g real_continuous net
1951            ==> (\x. f(x) + g(x)) real_continuous net`,
1952   REWRITE_TAC[real_continuous; REALLIM_ADD]);;
1953
1954 let REAL_CONTINUOUS_SUB = prove
1955  (`!f g net. f real_continuous net /\ g real_continuous net
1956            ==> (\x. f(x) - g(x)) real_continuous net`,
1957   REWRITE_TAC[real_continuous; REALLIM_SUB]);;
1958
1959 let REAL_CONTINUOUS_MUL = prove
1960  (`!net f g.
1961      f real_continuous net /\ g real_continuous net
1962      ==> (\x. f(x) * g(x)) real_continuous net`,
1963   SIMP_TAC[real_continuous; REALLIM_MUL]);;
1964
1965 let REAL_CONTINUOUS_INV = prove
1966  (`!net f.
1967     f real_continuous net /\ ~(f(netlimit net) = &0)
1968     ==> (\x. inv(f x)) real_continuous net`,
1969   SIMP_TAC[real_continuous; REALLIM_INV]);;
1970
1971 let REAL_CONTINUOUS_DIV = prove
1972  (`!net f g.
1973     f real_continuous net /\ g real_continuous net /\ ~(g(netlimit net) = &0)
1974     ==> (\x. f(x) / g(x)) real_continuous net`,
1975   SIMP_TAC[real_continuous; REALLIM_DIV]);;
1976
1977 let REAL_CONTINUOUS_POW = prove
1978  (`!net f n. f real_continuous net ==> (\x. f(x) pow n) real_continuous net`,
1979   SIMP_TAC[real_continuous; REALLIM_POW]);;
1980
1981 let REAL_CONTINUOUS_ABS = prove
1982  (`!net f. f real_continuous net ==> (\x. abs(f(x))) real_continuous net`,
1983   REWRITE_TAC[real_continuous; REALLIM_ABS]);;
1984
1985 let REAL_CONTINUOUS_MAX = prove
1986  (`!f g net. f real_continuous net /\ g real_continuous net
1987            ==> (\x. max (f x) (g x)) real_continuous net`,
1988   REWRITE_TAC[real_continuous; REALLIM_MAX]);;
1989
1990 let REAL_CONTINUOUS_MIN = prove
1991  (`!f g net. f real_continuous net /\ g real_continuous net
1992            ==> (\x. min (f x) (g x)) real_continuous net`,
1993   REWRITE_TAC[real_continuous; REALLIM_MIN]);;
1994
1995 (* ------------------------------------------------------------------------- *)
1996 (* Some of these without netlimit, but with many different cases.            *)
1997 (* ------------------------------------------------------------------------- *)
1998
1999 let REAL_CONTINUOUS_WITHIN_ID = prove
2000  (`!x s. (\x. x) real_continuous (atreal x within s)`,
2001   REWRITE_TAC[real_continuous_withinreal] THEN MESON_TAC[]);;
2002
2003 let REAL_CONTINUOUS_AT_ID = prove
2004  (`!x. (\x. x) real_continuous (atreal x)`,
2005   REWRITE_TAC[real_continuous_atreal] THEN MESON_TAC[]);;
2006
2007 let REAL_CONTINUOUS_INV_WITHIN = prove
2008  (`!f s a. f real_continuous (at a within s) /\ ~(f a = &0)
2009            ==> (\x. inv(f x)) real_continuous (at a within s)`,
2010   MESON_TAC[REAL_CONTINUOUS_INV; REAL_CONTINUOUS_TRIVIAL_LIMIT;
2011             NETLIMIT_WITHIN]);;
2012
2013 let REAL_CONTINUOUS_INV_AT = prove
2014  (`!f a. f real_continuous (at a) /\ ~(f a = &0)
2015          ==> (\x. inv(f x)) real_continuous (at a)`,
2016   ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
2017   REWRITE_TAC[REAL_CONTINUOUS_INV_WITHIN]);;
2018
2019 let REAL_CONTINUOUS_INV_WITHINREAL = prove
2020  (`!f s a. f real_continuous (atreal a within s) /\ ~(f a = &0)
2021            ==> (\x. inv(f x)) real_continuous (atreal a within s)`,
2022   MESON_TAC[REAL_CONTINUOUS_INV; REAL_CONTINUOUS_TRIVIAL_LIMIT;
2023             NETLIMIT_WITHINREAL]);;
2024
2025 let REAL_CONTINUOUS_INV_ATREAL = prove
2026  (`!f a. f real_continuous (atreal a) /\ ~(f a = &0)
2027          ==> (\x. inv(f x)) real_continuous (atreal a)`,
2028   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
2029   REWRITE_TAC[REAL_CONTINUOUS_INV_WITHINREAL]);;
2030
2031 let REAL_CONTINUOUS_DIV_WITHIN = prove
2032  (`!f s a. f real_continuous (at a within s) /\
2033            g real_continuous (at a within s) /\ ~(g a = &0)
2034            ==> (\x. f x / g x) real_continuous (at a within s)`,
2035   MESON_TAC[REAL_CONTINUOUS_DIV; REAL_CONTINUOUS_TRIVIAL_LIMIT;
2036             NETLIMIT_WITHIN]);;
2037
2038 let REAL_CONTINUOUS_DIV_AT = prove
2039  (`!f a. f real_continuous (at a) /\
2040          g real_continuous (at a) /\ ~(g a = &0)
2041          ==> (\x. f x / g x) real_continuous (at a)`,
2042   ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
2043   REWRITE_TAC[REAL_CONTINUOUS_DIV_WITHIN]);;
2044
2045 let REAL_CONTINUOUS_DIV_WITHINREAL = prove
2046  (`!f s a. f real_continuous (atreal a within s) /\
2047            g real_continuous (atreal a within s) /\ ~(g a = &0)
2048            ==> (\x. f x / g x) real_continuous (atreal a within s)`,
2049   MESON_TAC[REAL_CONTINUOUS_DIV; REAL_CONTINUOUS_TRIVIAL_LIMIT;
2050             NETLIMIT_WITHINREAL]);;
2051
2052 let REAL_CONTINUOUS_DIV_ATREAL = prove
2053  (`!f a. f real_continuous (atreal a) /\
2054          g real_continuous (atreal a) /\ ~(g a = &0)
2055          ==> (\x. f x / g x) real_continuous (atreal a)`,
2056   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
2057   REWRITE_TAC[REAL_CONTINUOUS_DIV_WITHINREAL]);;
2058
2059 (* ------------------------------------------------------------------------- *)
2060 (* Composition of (real->real) o (real->real) functions.                     *)
2061 (* ------------------------------------------------------------------------- *)
2062
2063 let REAL_CONTINUOUS_WITHINREAL_COMPOSE = prove
2064  (`!f g x s. f real_continuous (atreal x within s) /\
2065              g real_continuous (atreal (f x) within IMAGE f s)
2066              ==> (g o f) real_continuous (atreal x within s)`,
2067   REPEAT GEN_TAC THEN
2068   REWRITE_TAC[real_continuous_withinreal; o_THM; IN_IMAGE] THEN
2069   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2070   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2071   ASM_MESON_TAC[]);;
2072
2073 let REAL_CONTINUOUS_ATREAL_COMPOSE = prove
2074  (`!f g x. f real_continuous (atreal x) /\ g real_continuous (atreal (f x))
2075            ==> (g o f) real_continuous (atreal x)`,
2076   REPEAT GEN_TAC THEN
2077   REWRITE_TAC[real_continuous_atreal; o_THM; IN_IMAGE] THEN
2078   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2079   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2080   ASM_MESON_TAC[]);;
2081
2082 (* ------------------------------------------------------------------------- *)
2083 (* Composition of (real->real) o (real^N->real) functions.                   *)
2084 (* ------------------------------------------------------------------------- *)
2085
2086 let REAL_CONTINUOUS_WITHIN_COMPOSE = prove
2087  (`!f g x s. f real_continuous (at x within s) /\
2088              g real_continuous (atreal (f x) within IMAGE f s)
2089              ==> (g o f) real_continuous (at x within s)`,
2090   REPEAT GEN_TAC THEN
2091   REWRITE_TAC[real_continuous_withinreal; real_continuous_within;
2092               o_THM; IN_IMAGE] THEN
2093   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2094   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2095   ASM_MESON_TAC[]);;
2096
2097 let REAL_CONTINUOUS_AT_COMPOSE = prove
2098  (`!f g x. f real_continuous (at x) /\
2099            g real_continuous (atreal (f x) within IMAGE f (:real^N))
2100            ==> (g o f) real_continuous (at x)`,
2101   ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
2102   REWRITE_TAC[REAL_CONTINUOUS_WITHIN_COMPOSE]);;
2103
2104 (* ------------------------------------------------------------------------- *)
2105 (* Composition of (real^N->real) o (real^M->real^N) functions.               *)
2106 (* ------------------------------------------------------------------------- *)
2107
2108 let REAL_CONTINUOUS_CONTINUOUS_WITHIN_COMPOSE = prove
2109  (`!f g x s. f continuous (at x within s) /\
2110              g real_continuous (at (f x) within IMAGE f s)
2111              ==> (g o f) real_continuous (at x within s)`,
2112   REPEAT GEN_TAC THEN
2113   REWRITE_TAC[real_continuous_within; continuous_within; o_THM; IN_IMAGE] THEN
2114   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2115   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2116   ASM_MESON_TAC[]);;
2117
2118 let REAL_CONTINUOUS_CONTINUOUS_AT_COMPOSE = prove
2119  (`!f g x. f continuous (at x) /\
2120            g real_continuous (at (f x) within IMAGE f (:real^N))
2121            ==> (g o f) real_continuous (at x)`,
2122   REPEAT GEN_TAC THEN
2123   ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
2124   REWRITE_TAC[WITHIN_WITHIN; INTER_UNIV] THEN
2125   REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS_WITHIN_COMPOSE]);;
2126
2127 (* ------------------------------------------------------------------------- *)
2128 (* Composition of (real^N->real) o (real->real^N) functions.                 *)
2129 (* ------------------------------------------------------------------------- *)
2130
2131 let REAL_CONTINUOUS_CONTINUOUS_WITHINREAL_COMPOSE = prove
2132  (`!f g x s. f continuous (atreal x within s) /\
2133              g real_continuous (at (f x) within IMAGE f s)
2134              ==> (g o f) real_continuous (atreal x within s)`,
2135   REPEAT GEN_TAC THEN
2136   REWRITE_TAC[real_continuous_within; continuous_withinreal;
2137               real_continuous_withinreal; o_THM; IN_IMAGE] THEN
2138   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2139   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2140   ASM_MESON_TAC[]);;
2141
2142 let REAL_CONTINUOUS_CONTINUOUS_ATREAL_COMPOSE = prove
2143  (`!f g x. f continuous (atreal x) /\
2144            g real_continuous (at (f x) within IMAGE f (:real))
2145            ==> (g o f) real_continuous (atreal x)`,
2146   REPEAT GEN_TAC THEN
2147   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
2148   REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS_WITHINREAL_COMPOSE]);;
2149
2150 (* ------------------------------------------------------------------------- *)
2151 (* Composition of (real->real^N) o (real->real) functions.                   *)
2152 (* ------------------------------------------------------------------------- *)
2153
2154 let CONTINUOUS_REAL_CONTINUOUS_WITHINREAL_COMPOSE = prove
2155  (`!f g x s. f real_continuous (atreal x within s) /\
2156              g continuous (atreal (f x) within IMAGE f s)
2157              ==> (g o f) continuous (atreal x within s)`,
2158   REPEAT GEN_TAC THEN
2159   REWRITE_TAC[real_continuous_within; continuous_withinreal;
2160               real_continuous_withinreal; o_THM; IN_IMAGE] THEN
2161   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2162   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2163   ASM_MESON_TAC[]);;
2164
2165 let CONTINUOUS_REAL_CONTINUOUS_ATREAL_COMPOSE = prove
2166  (`!f g x. f real_continuous (atreal x) /\
2167            g continuous (atreal (f x) within IMAGE f (:real))
2168            ==> (g o f) continuous (atreal x)`,
2169   REPEAT GEN_TAC THEN
2170   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
2171   REWRITE_TAC[WITHIN_WITHIN; INTER_UNIV] THEN
2172   REWRITE_TAC[CONTINUOUS_REAL_CONTINUOUS_WITHINREAL_COMPOSE]);;
2173
2174 (* ------------------------------------------------------------------------- *)
2175 (* Composition of (real^M->real^N) o (real->real^M) functions.               *)
2176 (* ------------------------------------------------------------------------- *)
2177
2178 let CONTINUOUS_WITHINREAL_COMPOSE = prove
2179  (`!f g x s. f continuous (atreal x within s) /\
2180              g continuous (at (f x) within IMAGE f s)
2181              ==> (g o f) continuous (atreal x within s)`,
2182   REPEAT GEN_TAC THEN
2183   REWRITE_TAC[continuous_within; continuous_withinreal; o_THM; IN_IMAGE] THEN
2184   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2185   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2186   ASM_MESON_TAC[]);;
2187
2188 let CONTINUOUS_ATREAL_COMPOSE = prove
2189  (`!f g x. f continuous (atreal x) /\
2190            g continuous (at (f x) within IMAGE f (:real))
2191            ==> (g o f) continuous (atreal x)`,
2192   REPEAT GEN_TAC THEN
2193   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
2194   REWRITE_TAC[WITHIN_WITHIN; INTER_UNIV] THEN
2195   REWRITE_TAC[CONTINUOUS_WITHINREAL_COMPOSE]);;
2196
2197 (* ------------------------------------------------------------------------- *)
2198 (* Composition of (real->real^N) o (real^M->real) functions.                 *)
2199 (* ------------------------------------------------------------------------- *)
2200
2201 let CONTINUOUS_REAL_CONTINUOUS_WITHIN_COMPOSE = prove
2202  (`!f g x s. f real_continuous (at x within s) /\
2203              g continuous (atreal (f x) within IMAGE f s)
2204              ==> (g o f) continuous (at x within s)`,
2205   REPEAT GEN_TAC THEN
2206   REWRITE_TAC[continuous_within; real_continuous_within; continuous_withinreal;
2207               o_THM; IN_IMAGE] THEN
2208   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2209   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2210   ASM_MESON_TAC[]);;
2211
2212 let CONTINUOUS_REAL_CONTINUOUS_AT_COMPOSE = prove
2213  (`!f g x. f real_continuous (at x) /\
2214            g continuous (atreal (f x) within IMAGE f (:real^M))
2215            ==> (g o f) continuous (at x)`,
2216   REPEAT GEN_TAC THEN
2217   ONCE_REWRITE_TAC[GSYM WITHIN_UNIV] THEN
2218   REWRITE_TAC[WITHIN_WITHIN; INTER_UNIV] THEN
2219   REWRITE_TAC[CONTINUOUS_REAL_CONTINUOUS_WITHIN_COMPOSE]);;
2220
2221 (* ------------------------------------------------------------------------- *)
2222 (* Continuity of a real->real function on a set.                             *)
2223 (* ------------------------------------------------------------------------- *)
2224
2225 parse_as_infix ("real_continuous_on",(12,"right"));;
2226
2227 let real_continuous_on = new_definition
2228   `f real_continuous_on s <=>
2229         !x. x IN s ==> !e. &0 < e
2230                            ==> ?d. &0 < d /\
2231                                    !x'. x' IN s /\ abs(x' - x) < d
2232                                         ==> abs(f(x') - f(x)) < e`;;
2233
2234 let REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN = prove
2235  (`!f s. f real_continuous_on s <=>
2236               !x. x IN s ==> f real_continuous (atreal x within s)`,
2237   REWRITE_TAC[real_continuous_on; real_continuous_withinreal]);;
2238
2239 let REAL_CONTINUOUS_ON_SUBSET = prove
2240  (`!f s t. f real_continuous_on s /\ t SUBSET s ==> f real_continuous_on t`,
2241   REWRITE_TAC[real_continuous_on; SUBSET] THEN MESON_TAC[]);;
2242
2243 let REAL_CONTINUOUS_ON_COMPOSE = prove
2244  (`!f g s. f real_continuous_on s /\ g real_continuous_on (IMAGE f s)
2245            ==> (g o f) real_continuous_on s`,
2246   REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
2247   MESON_TAC[IN_IMAGE; REAL_CONTINUOUS_WITHINREAL_COMPOSE]);;
2248
2249 let REAL_CONTINUOUS_ON = prove
2250  (`!f s. f real_continuous_on s <=>
2251           (lift o f o drop) continuous_on (IMAGE lift s)`,
2252   REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
2253               CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
2254               REAL_CONTINUOUS_WITHINREAL; CONTINUOUS_WITHIN;
2255               FORALL_IN_IMAGE; REALLIM_WITHINREAL_WITHIN; TENDSTO_REAL] THEN
2256   REWRITE_TAC[o_THM; LIFT_DROP]);;
2257
2258 let REAL_CONTINUOUS_ON_CONST = prove
2259  (`!s c. (\x. c) real_continuous_on s`,
2260   SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_CONST]);;
2261
2262 let REAL_CONTINUOUS_ON_ID = prove
2263  (`!s. (\x. x) real_continuous_on s`,
2264   REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
2265               REAL_CONTINUOUS_WITHIN_ID]);;
2266
2267 let REAL_CONTINUOUS_ON_LMUL = prove
2268  (`!f c s. f real_continuous_on s ==> (\x. c * f(x)) real_continuous_on s`,
2269   SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_LMUL]);;
2270
2271 let REAL_CONTINUOUS_ON_RMUL = prove
2272  (`!f c s. f real_continuous_on s ==> (\x. f(x) * c) real_continuous_on s`,
2273   SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_RMUL]);;
2274
2275 let REAL_CONTINUOUS_ON_NEG = prove
2276  (`!f s. f real_continuous_on s
2277          ==> (\x. --(f x)) real_continuous_on s`,
2278   SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_NEG]);;
2279
2280 let REAL_CONTINUOUS_ON_ADD = prove
2281  (`!f g s. f real_continuous_on s /\ g real_continuous_on s
2282            ==> (\x. f(x) + g(x)) real_continuous_on s`,
2283   SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_ADD]);;
2284
2285 let REAL_CONTINUOUS_ON_SUB = prove
2286  (`!f g s. f real_continuous_on s /\ g real_continuous_on s
2287            ==> (\x. f(x) - g(x)) real_continuous_on s`,
2288   SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_SUB]);;
2289
2290 let REAL_CONTINUOUS_ON_MUL = prove
2291  (`!f g s. f real_continuous_on s /\ g real_continuous_on s
2292            ==> (\x. f(x) * g(x)) real_continuous_on s`,
2293   SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_MUL]);;
2294
2295 let REAL_CONTINUOUS_ON_POW = prove
2296  (`!f n s. f real_continuous_on s
2297            ==> (\x. f(x) pow n) real_continuous_on s`,
2298   SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REAL_CONTINUOUS_POW]);;
2299
2300 let REAL_CONTINUOUS_ON_INV = prove
2301  (`!f s. f real_continuous_on s /\  (!x. x IN s ==> ~(f x = &0))
2302          ==> (\x. inv(f x)) real_continuous_on s`,
2303   SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
2304            REAL_CONTINUOUS_INV_WITHINREAL]);;
2305
2306 let REAL_CONTINUOUS_ON_DIV = prove
2307  (`!f g s.
2308         f real_continuous_on s /\
2309         g real_continuous_on s /\
2310         (!x. x IN s ==> ~(g x = &0))
2311         ==> (\x. f x / g x) real_continuous_on s`,
2312   SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
2313            REAL_CONTINUOUS_DIV_WITHINREAL]);;
2314
2315 let REAL_CONTINUOUS_ON_ABS = prove
2316  (`!f s. f real_continuous_on s ==> (\x. abs(f x)) real_continuous_on s`,
2317   REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
2318   SIMP_TAC[REAL_CONTINUOUS_ABS]);;
2319
2320 let REAL_CONTINUOUS_ON_EQ = prove
2321  (`!f g s. (!x. x IN s ==> f(x) = g(x)) /\ f real_continuous_on s
2322            ==> g real_continuous_on s`,
2323   SIMP_TAC[real_continuous_on; IMP_CONJ]);;
2324
2325 let REAL_CONTINUOUS_ON_UNION = prove
2326  (`!f s t.
2327          real_closed s /\ real_closed t /\
2328          f real_continuous_on s /\ f real_continuous_on t
2329          ==> f real_continuous_on (s UNION t)`,
2330   REWRITE_TAC[REAL_CLOSED; REAL_CONTINUOUS_ON; IMAGE_UNION;
2331               CONTINUOUS_ON_UNION]);;
2332
2333 let REAL_CONTINUOUS_ON_UNION_OPEN = prove
2334  (`!f s t.
2335          real_open s /\ real_open t /\
2336          f real_continuous_on s /\ f real_continuous_on t
2337          ==> f real_continuous_on (s UNION t)`,
2338   REWRITE_TAC[REAL_OPEN; REAL_CONTINUOUS_ON; IMAGE_UNION;
2339               CONTINUOUS_ON_UNION_OPEN]);;
2340
2341 let REAL_CONTINUOUS_ON_CASES = prove
2342  (`!P f g s t.
2343         real_closed s /\ real_closed t /\
2344         f real_continuous_on s /\ g real_continuous_on t /\
2345         (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x)
2346         ==> (\x. if P x then f x else g x) real_continuous_on (s UNION t)`,
2347   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_ON_UNION THEN
2348   ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_ON_EQ THENL
2349    [EXISTS_TAC `f:real->real`; EXISTS_TAC `g:real->real`] THEN
2350   ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;
2351
2352 let REAL_CONTINUOUS_ON_CASES_OPEN = prove
2353  (`!P f g s t.
2354         real_open s /\ real_open t /\
2355         f real_continuous_on s /\ g real_continuous_on t /\
2356         (!x. x IN s /\ ~P x \/ x IN t /\ P x ==> f x = g x)
2357         ==> (\x. if P x then f x else g x) real_continuous_on (s UNION t)`,
2358   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_ON_UNION_OPEN THEN
2359   ASM_REWRITE_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_ON_EQ THENL
2360    [EXISTS_TAC `f:real->real`; EXISTS_TAC `g:real->real`] THEN
2361   ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;
2362
2363 let REAL_CONTINUOUS_ON_SUM = prove
2364  (`!t f s.
2365          FINITE s /\ (!a. a IN s ==> f a real_continuous_on t)
2366          ==> (\x. sum s (\a. f a x)) real_continuous_on t`,
2367   REPEAT GEN_TAC THEN SIMP_TAC[REAL_CONTINUOUS_ON; o_DEF; LIFT_SUM] THEN
2368   DISCH_THEN(MP_TAC o MATCH_MP CONTINUOUS_ON_VSUM) THEN
2369   REWRITE_TAC[]);;
2370
2371 let REALLIM_CONTINUOUS_FUNCTION = prove
2372  (`!f net g l.
2373         f continuous (atreal l) /\ (g ---> l) net
2374         ==> ((\x. f(g x)) --> f l) net`,
2375   REWRITE_TAC[tendsto_real; tendsto; continuous_atreal; eventually] THEN
2376   MESON_TAC[]);;
2377
2378 let LIM_REAL_CONTINUOUS_FUNCTION = prove
2379  (`!f net g l.
2380         f real_continuous (at l) /\ (g --> l) net
2381         ==> ((\x. f(g x)) ---> f l) net`,
2382   REWRITE_TAC[tendsto_real; tendsto; real_continuous_at; eventually] THEN
2383   MESON_TAC[]);;
2384
2385 let REALLIM_REAL_CONTINUOUS_FUNCTION = prove
2386  (`!f net g l.
2387         f real_continuous (atreal l) /\ (g ---> l) net
2388         ==> ((\x. f(g x)) ---> f l) net`,
2389   REWRITE_TAC[tendsto_real; real_continuous_atreal; eventually] THEN
2390   MESON_TAC[]);;
2391
2392 let REAL_CONTINUOUS_ON_EQ_REAL_CONTINUOUS_AT = prove
2393  (`!f s. real_open s
2394          ==> (f real_continuous_on s <=>
2395               !x. x IN s ==> f real_continuous atreal x)`,
2396   SIMP_TAC[REAL_CONTINUOUS_ATREAL; REAL_CONTINUOUS_WITHINREAL;
2397         REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; REALLIM_WITHIN_REAL_OPEN]);;
2398
2399 let REAL_CONTINUOUS_ATTAINS_SUP = prove
2400  (`!f s. real_compact s /\ ~(s = {}) /\ f real_continuous_on s
2401          ==> ?x. x IN s /\ (!y. y IN s ==> f y <= f x)`,
2402   REPEAT STRIP_TAC THEN
2403   MP_TAC(ISPECL [`(f:real->real) o drop`; `IMAGE lift s`]
2404         CONTINUOUS_ATTAINS_SUP) THEN
2405   ASM_REWRITE_TAC[GSYM REAL_CONTINUOUS_ON; GSYM real_compact] THEN
2406   ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; EXISTS_IN_IMAGE; FORALL_IN_IMAGE] THEN
2407   REWRITE_TAC[o_THM; LIFT_DROP]);;
2408
2409 let REAL_CONTINUOUS_ATTAINS_INF = prove
2410  (`!f s. real_compact s /\ ~(s = {}) /\ f real_continuous_on s
2411          ==> ?x. x IN s /\ (!y. y IN s ==> f x <= f y)`,
2412   REPEAT STRIP_TAC THEN
2413   MP_TAC(ISPECL [`(f:real->real) o drop`; `IMAGE lift s`]
2414         CONTINUOUS_ATTAINS_INF) THEN
2415   ASM_REWRITE_TAC[GSYM REAL_CONTINUOUS_ON; GSYM real_compact] THEN
2416   ASM_REWRITE_TAC[IMAGE_EQ_EMPTY; EXISTS_IN_IMAGE; FORALL_IN_IMAGE] THEN
2417   REWRITE_TAC[o_THM; LIFT_DROP]);;
2418
2419 (* ------------------------------------------------------------------------- *)
2420 (* Real version of uniform continuity.                                       *)
2421 (* ------------------------------------------------------------------------- *)
2422
2423 parse_as_infix ("real_uniformly_continuous_on",(12,"right"));;
2424
2425 let real_uniformly_continuous_on = new_definition
2426   `f real_uniformly_continuous_on s <=>
2427         !e. &0 < e
2428             ==> ?d. &0 < d /\
2429                     !x x'. x IN s /\ x' IN s /\ abs(x' - x) < d
2430                            ==> abs(f x' - f x) < e`;;
2431
2432 let REAL_UNIFORMLY_CONTINUOUS_ON = prove
2433  (`!f s. f real_uniformly_continuous_on s <=>
2434           (lift o f o drop) uniformly_continuous_on (IMAGE lift s)`,
2435   REWRITE_TAC[real_uniformly_continuous_on; uniformly_continuous_on] THEN
2436   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
2437   REWRITE_TAC[o_THM; DIST_LIFT; LIFT_DROP]);;
2438
2439 let REAL_UNIFORMLY_CONTINUOUS_IMP_REAL_CONTINUOUS = prove
2440  (`!f s. f real_uniformly_continuous_on s ==> f real_continuous_on s`,
2441   REWRITE_TAC[real_uniformly_continuous_on; real_continuous_on] THEN
2442   MESON_TAC[]);;
2443
2444 let REAL_UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY = prove
2445  (`!f s. f real_uniformly_continuous_on s <=>
2446                 !x y. (!n. x(n) IN s) /\ (!n. y(n) IN s) /\
2447                       ((\n. x(n) - y(n)) ---> &0) sequentially
2448                       ==> ((\n. f(x(n)) - f(y(n))) ---> &0) sequentially`,
2449   REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON] THEN
2450   REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY; REAL_TENDSTO] THEN
2451   REWRITE_TAC[o_DEF; LIFT_DROP; IN_IMAGE_LIFT_DROP; DROP_SUB; DROP_VEC] THEN
2452   REWRITE_TAC[FORALL_LIFT_FUN; o_THM; LIFT_DROP]);;
2453
2454 let REAL_UNIFORMLY_CONTINUOUS_ON_SUBSET = prove
2455  (`!f s t. f real_uniformly_continuous_on s /\ t SUBSET s
2456            ==> f real_uniformly_continuous_on t`,
2457   REWRITE_TAC[real_uniformly_continuous_on; SUBSET] THEN MESON_TAC[]);;
2458
2459 let REAL_UNIFORMLY_CONTINUOUS_ON_COMPOSE = prove
2460  (`!f g s. f real_uniformly_continuous_on s /\
2461            g real_uniformly_continuous_on (IMAGE f s)
2462            ==> (g o f) real_uniformly_continuous_on s`,
2463   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON] THEN
2464   SUBGOAL_THEN
2465    `IMAGE lift (IMAGE f s) = IMAGE (lift o f o drop) (IMAGE lift s)`
2466   SUBST1_TAC THENL
2467    [ALL_TAC;
2468     DISCH_THEN(MP_TAC o MATCH_MP UNIFORMLY_CONTINUOUS_ON_COMPOSE)] THEN
2469   REWRITE_TAC[GSYM IMAGE_o; o_DEF; LIFT_DROP]);;
2470
2471 let REAL_UNIFORMLY_CONTINUOUS_ON_CONST = prove
2472  (`!s c. (\x. c) real_uniformly_continuous_on s`,
2473   REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON_SEQUENTIALLY; o_DEF;
2474               REAL_SUB_REFL; REALLIM_CONST]);;
2475
2476 let REAL_UNIFORMLY_CONTINUOUS_ON_LMUL = prove
2477  (`!f c s. f real_uniformly_continuous_on s
2478            ==> (\x. c * f(x)) real_uniformly_continuous_on s`,
2479   REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON] THEN
2480   REWRITE_TAC[o_DEF; LIFT_CMUL; UNIFORMLY_CONTINUOUS_ON_CMUL]);;
2481
2482 let REAL_UNIFORMLY_CONTINUOUS_ON_RMUL = prove
2483  (`!f c s. f real_uniformly_continuous_on s
2484            ==> (\x. f(x) * c) real_uniformly_continuous_on s`,
2485   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
2486   REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON_LMUL]);;
2487
2488 let REAL_UNIFORMLY_CONTINUOUS_ON_ID = prove
2489  (`!s. (\x. x) real_uniformly_continuous_on s`,
2490   REWRITE_TAC[real_uniformly_continuous_on] THEN MESON_TAC[]);;
2491
2492 let REAL_UNIFORMLY_CONTINUOUS_ON_NEG = prove
2493  (`!f s. f real_uniformly_continuous_on s
2494          ==> (\x. --(f x)) real_uniformly_continuous_on s`,
2495   ONCE_REWRITE_TAC[REAL_ARITH `--x = -- &1 * x`] THEN
2496   REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON_LMUL]);;
2497
2498 let REAL_UNIFORMLY_CONTINUOUS_ON_ADD = prove
2499  (`!f g s. f real_uniformly_continuous_on s /\
2500            g real_uniformly_continuous_on s
2501            ==> (\x. f(x) + g(x)) real_uniformly_continuous_on s`,
2502   REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON; o_DEF; LIFT_ADD] THEN
2503   REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_ADD]);;
2504
2505 let REAL_UNIFORMLY_CONTINUOUS_ON_SUB = prove
2506  (`!f g s. f real_uniformly_continuous_on s /\
2507            g real_uniformly_continuous_on s
2508            ==> (\x. f(x) - g(x)) real_uniformly_continuous_on s`,
2509   REWRITE_TAC[REAL_UNIFORMLY_CONTINUOUS_ON; o_DEF; LIFT_SUB] THEN
2510   REWRITE_TAC[UNIFORMLY_CONTINUOUS_ON_SUB]);;
2511
2512 let REAL_UNIFORMLY_CONTINUOUS_ON_SUM = prove
2513  (`!t f s.
2514          FINITE s /\ (!a. a IN s ==> f a real_uniformly_continuous_on t)
2515          ==> (\x. sum s (\a. f a x)) real_uniformly_continuous_on t`,
2516   REPEAT GEN_TAC THEN
2517   SIMP_TAC[REAL_UNIFORMLY_CONTINUOUS_ON; o_DEF; LIFT_SUM] THEN
2518   DISCH_THEN(MP_TAC o MATCH_MP UNIFORMLY_CONTINUOUS_ON_VSUM) THEN
2519   REWRITE_TAC[]);;
2520
2521 let REAL_COMPACT_UNIFORMLY_CONTINUOUS = prove
2522  (`!f s. f real_continuous_on s /\ real_compact s
2523          ==> f real_uniformly_continuous_on s`,
2524   REWRITE_TAC[real_compact; REAL_CONTINUOUS_ON; REAL_UNIFORMLY_CONTINUOUS_ON;
2525               COMPACT_UNIFORMLY_CONTINUOUS]);;
2526
2527 let REAL_COMPACT_CONTINUOUS_IMAGE = prove
2528  (`!f s. f real_continuous_on s /\ real_compact s
2529          ==> real_compact (IMAGE f s)`,
2530   REPEAT GEN_TAC THEN REWRITE_TAC[real_compact; REAL_CONTINUOUS_ON] THEN
2531   DISCH_THEN(MP_TAC o MATCH_MP COMPACT_CONTINUOUS_IMAGE) THEN
2532   REWRITE_TAC[GSYM IMAGE_o; o_DEF; LIFT_DROP]);;
2533
2534 let REAL_DINI = prove
2535  (`!f g s.
2536         real_compact s /\ (!n. (f n) real_continuous_on s) /\
2537         g real_continuous_on s /\
2538         (!x. x IN s ==> ((\n. (f n x)) ---> g x) sequentially) /\
2539         (!n x. x IN s ==> f n x <= f (n + 1) x)
2540         ==> !e. &0 < e
2541                 ==> eventually (\n. !x. x IN s ==> abs(f n x - g x) < e)
2542                                sequentially`,
2543   REPEAT STRIP_TAC THEN
2544   MP_TAC(ISPECL [`\n:num. lift o f n o drop`; `lift o g o drop`;
2545                  `IMAGE lift s`] DINI) THEN
2546   ASM_REWRITE_TAC[GSYM real_compact; GSYM REAL_CONTINUOUS_ON] THEN
2547   ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_DEF; LIFT_DROP; REAL_TENDSTO] THEN
2548   ASM_SIMP_TAC[GSYM LIFT_SUB; NORM_LIFT]);;
2549
2550 (* ------------------------------------------------------------------------- *)
2551 (* Continuity versus componentwise continuity.                               *)
2552 (* ------------------------------------------------------------------------- *)
2553
2554 let CONTINUOUS_COMPONENTWISE = prove
2555  (`!net f:A->real^N.
2556         f continuous net <=>
2557         !i. 1 <= i /\ i <= dimindex(:N)
2558             ==> (\x. (f x)$i) real_continuous net`,
2559   REWRITE_TAC[real_continuous; continuous; LIM_COMPONENTWISE]);;
2560
2561 let REAL_CONTINUOUS_COMPLEX_COMPONENTS_AT = prove
2562  (`!z. Re real_continuous (at z) /\ Im real_continuous (at z)`,
2563   GEN_TAC THEN MP_TAC(ISPECL
2564    [`at(z:complex)`; `\z:complex. z`] CONTINUOUS_COMPONENTWISE) THEN
2565   REWRITE_TAC[CONTINUOUS_AT_ID; DIMINDEX_2; FORALL_2] THEN
2566   REWRITE_TAC[GSYM RE_DEF; GSYM IM_DEF; ETA_AX]);;
2567
2568 let REAL_CONTINUOUS_COMPLEX_COMPONENTS_WITHIN = prove
2569  (`!s z. Re real_continuous (at z within s) /\
2570          Im real_continuous (at z within s)`,
2571   MESON_TAC[REAL_CONTINUOUS_COMPLEX_COMPONENTS_AT;
2572               REAL_CONTINUOUS_AT_WITHIN]);;
2573
2574 let REAL_CONTINUOUS_NORM_AT = prove
2575  (`!z. norm real_continuous (at z)`,
2576   REWRITE_TAC[real_continuous_at; dist] THEN
2577   GEN_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2578   EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);;
2579
2580 let REAL_CONTINUOUS_NORM_WITHIN = prove
2581  (`!s z. norm real_continuous (at z within s)`,
2582   MESON_TAC[REAL_CONTINUOUS_NORM_AT; REAL_CONTINUOUS_AT_WITHIN]);;
2583
2584 let REAL_CONTINUOUS_DIST_AT = prove
2585  (`!a z. (\x. dist(a,x)) real_continuous (at z)`,
2586   REWRITE_TAC[real_continuous_at; dist] THEN
2587   GEN_TAC THEN GEN_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2588   EXISTS_TAC `e:real` THEN ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);;
2589
2590 let REAL_CONTINUOUS_DIST_WITHIN = prove
2591  (`!a s z. (\x. dist(a,x)) real_continuous (at z within s)`,
2592   MESON_TAC[REAL_CONTINUOUS_DIST_AT; REAL_CONTINUOUS_AT_WITHIN]);;
2593
2594 (* ------------------------------------------------------------------------- *)
2595 (* Derivative of real->real function.                                        *)
2596 (* ------------------------------------------------------------------------- *)
2597
2598 parse_as_infix ("has_real_derivative",(12,"right"));;
2599 parse_as_infix ("real_differentiable",(12,"right"));;
2600 parse_as_infix ("real_differentiable_on",(12,"right"));;
2601
2602 let has_real_derivative = new_definition
2603  `(f has_real_derivative f') net <=>
2604         ((\x. inv(x - netlimit net) *
2605               (f x - (f(netlimit net) + f' * (x - netlimit net))))
2606          ---> &0) net`;;
2607
2608 let real_differentiable = new_definition
2609  `f real_differentiable net <=> ?f'. (f has_real_derivative f') net`;;
2610
2611 let real_derivative = new_definition
2612  `real_derivative f x = @f'. (f has_real_derivative f') (atreal x)`;;
2613
2614 let higher_real_derivative = define
2615  `higher_real_derivative 0 f = f /\
2616   (!n. higher_real_derivative (SUC n) f =
2617                 real_derivative (higher_real_derivative n f))`;;
2618
2619 let real_differentiable_on = new_definition
2620  `f real_differentiable_on s <=>
2621      !x. x IN s ==> ?f'. (f has_real_derivative f') (atreal x within s)`;;
2622
2623 (* ------------------------------------------------------------------------- *)
2624 (* Basic limit definitions in the useful cases.                              *)
2625 (* ------------------------------------------------------------------------- *)
2626
2627 let HAS_REAL_DERIVATIVE_WITHINREAL = prove
2628  (`(f has_real_derivative f') (atreal a within s) <=>
2629            ((\x. (f x - f a) / (x - a)) ---> f') (atreal a within s)`,
2630   REWRITE_TAC[has_real_derivative] THEN
2631   ASM_CASES_TAC `trivial_limit(atreal a within s)` THENL
2632    [ASM_REWRITE_TAC[REALLIM]; ALL_TAC] THEN
2633   ASM_SIMP_TAC[NETLIMIT_WITHINREAL] THEN
2634   GEN_REWRITE_TAC RAND_CONV [REALLIM_NULL] THEN
2635   REWRITE_TAC[REALLIM_WITHINREAL; REAL_SUB_RZERO] THEN
2636   SIMP_TAC[REAL_FIELD
2637    `&0 < abs(x - a) ==> (fy - fa) / (x - a) - f' =
2638                         inv(x - a) * (fy - (fa + f' * (x - a)))`]);;
2639
2640 let HAS_REAL_DERIVATIVE_ATREAL = prove
2641  (`(f has_real_derivative f') (atreal a) <=>
2642            ((\x. (f x - f a) / (x - a)) ---> f') (atreal a)`,
2643   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
2644   REWRITE_TAC[HAS_REAL_DERIVATIVE_WITHINREAL]);;
2645
2646 (* ------------------------------------------------------------------------- *)
2647 (* Relation to Frechet derivative.                                           *)
2648 (* ------------------------------------------------------------------------- *)
2649
2650 let HAS_REAL_FRECHET_DERIVATIVE_WITHIN = prove
2651  (`(f has_real_derivative f') (atreal x within s) <=>
2652         ((lift o f o drop) has_derivative (\x. f' % x))
2653         (at (lift x) within (IMAGE lift s))`,
2654   REWRITE_TAC[has_derivative_within; HAS_REAL_DERIVATIVE_WITHINREAL] THEN
2655   REWRITE_TAC[o_THM; LIFT_DROP; LIM_WITHIN; REALLIM_WITHINREAL] THEN
2656   SIMP_TAC[LINEAR_COMPOSE_CMUL; LINEAR_ID; IMP_CONJ] THEN
2657   REWRITE_TAC[FORALL_IN_IMAGE; DIST_LIFT; GSYM LIFT_SUB; LIFT_DROP;
2658     NORM_ARITH `dist(x,vec 0) = norm x`; GSYM LIFT_CMUL; GSYM LIFT_ADD;
2659     NORM_LIFT] THEN
2660   SIMP_TAC[REAL_FIELD
2661    `&0 < abs(y - x)
2662     ==> fy - (fx + f' * (y - x)) = (y - x) * ((fy - fx) / (y - x) - f')`] THEN
2663   REWRITE_TAC[REAL_ABS_MUL; REAL_MUL_ASSOC; REAL_ABS_INV; REAL_ABS_ABS] THEN
2664   SIMP_TAC[REAL_LT_IMP_NZ; REAL_MUL_LINV; REAL_MUL_LID]);;
2665
2666 let HAS_REAL_FRECHET_DERIVATIVE_AT = prove
2667  (`(f has_real_derivative f') (atreal x) <=>
2668         ((lift o f o drop) has_derivative (\x. f' % x)) (at (lift x))`,
2669   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV; GSYM WITHIN_UNIV] THEN
2670   REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN
2671   REWRITE_TAC[IMAGE_LIFT_UNIV]);;
2672
2673 let HAS_REAL_VECTOR_DERIVATIVE_WITHIN = prove
2674  (`(f has_real_derivative f') (atreal x within s) <=>
2675         ((lift o f o drop) has_vector_derivative (lift f'))
2676         (at (lift x) within (IMAGE lift s))`,
2677   REWRITE_TAC[has_vector_derivative; HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN
2678   AP_THM_TAC THEN AP_TERM_TAC THEN
2679   REWRITE_TAC[FUN_EQ_THM; FORALL_LIFT; GSYM LIFT_CMUL] THEN
2680   REWRITE_TAC[LIFT_DROP; LIFT_EQ; REAL_MUL_SYM]);;
2681
2682 let HAS_REAL_VECTOR_DERIVATIVE_AT = prove
2683  (`(f has_real_derivative f') (atreal x) <=>
2684         ((lift o f o drop) has_vector_derivative (lift f')) (at (lift x))`,
2685   REWRITE_TAC[has_vector_derivative; HAS_REAL_FRECHET_DERIVATIVE_AT] THEN
2686   AP_THM_TAC THEN AP_TERM_TAC THEN
2687   REWRITE_TAC[FUN_EQ_THM; FORALL_LIFT; GSYM LIFT_CMUL] THEN
2688   REWRITE_TAC[LIFT_DROP; LIFT_EQ; REAL_MUL_SYM]);;
2689
2690 let REAL_DIFFERENTIABLE_AT = prove
2691  (`!f a. f real_differentiable (atreal x) <=>
2692          (lift o f o drop) differentiable (at(lift x))`,
2693   REWRITE_TAC[real_differentiable; HAS_REAL_FRECHET_DERIVATIVE_AT] THEN
2694   REWRITE_TAC[differentiable; has_derivative; LINEAR_SCALING] THEN
2695   REWRITE_TAC[LINEAR_1; LEFT_AND_EXISTS_THM] THEN
2696   ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2]);;
2697
2698 let REAL_DIFFERENTIABLE_WITHIN = prove
2699  (`!f a s.
2700         f real_differentiable (atreal x within s) <=>
2701         (lift o f o drop) differentiable (at(lift x) within IMAGE lift s)`,
2702   REWRITE_TAC[real_differentiable; HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN
2703   REWRITE_TAC[differentiable; has_derivative; LINEAR_SCALING] THEN
2704   REWRITE_TAC[LINEAR_1; LEFT_AND_EXISTS_THM] THEN
2705   ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2]);;
2706
2707 (* ------------------------------------------------------------------------- *)
2708 (* Relation to complex derivative.                                           *)
2709 (* ------------------------------------------------------------------------- *)
2710
2711 let HAS_REAL_COMPLEX_DERIVATIVE_WITHIN = prove
2712  (`(f has_real_derivative f') (atreal a within s) <=>
2713         ((Cx o f o Re) has_complex_derivative (Cx f'))
2714                 (at (Cx a) within {z | real z /\ Re z IN s})`,
2715   REWRITE_TAC[HAS_REAL_DERIVATIVE_WITHINREAL; HAS_COMPLEX_DERIVATIVE_WITHIN;
2716               LIM_WITHIN; IN_ELIM_THM; IMP_CONJ; FORALL_REAL] THEN
2717   REWRITE_TAC[RE_CX; dist; GSYM CX_SUB; COMPLEX_NORM_CX; o_THM; GSYM CX_DIV;
2718               REALLIM_WITHINREAL] THEN
2719   MESON_TAC[]);;
2720
2721 let HAS_REAL_COMPLEX_DERIVATIVE_AT = prove
2722  (`(f has_real_derivative f') (atreal a) <=>
2723        ((Cx o f o Re) has_complex_derivative (Cx f')) (at (Cx a) within real)`,
2724   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
2725   REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN
2726   AP_TERM_TAC THEN AP_TERM_TAC THEN SET_TAC[]);;
2727
2728 let REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE = prove
2729  (`!f s. f real_differentiable_on s <=>
2730          !x. x IN s ==> f real_differentiable (atreal x within s)`,
2731   REWRITE_TAC[real_differentiable_on; real_differentiable]);;
2732
2733 let REAL_DIFFERENTIABLE_ON_REAL_OPEN = prove
2734  (`!f s. real_open s
2735          ==> (f real_differentiable_on s <=>
2736               !x. x IN s ==> ?f'. (f has_real_derivative f') (atreal x))`,
2737   REWRITE_TAC[real_differentiable_on; HAS_REAL_DERIVATIVE_WITHINREAL;
2738               HAS_REAL_DERIVATIVE_ATREAL] THEN
2739   SIMP_TAC[REALLIM_WITHIN_REAL_OPEN]);;
2740
2741 let REAL_DIFFERENTIABLE_ON_IMP_DIFFERENTIABLE_WITHIN = prove
2742  (`!f s x. f real_differentiable_on s /\ x IN s
2743            ==> f real_differentiable (atreal x within s)`,
2744   MESON_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE]);;
2745
2746 let REAL_DIFFERENTIABLE_ON_IMP_DIFFERENTIABLE_ATREAL = prove
2747  (`!f s x. f real_differentiable_on s /\ real_open s /\ x IN s
2748            ==> f real_differentiable (atreal x)`,
2749   MESON_TAC[REAL_DIFFERENTIABLE_ON_REAL_OPEN; real_differentiable]);;
2750
2751 let HAS_COMPLEX_REAL_DERIVATIVE_WITHIN_GEN = prove
2752  (`!f g h s d.
2753         &0 < d /\ x IN s /\
2754         (h has_complex_derivative Cx(g))
2755         (at (Cx x) within {z | real z /\ Re(z) IN s}) /\
2756         (!y. y IN s /\ abs(y - x) < d ==>  h(Cx y) = Cx(f y))
2757         ==> (f has_real_derivative g) (atreal x within s)`,
2758   REPEAT STRIP_TAC THEN REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN
2759   MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN THEN
2760   MAP_EVERY EXISTS_TAC [`h:complex->complex`; `d:real`] THEN
2761   ASM_REWRITE_TAC[IN_ELIM_THM; o_THM; REAL_CX; RE_CX; dist] THEN
2762   X_GEN_TAC `w:complex` THEN STRIP_TAC THEN
2763   FIRST_X_ASSUM(MP_TAC o SPEC `Re w`) THEN
2764   FIRST_X_ASSUM(SUBST_ALL_TAC o SYM o GEN_REWRITE_RULE I [REAL]) THEN
2765   RULE_ASSUM_TAC(REWRITE_RULE[GSYM CX_SUB; COMPLEX_NORM_CX]) THEN
2766   ASM_REWRITE_TAC[RE_CX]);;
2767
2768 let HAS_COMPLEX_REAL_DERIVATIVE_AT_GEN = prove
2769  (`!f g h d.
2770         &0 < d /\
2771         (h has_complex_derivative Cx(g)) (at (Cx x) within real) /\
2772         (!y. abs(y - x) < d ==>  h(Cx y) = Cx(f y))
2773         ==> (f has_real_derivative g) (atreal x)`,
2774   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
2775   MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_WITHIN_GEN THEN
2776   MAP_EVERY EXISTS_TAC [`h:complex->complex`; `d:real`] THEN
2777   ASM_REWRITE_TAC[IN_UNIV; ETA_AX; SET_RULE `{x | r x} = r`]);;
2778
2779 let HAS_COMPLEX_REAL_DERIVATIVE_WITHIN = prove
2780  (`!f g h s.
2781         x IN s /\
2782         (h has_complex_derivative Cx(g))
2783         (at (Cx x) within {z | real z /\ Re(z) IN s}) /\
2784         (!y. y IN s ==>  h(Cx y) = Cx(f y))
2785         ==> (f has_real_derivative g) (atreal x within s)`,
2786   REPEAT STRIP_TAC THEN
2787   MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_WITHIN_GEN THEN
2788   MAP_EVERY EXISTS_TAC [`h:complex->complex`; `&1`] THEN
2789   ASM_SIMP_TAC[REAL_LT_01]);;
2790
2791 let HAS_COMPLEX_REAL_DERIVATIVE_AT = prove
2792  (`!f g h.
2793         (h has_complex_derivative Cx(g)) (at (Cx x) within real) /\
2794         (!y. h(Cx y) = Cx(f y))
2795         ==> (f has_real_derivative g) (atreal x)`,
2796   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
2797   MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_WITHIN THEN
2798   EXISTS_TAC `h:complex->complex` THEN
2799   ASM_REWRITE_TAC[IN_UNIV; ETA_AX; SET_RULE `{x | r x} = r`]);;
2800
2801 (* ------------------------------------------------------------------------- *)
2802 (* Caratheodory characterization.                                            *)
2803 (* ------------------------------------------------------------------------- *)
2804
2805 let HAS_REAL_DERIVATIVE_CARATHEODORY_ATREAL = prove
2806  (`!f f' z.
2807         (f has_real_derivative f') (atreal z) <=>
2808         ?g. (!w. f(w) - f(z) = g(w) * (w - z)) /\
2809             g real_continuous atreal z /\ g(z) = f'`,
2810   REPEAT GEN_TAC THEN
2811   REWRITE_TAC[REAL_RING `w' - z':real = a <=> w' = z' + a`] THEN
2812   SIMP_TAC[GSYM FUN_EQ_THM; HAS_REAL_DERIVATIVE_ATREAL;
2813            REAL_CONTINUOUS_ATREAL] THEN
2814   EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THENL
2815    [EXISTS_TAC `\w. if w = z then f':real else (f(w) - f(z)) / (w - z)` THEN
2816     ASM_SIMP_TAC[FUN_EQ_THM; COND_RAND; COND_RATOR; REAL_SUB_REFL] THEN
2817     CONV_TAC REAL_FIELD;
2818     FIRST_X_ASSUM SUBST_ALL_TAC THEN FIRST_X_ASSUM SUBST1_TAC THEN
2819     ASM_SIMP_TAC[REAL_RING `(z + a) - (z + b * (w - w)):real = a`] THEN
2820     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
2821       REALLIM_TRANSFORM)) THEN
2822     SIMP_TAC[REALLIM_CONST; REAL_FIELD
2823      `~(w = z) ==> x - (x * (w - z)) / (w - z) = &0`]]);;
2824
2825 let HAS_REAL_DERIVATIVE_CARATHEODORY_WITHINREAL = prove
2826  (`!f f' z s.
2827         (f has_real_derivative f') (atreal z within s) <=>
2828         ?g. (!w. f(w) - f(z) = g(w) * (w - z)) /\
2829             g real_continuous (atreal z within s) /\ g(z) = f'`,
2830   REPEAT GEN_TAC THEN
2831   REWRITE_TAC[REAL_RING `w' - z':real = a <=> w' = z' + a`] THEN
2832   SIMP_TAC[GSYM FUN_EQ_THM; HAS_REAL_DERIVATIVE_WITHINREAL;
2833            REAL_CONTINUOUS_WITHINREAL] THEN
2834   EQ_TAC THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THENL
2835    [EXISTS_TAC `\w. if w = z then f':real else (f(w) - f(z)) / (w - z)` THEN
2836     ASM_SIMP_TAC[FUN_EQ_THM; COND_RAND; COND_RATOR; REAL_SUB_REFL] THEN
2837     CONV_TAC REAL_FIELD;
2838     FIRST_X_ASSUM SUBST_ALL_TAC THEN FIRST_X_ASSUM SUBST1_TAC THEN
2839     ASM_SIMP_TAC[REAL_RING `(z + a) - (z + b * (w - w)):real = a`] THEN
2840     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
2841       REALLIM_TRANSFORM)) THEN
2842     SIMP_TAC[REALLIM_CONST; REAL_FIELD
2843      `~(w = z) ==> x - (x * (w - z)) / (w - z) = &0`]]);;
2844
2845 let REAL_DIFFERENTIABLE_CARATHEODORY_ATREAL = prove
2846  (`!f z. f real_differentiable atreal z <=>
2847          ?g. (!w. f(w) - f(z) = g(w) * (w - z)) /\ g real_continuous atreal z`,
2848   SIMP_TAC[real_differentiable; HAS_REAL_DERIVATIVE_CARATHEODORY_ATREAL] THEN
2849   MESON_TAC[]);;
2850
2851 let REAL_DIFFERENTIABLE_CARATHEODORY_WITHINREAL = prove
2852  (`!f z s.
2853       f real_differentiable (atreal z within s) <=>
2854       ?g. (!w. f(w) - f(z) = g(w) * (w - z)) /\
2855           g real_continuous (atreal z within s)`,
2856   SIMP_TAC[real_differentiable;
2857            HAS_REAL_DERIVATIVE_CARATHEODORY_WITHINREAL] THEN
2858   MESON_TAC[]);;
2859
2860 (* ------------------------------------------------------------------------- *)
2861 (* Property of being an interval (equivalent to convex or connected).        *)
2862 (* ------------------------------------------------------------------------- *)
2863
2864 let is_realinterval = new_definition
2865  `is_realinterval s <=>
2866         !a b c. a IN s /\ b IN s /\ a <= c /\ c <= b ==> c IN s`;;
2867
2868 let IS_REALINTERVAL_IS_INTERVAL = prove
2869  (`!s. is_realinterval s <=> is_interval(IMAGE lift s)`,
2870   REWRITE_TAC[IS_INTERVAL_1; is_realinterval] THEN
2871   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
2872   REWRITE_TAC[LIFT_DROP; IN_IMAGE; EXISTS_DROP; UNWIND_THM1] THEN
2873   REWRITE_TAC[GSYM FORALL_DROP]);;
2874
2875 let IS_REALINTERVAL_CONVEX = prove
2876  (`!s. is_realinterval s <=> convex(IMAGE lift s)`,
2877   REWRITE_TAC[IS_REALINTERVAL_IS_INTERVAL; IS_INTERVAL_CONVEX_1]);;
2878
2879 let IS_REALINTERVAL_CONNECTED = prove
2880  (`!s. is_realinterval s <=> connected(IMAGE lift s)`,
2881   REWRITE_TAC[IS_REALINTERVAL_IS_INTERVAL; IS_INTERVAL_CONNECTED_1]);;
2882
2883 let TRIVIAL_LIMIT_WITHIN_REALINTERVAL = prove
2884  (`!s x. is_realinterval s /\ x IN s
2885          ==> (trivial_limit(atreal x within s) <=> s = {x})`,
2886   REWRITE_TAC[TRIVIAL_LIMIT_WITHINREAL_WITHIN; IS_REALINTERVAL_CONVEX] THEN
2887   REWRITE_TAC[FORALL_DROP; GSYM IN_IMAGE_LIFT_DROP; LIFT_DROP] THEN
2888   SIMP_TAC[TRIVIAL_LIMIT_WITHIN_CONVEX] THEN REPEAT STRIP_TAC THEN
2889   REWRITE_TAC[EXTENSION; IN_IMAGE_LIFT_DROP; IN_SING] THEN
2890   MESON_TAC[LIFT_DROP]);;
2891
2892 let IS_REALINTERVAL_EMPTY = prove
2893  (`is_realinterval {}`,
2894   REWRITE_TAC[is_realinterval; NOT_IN_EMPTY]);;
2895
2896 let IS_REALINTERVAL_UNION = prove
2897  (`!s t. is_realinterval s /\ is_realinterval t /\ ~(s INTER t = {})
2898          ==> is_realinterval(s UNION t)`,
2899   REWRITE_TAC[is_realinterval; IN_UNION; IN_INTER;
2900               NOT_IN_EMPTY; EXTENSION] THEN
2901   MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL]);;
2902
2903 let IS_REALINTERVAL_UNIV = prove
2904  (`is_realinterval (:real)`,
2905   REWRITE_TAC[is_realinterval; IN_UNIV]);;
2906
2907 let IS_REAL_INTERVAL_CASES = prove
2908  (`!s. is_realinterval s <=>
2909         s = {} \/
2910         s = (:real) \/
2911         (?a. s = {x | a < x}) \/
2912         (?a. s = {x | a <= x}) \/
2913         (?b. s = {x | x <= b}) \/
2914         (?b. s = {x | x < b}) \/
2915         (?a b. s = {x | a < x /\ x < b}) \/
2916         (?a b. s = {x | a < x /\ x <= b}) \/
2917         (?a b. s = {x | a <= x /\ x < b}) \/
2918         (?a b. s = {x | a <= x /\ x <= b})`,
2919   REWRITE_TAC[IS_REALINTERVAL_IS_INTERVAL; IS_INTERVAL_1_CASES] THEN
2920   REWRITE_TAC[EXTENSION; IN_IMAGE_LIFT_DROP; IN_ELIM_THM] THEN
2921   REWRITE_TAC[GSYM FORALL_DROP; IN_UNIV; NOT_IN_EMPTY]);;
2922
2923 let REAL_CONVEX = prove
2924  (`!s. is_realinterval s <=>
2925        !x y u v. x IN s /\ y IN s /\ &0 <= u /\ &0 <= v /\ u + v = &1
2926                  ==> (u * x + v * y) IN s`,
2927   REWRITE_TAC[IS_REALINTERVAL_CONVEX; convex] THEN
2928   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
2929   REWRITE_TAC[IN_IMAGE_LIFT_DROP; DROP_ADD; DROP_CMUL; LIFT_DROP]);;
2930
2931 let REAL_CONVEX_ALT = prove
2932  (`!s. is_realinterval s <=>
2933        !x y u. x IN s /\ y IN s /\ &0 <= u /\ u <= &1
2934                  ==> ((&1 - u) * x + u * y) IN s`,
2935   REWRITE_TAC[IS_REALINTERVAL_CONVEX; CONVEX_ALT] THEN
2936   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
2937   REWRITE_TAC[IN_IMAGE_LIFT_DROP; DROP_ADD; DROP_CMUL; LIFT_DROP]);;
2938
2939 let REAL_MIDPOINT_IN_CONVEX = prove
2940  (`!s x y. is_realinterval s /\ x IN s /\ y IN s ==> ((x + y) / &2) IN s`,
2941   REPEAT STRIP_TAC THEN
2942   REWRITE_TAC[REAL_ARITH `(x + y) / &2 = inv(&2) * x + inv(&2) * y`] THEN
2943   FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [REAL_CONVEX]) THEN
2944   CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_REWRITE_TAC[]);;
2945
2946 (* ------------------------------------------------------------------------- *)
2947 (* Some relations with the complex numbers can also be useful.               *)
2948 (* ------------------------------------------------------------------------- *)
2949
2950 let IS_REALINTERVAL_CONVEX_COMPLEX = prove
2951  (`!s. is_realinterval s <=> convex {z | real z /\ Re z IN s}`,
2952   GEN_TAC THEN
2953   REWRITE_TAC[GSYM IMAGE_CX; IS_REALINTERVAL_CONVEX] THEN EQ_TAC THENL
2954    [DISCH_THEN(MP_TAC o ISPEC `Cx o drop` o MATCH_MP
2955      (REWRITE_RULE[IMP_CONJ] CONVEX_LINEAR_IMAGE)) THEN
2956     REWRITE_TAC[GSYM IMAGE_o; GSYM o_ASSOC] THEN
2957     ONCE_REWRITE_TAC[IMAGE_o] THEN REWRITE_TAC[IMAGE_LIFT_DROP] THEN
2958     DISCH_THEN MATCH_MP_TAC THEN
2959     REWRITE_TAC[linear; o_THM; CX_ADD; CX_MUL; DROP_ADD; DROP_CMUL;
2960                 COMPLEX_CMUL];
2961     DISCH_THEN(MP_TAC o ISPEC `lift o Re` o MATCH_MP
2962      (REWRITE_RULE[IMP_CONJ] CONVEX_LINEAR_IMAGE)) THEN
2963     REWRITE_TAC[GSYM IMAGE_o; GSYM o_ASSOC] THEN
2964     ONCE_REWRITE_TAC[IMAGE_o] THEN
2965     REWRITE_TAC[o_DEF; RE_CX; SET_RULE `IMAGE (\x. x) s = s`] THEN
2966     DISCH_THEN MATCH_MP_TAC THEN
2967     REWRITE_TAC[linear; o_THM; RE_CMUL;
2968                 RE_ADD; RE_MUL_CX; LIFT_ADD; LIFT_CMUL]]);;
2969
2970 (* ------------------------------------------------------------------------- *)
2971 (* The same tricks to define closed and open intervals.                      *)
2972 (* ------------------------------------------------------------------------- *)
2973
2974 let open_real_interval = new_definition
2975   `open_real_interval(a:real,b:real) = {x:real | a < x /\ x < b}`;;
2976
2977 let closed_real_interval = define
2978   `closed_real_interval[a:real,b:real] = {x:real | a <= x /\ x <= b}`;;
2979
2980 make_overloadable "real_interval" `:A`;;
2981
2982 overload_interface("real_interval",`open_real_interval`);;
2983 overload_interface("real_interval",`closed_real_interval`);;
2984
2985 let real_interval = prove
2986  (`real_interval(a,b) = {x | a < x /\ x < b} /\
2987    real_interval[a,b] = {x | a <= x /\ x <= b}`,
2988   REWRITE_TAC[open_real_interval; closed_real_interval]);;
2989
2990 let IN_REAL_INTERVAL = prove
2991  (`!a b x. (x IN real_interval[a,b] <=> a <= x /\ x <= b) /\
2992            (x IN real_interval(a,b) <=> a < x /\ x < b)`,
2993   REWRITE_TAC[real_interval; IN_ELIM_THM]);;
2994
2995 let REAL_INTERVAL_INTERVAL = prove
2996  (`real_interval[a,b] = IMAGE drop (interval[lift a,lift b]) /\
2997    real_interval(a,b) = IMAGE drop (interval(lift a,lift b))`,
2998   REWRITE_TAC[EXTENSION; IN_IMAGE; IN_INTERVAL_1; IN_REAL_INTERVAL] THEN
2999   REWRITE_TAC[EXISTS_LIFT; LIFT_DROP; UNWIND_THM1]);;
3000
3001 let INTERVAL_REAL_INTERVAL = prove
3002  (`interval[a,b] = IMAGE lift (real_interval[drop a,drop b]) /\
3003    interval(a,b) = IMAGE lift (real_interval(drop a,drop b))`,
3004   REWRITE_TAC[EXTENSION; IN_IMAGE; IN_INTERVAL_1; IN_REAL_INTERVAL] THEN
3005   REWRITE_TAC[EXISTS_DROP; LIFT_DROP; UNWIND_THM1]);;
3006
3007 let EMPTY_AS_REAL_INTERVAL = prove
3008  (`{} = real_interval[&1,&0]`,
3009   REWRITE_TAC[REAL_INTERVAL_INTERVAL; LIFT_NUM; GSYM EMPTY_AS_INTERVAL] THEN
3010   REWRITE_TAC[IMAGE_CLAUSES]);;
3011
3012 let IMAGE_LIFT_REAL_INTERVAL = prove
3013  (`IMAGE lift (real_interval[a,b]) = interval[lift a,lift b] /\
3014    IMAGE lift (real_interval(a,b)) = interval(lift a,lift b)`,
3015   REWRITE_TAC[REAL_INTERVAL_INTERVAL; GSYM IMAGE_o; o_DEF; LIFT_DROP] THEN
3016   SET_TAC[]);;
3017
3018 let IMAGE_DROP_INTERVAL = prove
3019  (`IMAGE drop (interval[a,b]) = real_interval[drop a,drop b] /\
3020    IMAGE drop (interval(a,b)) = real_interval(drop a,drop b)`,
3021   REWRITE_TAC[INTERVAL_REAL_INTERVAL; GSYM IMAGE_o; o_DEF; LIFT_DROP] THEN
3022   SET_TAC[]);;
3023
3024 let SUBSET_REAL_INTERVAL = prove
3025  (`!a b c d.
3026         (real_interval[a,b] SUBSET real_interval[c,d] <=>
3027                 b < a \/ c <= a /\ a <= b /\ b <= d) /\
3028         (real_interval[a,b] SUBSET real_interval(c,d) <=>
3029                 b < a \/ c < a /\ a <= b /\ b < d) /\
3030         (real_interval(a,b) SUBSET real_interval[c,d] <=>
3031                 b <= a \/ c <= a /\ a < b /\ b <= d) /\
3032         (real_interval(a,b) SUBSET real_interval(c,d) <=>
3033                 b <= a \/ c <= a /\ a < b /\ b <= d)`,
3034   let lemma = prove
3035    (`IMAGE drop s SUBSET IMAGE drop t <=> s SUBSET t`,
3036     SET_TAC[LIFT_DROP]) in
3037   REWRITE_TAC[REAL_INTERVAL_INTERVAL; lemma; SUBSET_INTERVAL_1] THEN
3038   REWRITE_TAC[LIFT_DROP]);;
3039
3040 let REAL_INTERVAL_OPEN_SUBSET_CLOSED = prove
3041  (`!a b. real_interval(a,b) SUBSET real_interval[a,b]`,
3042   REWRITE_TAC[SUBSET; IN_REAL_INTERVAL] THEN REAL_ARITH_TAC);;
3043
3044 let REAL_INTERVAL_EQ_EMPTY = prove
3045  (`(!a b. real_interval[a,b] = {} <=> b < a) /\
3046    (!a b. real_interval(a,b) = {} <=> b <= a)`,
3047   REWRITE_TAC[REAL_INTERVAL_INTERVAL; IMAGE_EQ_EMPTY] THEN
3048   REWRITE_TAC[INTERVAL_EQ_EMPTY_1; LIFT_DROP]);;
3049
3050 let REAL_INTERVAL_NE_EMPTY = prove
3051  (`(!a b. ~(real_interval[a,b] = {}) <=> a <= b) /\
3052    (!a b. ~(real_interval(a,b) = {}) <=> a < b)`,
3053   REWRITE_TAC[REAL_INTERVAL_EQ_EMPTY; REAL_NOT_LE; REAL_NOT_LT]);;
3054
3055 let REAL_OPEN_CLOSED_INTERVAL = prove
3056  (`!a b. real_interval(a,b) = real_interval[a,b] DIFF {a,b}`,
3057   SIMP_TAC[EXTENSION; IN_DIFF; IN_REAL_INTERVAL; IN_INSERT; NOT_IN_EMPTY] THEN
3058   REAL_ARITH_TAC);;
3059
3060 let REAL_CLOSED_OPEN_INTERVAL = prove
3061  (`!a b. a <= b ==> real_interval[a,b] = real_interval(a,b) UNION {a,b}`,
3062   SIMP_TAC[EXTENSION; IN_UNION; IN_REAL_INTERVAL; IN_INSERT; NOT_IN_EMPTY] THEN
3063   REAL_ARITH_TAC);;
3064
3065 let REAL_CLOSED_REAL_INTERVAL = prove
3066  (`!a b. real_closed(real_interval[a,b])`,
3067   REWRITE_TAC[REAL_CLOSED; IMAGE_LIFT_REAL_INTERVAL; CLOSED_INTERVAL]);;
3068
3069 let REAL_OPEN_REAL_INTERVAL = prove
3070  (`!a b. real_open(real_interval(a,b))`,
3071   REWRITE_TAC[REAL_OPEN; IMAGE_LIFT_REAL_INTERVAL; OPEN_INTERVAL]);;
3072
3073 let REAL_INTERVAL_SING = prove
3074  (`!a. real_interval[a,a] = {a} /\ real_interval(a,a) = {}`,
3075   REWRITE_TAC[EXTENSION; IN_SING; NOT_IN_EMPTY; IN_REAL_INTERVAL] THEN
3076   REAL_ARITH_TAC);;
3077
3078 let REAL_COMPACT_INTERVAL = prove
3079  (`!a b. real_compact(real_interval[a,b])`,
3080   REWRITE_TAC[REAL_INTERVAL_INTERVAL; real_compact] THEN
3081   REWRITE_TAC[GSYM IMAGE_o; o_DEF; LIFT_DROP; IMAGE_ID; COMPACT_INTERVAL]);;
3082
3083 let IS_REALINTERVAL_INTERVAL = prove
3084  (`!a b. is_realinterval(real_interval(a,b)) /\
3085          is_realinterval(real_interval[a,b])`,
3086   REWRITE_TAC[is_realinterval; IN_REAL_INTERVAL] THEN REAL_ARITH_TAC);;
3087
3088 let REAL_BOUNDED_REAL_INTERVAL = prove
3089  (`(!a b. real_bounded(real_interval[a,b])) /\
3090    (!a b. real_bounded(real_interval(a,b)))`,
3091   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; REAL_BOUNDED; BOUNDED_INTERVAL]);;
3092
3093 let ENDS_IN_REAL_INTERVAL = prove
3094  (`(!a b. a IN real_interval[a,b] <=> ~(real_interval[a,b] = {})) /\
3095    (!a b. b IN real_interval[a,b] <=> ~(real_interval[a,b] = {})) /\
3096    (!a b. ~(a IN real_interval(a,b))) /\
3097    (!a b. ~(b IN real_interval(a,b)))`,
3098   REWRITE_TAC[IN_REAL_INTERVAL; REAL_INTERVAL_EQ_EMPTY] THEN REAL_ARITH_TAC);;
3099
3100 let IMAGE_AFFINITY_REAL_INTERVAL = prove
3101  (`!a b m c.
3102          IMAGE (\x. m * x + c) (real_interval[a,b]) =
3103          (if real_interval[a,b] = {}
3104           then {}
3105           else if &0 <= m
3106                then real_interval[m * a + c,m * b + c]
3107                else real_interval[m * b + c,m * a + c])`,
3108   REWRITE_TAC[REAL_INTERVAL_INTERVAL; GSYM IMAGE_o; o_DEF; IMAGE_EQ_EMPTY] THEN
3109   REWRITE_TAC[FORALL_DROP; LIFT_DROP; GSYM DROP_CMUL; GSYM DROP_ADD] THEN
3110   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN
3111   REWRITE_TAC[IMAGE_o; IMAGE_AFFINITY_INTERVAL] THEN
3112   MESON_TAC[IMAGE_CLAUSES]);;
3113
3114 let IMAGE_STRETCH_REAL_INTERVAL = prove
3115  (`!a b m.
3116          IMAGE (\x. m * x) (real_interval[a,b]) =
3117          (if real_interval[a,b] = {}
3118           then {}
3119           else if &0 <= m
3120                then real_interval[m * a,m * b]
3121                else real_interval[m * b,m * a])`,
3122   ONCE_REWRITE_TAC[REAL_ARITH `m * x = m * x + &0`] THEN
3123   REWRITE_TAC[IMAGE_AFFINITY_REAL_INTERVAL]);;
3124
3125 let REAL_INTERVAL_TRANSLATION = prove
3126  (`(!c a b. real_interval[c + a,c + b] =
3127             IMAGE (\x. c + x) (real_interval[a,b])) /\
3128    (!c a b. real_interval(c + a,c + b) =
3129             IMAGE (\x. c + x) (real_interval(a,b)))`,
3130   REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
3131   MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
3132   REWRITE_TAC[REAL_ARITH `c + x:real = y <=> x = y - c`; EXISTS_REFL] THEN
3133   REWRITE_TAC[IN_REAL_INTERVAL] THEN REAL_ARITH_TAC);;
3134
3135 let IN_REAL_INTERVAL_REFLECT = prove
3136  (`(!a b x. --x IN real_interval[--b,--a] <=> x IN real_interval[a,b]) /\
3137    (!a b x. --x IN real_interval(--b,--a) <=> x IN real_interval(a,b))`,
3138   REWRITE_TAC[IN_REAL_INTERVAL] THEN REAL_ARITH_TAC);;
3139
3140 let REFLECT_REAL_INTERVAL = prove
3141  (`(!a b. IMAGE (--) (real_interval[a,b]) = real_interval[--b,--a]) /\
3142    (!a b. IMAGE (--) (real_interval(a,b)) = real_interval(--b,--a))`,
3143   REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; IN_REAL_INTERVAL] THEN
3144   ONCE_REWRITE_TAC[REAL_ARITH `x:real = --y <=> --x = y`] THEN
3145   REWRITE_TAC[UNWIND_THM1] THEN REAL_ARITH_TAC);;
3146
3147 (* ------------------------------------------------------------------------- *)
3148 (* Real continuity and differentiability.                                    *)
3149 (* ------------------------------------------------------------------------- *)
3150
3151 let REAL_CONTINUOUS_CONTINUOUS = prove
3152  (`f real_continuous net <=> (Cx o f) continuous net`,
3153   REWRITE_TAC[real_continuous; continuous; REALLIM_COMPLEX; o_THM]);;
3154
3155 let REAL_CONTINUOUS_CONTINUOUS1 = prove
3156  (`f real_continuous net <=> (lift o f) continuous net`,
3157   REWRITE_TAC[real_continuous; continuous; TENDSTO_REAL; o_THM]);;
3158
3159 let REAL_CONTINUOUS_CONTINUOUS_ATREAL = prove
3160  (`f real_continuous (atreal x) <=> (lift o f o drop) continuous (at(lift x))`,
3161   REWRITE_TAC[REAL_CONTINUOUS_ATREAL; REALLIM_ATREAL_AT; CONTINUOUS_AT;
3162               TENDSTO_REAL; o_THM; LIFT_DROP]);;
3163
3164 let REAL_CONTINUOUS_CONTINUOUS_WITHINREAL = prove
3165  (`f real_continuous (atreal x within s) <=>
3166    (lift o f o drop) continuous (at(lift x) within IMAGE lift s)`,
3167   REWRITE_TAC[REAL_CONTINUOUS_WITHINREAL; REALLIM_WITHINREAL_WITHIN] THEN
3168   REWRITE_TAC[TENDSTO_REAL; CONTINUOUS_WITHIN; o_THM; LIFT_DROP]);;
3169
3170 let REAL_COMPLEX_CONTINUOUS_WITHINREAL = prove
3171  (`f real_continuous (atreal x within s) <=>
3172        (Cx o f o Re) continuous (at (Cx x) within (real INTER IMAGE Cx s))`,
3173   REWRITE_TAC[real_continuous; continuous; REALLIM_COMPLEX;
3174          LIM_WITHINREAL_WITHINCOMPLEX; NETLIMIT_WITHINREAL; GSYM o_ASSOC] THEN
3175   ASM_CASES_TAC `trivial_limit(at(Cx x) within (real INTER IMAGE Cx s))` THENL
3176    [ASM_REWRITE_TAC[LIM];
3177     ASM_SIMP_TAC[TRIVIAL_LIMIT_WITHINREAL_WITHINCOMPLEX;
3178         NETLIMIT_WITHIN; NETLIMIT_WITHINREAL; RE_CX; o_THM]]);;
3179
3180 let REAL_COMPLEX_CONTINUOUS_ATREAL = prove
3181  (`f real_continuous (atreal x) <=>
3182        (Cx o f o Re) continuous (at (Cx x) within real)`,
3183   REWRITE_TAC[real_continuous; continuous; REALLIM_COMPLEX;
3184               LIM_ATREAL_ATCOMPLEX; NETLIMIT_ATREAL; GSYM o_ASSOC] THEN
3185   ASM_CASES_TAC `trivial_limit(at(Cx x) within real)` THENL
3186    [ASM_REWRITE_TAC[LIM];
3187     ASM_SIMP_TAC[NETLIMIT_WITHIN; RE_CX; o_THM]]);;
3188
3189 let CONTINUOUS_CONTINUOUS_WITHINREAL = prove
3190  (`!f x s. f continuous (atreal x within s) <=>
3191            (f o drop) continuous (at (lift x) within IMAGE lift s)`,
3192   REWRITE_TAC[REALLIM_WITHINREAL_WITHIN; CONTINUOUS_WITHIN;
3193           CONTINUOUS_WITHINREAL; o_DEF; LIFT_DROP; LIM_WITHINREAL_WITHIN]);;
3194
3195 let CONTINUOUS_CONTINUOUS_ATREAL = prove
3196  (`!f x. f continuous (atreal x) <=> (f o drop) continuous (at (lift x))`,
3197   REWRITE_TAC[REALLIM_ATREAL_AT; CONTINUOUS_AT;
3198           CONTINUOUS_ATREAL; o_DEF; LIFT_DROP; LIM_ATREAL_AT]);;
3199
3200 let REAL_CONTINUOUS_REAL_CONTINUOUS_WITHINREAL = prove
3201  (`!f x s. f real_continuous (atreal x within s) <=>
3202            (f o drop) real_continuous (at (lift x) within IMAGE lift s)`,
3203   REWRITE_TAC[REALLIM_WITHINREAL_WITHIN; REAL_CONTINUOUS_WITHIN;
3204               REAL_CONTINUOUS_WITHINREAL; o_DEF; LIFT_DROP;
3205               LIM_WITHINREAL_WITHIN]);;
3206
3207 let REAL_CONTINUOUS_REAL_CONTINUOUS_ATREAL = prove
3208  (`!f x. f real_continuous (atreal x) <=>
3209          (f o drop) real_continuous (at (lift x))`,
3210   REWRITE_TAC[REALLIM_ATREAL_AT; REAL_CONTINUOUS_AT;
3211           REAL_CONTINUOUS_ATREAL; o_DEF; LIFT_DROP; LIM_ATREAL_AT]);;
3212 let HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_WITHINREAL = prove
3213  (`!f f' x s. (f has_real_derivative f') (atreal x within s)
3214               ==> f real_continuous (atreal x within s)`,
3215   REPEAT GEN_TAC THEN
3216   REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN;
3217               REAL_COMPLEX_CONTINUOUS_WITHINREAL] THEN
3218   DISCH_THEN(MP_TAC o
3219     MATCH_MP HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_WITHIN) THEN
3220   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
3221   REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; IN_IMAGE] THEN
3222   MESON_TAC[REAL; RE_CX; REAL_CX; IN]);;
3223
3224 let REAL_DIFFERENTIABLE_IMP_CONTINUOUS_WITHINREAL = prove
3225  (`!f x s. f real_differentiable (atreal x within s)
3226            ==> f real_continuous (atreal x within s)`,
3227   MESON_TAC[HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_WITHINREAL;
3228             real_differentiable]);;
3229
3230 let HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL = prove
3231  (`!f f' x. (f has_real_derivative f') (atreal x)
3232             ==> f real_continuous (atreal x)`,
3233   REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_AT;
3234               REAL_COMPLEX_CONTINUOUS_ATREAL;
3235               HAS_COMPLEX_DERIVATIVE_IMP_CONTINUOUS_WITHIN]);;
3236
3237 let REAL_DIFFERENTIABLE_IMP_CONTINUOUS_ATREAL = prove
3238  (`!f x. f real_differentiable atreal x ==> f real_continuous atreal x`,
3239   MESON_TAC[HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL; real_differentiable]);;
3240
3241 let REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON = prove
3242  (`!f s. f real_differentiable_on s ==> f real_continuous_on s`,
3243   REWRITE_TAC[real_differentiable_on;
3244               REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
3245   MESON_TAC[REAL_DIFFERENTIABLE_IMP_CONTINUOUS_WITHINREAL;
3246             real_differentiable]);;
3247
3248 let REAL_CONTINUOUS_AT_COMPONENT = prove
3249  (`!i a. 1 <= i /\ i <= dimindex(:N)
3250          ==> (\x:real^N. x$i) real_continuous at a`,
3251   REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF;
3252               CONTINUOUS_AT_LIFT_COMPONENT]);;
3253
3254 let REAL_CONTINUOUS_AT_TRANSLATION = prove
3255  (`!a z f:real^N->real.
3256     f real_continuous at (a + z) <=> (\x. f(a + x)) real_continuous at z`,
3257   REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF; CONTINUOUS_AT_TRANSLATION]);;
3258
3259 add_translation_invariants [REAL_CONTINUOUS_AT_TRANSLATION];;
3260
3261 let REAL_CONTINUOUS_AT_LINEAR_IMAGE = prove
3262  (`!h:real^N->real^N z f:real^N->real.
3263         linear h /\ (!x. norm(h x) = norm x)
3264         ==> (f real_continuous at (h z) <=> (\x. f(h x)) real_continuous at z)`,
3265   REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF;
3266               CONTINUOUS_AT_LINEAR_IMAGE]);;
3267
3268 add_linear_invariants [REAL_CONTINUOUS_AT_LINEAR_IMAGE];;
3269
3270 let REAL_CONTINUOUS_AT_ARG = prove
3271  (`!z. ~(real z /\ &0 <= Re z) ==> Arg real_continuous (at z)`,
3272   REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS; CONTINUOUS_AT_ARG]);;
3273
3274 (* ------------------------------------------------------------------------- *)
3275 (* More basics about real derivatives.                                       *)
3276 (* ------------------------------------------------------------------------- *)
3277
3278 let HAS_REAL_DERIVATIVE_WITHIN_SUBSET = prove
3279  (`!f s t x. (f has_real_derivative f') (atreal x within s) /\ t SUBSET s
3280              ==> (f has_real_derivative f') (atreal x within t)`,
3281   REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN
3282   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
3283   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT]
3284    HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET) THEN ASM SET_TAC[]);;
3285
3286 let REAL_DIFFERENTIABLE_ON_SUBSET = prove
3287  (`!f s t. f real_differentiable_on s /\ t SUBSET s
3288            ==> f real_differentiable_on t`,
3289   REWRITE_TAC[real_differentiable_on] THEN
3290   MESON_TAC[SUBSET; HAS_REAL_DERIVATIVE_WITHIN_SUBSET]);;
3291
3292 let REAL_DIFFERENTIABLE_WITHIN_SUBSET = prove
3293  (`!f s t. f real_differentiable (atreal x within s) /\ t SUBSET s
3294            ==> f real_differentiable (atreal x within t)`,
3295   REWRITE_TAC[real_differentiable] THEN
3296   MESON_TAC[HAS_REAL_DERIVATIVE_WITHIN_SUBSET]);;
3297
3298 let HAS_REAL_DERIVATIVE_ATREAL_WITHIN = prove
3299  (`!f f' x s. (f has_real_derivative f') (atreal x)
3300               ==> (f has_real_derivative f') (atreal x within s)`,
3301   REPEAT GEN_TAC THEN
3302   REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN;
3303               HAS_REAL_COMPLEX_DERIVATIVE_AT] THEN
3304   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT]
3305      HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET) THEN ASM SET_TAC[]);;
3306
3307 let HAS_REAL_DERIVATIVE_WITHIN_REAL_OPEN = prove
3308  (`!f f' a s.
3309          a IN s /\ real_open s
3310          ==> ((f has_real_derivative f') (atreal a within s) <=>
3311               (f has_real_derivative f') (atreal a))`,
3312   REPEAT GEN_TAC THEN
3313   ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_WITHINREAL; HAS_REAL_DERIVATIVE_ATREAL;
3314                REALLIM_WITHIN_REAL_OPEN]);;
3315
3316 let REAL_DIFFERENTIABLE_ATREAL_WITHIN = prove
3317  (`!f s z. f real_differentiable (atreal z)
3318            ==> f real_differentiable (atreal z within s)`,
3319   REWRITE_TAC[real_differentiable] THEN
3320   MESON_TAC[HAS_REAL_DERIVATIVE_ATREAL_WITHIN]);;
3321
3322 let HAS_REAL_DERIVATIVE_TRANSFORM_WITHIN = prove
3323  (`!f f' g x s d.
3324        &0 < d /\ x IN s /\
3325        (!x'. x' IN s /\ abs(x' - x) < d ==> f x' = g x') /\
3326        (f has_real_derivative f') (atreal x within s)
3327        ==> (g has_real_derivative f') (atreal x within s)`,
3328   REPEAT GEN_TAC THEN
3329   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
3330   REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN
3331   MATCH_MP_TAC(ONCE_REWRITE_RULE
3332     [TAUT `a /\ b /\ c /\ d ==> e <=> a /\ b /\ c ==> d ==> e`]
3333     HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN) THEN
3334   EXISTS_TAC `d:real` THEN ASM_REWRITE_TAC[IN_ELIM_THM; REAL_CX; RE_CX] THEN
3335   REPEAT STRIP_TAC THEN REWRITE_TAC[o_THM] THEN AP_TERM_TAC THEN
3336   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
3337   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH
3338    `dist(a,b) < d ==> z <= norm(a - b) ==> z < d`)) THEN
3339   W(MP_TAC o PART_MATCH (rand o rand) COMPLEX_NORM_GE_RE_IM o rand o snd) THEN
3340   SIMP_TAC[RE_SUB; RE_CX]);;
3341
3342 let HAS_REAL_DERIVATIVE_TRANSFORM_ATREAL = prove
3343  (`!f f' g x d.
3344        &0 < d /\ (!x'. abs(x' - x) < d ==> f x' = g x') /\
3345        (f has_real_derivative f') (atreal x)
3346        ==> (g has_real_derivative f') (atreal x)`,
3347   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
3348   MESON_TAC[HAS_REAL_DERIVATIVE_TRANSFORM_WITHIN; IN_UNIV]);;
3349
3350 let HAS_REAL_DERIVATIVE_ZERO_CONSTANT = prove
3351  (`!f s.
3352         is_realinterval s /\
3353         (!x. x IN s ==> (f has_real_derivative (&0)) (atreal x within s))
3354         ==> ?c. !x. x IN s ==> f(x) = c`,
3355   REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN
3356   REPEAT STRIP_TAC THEN
3357   MP_TAC(ISPECL [`Cx o f o Re`; `{z | real z /\ Re z IN s}`]
3358     HAS_COMPLEX_DERIVATIVE_ZERO_CONSTANT) THEN
3359   ASM_REWRITE_TAC[IN_ELIM_THM; IMP_CONJ; FORALL_REAL; RE_CX; o_THM] THEN
3360   ASM_REWRITE_TAC[GSYM IS_REALINTERVAL_CONVEX_COMPLEX] THEN MESON_TAC[RE_CX]);;
3361
3362 let HAS_REAL_DERIVATIVE_ZERO_UNIQUE = prove
3363  (`!f s c a.
3364         is_realinterval s /\ a IN s /\ f a = c /\
3365         (!x. x IN s ==> (f has_real_derivative (&0)) (atreal x within s))
3366         ==> !x. x IN s ==> f(x) = c`,
3367   MESON_TAC[HAS_REAL_DERIVATIVE_ZERO_CONSTANT]);;
3368
3369 let REAL_DIFF_CHAIN_WITHIN = prove
3370  (`!f g f' g' x s.
3371         (f has_real_derivative f') (atreal x within s) /\
3372         (g has_real_derivative g') (atreal (f x) within (IMAGE f s))
3373         ==> ((g o f) has_real_derivative (g' * f'))(atreal x within s)`,
3374   REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN REPEAT STRIP_TAC THEN
3375   SUBGOAL_THEN `Cx o (g o f) o Re = (Cx o g o Re) o (Cx o f o Re)`
3376   SUBST1_TAC THENL [REWRITE_TAC[FUN_EQ_THM; o_DEF; RE_CX]; ALL_TAC] THEN
3377   REWRITE_TAC[CX_MUL] THEN MATCH_MP_TAC COMPLEX_DIFF_CHAIN_WITHIN THEN
3378   ASM_REWRITE_TAC[o_THM; RE_CX] THEN
3379   FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP
3380    (REWRITE_RULE[IMP_CONJ] HAS_COMPLEX_DERIVATIVE_WITHIN_SUBSET)) THEN
3381   REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
3382   REWRITE_TAC[IN_ELIM_THM; o_THM; REAL_CX; RE_CX] THEN SET_TAC[]);;
3383
3384 let REAL_DIFF_CHAIN_ATREAL = prove
3385  (`!f g f' g' x.
3386         (f has_real_derivative f') (atreal x) /\
3387         (g has_real_derivative g') (atreal (f x))
3388         ==> ((g o f) has_real_derivative (g' * f')) (atreal x)`,
3389   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
3390   ASM_MESON_TAC[REAL_DIFF_CHAIN_WITHIN; SUBSET_UNIV;
3391                 HAS_REAL_DERIVATIVE_WITHIN_SUBSET]);;
3392
3393 let HAS_REAL_DERIVATIVE_CHAIN = prove
3394  (`!P f g.
3395         (!x. P x ==> (g has_real_derivative g'(x)) (atreal x))
3396         ==> (!x s. (f has_real_derivative f') (atreal x within s) /\ P(f x)
3397                    ==> ((\x. g(f x)) has_real_derivative f' * g'(f x))
3398                        (atreal x within s)) /\
3399             (!x. (f has_real_derivative f') (atreal x) /\ P(f x)
3400                  ==> ((\x. g(f x)) has_real_derivative f' * g'(f x))
3401                      (atreal x))`,
3402   REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM o_DEF] THEN
3403   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
3404   ASM_MESON_TAC[REAL_DIFF_CHAIN_WITHIN; REAL_DIFF_CHAIN_ATREAL;
3405                 HAS_REAL_DERIVATIVE_ATREAL_WITHIN]);;
3406
3407 let HAS_REAL_DERIVATIVE_CHAIN_UNIV = prove
3408  (`!f g. (!x. (g has_real_derivative g'(x)) (atreal x))
3409          ==> (!x s. (f has_real_derivative f') (atreal x within s)
3410                     ==> ((\x. g(f x)) has_real_derivative f' * g'(f x))
3411                         (atreal x within s)) /\
3412              (!x. (f has_real_derivative f') (atreal x)
3413                   ==> ((\x. g(f x)) has_real_derivative f' * g'(f x))
3414                       (atreal x))`,
3415   MP_TAC(SPEC `\x:real. T` HAS_REAL_DERIVATIVE_CHAIN) THEN SIMP_TAC[]);;
3416
3417 let REAL_DERIVATIVE_UNIQUE_ATREAL = prove
3418  (`!f z f' f''.
3419         (f has_real_derivative f') (atreal z) /\
3420         (f has_real_derivative f'') (atreal z)
3421         ==> f' = f''`,
3422   REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_AT] THEN
3423   DISCH_THEN(MP_TAC o MATCH_MP FRECHET_DERIVATIVE_UNIQUE_AT) THEN
3424   DISCH_THEN(MP_TAC o C AP_THM `vec 1:real^1`) THEN
3425   REWRITE_TAC[VECTOR_MUL_RCANCEL; VEC_EQ; ARITH_EQ]);;
3426
3427 (* ------------------------------------------------------------------------- *)
3428 (* Some handy theorems about the actual differentition function.             *)
3429 (* ------------------------------------------------------------------------- *)
3430
3431 let HAS_REAL_DERIVATIVE_DERIVATIVE = prove
3432  (`!f f' x. (f has_real_derivative f') (atreal x)
3433             ==> real_derivative f x = f'`,
3434   REWRITE_TAC[real_derivative] THEN
3435   MESON_TAC[REAL_DERIVATIVE_UNIQUE_ATREAL]);;
3436
3437 let HAS_REAL_DERIVATIVE_DIFFERENTIABLE = prove
3438  (`!f x. (f has_real_derivative (real_derivative f x)) (atreal x) <=>
3439          f real_differentiable atreal x`,
3440   REWRITE_TAC[real_differentiable; real_derivative] THEN MESON_TAC[]);;
3441
3442 (* ------------------------------------------------------------------------- *)
3443 (* Arithmetical combining theorems.                                          *)
3444 (* ------------------------------------------------------------------------- *)
3445
3446 let HAS_REAL_DERIVATIVE_LMUL_WITHIN = prove
3447  (`!f f' c x s.
3448         (f has_real_derivative f') (atreal x within s)
3449         ==> ((\x. c * f(x)) has_real_derivative (c * f')) (atreal x within s)`,
3450   REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN
3451   REWRITE_TAC[o_DEF; CX_MUL; HAS_COMPLEX_DERIVATIVE_LMUL_WITHIN]);;
3452
3453 let HAS_REAL_DERIVATIVE_LMUL_ATREAL = prove
3454  (`!f f' c x.
3455         (f has_real_derivative f') (atreal x)
3456         ==> ((\x. c * f(x)) has_real_derivative (c * f')) (atreal x)`,
3457   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
3458   REWRITE_TAC[HAS_REAL_DERIVATIVE_LMUL_WITHIN]);;
3459
3460 let HAS_REAL_DERIVATIVE_RMUL_WITHIN = prove
3461  (`!f f' c x s.
3462         (f has_real_derivative f') (atreal x within s)
3463         ==> ((\x. f(x) * c) has_real_derivative (f' * c)) (atreal x within s)`,
3464   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
3465   REWRITE_TAC[HAS_REAL_DERIVATIVE_LMUL_WITHIN]);;
3466
3467 let HAS_REAL_DERIVATIVE_RMUL_ATREAL = prove
3468  (`!f f' c x.
3469         (f has_real_derivative f') (atreal x)
3470         ==> ((\x. f(x) * c) has_real_derivative (f' * c)) (atreal x)`,
3471   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
3472   REWRITE_TAC[HAS_REAL_DERIVATIVE_LMUL_ATREAL]);;
3473
3474 let HAS_REAL_DERIVATIVE_CDIV_WITHIN = prove
3475  (`!f f' c x s.
3476         (f has_real_derivative f') (atreal x within s)
3477         ==> ((\x. f(x) / c) has_real_derivative (f' / c)) (atreal x within s)`,
3478   SIMP_TAC[real_div; HAS_REAL_DERIVATIVE_RMUL_WITHIN]);;
3479
3480 let HAS_REAL_DERIVATIVE_CDIV_ATREAL = prove
3481  (`!f f' c x.
3482         (f has_real_derivative f') (atreal x)
3483         ==> ((\x. f(x) / c) has_real_derivative (f' / c)) (atreal x)`,
3484   SIMP_TAC[real_div; HAS_REAL_DERIVATIVE_RMUL_ATREAL]);;
3485
3486 let HAS_REAL_DERIVATIVE_ID = prove
3487  (`!net. ((\x. x) has_real_derivative &1) net`,
3488   REWRITE_TAC[has_real_derivative; TENDSTO_REAL;
3489               REAL_ARITH `x - (a + &1 * (x - a)) = &0`] THEN
3490   REWRITE_TAC[REAL_MUL_RZERO; LIM_CONST; o_DEF]);;
3491
3492 let HAS_REAL_DERIVATIVE_CONST = prove
3493  (`!c net. ((\x. c) has_real_derivative &0) net`,
3494   REWRITE_TAC[has_real_derivative; REAL_MUL_LZERO; REAL_ADD_RID; REAL_SUB_REFL;
3495               REAL_MUL_RZERO; REALLIM_CONST]);;
3496
3497 let HAS_REAL_DERIVATIVE_NEG = prove
3498  (`!f f' net. (f has_real_derivative f') net
3499             ==> ((\x. --(f(x))) has_real_derivative (--f')) net`,
3500   REPEAT GEN_TAC THEN REWRITE_TAC[has_real_derivative] THEN
3501   DISCH_THEN(MP_TAC o MATCH_MP REALLIM_NEG) THEN
3502   REWRITE_TAC[REAL_NEG_0; REAL_ARITH
3503    `a * (--b - (--c + --d * e:real)) = --(a * (b - (c + d * e)))`]);;
3504
3505 let HAS_REAL_DERIVATIVE_ADD = prove
3506  (`!f f' g g' net.
3507         (f has_real_derivative f') net /\ (g has_real_derivative g') net
3508         ==> ((\x. f(x) + g(x)) has_real_derivative (f' + g')) net`,
3509   REPEAT GEN_TAC THEN REWRITE_TAC[has_real_derivative] THEN
3510   DISCH_THEN(MP_TAC o MATCH_MP REALLIM_ADD) THEN
3511   REWRITE_TAC[GSYM REAL_ADD_LDISTRIB; REAL_ADD_RID] THEN
3512   REWRITE_TAC[REAL_ARITH
3513    `(fx - (fa + f' * (x - a))) + (gx - (ga + g' * (x - a))):real =
3514     (fx + gx) - ((fa + ga) + (f' + g') * (x - a))`]);;
3515
3516 let HAS_REAL_DERIVATIVE_SUB = prove
3517  (`!f f' g g' net.
3518         (f has_real_derivative f') net /\ (g has_real_derivative g') net
3519         ==> ((\x. f(x) - g(x)) has_real_derivative (f' - g')) net`,
3520   SIMP_TAC[real_sub; HAS_REAL_DERIVATIVE_ADD; HAS_REAL_DERIVATIVE_NEG]);;
3521
3522 let HAS_REAL_DERIVATIVE_MUL_WITHIN = prove
3523  (`!f f' g g' x s.
3524         (f has_real_derivative f') (atreal x within s) /\
3525         (g has_real_derivative g') (atreal x within s)
3526         ==> ((\x. f(x) * g(x)) has_real_derivative
3527              (f(x) * g' + f' * g(x))) (atreal x within s)`,
3528   REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN
3529   DISCH_THEN(MP_TAC o MATCH_MP HAS_COMPLEX_DERIVATIVE_MUL_WITHIN) THEN
3530   REWRITE_TAC[o_DEF; CX_MUL; CX_ADD; RE_CX]);;
3531
3532 let HAS_REAL_DERIVATIVE_MUL_ATREAL = prove
3533  (`!f f' g g' x.
3534         (f has_real_derivative f') (atreal x) /\
3535         (g has_real_derivative g') (atreal x)
3536         ==> ((\x. f(x) * g(x)) has_real_derivative
3537              (f(x) * g' + f' * g(x))) (atreal x)`,
3538   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
3539   REWRITE_TAC[HAS_REAL_DERIVATIVE_MUL_WITHIN]);;
3540
3541 let HAS_REAL_DERIVATIVE_POW_WITHIN = prove
3542  (`!f f' x s n. (f has_real_derivative f') (atreal x within s)
3543                 ==> ((\x. f(x) pow n) has_real_derivative
3544                      (&n * f(x) pow (n - 1) * f')) (atreal x within s)`,
3545   REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_WITHIN] THEN
3546   DISCH_THEN(MP_TAC o SPEC `n:num` o
3547     MATCH_MP HAS_COMPLEX_DERIVATIVE_POW_WITHIN) THEN
3548   REWRITE_TAC[o_DEF; CX_MUL; CX_POW; RE_CX]);;
3549
3550 let HAS_REAL_DERIVATIVE_POW_ATREAL = prove
3551  (`!f f' x n. (f has_real_derivative f') (atreal x)
3552               ==> ((\x. f(x) pow n) has_real_derivative
3553                    (&n * f(x) pow (n - 1) * f')) (atreal x)`,
3554   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
3555   REWRITE_TAC[HAS_REAL_DERIVATIVE_POW_WITHIN]);;
3556
3557 let HAS_REAL_DERIVATIVE_INV_BASIC = prove
3558  (`!x. ~(x = &0)
3559          ==> ((inv) has_real_derivative (--inv(x pow 2))) (atreal x)`,
3560   REPEAT STRIP_TAC THEN
3561   REWRITE_TAC[HAS_REAL_COMPLEX_DERIVATIVE_AT] THEN
3562   MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_TRANSFORM_WITHIN THEN
3563   EXISTS_TAC `inv:complex->complex` THEN
3564   ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_INV_BASIC; CX_INJ; CX_NEG; CX_INV;
3565                CX_POW; HAS_COMPLEX_DERIVATIVE_AT_WITHIN] THEN
3566   SIMP_TAC[IN; FORALL_REAL; IMP_CONJ; o_DEF; REAL_CX; RE_CX; CX_INV] THEN
3567   MESON_TAC[REAL_LT_01]);;
3568
3569 let HAS_REAL_DERIVATIVE_INV_WITHIN = prove
3570  (`!f f' x s. (f has_real_derivative f') (atreal x within s) /\
3571               ~(f x = &0)
3572               ==> ((\x. inv(f(x))) has_real_derivative (--f' / f(x) pow 2))
3573                   (atreal x within s)`,
3574   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN
3575   ASM_SIMP_TAC[REAL_FIELD
3576    `~(g = &0) ==> --f / g pow 2 = --inv(g pow 2) * f`] THEN
3577   MATCH_MP_TAC REAL_DIFF_CHAIN_WITHIN THEN ASM_REWRITE_TAC[] THEN
3578   MATCH_MP_TAC HAS_REAL_DERIVATIVE_ATREAL_WITHIN THEN
3579   ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_INV_BASIC]);;
3580
3581 let HAS_REAL_DERIVATIVE_INV_ATREAL = prove
3582  (`!f f' x. (f has_real_derivative f') (atreal x) /\
3583             ~(f x = &0)
3584             ==> ((\x. inv(f(x))) has_real_derivative (--f' / f(x) pow 2))
3585                 (atreal x)`,
3586   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
3587   REWRITE_TAC[HAS_REAL_DERIVATIVE_INV_WITHIN]);;
3588
3589 let HAS_REAL_DERIVATIVE_DIV_WITHIN = prove
3590  (`!f f' g g' x s.
3591         (f has_real_derivative f') (atreal x within s) /\
3592         (g has_real_derivative g') (atreal x within s) /\
3593         ~(g(x) = &0)
3594         ==> ((\x. f(x) / g(x)) has_real_derivative
3595              (f' * g(x) - f(x) * g') / g(x) pow 2) (atreal x within s)`,
3596   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3597   DISCH_THEN(fun th -> ASSUME_TAC(CONJUNCT2 th) THEN MP_TAC th) THEN
3598   DISCH_THEN(MP_TAC o MATCH_MP HAS_REAL_DERIVATIVE_INV_WITHIN) THEN
3599   UNDISCH_TAC `(f has_real_derivative f') (atreal x within s)` THEN
3600   REWRITE_TAC[IMP_IMP] THEN
3601   DISCH_THEN(MP_TAC o MATCH_MP HAS_REAL_DERIVATIVE_MUL_WITHIN) THEN
3602   REWRITE_TAC[GSYM real_div] THEN MATCH_MP_TAC EQ_IMP THEN
3603   AP_THM_TAC THEN AP_TERM_TAC THEN
3604   POP_ASSUM MP_TAC THEN CONV_TAC REAL_FIELD);;
3605
3606 let HAS_REAL_DERIVATIVE_DIV_ATREAL = prove
3607  (`!f f' g g' x.
3608         (f has_real_derivative f') (atreal x) /\
3609         (g has_real_derivative g') (atreal x) /\
3610         ~(g(x) = &0)
3611         ==> ((\x. f(x) / g(x)) has_real_derivative
3612              (f' * g(x) - f(x) * g') / g(x) pow 2) (atreal x)`,
3613   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
3614   REWRITE_TAC[HAS_REAL_DERIVATIVE_DIV_WITHIN]);;
3615
3616 let HAS_REAL_DERIVATIVE_SUM = prove
3617  (`!f net s.
3618          FINITE s /\ (!a. a IN s ==> (f a has_real_derivative f' a) net)
3619          ==> ((\x. sum s (\a. f a x)) has_real_derivative (sum s f'))
3620              net`,
3621   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
3622   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3623   SIMP_TAC[FORALL_IN_INSERT; NOT_IN_EMPTY; SUM_CLAUSES] THEN
3624   SIMP_TAC[HAS_REAL_DERIVATIVE_CONST; HAS_REAL_DERIVATIVE_ADD; ETA_AX]);;
3625
3626 (* ------------------------------------------------------------------------- *)
3627 (* Same thing just for real differentiability.                               *)
3628 (* ------------------------------------------------------------------------- *)
3629
3630 let REAL_DIFFERENTIABLE_CONST = prove
3631  (`!c net. (\z. c) real_differentiable net`,
3632   REWRITE_TAC[real_differentiable] THEN
3633   MESON_TAC[HAS_REAL_DERIVATIVE_CONST]);;
3634
3635 let REAL_DIFFERENTIABLE_ID = prove
3636  (`!net. (\z. z) real_differentiable net`,
3637   REWRITE_TAC[real_differentiable] THEN
3638   MESON_TAC[HAS_REAL_DERIVATIVE_ID]);;
3639
3640 let REAL_DIFFERENTIABLE_NEG = prove
3641  (`!f net.
3642         f real_differentiable net
3643         ==> (\z. --(f z)) real_differentiable net`,
3644   REWRITE_TAC[real_differentiable] THEN
3645   MESON_TAC[HAS_REAL_DERIVATIVE_NEG]);;
3646
3647 let REAL_DIFFERENTIABLE_ADD = prove
3648  (`!f g net.
3649         f real_differentiable net /\
3650         g real_differentiable net
3651         ==> (\z. f z + g z) real_differentiable net`,
3652   REWRITE_TAC[real_differentiable] THEN
3653   MESON_TAC[HAS_REAL_DERIVATIVE_ADD]);;
3654
3655 let REAL_DIFFERENTIABLE_SUB = prove
3656  (`!f g net.
3657         f real_differentiable net /\
3658         g real_differentiable net
3659         ==> (\z. f z - g z) real_differentiable net`,
3660   REWRITE_TAC[real_differentiable] THEN
3661   MESON_TAC[HAS_REAL_DERIVATIVE_SUB]);;
3662
3663 let REAL_DIFFERENTIABLE_INV_WITHIN = prove
3664  (`!f z s.
3665         f real_differentiable (atreal z within s) /\ ~(f z = &0)
3666         ==> (\z. inv(f z)) real_differentiable (atreal z within s)`,
3667   REWRITE_TAC[real_differentiable] THEN
3668   MESON_TAC[HAS_REAL_DERIVATIVE_INV_WITHIN]);;
3669
3670 let REAL_DIFFERENTIABLE_MUL_WITHIN = prove
3671  (`!f g z s.
3672         f real_differentiable (atreal z within s) /\
3673         g real_differentiable (atreal z within s)
3674         ==> (\z. f z * g z) real_differentiable (atreal z within s)`,
3675   REWRITE_TAC[real_differentiable] THEN
3676   MESON_TAC[HAS_REAL_DERIVATIVE_MUL_WITHIN]);;
3677
3678 let REAL_DIFFERENTIABLE_DIV_WITHIN = prove
3679  (`!f g z s.
3680         f real_differentiable (atreal z within s) /\
3681         g real_differentiable (atreal z within s) /\
3682         ~(g z = &0)
3683         ==> (\z. f z / g z) real_differentiable (atreal z within s)`,
3684   REWRITE_TAC[real_differentiable] THEN
3685   MESON_TAC[HAS_REAL_DERIVATIVE_DIV_WITHIN]);;
3686
3687 let REAL_DIFFERENTIABLE_POW_WITHIN = prove
3688  (`!f n z s.
3689         f real_differentiable (atreal z within s)
3690         ==> (\z. f z pow n) real_differentiable (atreal z within s)`,
3691   REWRITE_TAC[real_differentiable] THEN
3692   MESON_TAC[HAS_REAL_DERIVATIVE_POW_WITHIN]);;
3693
3694 let REAL_DIFFERENTIABLE_TRANSFORM_WITHIN = prove
3695  (`!f g x s d.
3696         &0 < d /\
3697         x IN s /\
3698         (!x'. x' IN s /\ abs(x' - x) < d ==> f x' = g x') /\
3699         f real_differentiable (atreal x within s)
3700         ==> g real_differentiable (atreal x within s)`,
3701   REWRITE_TAC[real_differentiable] THEN
3702   MESON_TAC[HAS_REAL_DERIVATIVE_TRANSFORM_WITHIN]);;
3703
3704 let REAL_DIFFERENTIABLE_TRANSFORM = prove
3705  (`!f g s. (!x. x IN s ==> f x = g x) /\ f real_differentiable_on s
3706            ==> g real_differentiable_on s`,
3707   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3708   REWRITE_TAC[real_differentiable_on; GSYM real_differentiable] THEN
3709   MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
3710   DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
3711   ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
3712   MATCH_MP_TAC REAL_DIFFERENTIABLE_TRANSFORM_WITHIN THEN
3713   MAP_EVERY EXISTS_TAC [`f:real->real`; `&1`] THEN
3714   ASM_SIMP_TAC[REAL_LT_01]);;
3715
3716 let REAL_DIFFERENTIABLE_EQ = prove
3717  (`!f g s. (!x. x IN s ==> f x = g x)
3718            ==> (f real_differentiable_on s <=> g real_differentiable_on s)`,
3719   MESON_TAC[REAL_DIFFERENTIABLE_TRANSFORM]);;
3720
3721 let REAL_DIFFERENTIABLE_INV_ATREAL = prove
3722  (`!f z.
3723         f real_differentiable atreal z /\ ~(f z = &0)
3724         ==> (\z. inv(f z)) real_differentiable atreal z`,
3725   REWRITE_TAC[real_differentiable] THEN
3726   MESON_TAC[HAS_REAL_DERIVATIVE_INV_ATREAL]);;
3727
3728 let REAL_DIFFERENTIABLE_MUL_ATREAL = prove
3729  (`!f g z.
3730         f real_differentiable atreal z /\
3731         g real_differentiable atreal z
3732         ==> (\z. f z * g z) real_differentiable atreal z`,
3733   REWRITE_TAC[real_differentiable] THEN
3734   MESON_TAC[HAS_REAL_DERIVATIVE_MUL_ATREAL]);;
3735
3736 let REAL_DIFFERENTIABLE_DIV_ATREAL = prove
3737  (`!f g z.
3738         f real_differentiable atreal z /\
3739         g real_differentiable atreal z /\
3740         ~(g z = &0)
3741         ==> (\z. f z / g z) real_differentiable atreal z`,
3742   REWRITE_TAC[real_differentiable] THEN
3743   MESON_TAC[HAS_REAL_DERIVATIVE_DIV_ATREAL]);;
3744
3745 let REAL_DIFFERENTIABLE_POW_ATREAL = prove
3746  (`!f n z.
3747         f real_differentiable atreal z
3748         ==> (\z. f z pow n) real_differentiable atreal z`,
3749   REWRITE_TAC[real_differentiable] THEN
3750   MESON_TAC[HAS_REAL_DERIVATIVE_POW_ATREAL]);;
3751
3752 let REAL_DIFFERENTIABLE_TRANSFORM_ATREAL = prove
3753  (`!f g x d.
3754         &0 < d /\
3755         (!x'. abs(x' - x) < d ==> f x' = g x') /\
3756         f real_differentiable atreal x
3757         ==> g real_differentiable atreal x`,
3758   REWRITE_TAC[real_differentiable] THEN
3759   MESON_TAC[HAS_REAL_DERIVATIVE_TRANSFORM_ATREAL]);;
3760
3761 let REAL_DIFFERENTIABLE_COMPOSE_WITHIN = prove
3762  (`!f g x s.
3763          f real_differentiable (atreal x within s) /\
3764          g real_differentiable (atreal (f x) within IMAGE f s)
3765          ==> (g o f) real_differentiable (atreal x within s)`,
3766   REWRITE_TAC[real_differentiable] THEN
3767   MESON_TAC[REAL_DIFF_CHAIN_WITHIN]);;
3768
3769 let REAL_DIFFERENTIABLE_COMPOSE_ATREAL = prove
3770  (`!f g x.
3771          f real_differentiable (atreal x) /\
3772          g real_differentiable (atreal (f x))
3773          ==> (g o f) real_differentiable (atreal x)`,
3774   REWRITE_TAC[real_differentiable] THEN
3775   MESON_TAC[REAL_DIFF_CHAIN_ATREAL]);;
3776
3777 (* ------------------------------------------------------------------------- *)
3778 (* Same again for being differentiable on a set.                             *)
3779 (* ------------------------------------------------------------------------- *)
3780
3781 let REAL_DIFFERENTIABLE_ON_CONST = prove
3782  (`!c s. (\z. c) real_differentiable_on s`,
3783   REWRITE_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE;
3784               REAL_DIFFERENTIABLE_CONST]);;
3785
3786 let REAL_DIFFERENTIABLE_ON_ID = prove
3787  (`!s. (\z. z) real_differentiable_on s`,
3788   REWRITE_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; REAL_DIFFERENTIABLE_ID]);;
3789
3790 let REAL_DIFFERENTIABLE_ON_COMPOSE = prove
3791  (`!f g s. f real_differentiable_on s /\ g real_differentiable_on (IMAGE f s)
3792            ==> (g o f) real_differentiable_on s`,
3793   SIMP_TAC[real_differentiable_on; GSYM real_differentiable;
3794            FORALL_IN_IMAGE] THEN
3795   MESON_TAC[REAL_DIFFERENTIABLE_COMPOSE_WITHIN]);;
3796
3797 let REAL_DIFFERENTIABLE_ON_NEG = prove
3798  (`!f s. f real_differentiable_on s ==> (\z. --(f z)) real_differentiable_on s`,
3799   SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; REAL_DIFFERENTIABLE_NEG]);;
3800
3801 let REAL_DIFFERENTIABLE_ON_ADD = prove
3802  (`!f g s.
3803         f real_differentiable_on s /\ g real_differentiable_on s
3804         ==> (\z. f z + g z) real_differentiable_on s`,
3805   SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; REAL_DIFFERENTIABLE_ADD]);;
3806
3807 let REAL_DIFFERENTIABLE_ON_SUB = prove
3808  (`!f g s.
3809         f real_differentiable_on s /\ g real_differentiable_on s
3810         ==> (\z. f z - g z) real_differentiable_on s`,
3811   SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; REAL_DIFFERENTIABLE_SUB]);;
3812
3813 let REAL_DIFFERENTIABLE_ON_MUL = prove
3814  (`!f g s.
3815         f real_differentiable_on s /\ g real_differentiable_on s
3816         ==> (\z. f z * g z) real_differentiable_on s`,
3817   SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE;
3818            REAL_DIFFERENTIABLE_MUL_WITHIN]);;
3819
3820 let REAL_DIFFERENTIABLE_ON_INV = prove
3821  (`!f s. f real_differentiable_on s /\ (!z. z IN s ==> ~(f z = &0))
3822          ==> (\z. inv(f z)) real_differentiable_on s`,
3823   SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE;
3824            REAL_DIFFERENTIABLE_INV_WITHIN]);;
3825
3826 let REAL_DIFFERENTIABLE_ON_DIV = prove
3827  (`!f g s.
3828         f real_differentiable_on s /\ g real_differentiable_on s /\
3829         (!z. z IN s ==> ~(g z = &0))
3830         ==> (\z. f z / g z) real_differentiable_on s`,
3831   SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE;
3832            REAL_DIFFERENTIABLE_DIV_WITHIN]);;
3833
3834 let REAL_DIFFERENTIABLE_ON_POW = prove
3835  (`!f s n. f real_differentiable_on s
3836            ==> (\z. (f z) pow n) real_differentiable_on s`,
3837   SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE;
3838            REAL_DIFFERENTIABLE_POW_WITHIN]);;
3839
3840 let REAL_DIFFERENTIABLE_ON_SUM = prove
3841  (`!f s k. FINITE k /\ (!a. a IN k ==> (f a) real_differentiable_on s)
3842            ==> (\x. sum k (\a. f a x)) real_differentiable_on s`,
3843   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
3844   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN SIMP_TAC[SUM_CLAUSES] THEN
3845   SIMP_TAC[REAL_DIFFERENTIABLE_ON_CONST; IN_INSERT; NOT_IN_EMPTY] THEN
3846   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_ADD THEN
3847   ASM_SIMP_TAC[ETA_AX]);;
3848
3849 (* ------------------------------------------------------------------------- *)
3850 (* Derivative (and continuity) theorems for real transcendental functions.   *)
3851 (* ------------------------------------------------------------------------- *)
3852
3853 let HAS_REAL_DERIVATIVE_EXP = prove
3854  (`!x. (exp has_real_derivative exp(x)) (atreal x)`,
3855   GEN_TAC THEN MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT THEN
3856   EXISTS_TAC `cexp` THEN
3857   ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN;
3858                HAS_COMPLEX_DERIVATIVE_CEXP; CX_EXP]);;
3859
3860 let REAL_DIFFERENTIABLE_AT_EXP = prove
3861  (`!x. exp real_differentiable (atreal x)`,
3862   REWRITE_TAC[real_differentiable] THEN
3863   MESON_TAC[HAS_REAL_DERIVATIVE_EXP]);;
3864
3865 let REAL_DIFFERENTIABLE_WITHIN_EXP = prove
3866  (`!s x. exp real_differentiable (atreal x within s)`,
3867   MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN;
3868             REAL_DIFFERENTIABLE_AT_EXP]);;
3869
3870 let REAL_CONTINUOUS_AT_EXP = prove
3871  (`!x. exp real_continuous (atreal x)`,
3872   MESON_TAC[HAS_REAL_DERIVATIVE_EXP;
3873             HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);;
3874
3875 let REAL_CONTINUOUS_WITHIN_EXP = prove
3876  (`!s x. exp real_continuous (atreal x within s)`,
3877   MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL;
3878             REAL_CONTINUOUS_AT_EXP]);;
3879
3880 let REAL_CONTINUOUS_ON_EXP = prove
3881  (`!s. exp real_continuous_on s`,
3882   REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
3883               REAL_CONTINUOUS_WITHIN_EXP]);;
3884
3885 let HAS_REAL_DERIVATIVE_SIN = prove
3886  (`!x. (sin has_real_derivative cos(x)) (atreal x)`,
3887   GEN_TAC THEN MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT THEN
3888   EXISTS_TAC `csin` THEN
3889   ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN;
3890                HAS_COMPLEX_DERIVATIVE_CSIN; CX_SIN; CX_COS]);;
3891
3892 let REAL_DIFFERENTIABLE_AT_SIN = prove
3893  (`!x. sin real_differentiable (atreal x)`,
3894   REWRITE_TAC[real_differentiable] THEN
3895   MESON_TAC[HAS_REAL_DERIVATIVE_SIN]);;
3896
3897 let REAL_DIFFERENTIABLE_WITHIN_SIN = prove
3898  (`!s x. sin real_differentiable (atreal x within s)`,
3899   MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN;
3900             REAL_DIFFERENTIABLE_AT_SIN]);;
3901
3902 let REAL_CONTINUOUS_AT_SIN = prove
3903  (`!x. sin real_continuous (atreal x)`,
3904   MESON_TAC[HAS_REAL_DERIVATIVE_SIN;
3905             HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);;
3906
3907 let REAL_CONTINUOUS_WITHIN_SIN = prove
3908  (`!s x. sin real_continuous (atreal x within s)`,
3909   MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL;
3910             REAL_CONTINUOUS_AT_SIN]);;
3911
3912 let REAL_CONTINUOUS_ON_SIN = prove
3913  (`!s. sin real_continuous_on s`,
3914   REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
3915               REAL_CONTINUOUS_WITHIN_SIN]);;
3916
3917 let HAS_REAL_DERIVATIVE_COS = prove
3918  (`!x. (cos has_real_derivative --sin(x)) (atreal x)`,
3919   GEN_TAC THEN MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT THEN
3920   EXISTS_TAC `ccos` THEN
3921   ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN;
3922                HAS_COMPLEX_DERIVATIVE_CCOS; CX_SIN; CX_COS; CX_NEG]);;
3923
3924 let REAL_DIFFERENTIABLE_AT_COS = prove
3925  (`!x. cos real_differentiable (atreal x)`,
3926   REWRITE_TAC[real_differentiable] THEN
3927   MESON_TAC[HAS_REAL_DERIVATIVE_COS]);;
3928
3929 let REAL_DIFFERENTIABLE_WITHIN_COS = prove
3930  (`!s x. cos real_differentiable (atreal x within s)`,
3931   MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN;
3932             REAL_DIFFERENTIABLE_AT_COS]);;
3933
3934 let REAL_CONTINUOUS_AT_COS = prove
3935  (`!x. cos real_continuous (atreal x)`,
3936   MESON_TAC[HAS_REAL_DERIVATIVE_COS;
3937             HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);;
3938
3939 let REAL_CONTINUOUS_WITHIN_COS = prove
3940  (`!s x. cos real_continuous (atreal x within s)`,
3941   MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL;
3942             REAL_CONTINUOUS_AT_COS]);;
3943
3944 let REAL_CONTINUOUS_ON_COS = prove
3945  (`!s. cos real_continuous_on s`,
3946   REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
3947               REAL_CONTINUOUS_WITHIN_COS]);;
3948
3949 let HAS_REAL_DERIVATIVE_TAN = prove
3950  (`!x. ~(cos x = &0)
3951        ==> (tan has_real_derivative inv(cos(x) pow 2)) (atreal x)`,
3952   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT THEN
3953   EXISTS_TAC `ctan` THEN REWRITE_TAC[CX_INV; CX_POW; CX_COS] THEN
3954   ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN;
3955                HAS_COMPLEX_DERIVATIVE_CTAN; GSYM CX_COS; CX_INJ; CX_TAN]);;
3956
3957 let REAL_DIFFERENTIABLE_AT_TAN = prove
3958  (`!x. ~(cos x = &0) ==> tan real_differentiable (atreal x)`,
3959   REWRITE_TAC[real_differentiable] THEN
3960   MESON_TAC[HAS_REAL_DERIVATIVE_TAN]);;
3961
3962 let REAL_DIFFERENTIABLE_WITHIN_TAN = prove
3963  (`!s x. ~(cos x = &0) ==> tan real_differentiable (atreal x within s)`,
3964   MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN;
3965             REAL_DIFFERENTIABLE_AT_TAN]);;
3966
3967 let REAL_CONTINUOUS_AT_TAN = prove
3968  (`!x. ~(cos x = &0) ==> tan real_continuous (atreal x)`,
3969   MESON_TAC[HAS_REAL_DERIVATIVE_TAN;
3970             HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);;
3971
3972 let REAL_CONTINUOUS_WITHIN_TAN = prove
3973  (`!s x. ~(cos x = &0) ==> tan real_continuous (atreal x within s)`,
3974   MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL;
3975             REAL_CONTINUOUS_AT_TAN]);;
3976
3977 let REAL_CONTINUOUS_ON_TAN = prove
3978  (`!s. (!x. x IN s ==> ~(cos x = &0)) ==> tan real_continuous_on s`,
3979   MESON_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
3980             REAL_CONTINUOUS_WITHIN_TAN]);;
3981
3982 let HAS_REAL_DERIVATIVE_LOG = prove
3983  (`!x. &0 < x ==> (log has_real_derivative inv(x)) (atreal x)`,
3984   REPEAT STRIP_TAC THEN
3985   MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT_GEN THEN
3986   MAP_EVERY EXISTS_TAC [`clog`; `x:real`] THEN ASM_REWRITE_TAC[] THEN
3987   REPEAT STRIP_TAC THENL
3988    [REWRITE_TAC[CX_INV] THEN MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN
3989     MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_CLOG THEN ASM_REWRITE_TAC[RE_CX];
3990     MATCH_MP_TAC(GSYM CX_LOG) THEN ASM_REAL_ARITH_TAC]);;
3991
3992 let REAL_DIFFERENTIABLE_AT_LOG = prove
3993  (`!x. &0 < x ==> log real_differentiable (atreal x)`,
3994   REWRITE_TAC[real_differentiable] THEN
3995   MESON_TAC[HAS_REAL_DERIVATIVE_LOG]);;
3996
3997 let REAL_DIFFERENTIABLE_WITHIN_LOG = prove
3998  (`!s x. &0 < x ==> log real_differentiable (atreal x within s)`,
3999   MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN;
4000             REAL_DIFFERENTIABLE_AT_LOG]);;
4001
4002 let REAL_CONTINUOUS_AT_LOG = prove
4003  (`!x. &0 < x ==> log real_continuous (atreal x)`,
4004   MESON_TAC[HAS_REAL_DERIVATIVE_LOG;
4005             HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);;
4006
4007 let REAL_CONTINUOUS_WITHIN_LOG = prove
4008  (`!s x. &0 < x ==> log real_continuous (atreal x within s)`,
4009   MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL;
4010             REAL_CONTINUOUS_AT_LOG]);;
4011
4012 let REAL_CONTINUOUS_ON_LOG = prove
4013  (`!s. (!x. x IN s ==> &0 < x) ==> log real_continuous_on s`,
4014   MESON_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
4015             REAL_CONTINUOUS_WITHIN_LOG]);;
4016
4017 let HAS_REAL_DERIVATIVE_SQRT = prove
4018  (`!x. &0 < x ==> (sqrt has_real_derivative inv(&2 * sqrt x)) (atreal x)`,
4019   REPEAT STRIP_TAC THEN
4020   MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT_GEN THEN
4021   MAP_EVERY EXISTS_TAC [`csqrt`; `x:real`] THEN ASM_REWRITE_TAC[] THEN
4022   REPEAT STRIP_TAC THENL
4023    [ASM_SIMP_TAC[CX_INV; CX_MUL; CX_SQRT; REAL_LT_IMP_LE] THEN
4024     MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN
4025     MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_CSQRT THEN
4026     ASM_SIMP_TAC[RE_CX];
4027     MATCH_MP_TAC(GSYM CX_SQRT) THEN ASM_REAL_ARITH_TAC]);;
4028
4029 let REAL_DIFFERENTIABLE_AT_SQRT = prove
4030  (`!x. &0 < x ==> sqrt real_differentiable (atreal x)`,
4031   REWRITE_TAC[real_differentiable] THEN
4032   MESON_TAC[HAS_REAL_DERIVATIVE_SQRT]);;
4033
4034 let REAL_DIFFERENTIABLE_WITHIN_SQRT = prove
4035  (`!s x. &0 < x ==> sqrt real_differentiable (atreal x within s)`,
4036   MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN;
4037             REAL_DIFFERENTIABLE_AT_SQRT]);;
4038
4039 let REAL_CONTINUOUS_AT_SQRT = prove
4040  (`!x. &0 < x ==> sqrt real_continuous (atreal x)`,
4041   MESON_TAC[HAS_REAL_DERIVATIVE_SQRT;
4042             HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);;
4043
4044 let REAL_CONTINUOUS_WITHIN_SQRT = prove
4045  (`!s x. &0 < x ==> sqrt real_continuous (atreal x within s)`,
4046   MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL;
4047             REAL_CONTINUOUS_AT_SQRT]);;
4048
4049 let REAL_CONTINUOUS_WITHIN_SQRT_COMPOSE = prove
4050  (`!f s a:real^N.
4051         f real_continuous (at a within s) /\
4052         (&0 < f a \/ !x. x IN s ==> &0 <= f x)
4053         ==> (\x. sqrt(f x)) real_continuous (at a within s)`,
4054   REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF] THEN
4055   REWRITE_TAC[CONTINUOUS_WITHIN_SQRT_COMPOSE]);;
4056
4057 let REAL_CONTINUOUS_AT_SQRT_COMPOSE = prove
4058  (`!f a:real^N.
4059         f real_continuous (at a) /\
4060         (&0 < f a \/ !x. &0 <= f x)
4061         ==> (\x. sqrt(f x)) real_continuous (at a)`,
4062   REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF] THEN
4063   REWRITE_TAC[CONTINUOUS_AT_SQRT_COMPOSE]);;
4064
4065 let CONTINUOUS_WITHINREAL_SQRT_COMPOSE = prove
4066  (`!f s a. (\x. lift(f x)) continuous (atreal a within s) /\
4067            (&0 < f a \/ !x. x IN s ==> &0 <= f x)
4068            ==> (\x. lift(sqrt(f x))) continuous (atreal a within s)`,
4069   REWRITE_TAC[CONTINUOUS_CONTINUOUS_WITHINREAL] THEN
4070   REWRITE_TAC[o_DEF] THEN REPEAT GEN_TAC THEN DISCH_TAC THEN
4071   MATCH_MP_TAC CONTINUOUS_WITHIN_SQRT_COMPOSE THEN
4072   ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP]);;
4073
4074 let CONTINUOUS_ATREAL_SQRT_COMPOSE = prove
4075  (`!f a. (\x. lift(f x)) continuous (atreal a) /\ (&0 < f a \/ !x. &0 <= f x)
4076          ==> (\x. lift(sqrt(f x))) continuous (atreal a)`,
4077   REPEAT GEN_TAC THEN
4078   MP_TAC(ISPECL [`f:real->real`; `(:real)`; `a:real`]
4079         CONTINUOUS_WITHINREAL_SQRT_COMPOSE) THEN
4080   REWRITE_TAC[WITHINREAL_UNIV; IN_UNIV]);;
4081
4082 let REAL_CONTINUOUS_WITHINREAL_SQRT_COMPOSE = prove
4083  (`!f s a. f real_continuous (atreal a within s) /\
4084            (&0 < f a \/ !x. x IN s ==> &0 <= f x)
4085            ==> (\x. sqrt(f x)) real_continuous (atreal a within s)`,
4086   REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF] THEN
4087   REWRITE_TAC[CONTINUOUS_WITHINREAL_SQRT_COMPOSE]);;
4088
4089 let REAL_CONTINUOUS_ATREAL_SQRT_COMPOSE = prove
4090  (`!f a. f real_continuous (atreal a) /\
4091          (&0 < f a \/ !x. &0 <= f x)
4092          ==> (\x. sqrt(f x)) real_continuous (atreal a)`,
4093   REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; o_DEF] THEN
4094   REWRITE_TAC[CONTINUOUS_ATREAL_SQRT_COMPOSE]);;
4095
4096 let HAS_REAL_DERIVATIVE_ATN = prove
4097  (`!x. (atn has_real_derivative inv(&1 + x pow 2)) (atreal x)`,
4098   GEN_TAC THEN MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT THEN
4099   EXISTS_TAC `catn` THEN REWRITE_TAC[CX_INV; CX_ADD; CX_ATN; CX_POW] THEN
4100   ASM_SIMP_TAC[HAS_COMPLEX_DERIVATIVE_AT_WITHIN; HAS_COMPLEX_DERIVATIVE_CATN;
4101                IM_CX; REAL_ABS_NUM; REAL_LT_01]);;
4102
4103 let REAL_DIFFERENTIABLE_AT_ATN = prove
4104  (`!x. atn real_differentiable (atreal x)`,
4105   REWRITE_TAC[real_differentiable] THEN
4106   MESON_TAC[HAS_REAL_DERIVATIVE_ATN]);;
4107
4108 let REAL_DIFFERENTIABLE_WITHIN_ATN = prove
4109  (`!s x. atn real_differentiable (atreal x within s)`,
4110   MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN;
4111             REAL_DIFFERENTIABLE_AT_ATN]);;
4112
4113 let REAL_CONTINUOUS_AT_ATN = prove
4114  (`!x. atn real_continuous (atreal x)`,
4115   MESON_TAC[HAS_REAL_DERIVATIVE_ATN;
4116             HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);;
4117
4118 let REAL_CONTINUOUS_WITHIN_ATN = prove
4119  (`!s x. atn real_continuous (atreal x within s)`,
4120   MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL;
4121             REAL_CONTINUOUS_AT_ATN]);;
4122
4123 let REAL_CONTINUOUS_ON_ATN = prove
4124  (`!s. atn real_continuous_on s`,
4125   REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
4126               REAL_CONTINUOUS_WITHIN_ATN]);;
4127
4128 let HAS_REAL_DERIVATIVE_ASN_COS = prove
4129  (`!x. abs(x) < &1 ==> (asn has_real_derivative inv(cos(asn x))) (atreal x)`,
4130   REPEAT STRIP_TAC THEN
4131   MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT_GEN THEN
4132   MAP_EVERY EXISTS_TAC [`casn`; `&1 - abs x`] THEN
4133   ASM_REWRITE_TAC[REAL_SUB_LT] THEN REPEAT STRIP_TAC THENL
4134    [ASM_SIMP_TAC[CX_INV; CX_COS; CX_ASN; REAL_LT_IMP_LE] THEN
4135     MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN
4136     MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_CASN THEN ASM_REWRITE_TAC[RE_CX];
4137     MATCH_MP_TAC(GSYM CX_ASN) THEN ASM_REAL_ARITH_TAC]);;
4138
4139 let HAS_REAL_DERIVATIVE_ASN = prove
4140  (`!x. abs(x) < &1
4141        ==> (asn has_real_derivative inv(sqrt(&1 - x pow 2))) (atreal x)`,
4142   REPEAT STRIP_TAC THEN
4143   FIRST_ASSUM(MP_TAC o MATCH_MP HAS_REAL_DERIVATIVE_ASN_COS) THEN
4144   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
4145   AP_TERM_TAC THEN MATCH_MP_TAC COS_ASN THEN ASM_REAL_ARITH_TAC);;
4146
4147 let REAL_DIFFERENTIABLE_AT_ASN = prove
4148  (`!x. abs(x) < &1 ==> asn real_differentiable (atreal x)`,
4149   REWRITE_TAC[real_differentiable] THEN
4150   MESON_TAC[HAS_REAL_DERIVATIVE_ASN]);;
4151
4152 let REAL_DIFFERENTIABLE_WITHIN_ASN = prove
4153  (`!s x. abs(x) < &1 ==> asn real_differentiable (atreal x within s)`,
4154   MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN;
4155             REAL_DIFFERENTIABLE_AT_ASN]);;
4156
4157 let REAL_CONTINUOUS_AT_ASN = prove
4158  (`!x. abs(x) < &1 ==> asn real_continuous (atreal x)`,
4159   MESON_TAC[HAS_REAL_DERIVATIVE_ASN;
4160             HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);;
4161
4162 let REAL_CONTINUOUS_WITHIN_ASN = prove
4163  (`!s x. abs(x) < &1 ==> asn real_continuous (atreal x within s)`,
4164   MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL;
4165             REAL_CONTINUOUS_AT_ASN]);;
4166
4167 let HAS_REAL_DERIVATIVE_ACS_SIN = prove
4168  (`!x. abs(x) < &1 ==> (acs has_real_derivative --inv(sin(acs x))) (atreal x)`,
4169   REPEAT STRIP_TAC THEN
4170   MATCH_MP_TAC HAS_COMPLEX_REAL_DERIVATIVE_AT_GEN THEN
4171   MAP_EVERY EXISTS_TAC [`cacs`; `&1 - abs x`] THEN
4172   ASM_REWRITE_TAC[REAL_SUB_LT] THEN REPEAT STRIP_TAC THENL
4173    [ASM_SIMP_TAC[CX_INV; CX_SIN; CX_ACS; CX_NEG; REAL_LT_IMP_LE] THEN
4174     MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_AT_WITHIN THEN
4175     MATCH_MP_TAC HAS_COMPLEX_DERIVATIVE_CACS THEN ASM_REWRITE_TAC[RE_CX];
4176     MATCH_MP_TAC(GSYM CX_ACS) THEN ASM_REAL_ARITH_TAC]);;
4177
4178 let HAS_REAL_DERIVATIVE_ACS = prove
4179  (`!x. abs(x) < &1
4180        ==> (acs has_real_derivative --inv(sqrt(&1 - x pow 2))) (atreal x)`,
4181   REPEAT STRIP_TAC THEN
4182   FIRST_ASSUM(MP_TAC o MATCH_MP HAS_REAL_DERIVATIVE_ACS_SIN) THEN
4183   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
4184   AP_TERM_TAC THEN AP_TERM_TAC THEN
4185   MATCH_MP_TAC SIN_ACS THEN ASM_REAL_ARITH_TAC);;
4186
4187 let REAL_DIFFERENTIABLE_AT_ACS = prove
4188  (`!x. abs(x) < &1 ==> acs real_differentiable (atreal x)`,
4189   REWRITE_TAC[real_differentiable] THEN
4190   MESON_TAC[HAS_REAL_DERIVATIVE_ACS]);;
4191
4192 let REAL_DIFFERENTIABLE_WITHIN_ACS = prove
4193  (`!s x. abs(x) < &1 ==> acs real_differentiable (atreal x within s)`,
4194   MESON_TAC[REAL_DIFFERENTIABLE_ATREAL_WITHIN;
4195             REAL_DIFFERENTIABLE_AT_ACS]);;
4196
4197 let REAL_CONTINUOUS_AT_ACS = prove
4198  (`!x. abs(x) < &1 ==> acs real_continuous (atreal x)`,
4199   MESON_TAC[HAS_REAL_DERIVATIVE_ACS;
4200             HAS_REAL_DERIVATIVE_IMP_CONTINUOUS_ATREAL]);;
4201
4202 let REAL_CONTINUOUS_WITHIN_ACS = prove
4203  (`!s x. abs(x) < &1 ==> acs real_continuous (atreal x within s)`,
4204   MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL;
4205             REAL_CONTINUOUS_AT_ACS]);;
4206
4207 (* ------------------------------------------------------------------------- *)
4208 (* Hence differentiation of the norm.                                        *)
4209 (* ------------------------------------------------------------------------- *)
4210
4211 let DIFFERENTIABLE_NORM_AT = prove
4212  (`!a:real^N. ~(a = vec 0) ==> (\x. lift(norm x)) differentiable (at a)`,
4213   REPEAT STRIP_TAC THEN REWRITE_TAC[vector_norm] THEN
4214   SUBGOAL_THEN
4215    `(\x:real^N. lift(sqrt(x dot x))) =
4216     (lift o sqrt o drop) o (\x. lift(x dot x))`
4217   SUBST1_TAC THENL [REWRITE_TAC[o_DEF; LIFT_DROP]; ALL_TAC] THEN
4218   MATCH_MP_TAC DIFFERENTIABLE_CHAIN_AT THEN
4219   REWRITE_TAC[DIFFERENTIABLE_SQNORM_AT; GSYM NORM_POW_2] THEN
4220   MP_TAC(ISPEC `norm(a:real^N) pow 2` REAL_DIFFERENTIABLE_AT_SQRT) THEN
4221   ASM_SIMP_TAC[REAL_POW_LT; NORM_POS_LT; REAL_DIFFERENTIABLE_AT]);;
4222
4223 let DIFFERENTIABLE_ON_NORM = prove
4224  (`!s:real^N->bool. ~(vec 0 IN s) ==> (\x. lift(norm x)) differentiable_on s`,
4225   REPEAT STRIP_TAC THEN
4226   MATCH_MP_TAC DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON THEN
4227   REPEAT STRIP_TAC THEN MATCH_MP_TAC DIFFERENTIABLE_NORM_AT THEN
4228   ASM_MESON_TAC[]);;
4229
4230 (* ------------------------------------------------------------------------- *)
4231 (* Some somewhat sharper continuity theorems including endpoints.            *)
4232 (* ------------------------------------------------------------------------- *)
4233
4234 let REAL_CONTINUOUS_WITHIN_SQRT_STRONG = prove
4235  (`!x. sqrt real_continuous (atreal x within {t | &0 <= t})`,
4236   GEN_TAC THEN REWRITE_TAC[REAL_COMPLEX_CONTINUOUS_WITHINREAL] THEN
4237   ASM_CASES_TAC `x IN {t | &0 <= t}` THENL
4238    [MATCH_MP_TAC CONTINUOUS_TRANSFORM_WITHIN THEN
4239     MAP_EVERY EXISTS_TAC [`csqrt`; `&1`] THEN
4240     REWRITE_TAC[IMAGE_CX; IN_ELIM_THM; REAL_LT_01;
4241       CONTINUOUS_WITHIN_CSQRT_POSREAL;
4242       SET_RULE `real INTER {z | real z /\ P z} = {z | real z /\ P z}`] THEN
4243     RULE_ASSUM_TAC(REWRITE_RULE[IN_ELIM_THM]) THEN
4244     ASM_REWRITE_TAC[REAL_CX; RE_CX; IMP_CONJ; FORALL_REAL; o_THM] THEN
4245     SIMP_TAC[CX_SQRT];
4246     MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN CONJ_TAC THENL
4247      [SUBGOAL_THEN `real INTER IMAGE Cx {t | &0 <= t} =
4248                     real INTER {t | Re t >= &0}`
4249        (fun th -> SIMP_TAC[th; CLOSED_INTER; CLOSED_REAL;
4250                            CLOSED_HALFSPACE_RE_GE]) THEN
4251      REWRITE_TAC[EXTENSION; IMAGE_CX; IN_ELIM_THM; IN_CBALL; IN_INTER] THEN
4252      REWRITE_TAC[real_ge; IN; CONJ_ACI];
4253       MATCH_MP_TAC(SET_RULE
4254        `(!x y. f x = f y ==> x = y) /\ ~(x IN s)
4255         ==> ~(f x IN t INTER IMAGE f s)`) THEN
4256       ASM_REWRITE_TAC[CX_INJ]]]);;
4257
4258 let REAL_CONTINUOUS_ON_SQRT = prove
4259  (`!s. (!x. x IN s ==> &0 <= x) ==> sqrt real_continuous_on s`,
4260   REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
4261   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_WITHINREAL_SUBSET THEN
4262   EXISTS_TAC `{x | &0 <= x}` THEN
4263   ASM_REWRITE_TAC[SUBSET; IN_ELIM_THM; REAL_CONTINUOUS_WITHIN_SQRT_STRONG]);;
4264
4265 let REAL_CONTINUOUS_WITHIN_ASN_STRONG = prove
4266  (`!x. asn real_continuous (atreal x within {t | abs(t) <= &1})`,
4267   GEN_TAC THEN REWRITE_TAC[REAL_COMPLEX_CONTINUOUS_WITHINREAL] THEN
4268   ASM_CASES_TAC `x IN {t | abs(t) <= &1}` THENL
4269    [MATCH_MP_TAC CONTINUOUS_TRANSFORM_WITHIN THEN
4270     MAP_EVERY EXISTS_TAC [`casn`; `&1`] THEN
4271     REWRITE_TAC[IMAGE_CX; IN_ELIM_THM; CONTINUOUS_WITHIN_CASN_REAL; REAL_LT_01;
4272      SET_RULE `real INTER {z | real z /\ P z} = {z | real z /\ P z}`] THEN
4273     RULE_ASSUM_TAC(REWRITE_RULE[IN_ELIM_THM]) THEN
4274     ASM_REWRITE_TAC[REAL_CX; RE_CX; IMP_CONJ; FORALL_REAL; o_THM] THEN
4275     SIMP_TAC[CX_ASN];
4276     MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN CONJ_TAC THENL
4277      [SUBGOAL_THEN `real INTER IMAGE Cx {t | abs t <= &1} =
4278                     real INTER cball(Cx(&0),&1)`
4279        (fun th -> SIMP_TAC[th; CLOSED_INTER; CLOSED_REAL; CLOSED_CBALL]) THEN
4280       REWRITE_TAC[EXTENSION; IMAGE_CX; IN_ELIM_THM; IN_CBALL; IN_INTER] THEN
4281       REWRITE_TAC[dist; COMPLEX_SUB_LZERO; NORM_NEG; IN] THEN
4282       MESON_TAC[REAL_NORM];
4283       MATCH_MP_TAC(SET_RULE
4284        `(!x y. f x = f y ==> x = y) /\ ~(x IN s)
4285         ==> ~(f x IN t INTER IMAGE f s)`) THEN
4286       ASM_REWRITE_TAC[CX_INJ]]]);;
4287
4288 let REAL_CONTINUOUS_ON_ASN = prove
4289  (`!s. (!x. x IN s ==> abs(x) <= &1) ==> asn real_continuous_on s`,
4290   REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
4291   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_WITHINREAL_SUBSET THEN
4292   EXISTS_TAC `{x | abs(x) <= &1}` THEN
4293   ASM_REWRITE_TAC[SUBSET; IN_ELIM_THM; REAL_CONTINUOUS_WITHIN_ASN_STRONG]);;
4294
4295 let REAL_CONTINUOUS_WITHIN_ACS_STRONG = prove
4296  (`!x. acs real_continuous (atreal x within {t | abs(t) <= &1})`,
4297   GEN_TAC THEN REWRITE_TAC[REAL_COMPLEX_CONTINUOUS_WITHINREAL] THEN
4298   ASM_CASES_TAC `x IN {t | abs(t) <= &1}` THENL
4299    [MATCH_MP_TAC CONTINUOUS_TRANSFORM_WITHIN THEN
4300     MAP_EVERY EXISTS_TAC [`cacs`; `&1`] THEN
4301     REWRITE_TAC[IMAGE_CX; IN_ELIM_THM; CONTINUOUS_WITHIN_CACS_REAL; REAL_LT_01;
4302      SET_RULE `real INTER {z | real z /\ P z} = {z | real z /\ P z}`] THEN
4303     RULE_ASSUM_TAC(REWRITE_RULE[IN_ELIM_THM]) THEN
4304     ASM_REWRITE_TAC[REAL_CX; RE_CX; IMP_CONJ; FORALL_REAL; o_THM] THEN
4305     SIMP_TAC[CX_ACS];
4306     MATCH_MP_TAC CONTINUOUS_WITHIN_CLOSED_NONTRIVIAL THEN CONJ_TAC THENL
4307      [SUBGOAL_THEN `real INTER IMAGE Cx {t | abs t <= &1} =
4308                     real INTER cball(Cx(&0),&1)`
4309        (fun th -> SIMP_TAC[th; CLOSED_INTER; CLOSED_REAL; CLOSED_CBALL]) THEN
4310       REWRITE_TAC[EXTENSION; IMAGE_CX; IN_ELIM_THM; IN_CBALL; IN_INTER] THEN
4311       REWRITE_TAC[dist; COMPLEX_SUB_LZERO; NORM_NEG; IN] THEN
4312       MESON_TAC[REAL_NORM];
4313       MATCH_MP_TAC(SET_RULE
4314        `(!x y. f x = f y ==> x = y) /\ ~(x IN s)
4315         ==> ~(f x IN t INTER IMAGE f s)`) THEN
4316       ASM_REWRITE_TAC[CX_INJ]]]);;
4317
4318 let REAL_CONTINUOUS_ON_ACS = prove
4319  (`!s. (!x. x IN s ==> abs(x) <= &1) ==> acs real_continuous_on s`,
4320   REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
4321   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_WITHINREAL_SUBSET THEN
4322   EXISTS_TAC `{x | abs(x) <= &1}` THEN
4323   ASM_REWRITE_TAC[SUBSET; IN_ELIM_THM; REAL_CONTINUOUS_WITHIN_ACS_STRONG]);;
4324
4325 (* ------------------------------------------------------------------------- *)
4326 (* Differentiation conversion.                                               *)
4327 (* ------------------------------------------------------------------------- *)
4328
4329 let real_differentiation_theorems = ref [];;
4330
4331 let add_real_differentiation_theorems =
4332   let ETA_THM = prove
4333    (`(f has_real_derivative f') net <=>
4334      ((\x. f x) has_real_derivative f') net`,
4335     REWRITE_TAC[ETA_AX]) in
4336   let ETA_TWEAK =
4337     PURE_REWRITE_RULE [IMP_CONJ] o
4338     GEN_REWRITE_RULE (LAND_CONV o ONCE_DEPTH_CONV) [ETA_THM] o
4339     SPEC_ALL in
4340   fun l -> real_differentiation_theorems :=
4341               !real_differentiation_theorems @ map ETA_TWEAK l;;
4342
4343 add_real_differentiation_theorems
4344  ([HAS_REAL_DERIVATIVE_LMUL_WITHIN; HAS_REAL_DERIVATIVE_LMUL_ATREAL;
4345    HAS_REAL_DERIVATIVE_RMUL_WITHIN; HAS_REAL_DERIVATIVE_RMUL_ATREAL;
4346    HAS_REAL_DERIVATIVE_CDIV_WITHIN; HAS_REAL_DERIVATIVE_CDIV_ATREAL;
4347    HAS_REAL_DERIVATIVE_ID;
4348    HAS_REAL_DERIVATIVE_CONST;
4349    HAS_REAL_DERIVATIVE_NEG;
4350    HAS_REAL_DERIVATIVE_ADD;
4351    HAS_REAL_DERIVATIVE_SUB;
4352    HAS_REAL_DERIVATIVE_MUL_WITHIN; HAS_REAL_DERIVATIVE_MUL_ATREAL;
4353    HAS_REAL_DERIVATIVE_DIV_WITHIN; HAS_REAL_DERIVATIVE_DIV_ATREAL;
4354    HAS_REAL_DERIVATIVE_POW_WITHIN; HAS_REAL_DERIVATIVE_POW_ATREAL;
4355    HAS_REAL_DERIVATIVE_INV_WITHIN; HAS_REAL_DERIVATIVE_INV_ATREAL] @
4356   (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4357     (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN_UNIV
4358               HAS_REAL_DERIVATIVE_EXP))) @
4359   (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4360     (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN_UNIV
4361               HAS_REAL_DERIVATIVE_SIN))) @
4362   (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4363     (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN_UNIV
4364               HAS_REAL_DERIVATIVE_COS))) @
4365   (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4366     (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN
4367               HAS_REAL_DERIVATIVE_TAN))) @
4368   (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4369     (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN
4370               HAS_REAL_DERIVATIVE_LOG))) @
4371   (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4372     (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN
4373               HAS_REAL_DERIVATIVE_SQRT))) @
4374   (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4375     (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN_UNIV
4376               HAS_REAL_DERIVATIVE_ATN))) @
4377   (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4378     (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN
4379               HAS_REAL_DERIVATIVE_ASN))) @
4380   (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4381     (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN
4382               HAS_REAL_DERIVATIVE_ACS))));;
4383
4384 let rec REAL_DIFF_CONV =
4385   let partfn tm = let l,r = dest_comb tm in mk_pair(lhand l,r)
4386   and is_deriv = can (term_match [] `(f has_real_derivative f') net`) in
4387   let rec REAL_DIFF_CONV tm =
4388     try tryfind (fun th -> PART_MATCH partfn th (partfn tm))
4389                 (!real_differentiation_theorems)
4390     with Failure _ ->
4391         let ith = tryfind (fun th ->
4392          PART_MATCH (partfn o repeat (snd o dest_imp)) th (partfn tm))
4393                     (!real_differentiation_theorems) in
4394         REAL_DIFF_ELIM ith
4395   and REAL_DIFF_ELIM th =
4396     let tm = concl th in
4397     if not(is_imp tm) then th else
4398     let t = lhand tm in
4399     if not(is_deriv t) then UNDISCH th
4400     else REAL_DIFF_ELIM (MATCH_MP th (REAL_DIFF_CONV t)) in
4401   REAL_DIFF_CONV;;
4402
4403 (* ------------------------------------------------------------------------- *)
4404 (* Hence a tactic.                                                           *)
4405 (* ------------------------------------------------------------------------- *)
4406
4407 let REAL_DIFF_TAC =
4408   let pth = MESON[]
4409    `(f has_real_derivative f') net
4410     ==> f' = g'
4411         ==> (f has_real_derivative g') net` in
4412   W(fun (asl,w) -> let th = MATCH_MP pth (REAL_DIFF_CONV w) in
4413        MATCH_MP_TAC(repeat (GEN_REWRITE_RULE I [IMP_IMP]) (DISCH_ALL th)));;
4414
4415 let REAL_DIFFERENTIABLE_TAC =
4416   let DISCH_FIRST th = DISCH (hd(hyp th)) th in
4417   GEN_REWRITE_TAC I [real_differentiable] THEN
4418   W(fun (asl,w) ->
4419         let th = REAL_DIFF_CONV(snd(dest_exists w)) in
4420         let f' = rand(rator(concl th)) in
4421         EXISTS_TAC f' THEN
4422         (if hyp th = [] then MATCH_ACCEPT_TAC th else
4423          let th' = repeat (GEN_REWRITE_RULE I [IMP_IMP] o DISCH_FIRST)
4424                           (DISCH_FIRST th) in
4425          MATCH_MP_TAC th'));;
4426
4427 (* ------------------------------------------------------------------------- *)
4428 (* Analytic results for real power function.                                 *)
4429 (* ------------------------------------------------------------------------- *)
4430
4431 let HAS_REAL_DERIVATIVE_RPOW = prove
4432  (`!x y.
4433     &0 < x
4434     ==> ((\x. x rpow y) has_real_derivative y * x rpow (y - &1)) (atreal x)`,
4435   REPEAT STRIP_TAC THEN
4436   MATCH_MP_TAC HAS_REAL_DERIVATIVE_TRANSFORM_ATREAL THEN
4437   EXISTS_TAC `\x. exp(y * log x)` THEN EXISTS_TAC `x:real` THEN
4438   ASM_SIMP_TAC[rpow; REAL_ARITH
4439     `&0 < x ==> (abs(y - x) < x <=> &0 < y /\ y < &2 * x)`] THEN
4440   REAL_DIFF_TAC THEN
4441   ASM_SIMP_TAC[REAL_SUB_RDISTRIB; REAL_EXP_SUB; REAL_MUL_LID; EXP_LOG] THEN
4442   REAL_ARITH_TAC);;
4443
4444 add_real_differentiation_theorems
4445  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4446    (GEN `y:real` (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN
4447     (SPEC `y:real`
4448       (ONCE_REWRITE_RULE[SWAP_FORALL_THM] HAS_REAL_DERIVATIVE_RPOW))))));;
4449
4450 let HAS_REAL_DERIVATIVE_RPOW_RIGHT = prove
4451  (`!a x. &0 < a
4452          ==> ((\x. a rpow x) has_real_derivative log(a) * a rpow x)
4453               (atreal x)`,
4454   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[rpow] THEN
4455   REAL_DIFF_TAC THEN REAL_ARITH_TAC);;
4456
4457 add_real_differentiation_theorems
4458 (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4459     (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN
4460               (SPEC `a:real` HAS_REAL_DERIVATIVE_RPOW_RIGHT))));;
4461
4462 let REAL_DIFFERENTIABLE_AT_RPOW = prove
4463  (`!x y. ~(x = &0) ==> (\x. x rpow y) real_differentiable atreal x`,
4464   REPEAT GEN_TAC THEN
4465   REWRITE_TAC[REAL_ARITH `~(x = &0) <=> &0 < x \/ &0 < --x`] THEN
4466   STRIP_TAC THEN MATCH_MP_TAC REAL_DIFFERENTIABLE_TRANSFORM_ATREAL THEN
4467   REWRITE_TAC[] THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
4468   EXISTS_TAC `abs x` THENL
4469    [EXISTS_TAC `\x. exp(y * log x)` THEN
4470     ASM_SIMP_TAC[REAL_ARITH `&0 < x ==> &0 < abs x`] THEN CONJ_TAC THENL
4471      [X_GEN_TAC `z:real` THEN DISCH_TAC THEN
4472       SUBGOAL_THEN `&0 < z` (fun th -> REWRITE_TAC[rpow; th]) THEN
4473       ASM_REAL_ARITH_TAC;
4474       REAL_DIFFERENTIABLE_TAC THEN ASM_REAL_ARITH_TAC];
4475     ASM_CASES_TAC `?m n. ODD m /\ ODD n /\ abs y = &m / &n` THENL
4476      [EXISTS_TAC `\x. --(exp(y * log(--x)))`;
4477       EXISTS_TAC `\x. exp(y * log(--x))`] THEN
4478     (ASM_SIMP_TAC[REAL_ARITH `&0 < --x ==> &0 < abs x`] THEN CONJ_TAC THENL
4479       [X_GEN_TAC `z:real` THEN DISCH_TAC THEN
4480        SUBGOAL_THEN `~(&0 < z) /\ ~(z = &0)`
4481          (fun th -> ASM_REWRITE_TAC[rpow; th]) THEN
4482        ASM_REAL_ARITH_TAC;
4483        REAL_DIFFERENTIABLE_TAC THEN ASM_REAL_ARITH_TAC])]);;
4484
4485 let REAL_CONTINUOUS_AT_RPOW = prove
4486  (`!x y. (x = &0 ==> &0 <= y)
4487          ==> (\x. x rpow y) real_continuous (atreal x)`,
4488   REPEAT GEN_TAC THEN ASM_CASES_TAC `y = &0` THEN
4489   ASM_REWRITE_TAC[RPOW_POW; real_pow; REAL_CONTINUOUS_CONST] THEN
4490   ASM_CASES_TAC `x = &0` THENL
4491    [ASM_REWRITE_TAC[real_continuous_atreal; RPOW_ZERO] THEN
4492     REWRITE_TAC[REAL_SUB_RZERO; REAL_ABS_RPOW] THEN STRIP_TAC THEN
4493     X_GEN_TAC `e:real` THEN DISCH_TAC THEN EXISTS_TAC `e rpow inv(y)` THEN
4494     ASM_SIMP_TAC[RPOW_POS_LT] THEN X_GEN_TAC `z:real` THEN DISCH_TAC THEN
4495     MATCH_MP_TAC REAL_LTE_TRANS THEN
4496     EXISTS_TAC `e rpow inv y rpow y` THEN CONJ_TAC THENL
4497      [MATCH_MP_TAC RPOW_LT2 THEN ASM_REAL_ARITH_TAC;
4498       ASM_SIMP_TAC[RPOW_RPOW; REAL_LT_IMP_LE; REAL_MUL_LINV] THEN
4499       REWRITE_TAC[RPOW_POW; REAL_POW_1; REAL_LE_REFL]];
4500     ASM_SIMP_TAC[REAL_DIFFERENTIABLE_IMP_CONTINUOUS_ATREAL;
4501                  REAL_DIFFERENTIABLE_AT_RPOW]]);;
4502
4503 let REAL_CONTINUOUS_WITHIN_RPOW = prove
4504  (`!s x y. (x = &0 ==> &0 <= y)
4505            ==> (\x. x rpow y) real_continuous (atreal x within s)`,
4506   MESON_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL;
4507             REAL_CONTINUOUS_AT_RPOW]);;
4508
4509 let REAL_CONTINUOUS_ON_RPOW = prove
4510  (`!s y. (&0 IN s ==> &0 <= y) ==> (\x. x rpow y) real_continuous_on s`,
4511   REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
4512   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONTINUOUS_WITHIN_RPOW THEN
4513   ASM_MESON_TAC[]);;
4514
4515 let REALLIM_RPOW = prove
4516  (`!net f l n.
4517         (f ---> l) net /\ (l = &0 ==> &0 <= n)
4518         ==> ((\x. f x rpow n) ---> l rpow n) net`,
4519   REPEAT STRIP_TAC THEN MATCH_MP_TAC
4520   (REWRITE_RULE[] (ISPEC `\x. x rpow n` REALLIM_REAL_CONTINUOUS_FUNCTION)) THEN
4521   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_CONTINUOUS_AT_RPOW THEN
4522   ASM_REWRITE_TAC[]);;
4523
4524 let REALLIM_NULL_POW_EQ = prove
4525  (`!net f n.
4526         ~(n = 0)
4527         ==> (((\x. f x pow n) ---> &0) net <=> (f ---> &0) net)`,
4528   REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[REALLIM_NULL_POW] THEN
4529   DISCH_THEN(MP_TAC o ISPEC `(\x. x rpow (inv(&n))) o abs` o
4530     MATCH_MP(REWRITE_RULE[IMP_CONJ_ALT] REALLIM_REAL_CONTINUOUS_FUNCTION)) THEN
4531   REWRITE_TAC[o_THM] THEN
4532   ASM_REWRITE_TAC[RPOW_ZERO; REAL_INV_EQ_0; REAL_OF_NUM_EQ; REAL_ABS_NUM] THEN
4533   SIMP_TAC[GSYM RPOW_POW; RPOW_RPOW; REAL_ABS_POS; REAL_ABS_RPOW] THEN
4534   ASM_SIMP_TAC[REAL_MUL_RINV; REAL_OF_NUM_EQ] THEN
4535   REWRITE_TAC[REALLIM_NULL_ABS; RPOW_POW; REAL_POW_1] THEN
4536   DISCH_THEN MATCH_MP_TAC THEN
4537   ONCE_REWRITE_TAC[GSYM WITHINREAL_UNIV] THEN
4538   MATCH_MP_TAC REAL_CONTINUOUS_WITHINREAL_COMPOSE THEN CONJ_TAC THENL
4539    [GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN
4540     MATCH_MP_TAC REAL_CONTINUOUS_ABS THEN
4541     REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID];
4542     MATCH_MP_TAC REAL_CONTINUOUS_WITHIN_RPOW THEN
4543     REWRITE_TAC[REAL_LE_INV_EQ; REAL_POS]]);;
4544
4545 let LIM_NULL_COMPLEX_POW_EQ = prove
4546  (`!net f n.
4547         ~(n = 0)
4548         ==> (((\x. f x pow n) --> Cx(&0)) net <=> (f --> Cx(&0)) net)`,
4549   REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM COMPLEX_VEC_0] THEN
4550   ONCE_REWRITE_TAC[LIM_NULL_NORM] THEN
4551   REWRITE_TAC[COMPLEX_NORM_POW; REAL_TENDSTO; o_DEF; LIFT_DROP] THEN
4552   ASM_SIMP_TAC[REALLIM_NULL_POW_EQ; DROP_VEC]);;
4553
4554 (* ------------------------------------------------------------------------- *)
4555 (* Analytic result for "frac".                                               *)
4556 (* ------------------------------------------------------------------------- *)
4557
4558 let HAS_REAL_DERIVATIVE_FRAC = prove
4559  (`!x. ~(integer x) ==> (frac has_real_derivative (&1)) (atreal x)`,
4560   REPEAT STRIP_TAC THEN
4561   MATCH_MP_TAC HAS_REAL_DERIVATIVE_TRANSFORM_ATREAL THEN
4562   EXISTS_TAC `\y. y - floor x` THEN
4563   EXISTS_TAC `min (frac x) (floor x + &1 - x)` THEN
4564   ASM_REWRITE_TAC[REAL_LT_MIN; REAL_FRAC_POS_LT] THEN
4565   REWRITE_TAC[REAL_ARITH `&0 < x + &1 - y <=> y < x + &1`; FLOOR] THEN
4566   CONJ_TAC THENL [ALL_TAC; REAL_DIFF_TAC THEN REAL_ARITH_TAC] THEN
4567   X_GEN_TAC `y:real` THEN DISCH_TAC THEN CONV_TAC SYM_CONV THEN
4568   REWRITE_TAC[GSYM FRAC_UNIQUE; REAL_ARITH `y - (y - x):real = x`] THEN
4569   MP_TAC(SPEC `x:real` FLOOR_FRAC) THEN SIMP_TAC[] THEN ASM_REAL_ARITH_TAC);;
4570
4571 let REAL_DIFFERENTIABLE_FRAC = prove
4572  (`!x. ~(integer x) ==> frac real_differentiable (atreal x)`,
4573   REWRITE_TAC[real_differentiable] THEN
4574   MESON_TAC[HAS_REAL_DERIVATIVE_FRAC]);;
4575
4576 add_real_differentiation_theorems
4577  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
4578   (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN HAS_REAL_DERIVATIVE_FRAC)));;
4579
4580 (* ------------------------------------------------------------------------- *)
4581 (* Polynomials are differentiable and continuous.                            *)
4582 (* ------------------------------------------------------------------------- *)
4583
4584 let REAL_DIFFERENTIABLE_POLYNOMIAL_FUNCTION_ATREAL = prove
4585  (`!p x. polynomial_function p ==> p real_differentiable atreal x`,
4586   REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
4587   MATCH_MP_TAC POLYNOMIAL_FUNCTION_INDUCT THEN
4588   SIMP_TAC[REAL_DIFFERENTIABLE_CONST; REAL_DIFFERENTIABLE_ID;
4589            REAL_DIFFERENTIABLE_ADD; REAL_DIFFERENTIABLE_MUL_ATREAL]);;
4590
4591 let REAL_DIFFERENTIABLE_POLYNOMIAL_FUNCTION_WITHIN = prove
4592  (`!p s x. polynomial_function p ==> p real_differentiable atreal x within s`,
4593   SIMP_TAC[REAL_DIFFERENTIABLE_POLYNOMIAL_FUNCTION_ATREAL;
4594            REAL_DIFFERENTIABLE_ATREAL_WITHIN]);;
4595
4596 let REAL_DIFFERENTIABLE_ON_POLYNOMIAL_FUNCTION = prove
4597  (`!p s. polynomial_function p ==> p real_differentiable_on s`,
4598   SIMP_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE;
4599            REAL_DIFFERENTIABLE_POLYNOMIAL_FUNCTION_WITHIN]);;
4600
4601 let REAL_CONTINUOUS_POLYNOMIAL_FUNCTION_ATREAL = prove
4602  (`!p x. polynomial_function p ==> p real_continuous atreal x`,
4603   SIMP_TAC[REAL_DIFFERENTIABLE_IMP_CONTINUOUS_ATREAL;
4604            REAL_DIFFERENTIABLE_POLYNOMIAL_FUNCTION_ATREAL]);;
4605
4606 let REAL_CONTINUOUS_POLYNOMIAL_FUNCTION_WITHIN = prove
4607  (`!p s x. polynomial_function p ==> p real_continuous atreal x within s`,
4608   SIMP_TAC[REAL_DIFFERENTIABLE_IMP_CONTINUOUS_WITHINREAL;
4609            REAL_DIFFERENTIABLE_POLYNOMIAL_FUNCTION_WITHIN]);;
4610
4611 let REAL_CONTINUOUS_ON_POLYNOMIAL_FUNCTION = prove
4612  (`!p s. polynomial_function p ==> p real_continuous_on s`,
4613   SIMP_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN;
4614            REAL_CONTINUOUS_POLYNOMIAL_FUNCTION_WITHIN]);;
4615
4616 (* ------------------------------------------------------------------------- *)
4617 (* Intermediate Value Theorem.                                               *)
4618 (* ------------------------------------------------------------------------- *)
4619
4620 let REAL_IVT_INCREASING = prove
4621  (`!f a b y.
4622         a <= b /\ f real_continuous_on real_interval[a,b] /\
4623         f a <= y /\ y <= f b
4624         ==> ?x. x IN real_interval [a,b] /\ f x = y`,
4625   REWRITE_TAC[REAL_CONTINUOUS_ON; IMAGE_LIFT_REAL_INTERVAL] THEN
4626   REPEAT STRIP_TAC THEN
4627   MP_TAC(ISPECL [`lift o f o drop`; `lift a`; `lift b`; `y:real`; `1`]
4628         IVT_INCREASING_COMPONENT_ON_1) THEN
4629   ASM_REWRITE_TAC[GSYM drop; o_THM; LIFT_DROP; DIMINDEX_1; LE_REFL] THEN
4630   REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; EXISTS_IN_IMAGE; LIFT_DROP]);;
4631
4632 let REAL_IVT_DECREASING = prove
4633  (`!f a b y.
4634         a <= b /\ f real_continuous_on real_interval[a,b] /\
4635         f b <= y /\ y <= f a
4636         ==> ?x. x IN real_interval [a,b] /\ f x = y`,
4637   REWRITE_TAC[REAL_CONTINUOUS_ON; IMAGE_LIFT_REAL_INTERVAL] THEN
4638   REPEAT STRIP_TAC THEN
4639   MP_TAC(ISPECL [`lift o f o drop`; `lift a`; `lift b`; `y:real`; `1`]
4640         IVT_DECREASING_COMPONENT_ON_1) THEN
4641   ASM_REWRITE_TAC[GSYM drop; o_THM; LIFT_DROP; DIMINDEX_1; LE_REFL] THEN
4642   REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; EXISTS_IN_IMAGE; LIFT_DROP]);;
4643
4644 let IS_REALINTERVAL_CONTINUOUS_IMAGE = prove
4645  (`!s. f real_continuous_on s /\ is_realinterval s
4646        ==> is_realinterval(IMAGE f s)`,
4647   GEN_TAC THEN REWRITE_TAC[REAL_CONTINUOUS_ON; IS_REALINTERVAL_CONNECTED] THEN
4648   DISCH_THEN(MP_TAC o MATCH_MP CONNECTED_CONTINUOUS_IMAGE) THEN
4649   REWRITE_TAC[IMAGE_o; REWRITE_RULE[IMAGE_o] IMAGE_LIFT_DROP]);;
4650
4651 (* ------------------------------------------------------------------------- *)
4652 (* Zeroness (or sign at boundary) of derivative at local extremum.           *)
4653 (* ------------------------------------------------------------------------- *)
4654
4655 let REAL_DERIVATIVE_POS_LEFT_MINIMUM = prove
4656  (`!f f' a b e.
4657         a < b /\ &0 < e /\
4658         (f has_real_derivative f') (atreal a within real_interval[a,b]) /\
4659         (!x. x IN real_interval[a,b] /\ abs(x - a) < e ==> f a <= f x)
4660         ==> &0 <= f'`,
4661   REPEAT STRIP_TAC THEN
4662   MP_TAC(ISPECL [`lift o f o drop`; `\x:real^1. f' % x`;
4663                  `lift a`; `interval[lift a,lift b]`; `e:real`]
4664         DROP_DIFFERENTIAL_POS_AT_MINIMUM) THEN
4665   ASM_REWRITE_TAC[ENDS_IN_INTERVAL; CONVEX_INTERVAL; IN_INTER; IMP_CONJ] THEN
4666   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY;
4667                   GSYM HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN
4668   ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; IN_BALL; DIST_LIFT;
4669                REAL_INTERVAL_NE_EMPTY; REAL_LT_IMP_LE] THEN
4670   ANTS_TAC THENL [ASM_MESON_TAC[REAL_ABS_SUB]; ALL_TAC] THEN
4671   DISCH_THEN(MP_TAC o SPEC `b:real`) THEN
4672   ASM_SIMP_TAC[ENDS_IN_REAL_INTERVAL; REAL_INTERVAL_NE_EMPTY;
4673                REAL_LT_IMP_LE] THEN
4674   ASM_SIMP_TAC[DROP_CMUL; DROP_SUB; LIFT_DROP; REAL_LE_MUL_EQ;
4675                REAL_SUB_LT]);;
4676
4677 let REAL_DERIVATIVE_NEG_LEFT_MAXIMUM = prove
4678  (`!f f' a b e.
4679         a < b /\ &0 < e /\
4680         (f has_real_derivative f') (atreal a within real_interval[a,b]) /\
4681         (!x. x IN real_interval[a,b] /\ abs(x - a) < e ==> f x <= f a)
4682         ==> f' <= &0`,
4683   REPEAT STRIP_TAC THEN
4684   MP_TAC(ISPECL [`lift o f o drop`; `\x:real^1. f' % x`;
4685                  `lift a`; `interval[lift a,lift b]`; `e:real`]
4686         DROP_DIFFERENTIAL_NEG_AT_MAXIMUM) THEN
4687   ASM_REWRITE_TAC[ENDS_IN_INTERVAL; CONVEX_INTERVAL; IN_INTER; IMP_CONJ] THEN
4688   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY;
4689                   GSYM HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN
4690   ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; IN_BALL; DIST_LIFT;
4691                REAL_INTERVAL_NE_EMPTY; REAL_LT_IMP_LE] THEN
4692   ANTS_TAC THENL [ASM_MESON_TAC[REAL_ABS_SUB]; ALL_TAC] THEN
4693   DISCH_THEN(MP_TAC o SPEC `b:real`) THEN
4694   ASM_SIMP_TAC[ENDS_IN_REAL_INTERVAL; REAL_INTERVAL_NE_EMPTY;
4695                REAL_LT_IMP_LE] THEN
4696   ASM_SIMP_TAC[DROP_CMUL; DROP_SUB; LIFT_DROP; REAL_LE_MUL_EQ;
4697                REAL_SUB_LT; REAL_ARITH `f * ba <= &0 <=> &0 <= --f * ba`] THEN
4698   REAL_ARITH_TAC);;
4699
4700 let REAL_DERIVATIVE_POS_RIGHT_MAXIMUM = prove
4701  (`!f f' a b e.
4702         a < b /\ &0 < e /\
4703         (f has_real_derivative f') (atreal b within real_interval[a,b]) /\
4704         (!x. x IN real_interval[a,b] /\ abs(x - b) < e ==> f x <= f b)
4705         ==> &0 <= f'`,
4706   REPEAT STRIP_TAC THEN
4707   MP_TAC(ISPECL [`lift o f o drop`; `\x:real^1. f' % x`;
4708                  `lift b`; `interval[lift a,lift b]`; `e:real`]
4709         DROP_DIFFERENTIAL_NEG_AT_MAXIMUM) THEN
4710   ASM_REWRITE_TAC[ENDS_IN_INTERVAL; CONVEX_INTERVAL; IN_INTER; IMP_CONJ] THEN
4711   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY;
4712                   GSYM HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN
4713   ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; IN_BALL; DIST_LIFT;
4714                REAL_INTERVAL_NE_EMPTY; REAL_LT_IMP_LE] THEN
4715   ANTS_TAC THENL [ASM_MESON_TAC[REAL_ABS_SUB]; ALL_TAC] THEN
4716   DISCH_THEN(MP_TAC o SPEC `a:real`) THEN
4717   ASM_SIMP_TAC[ENDS_IN_REAL_INTERVAL; REAL_INTERVAL_NE_EMPTY;
4718                REAL_LT_IMP_LE] THEN
4719   ASM_SIMP_TAC[DROP_CMUL; DROP_SUB; LIFT_DROP; REAL_LE_MUL_EQ; REAL_SUB_LT;
4720                REAL_ARITH `f * (a - b) <= &0 <=> &0 <= f * (b - a)`]);;
4721
4722 let REAL_DERIVATIVE_NEG_RIGHT_MINIMUM = prove
4723  (`!f f' a b e.
4724         a < b /\ &0 < e /\
4725         (f has_real_derivative f') (atreal b within real_interval[a,b]) /\
4726         (!x. x IN real_interval[a,b] /\ abs(x - b) < e ==> f b <= f x)
4727         ==> f' <= &0`,
4728   REPEAT STRIP_TAC THEN
4729   MP_TAC(ISPECL [`lift o f o drop`; `\x:real^1. f' % x`;
4730                  `lift b`; `interval[lift a,lift b]`; `e:real`]
4731         DROP_DIFFERENTIAL_POS_AT_MINIMUM) THEN
4732   ASM_REWRITE_TAC[ENDS_IN_INTERVAL; CONVEX_INTERVAL; IN_INTER; IMP_CONJ] THEN
4733   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY;
4734                   GSYM HAS_REAL_FRECHET_DERIVATIVE_WITHIN] THEN
4735   ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; IN_BALL; DIST_LIFT;
4736                REAL_INTERVAL_NE_EMPTY; REAL_LT_IMP_LE] THEN
4737   ANTS_TAC THENL [ASM_MESON_TAC[REAL_ABS_SUB]; ALL_TAC] THEN
4738   DISCH_THEN(MP_TAC o SPEC `a:real`) THEN
4739   ASM_SIMP_TAC[ENDS_IN_REAL_INTERVAL; REAL_INTERVAL_NE_EMPTY;
4740                REAL_LT_IMP_LE] THEN
4741   ASM_SIMP_TAC[DROP_CMUL; DROP_SUB; LIFT_DROP] THEN
4742   ONCE_REWRITE_TAC[REAL_ARITH `&0 <= f * (a - b) <=> &0 <= --f * (b - a)`] THEN
4743   ASM_SIMP_TAC[REAL_LE_MUL_EQ; REAL_SUB_LT] THEN REAL_ARITH_TAC);;
4744
4745 let REAL_DERIVATIVE_ZERO_MAXMIN = prove
4746  (`!f f' x s.
4747         x IN s /\ real_open s /\
4748         (f has_real_derivative f') (atreal x) /\
4749         ((!y. y IN s ==> f y <= f x) \/ (!y. y IN s ==> f x <= f y))
4750         ==> f' = &0`,
4751   REPEAT STRIP_TAC THEN
4752   MP_TAC(ISPECL [`lift o f o drop`; `\x:real^1. f' % x`;
4753                  `lift x`; `IMAGE lift s`]
4754         DIFFERENTIAL_ZERO_MAXMIN) THEN
4755   ASM_REWRITE_TAC[GSYM HAS_REAL_FRECHET_DERIVATIVE_AT; GSYM REAL_OPEN] THEN
4756   ASM_SIMP_TAC[FUN_IN_IMAGE; FORALL_IN_IMAGE] THEN
4757   ASM_REWRITE_TAC[o_DEF; LIFT_DROP] THEN
4758   DISCH_THEN(MP_TAC o C AP_THM `vec 1:real^1`) THEN
4759   REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_VEC; REAL_MUL_RID]);;
4760
4761 (* ------------------------------------------------------------------------- *)
4762 (* Rolle and Mean Value Theorem.                                             *)
4763 (* ------------------------------------------------------------------------- *)
4764
4765 let REAL_ROLLE = prove
4766  (`!f f' a b.
4767         a < b /\ f a = f b /\
4768         f real_continuous_on real_interval[a,b] /\
4769         (!x. x IN real_interval(a,b)
4770              ==> (f has_real_derivative f'(x)) (atreal x))
4771         ==> ?x. x IN real_interval(a,b) /\ f'(x) = &0`,
4772   REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN
4773   REWRITE_TAC[REAL_CONTINUOUS_ON; HAS_REAL_VECTOR_DERIVATIVE_AT] THEN
4774   REWRITE_TAC[GSYM IMAGE_o; IMAGE_LIFT_DROP; has_vector_derivative] THEN
4775   REWRITE_TAC[LIFT_DROP] THEN REPEAT STRIP_TAC THEN
4776   MP_TAC(ISPECL [`lift o f o drop`; `\x:real^1 h:real^1. f'(drop x) % h`;
4777                  `lift a`; `lift b`] ROLLE) THEN
4778   ASM_REWRITE_TAC[o_THM; LIFT_DROP] THEN ANTS_TAC THENL
4779    [X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN
4780     FIRST_X_ASSUM(MP_TAC o SPEC `t:real^1`) THEN
4781     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN
4782     AP_THM_TAC THEN AP_TERM_TAC THEN
4783     REWRITE_TAC[FUN_EQ_THM; FORALL_LIFT; LIFT_DROP; GSYM LIFT_CMUL] THEN
4784     REWRITE_TAC[REAL_MUL_AC];
4785     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real^1` THEN
4786     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4787     FIRST_X_ASSUM(MP_TAC o C AP_THM `lift(&1)`) THEN
4788     REWRITE_TAC[GSYM LIFT_CMUL; GSYM LIFT_NUM; LIFT_EQ; REAL_MUL_RID]]);;
4789
4790 let REAL_MVT = prove
4791  (`!f f' a b.
4792         a < b /\
4793         f real_continuous_on real_interval[a,b] /\
4794         (!x. x IN real_interval(a,b)
4795              ==> (f has_real_derivative f'(x)) (atreal x))
4796         ==> ?x. x IN real_interval(a,b) /\ f(b) - f(a) = f'(x) * (b - a)`,
4797   REPEAT STRIP_TAC THEN
4798   MP_TAC(SPECL [`\x:real. f(x) - (f b - f a) / (b - a) * x`;
4799                 `(\x. f'(x) - (f b - f a) / (b - a)):real->real`;
4800                  `a:real`; `b:real`]
4801                REAL_ROLLE) THEN
4802   ASM_SIMP_TAC[REAL_FIELD
4803    `a < b ==> (fx - fba / (b - a) = &0 <=> fba = fx * (b - a))`] THEN
4804   DISCH_THEN MATCH_MP_TAC THEN
4805   ASM_SIMP_TAC[REAL_CONTINUOUS_ON_SUB; REAL_CONTINUOUS_ON_LMUL;
4806                REAL_CONTINUOUS_ON_ID] THEN
4807   CONJ_TAC THENL [UNDISCH_TAC `a < b` THEN CONV_TAC REAL_FIELD; ALL_TAC] THEN
4808   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUB THEN
4809   ASM_SIMP_TAC[] THEN GEN_REWRITE_TAC LAND_CONV [GSYM REAL_MUL_RID] THEN
4810   ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_LMUL_ATREAL; HAS_REAL_DERIVATIVE_ID]);;
4811
4812 let REAL_MVT_SIMPLE = prove
4813  (`!f f' a b.
4814         a < b /\
4815         (!x. x IN real_interval[a,b]
4816              ==> (f has_real_derivative f'(x))
4817                  (atreal x within real_interval[a,b]))
4818         ==> ?x. x IN real_interval(a,b) /\ f(b) - f(a) = f'(x) * (b - a)`,
4819   MP_TAC REAL_MVT THEN
4820   REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
4821   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
4822   CONJ_TAC THENL
4823    [MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON THEN
4824     ASM_MESON_TAC[real_differentiable_on; real_differentiable];
4825     ASM_MESON_TAC[HAS_REAL_DERIVATIVE_WITHIN_REAL_OPEN; REAL_OPEN_REAL_INTERVAL;
4826                   REAL_INTERVAL_OPEN_SUBSET_CLOSED;
4827                   HAS_REAL_DERIVATIVE_WITHIN_SUBSET; SUBSET]]);;
4828
4829 let REAL_MVT_VERY_SIMPLE = prove
4830  (`!f f' a b.
4831         a <= b /\
4832         (!x. x IN real_interval[a,b]
4833              ==> (f has_real_derivative f'(x))
4834                  (atreal x within real_interval[a,b]))
4835         ==> ?x. x IN real_interval[a,b] /\ f(b) - f(a) = f'(x) * (b - a)`,
4836   REPEAT GEN_TAC THEN ASM_CASES_TAC `b:real = a` THENL
4837    [ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_MUL_RZERO] THEN
4838     REWRITE_TAC[REAL_INTERVAL_SING; IN_SING; EXISTS_REFL];
4839     ASM_REWRITE_TAC[REAL_LE_LT] THEN
4840     DISCH_THEN(MP_TAC o MATCH_MP REAL_MVT_SIMPLE) THEN
4841     MATCH_MP_TAC MONO_EXISTS THEN
4842     SIMP_TAC[REWRITE_RULE[SUBSET] REAL_INTERVAL_OPEN_SUBSET_CLOSED]]);;
4843
4844 let REAL_ROLLE_SIMPLE = prove
4845  (`!f f' a b.
4846         a < b /\ f a = f b /\
4847         (!x. x IN real_interval[a,b]
4848              ==> (f has_real_derivative f'(x))
4849                  (atreal x within real_interval[a,b]))
4850         ==> ?x. x IN real_interval(a,b) /\ f'(x) = &0`,
4851   MP_TAC REAL_MVT_SIMPLE THEN
4852   REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
4853   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
4854   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN MATCH_MP_TAC MONO_AND THEN
4855   REWRITE_TAC[REAL_RING `a - a = b * (c - d) <=> b = &0 \/ c = d`] THEN
4856   ASM_MESON_TAC[REAL_LT_REFL]);;
4857
4858 (* ------------------------------------------------------------------------- *)
4859 (* Cauchy MVT and l'Hospital's rule.                                         *)
4860 (* ------------------------------------------------------------------------- *)
4861
4862 let REAL_MVT_CAUCHY = prove
4863  (`!f g f' g' a b.
4864            a < b /\
4865            f real_continuous_on real_interval[a,b] /\
4866            g real_continuous_on real_interval[a,b] /\
4867            (!x. x IN real_interval(a,b)
4868                 ==> (f has_real_derivative f' x) (atreal x) /\
4869                     (g has_real_derivative g' x) (atreal x))
4870            ==> ?x. x IN real_interval(a,b) /\
4871                    (f b - f a) * g'(x) = (g b - g a) * f'(x)`,
4872   REPEAT STRIP_TAC THEN MP_TAC(SPECL
4873    [`\x. (f:real->real)(x) * (g(b:real) - g(a)) - g(x) * (f(b) - f(a))`;
4874     `\x. (f':real->real)(x) * (g(b:real) - g(a)) - g'(x) * (f(b) - f(a))`;
4875     `a:real`; `b:real`] REAL_MVT) THEN
4876   ASM_SIMP_TAC[REAL_CONTINUOUS_ON_SUB; REAL_CONTINUOUS_ON_RMUL;
4877                HAS_REAL_DERIVATIVE_SUB; HAS_REAL_DERIVATIVE_RMUL_ATREAL] THEN
4878   MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN
4879   UNDISCH_TAC `a < b` THEN CONV_TAC REAL_FIELD);;
4880
4881 let LHOSPITAL = prove
4882  (`!f g f' g' c l d.
4883         &0 < d /\
4884         (!x. &0 < abs(x - c) /\ abs(x - c) < d
4885              ==> (f has_real_derivative f'(x)) (atreal x) /\
4886                  (g has_real_derivative g'(x)) (atreal x) /\
4887                  ~(g'(x) = &0)) /\
4888         (f ---> &0) (atreal c) /\ (g ---> &0) (atreal c) /\
4889         ((\x. f'(x) / g'(x)) ---> l) (atreal c)
4890         ==> ((\x. f(x) / g(x)) ---> l) (atreal c)`,
4891   SUBGOAL_THEN
4892     `!f g f' g' c l d.
4893         &0 < d /\
4894         (!x. &0 < abs(x - c) /\ abs(x - c) < d
4895              ==> (f has_real_derivative f'(x)) (atreal x) /\
4896                  (g has_real_derivative g'(x)) (atreal x) /\
4897                  ~(g'(x) = &0)) /\
4898         f(c) = &0 /\ g(c) = &0 /\
4899         (f ---> &0) (atreal c) /\ (g ---> &0) (atreal c) /\
4900         ((\x. f'(x) / g'(x)) ---> l) (atreal c)
4901         ==> ((\x. f(x) / g(x)) ---> l) (atreal c)`
4902   ASSUME_TAC THENL
4903    [REWRITE_TAC[TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN
4904     REWRITE_TAC[FORALL_AND_THM] THEN REPEAT STRIP_TAC THEN
4905     SUBGOAL_THEN
4906      `(!x. abs(x - c) < d ==> f real_continuous atreal x) /\
4907       (!x. abs(x - c) < d ==> g real_continuous atreal x)`
4908     STRIP_ASSUME_TAC THENL
4909      [REWRITE_TAC[AND_FORALL_THM] THEN X_GEN_TAC `x:real` THEN
4910       DISJ_CASES_TAC(REAL_ARITH `x = c \/ &0 < abs(x - c)`) THENL
4911        [ASM_REWRITE_TAC[REAL_CONTINUOUS_ATREAL]; ALL_TAC] THEN
4912       REPEAT STRIP_TAC THEN
4913       MATCH_MP_TAC REAL_DIFFERENTIABLE_IMP_CONTINUOUS_ATREAL THEN
4914       REWRITE_TAC[real_differentiable] THEN ASM_MESON_TAC[];
4915       ALL_TAC] THEN
4916     SUBGOAL_THEN
4917      `!x.  &0 < abs(x - c) /\ abs(x - c) < d ==> ~(g x = &0)`
4918     STRIP_ASSUME_TAC THENL
4919      [REPEAT STRIP_TAC THEN
4920       SUBGOAL_THEN `c < x \/ x < c` DISJ_CASES_TAC THENL
4921        [ASM_REAL_ARITH_TAC;
4922         MP_TAC(ISPECL [`g:real->real`; `g':real->real`; `c:real`; `x:real`]
4923           REAL_ROLLE);
4924         MP_TAC(ISPECL [`g:real->real`; `g':real->real`; `x:real`; `c:real`]
4925           REAL_ROLLE)] THEN
4926       ASM_REWRITE_TAC[NOT_IMP; NOT_EXISTS_THM] THEN
4927       (REPEAT CONJ_TAC THENL
4928         [REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
4929          REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN
4930          MATCH_MP_TAC REAL_CONTINUOUS_ATREAL_WITHINREAL;
4931          REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC;
4932          X_GEN_TAC `y:real` THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN
4933          DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
4934          REWRITE_TAC[]] THEN
4935        FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC);
4936       ALL_TAC] THEN
4937     UNDISCH_TAC `((\x. f' x / g' x) ---> l) (atreal c)` THEN
4938     REWRITE_TAC[REALLIM_ATREAL] THEN MATCH_MP_TAC MONO_FORALL THEN
4939     X_GEN_TAC `e:real` THEN ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
4940     DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
4941     EXISTS_TAC `min d k:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
4942     X_GEN_TAC `x:real` THEN STRIP_TAC THEN
4943     SUBGOAL_THEN
4944      `?y. &0 < abs(y - c) /\ abs(y - c) < abs(x - c) /\
4945           (f:real->real) x / g x = f' y / g' y`
4946     STRIP_ASSUME_TAC THENL
4947      [ALL_TAC; ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[REAL_LT_TRANS]] THEN
4948     SUBGOAL_THEN `c < x \/ x < c` DISJ_CASES_TAC THENL
4949      [ASM_REAL_ARITH_TAC;
4950       MP_TAC(ISPECL
4951        [`f:real->real`; `g:real->real`; `f':real->real`; `g':real->real`;
4952         `c:real`; `x:real`] REAL_MVT_CAUCHY);
4953       MP_TAC(ISPECL
4954        [`f:real->real`; `g:real->real`; `f':real->real`; `g':real->real`;
4955         `x:real`; `c:real`] REAL_MVT_CAUCHY)] THEN
4956     (ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN ANTS_TAC THENL
4957       [REWRITE_TAC[CONJ_ASSOC] THEN CONJ_TAC THENL
4958         [CONJ_TAC THEN
4959          REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
4960          REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN
4961          MATCH_MP_TAC REAL_CONTINUOUS_ATREAL_WITHINREAL;
4962          REPEAT STRIP_TAC] THEN
4963        FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC;
4964        MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[REAL_SUB_RZERO] THEN
4965        GEN_TAC THEN STRIP_TAC THEN
4966         REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
4967        MATCH_MP_TAC(REAL_FIELD
4968         `f * g' = g * f' /\ ~(g = &0) /\ ~(g' = &0) ==> f / g = f' / g'`) THEN
4969        CONJ_TAC THENL [ASM_REAL_ARITH_TAC; CONJ_TAC] THEN
4970        FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC]);
4971     REPEAT GEN_TAC THEN
4972     FIRST_X_ASSUM(MP_TAC o SPECL
4973      [`\x:real. if x = c then &0 else f(x)`;
4974                 `\x:real. if x = c then &0 else g(x)`;
4975                 `f':real->real`; `g':real->real`;
4976                 `c:real`; `l:real`; `d:real`]) THEN
4977     REWRITE_TAC[] THEN MATCH_MP_TAC MONO_IMP THEN CONJ_TAC THEN
4978     REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THEN
4979     TRY(SIMP_TAC[REALLIM_ATREAL;REAL_ARITH `&0 < abs(x - c) ==> ~(x = c)`] THEN
4980         NO_TAC) THEN
4981     DISCH_TAC THEN X_GEN_TAC `x:real` THEN STRIP_TAC THEN
4982     FIRST_X_ASSUM(MP_TAC o SPEC `x:real`) THEN ASM_REWRITE_TAC[] THEN
4983     REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THEN REWRITE_TAC[] THEN
4984     MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
4985           HAS_REAL_DERIVATIVE_TRANSFORM_ATREAL) THEN
4986     EXISTS_TAC `abs(x - c)` THEN ASM_REAL_ARITH_TAC]);;
4987
4988 (* ------------------------------------------------------------------------- *)
4989 (* Darboux's theorem (intermediate value property for derivatives).          *)
4990 (* ------------------------------------------------------------------------- *)
4991
4992 let REAL_DERIVATIVE_IVT_INCREASING = prove
4993  (`!f f' a b.
4994    a <= b /\
4995    (!x. x IN real_interval[a,b]
4996         ==> (f has_real_derivative f'(x)) (atreal x within real_interval[a,b]))
4997    ==> !t. f'(a) <= t /\ t <= f'(b)
4998            ==> ?x. x IN real_interval[a,b] /\ f' x = t`,
4999   REPEAT GEN_TAC THEN STRIP_TAC THEN GEN_TAC THEN
5000   ASM_CASES_TAC `(f':real->real) a = t` THENL
5001    [ASM_MESON_TAC[ENDS_IN_REAL_INTERVAL; REAL_INTERVAL_NE_EMPTY];
5002     ALL_TAC] THEN
5003   ASM_CASES_TAC `(f':real->real) b = t` THENL
5004    [ASM_MESON_TAC[ENDS_IN_REAL_INTERVAL; REAL_INTERVAL_NE_EMPTY];
5005     ALL_TAC] THEN
5006   ASM_CASES_TAC `b:real = a` THEN ASM_REWRITE_TAC[REAL_LE_ANTISYM] THEN
5007   SUBGOAL_THEN `a < b` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
5008   ASM_REWRITE_TAC[REAL_LE_LT] THEN STRIP_TAC THEN
5009   MP_TAC(ISPECL [`\x:real. f x - t * x`; `real_interval[a,b]`]
5010         REAL_CONTINUOUS_ATTAINS_INF) THEN
5011   ASM_REWRITE_TAC[REAL_INTERVAL_NE_EMPTY; REAL_COMPACT_INTERVAL] THEN
5012   ANTS_TAC THENL
5013    [MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON THEN
5014     MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_SUB THEN
5015     SIMP_TAC[REAL_DIFFERENTIABLE_ON_MUL; REAL_DIFFERENTIABLE_ON_ID;
5016              REAL_DIFFERENTIABLE_ON_CONST] THEN
5017     ASM_MESON_TAC[real_differentiable_on];
5018     ALL_TAC] THEN
5019   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real` THEN
5020   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
5021   MP_TAC(SPECL
5022    [`\x:real. f x - t * x`; `(f':real->real) x - t:real`;
5023     `x:real`; `real_interval(a,b)`]
5024         REAL_DERIVATIVE_ZERO_MAXMIN) THEN
5025   ASM_REWRITE_TAC[REAL_SUB_0] THEN DISCH_THEN MATCH_MP_TAC THEN
5026   REWRITE_TAC[REAL_OPEN_REAL_INTERVAL] THEN
5027   ASM_SIMP_TAC[REAL_OPEN_CLOSED_INTERVAL; IN_DIFF] THEN
5028   ASM_CASES_TAC `x:real = a` THENL
5029    [FIRST_X_ASSUM SUBST_ALL_TAC THEN
5030     MP_TAC(ISPECL[`\x:real. f x - t * x`; `(f':real->real) a - t:real`;
5031                   `a:real`; `b:real`; `&1`]
5032         REAL_DERIVATIVE_POS_LEFT_MINIMUM) THEN
5033     ASM_SIMP_TAC[REAL_LT_01; REAL_SUB_LE] THEN
5034     MATCH_MP_TAC(TAUT `~q /\ p ==> (p ==> q) ==> r`) THEN
5035     ASM_REWRITE_TAC[REAL_NOT_LE] THEN
5036     MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUB THEN
5037     CONJ_TAC THENL [ALL_TAC; REAL_DIFF_TAC THEN REWRITE_TAC[REAL_MUL_RID]] THEN
5038     FIRST_X_ASSUM MATCH_MP_TAC THEN
5039     ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY];
5040     ALL_TAC] THEN
5041   ASM_CASES_TAC `x:real = b` THENL
5042    [FIRST_X_ASSUM SUBST_ALL_TAC THEN
5043     MP_TAC(ISPECL[`\x:real. f x - t * x`; `(f':real->real) b - t:real`;
5044                   `a:real`; `b:real`; `&1`]
5045         REAL_DERIVATIVE_NEG_RIGHT_MINIMUM) THEN
5046     ASM_SIMP_TAC[REAL_LT_01; REAL_SUB_LE] THEN
5047     MATCH_MP_TAC(TAUT `~q /\ p ==> (p ==> q) ==> r`) THEN
5048     ASM_REWRITE_TAC[REAL_NOT_LE; REAL_SUB_LT] THEN
5049     MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUB THEN
5050     CONJ_TAC THENL [ALL_TAC; REAL_DIFF_TAC THEN REWRITE_TAC[REAL_MUL_RID]] THEN
5051     FIRST_X_ASSUM MATCH_MP_TAC THEN
5052     ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY];
5053     ALL_TAC] THEN
5054   ASM_REWRITE_TAC[IN_INSERT; NOT_IN_EMPTY] THEN
5055   MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUB THEN
5056   CONJ_TAC THENL [ALL_TAC; REAL_DIFF_TAC THEN REWRITE_TAC[REAL_MUL_RID]] THEN
5057   SUBGOAL_THEN
5058    `(f has_real_derivative f' x) (atreal x within real_interval(a,b))`
5059   MP_TAC THENL
5060    [MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN
5061     EXISTS_TAC `real_interval[a,b]` THEN
5062     ASM_SIMP_TAC[REAL_INTERVAL_OPEN_SUBSET_CLOSED];
5063     MATCH_MP_TAC EQ_IMP THEN
5064     MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_REAL_OPEN THEN
5065     REWRITE_TAC[REAL_OPEN_REAL_INTERVAL] THEN
5066     ASM_REWRITE_TAC[REAL_OPEN_CLOSED_INTERVAL] THEN ASM SET_TAC[]]);;
5067
5068 let REAL_DERIVATIVE_IVT_DECREASING = prove
5069  (`!f f' a b t.
5070    a <= b /\
5071    (!x. x IN real_interval[a,b]
5072         ==> (f has_real_derivative f'(x)) (atreal x within real_interval[a,b]))
5073    ==> !t. f'(b) <= t /\ t <= f'(a)
5074            ==> ?x. x IN real_interval[a,b] /\ f' x = t`,
5075   REPEAT STRIP_TAC THEN MP_TAC(SPECL
5076    [`\x. --((f:real->real) x)`; `\x. --((f':real->real) x)`;
5077     `a:real`; `b:real`] REAL_DERIVATIVE_IVT_INCREASING) THEN
5078   ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_NEG] THEN
5079   DISCH_THEN(MP_TAC o SPEC `--t:real`) THEN
5080   ASM_REWRITE_TAC[REAL_LE_NEG2; REAL_EQ_NEG2]);;
5081
5082 (* ------------------------------------------------------------------------- *)
5083 (* Continuity and differentiability of inverse functions.                    *)
5084 (* ------------------------------------------------------------------------- *)
5085
5086 let HAS_REAL_DERIVATIVE_INVERSE_BASIC = prove
5087  (`!f g f' t y.
5088         (f has_real_derivative f') (atreal (g y)) /\
5089         ~(f' = &0) /\
5090         g real_continuous atreal y /\
5091         real_open t /\
5092         y IN t /\
5093         (!z. z IN t ==> f (g z) = z)
5094         ==> (g has_real_derivative inv(f')) (atreal y)`,
5095   REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_AT; REAL_OPEN;
5096               REAL_CONTINUOUS_CONTINUOUS_ATREAL] THEN
5097   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_INVERSE_BASIC THEN
5098   MAP_EVERY EXISTS_TAC
5099    [`lift o f o drop`; `\x:real^1. f' % x`; `IMAGE lift t`] THEN
5100   ASM_REWRITE_TAC[o_THM; LIFT_DROP; LIFT_IN_IMAGE_LIFT] THEN
5101   ASM_SIMP_TAC[FORALL_IN_IMAGE; LIFT_DROP; LINEAR_COMPOSE_CMUL; LINEAR_ID] THEN
5102   REWRITE_TAC[FUN_EQ_THM; I_THM; o_THM; VECTOR_MUL_ASSOC] THEN
5103   ASM_SIMP_TAC[REAL_MUL_LINV; VECTOR_MUL_LID]);;
5104
5105 let HAS_REAL_DERIVATIVE_INVERSE_STRONG = prove
5106  (`!f g f' s x.
5107          real_open s /\
5108          x IN s /\
5109          f real_continuous_on s /\
5110          (!x. x IN s ==> g (f x) = x) /\
5111          (f has_real_derivative f') (atreal x) /\
5112          ~(f' = &0)
5113          ==> (g has_real_derivative inv(f')) (atreal (f x))`,
5114   REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_AT; REAL_OPEN;
5115               REAL_CONTINUOUS_ON] THEN
5116   REPEAT STRIP_TAC THEN
5117   MP_TAC(ISPEC `lift o f o drop` HAS_DERIVATIVE_INVERSE_STRONG) THEN
5118   REWRITE_TAC[FORALL_LIFT; o_THM; LIFT_DROP] THEN
5119   DISCH_THEN MATCH_MP_TAC THEN
5120   MAP_EVERY EXISTS_TAC [`\x:real^1. f' % x`; `IMAGE lift s`] THEN
5121   ASM_REWRITE_TAC[o_THM; LIFT_DROP; LIFT_IN_IMAGE_LIFT] THEN
5122   ASM_SIMP_TAC[FUN_EQ_THM; I_THM; o_THM; VECTOR_MUL_ASSOC] THEN
5123   ASM_SIMP_TAC[REAL_MUL_RINV; VECTOR_MUL_LID]);;
5124
5125 let HAS_REAL_DERIVATIVE_INVERSE_STRONG_X = prove
5126  (`!f g f' s y.
5127         real_open s /\ (g y) IN s /\ f real_continuous_on s /\
5128         (!x. x IN s ==> (g(f(x)) = x)) /\
5129         (f has_real_derivative f') (atreal (g y)) /\ ~(f' = &0) /\
5130         f(g y) = y
5131         ==> (g has_real_derivative inv(f')) (atreal y)`,
5132   REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_AT; REAL_OPEN;
5133               REAL_CONTINUOUS_ON] THEN
5134   REPEAT STRIP_TAC THEN
5135   MP_TAC(ISPEC `lift o f o drop` HAS_DERIVATIVE_INVERSE_STRONG_X) THEN
5136   REWRITE_TAC[FORALL_LIFT; o_THM; LIFT_DROP] THEN
5137   DISCH_THEN MATCH_MP_TAC THEN
5138   MAP_EVERY EXISTS_TAC [`\x:real^1. f' % x`; `IMAGE lift s`] THEN
5139   ASM_REWRITE_TAC[o_THM; LIFT_DROP; LIFT_IN_IMAGE_LIFT] THEN
5140   ASM_SIMP_TAC[FUN_EQ_THM; I_THM; o_THM; VECTOR_MUL_ASSOC] THEN
5141   ASM_SIMP_TAC[REAL_MUL_RINV; VECTOR_MUL_LID]);;
5142
5143 (* ------------------------------------------------------------------------- *)
5144 (* Real differentiation of sequences and series.                             *)
5145 (* ------------------------------------------------------------------------- *)
5146
5147 let HAS_REAL_DERIVATIVE_SEQUENCE = prove
5148  (`!s f f' g'.
5149          is_realinterval s /\
5150          (!n x. x IN s
5151                 ==> (f n has_real_derivative f' n x) (atreal x within s)) /\
5152          (!e. &0 < e
5153               ==> ?N. !n x. n >= N /\ x IN s ==> abs(f' n x - g' x) <= e) /\
5154          (?x l. x IN s /\ ((\n. f n x) ---> l) sequentially)
5155          ==> ?g. !x. x IN s
5156                      ==> ((\n. f n x) ---> g x) sequentially /\
5157                          (g has_real_derivative g' x) (atreal x within s)`,
5158   REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN; IS_REALINTERVAL_CONVEX;
5159               TENDSTO_REAL] THEN REPEAT STRIP_TAC THEN
5160   MP_TAC(ISPECL [`IMAGE lift s`;
5161                  `\n:num. lift o f n o drop`;
5162                  `\n:num x:real^1 h:real^1. f' n (drop x) % h`;
5163                  `\x:real^1 h:real^1. g' (drop x) % h`]
5164          HAS_DERIVATIVE_SEQUENCE) THEN
5165   ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP] THEN ANTS_TAC THENL
5166    [REWRITE_TAC[IMP_CONJ; RIGHT_EXISTS_AND_THM; RIGHT_FORALL_IMP_THM;
5167                 EXISTS_IN_IMAGE; FORALL_IN_IMAGE] THEN
5168     REWRITE_TAC[EXISTS_LIFT; o_THM; LIFT_DROP] THEN
5169     RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN
5170     CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
5171     REWRITE_TAC[GSYM VECTOR_SUB_RDISTRIB; NORM_MUL] THEN
5172     ASM_MESON_TAC[REAL_LE_RMUL; NORM_POS_LE];
5173     REWRITE_TAC[o_DEF; LIFT_DROP] THEN
5174     DISCH_THEN(X_CHOOSE_TAC `g:real^1->real^1`) THEN
5175     EXISTS_TAC `drop o g o lift` THEN
5176     RULE_ASSUM_TAC(REWRITE_RULE[ETA_AX]) THEN
5177     ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]]);;
5178
5179 let HAS_REAL_DERIVATIVE_SERIES = prove
5180  (`!s f f' g' k.
5181          is_realinterval s /\
5182          (!n x. x IN s
5183                 ==> (f n has_real_derivative f' n x) (atreal x within s)) /\
5184          (!e. &0 < e
5185               ==> ?N. !n x. n >= N /\ x IN s
5186                             ==> abs(sum (k INTER (0..n)) (\i. f' i x) - g' x)
5187                                     <= e) /\
5188          (?x l. x IN s /\ ((\n. f n x) real_sums l) k)
5189          ==> ?g. !x. x IN s
5190                      ==> ((\n. f n x) real_sums g x) k /\
5191                          (g has_real_derivative g' x) (atreal x within s)`,
5192   REPEAT GEN_TAC THEN REWRITE_TAC[real_sums] THEN
5193   DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
5194   MATCH_MP_TAC HAS_REAL_DERIVATIVE_SEQUENCE THEN EXISTS_TAC
5195    `\n:num x:real. sum(k INTER (0..n)) (\n. f' n x):real` THEN
5196   ASM_SIMP_TAC[ETA_AX; FINITE_INTER_NUMSEG; HAS_REAL_DERIVATIVE_SUM]);;
5197
5198 let REAL_DIFFERENTIABLE_BOUND = prove
5199  (`!f f' s B.
5200         is_realinterval s /\
5201         (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s) /\
5202                         abs(f' x) <= B)
5203         ==> !x y. x IN s /\ y IN s ==> abs(f x - f y) <= B * abs(x - y)`,
5204   REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN; IS_REALINTERVAL_CONVEX;
5205               o_DEF] THEN REPEAT STRIP_TAC THEN
5206   MP_TAC(ISPECL
5207    [`lift o f o drop`; `\x h:real^1. f' (drop x) % h`;
5208     `IMAGE lift s`; `B:real`]
5209         DIFFERENTIABLE_BOUND) THEN
5210   ASM_SIMP_TAC[o_DEF; FORALL_IN_IMAGE; LIFT_DROP] THEN ANTS_TAC THENL
5211    [X_GEN_TAC `v:real` THEN DISCH_TAC THEN
5212     MP_TAC(ISPEC `\h:real^1. f' (v:real) % h` ONORM) THEN
5213     SIMP_TAC[LINEAR_COMPOSE_CMUL; LINEAR_ID] THEN
5214     DISCH_THEN(MATCH_MP_TAC o CONJUNCT2) THEN
5215     ASM_SIMP_TAC[NORM_MUL; REAL_LE_RMUL; NORM_POS_LE];
5216     SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE; LIFT_DROP] THEN
5217     ASM_SIMP_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM LIFT_SUB; NORM_LIFT]]);;
5218
5219 let REAL_TAYLOR_MVT_POS = prove
5220  (`!f a x n.
5221     a < x /\
5222     (!i t. t IN real_interval[a,x] /\ i <= n
5223            ==> ((f i) has_real_derivative f (i + 1) t)
5224                (atreal t within real_interval[a,x]))
5225     ==> ?t. t IN real_interval(a,x) /\
5226             f 0 x =
5227               sum (0..n) (\i. f i a * (x - a) pow i / &(FACT i)) +
5228               f (n + 1) t * (x - a) pow (n + 1) / &(FACT(n + 1))`,
5229   REPEAT STRIP_TAC THEN
5230   SUBGOAL_THEN
5231    `?B. sum (0..n) (\i. f i a * (x - a) pow i / &(FACT i)) +
5232         B * (x - a) pow (n + 1) = f 0 x`
5233   STRIP_ASSUME_TAC THENL
5234    [MATCH_MP_TAC(MESON[]
5235      `a + (y - a) / x * x:real = y ==> ?b. a + b * x = y`) THEN
5236     MATCH_MP_TAC(REAL_FIELD `~(x = &0) ==> a + (y - a) / x * x = y`) THEN
5237     ASM_REWRITE_TAC[REAL_POW_EQ_0; REAL_SUB_0] THEN ASM_REAL_ARITH_TAC;
5238     ALL_TAC] THEN
5239   MP_TAC(SPECL [`\t. sum(0..n) (\i. f i t * (x - t) pow i / &(FACT i)) +
5240                      B * (x - t) pow (n + 1)`;
5241                 `\t. (f (n + 1) t * (x - t) pow n / &(FACT n)) -
5242                      B * &(n + 1) * (x - t) pow n`;
5243                 `a:real`; `x:real`]
5244         REAL_ROLLE_SIMPLE) THEN
5245   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
5246    [CONJ_TAC THENL
5247      [SIMP_TAC[SUM_CLAUSES_LEFT; LE_0] THEN
5248       REWRITE_TAC[GSYM ADD1; real_pow; REAL_SUB_REFL; REAL_POW_ZERO;
5249                   REAL_MUL_LZERO; REAL_MUL_RZERO; REAL_ADD_RID] THEN
5250       CONV_TAC NUM_REDUCE_CONV THEN
5251       REWRITE_TAC[NOT_SUC; REAL_MUL_RZERO; REAL_DIV_1; REAL_MUL_RID] THEN
5252       REWRITE_TAC[REAL_ARITH `x = (x + y) + &0 <=> y = &0`] THEN
5253       MATCH_MP_TAC SUM_EQ_0_NUMSEG THEN
5254       SIMP_TAC[ARITH; ARITH_RULE `1 <= i ==> ~(i = 0)`] THEN
5255       REWRITE_TAC[real_div; REAL_MUL_LZERO; REAL_MUL_RZERO];
5256       ALL_TAC] THEN
5257     X_GEN_TAC `t:real` THEN DISCH_TAC THEN REWRITE_TAC[real_sub] THEN
5258     MATCH_MP_TAC HAS_REAL_DERIVATIVE_ADD THEN CONJ_TAC THENL
5259      [ALL_TAC;
5260       REAL_DIFF_TAC THEN REWRITE_TAC[ADD_SUB] THEN CONV_TAC REAL_RING] THEN
5261     REWRITE_TAC[GSYM real_sub] THEN
5262     MATCH_MP_TAC(MESON[]
5263      `!g'. f' = g' /\ (f has_real_derivative g') net
5264            ==> (f has_real_derivative f') net`) THEN
5265     EXISTS_TAC
5266      `sum (0..n) (\i. f i t * --(&i * (x - t) pow (i - 1)) / &(FACT i) +
5267                                 f (i + 1) t * (x - t) pow i / &(FACT i))` THEN
5268     REWRITE_TAC[] THEN CONJ_TAC THENL
5269      [ALL_TAC;
5270       MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUM THEN
5271       REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
5272       X_GEN_TAC `m:num` THEN STRIP_TAC THEN
5273       MATCH_MP_TAC HAS_REAL_DERIVATIVE_MUL_WITHIN THEN
5274       ASM_SIMP_TAC[ETA_AX] THEN REAL_DIFF_TAC THEN REAL_ARITH_TAC] THEN
5275     SIMP_TAC[SUM_CLAUSES_LEFT; LE_0; ARITH; FACT; REAL_DIV_1;
5276              real_pow; REAL_MUL_LZERO; REAL_NEG_0; REAL_MUL_RZERO;
5277              REAL_MUL_RID; REAL_ADD_LID] THEN
5278     ASM_CASES_TAC `n = 0` THENL
5279      [ASM_REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH; FACT] THEN REAL_ARITH_TAC;
5280       ALL_TAC] THEN
5281     ASM_SIMP_TAC[SPECL [`f:num->real`; `1`] SUM_OFFSET_0; LE_1] THEN
5282     REWRITE_TAC[ADD_SUB] THEN
5283     REWRITE_TAC[GSYM ADD1; FACT; GSYM REAL_OF_NUM_MUL; GSYM REAL_OF_NUM_ADD;
5284                 GSYM REAL_OF_NUM_SUC] THEN
5285     REWRITE_TAC[real_div; REAL_INV_MUL] THEN
5286     REWRITE_TAC[REAL_ARITH `--(n * x) * (inv n * inv y):real =
5287                             --(n / n) * x / y`] THEN
5288     REWRITE_TAC[REAL_FIELD `--((&n + &1) / (&n + &1)) * x = --x`] THEN
5289     REWRITE_TAC[GSYM REAL_INV_MUL; REAL_OF_NUM_MUL; REAL_OF_NUM_SUC] THEN
5290     REWRITE_TAC[GSYM(CONJUNCT2 FACT)] THEN
5291     REWRITE_TAC[REAL_ARITH `a * --b + c:real = c - a * b`] THEN
5292     REWRITE_TAC[ADD1; GSYM real_div; SUM_DIFFS_ALT; LE_0] THEN
5293     ASM_SIMP_TAC[ARITH_RULE `~(n = 0) ==> n - 1 + 1 = n`; FACT] THEN
5294     REWRITE_TAC[ADD_CLAUSES] THEN REAL_ARITH_TAC;
5295     ALL_TAC] THEN
5296   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `t:real` THEN STRIP_TAC THEN
5297   ASM_REWRITE_TAC[] THEN
5298   FIRST_X_ASSUM(fun th -> GEN_REWRITE_TAC LAND_CONV [GSYM th]) THEN
5299   REWRITE_TAC[REAL_EQ_ADD_LCANCEL] THEN
5300   REWRITE_TAC[REAL_ARITH `a * b / c:real = a / c * b`] THEN
5301   AP_THM_TAC THEN AP_TERM_TAC THEN
5302   FIRST_X_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH
5303    `a * x / f - B * k * x = &0 ==> (B * k - a / f) * x = &0`)) THEN
5304   REWRITE_TAC[REAL_ENTIRE; REAL_POW_EQ_0; REAL_SUB_0] THEN
5305   ASM_CASES_TAC `x:real = t` THENL
5306    [ASM_MESON_TAC[IN_REAL_INTERVAL; REAL_LT_REFL]; ALL_TAC] THEN
5307   ASM_REWRITE_TAC[GSYM ADD1; FACT] THEN
5308   REWRITE_TAC[GSYM REAL_OF_NUM_MUL; GSYM REAL_OF_NUM_ADD; ADD1] THEN
5309   SUBGOAL_THEN `~(&(FACT n) = &0)` MP_TAC THENL
5310    [REWRITE_TAC[REAL_OF_NUM_EQ; FACT_NZ]; CONV_TAC REAL_FIELD]);;
5311
5312 let REAL_TAYLOR_MVT_NEG = prove
5313  (`!f a x n.
5314     x < a /\
5315     (!i t. t IN real_interval[x,a] /\ i <= n
5316            ==> ((f i) has_real_derivative f (i + 1) t)
5317                (atreal t within real_interval[x,a]))
5318     ==> ?t. t IN real_interval(x,a) /\
5319             f 0 x =
5320               sum (0..n) (\i. f i a * (x - a) pow i / &(FACT i)) +
5321               f (n + 1) t * (x - a) pow (n + 1) / &(FACT(n + 1))`,
5322   REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN
5323   ONCE_REWRITE_TAC[MESON[REAL_NEG_NEG] `(?x:real. P x) <=> (?x. P(--x))`] THEN
5324   MP_TAC(SPECL [`\n x. (-- &1) pow n * (f:num->real->real) n (--x)`;
5325                 `--a:real`; `  --x:real`; `n:num`]
5326         REAL_TAYLOR_MVT_POS) THEN
5327   REWRITE_TAC[REAL_NEG_NEG] THEN
5328   ONCE_REWRITE_TAC[REAL_ARITH `(x * y) * z / w:real = y * (x * z) / w`] THEN
5329   REWRITE_TAC[GSYM REAL_POW_MUL] THEN
5330   REWRITE_TAC[REAL_ARITH `-- &1 * (--x - --a) = x - a`] THEN
5331   REWRITE_TAC[IN_REAL_INTERVAL; real_pow; REAL_MUL_LID] THEN
5332   REWRITE_TAC[REAL_ARITH `--a < t /\ t < --x <=> x < --t /\ --t < a`] THEN
5333   DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[REAL_LT_NEG2] THEN
5334   MAP_EVERY X_GEN_TAC [`m:num`; `t:real`] THEN STRIP_TAC THEN
5335   REWRITE_TAC[REAL_POW_ADD; GSYM REAL_MUL_ASSOC] THEN
5336   MATCH_MP_TAC HAS_REAL_DERIVATIVE_LMUL_WITHIN THEN
5337   ONCE_REWRITE_TAC[REAL_ARITH `y pow 1 * x:real = x * y`] THEN
5338   ONCE_REWRITE_TAC[GSYM o_DEF] THEN
5339   MATCH_MP_TAC REAL_DIFF_CHAIN_WITHIN THEN CONJ_TAC THENL
5340    [GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
5341     REAL_DIFF_TAC THEN REFL_TAC;
5342     ALL_TAC] THEN
5343   SUBGOAL_THEN `IMAGE (--) (real_interval[--a,--x]) = real_interval[x,a]`
5344   SUBST1_TAC THENL
5345    [REWRITE_TAC[EXTENSION; IN_IMAGE; IN_REAL_INTERVAL] THEN
5346     REWRITE_TAC[REAL_ARITH `x:real = --y <=> --x = y`; UNWIND_THM1] THEN
5347     REAL_ARITH_TAC;
5348     FIRST_X_ASSUM MATCH_MP_TAC THEN
5349     ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]);;
5350
5351 let REAL_TAYLOR = prove
5352  (`!f n s B.
5353     is_realinterval s /\
5354     (!i x. x IN s /\ i <= n
5355            ==> ((f i) has_real_derivative f (i + 1) x) (atreal x within s)) /\
5356     (!x. x IN s ==> abs(f (n + 1) x) <= B)
5357     ==> !w z. w IN s /\ z IN s
5358               ==> abs(f 0 z -
5359                       sum (0..n) (\i. f i w * (z - w) pow i / &(FACT i)))
5360                   <= B * abs(z - w) pow (n + 1) / &(FACT(n + 1))`,
5361   REPEAT STRIP_TAC THEN
5362   REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC
5363    (REAL_ARITH `w = z \/ w < z \/ z < w`)
5364   THENL
5365    [ASM_SIMP_TAC[SUM_CLAUSES_LEFT; LE_0; REAL_SUB_REFL; REAL_POW_ZERO;
5366                  REAL_ABS_0; ARITH; ADD_EQ_0; real_div] THEN
5367     REWRITE_TAC[REAL_MUL_LZERO; FACT; REAL_INV_1; REAL_MUL_RZERO] THEN
5368     MATCH_MP_TAC(REAL_ARITH `y = &0 ==> abs(x - (x * &1 * &1 + y)) <= &0`) THEN
5369     MATCH_MP_TAC SUM_EQ_0_NUMSEG THEN
5370     SIMP_TAC[ARITH; LE_1; REAL_MUL_RZERO; REAL_MUL_LZERO];
5371     MP_TAC(ISPECL [`f:num->real->real`; `w:real`; `z:real`; `n:num`]
5372                   REAL_TAYLOR_MVT_POS) THEN
5373     ASM_REWRITE_TAC[] THEN
5374     SUBGOAL_THEN `real_interval[w,z] SUBSET s` ASSUME_TAC THENL
5375      [SIMP_TAC[SUBSET; IN_REAL_INTERVAL] THEN ASM_MESON_TAC[is_realinterval];
5376       ALL_TAC];
5377     MP_TAC(ISPECL [`f:num->real->real`; `w:real`; `z:real`; `n:num`]
5378                   REAL_TAYLOR_MVT_NEG) THEN
5379     ASM_REWRITE_TAC[] THEN
5380     SUBGOAL_THEN `real_interval[z,w] SUBSET s` ASSUME_TAC THENL
5381      [SIMP_TAC[SUBSET; IN_REAL_INTERVAL] THEN ASM_MESON_TAC[is_realinterval];
5382       ALL_TAC]] THEN
5383  (ANTS_TAC THENL
5384    [MAP_EVERY X_GEN_TAC [`m:num`; `t:real`] THEN STRIP_TAC THEN
5385     MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN
5386     EXISTS_TAC `s:real->bool` THEN ASM_REWRITE_TAC[] THEN
5387     FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[SUBSET];
5388     ALL_TAC] THEN
5389   DISCH_THEN(X_CHOOSE_THEN `t:real`
5390    (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN
5391   REWRITE_TAC[REAL_ADD_SUB; REAL_ABS_MUL; REAL_ABS_DIV] THEN
5392   REWRITE_TAC[REAL_ABS_POW; REAL_ABS_NUM] THEN
5393   MATCH_MP_TAC REAL_LE_RMUL THEN
5394   SIMP_TAC[REAL_LE_DIV; REAL_POS; REAL_POW_LE; REAL_ABS_POS] THEN
5395   ASM_MESON_TAC[REAL_INTERVAL_OPEN_SUBSET_CLOSED; SUBSET]));;
5396
5397 (* ------------------------------------------------------------------------- *)
5398 (* Comparing sums and "integrals" via real antiderivatives.                  *)
5399 (* ------------------------------------------------------------------------- *)
5400
5401 let REAL_SUM_INTEGRAL_UBOUND_INCREASING = prove
5402  (`!f g m n.
5403       m <= n /\
5404       (!x. x IN real_interval[&m,&n + &1]
5405            ==> (g has_real_derivative f(x))
5406                (atreal x within real_interval[&m,&n + &1])) /\
5407       (!x y. &m <= x /\ x <= y /\ y <= &n + &1 ==> f x <= f y)
5408       ==> sum(m..n) (\k. f(&k)) <= g(&n + &1) - g(&m)`,
5409   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
5410   EXISTS_TAC `sum(m..n) (\k. g(&(k + 1)) - g(&k))` THEN CONJ_TAC THENL
5411    [ALL_TAC; ASM_SIMP_TAC[SUM_DIFFS_ALT; REAL_OF_NUM_ADD; REAL_LE_REFL]] THEN
5412   MATCH_MP_TAC SUM_LE_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
5413   MP_TAC(ISPECL [`g:real->real`; `f:real->real`; `&k`; `&(k + 1)`]
5414                 REAL_MVT_SIMPLE) THEN
5415   ASM_REWRITE_TAC[REAL_OF_NUM_LT; ARITH_RULE `k < k + 1`] THEN
5416   ASM_REWRITE_TAC[GSYM REAL_OF_NUM_ADD; REAL_ADD_SUB] THEN ANTS_TAC THENL
5417    [REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN
5418     EXISTS_TAC `real_interval[&m,&n + &1]` THEN CONJ_TAC THENL
5419      [FIRST_X_ASSUM MATCH_MP_TAC THEN
5420       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_REAL_INTERVAL]);
5421       REWRITE_TAC[SUBSET] THEN GEN_TAC] THEN
5422     REWRITE_TAC[IN_REAL_INTERVAL] THEN
5423     RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN ASM_REAL_ARITH_TAC;
5424     DISCH_THEN(X_CHOOSE_THEN `t:real`
5425      (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN
5426     REWRITE_TAC[REAL_MUL_RID] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
5427     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_REAL_INTERVAL]) THEN
5428     RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN
5429     ASM_REAL_ARITH_TAC]);;
5430
5431 let REAL_SUM_INTEGRAL_UBOUND_DECREASING = prove
5432  (`!f g m n.
5433       m <= n /\
5434       (!x. x IN real_interval[&m - &1,&n]
5435            ==> (g has_real_derivative f(x))
5436                (atreal x within real_interval[&m - &1,&n])) /\
5437       (!x y. &m - &1 <= x /\ x <= y /\ y <= &n ==> f y <= f x)
5438       ==> sum(m..n) (\k. f(&k)) <= g(&n) - g(&m - &1)`,
5439   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
5440   EXISTS_TAC `sum(m..n) (\k. g(&(k + 1) - &1) - g(&k - &1))` THEN
5441   CONJ_TAC THENL
5442    [ALL_TAC;
5443     ASM_REWRITE_TAC[SUM_DIFFS_ALT] THEN
5444     ASM_REWRITE_TAC[GSYM REAL_OF_NUM_ADD; REAL_ARITH `(x + &1) - &1 = x`] THEN
5445     REWRITE_TAC[REAL_LE_REFL]] THEN
5446   MATCH_MP_TAC SUM_LE_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
5447   MP_TAC(ISPECL [`g:real->real`; `f:real->real`; `&k - &1`; `&k`]
5448                 REAL_MVT_SIMPLE) THEN
5449   ASM_REWRITE_TAC[REAL_ARITH `k - &1 < k`] THEN ANTS_TAC THENL
5450    [REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN
5451     EXISTS_TAC `real_interval[&m - &1,&n]` THEN CONJ_TAC THENL
5452      [FIRST_X_ASSUM MATCH_MP_TAC THEN
5453       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_REAL_INTERVAL]);
5454       REWRITE_TAC[SUBSET] THEN GEN_TAC] THEN
5455     REWRITE_TAC[IN_REAL_INTERVAL] THEN
5456     RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN ASM_REAL_ARITH_TAC;
5457     REWRITE_TAC[GSYM REAL_OF_NUM_ADD; REAL_ARITH `(a + &1) - &1 = a`] THEN
5458     DISCH_THEN(X_CHOOSE_THEN `t:real`
5459      (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC)) THEN
5460     REWRITE_TAC[REAL_ARITH `a * (x - (x - &1)) = a`] THEN
5461     FIRST_X_ASSUM MATCH_MP_TAC THEN
5462     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_REAL_INTERVAL]) THEN
5463     RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN
5464     ASM_REAL_ARITH_TAC]);;
5465
5466 let REAL_SUM_INTEGRAL_LBOUND_INCREASING = prove
5467  (`!f g m n.
5468       m <= n /\
5469       (!x. x IN real_interval[&m - &1,&n]
5470            ==> (g has_real_derivative f(x))
5471                (atreal x within real_interval[&m - &1,&n])) /\
5472       (!x y. &m - &1 <= x /\ x <= y /\ y <= &n ==> f x <= f y)
5473       ==> g(&n) - g(&m - &1) <= sum(m..n) (\k. f(&k))`,
5474   REPEAT STRIP_TAC THEN
5475   MP_TAC(ISPECL [`\z. --((f:real->real) z)`;
5476                  `\z. --((g:real->real) z)`;
5477                  `m:num`; `n:num`] REAL_SUM_INTEGRAL_UBOUND_DECREASING) THEN
5478   REWRITE_TAC[RE_NEG; RE_SUB; SUM_NEG; REAL_LE_NEG2;
5479               REAL_ARITH `--x - --y:real = --(x - y)`] THEN
5480   ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_NEG]);;
5481
5482 let REAL_SUM_INTEGRAL_LBOUND_DECREASING = prove
5483  (`!f g m n.
5484       m <= n /\
5485       (!x. x IN real_interval[&m,&n + &1]
5486            ==> (g has_real_derivative f(x))
5487                (atreal x within  real_interval[&m,&n + &1])) /\
5488       (!x y. &m <= x /\ x <= y /\ y <= &n + &1 ==> f y <= f x)
5489       ==> g(&n + &1) - g(&m) <= sum(m..n) (\k. f(&k))`,
5490   REPEAT STRIP_TAC THEN
5491   MP_TAC(ISPECL [`\z. --((f:real->real) z)`;
5492                  `\z. --((g:real->real) z)`;
5493                  `m:num`; `n:num`] REAL_SUM_INTEGRAL_UBOUND_INCREASING) THEN
5494   REWRITE_TAC[RE_NEG; RE_SUB; SUM_NEG; REAL_LE_NEG2;
5495               REAL_ARITH `--x - --y:real = --(x - y)`] THEN
5496   ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_NEG]);;
5497
5498 let REAL_SUM_INTEGRAL_BOUNDS_INCREASING = prove
5499  (`!f g m n.
5500          m <= n /\
5501          (!x. x IN real_interval[&m - &1,&n + &1]
5502               ==> (g has_real_derivative f x)
5503                   (atreal x within real_interval[&m - &1,&n + &1])) /\
5504          (!x y. &m - &1 <= x /\ x <= y /\ y <= &n + &1 ==> f x <= f y)
5505          ==> g(&n) - g(&m - &1) <= sum(m..n) (\k. f(&k)) /\
5506              sum (m..n) (\k. f(&k)) <= g(&n + &1) - g(&m)`,
5507   REPEAT STRIP_TAC THENL
5508    [MATCH_MP_TAC REAL_SUM_INTEGRAL_LBOUND_INCREASING;
5509     MATCH_MP_TAC REAL_SUM_INTEGRAL_UBOUND_INCREASING] THEN
5510   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
5511   TRY(MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN
5512       EXISTS_TAC `real_interval[&m - &1,&n + &1]` THEN CONJ_TAC) THEN
5513   TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN
5514   TRY(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_REAL_INTERVAL])) THEN
5515   REWRITE_TAC[SUBSET; IN_REAL_INTERVAL] THEN
5516   RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN ASM_REAL_ARITH_TAC);;
5517
5518 let REAL_SUM_INTEGRAL_BOUNDS_DECREASING = prove
5519  (`!f g m n.
5520       m <= n /\
5521       (!x. x IN real_interval[&m - &1,&n + &1]
5522            ==> (g has_real_derivative f(x))
5523                (atreal x within real_interval[&m - &1,&n + &1])) /\
5524       (!x y. &m - &1 <= x /\ x <= y /\ y <= &n + &1 ==> f y <= f x)
5525       ==> g(&n + &1) - g(&m) <= sum(m..n) (\k. f(&k)) /\
5526           sum(m..n) (\k. f(&k)) <= g(&n) - g(&m - &1)`,
5527   REPEAT STRIP_TAC THENL
5528    [MATCH_MP_TAC REAL_SUM_INTEGRAL_LBOUND_DECREASING;
5529     MATCH_MP_TAC REAL_SUM_INTEGRAL_UBOUND_DECREASING] THEN
5530   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
5531   TRY(MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN
5532       EXISTS_TAC `real_interval[&m - &1,&n + &1]` THEN CONJ_TAC) THEN
5533   TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN
5534   TRY(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_REAL_INTERVAL])) THEN
5535   REWRITE_TAC[SUBSET; IN_REAL_INTERVAL] THEN
5536   RULE_ASSUM_TAC(REWRITE_RULE[GSYM REAL_OF_NUM_LE]) THEN ASM_REAL_ARITH_TAC);;
5537
5538 (* ------------------------------------------------------------------------- *)
5539 (* Relating different kinds of real limits.                                  *)
5540 (* ------------------------------------------------------------------------- *)
5541
5542 let REALLIM_POSINFINITY_SEQUENTIALLY = prove
5543  (`!f l. (f ---> l) at_posinfinity ==> ((\n. f(&n)) ---> l) sequentially`,
5544   REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN
5545   DISCH_THEN(MP_TAC o MATCH_MP LIM_POSINFINITY_SEQUENTIALLY) THEN
5546   REWRITE_TAC[o_DEF]);;
5547
5548 let LIM_ZERO_POSINFINITY = prove
5549  (`!f l. ((\x. f(&1 / x)) --> l) (atreal (&0)) ==> (f --> l) at_posinfinity`,
5550   REPEAT GEN_TAC THEN REWRITE_TAC[LIM_ATREAL; LIM_AT_POSINFINITY] THEN
5551   DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5552   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
5553   REWRITE_TAC[dist; REAL_SUB_RZERO; real_ge] THEN
5554   DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
5555   EXISTS_TAC `&2 / d` THEN X_GEN_TAC `z:real` THEN DISCH_TAC THEN
5556   FIRST_X_ASSUM(MP_TAC o SPEC `inv(z):real`) THEN
5557   REWRITE_TAC[real_div; REAL_MUL_LINV; REAL_INV_INV] THEN
5558   REWRITE_TAC[REAL_MUL_LID] THEN DISCH_THEN MATCH_MP_TAC THEN
5559   ASM_REWRITE_TAC[REAL_ABS_INV; REAL_LT_INV_EQ] THEN CONJ_TAC THENL
5560    [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
5561      `a <= z ==> &0 < a ==> &0 < abs z`));
5562     GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_INV] THEN
5563     MATCH_MP_TAC REAL_LT_INV2 THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN
5564     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
5565      `&2 / d <= z ==> &0 < &2 / d ==> inv d < abs z`))] THEN
5566   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH]);;
5567
5568 let LIM_ZERO_NEGINFINITY = prove
5569  (`!f l. ((\x. f(&1 / x)) --> l) (atreal (&0)) ==> (f --> l) at_neginfinity`,
5570   REPEAT GEN_TAC THEN REWRITE_TAC[LIM_ATREAL; LIM_AT_NEGINFINITY] THEN
5571   DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5572   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
5573   REWRITE_TAC[dist; REAL_SUB_RZERO; real_ge] THEN
5574   DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
5575   EXISTS_TAC `--(&2 / d)` THEN X_GEN_TAC `z:real` THEN DISCH_TAC THEN
5576   FIRST_X_ASSUM(MP_TAC o SPEC `inv(z):real`) THEN
5577   REWRITE_TAC[real_div; REAL_MUL_LINV; REAL_INV_INV] THEN
5578   REWRITE_TAC[REAL_MUL_LID] THEN DISCH_THEN MATCH_MP_TAC THEN
5579   ASM_REWRITE_TAC[REAL_ABS_INV; REAL_LT_INV_EQ] THEN CONJ_TAC THENL
5580    [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
5581      `z <= --a ==> &0 < a ==> &0 < abs z`));
5582     GEN_REWRITE_TAC RAND_CONV [GSYM REAL_INV_INV] THEN
5583     MATCH_MP_TAC REAL_LT_INV2 THEN ASM_REWRITE_TAC[REAL_LT_INV_EQ] THEN
5584     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
5585      `z <= --(&2 / d) ==> &0 < &2 / d ==> inv d < abs z`))] THEN
5586   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH]);;
5587
5588 let REALLIM_ZERO_POSINFINITY = prove
5589  (`!f l. ((\x. f(&1 / x)) ---> l) (atreal (&0)) ==> (f ---> l) at_posinfinity`,
5590   REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN
5591   REWRITE_TAC[o_DEF; LIM_ZERO_POSINFINITY]);;
5592
5593 let REALLIM_ZERO_NEGINFINITY = prove
5594  (`!f l. ((\x. f(&1 / x)) ---> l) (atreal (&0)) ==> (f ---> l) at_neginfinity`,
5595   REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL] THEN
5596   REWRITE_TAC[o_DEF; LIM_ZERO_NEGINFINITY]);;
5597
5598 (* ------------------------------------------------------------------------- *)
5599 (* Real segments (bidirectional intervals).                                  *)
5600 (* ------------------------------------------------------------------------- *)
5601
5602 let closed_real_segment = define
5603  `closed_real_segment[a,b] = {(&1 - u) * a + u * b | &0 <= u /\ u <= &1}`;;
5604
5605 let open_real_segment = new_definition
5606  `open_real_segment(a,b) = closed_real_segment[a,b] DIFF {a,b}`;;
5607
5608 make_overloadable "real_segment" `:A`;;
5609
5610 overload_interface("real_segment",`open_real_segment`);;
5611 overload_interface("real_segment",`closed_real_segment`);;
5612
5613 let real_segment = prove
5614  (`real_segment[a,b] = {(&1 - u) * a + u * b | &0 <= u /\ u <= &1} /\
5615    real_segment(a,b) = real_segment[a,b] DIFF {a,b}`,
5616   REWRITE_TAC[open_real_segment; closed_real_segment]);;
5617
5618 let REAL_SEGMENT_SEGMENT = prove
5619  (`(!a b. real_segment[a,b] = IMAGE drop (segment[lift a,lift b])) /\
5620    (!a b. real_segment(a,b) = IMAGE drop (segment(lift a,lift b)))`,
5621   REWRITE_TAC[segment; real_segment] THEN
5622   SIMP_TAC[IMAGE_DIFF_INJ; DROP_EQ; IMAGE_CLAUSES; LIFT_DROP] THEN
5623   ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
5624   REWRITE_TAC[GSYM IMAGE_o; o_DEF; DROP_ADD; DROP_CMUL; LIFT_DROP]);;
5625
5626 let SEGMENT_REAL_SEGMENT = prove
5627  (`(!a b. segment[a,b] = IMAGE lift (real_segment[drop a,drop b])) /\
5628    (!a b. segment(a,b) = IMAGE lift (real_segment(drop a,drop b)))`,
5629   REWRITE_TAC[REAL_SEGMENT_SEGMENT; GSYM IMAGE_o] THEN
5630   REWRITE_TAC[o_DEF; IMAGE_ID; LIFT_DROP]);;
5631
5632 let IMAGE_LIFT_REAL_SEGMENT = prove
5633  (`(!a b. IMAGE lift (real_segment[a,b]) = segment[lift a,lift b]) /\
5634    (!a b. IMAGE lift (real_segment(a,b)) = segment(lift a,lift b))`,
5635   REWRITE_TAC[SEGMENT_REAL_SEGMENT; LIFT_DROP]);;
5636
5637 let REAL_SEGMENT_INTERVAL = prove
5638  (`(!a b. real_segment[a,b] =
5639           if a <= b then real_interval[a,b] else real_interval[b,a]) /\
5640    (!a b. real_segment(a,b) =
5641           if a <= b then real_interval(a,b) else real_interval(b,a))`,
5642   REWRITE_TAC[REAL_SEGMENT_SEGMENT; SEGMENT_1; LIFT_DROP] THEN
5643   REWRITE_TAC[REAL_INTERVAL_INTERVAL] THEN
5644   CONJ_TAC THEN REPEAT GEN_TAC THEN COND_CASES_TAC THEN REWRITE_TAC[]);;
5645
5646 let REAL_CONTINUOUS_INJECTIVE_IFF_MONOTONIC = prove
5647  (`!f s.
5648         f real_continuous_on s /\ is_realinterval s
5649         ==> ((!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) <=>
5650              (!x y. x IN s /\ y IN s /\ x < y ==> f x < f y) \/
5651              (!x y. x IN s /\ y IN s /\ x < y ==> f y < f x))`,
5652   REPEAT GEN_TAC THEN
5653   REWRITE_TAC[REAL_CONTINUOUS_ON; IS_REALINTERVAL_IS_INTERVAL] THEN
5654   DISCH_THEN(MP_TAC o MATCH_MP CONTINUOUS_INJECTIVE_IFF_MONOTONIC) THEN
5655   REWRITE_TAC[FORALL_LIFT; LIFT_IN_IMAGE_LIFT; o_THM; LIFT_DROP; LIFT_EQ]);;
5656
5657 let ENDS_IN_REAL_SEGMENT = prove
5658  (`!a b. a IN real_segment[a,b] /\ b IN real_segment[a,b]`,
5659   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_SEGMENT_INTERVAL] THEN
5660   COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN
5661   ASM_REAL_ARITH_TAC);;
5662
5663 let IS_REAL_INTERVAL_CONTAINS_SEGMENT = prove
5664  (`!s. is_realinterval s <=>
5665        !a b. a IN s /\ b IN s ==> real_segment[a,b] SUBSET s`,
5666   REWRITE_TAC[CONVEX_CONTAINS_SEGMENT; IS_REALINTERVAL_CONVEX] THEN
5667   REWRITE_TAC[REAL_SEGMENT_SEGMENT; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
5668   REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_IMAGE_LIFT_DROP]);;
5669
5670 let IS_REALINTERVAL_CONTAINS_SEGMENT_EQ = prove
5671  (`!s. is_realinterval s <=>
5672        !a b. real_segment [a,b] SUBSET s <=> a IN s /\ b IN s`,
5673   MESON_TAC[IS_REAL_INTERVAL_CONTAINS_SEGMENT;
5674             SUBSET; ENDS_IN_REAL_SEGMENT]);;
5675
5676 let IS_REALINTERVAL_CONTAINS_SEGMENT_IMP = prove
5677  (`!s a b. is_realinterval s
5678            ==> (real_segment [a,b] SUBSET s <=> a IN s /\ b IN s)`,
5679   MESON_TAC[IS_REALINTERVAL_CONTAINS_SEGMENT_EQ]);;
5680
5681 let IS_REALINTERVAL_SEGMENT = prove
5682  (`(!a b. is_realinterval(real_segment[a,b])) /\
5683    (!a b. is_realinterval(real_segment(a,b)))`,
5684   REWRITE_TAC[REAL_SEGMENT_INTERVAL] THEN
5685   MESON_TAC[IS_REALINTERVAL_INTERVAL]);;
5686
5687 let IN_REAL_SEGMENT = prove
5688  (`(!a b x. x IN real_segment[a,b] <=> a <= x /\ x <= b \/ b <= x /\ x <= a) /\
5689    (!a b x. x IN real_segment(a,b) <=> a < x /\ x < b \/ b < x /\ x < a)`,
5690   REWRITE_TAC[REAL_SEGMENT_INTERVAL] THEN
5691   REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
5692   ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN ASM_REAL_ARITH_TAC);;
5693
5694 (* ------------------------------------------------------------------------- *)
5695 (* Convex real->real functions.                                              *)
5696 (* ------------------------------------------------------------------------- *)
5697
5698 parse_as_infix ("real_convex_on",(12,"right"));;
5699
5700 let real_convex_on = new_definition
5701   `(f:real->real) real_convex_on s <=>
5702         !x y u v. x IN s /\ y IN s /\ &0 <= u /\ &0 <= v /\ (u + v = &1)
5703                   ==> f(u * x + v * y) <= u * f(x) + v * f(y)`;;
5704
5705 let REAL_CONVEX_ON = prove
5706  (`!f s. f real_convex_on s <=> (f o drop) convex_on (IMAGE lift s)`,
5707   REWRITE_TAC[real_convex_on; convex_on] THEN
5708   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
5709   REWRITE_TAC[o_THM; LIFT_DROP; DROP_ADD; DROP_CMUL]);;
5710
5711 let REAL_CONVEX_ON_SUBSET = prove
5712  (`!f s t. f real_convex_on t /\ s SUBSET t ==> f real_convex_on s`,
5713   REWRITE_TAC[REAL_CONVEX_ON] THEN
5714   MESON_TAC[CONVEX_ON_SUBSET; IMAGE_SUBSET]);;
5715
5716 let REAL_CONVEX_ADD = prove
5717  (`!s f g. f real_convex_on s /\ g real_convex_on s
5718            ==> (\x. f(x) + g(x)) real_convex_on s`,
5719   REWRITE_TAC[REAL_CONVEX_ON; o_DEF; CONVEX_ADD]);;
5720
5721 let REAL_CONVEX_LMUL = prove
5722  (`!s c f. &0 <= c /\ f real_convex_on s ==> (\x. c * f(x)) real_convex_on s`,
5723   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_CONVEX_ON; o_DEF] THEN
5724   DISCH_THEN(MP_TAC o MATCH_MP CONVEX_CMUL) THEN REWRITE_TAC[]);;
5725
5726 let REAL_CONVEX_RMUL = prove
5727  (`!s c f. &0 <= c /\ f real_convex_on s ==> (\x. f(x) * c) real_convex_on s`,
5728   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[REAL_CONVEX_LMUL]);;
5729
5730 let REAL_CONVEX_CONVEX_COMPOSE = prove
5731  (`!f g s:real^N->bool t.
5732         f convex_on s /\ g real_convex_on t /\
5733         convex s /\ is_realinterval t /\ IMAGE f s SUBSET t /\
5734         (!x y. x IN t /\ y IN t /\ x <= y ==> g x <= g y)
5735         ==> (g o f) convex_on s`,
5736   REWRITE_TAC[convex_on; convex; IS_REALINTERVAL_CONVEX;
5737                real_convex_on; SUBSET] THEN
5738   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE; o_DEF] THEN
5739   REWRITE_TAC[IN_IMAGE_LIFT_DROP; DROP_ADD; DROP_CMUL; LIFT_DROP] THEN
5740   REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN
5741   ASM_MESON_TAC[REAL_LE_TRANS]);;
5742
5743 let REAL_CONVEX_COMPOSE = prove
5744  (`!f g. f real_convex_on s /\ g real_convex_on t /\
5745          is_realinterval s /\ is_realinterval t /\ IMAGE f s SUBSET t /\
5746          (!x y. x IN t /\ y IN t /\ x <= y ==> g x <= g y)
5747         ==> (g o f) real_convex_on s`,
5748   REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_CONVEX_ON; GSYM o_ASSOC] THEN
5749   MATCH_MP_TAC REAL_CONVEX_CONVEX_COMPOSE THEN EXISTS_TAC `t:real->bool` THEN
5750   ASM_REWRITE_TAC[GSYM REAL_CONVEX_ON; GSYM IMAGE_o; o_DEF; LIFT_DROP;
5751                   ETA_AX; GSYM IS_REALINTERVAL_CONVEX]);;
5752
5753 let REAL_CONVEX_LOWER = prove
5754  (`!f s x y. f real_convex_on s /\
5755              x IN s /\ y IN s /\ &0 <= u /\ &0 <= v /\ u + v = &1
5756              ==> f(u * x + v * y) <= max (f(x)) (f(y))`,
5757   REWRITE_TAC[REAL_CONVEX_ON] THEN
5758   REWRITE_TAC[FORALL_DROP; GSYM IN_IMAGE_LIFT_DROP] THEN
5759   REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP CONVEX_LOWER) THEN
5760   REWRITE_TAC[o_THM; DROP_ADD; DROP_CMUL]);;
5761
5762 let REAL_CONVEX_LOCAL_GLOBAL_MINIMUM = prove
5763  (`!f s t x.
5764        f real_convex_on s /\ x IN t /\ real_open t /\ t SUBSET s /\
5765        (!y. y IN t ==> f(x) <= f(y))
5766        ==> !y. y IN s ==> f(x) <= f(y)`,
5767   REWRITE_TAC[REAL_CONVEX_ON; REAL_OPEN] THEN
5768   REWRITE_TAC[FORALL_DROP; GSYM IN_IMAGE_LIFT_DROP] THEN
5769   REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP] THEN
5770   REPEAT GEN_TAC THEN STRIP_TAC THEN
5771   MP_TAC(ISPECL [`(f:real->real) o drop`; `IMAGE lift s`;
5772                  `IMAGE lift t`; `x:real^1`] CONVEX_LOCAL_GLOBAL_MINIMUM) THEN
5773   ASM_SIMP_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_THM; IMAGE_SUBSET]);;
5774
5775 let REAL_CONVEX_DISTANCE = prove
5776  (`!s a. (\x. abs(a - x)) real_convex_on s`,
5777   REWRITE_TAC[REAL_CONVEX_ON; o_DEF; FORALL_DROP; GSYM DROP_SUB] THEN
5778   REWRITE_TAC[drop; GSYM NORM_REAL; GSYM dist; CONVEX_DISTANCE]);;
5779
5780 let REAL_CONVEX_ON_JENSEN = prove
5781  (`!f s. is_realinterval s
5782          ==> (f real_convex_on s <=>
5783                 !k u x.
5784                    (!i:num. 1 <= i /\ i <= k ==> &0 <= u(i) /\ x(i) IN s) /\
5785                    (sum (1..k) u = &1)
5786                    ==> f(sum (1..k) (\i. u(i) * x(i)))
5787                            <= sum (1..k) (\i. u(i) * f(x(i))))`,
5788   REWRITE_TAC[IS_REALINTERVAL_CONVEX; REAL_CONVEX_ON] THEN
5789   SIMP_TAC[CONVEX_ON_JENSEN] THEN REPEAT STRIP_TAC THEN
5790   SIMP_TAC[o_DEF; DROP_VSUM; FINITE_NUMSEG] THEN
5791   AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
5792   X_GEN_TAC `k:num` THEN REWRITE_TAC[] THEN
5793   AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
5794   X_GEN_TAC `u:num->real` THEN REWRITE_TAC[] THEN EQ_TAC THEN DISCH_TAC THENL
5795    [X_GEN_TAC `x:num->real` THEN STRIP_TAC THEN
5796     FIRST_X_ASSUM(MP_TAC o SPEC `lift o (x:num->real)`) THEN
5797     ASM_REWRITE_TAC[o_DEF; LIFT_DROP; IN_IMAGE_LIFT_DROP] THEN
5798     REWRITE_TAC[DROP_CMUL; LIFT_DROP];
5799     X_GEN_TAC `x:num->real^1` THEN STRIP_TAC THEN
5800     FIRST_X_ASSUM(MP_TAC o SPEC `drop o (x:num->real^1)`) THEN
5801     ASM_REWRITE_TAC[o_DEF; LIFT_DROP; IN_IMAGE_LIFT_DROP] THEN
5802     ASM_REWRITE_TAC[DROP_CMUL; LIFT_DROP; GSYM IN_IMAGE_LIFT_DROP]]);;
5803
5804 let REAL_CONVEX_ON_IMP_JENSEN = prove
5805  (`!f s k:A->bool u x.
5806         f real_convex_on s /\ is_realinterval s /\ FINITE k /\
5807         (!i. i IN k ==> &0 <= u i /\ x i IN s) /\ sum k u = &1
5808         ==> f(sum k (\i. u i * x i)) <= sum k (\i. u i * f(x i))`,
5809   REWRITE_TAC[REAL_CONVEX_ON; IS_REALINTERVAL_IS_INTERVAL] THEN
5810   REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o
5811    SPECL [`k:A->bool`; `u:A->real`; `\i:A. lift(x i)`] o
5812    MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ] CONVEX_ON_IMP_JENSEN)) THEN
5813   ASM_REWRITE_TAC[LIFT_IN_IMAGE_LIFT; o_DEF; LIFT_DROP; DROP_VSUM; DROP_CMUL;
5814                   GSYM IS_INTERVAL_CONVEX_1]);;
5815
5816 let REAL_CONVEX_ON_CONTINUOUS = prove
5817  (`!f s. real_open s /\ f real_convex_on s ==> f real_continuous_on s`,
5818   REWRITE_TAC[REAL_CONVEX_ON; REAL_OPEN; REAL_CONTINUOUS_ON] THEN
5819   REWRITE_TAC[CONVEX_ON_CONTINUOUS]);;
5820
5821 let REAL_CONVEX_ON_LEFT_SECANT_MUL = prove
5822  (`!f s. f real_convex_on s <=>
5823           !a b x. a IN s /\ b IN s /\ x IN real_segment[a,b]
5824                   ==> (f x - f a) * abs(b - a) <= (f b - f a) * abs(x - a)`,
5825   REWRITE_TAC[REAL_CONVEX_ON; CONVEX_ON_LEFT_SECANT_MUL] THEN
5826   REWRITE_TAC[REAL_SEGMENT_SEGMENT] THEN
5827   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
5828   REWRITE_TAC[o_DEF; LIFT_DROP] THEN
5829   REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP]);;
5830
5831 let REAL_CONVEX_ON_RIGHT_SECANT_MUL = prove
5832  (`!f s. f real_convex_on s <=>
5833           !a b x. a IN s /\ b IN s /\ x IN real_segment[a,b]
5834                   ==> (f b - f a) * abs(b - x) <= (f b - f x) * abs(b - a)`,
5835   REWRITE_TAC[REAL_CONVEX_ON; CONVEX_ON_RIGHT_SECANT_MUL] THEN
5836   REWRITE_TAC[REAL_SEGMENT_SEGMENT] THEN
5837   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
5838   REWRITE_TAC[o_DEF; LIFT_DROP] THEN
5839   REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP]);;
5840
5841 let REAL_CONVEX_ON_LEFT_SECANT = prove
5842  (`!f s.
5843       f real_convex_on s <=>
5844         !a b x. a IN s /\ b IN s /\ x IN real_segment(a,b)
5845                 ==> (f x - f a) / abs(x - a) <= (f b - f a) / abs(b - a)`,
5846   REWRITE_TAC[REAL_CONVEX_ON; CONVEX_ON_LEFT_SECANT] THEN
5847   REWRITE_TAC[REAL_SEGMENT_SEGMENT] THEN
5848   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
5849   REWRITE_TAC[o_DEF; LIFT_DROP] THEN
5850   REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP]);;
5851
5852 let REAL_CONVEX_ON_RIGHT_SECANT = prove
5853  (`!f s.
5854       f real_convex_on s <=>
5855         !a b x. a IN s /\ b IN s /\ x IN real_segment(a,b)
5856                 ==> (f b - f a) / abs(b - a) <= (f b - f x) / abs(b - x)`,
5857   REWRITE_TAC[REAL_CONVEX_ON; CONVEX_ON_RIGHT_SECANT] THEN
5858   REWRITE_TAC[REAL_SEGMENT_SEGMENT] THEN
5859   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
5860   REWRITE_TAC[o_DEF; LIFT_DROP] THEN
5861   REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP]);;
5862
5863 let REAL_CONVEX_ON_DERIVATIVE_SECANT_IMP = prove
5864  (`!f f' s x y.
5865         f real_convex_on s /\ real_segment[x,y] SUBSET s /\
5866         (f has_real_derivative f') (atreal x within s)
5867         ==> f' * (y - x) <= f y - f x`,
5868   REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN;
5869               REAL_CONVEX_ON; REAL_SEGMENT_SEGMENT] THEN
5870   REWRITE_TAC[SUBSET; IN_IMAGE_LIFT_DROP] THEN
5871   REPEAT GEN_TAC THEN REWRITE_TAC[FORALL_DROP] THEN
5872   REWRITE_TAC[LIFT_DROP] THEN
5873   REWRITE_TAC[GSYM IN_IMAGE_LIFT_DROP; GSYM SUBSET] THEN
5874   ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[LIFT_DROP]
5875         `\x. lift(drop(f % x))`)] THEN
5876   REWRITE_TAC[GSYM o_DEF] THEN
5877   DISCH_THEN(MP_TAC o MATCH_MP CONVEX_ON_DERIVATIVE_SECANT_IMP) THEN
5878   REWRITE_TAC[o_THM; DROP_CMUL; DROP_SUB; LIFT_DROP]);;
5879
5880 let REAL_CONVEX_ON_SECANT_DERIVATIVE_IMP = prove
5881  (`!f f' s x y.
5882         f real_convex_on s /\ real_segment[x,y] SUBSET s /\
5883         (f has_real_derivative f') (atreal y within s)
5884         ==> f y - f x <= f' * (y - x)`,
5885   REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN;
5886               REAL_CONVEX_ON; REAL_SEGMENT_SEGMENT] THEN
5887   REWRITE_TAC[SUBSET; IN_IMAGE_LIFT_DROP] THEN
5888   REPEAT GEN_TAC THEN REWRITE_TAC[FORALL_DROP] THEN
5889   REWRITE_TAC[LIFT_DROP] THEN
5890   REWRITE_TAC[GSYM IN_IMAGE_LIFT_DROP; GSYM SUBSET] THEN
5891   ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[LIFT_DROP]
5892         `\x. lift(drop(f % x))`)] THEN
5893   REWRITE_TAC[GSYM o_DEF] THEN
5894   DISCH_THEN(MP_TAC o MATCH_MP CONVEX_ON_SECANT_DERIVATIVE_IMP) THEN
5895   REWRITE_TAC[o_THM; DROP_CMUL; DROP_SUB; LIFT_DROP]);;
5896
5897 let REAL_CONVEX_ON_DERIVATIVES_IMP = prove
5898  (`!f f'x f'y s x y.
5899         f real_convex_on s /\ real_segment[x,y] SUBSET s /\
5900         (f has_real_derivative f'x) (atreal x within s) /\
5901         (f has_real_derivative f'y) (atreal y within s)
5902         ==> f'x * (y - x) <= f'y * (y - x)`,
5903   REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN;
5904               REAL_CONVEX_ON; REAL_SEGMENT_SEGMENT] THEN
5905   REWRITE_TAC[SUBSET; IN_IMAGE_LIFT_DROP] THEN
5906   REPEAT GEN_TAC THEN REWRITE_TAC[FORALL_DROP] THEN
5907   REWRITE_TAC[LIFT_DROP] THEN
5908   REWRITE_TAC[GSYM IN_IMAGE_LIFT_DROP; GSYM SUBSET] THEN
5909   ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[LIFT_DROP]
5910         `\x. lift(drop(f % x))`)] THEN
5911   REWRITE_TAC[GSYM o_DEF] THEN
5912   DISCH_THEN(MP_TAC o MATCH_MP CONVEX_ON_DERIVATIVES_IMP) THEN
5913   REWRITE_TAC[o_THM; DROP_CMUL; DROP_SUB; LIFT_DROP]);;
5914
5915 let REAL_CONVEX_ON_DERIVATIVE_INCREASING_IMP = prove
5916  (`!f f'x f'y s x y.
5917         f real_convex_on s /\ real_interval[x,y] SUBSET s /\
5918         (f has_real_derivative f'x) (atreal x within s) /\
5919         (f has_real_derivative f'y) (atreal y within s) /\
5920         x < y
5921         ==> f'x <= f'y`,
5922   REPEAT STRIP_TAC THEN
5923   MP_TAC(ISPECL [`f:real->real`; `f'x:real`; `f'y:real`; `s:real->bool`;
5924                  `x:real`; `y:real`] REAL_CONVEX_ON_DERIVATIVES_IMP) THEN
5925   ASM_REWRITE_TAC[REAL_SEGMENT_INTERVAL] THEN
5926   ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_RMUL_EQ; REAL_SUB_LT]);;
5927
5928 let REAL_CONVEX_ON_DERIVATIVE_SECANT = prove
5929  (`!f f' s.
5930         is_realinterval s /\
5931         (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s))
5932         ==> (f real_convex_on s <=>
5933              !x y. x IN s /\ y IN s ==> f'(x) * (y - x) <= f y - f x)`,
5934   REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN;
5935               REAL_CONVEX_ON; IS_REALINTERVAL_CONVEX] THEN
5936   REPEAT GEN_TAC THEN
5937   REWRITE_TAC[FORALL_DROP; GSYM IN_IMAGE_LIFT_DROP; LIFT_DROP] THEN
5938   ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[LIFT_DROP; o_DEF]
5939         `lift o (\x. drop(f % x))`)] THEN
5940   DISCH_THEN(SUBST1_TAC o MATCH_MP CONVEX_ON_DERIVATIVE_SECANT) THEN
5941   REWRITE_TAC[DROP_CMUL; DROP_SUB; o_THM]);;
5942
5943 let REAL_CONVEX_ON_SECANT_DERIVATIVE = prove
5944  (`!f f' s.
5945         is_realinterval s /\
5946         (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s))
5947         ==> (f real_convex_on s <=>
5948              !x y. x IN s /\ y IN s ==> f y - f x <= f'(y) * (y - x))`,
5949   REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN;
5950               REAL_CONVEX_ON; IS_REALINTERVAL_CONVEX] THEN
5951   REPEAT GEN_TAC THEN
5952   REWRITE_TAC[FORALL_DROP; GSYM IN_IMAGE_LIFT_DROP; LIFT_DROP] THEN
5953   ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[LIFT_DROP; o_DEF]
5954         `lift o (\x. drop(f % x))`)] THEN
5955   DISCH_THEN(SUBST1_TAC o MATCH_MP CONVEX_ON_SECANT_DERIVATIVE) THEN
5956   REWRITE_TAC[DROP_CMUL; DROP_SUB; o_THM]);;
5957
5958 let REAL_CONVEX_ON_DERIVATIVES = prove
5959  (`!f f' s.
5960         is_realinterval s /\
5961         (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s))
5962         ==> (f real_convex_on s <=>
5963              !x y. x IN s /\ y IN s ==> f'(x) * (y - x) <= f'(y) * (y - x))`,
5964   REWRITE_TAC[HAS_REAL_FRECHET_DERIVATIVE_WITHIN;
5965               REAL_CONVEX_ON; IS_REALINTERVAL_CONVEX] THEN
5966   REPEAT GEN_TAC THEN
5967   REWRITE_TAC[FORALL_DROP; GSYM IN_IMAGE_LIFT_DROP; LIFT_DROP] THEN
5968   ONCE_REWRITE_TAC[GSYM(REWRITE_CONV[LIFT_DROP; o_DEF]
5969         `lift o (\x. drop(f % x))`)] THEN
5970   DISCH_THEN(SUBST1_TAC o MATCH_MP CONVEX_ON_DERIVATIVES) THEN
5971   REWRITE_TAC[DROP_CMUL; DROP_SUB; o_THM]);;
5972
5973 let REAL_CONVEX_ON_DERIVATIVE_INCREASING = prove
5974  (`!f f' s.
5975         is_realinterval s /\
5976         (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s))
5977         ==> (f real_convex_on s <=>
5978              !x y. x IN s /\ y IN s /\ x <= y ==> f'(x) <= f'(y))`,
5979   REPEAT GEN_TAC THEN DISCH_TAC THEN
5980   FIRST_ASSUM(SUBST1_TAC o MATCH_MP REAL_CONVEX_ON_DERIVATIVES) THEN
5981   EQ_TAC THEN DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN
5982   STRIP_TAC THENL
5983    [FIRST_X_ASSUM(MP_TAC o SPECL [`x:real`; `y:real`]) THEN
5984     ASM_CASES_TAC `x:real = y` THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN
5985     ASM_SIMP_TAC[REAL_LE_RMUL_EQ; REAL_SUB_LT; REAL_LT_LE];
5986     DISJ_CASES_TAC(REAL_ARITH `x <= y \/ y <= x`) THENL
5987      [FIRST_X_ASSUM(MP_TAC o SPECL [`x:real`; `y:real`]);
5988       FIRST_X_ASSUM(MP_TAC o SPECL [`y:real`; `x:real`])] THEN
5989     ASM_CASES_TAC `x:real = y` THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN
5990     ASM_SIMP_TAC[REAL_LE_RMUL_EQ; REAL_SUB_LT; REAL_LT_LE] THEN
5991     ONCE_REWRITE_TAC[REAL_ARITH
5992      `a * (y - x) <= b * (y - x) <=> b * (x - y) <= a * (x - y)`] THEN
5993     ASM_SIMP_TAC[REAL_LE_RMUL_EQ; REAL_SUB_LT; REAL_LT_LE]]);;
5994
5995 let HAS_REAL_DERIVATIVE_INCREASING_IMP = prove
5996  (`!f f' s a b.
5997         is_realinterval s /\
5998         (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s)) /\
5999         (!x. x IN s ==> &0 <= f'(x)) /\
6000         a IN s /\ b IN s /\ a <= b
6001         ==> f(a) <= f(b)`,
6002   REPEAT STRIP_TAC THEN
6003   SUBGOAL_THEN `real_interval[a,b] SUBSET s` ASSUME_TAC THENL
6004    [REWRITE_TAC[SUBSET; IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN
6005     FIRST_X_ASSUM(MATCH_MP_TAC o GEN_REWRITE_RULE I [is_realinterval]) THEN
6006     MAP_EVERY EXISTS_TAC [`a:real`; `b:real`] THEN ASM_REWRITE_TAC[];
6007     ALL_TAC] THEN
6008   MP_TAC(ISPECL [`f:real->real`; `f':real->real`; `a:real`; `b:real`]
6009     REAL_MVT_VERY_SIMPLE) THEN
6010   ANTS_TAC THENL
6011    [ASM_REWRITE_TAC[] THEN X_GEN_TAC `z:real` THEN DISCH_TAC THEN
6012     MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN
6013     EXISTS_TAC `s:real->bool` THEN ASM SET_TAC[];
6014     DISCH_THEN(X_CHOOSE_THEN `z:real` MP_TAC) THEN STRIP_TAC THEN
6015     GEN_REWRITE_TAC I [GSYM REAL_SUB_LE] THEN
6016     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_MUL THEN
6017     CONJ_TAC THENL [ASM SET_TAC[]; ASM_REAL_ARITH_TAC]]);;
6018
6019 let HAS_REAL_DERIVATIVE_INCREASING = prove
6020  (`!f f' s. is_realinterval s /\ ~(?a. s = {a}) /\
6021            (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s))
6022            ==> ((!x. x IN s ==> &0 <= f'(x)) <=>
6023                 (!x y. x IN s /\ y IN s /\ x <= y ==> f(x) <= f(y)))`,
6024   REWRITE_TAC[NOT_EXISTS_THM] THEN REPEAT STRIP_TAC THEN EQ_TAC THENL
6025    [ASM_MESON_TAC[HAS_REAL_DERIVATIVE_INCREASING_IMP]; ALL_TAC] THEN
6026   DISCH_TAC THEN X_GEN_TAC `x:real` THEN DISCH_TAC THEN
6027   MATCH_MP_TAC(ISPEC `atreal x within s` REALLIM_LBOUND) THEN
6028   EXISTS_TAC `\y:real. (f y - f x) / (y - x)` THEN
6029   ASM_SIMP_TAC[GSYM HAS_REAL_DERIVATIVE_WITHINREAL] THEN
6030   ASM_SIMP_TAC[TRIVIAL_LIMIT_WITHIN_REALINTERVAL] THEN
6031   REWRITE_TAC[EVENTUALLY_WITHINREAL] THEN
6032   EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
6033   X_GEN_TAC `y:real` THEN
6034   REWRITE_TAC[REAL_ARITH `&0 < abs(y - x) <=> ~(y = x)`] THEN STRIP_TAC THEN
6035   FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (REAL_ARITH
6036    `~(y:real = x) ==> x < y \/ y < x`))
6037   THENL
6038    [ALL_TAC;
6039     ONCE_REWRITE_TAC[GSYM REAL_NEG_SUB] THEN
6040     REWRITE_TAC[real_div; REAL_INV_NEG; REAL_MUL_LNEG; REAL_MUL_RNEG] THEN
6041     REWRITE_TAC[REAL_NEG_NEG; GSYM real_div]] THEN
6042   MATCH_MP_TAC REAL_LE_DIV THEN
6043   ASM_SIMP_TAC[REAL_SUB_LE; REAL_LT_IMP_LE]);;
6044
6045 let HAS_REAL_DERIVATIVE_STRICTLY_INCREASING_IMP = prove
6046  (`!f f' a b.
6047         (!x. x IN real_interval[a,b]
6048              ==> (f has_real_derivative f'(x))
6049
6050                  (atreal x within real_interval[a,b])) /\
6051         (!x. x IN real_interval(a,b) ==> &0 < f'(x)) /\
6052         a < b
6053         ==> f(a) < f(b)`,
6054   REPEAT STRIP_TAC THEN
6055   MP_TAC(ISPECL [`f:real->real`; `f':real->real`; `a:real`; `b:real`]
6056         REAL_MVT) THEN
6057   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
6058    [ALL_TAC; ASM_MESON_TAC[REAL_SUB_LT; REAL_LT_MUL]] THEN
6059   CONJ_TAC THENL
6060    [ASM_MESON_TAC[REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON;
6061                   real_differentiable_on];
6062     ASM_MESON_TAC[HAS_REAL_DERIVATIVE_WITHIN_SUBSET; SUBSET;
6063                   REAL_INTERVAL_OPEN_SUBSET_CLOSED; REAL_OPEN_REAL_INTERVAL;
6064                   HAS_REAL_DERIVATIVE_WITHIN_REAL_OPEN]]);;
6065
6066 let REAL_CONVEX_ON_SECOND_DERIVATIVE = prove
6067  (`!f f' f'' s.
6068         is_realinterval s /\ ~(?a. s = {a}) /\
6069         (!x. x IN s ==> (f has_real_derivative f'(x)) (atreal x within s)) /\
6070         (!x. x IN s ==> (f' has_real_derivative f''(x)) (atreal x within s))
6071         ==> (f real_convex_on s <=> !x. x IN s ==> &0 <= f''(x))`,
6072   REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC
6073    `!x y. x IN s /\ y IN s /\ x <= y ==> (f':real->real)(x) <= f'(y)` THEN
6074   CONJ_TAC THENL
6075    [MATCH_MP_TAC REAL_CONVEX_ON_DERIVATIVE_INCREASING;
6076     CONV_TAC SYM_CONV THEN MATCH_MP_TAC HAS_REAL_DERIVATIVE_INCREASING] THEN
6077   ASM_REWRITE_TAC[]);;
6078
6079 let REAL_CONVEX_ON_ASYM = prove
6080  (`!s f. f real_convex_on s <=>
6081          !x y u v.
6082                 x IN s /\ y IN s /\ x < y /\ &0 <= u /\ &0 <= v /\ u + v = &1
6083                 ==> f (u * x + v * y) <= u * f x + v * f y`,
6084   REPEAT GEN_TAC THEN REWRITE_TAC[real_convex_on] THEN
6085   EQ_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC[] THEN
6086   MATCH_MP_TAC REAL_WLOG_LT THEN
6087   SIMP_TAC[GSYM REAL_ADD_RDISTRIB; REAL_MUL_LID; REAL_LE_REFL] THEN
6088   ASM_MESON_TAC[REAL_ADD_SYM]);;
6089
6090 let REAL_CONVEX_ON_EXP = prove
6091  (`!s. exp real_convex_on s`,
6092   GEN_TAC THEN MATCH_MP_TAC REAL_CONVEX_ON_SUBSET THEN
6093   EXISTS_TAC `(:real)` THEN REWRITE_TAC[SUBSET_UNIV] THEN
6094   MP_TAC(ISPECL [`exp`; `exp`; `exp`; `(:real)`]
6095      REAL_CONVEX_ON_SECOND_DERIVATIVE) THEN
6096   SIMP_TAC[HAS_REAL_DERIVATIVE_EXP; REAL_EXP_POS_LE;
6097            HAS_REAL_DERIVATIVE_ATREAL_WITHIN; IS_REALINTERVAL_UNIV] THEN
6098   DISCH_THEN MATCH_MP_TAC THEN
6099   MATCH_MP_TAC(SET_RULE
6100    `&0 IN s /\ &1 IN s /\ ~(&1 = &0) ==> ~(?a. s = {a})`) THEN
6101   REWRITE_TAC[IN_UNIV] THEN REAL_ARITH_TAC);;
6102
6103 let REAL_CONVEX_ON_RPOW = prove
6104  (`!s t. s SUBSET {x | &0 <= x} /\ &1 <= t
6105          ==> (\x. x rpow t) real_convex_on s`,
6106   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_CONVEX_ON_SUBSET THEN
6107   EXISTS_TAC `{x | &0 <= x}` THEN ASM_REWRITE_TAC[] THEN
6108   SUBGOAL_THEN `(\x. x rpow t) real_convex_on {x | &0 < x}` MP_TAC THENL
6109    [MP_TAC(ISPECL
6110      [`\x. x rpow t`; `\x. t * x rpow (t - &1)`;
6111       `\x. t * (t - &1) * x rpow (t - &2)`; `{x | &0 < x}`]
6112         REAL_CONVEX_ON_SECOND_DERIVATIVE) THEN
6113     ASM_REWRITE_TAC[IN_ELIM_THM] THEN ANTS_TAC THENL
6114      [REPEAT CONJ_TAC THENL
6115        [REWRITE_TAC[is_realinterval; IN_ELIM_THM] THEN REAL_ARITH_TAC;
6116         MATCH_MP_TAC(SET_RULE
6117          `&1 IN s /\ &2 IN s /\ ~(&1 = &2) ==> ~(?a. s = {a})`) THEN
6118         REWRITE_TAC[IN_ELIM_THM] THEN REAL_ARITH_TAC;
6119         REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN ASM_REAL_ARITH_TAC;
6120         REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN
6121         ASM_REWRITE_TAC[REAL_ARITH `t - &1 - &1 = t - &2`] THEN
6122         ASM_REAL_ARITH_TAC];
6123       DISCH_THEN SUBST1_TAC THEN REPEAT STRIP_TAC THEN
6124       REPEAT(MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THENL
6125        [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
6126       MATCH_MP_TAC RPOW_POS_LE THEN ASM_SIMP_TAC[REAL_LT_IMP_LE]];
6127     REWRITE_TAC[REAL_CONVEX_ON_ASYM] THEN
6128     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real` THEN
6129     REWRITE_TAC[IN_ELIM_THM] THEN ASM_CASES_TAC `x = &0` THENL
6130      [DISCH_THEN(K ALL_TAC) THEN ASM_REWRITE_TAC[REAL_MUL_RZERO] THEN
6131       REPEAT STRIP_TAC THEN
6132       ASM_SIMP_TAC[RPOW_ZERO; REAL_ARITH `&1 <= t ==> ~(t = &0)`] THEN
6133       REWRITE_TAC[REAL_MUL_RZERO; REAL_ADD_LID] THEN
6134       ASM_CASES_TAC `v = &0` THEN
6135       ASM_SIMP_TAC[RPOW_ZERO; REAL_ARITH `&1 <= t ==> ~(t = &0)`;
6136                    REAL_MUL_LZERO; REAL_LE_REFL] THEN
6137       ASM_SIMP_TAC[RPOW_MUL; REAL_LT_LE] THEN
6138       MATCH_MP_TAC REAL_LE_RMUL THEN
6139       ASM_SIMP_TAC[RPOW_POS_LE; REAL_LT_IMP_LE] THEN
6140        MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `exp(&1 * log v)` THEN
6141       CONJ_TAC THENL
6142        [ASM_SIMP_TAC[rpow; REAL_LT_LE; REAL_EXP_MONO_LE] THEN
6143         ONCE_REWRITE_TAC[REAL_ARITH
6144          `a * l <= b * l <=> --l * b <= --l * a`] THEN
6145         MATCH_MP_TAC REAL_LE_LMUL THEN ASM_REWRITE_TAC[] THEN
6146         ASM_SIMP_TAC[GSYM LOG_INV; REAL_LT_LE] THEN MATCH_MP_TAC LOG_POS THEN
6147         MATCH_MP_TAC REAL_INV_1_LE THEN ASM_REAL_ARITH_TAC;
6148         ASM_SIMP_TAC[REAL_MUL_LID; EXP_LOG; REAL_LT_LE; REAL_LE_REFL]];
6149       ASM_MESON_TAC[REAL_LT_LE; REAL_LET_TRANS]]]);;
6150
6151 let REAL_CONVEX_ON_LOG = prove
6152  (`!s. s SUBSET {x | &0 < x} ==> (\x. --log x) real_convex_on s`,
6153   GEN_TAC THEN
6154   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_CONVEX_ON_SUBSET) THEN
6155   MP_TAC(ISPECL [`\x. --log x`; `\x:real. --inv(x)`; `\x:real. inv(x pow 2)`;
6156                  `{x | &0 < x}`]
6157         REAL_CONVEX_ON_SECOND_DERIVATIVE) THEN
6158   REWRITE_TAC[IN_ELIM_THM; REAL_LE_INV_EQ; REAL_LE_POW_2] THEN
6159   DISCH_THEN MATCH_MP_TAC THEN REPEAT CONJ_TAC THENL
6160    [REWRITE_TAC[is_realinterval; IN_ELIM_THM] THEN REAL_ARITH_TAC;
6161     REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_SING] THEN
6162     MESON_TAC[REAL_ARITH `&0 < a ==> &0 < a + &1 /\ ~(a + &1 = a)`];
6163     REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN ASM_REAL_ARITH_TAC;
6164     REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN ASM_REAL_ARITH_TAC]);;
6165
6166 let REAL_CONTINUOUS_MIDPOINT_CONVEX = prove
6167  (`!f s. f real_continuous_on s /\ is_realinterval s /\
6168          (!x y. x IN s /\ y IN s ==> f ((x + y) / &2) <= (f x + f y) / &2)
6169          ==> f real_convex_on s`,
6170   REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_CONVEX_ON] THEN
6171   MATCH_MP_TAC CONTINUOUS_MIDPOINT_CONVEX THEN
6172   ASM_REWRITE_TAC[GSYM REAL_CONTINUOUS_ON; GSYM IS_REALINTERVAL_CONVEX] THEN
6173   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
6174   REWRITE_TAC[midpoint; LIFT_DROP; o_THM; DROP_CMUL; DROP_ADD] THEN
6175   ASM_SIMP_TAC[REAL_ARITH `inv(&2) * x = x / &2`]);;
6176
6177 (* ------------------------------------------------------------------------- *)
6178 (* Some convexity-derived inequalities including AGM and Young's inequality. *)
6179 (* ------------------------------------------------------------------------- *)
6180
6181 let AGM_GEN = prove
6182  (`!a x k:A->bool.
6183         FINITE k /\ sum k a = &1 /\ (!i. i IN k ==> &0 <= a i /\ &0 <= x i)
6184         ==> product k (\i. x i rpow a i) <= sum k (\i. a i * x i)`,
6185   let version1 = prove
6186    (`!a x k:A->bool.
6187           FINITE k /\ sum k a = &1 /\ (!i. i IN k ==> &0 < a i /\ &0 < x i)
6188           ==> product k (\i. x i rpow a i) <= sum k (\i. a i * x i)`,
6189     REPEAT GEN_TAC THEN ASM_CASES_TAC `k:A->bool = {}` THEN
6190     ASM_REWRITE_TAC[SUM_CLAUSES; REAL_OF_NUM_EQ; ARITH_EQ] THEN STRIP_TAC THEN
6191     MATCH_MP_TAC LOG_MONO_LE_REV THEN
6192     ASM_SIMP_TAC[PRODUCT_POS_LT; RPOW_POS_LT; LOG_PRODUCT; LOG_RPOW;
6193                  SUM_POS_LT_ALL; REAL_LT_MUL] THEN
6194     MP_TAC(ISPECL [`\x. --log x`; `{x | &0 < x}`; `k:A->bool`; `a:A->real`;
6195                    `x:A->real`] REAL_CONVEX_ON_IMP_JENSEN) THEN
6196     ASM_SIMP_TAC[IN_ELIM_THM; REAL_CONVEX_ON_LOG; SUBSET_REFL; REAL_LT_IMP_LE;
6197                  is_realinterval] THEN
6198     REWRITE_TAC[REAL_MUL_RNEG; SUM_NEG; REAL_LE_NEG2] THEN
6199     DISCH_THEN MATCH_MP_TAC THEN REAL_ARITH_TAC) in
6200   let version2 = prove
6201    (`!a x k:A->bool.
6202           FINITE k /\ sum k a = &1 /\ (!i. i IN k ==> &0 < a i /\ &0 <= x i)
6203           ==> product k (\i. x i rpow a i) <= sum k (\i. a i * x i)`,
6204     REPEAT STRIP_TAC THEN ASM_CASES_TAC `?i:A. i IN k /\ x i = &0` THENL
6205      [MATCH_MP_TAC(REAL_ARITH `&0 <= y /\ x = &0 ==> x <= y`) THEN
6206       CONJ_TAC THENL
6207        [MATCH_MP_TAC SUM_POS_LE THEN ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE];
6208         ASM_SIMP_TAC[PRODUCT_EQ_0; RPOW_EQ_0] THEN
6209         ASM_MESON_TAC[REAL_LT_IMP_NZ]];
6210       MATCH_MP_TAC version1 THEN ASM_MESON_TAC[REAL_LT_LE]]) in
6211   REPEAT STRIP_TAC THEN
6212   SUBGOAL_THEN
6213    `product {i:A | i IN k /\ ~(a i = &0)} (\i. x i rpow a i)
6214     <= sum {i:A | i IN k /\ ~(a i = &0)} (\i. a i * x i)`
6215   MP_TAC THENL
6216    [MATCH_MP_TAC version2 THEN
6217     ASM_SIMP_TAC[FINITE_RESTRICT; REAL_LT_LE; IN_ELIM_THM] THEN
6218     FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
6219     GEN_REWRITE_TAC RAND_CONV [GSYM SUM_SUPPORT] THEN
6220     REWRITE_TAC[support; NEUTRAL_REAL_ADD];
6221     MATCH_MP_TAC EQ_IMP THEN CONV_TAC SYM_CONV THEN BINOP_TAC THENL
6222      [MATCH_MP_TAC PRODUCT_SUPERSET;
6223       MATCH_MP_TAC SUM_SUPERSET] THEN
6224     SIMP_TAC[IN_ELIM_THM; SUBSET_RESTRICT; IMP_CONJ; RPOW_0] THEN
6225     REWRITE_TAC[REAL_MUL_LZERO]]);;
6226
6227 let AGM_RPOW = prove
6228  (`!k:A->bool x n.
6229         k HAS_SIZE n /\ ~(n = 0) /\ (!i. i IN k ==> &0 <= x(i))
6230         ==> product k (\i. x(i) rpow (&1 / &n)) <= sum k (\i. x(i) / &n)`,
6231   REWRITE_TAC[HAS_SIZE] THEN REPEAT STRIP_TAC THEN
6232   MP_TAC(ISPECL [`\i:A. &1 / &n`; `x:A->real`; `k:A->bool`]
6233         AGM_GEN) THEN
6234   ASM_SIMP_TAC[SUM_CONST; REAL_LE_DIV; REAL_OF_NUM_LT; LE_1; ARITH;
6235                REAL_DIV_LMUL; REAL_OF_NUM_EQ; REAL_POS] THEN
6236   REWRITE_TAC[real_div; REAL_MUL_LID; REAL_MUL_AC]);;
6237
6238 let AGM_ROOT = prove
6239  (`!k:A->bool x n.
6240         k HAS_SIZE n /\ ~(n = 0) /\ (!i. i IN k ==> &0 <= x(i))
6241         ==> root n (product k x) <= sum k x / &n`,
6242   REWRITE_TAC[HAS_SIZE] THEN REPEAT STRIP_TAC THEN
6243   ASM_SIMP_TAC[ROOT_PRODUCT; real_div; GSYM SUM_RMUL] THEN
6244   ASM_SIMP_TAC[REAL_ROOT_RPOW; GSYM real_div] THEN
6245   REWRITE_TAC[REAL_ARITH `inv(x) = &1 / x`] THEN
6246   MATCH_MP_TAC AGM_RPOW THEN ASM_REWRITE_TAC[HAS_SIZE]);;
6247
6248 let AGM_SQRT = prove
6249  (`!x y. &0 <= x /\ &0 <= y ==> sqrt(x * y) <= (x + y) / &2`,
6250   REPEAT STRIP_TAC THEN MP_TAC
6251    (ISPECL [`{0,1}`; `\n. if n = 0 then (x:real) else y`; `2`] AGM_ROOT) THEN
6252   SIMP_TAC[SUM_CLAUSES; PRODUCT_CLAUSES; FINITE_RULES] THEN
6253   REWRITE_TAC[ARITH_EQ; IN_INSERT; NOT_IN_EMPTY;
6254               HAS_SIZE_CONV`s HAS_SIZE 2 `] THEN
6255   ASM_SIMP_TAC[ROOT_2; REAL_MUL_RID; REAL_ADD_RID;
6256                REAL_ARITH `x / &2 + y / &2 = (x + y) / &2`] THEN
6257   ASM_MESON_TAC[ARITH_RULE `~(1 = 0)`]);;
6258
6259 let AGM = prove
6260  (`!k:A->bool x n.
6261         k HAS_SIZE n /\ ~(n = 0) /\ (!i. i IN k ==> &0 <= x(i))
6262         ==> product k x <= (sum k x / &n) pow n`,
6263   REWRITE_TAC[HAS_SIZE] THEN REPEAT STRIP_TAC THEN
6264   TRANS_TAC REAL_LE_TRANS `root n (product (k:A->bool) x) pow n` THEN
6265   CONJ_TAC THENL
6266    [ASM_SIMP_TAC[REAL_POW_ROOT; PRODUCT_POS_LE; REAL_LE_REFL];
6267     MATCH_MP_TAC REAL_POW_LE2 THEN
6268     ASM_SIMP_TAC[AGM_ROOT; HAS_SIZE; ROOT_LE_0; PRODUCT_POS_LE]]);;
6269
6270 let AGM_2 = prove
6271  (`!x y u v.
6272         &0 <= x /\ &0 <= y /\ &0 <= u /\ &0 <= v /\ u + v = &1
6273         ==> x rpow u * y rpow v <= u * x + v * y`,
6274   REPEAT STRIP_TAC THEN
6275   MP_TAC(ISPECL [`\i. if i = 0 then u:real else v`;
6276                  `\i. if i = 0 then x:real else y`; `0..SUC 0`]
6277         AGM_GEN) THEN
6278   REWRITE_TAC[SUM_CLAUSES_NUMSEG; PRODUCT_CLAUSES_NUMSEG; ARITH] THEN
6279   REWRITE_TAC[FINITE_NUMSEG] THEN ASM_MESON_TAC[]);;
6280
6281 let YOUNG_INEQUALITY = prove
6282  (`!a b p q. &0 <= a /\ &0 <= b /\ &0 < p /\ &0 < q /\ inv(p) + inv(q) = &1
6283              ==> a * b <= a rpow p / p + b rpow q / q`,
6284   REPEAT STRIP_TAC THEN
6285   MP_TAC(ISPECL [`a rpow p`; `b rpow q`; `inv p:real`; `inv q:real`]
6286         AGM_2) THEN
6287   ASM_SIMP_TAC[RPOW_RPOW; RPOW_POS_LE; REAL_LE_INV_EQ; REAL_LT_IMP_LE;
6288                REAL_MUL_RINV; RPOW_POW; REAL_POW_1; REAL_LT_IMP_NZ] THEN
6289   REAL_ARITH_TAC);;
6290
6291 let HOELDER = prove
6292  (`!k:A->bool a x y.
6293         FINITE k /\ sum k a = &1 /\
6294         (!i. i IN k ==> &0 <= a i /\ &0 <= x i /\ &0 <= y i)
6295         ==> product k (\i. x i rpow a i) + product k (\i. y i rpow a i)
6296             <= product k (\i. (x i + y i) rpow a i)`,
6297   REPEAT STRIP_TAC THEN
6298   SUBGOAL_THEN `&0 <= product (k:A->bool) (\i. (x i + y i) rpow a i)`
6299   MP_TAC THENL
6300    [MATCH_MP_TAC PRODUCT_POS_LE THEN ASM_SIMP_TAC[REAL_LE_ADD; RPOW_POS_LE];
6301     ALL_TAC] THEN
6302   REWRITE_TAC[REAL_ARITH `&0 <= x <=> x = &0 \/ &0 < x`] THEN
6303   ASM_SIMP_TAC[PRODUCT_EQ_0; RPOW_EQ_0; TAUT `p /\ q <=> ~(p ==> ~q)`;
6304    REAL_ARITH `&0 <= x /\ &0 <= y ==> (x + y = &0 <=> x = &0 /\ y = &0)`] THEN
6305   REWRITE_TAC[NOT_IMP] THEN STRIP_TAC THENL
6306    [MATCH_MP_TAC(REAL_ARITH
6307      `x = &0 /\ y = &0 /\ z = &0 ==> x + y <= z`) THEN
6308     ASM_SIMP_TAC[PRODUCT_EQ_0; RPOW_EQ_0] THEN ASM_MESON_TAC[REAL_ADD_LID];
6309     GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_LID]] THEN
6310   ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; GSYM PRODUCT_DIV; GSYM RPOW_DIV;
6311                REAL_ARITH `(x + y) / z:real = x / z + y / z`] THEN
6312   ASM_SIMP_TAC[GSYM RPOW_PRODUCT] THEN
6313   TRANS_TAC REAL_LE_TRANS
6314    `sum k (\i:A. a i * (x i / (x i + y i))) +
6315     sum k (\i. a i * (y i / (x i + y i)))` THEN
6316   CONJ_TAC THENL
6317    [MATCH_MP_TAC REAL_LE_ADD2 THEN CONJ_TAC THEN MATCH_MP_TAC AGM_GEN THEN
6318     ASM_SIMP_TAC[REAL_LE_ADD; REAL_LE_DIV];
6319     ASM_SIMP_TAC[GSYM SUM_ADD]] THEN
6320   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
6321    `s = &1 ==> p = s ==> p <= &1`)) THEN
6322   MATCH_MP_TAC SUM_EQ THEN ASM_REWRITE_TAC[] THEN
6323   X_GEN_TAC `i:A` THEN DISCH_TAC THEN
6324   ASM_CASES_TAC `(a:A->real) i = &0` THEN
6325   ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_ADD_LID] THEN
6326   FIRST_X_ASSUM(MP_TAC o MATCH_MP REAL_LT_IMP_NZ) THEN
6327   ASM_SIMP_TAC[PRODUCT_EQ_0; RPOW_EQ_0; NOT_EXISTS_THM] THEN
6328   DISCH_THEN(MP_TAC o SPEC `i:A`) THEN ASM_REWRITE_TAC[] THEN
6329   CONV_TAC REAL_FIELD);;
6330
6331 (* ------------------------------------------------------------------------- *)
6332 (* Some other inequalities where it's handy just to use calculus.            *)
6333 (* ------------------------------------------------------------------------- *)
6334
6335 let RPOW_MINUS1_QUOTIENT_LT = prove
6336  (`!a x y. &0 < a /\ ~(a = &1) /\ &0 < x /\ x < y
6337            ==> (a rpow x - &1) / x < (a rpow y - &1) / y`,
6338   REPEAT STRIP_TAC THEN
6339   MP_TAC(ISPECL [`\x. (a rpow x - &1) / x`;
6340                  `\x. log a * a rpow x / x - (a rpow x - &1) / x pow 2`;
6341                  `x:real`; `y:real`]
6342    HAS_REAL_DERIVATIVE_STRICTLY_INCREASING_IMP) THEN
6343   ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN DISCH_THEN MATCH_MP_TAC THEN
6344   CONJ_TAC THENL
6345    [ASM_SIMP_TAC[rpow] THEN REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN
6346     REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD;
6347     ALL_TAC] THEN
6348   X_GEN_TAC `z:real` THEN DISCH_TAC THEN
6349   SUBGOAL_THEN `&0 < z` ASSUME_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
6350   MATCH_MP_TAC REAL_LT_LCANCEL_IMP THEN
6351   EXISTS_TAC `(z:real) pow 2` THEN
6352   ASM_SIMP_TAC[REAL_POW_LT; REAL_MUL_RZERO; REAL_FIELD
6353    `&0 < x ==> x pow 2 * (a * b / x - c / x pow 2) = a * b * x - c`] THEN
6354   REWRITE_TAC[REAL_ARITH `l * a * z - (a - &1) = a * (l * z - &1) + &1`] THEN
6355   MP_TAC(ISPECL [`\x. a rpow x * (log a * x - &1) + &1`;
6356                  `\x. log(a) pow 2 * x * a rpow x`;
6357                  `&0`; `z:real`]
6358    HAS_REAL_DERIVATIVE_STRICTLY_INCREASING_IMP) THEN
6359   ASM_REWRITE_TAC[RPOW_0] THEN
6360   ANTS_TAC THENL [ALL_TAC; REAL_ARITH_TAC] THEN CONJ_TAC THENL
6361    [REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN
6362     REPEAT(POP_ASSUM MP_TAC) THEN CONV_TAC REAL_FIELD;
6363     REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN
6364     REPEAT(MATCH_MP_TAC REAL_LT_MUL THEN CONJ_TAC) THEN
6365     ASM_SIMP_TAC[RPOW_POS_LT; REAL_LT_POW_2] THEN
6366     ASM_SIMP_TAC[GSYM LOG_1; LOG_INJ; REAL_LT_01]]);;
6367
6368 let RPOW_MINUS1_QUOTIENT_LE = prove
6369  (`!a x y. &0 < a /\ &0 < x /\ x <= y
6370            ==> (a rpow x - &1) / x <= (a rpow y - &1) / y`,
6371   REPEAT GEN_TAC THEN ASM_CASES_TAC `x:real = y` THEN
6372   ASM_REWRITE_TAC[REAL_LE_REFL] THEN
6373   ASM_CASES_TAC `a = &1` THEN
6374   ASM_REWRITE_TAC[real_div; RPOW_ONE; REAL_SUB_REFL; REAL_MUL_LZERO;
6375                   REAL_LE_REFL] THEN
6376   ASM_SIMP_TAC[REAL_LE_LT; GSYM real_div; RPOW_MINUS1_QUOTIENT_LT]);;
6377
6378 let REAL_EXP_LIMIT_RPOW_LT = prove
6379  (`!x r s. &0 < r /\ r < s /\ ~(x = &0) /\ x < r
6380            ==> (&1 - x / r) rpow r < (&1 - x / s) rpow s`,
6381   REPEAT STRIP_TAC THEN
6382   SUBGOAL_THEN `&0 < s` STRIP_ASSUME_TAC THENL
6383    [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
6384   SUBGOAL_THEN `&0 < &1 - x / s` ASSUME_TAC THENL
6385    [ASM_SIMP_TAC[REAL_SUB_LT; REAL_LT_LDIV_EQ] THEN ASM_REAL_ARITH_TAC;
6386     ALL_TAC] THEN
6387   MP_TAC(ISPECL
6388    [`(&1 - x / s) rpow (inv r)`; `r:real`; `s:real`]
6389         RPOW_MINUS1_QUOTIENT_LT) THEN
6390   ASM_SIMP_TAC[RPOW_RPOW; REAL_MUL_LINV; REAL_LT_IMP_NZ; REAL_LT_IMP_LE;
6391                RPOW_POW; REAL_POW_1; RPOW_POS_LT] THEN
6392   ANTS_TAC THENL
6393    [ASM_SIMP_TAC[rpow; GSYM REAL_EXP_0; REAL_EXP_INJ] THEN
6394     ASM_SIMP_TAC[REAL_ENTIRE; REAL_INV_EQ_0; REAL_LT_IMP_NZ] THEN
6395     REWRITE_TAC[REAL_EXP_0] THEN
6396     ASM_SIMP_TAC[GSYM LOG_1; LOG_INJ; REAL_LT_01] THEN
6397     REWRITE_TAC[REAL_ARITH `a - x = a <=> x = &0`; REAL_DIV_EQ_0] THEN
6398     ASM_REAL_ARITH_TAC;
6399     REWRITE_TAC[REAL_ARITH `(&1 - x / s - &1) / r = --(x / r) / s`] THEN
6400     ASM_SIMP_TAC[REAL_LT_DIV2_EQ; REAL_ARITH
6401       `--x < a - &1 <=> &1 - x < a`] THEN
6402     DISCH_THEN(MP_TAC o SPEC `r:real` o MATCH_MP(MESON[RPOW_LT2]
6403      `x < y ==> !z. &0 <= x /\ &0 < z ==> x rpow z < y rpow z`)) THEN
6404     ASM_SIMP_TAC[RPOW_RPOW; REAL_LT_IMP_LE; REAL_FIELD
6405      `&0 < r ==> (inv r * s) * r = s`] THEN
6406     DISCH_THEN MATCH_MP_TAC THEN
6407     ASM_SIMP_TAC[REAL_SUB_LE; REAL_LE_LDIV_EQ] THEN ASM_REAL_ARITH_TAC]);;
6408
6409 let REAL_EXP_LIMIT_RPOW_LE = prove
6410  (`!x r s. &0 <= r /\ r <= s /\ x <= r
6411            ==> (&1 - x / r) rpow r <= (&1 - x / s) rpow s`,
6412   REPEAT GEN_TAC THEN ASM_CASES_TAC `x = &0` THENL
6413    [ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO; REAL_SUB_RZERO; RPOW_ONE];
6414     ALL_TAC] THEN
6415   ASM_CASES_TAC `r:real = s` THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN
6416   ASM_CASES_TAC `r:real = x` THENL
6417    [ASM_SIMP_TAC[REAL_DIV_REFL; REAL_SUB_REFL; RPOW_ZERO] THEN
6418     STRIP_TAC THEN MATCH_MP_TAC RPOW_POS_LE THEN
6419     REWRITE_TAC[REAL_SUB_LE] THEN
6420     SUBGOAL_THEN `&0 < s` (fun th -> SIMP_TAC[th; REAL_LE_LDIV_EQ]) THEN
6421     ASM_REAL_ARITH_TAC;
6422     ALL_TAC] THEN
6423   ASM_CASES_TAC `r = &0` THEN
6424   ASM_SIMP_TAC[REAL_LE_LT; REAL_EXP_LIMIT_RPOW_LT] THEN
6425   STRIP_TAC THEN REWRITE_TAC[GSYM REAL_LE_LT; RPOW_POW; real_pow] THEN
6426   ASM_SIMP_TAC[rpow; REAL_SUB_LT; REAL_LT_LDIV_EQ] THEN COND_CASES_TAC THENL
6427    [ALL_TAC; MATCH_MP_TAC(TAUT `F ==> p`) THEN ASM_REAL_ARITH_TAC] THEN
6428   GEN_REWRITE_TAC LAND_CONV [GSYM REAL_EXP_0] THEN
6429   REWRITE_TAC[REAL_EXP_MONO_LE] THEN MATCH_MP_TAC REAL_LE_MUL THEN
6430   ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN MATCH_MP_TAC LOG_POS THEN
6431   REWRITE_TAC[REAL_ARITH `&1 <= &1 - x / y <=> &0 <= --x / y`] THEN
6432   MATCH_MP_TAC REAL_LE_DIV THEN ASM_REAL_ARITH_TAC);;
6433
6434 let REAL_LE_X_SINH = prove
6435  (`!x. &0 <= x ==> x <= (exp x - inv(exp x)) / &2`,
6436   SUBGOAL_THEN
6437    `!a b. a <= b
6438           ==> exp a - inv(exp a) - &2 * a <= exp b - inv(exp b) - &2 * b`
6439    (MP_TAC o SPEC `&0`)
6440   THENL
6441    [MP_TAC(ISPECL
6442      [`\x. exp x - exp(--x) - &2 * x`; `\x. exp x + exp(--x) - &2`; `(:real)`]
6443      HAS_REAL_DERIVATIVE_INCREASING) THEN
6444     REWRITE_TAC[IN_ELIM_THM; IS_REALINTERVAL_UNIV; IN_UNIV] THEN ANTS_TAC THENL
6445      [CONJ_TAC THENL [SET_TAC[REAL_ARITH `~(&1 = &0)`]; ALL_TAC] THEN
6446       GEN_TAC THEN REAL_DIFF_TAC THEN REAL_ARITH_TAC;
6447       SIMP_TAC[REAL_EXP_NEG] THEN DISCH_THEN(fun th -> SIMP_TAC[GSYM th]) THEN
6448       X_GEN_TAC `x:real` THEN
6449       SIMP_TAC[REAL_EXP_NZ; REAL_FIELD
6450        `~(e = &0) ==> e + inv e - &2 = (e - &1) pow 2 / e`] THEN
6451       SIMP_TAC[REAL_EXP_POS_LE; REAL_LE_DIV; REAL_LE_POW_2]];
6452     MATCH_MP_TAC MONO_FORALL THEN REWRITE_TAC[REAL_EXP_0] THEN
6453     REAL_ARITH_TAC]);;
6454
6455 let REAL_LE_ABS_SINH = prove
6456  (`!x. abs x <= abs((exp x - inv(exp x)) / &2)`,
6457   GEN_TAC THEN ASM_CASES_TAC `&0 <= x` THENL
6458    [MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= y ==> abs x <= abs y`) THEN
6459     ASM_SIMP_TAC[REAL_LE_X_SINH];
6460     MATCH_MP_TAC(REAL_ARITH `~(&0 <= x) /\ --x <= --y ==> abs x <= abs y`) THEN
6461     ASM_REWRITE_TAC[REAL_ARITH `--((a - b) / &2) = (b - a) / &2`] THEN
6462     MATCH_MP_TAC REAL_LE_TRANS THEN
6463     EXISTS_TAC `(exp(--x) - inv(exp(--x))) / &2` THEN
6464     ASM_SIMP_TAC[REAL_LE_X_SINH; REAL_ARITH `~(&0 <= x) ==> &0 <= --x`] THEN
6465     REWRITE_TAC[REAL_EXP_NEG; REAL_INV_INV] THEN REAL_ARITH_TAC]);;
6466
6467 (* ------------------------------------------------------------------------- *)
6468 (* Log-convex functions.                                                     *)
6469 (* ------------------------------------------------------------------------- *)
6470
6471 parse_as_infix("log_convex_on",(12,"right"));;
6472
6473 let log_convex_on = new_definition
6474  `f log_convex_on (s:real^N->bool) <=>
6475         (!x y u v. x IN s /\ y IN s /\ &0 <= u /\ &0 <= v /\ u + v = &1
6476                    ==> &0 <= f(u % x + v % y) /\
6477                        f(u % x + v % y) <= f(x) rpow u * f(y) rpow v)`;;
6478
6479 let LOG_CONVEX_ON_SUBSET = prove
6480  (`!f s t. f log_convex_on t /\ s SUBSET t ==> f log_convex_on s`,
6481   REWRITE_TAC[log_convex_on] THEN SET_TAC[]);;
6482
6483 let LOG_CONVEX_IMP_POS = prove
6484  (`!f s x:real^N.
6485         f log_convex_on s /\ x IN s ==> &0 <= f x`,
6486   REWRITE_TAC[log_convex_on] THEN REPEAT STRIP_TAC THEN
6487   FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `x:real^N`; `&0`; `&1`]) THEN
6488   REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_MUL_LID; VECTOR_ADD_LID] THEN
6489   CONV_TAC REAL_RAT_REDUCE_CONV THEN ASM_MESON_TAC[]);;
6490
6491 let LOG_CONVEX_ON_CONVEX = prove
6492  (`!f s:real^N->bool.
6493         convex s
6494         ==> (f log_convex_on s <=>
6495              (!x. x IN s ==> &0 <= f x) /\
6496              !x y u v. x IN s /\ y IN s /\ &0 <= u /\ &0 <= v /\ u + v = &1
6497                        ==> f(u % x + v % y) <= f(x) rpow u * f(y) rpow v)`,
6498   REWRITE_TAC[convex] THEN REPEAT(STRIP_TAC ORELSE EQ_TAC) THENL
6499    [ASM_MESON_TAC[LOG_CONVEX_IMP_POS];
6500     ASM_MESON_TAC[log_convex_on];
6501     ASM_SIMP_TAC[log_convex_on] THEN ASM_MESON_TAC[]]);;
6502
6503 let LOG_CONVEX_ON = prove
6504  (`!f s:real^N->bool.
6505         convex s /\ (!x. x IN s ==> &0 < f x)
6506         ==> (f log_convex_on s <=> (log o f) convex_on s)`,
6507   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[LOG_CONVEX_ON_CONVEX; REAL_LT_IMP_LE] THEN
6508   RULE_ASSUM_TAC(REWRITE_RULE[convex]) THEN REWRITE_TAC[convex_on; o_DEF] THEN
6509   GEN_REWRITE_TAC (RAND_CONV o funpow 4 BINDER_CONV o RAND_CONV)
6510     [GSYM REAL_EXP_MONO_LE] THEN
6511   ASM_SIMP_TAC[EXP_LOG; rpow; REAL_EXP_ADD]);;
6512
6513 let LOG_CONVEX_IMP_CONVEX = prove
6514  (`!f s:real^N->bool. f log_convex_on s ==> f convex_on s`,
6515   REPEAT STRIP_TAC THEN
6516   FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
6517     LOG_CONVEX_IMP_POS)) THEN
6518   RULE_ASSUM_TAC(REWRITE_RULE[log_convex_on]) THEN REWRITE_TAC[convex_on] THEN
6519   MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `u:real`; `v:real`] THEN
6520   STRIP_TAC THEN FIRST_X_ASSUM
6521    (MP_TAC o SPECL [`x:real^N`; `y:real^N`; `u:real`; `v:real`]) THEN
6522   ASM_SIMP_TAC[] THEN DISCH_THEN(MP_TAC o CONJUNCT2) THEN
6523   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
6524   MATCH_MP_TAC AGM_2 THEN ASM_SIMP_TAC[]);;
6525
6526 let LOG_CONVEX_ADD = prove
6527  (`!f g s:real^N->bool.
6528         f log_convex_on s /\ g log_convex_on s
6529         ==> (\x. f x + g x) log_convex_on s`,
6530   REPEAT GEN_TAC THEN DISCH_TAC THEN
6531   FIRST_ASSUM(CONJUNCTS_THEN(ASSUME_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
6532     LOG_CONVEX_IMP_POS))) THEN
6533   REWRITE_TAC[log_convex_on] THEN
6534   FIRST_X_ASSUM(CONJUNCTS_THEN (ASSUME_TAC o REWRITE_RULE[log_convex_on])) THEN
6535   REWRITE_TAC[log_convex_on] THEN
6536   MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `u:real`; `v:real`] THEN
6537   STRIP_TAC THEN ASM_SIMP_TAC[REAL_LE_ADD] THEN
6538   MP_TAC(ISPEC `0..SUC 0` HOELDER) THEN
6539   SIMP_TAC[PRODUCT_CLAUSES_NUMSEG;
6540            FINITE_NUMSEG; SUM_CLAUSES_NUMSEG; ARITH] THEN
6541   DISCH_THEN(MP_TAC o SPECL
6542    [`\i. if i = 0 then u:real else v`;
6543     `\i. if i = 0 then (f:real^N->real) x else f y`;
6544     `\i. if i = 0 then (g:real^N->real) x else g y`]) THEN
6545   REWRITE_TAC[ARITH] THEN ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
6546   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN
6547   MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_MESON_TAC[]);;
6548
6549 let LOG_CONVEX_MUL = prove
6550  (`!f g s:real^N->bool.
6551         f log_convex_on s /\ g log_convex_on s
6552         ==> (\x. f x * g x) log_convex_on s`,
6553   REWRITE_TAC[log_convex_on] THEN REPEAT STRIP_TAC THEN
6554   ASM_SIMP_TAC[REAL_LE_MUL; RPOW_MUL] THEN
6555   ONCE_REWRITE_TAC[REAL_ARITH
6556    `(a * b) * (c * d):real = (a * c) * (b * d)`] THEN
6557   ASM_SIMP_TAC[REAL_LE_MUL2]);;
6558
6559 let MIDPOINT_LOG_CONVEX = prove
6560  (`!f s:real^N->bool.
6561         (lift o f) continuous_on s /\ convex s /\
6562         (!x. x IN s ==> &0 < f x) /\
6563         (!x y. x IN s /\ y IN s ==> f(midpoint(x,y)) pow 2 <= f(x) * f(y))
6564         ==> f log_convex_on s`,
6565   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[LOG_CONVEX_ON] THEN
6566   MATCH_MP_TAC CONTINUOUS_MIDPOINT_CONVEX THEN ASM_REWRITE_TAC[] THEN
6567   CONJ_TAC THENL
6568    [SUBGOAL_THEN `lift o log o (f:real^N->real) =
6569                   (lift o log o drop) o (lift o f)`
6570     SUBST1_TAC THENL [REWRITE_TAC[o_DEF; LIFT_DROP]; ALL_TAC] THEN
6571     MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
6572     ASM_REWRITE_TAC[GSYM REAL_CONTINUOUS_ON; IMAGE_o] THEN
6573     MATCH_MP_TAC REAL_CONTINUOUS_ON_LOG THEN
6574     ASM_REWRITE_TAC[FORALL_IN_IMAGE];
6575     MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
6576     REWRITE_TAC[o_DEF; REAL_ARITH `x <= y / &2 <=> &2 * x <= y`] THEN
6577     ONCE_REWRITE_TAC[GSYM REAL_EXP_MONO_LE] THEN
6578     ASM_SIMP_TAC[REAL_EXP_N; EXP_LOG; REAL_EXP_ADD; MIDPOINT_IN_CONVEX]]);;
6579
6580 let LOG_CONVEX_CONST = prove
6581  (`!s a. &0 <= a ==> (\x. a) log_convex_on s`,
6582   SIMP_TAC[log_convex_on; GSYM RPOW_ADD] THEN
6583   IMP_REWRITE_TAC[GSYM RPOW_ADD_ALT] THEN
6584   REWRITE_TAC[RPOW_POW; REAL_POW_1; REAL_LE_REFL] THEN REAL_ARITH_TAC);;
6585
6586 let LOG_CONVEX_PRODUCT = prove
6587  (`!f s k. FINITE k /\ (!i. i IN k ==> (\x. f x i) log_convex_on s)
6588            ==> (\x. product k (f x)) log_convex_on s`,
6589   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
6590   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
6591   SIMP_TAC[PRODUCT_CLAUSES; LOG_CONVEX_CONST; REAL_POS] THEN
6592   SIMP_TAC[FORALL_IN_INSERT; LOG_CONVEX_MUL]);;
6593
6594 (* ------------------------------------------------------------------------- *)
6595 (* Real log-convex functions.                                                *)
6596 (* ------------------------------------------------------------------------- *)
6597
6598 parse_as_infix("real_log_convex_on",(12,"right"));;
6599
6600 let real_log_convex_on = new_definition
6601  `(f:real->real) real_log_convex_on s <=>
6602         (!x y u v. x IN s /\ y IN s /\ &0 <= u /\ &0 <= v /\ u + v = &1
6603                    ==> &0 <= f(u * x + v * y) /\
6604                        f(u * x + v * y) <= f(x) rpow u * f(y) rpow v)`;;
6605
6606 let REAL_LOG_CONVEX_ON_SUBSET = prove
6607  (`!f s t. f real_log_convex_on t /\ s SUBSET t ==> f real_log_convex_on s`,
6608   REWRITE_TAC[real_log_convex_on] THEN SET_TAC[]);;
6609
6610 let REAL_LOG_CONVEX_LOG_CONVEX = prove
6611  (`!f s. f real_log_convex_on s <=> (f o drop) log_convex_on (IMAGE lift s)`,
6612   REWRITE_TAC[real_log_convex_on; log_convex_on] THEN
6613   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
6614   REWRITE_TAC[o_DEF; DROP_ADD; DROP_CMUL; LIFT_DROP]);;
6615
6616 let REAL_LOG_CONVEX_IMP_POS = prove
6617  (`!f s x.
6618         f real_log_convex_on s /\ x IN s ==> &0 <= f x`,
6619   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; REAL_LOG_CONVEX_LOG_CONVEX] THEN
6620   REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP
6621    (REWRITE_RULE[IMP_CONJ] LOG_CONVEX_IMP_POS)) THEN
6622   REWRITE_TAC[o_DEF; FORALL_IN_IMAGE; LIFT_DROP]);;
6623
6624 let REAL_LOG_CONVEX_ON_CONVEX = prove
6625  (`!f s.
6626         is_realinterval s
6627         ==> (f real_log_convex_on s <=>
6628              (!x. x IN s ==> &0 <= f x) /\
6629              !x y u v. x IN s /\ y IN s /\ &0 <= u /\ &0 <= v /\ u + v = &1
6630                        ==> f(u * x + v * y) <= f(x) rpow u * f(y) rpow v)`,
6631   REWRITE_TAC[REAL_CONVEX] THEN REPEAT(STRIP_TAC ORELSE EQ_TAC) THENL
6632    [ASM_MESON_TAC[REAL_LOG_CONVEX_IMP_POS];
6633     ASM_MESON_TAC[real_log_convex_on];
6634     ASM_SIMP_TAC[real_log_convex_on] THEN ASM_MESON_TAC[]]);;
6635
6636 let REAL_LOG_CONVEX_ON = prove
6637  (`!f s:real->bool.
6638         is_realinterval s /\ (!x. x IN s ==> &0 < f x)
6639         ==> (f real_log_convex_on s <=> (log o f) real_convex_on s)`,
6640   REPEAT STRIP_TAC THEN
6641   ASM_SIMP_TAC[REAL_LOG_CONVEX_ON_CONVEX; REAL_LT_IMP_LE] THEN
6642   RULE_ASSUM_TAC(REWRITE_RULE[REAL_CONVEX]) THEN
6643   REWRITE_TAC[real_convex_on; o_DEF] THEN
6644   GEN_REWRITE_TAC (RAND_CONV o funpow 4 BINDER_CONV o RAND_CONV)
6645     [GSYM REAL_EXP_MONO_LE] THEN
6646   ASM_SIMP_TAC[EXP_LOG; rpow; REAL_EXP_ADD]);;
6647
6648 let REAL_LOG_CONVEX_IMP_CONVEX = prove
6649  (`!f s:real->bool. f real_log_convex_on s ==> f real_convex_on s`,
6650   REPEAT STRIP_TAC THEN
6651   FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
6652     REAL_LOG_CONVEX_IMP_POS)) THEN
6653   RULE_ASSUM_TAC(REWRITE_RULE[real_log_convex_on]) THEN
6654   REWRITE_TAC[real_convex_on] THEN
6655   MAP_EVERY X_GEN_TAC [`x:real`; `y:real`; `u:real`; `v:real`] THEN
6656   STRIP_TAC THEN FIRST_X_ASSUM
6657    (MP_TAC o SPECL [`x:real`; `y:real`; `u:real`; `v:real`]) THEN
6658   ASM_SIMP_TAC[] THEN DISCH_THEN(MP_TAC o CONJUNCT2) THEN
6659   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
6660   MATCH_MP_TAC AGM_2 THEN ASM_SIMP_TAC[]);;
6661
6662 let REAL_LOG_CONVEX_ADD = prove
6663  (`!f g s:real->bool.
6664         f real_log_convex_on s /\ g real_log_convex_on s
6665         ==> (\x. f x + g x) real_log_convex_on s`,
6666   REPEAT GEN_TAC THEN DISCH_TAC THEN
6667   FIRST_ASSUM(CONJUNCTS_THEN(ASSUME_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
6668     REAL_LOG_CONVEX_IMP_POS))) THEN
6669   REWRITE_TAC[real_log_convex_on] THEN
6670   FIRST_X_ASSUM(CONJUNCTS_THEN
6671     (ASSUME_TAC o REWRITE_RULE[real_log_convex_on])) THEN
6672   REWRITE_TAC[real_log_convex_on] THEN
6673   MAP_EVERY X_GEN_TAC [`x:real`; `y:real`; `u:real`; `v:real`] THEN
6674   STRIP_TAC THEN ASM_SIMP_TAC[REAL_LE_ADD] THEN
6675   MP_TAC(ISPEC `0..SUC 0` HOELDER) THEN
6676   SIMP_TAC[PRODUCT_CLAUSES_NUMSEG;
6677            FINITE_NUMSEG; SUM_CLAUSES_NUMSEG; ARITH] THEN
6678   DISCH_THEN(MP_TAC o SPECL
6679    [`\i. if i = 0 then u:real else v`;
6680     `\i. if i = 0 then (f:real->real) x else f y`;
6681     `\i. if i = 0 then (g:real->real) x else g y`]) THEN
6682   REWRITE_TAC[ARITH] THEN ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
6683   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN
6684   MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_MESON_TAC[]);;
6685
6686 let REAL_LOG_CONVEX_MUL = prove
6687  (`!f g s:real->bool.
6688         f real_log_convex_on s /\ g real_log_convex_on s
6689         ==> (\x. f x * g x) real_log_convex_on s`,
6690   REWRITE_TAC[real_log_convex_on] THEN REPEAT STRIP_TAC THEN
6691   ASM_SIMP_TAC[REAL_LE_MUL; RPOW_MUL] THEN
6692   ONCE_REWRITE_TAC[REAL_ARITH
6693    `(a * b) * (c * d):real = (a * c) * (b * d)`] THEN
6694   ASM_SIMP_TAC[REAL_LE_MUL2]);;
6695
6696 let MIDPOINT_REAL_LOG_CONVEX = prove
6697  (`!f s:real->bool.
6698         f real_continuous_on s /\ is_realinterval s /\
6699         (!x. x IN s ==> &0 < f x) /\
6700         (!x y. x IN s /\ y IN s ==> f((x + y) / &2) pow 2 <= f(x) * f(y))
6701         ==> f real_log_convex_on s`,
6702   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[REAL_LOG_CONVEX_ON] THEN
6703   MATCH_MP_TAC REAL_CONTINUOUS_MIDPOINT_CONVEX THEN ASM_REWRITE_TAC[] THEN
6704   CONJ_TAC THENL
6705    [MATCH_MP_TAC REAL_CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN
6706     MATCH_MP_TAC REAL_CONTINUOUS_ON_LOG THEN
6707     ASM_REWRITE_TAC[FORALL_IN_IMAGE];
6708     MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN STRIP_TAC THEN
6709     REWRITE_TAC[o_DEF; REAL_ARITH `x <= y / &2 <=> &2 * x <= y`] THEN
6710     ONCE_REWRITE_TAC[GSYM REAL_EXP_MONO_LE] THEN
6711     ASM_SIMP_TAC[REAL_EXP_N; EXP_LOG; REAL_EXP_ADD; REAL_MIDPOINT_IN_CONVEX]]);;
6712
6713 let REAL_LOG_CONVEX_CONST = prove
6714  (`!s a. &0 <= a ==> (\x. a) real_log_convex_on s`,
6715   SIMP_TAC[real_log_convex_on; GSYM RPOW_ADD] THEN
6716   IMP_REWRITE_TAC[GSYM RPOW_ADD_ALT] THEN
6717   REWRITE_TAC[RPOW_POW; REAL_POW_1; REAL_LE_REFL] THEN REAL_ARITH_TAC);;
6718
6719 let REAL_LOG_CONVEX_PRODUCT = prove
6720  (`!f s k. FINITE k /\ (!i. i IN k ==> (\x. f x i) real_log_convex_on s)
6721            ==> (\x. product k (f x)) real_log_convex_on s`,
6722   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
6723   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
6724   SIMP_TAC[PRODUCT_CLAUSES; REAL_LOG_CONVEX_CONST; REAL_POS] THEN
6725   SIMP_TAC[FORALL_IN_INSERT; REAL_LOG_CONVEX_MUL]);;
6726
6727 let REAL_LOG_CONVEX_RPOW_RIGHT = prove
6728  (`!s a. &0 < a ==> (\x. a rpow x) real_log_convex_on s`,
6729   SIMP_TAC[real_log_convex_on; RPOW_POS_LE; REAL_LT_IMP_LE] THEN
6730   SIMP_TAC[DROP_ADD; DROP_CMUL; RPOW_ADD; RPOW_RPOW; REAL_LT_IMP_LE] THEN
6731   REWRITE_TAC[REAL_MUL_AC; REAL_LE_REFL]);;
6732
6733 let REAL_LOG_CONVEX_LIM = prove
6734  (`!net:A net f g s.
6735        ~(trivial_limit net) /\
6736        (!x y u v. x IN s /\ y IN s /\ &0 <= u /\ &0 <= v /\ u + v = &1
6737                   ==> ((\i. f i (u * x + v * y)) ---> g(u * x + v * y)) net) /\
6738        eventually (\i. (f i) real_log_convex_on s) net
6739        ==> g real_log_convex_on s`,
6740   REWRITE_TAC[real_log_convex_on] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
6741   REPEAT GEN_TAC THEN STRIP_TAC THEN
6742   GEN_REWRITE_TAC RAND_CONV [GSYM REAL_SUB_LE] THEN
6743   CONJ_TAC THEN MATCH_MP_TAC(ISPEC `net:A net` REALLIM_LBOUND) THENL
6744    [EXISTS_TAC `\i. (f:A->real->real) i (u * x + v * y)`;
6745     EXISTS_TAC `\i. (f:A->real->real) i x rpow u * f i y rpow v -
6746                     f i (u * x + v * y)`] THEN
6747   ASM_SIMP_TAC[] THEN TRY CONJ_TAC THEN
6748   TRY(FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
6749         EVENTUALLY_MONO))) THEN
6750   ASM_SIMP_TAC[REAL_SUB_LE] THEN
6751   MATCH_MP_TAC REALLIM_SUB THEN ASM_SIMP_TAC[] THEN
6752   MATCH_MP_TAC REALLIM_MUL THEN CONJ_TAC THEN
6753   MATCH_MP_TAC(REWRITE_RULE[] (ISPEC `\x. x rpow y`
6754     REALLIM_REAL_CONTINUOUS_FUNCTION)) THEN
6755   ASM_SIMP_TAC[REAL_CONTINUOUS_AT_RPOW] THENL
6756    [FIRST_X_ASSUM(MP_TAC o SPECL [`x:real`; `x:real`; `&1`; `&0`]);
6757     FIRST_X_ASSUM(MP_TAC o SPECL [`y:real`; `y:real`; `&1`; `&0`])] THEN
6758   ASM_REWRITE_TAC[REAL_POS; REAL_ADD_RID; REAL_MUL_LZERO] THEN
6759   REWRITE_TAC[REAL_MUL_LID]);;
6760
6761 (* ------------------------------------------------------------------------- *)
6762 (* Integrals of real->real functions; measures of real sets.                 *)
6763 (* ------------------------------------------------------------------------- *)
6764
6765 parse_as_infix("has_real_integral",(12,"right"));;
6766 parse_as_infix("real_integrable_on",(12,"right"));;
6767 parse_as_infix("absolutely_real_integrable_on",(12,"right"));;
6768 parse_as_infix("has_real_measure",(12,"right"));;
6769
6770 let has_real_integral = new_definition
6771  `(f has_real_integral y) s <=>
6772         ((lift o f o drop) has_integral (lift y)) (IMAGE lift s)`;;
6773
6774 let real_integrable_on = new_definition
6775  `f real_integrable_on i <=> ?y. (f has_real_integral y) i`;;
6776
6777 let real_integral = new_definition
6778  `real_integral i f = @y. (f has_real_integral y) i`;;
6779
6780 let real_negligible = new_definition
6781  `real_negligible s <=> negligible (IMAGE lift s)`;;
6782
6783 let absolutely_real_integrable_on = new_definition
6784  `f absolutely_real_integrable_on s <=>
6785         f real_integrable_on s /\ (\x. abs(f x)) real_integrable_on s`;;
6786
6787 let has_real_measure = new_definition
6788  `s has_real_measure m <=> ((\x. &1) has_real_integral m) s`;;
6789
6790 let real_measurable = new_definition
6791  `real_measurable s <=> ?m. s has_real_measure m`;;
6792
6793 let real_measure = new_definition
6794  `real_measure s = @m. s has_real_measure m`;;
6795
6796 let HAS_REAL_INTEGRAL = prove
6797  (`(f has_real_integral y) (real_interval[a,b]) <=>
6798    ((lift o f o drop) has_integral (lift y)) (interval[lift a,lift b])`,
6799   REWRITE_TAC[has_real_integral; IMAGE_LIFT_REAL_INTERVAL]);;
6800
6801 let REAL_INTEGRABLE_INTEGRAL = prove
6802  (`!f i. f real_integrable_on i
6803          ==> (f has_real_integral (real_integral i f)) i`,
6804   REPEAT GEN_TAC THEN REWRITE_TAC[real_integrable_on; real_integral] THEN
6805   CONV_TAC(RAND_CONV SELECT_CONV) THEN REWRITE_TAC[]);;
6806
6807 let HAS_REAL_INTEGRAL_INTEGRABLE = prove
6808  (`!f i s. (f has_real_integral i) s ==> f real_integrable_on s`,
6809   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[]);;
6810
6811 let HAS_REAL_INTEGRAL_INTEGRAL = prove
6812  (`!f s. f real_integrable_on s <=>
6813          (f has_real_integral (real_integral s f)) s`,
6814   MESON_TAC[REAL_INTEGRABLE_INTEGRAL; HAS_REAL_INTEGRAL_INTEGRABLE]);;
6815
6816 let HAS_REAL_INTEGRAL_UNIQUE = prove
6817  (`!f i k1 k2.
6818         (f has_real_integral k1) i /\ (f has_real_integral k2) i ==> k1 = k2`,
6819   REPEAT GEN_TAC THEN REWRITE_TAC[has_real_integral] THEN
6820   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_UNIQUE) THEN
6821   REWRITE_TAC[LIFT_EQ]);;
6822
6823 let REAL_INTEGRAL_UNIQUE = prove
6824  (`!f y k.
6825       (f has_real_integral y) k ==> real_integral k f = y`,
6826   REPEAT STRIP_TAC THEN REWRITE_TAC[real_integral] THEN
6827   MATCH_MP_TAC SELECT_UNIQUE THEN ASM_MESON_TAC[HAS_REAL_INTEGRAL_UNIQUE]);;
6828
6829 let HAS_REAL_INTEGRAL_INTEGRABLE_INTEGRAL = prove
6830  (`!f i s.
6831         (f has_real_integral i) s <=>
6832         f real_integrable_on s /\ real_integral s f = i`,
6833   MESON_TAC[REAL_INTEGRABLE_INTEGRAL; REAL_INTEGRAL_UNIQUE;
6834             real_integrable_on]);;
6835
6836 let REAL_INTEGRAL_EQ_HAS_INTEGRAL = prove
6837  (`!s f y. f real_integrable_on s
6838            ==> (real_integral s f = y <=> (f has_real_integral y) s)`,
6839   MESON_TAC[REAL_INTEGRABLE_INTEGRAL; REAL_INTEGRAL_UNIQUE]);;
6840
6841 let REAL_INTEGRABLE_ON = prove
6842  (`f real_integrable_on s <=>
6843         (lift o f o drop) integrable_on (IMAGE lift s)`,
6844   REWRITE_TAC[real_integrable_on; has_real_integral; EXISTS_DROP;
6845               integrable_on; LIFT_DROP]);;
6846
6847 let ABSOLUTELY_REAL_INTEGRABLE_ON = prove
6848  (`f absolutely_real_integrable_on s <=>
6849         (lift o f o drop) absolutely_integrable_on (IMAGE lift s)`,
6850   REWRITE_TAC[absolutely_real_integrable_on; REAL_INTEGRABLE_ON;
6851               absolutely_integrable_on] THEN
6852   REWRITE_TAC[o_DEF; LIFT_DROP; NORM_LIFT]);;
6853
6854 let REAL_INTEGRAL = prove
6855  (`f real_integrable_on s
6856    ==> real_integral s f = drop(integral (IMAGE lift s) (lift o f o drop))`,
6857   REWRITE_TAC[REAL_INTEGRABLE_ON] THEN REPEAT STRIP_TAC THEN
6858   MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
6859   REWRITE_TAC[has_real_integral; LIFT_DROP] THEN
6860   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);;
6861
6862 let HAS_REAL_INTEGRAL_ALT = prove
6863  (`!f s i.
6864          (f has_real_integral i) s <=>
6865          (!a b. (\x. if x IN s then f x else &0) real_integrable_on
6866                 real_interval [a,b]) /\
6867          (!e. &0 < e
6868               ==> (?B. &0 < B /\
6869                        (!a b.
6870                             real_interval(--B,B) SUBSET real_interval[a,b]
6871                             ==> abs
6872                                 (real_integral (real_interval[a,b])
6873                                  (\x. if x IN s then f x else &0) -
6874                                  i) < e)))`,
6875   REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [has_real_integral] THEN
6876   GEN_REWRITE_TAC LAND_CONV [HAS_INTEGRAL_ALT] THEN
6877   REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF; IMAGE_LIFT_REAL_INTERVAL] THEN
6878   REWRITE_TAC[GSYM FORALL_LIFT; COND_RAND; LIFT_NUM; IN_IMAGE_LIFT_DROP] THEN
6879   MATCH_MP_TAC(TAUT `(p ==> (q <=> q')) ==> (p /\ q <=> p /\ q')`) THEN
6880   DISCH_TAC THEN REWRITE_TAC[BALL_1] THEN
6881   AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
6882   X_GEN_TAC `e:real` THEN ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
6883   AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
6884   X_GEN_TAC `B:real` THEN ASM_CASES_TAC `&0 < B` THEN ASM_REWRITE_TAC[] THEN
6885   REWRITE_TAC[FORALL_LIFT; VECTOR_ADD_LID; VECTOR_SUB_LZERO] THEN
6886   REWRITE_TAC[GSYM LIFT_NEG; GSYM IMAGE_LIFT_REAL_INTERVAL] THEN
6887   REWRITE_TAC[SUBSET_LIFT_IMAGE; NORM_REAL; GSYM drop] THEN
6888   AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
6889   X_GEN_TAC `a:real` THEN REWRITE_TAC[] THEN
6890   AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
6891   X_GEN_TAC `b:real` THEN
6892   ASM_CASES_TAC `real_interval(--B,B) SUBSET real_interval[a,b]` THEN
6893   ASM_REWRITE_TAC[DROP_SUB; LIFT_DROP] THEN
6894   AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
6895   AP_THM_TAC THEN AP_TERM_TAC THEN IMP_REWRITE_TAC[REAL_INTEGRAL] THEN
6896   REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF; LIFT_DROP; COND_RAND] THEN
6897   ASM_REWRITE_TAC[LIFT_NUM; IMAGE_LIFT_REAL_INTERVAL]);;
6898
6899 let HAS_REAL_INTEGRAL_IS_0 = prove
6900  (`!f s. (!x. x IN s ==> f(x) = &0) ==> (f has_real_integral &0) s`,
6901   REPEAT STRIP_TAC THEN REWRITE_TAC[has_real_integral; LIFT_NUM] THEN
6902   MATCH_MP_TAC HAS_INTEGRAL_IS_0 THEN
6903   ASM_REWRITE_TAC[LIFT_EQ; FORALL_IN_IMAGE; o_THM; LIFT_DROP; GSYM LIFT_NUM]);;
6904
6905 let HAS_REAL_INTEGRAL_0 = prove
6906  (`!s. ((\x. &0) has_real_integral &0) s`,
6907   SIMP_TAC[HAS_REAL_INTEGRAL_IS_0]);;
6908
6909 let HAS_REAL_INTEGRAL_0_EQ = prove
6910  (`!i s. ((\x. &0) has_real_integral i) s <=> i = &0`,
6911   MESON_TAC[HAS_REAL_INTEGRAL_UNIQUE; HAS_REAL_INTEGRAL_0]);;
6912
6913 let HAS_REAL_INTEGRAL_LINEAR = prove
6914  (`!f:real->real y s h:real->real.
6915         (f has_real_integral y) s /\ linear(lift o h o drop)
6916         ==> ((h o f) has_real_integral h(y)) s`,
6917   REPEAT GEN_TAC THEN REWRITE_TAC[has_real_integral] THEN
6918   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_LINEAR) THEN
6919   REWRITE_TAC[o_DEF; LIFT_DROP]);;
6920
6921 let HAS_REAL_INTEGRAL_LMUL = prove
6922  (`!(f:real->real) k s c.
6923         (f has_real_integral k) s
6924         ==> ((\x. c * f(x)) has_real_integral (c * k)) s`,
6925   REPEAT GEN_TAC THEN REWRITE_TAC[has_real_integral] THEN
6926   DISCH_THEN(MP_TAC o SPEC `c:real` o MATCH_MP HAS_INTEGRAL_CMUL) THEN
6927   REWRITE_TAC[GSYM LIFT_CMUL; o_DEF]);;
6928
6929 let HAS_REAL_INTEGRAL_RMUL = prove
6930  (`!(f:real->real) k s c.
6931         (f has_real_integral k) s
6932         ==> ((\x. f(x) * c) has_real_integral (k * c)) s`,
6933   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
6934   REWRITE_TAC[HAS_REAL_INTEGRAL_LMUL]);;
6935
6936 let HAS_REAL_INTEGRAL_NEG = prove
6937  (`!f k s. (f has_real_integral k) s
6938            ==> ((\x. --(f x)) has_real_integral (--k)) s`,
6939   REPEAT GEN_TAC THEN REWRITE_TAC[has_real_integral] THEN
6940   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_NEG) THEN
6941   REWRITE_TAC[o_DEF; LIFT_NEG]);;
6942
6943 let HAS_REAL_INTEGRAL_ADD = prove
6944  (`!f:real->real g k l s.
6945         (f has_real_integral k) s /\ (g has_real_integral l) s
6946         ==> ((\x. f(x) + g(x)) has_real_integral (k + l)) s`,
6947   REPEAT GEN_TAC THEN REWRITE_TAC[has_real_integral] THEN
6948   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_ADD) THEN
6949   REWRITE_TAC[o_DEF; LIFT_ADD]);;
6950
6951 let HAS_REAL_INTEGRAL_SUB = prove
6952  (`!f:real->real g k l s.
6953         (f has_real_integral k) s /\ (g has_real_integral l) s
6954         ==> ((\x. f(x) - g(x)) has_real_integral (k - l)) s`,
6955   REPEAT GEN_TAC THEN REWRITE_TAC[has_real_integral] THEN
6956   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_SUB) THEN
6957   REWRITE_TAC[o_DEF; LIFT_SUB]);;
6958
6959 let REAL_INTEGRAL_0 = prove
6960  (`!s. real_integral s (\x. &0) = &0`,
6961   MESON_TAC[REAL_INTEGRAL_UNIQUE; HAS_REAL_INTEGRAL_0]);;
6962
6963 let REAL_INTEGRAL_ADD = prove
6964  (`!f:real->real g s.
6965         f real_integrable_on s /\ g real_integrable_on s
6966         ==> real_integral s (\x. f x + g x) =
6967             real_integral s f + real_integral s g`,
6968   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
6969   MATCH_MP_TAC HAS_REAL_INTEGRAL_ADD THEN
6970   ASM_SIMP_TAC[REAL_INTEGRABLE_INTEGRAL]);;
6971
6972 let REAL_INTEGRAL_LMUL = prove
6973  (`!f:real->real c s.
6974         f real_integrable_on s
6975         ==> real_integral s (\x. c * f(x)) = c * real_integral s f`,
6976   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
6977   MATCH_MP_TAC HAS_REAL_INTEGRAL_LMUL THEN
6978   ASM_SIMP_TAC[REAL_INTEGRABLE_INTEGRAL]);;
6979
6980 let REAL_INTEGRAL_RMUL = prove
6981  (`!f:real->real c s.
6982         f real_integrable_on s
6983         ==> real_integral s (\x. f(x) * c) = real_integral s f * c`,
6984   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
6985   MATCH_MP_TAC HAS_REAL_INTEGRAL_RMUL THEN
6986   ASM_SIMP_TAC[REAL_INTEGRABLE_INTEGRAL]);;
6987
6988 let REAL_INTEGRAL_NEG = prove
6989  (`!f:real->real s.
6990         f real_integrable_on s
6991         ==> real_integral s (\x. --f(x)) = --real_integral s f`,
6992   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
6993   MATCH_MP_TAC HAS_REAL_INTEGRAL_NEG THEN
6994   ASM_SIMP_TAC[REAL_INTEGRABLE_INTEGRAL]);;
6995
6996 let REAL_INTEGRAL_SUB = prove
6997  (`!f:real->real g s.
6998         f real_integrable_on s /\ g real_integrable_on s
6999         ==> real_integral s (\x. f x - g x) =
7000             real_integral s f - real_integral s g`,
7001   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
7002   MATCH_MP_TAC HAS_REAL_INTEGRAL_SUB THEN
7003   ASM_SIMP_TAC[REAL_INTEGRABLE_INTEGRAL]);;
7004
7005 let REAL_INTEGRABLE_0 = prove
7006  (`!s. (\x. &0) real_integrable_on s`,
7007   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_0]);;
7008
7009 let REAL_INTEGRABLE_ADD = prove
7010  (`!f:real->real g s.
7011         f real_integrable_on s /\ g real_integrable_on s
7012         ==> (\x. f x + g x) real_integrable_on s`,
7013   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_ADD]);;
7014
7015 let REAL_INTEGRABLE_LMUL = prove
7016  (`!f:real->real c s.
7017         f real_integrable_on s
7018         ==> (\x. c * f(x)) real_integrable_on s`,
7019   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_LMUL]);;
7020
7021 let REAL_INTEGRABLE_RMUL = prove
7022  (`!f:real->real c s.
7023         f real_integrable_on s
7024         ==> (\x. f(x) * c) real_integrable_on s`,
7025   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_RMUL]);;
7026
7027 let REAL_INTEGRABLE_LMUL_EQ = prove
7028  (`!f s c.
7029         (\x. c * f x) real_integrable_on s <=>
7030         c = &0 \/ f real_integrable_on s`,
7031   REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN
7032   ASM_SIMP_TAC[REAL_INTEGRABLE_LMUL; REAL_MUL_LZERO] THEN
7033   REWRITE_TAC[REAL_INTEGRABLE_0] THEN
7034   ASM_CASES_TAC `c = &0` THEN ASM_REWRITE_TAC[] THEN
7035   FIRST_X_ASSUM(MP_TAC o SPEC `inv c:real` o
7036     MATCH_MP REAL_INTEGRABLE_LMUL) THEN
7037   ASM_SIMP_TAC[REAL_MUL_ASSOC; REAL_MUL_LID; REAL_MUL_LINV; ETA_AX]);;
7038
7039 let REAL_INTEGRABLE_RMUL_EQ = prove
7040  (`!f s c.
7041         (\x. f x * c) real_integrable_on s <=>
7042         c = &0 \/ f real_integrable_on s`,
7043   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
7044   REWRITE_TAC[REAL_INTEGRABLE_LMUL_EQ]);;
7045
7046 let REAL_INTEGRABLE_NEG = prove
7047  (`!f:real->real s.
7048         f real_integrable_on s ==> (\x. --f(x)) real_integrable_on s`,
7049   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_NEG]);;
7050
7051 let REAL_INTEGRABLE_SUB = prove
7052  (`!f:real->real g s.
7053         f real_integrable_on s /\ g real_integrable_on s
7054         ==> (\x. f x - g x) real_integrable_on s`,
7055   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_SUB]);;
7056
7057 let REAL_INTEGRABLE_LINEAR = prove
7058  (`!f h s. f real_integrable_on s /\
7059            linear(lift o h o drop) ==> (h o f) real_integrable_on s`,
7060   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_LINEAR]);;
7061
7062 let REAL_INTEGRAL_LINEAR = prove
7063  (`!f:real->real s h:real->real.
7064         f real_integrable_on s /\ linear(lift o h o drop)
7065         ==> real_integral s (h o f) = h(real_integral s f)`,
7066   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_UNIQUE THEN
7067   MAP_EVERY EXISTS_TAC
7068    [`(h:real->real) o (f:real->real)`; `s:real->bool`] THEN
7069   CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC HAS_REAL_INTEGRAL_LINEAR] THEN
7070   ASM_SIMP_TAC[GSYM HAS_REAL_INTEGRAL_INTEGRAL; REAL_INTEGRABLE_LINEAR]);;
7071
7072 let HAS_REAL_INTEGRAL_SUM = prove
7073  (`!f:A->real->real s t.
7074         FINITE t /\
7075         (!a. a IN t ==> ((f a) has_real_integral (i a)) s)
7076         ==> ((\x. sum t (\a. f a x)) has_real_integral (sum t i)) s`,
7077   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
7078   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
7079   SIMP_TAC[SUM_CLAUSES; HAS_REAL_INTEGRAL_0; IN_INSERT] THEN
7080   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_ADD THEN
7081   ASM_REWRITE_TAC[ETA_AX] THEN CONJ_TAC THEN
7082   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[]);;
7083
7084 let REAL_INTEGRAL_SUM = prove
7085  (`!f:A->real->real s t.
7086         FINITE t /\
7087         (!a. a IN t ==> (f a) real_integrable_on s)
7088         ==> real_integral s (\x. sum t (\a. f a x)) =
7089                 sum t (\a. real_integral s (f a))`,
7090   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
7091   MATCH_MP_TAC HAS_REAL_INTEGRAL_SUM THEN
7092   ASM_SIMP_TAC[REAL_INTEGRABLE_INTEGRAL]);;
7093
7094 let REAL_INTEGRABLE_SUM = prove
7095  (`!f:A->real->real s t.
7096         FINITE t /\
7097         (!a. a IN t ==> (f a) real_integrable_on s)
7098         ==>  (\x. sum t (\a. f a x)) real_integrable_on s`,
7099   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_SUM]);;
7100
7101 let HAS_REAL_INTEGRAL_EQ = prove
7102  (`!f:real->real g k s.
7103         (!x. x IN s ==> (f(x) = g(x))) /\
7104         (f has_real_integral k) s
7105         ==> (g has_real_integral k) s`,
7106   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN
7107   DISCH_THEN(CONJUNCTS_THEN2
7108    (MP_TAC o MATCH_MP HAS_REAL_INTEGRAL_IS_0) MP_TAC) THEN
7109   REWRITE_TAC[IMP_IMP] THEN DISCH_THEN
7110    (MP_TAC o MATCH_MP HAS_REAL_INTEGRAL_SUB) THEN
7111   SIMP_TAC[REAL_ARITH `x - (x - y:real) = y`; ETA_AX; REAL_SUB_RZERO]);;
7112
7113 let REAL_INTEGRABLE_EQ = prove
7114  (`!f:real->real g s.
7115         (!x. x IN s ==> (f(x) = g(x))) /\
7116         f real_integrable_on s
7117         ==> g real_integrable_on s`,
7118   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_EQ]);;
7119
7120 let HAS_REAL_INTEGRAL_EQ_EQ = prove
7121  (`!f:real->real g k s.
7122         (!x. x IN s ==> (f(x) = g(x)))
7123         ==> ((f has_real_integral k) s <=> (g has_real_integral k) s)`,
7124   MESON_TAC[HAS_REAL_INTEGRAL_EQ]);;
7125
7126 let HAS_REAL_INTEGRAL_NULL = prove
7127  (`!f:real->real a b.
7128     b <= a ==> (f has_real_integral &0) (real_interval[a,b])`,
7129   REPEAT STRIP_TAC THEN
7130   REWRITE_TAC[has_real_integral; REAL_INTERVAL_INTERVAL] THEN
7131   REWRITE_TAC[GSYM IMAGE_o; o_DEF; LIFT_DROP; LIFT_NUM] THEN
7132   REWRITE_TAC[SET_RULE `IMAGE (\x. x) s = s`] THEN
7133   MATCH_MP_TAC HAS_INTEGRAL_NULL THEN
7134   ASM_REWRITE_TAC[CONTENT_EQ_0_1; LIFT_DROP]);;
7135
7136 let HAS_REAL_INTEGRAL_NULL_EQ = prove
7137  (`!f a b i. b <= a
7138              ==> ((f has_real_integral i) (real_interval[a,b]) <=> i = &0)`,
7139   ASM_MESON_TAC[REAL_INTEGRAL_UNIQUE; HAS_REAL_INTEGRAL_NULL]);;
7140
7141 let REAL_INTEGRAL_NULL = prove
7142  (`!f a b. b <= a
7143            ==> real_integral(real_interval[a,b]) f = &0`,
7144   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
7145   ASM_MESON_TAC[HAS_REAL_INTEGRAL_NULL]);;
7146
7147 let REAL_INTEGRABLE_ON_NULL = prove
7148  (`!f a b. b <= a
7149            ==> f real_integrable_on real_interval[a,b]`,
7150   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_NULL]);;
7151
7152 let HAS_REAL_INTEGRAL_EMPTY = prove
7153  (`!f. (f has_real_integral &0) {}`,
7154   GEN_TAC THEN REWRITE_TAC[EMPTY_AS_REAL_INTERVAL] THEN
7155   MATCH_MP_TAC HAS_REAL_INTEGRAL_NULL THEN REWRITE_TAC[REAL_POS]);;
7156
7157 let HAS_REAL_INTEGRAL_EMPTY_EQ = prove
7158  (`!f i. (f has_real_integral i) {} <=> i = &0`,
7159   MESON_TAC[HAS_REAL_INTEGRAL_UNIQUE; HAS_REAL_INTEGRAL_EMPTY]);;
7160
7161 let REAL_INTEGRABLE_ON_EMPTY = prove
7162  (`!f. f real_integrable_on {}`,
7163   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_EMPTY]);;
7164
7165 let REAL_INTEGRAL_EMPTY = prove
7166  (`!f. real_integral {} f = &0`,
7167   MESON_TAC[EMPTY_AS_REAL_INTERVAL; REAL_INTEGRAL_UNIQUE;
7168             HAS_REAL_INTEGRAL_EMPTY]);;
7169
7170 let HAS_REAL_INTEGRAL_REFL = prove
7171  (`!f a. (f has_real_integral &0) (real_interval[a,a])`,
7172   REPEAT GEN_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_NULL THEN
7173   REWRITE_TAC[REAL_LE_REFL]);;
7174
7175 let REAL_INTEGRABLE_ON_REFL = prove
7176  (`!f a. f real_integrable_on real_interval[a,a]`,
7177   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_REFL]);;
7178
7179 let REAL_INTEGRAL_REFL = prove
7180  (`!f a. real_integral (real_interval[a,a]) f = &0`,
7181   MESON_TAC[REAL_INTEGRAL_UNIQUE; HAS_REAL_INTEGRAL_REFL]);;
7182
7183 let HAS_REAL_INTEGRAL_CONST = prove
7184  (`!a b c.
7185         a <= b
7186         ==> ((\x. c) has_real_integral (c * (b - a))) (real_interval[a,b])`,
7187   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
7188   REWRITE_TAC[has_real_integral; IMAGE_LIFT_REAL_INTERVAL] THEN
7189   MP_TAC(ISPECL [`lift a`; `lift b`; `lift c`] HAS_INTEGRAL_CONST) THEN
7190   ASM_SIMP_TAC[o_DEF; CONTENT_1; LIFT_DROP; LIFT_CMUL]);;
7191
7192 let REAL_INTEGRABLE_CONST = prove
7193  (`!a b c. (\x. c) real_integrable_on real_interval[a,b]`,
7194   REWRITE_TAC[REAL_INTEGRABLE_ON; IMAGE_LIFT_REAL_INTERVAL;
7195               o_DEF; INTEGRABLE_CONST]);;
7196
7197 let REAL_INTEGRAL_CONST = prove
7198  (`!a b c.
7199         a <= b
7200         ==> real_integral (real_interval [a,b]) (\x. c) = c * (b - a)`,
7201   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
7202   ASM_SIMP_TAC[HAS_REAL_INTEGRAL_CONST]);;
7203
7204 let HAS_REAL_INTEGRAL_BOUND = prove
7205  (`!f:real->real a b i B.
7206         &0 <= B /\ a <= b /\
7207         (f has_real_integral i) (real_interval[a,b]) /\
7208         (!x. x IN real_interval[a,b] ==> abs(f x) <= B)
7209         ==> abs i <= B * (b - a)`,
7210   REWRITE_TAC[HAS_REAL_INTEGRAL; REAL_INTERVAL_INTERVAL; GSYM NORM_LIFT] THEN
7211   REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP] THEN REPEAT STRIP_TAC THEN
7212   GEN_REWRITE_TAC (RAND_CONV o RAND_CONV o BINOP_CONV) [GSYM LIFT_DROP] THEN
7213   ASM_SIMP_TAC[GSYM CONTENT_1; LIFT_DROP] THEN
7214   MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN
7215   EXISTS_TAC `lift o f o drop` THEN ASM_REWRITE_TAC[o_THM]);;
7216
7217 let HAS_REAL_INTEGRAL_LE = prove
7218  (`!f g s i j.
7219         (f has_real_integral i) s /\ (g has_real_integral j) s /\
7220         (!x. x IN s ==> f x <= g x)
7221         ==> i <= j`,
7222   REWRITE_TAC[has_real_integral] THEN REPEAT STRIP_TAC THEN
7223   GEN_REWRITE_TAC BINOP_CONV [GSYM LIFT_DROP] THEN
7224   REWRITE_TAC[drop] THEN MATCH_MP_TAC
7225    (ISPECL [`lift o f o drop`; `lift o g o drop`; `IMAGE lift s`]
7226            HAS_INTEGRAL_COMPONENT_LE) THEN
7227   ASM_REWRITE_TAC[FORALL_IN_IMAGE; DIMINDEX_1; LE_REFL; o_THM; LIFT_DROP;
7228                   GSYM drop]);;
7229
7230 let REAL_INTEGRAL_LE = prove
7231  (`!f:real->real g:real->real s.
7232         f real_integrable_on s /\ g real_integrable_on s /\
7233         (!x. x IN s ==> f x <= g x)
7234         ==> real_integral s f <= real_integral s g`,
7235   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_LE THEN
7236   ASM_MESON_TAC[REAL_INTEGRABLE_INTEGRAL]);;
7237
7238 let HAS_REAL_INTEGRAL_POS = prove
7239  (`!f:real->real s i.
7240         (f has_real_integral i) s /\
7241         (!x. x IN s ==> &0 <= f x)
7242         ==> &0 <= i`,
7243   REPEAT STRIP_TAC THEN
7244   MP_TAC(ISPECL [`(\x. &0):real->real`; `f:real->real`;
7245                  `s:real->bool`; `&0:real`;
7246                  `i:real`] HAS_REAL_INTEGRAL_LE) THEN
7247   ASM_SIMP_TAC[HAS_REAL_INTEGRAL_0]);;
7248
7249 let REAL_INTEGRAL_POS = prove
7250  (`!f:real->real s.
7251         f real_integrable_on s /\
7252         (!x. x IN s ==> &0 <= f x)
7253         ==> &0 <= real_integral s f`,
7254   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_POS THEN
7255   ASM_MESON_TAC[REAL_INTEGRABLE_INTEGRAL]);;
7256
7257 let HAS_REAL_INTEGRAL_ISNEG = prove
7258  (`!f:real->real s i.
7259         (f has_real_integral i) s /\
7260         (!x. x IN s ==> f x <= &0)
7261         ==> i <= &0`,
7262   REPEAT STRIP_TAC THEN
7263   MP_TAC(ISPECL [`f:real->real`; `(\x. &0):real->real`;
7264                  `s:real->bool`; `i:real`; `&0:real`;
7265                 ] HAS_REAL_INTEGRAL_LE) THEN
7266   ASM_SIMP_TAC[HAS_REAL_INTEGRAL_0]);;
7267
7268 let HAS_REAL_INTEGRAL_LBOUND = prove
7269  (`!f:real->real a b i.
7270         a <= b /\
7271         (f has_real_integral i) (real_interval[a,b]) /\
7272         (!x. x IN real_interval[a,b] ==> B <= f(x))
7273         ==> B * (b - a) <= i`,
7274   REPEAT STRIP_TAC THEN
7275   MP_TAC(ISPECL [`(\x. B):real->real`; `f:real->real`;
7276                  `real_interval[a,b]`;
7277                   `B * (b - a):real`;
7278                  `i:real`]
7279                 HAS_REAL_INTEGRAL_LE) THEN
7280   ASM_SIMP_TAC[HAS_REAL_INTEGRAL_CONST]);;
7281
7282 let HAS_REAL_INTEGRAL_UBOUND = prove
7283  (`!f:real->real a b i.
7284         a <= b /\
7285         (f has_real_integral i) (real_interval[a,b]) /\
7286         (!x. x IN real_interval[a,b] ==> f(x) <= B)
7287         ==> i <= B * (b - a)`,
7288   REPEAT STRIP_TAC THEN
7289   MP_TAC(ISPECL [`f:real->real`; `(\x. B):real->real`;
7290                  `real_interval[a,b]`; `i:real`;
7291                  `B * (b - a):real`]
7292                 HAS_REAL_INTEGRAL_LE) THEN
7293   ASM_SIMP_TAC[HAS_REAL_INTEGRAL_CONST]);;
7294
7295 let REAL_INTEGRAL_LBOUND = prove
7296  (`!f:real->real a b.
7297         a <= b /\
7298         f real_integrable_on real_interval[a,b] /\
7299         (!x. x IN real_interval[a,b] ==> B <= f(x))
7300         ==> B * (b - a) <= real_integral(real_interval[a,b]) f`,
7301   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_LBOUND THEN
7302   EXISTS_TAC `f:real->real` THEN
7303   ASM_REWRITE_TAC[GSYM HAS_REAL_INTEGRAL_INTEGRAL]);;
7304
7305 let REAL_INTEGRAL_UBOUND = prove
7306  (`!f:real->real a b.
7307         a <= b /\
7308         f real_integrable_on real_interval[a,b] /\
7309         (!x. x IN real_interval[a,b] ==> f(x) <= B)
7310         ==> real_integral(real_interval[a,b]) f <= B * (b - a)`,
7311   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_UBOUND THEN
7312   EXISTS_TAC `f:real->real` THEN
7313   ASM_REWRITE_TAC[GSYM HAS_REAL_INTEGRAL_INTEGRAL]);;
7314
7315 let REAL_INTEGRABLE_UNIFORM_LIMIT = prove
7316  (`!f a b. (!e. &0 < e
7317                 ==> ?g. (!x. x IN real_interval[a,b] ==> abs(f x - g x) <= e) /\
7318                         g real_integrable_on real_interval[a,b] )
7319            ==> f real_integrable_on real_interval[a,b]`,
7320   REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL; GSYM EXISTS_LIFT] THEN
7321   REWRITE_TAC[GSYM integrable_on] THEN REPEAT STRIP_TAC THEN
7322   MATCH_MP_TAC INTEGRABLE_UNIFORM_LIMIT THEN
7323   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
7324   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
7325   DISCH_THEN(X_CHOOSE_THEN `g:real->real` STRIP_ASSUME_TAC) THEN
7326   EXISTS_TAC `lift o g o drop` THEN ASM_REWRITE_TAC[] THEN
7327   REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; FORALL_IN_IMAGE] THEN
7328   ASM_SIMP_TAC[o_THM; LIFT_DROP; GSYM LIFT_SUB; NORM_LIFT]);;
7329
7330 let HAS_REAL_INTEGRAL_NEGLIGIBLE = prove
7331  (`!f s t.
7332         real_negligible s /\ (!x. x IN (t DIFF s) ==> f x = &0)
7333         ==> (f has_real_integral (&0)) t`,
7334   REWRITE_TAC[has_real_integral; real_negligible; LIFT_NUM] THEN
7335   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_NEGLIGIBLE THEN
7336   EXISTS_TAC `IMAGE lift s` THEN ASM_REWRITE_TAC[] THEN
7337   REWRITE_TAC[o_THM; IN_DIFF; IMP_CONJ; FORALL_IN_IMAGE] THEN
7338   REWRITE_TAC[LIFT_IN_IMAGE_LIFT; LIFT_DROP] THEN ASM SET_TAC[LIFT_NUM]);;
7339
7340 let HAS_REAL_INTEGRAL_SPIKE = prove
7341  (`!f g s t y.
7342         real_negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x) /\
7343         (f has_real_integral y) t
7344         ==> (g has_real_integral y) t`,
7345   REWRITE_TAC[has_real_integral; real_negligible] THEN
7346   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN
7347   MAP_EVERY EXISTS_TAC [`lift o f o drop`; `IMAGE lift s`] THEN
7348   ASM_REWRITE_TAC[] THEN
7349   REWRITE_TAC[o_THM; IN_DIFF; IMP_CONJ; FORALL_IN_IMAGE] THEN
7350   REWRITE_TAC[LIFT_IN_IMAGE_LIFT; LIFT_DROP] THEN ASM SET_TAC[LIFT_NUM]);;
7351
7352 let HAS_REAL_INTEGRAL_SPIKE_EQ = prove
7353  (`!f g s t y.
7354         real_negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x)
7355         ==> ((f has_real_integral y) t <=> (g has_real_integral y) t)`,
7356   REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
7357   MATCH_MP_TAC HAS_REAL_INTEGRAL_SPIKE THENL
7358    [EXISTS_TAC `f:real->real`; EXISTS_TAC `g:real->real`] THEN
7359   EXISTS_TAC `s:real->bool` THEN ASM_REWRITE_TAC[] THEN
7360   ASM_MESON_TAC[REAL_ABS_SUB]);;
7361
7362 let REAL_INTEGRABLE_SPIKE = prove
7363  (`!f g s t.
7364         real_negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x)
7365         ==> f real_integrable_on t ==> g real_integrable_on  t`,
7366   REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[real_integrable_on] THEN
7367   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
7368   MP_TAC(SPEC_ALL HAS_REAL_INTEGRAL_SPIKE) THEN ASM_REWRITE_TAC[]);;
7369
7370 let REAL_INTEGRABLE_SPIKE_EQ = prove
7371  (`!f g s t.
7372          real_negligible s /\ (!x. x IN t DIFF s ==> g x = f x)
7373          ==> (f real_integrable_on t <=> g real_integrable_on t)`,
7374   MESON_TAC[REAL_INTEGRABLE_SPIKE]);;
7375
7376 let REAL_INTEGRAL_SPIKE = prove
7377  (`!f:real->real g s t.
7378         real_negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x)
7379         ==> real_integral t f = real_integral t g`,
7380   REPEAT STRIP_TAC THEN REWRITE_TAC[real_integral] THEN
7381   AP_TERM_TAC THEN ABS_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_SPIKE_EQ THEN
7382   ASM_MESON_TAC[]);;
7383
7384 let REAL_NEGLIGIBLE_SUBSET = prove
7385  (`!s:real->bool t:real->bool.
7386         real_negligible s /\ t SUBSET s ==> real_negligible t`,
7387   REWRITE_TAC[real_negligible] THEN REPEAT STRIP_TAC THEN
7388   MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN
7389   EXISTS_TAC `IMAGE lift s` THEN ASM_SIMP_TAC[IMAGE_SUBSET]);;
7390
7391 let REAL_NEGLIGIBLE_DIFF = prove
7392  (`!s t:real->bool. real_negligible s ==> real_negligible(s DIFF t)`,
7393   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_NEGLIGIBLE_SUBSET THEN
7394   EXISTS_TAC `s:real->bool` THEN ASM_REWRITE_TAC[SUBSET_DIFF]);;
7395
7396 let REAL_NEGLIGIBLE_INTER = prove
7397  (`!s t. real_negligible s \/ real_negligible t ==> real_negligible(s INTER t)`,
7398   MESON_TAC[REAL_NEGLIGIBLE_SUBSET; INTER_SUBSET]);;
7399
7400 let REAL_NEGLIGIBLE_UNION = prove
7401  (`!s t:real->bool.
7402        real_negligible s /\ real_negligible t ==> real_negligible (s UNION t)`,
7403   SIMP_TAC[NEGLIGIBLE_UNION; IMAGE_UNION; real_negligible]);;
7404
7405 let REAL_NEGLIGIBLE_UNION_EQ = prove
7406  (`!s t:real->bool.
7407         real_negligible (s UNION t) <=> real_negligible s /\ real_negligible t`,
7408   MESON_TAC[REAL_NEGLIGIBLE_UNION; SUBSET_UNION; REAL_NEGLIGIBLE_SUBSET]);;
7409
7410 let REAL_NEGLIGIBLE_SING = prove
7411  (`!a:real. real_negligible {a}`,
7412   REWRITE_TAC[real_negligible; NEGLIGIBLE_SING; IMAGE_CLAUSES]);;
7413
7414 let REAL_NEGLIGIBLE_INSERT = prove
7415  (`!a:real s. real_negligible(a INSERT s) <=> real_negligible s`,
7416   REWRITE_TAC[real_negligible; NEGLIGIBLE_INSERT; IMAGE_CLAUSES]);;
7417
7418 let REAL_NEGLIGIBLE_EMPTY = prove
7419  (`real_negligible {}`,
7420   REWRITE_TAC[real_negligible; NEGLIGIBLE_EMPTY; IMAGE_CLAUSES]);;
7421
7422 let REAL_NEGLIGIBLE_FINITE = prove
7423  (`!s. FINITE s ==> real_negligible s`,
7424   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
7425   SIMP_TAC[REAL_NEGLIGIBLE_EMPTY; REAL_NEGLIGIBLE_INSERT]);;
7426
7427 let REAL_NEGLIGIBLE_UNIONS = prove
7428  (`!s. FINITE s /\ (!t. t IN s ==> real_negligible t)
7429        ==> real_negligible(UNIONS s)`,
7430   REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
7431   REWRITE_TAC[UNIONS_0; UNIONS_INSERT; REAL_NEGLIGIBLE_EMPTY; IN_INSERT] THEN
7432   SIMP_TAC[REAL_NEGLIGIBLE_UNION]);;
7433
7434 let HAS_REAL_INTEGRAL_SPIKE_FINITE = prove
7435  (`!f:real->real g s t y.
7436         FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x) /\
7437         (f has_real_integral y) t
7438         ==> (g has_real_integral y) t`,
7439   MESON_TAC[HAS_REAL_INTEGRAL_SPIKE; REAL_NEGLIGIBLE_FINITE]);;
7440
7441 let HAS_REAL_INTEGRAL_SPIKE_FINITE_EQ = prove
7442  (`!f:real->real g s y.
7443         FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x)
7444         ==> ((f has_real_integral y) t <=> (g has_real_integral y) t)`,
7445   MESON_TAC[HAS_REAL_INTEGRAL_SPIKE_FINITE]);;
7446
7447 let REAL_INTEGRABLE_SPIKE_FINITE = prove
7448  (`!f:real->real g s.
7449         FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x)
7450         ==> f real_integrable_on t
7451             ==> g real_integrable_on  t`,
7452   REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[real_integrable_on] THEN
7453   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
7454   MP_TAC(SPEC_ALL HAS_REAL_INTEGRAL_SPIKE_FINITE) THEN ASM_REWRITE_TAC[]);;
7455
7456 let REAL_NEGLIGIBLE_FRONTIER_INTERVAL = prove
7457  (`!a b:real. real_negligible(real_interval[a,b] DIFF real_interval(a,b))`,
7458   REPEAT GEN_TAC THEN REWRITE_TAC[real_interval; DIFF; IN_ELIM_THM] THEN
7459   MATCH_MP_TAC REAL_NEGLIGIBLE_SUBSET THEN EXISTS_TAC `{(a:real),b}` THEN
7460   ASM_SIMP_TAC[REAL_NEGLIGIBLE_FINITE; FINITE_RULES] THEN
7461   REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_INSERT; NOT_IN_EMPTY] THEN
7462   REAL_ARITH_TAC);;
7463
7464 let HAS_REAL_INTEGRAL_SPIKE_INTERIOR = prove
7465  (`!f:real->real g a b y.
7466         (!x. x IN real_interval(a,b) ==> g x = f x) /\
7467         (f has_real_integral y) (real_interval[a,b])
7468         ==> (g has_real_integral y) (real_interval[a,b])`,
7469   REPEAT GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN DISCH_TAC THEN
7470   MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
7471                            HAS_REAL_INTEGRAL_SPIKE) THEN
7472   EXISTS_TAC `real_interval[a:real,b] DIFF real_interval(a,b)` THEN
7473   REWRITE_TAC[REAL_NEGLIGIBLE_FRONTIER_INTERVAL] THEN ASM SET_TAC[]);;
7474
7475 let HAS_REAL_INTEGRAL_SPIKE_INTERIOR_EQ = prove
7476  (`!f:real->real g a b y.
7477         (!x. x IN real_interval(a,b) ==> g x = f x)
7478         ==> ((f has_real_integral y) (real_interval[a,b]) <=>
7479              (g has_real_integral y) (real_interval[a,b]))`,
7480   MESON_TAC[HAS_REAL_INTEGRAL_SPIKE_INTERIOR]);;
7481
7482 let REAL_INTEGRABLE_SPIKE_INTERIOR = prove
7483  (`!f:real->real g a b.
7484         (!x. x IN real_interval(a,b) ==> g x = f x)
7485         ==> f real_integrable_on (real_interval[a,b])
7486             ==> g real_integrable_on  (real_interval[a,b])`,
7487   REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[real_integrable_on] THEN
7488   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
7489   MP_TAC(SPEC_ALL HAS_REAL_INTEGRAL_SPIKE_INTERIOR) THEN ASM_REWRITE_TAC[]);;
7490
7491 let REAL_INTEGRAL_EQ = prove
7492  (`!f g s.
7493         (!x. x IN s ==> f x = g x) ==> real_integral s f = real_integral s g`,
7494   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_SPIKE THEN
7495   EXISTS_TAC `{}:real->bool` THEN
7496   ASM_SIMP_TAC[REAL_NEGLIGIBLE_EMPTY; IN_DIFF]);;
7497
7498 let REAL_INTEGRAL_EQ_0 = prove
7499  (`!f s. (!x. x IN s ==> f x = &0) ==> real_integral s f = &0`,
7500   REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
7501   EXISTS_TAC `real_integral s (\x. &0)` THEN
7502   CONJ_TAC THENL
7503    [MATCH_MP_TAC REAL_INTEGRAL_EQ THEN ASM_REWRITE_TAC[];
7504     REWRITE_TAC[REAL_INTEGRAL_0]]);;
7505
7506 let REAL_INTEGRABLE_CONTINUOUS = prove
7507  (`!f a b.
7508         f real_continuous_on real_interval[a,b]
7509         ==> f real_integrable_on real_interval[a,b]`,
7510   REWRITE_TAC[REAL_CONTINUOUS_ON; real_integrable_on; has_real_integral;
7511               GSYM integrable_on; GSYM EXISTS_LIFT] THEN
7512   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; INTEGRABLE_CONTINUOUS]);;
7513
7514 let REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS = prove
7515  (`!f f' a b.
7516         a <= b /\
7517         (!x. x IN real_interval[a,b]
7518              ==> (f has_real_derivative f'(x))
7519                  (atreal x within real_interval[a,b]))
7520         ==> (f' has_real_integral (f(b) - f(a))) (real_interval[a,b])`,
7521   REWRITE_TAC[has_real_integral; HAS_REAL_VECTOR_DERIVATIVE_WITHIN] THEN
7522   REPEAT GEN_TAC THEN REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; LIFT_SUB] THEN
7523   REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE; LIFT_DROP] THEN
7524   GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o BINOP_CONV) [GSYM LIFT_DROP] THEN
7525   DISCH_THEN(MP_TAC o MATCH_MP FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN
7526   REWRITE_TAC[o_DEF; LIFT_DROP]);;
7527
7528 let REAL_INTEGRABLE_SUBINTERVAL = prove
7529  (`!f:real->real a b c d.
7530         f real_integrable_on real_interval[a,b] /\
7531         real_interval[c,d] SUBSET real_interval[a,b]
7532         ==> f real_integrable_on real_interval[c,d]`,
7533   REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL] THEN
7534   REWRITE_TAC[EXISTS_DROP; GSYM integrable_on; LIFT_DROP] THEN
7535   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN
7536   MAP_EVERY EXISTS_TAC [`lift a`; `lift b`] THEN
7537   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL] THEN
7538   ASM_SIMP_TAC[IMAGE_SUBSET]);;
7539
7540 let HAS_REAL_INTEGRAL_COMBINE = prove
7541  (`!f i j a b c.
7542         a <= c /\ c <= b /\
7543         (f has_real_integral i) (real_interval[a,c]) /\
7544         (f has_real_integral j) (real_interval[c,b])
7545         ==> (f has_real_integral (i + j)) (real_interval[a,b])`,
7546   REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_INTEGRAL; LIFT_ADD] THEN
7547   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMBINE THEN
7548   EXISTS_TAC `lift c` THEN ASM_REWRITE_TAC[LIFT_DROP]);;
7549
7550 let REAL_INTEGRAL_COMBINE = prove
7551  (`!f a b c.
7552         a <= c /\ c <= b /\ f real_integrable_on (real_interval[a,b])
7553         ==> real_integral(real_interval[a,c]) f +
7554             real_integral(real_interval[c,b]) f =
7555             real_integral(real_interval[a,b]) f`,
7556   REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
7557   MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
7558   MATCH_MP_TAC HAS_REAL_INTEGRAL_COMBINE THEN
7559   EXISTS_TAC `c:real` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THEN
7560   MATCH_MP_TAC REAL_INTEGRABLE_INTEGRAL THEN
7561   MATCH_MP_TAC REAL_INTEGRABLE_SUBINTERVAL THEN
7562   MAP_EVERY EXISTS_TAC [`a:real`; `b:real`] THEN
7563   ASM_REWRITE_TAC[SUBSET_REAL_INTERVAL; REAL_LE_REFL]);;
7564
7565 let REAL_INTEGRABLE_COMBINE = prove
7566  (`!f a b c.
7567         a <= c /\ c <= b /\
7568         f real_integrable_on real_interval[a,c] /\
7569         f real_integrable_on real_interval[c,b]
7570         ==> f real_integrable_on real_interval[a,b]`,
7571   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_COMBINE]);;
7572
7573 let REAL_INTEGRABLE_ON_LITTLE_SUBINTERVALS = prove
7574  (`!f:real->real a b.
7575         (!x. x IN real_interval[a,b]
7576              ==> ?d. &0 < d /\
7577                      !u v. x IN real_interval[u,v] /\
7578                            (!y. y IN real_interval[u,v]
7579                                 ==> abs(y - x) < d /\ y IN real_interval[a,b])
7580                            ==> f real_integrable_on real_interval[u,v])
7581         ==> f real_integrable_on real_interval[a,b]`,
7582   REPEAT GEN_TAC THEN
7583   REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL; EXISTS_DROP;
7584               GSYM integrable_on; LIFT_DROP] THEN
7585   DISCH_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_LITTLE_SUBINTERVALS THEN
7586   REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; FORALL_IN_IMAGE] THEN
7587   X_GEN_TAC `x:real` THEN DISCH_TAC THEN
7588   FIRST_X_ASSUM(MP_TAC o SPEC `x:real`) THEN ASM_REWRITE_TAC[] THEN
7589   REWRITE_TAC[GSYM EXISTS_DROP; FORALL_LIFT] THEN
7590   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN
7591   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN
7592   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
7593   CONJ_TAC THENL
7594    [ASM_MESON_TAC[IMAGE_LIFT_REAL_INTERVAL; LIFT_IN_IMAGE_LIFT];
7595     REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE] THEN
7596     X_GEN_TAC `y:real^1` THEN DISCH_TAC THEN
7597     REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `y:real^1` o REWRITE_RULE[SUBSET])) THEN
7598     ASM_SIMP_TAC[IN_BALL; FUN_IN_IMAGE; dist; NORM_REAL] THEN
7599     REWRITE_TAC[GSYM drop; DROP_SUB; LIFT_DROP] THEN SIMP_TAC[REAL_ABS_SUB]]);;
7600
7601 let REAL_INTEGRAL_HAS_REAL_DERIVATIVE_POINTWISE = prove
7602  (`!f a b x.
7603         f real_integrable_on real_interval[a,b] /\ x IN real_interval[a,b] /\
7604         f real_continuous (atreal x within real_interval[a,b])
7605         ==> ((\u. real_integral(real_interval[a,u]) f)
7606                    has_real_derivative f(x))
7607                  (atreal x within real_interval[a,b])`,
7608   REPEAT GEN_TAC THEN
7609   DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
7610   REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1; IMAGE_LIFT_REAL_INTERVAL;
7611               REAL_INTEGRABLE_ON; CONTINUOUS_CONTINUOUS_WITHINREAL;
7612               HAS_REAL_VECTOR_DERIVATIVE_WITHIN] THEN
7613   REWRITE_TAC[REAL_INTERVAL_INTERVAL; IN_IMAGE_LIFT_DROP; GSYM o_ASSOC] THEN
7614   DISCH_TAC THEN
7615   FIRST_ASSUM(MP_TAC o MATCH_MP INTEGRAL_HAS_VECTOR_DERIVATIVE_POINTWISE) THEN
7616   REWRITE_TAC[o_DEF; LIFT_DROP] THEN
7617   MATCH_MP_TAC(REWRITE_RULE[TAUT
7618     `a /\ b /\ c /\ d ==> e <=> a /\ b /\ c ==> d ==> e`]
7619      HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN) THEN
7620   EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[REAL_LT_01] THEN
7621   X_GEN_TAC `y:real^1` THEN STRIP_TAC THEN
7622   ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN
7623   REWRITE_TAC[LIFT_DROP] THEN CONV_TAC SYM_CONV THEN
7624   REWRITE_TAC[INTERVAL_REAL_INTERVAL; GSYM IMAGE_o; LIFT_DROP; o_DEF] THEN
7625   REWRITE_TAC[GSYM o_DEF; SET_RULE `IMAGE (\x. x) s = s`] THEN
7626   MATCH_MP_TAC REAL_INTEGRAL THEN
7627   MATCH_MP_TAC REAL_INTEGRABLE_SUBINTERVAL THEN
7628   MAP_EVERY EXISTS_TAC [`a:real`; `b:real`] THEN ASM_REWRITE_TAC[] THEN
7629   ASM_REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN
7630   REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN
7631   REWRITE_TAC[LIFT_DROP] THEN REAL_ARITH_TAC);;
7632
7633 let REAL_INTEGRAL_HAS_REAL_DERIVATIVE = prove
7634  (`!f:real->real a b.
7635      f real_continuous_on real_interval[a,b]
7636      ==> !x. x IN real_interval[a,b]
7637              ==> ((\u. real_integral(real_interval[a,u]) f)
7638                   has_real_derivative f(x))
7639                  (atreal x within real_interval[a,b])`,
7640   REPEAT STRIP_TAC THEN
7641   MATCH_MP_TAC REAL_INTEGRAL_HAS_REAL_DERIVATIVE_POINTWISE THEN
7642   ASM_MESON_TAC[REAL_INTEGRABLE_CONTINUOUS;
7643                 REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]);;
7644
7645 let REAL_ANTIDERIVATIVE_CONTINUOUS = prove
7646  (`!f a b.
7647      (f real_continuous_on real_interval[a,b])
7648      ==> ?g. !x. x IN real_interval[a,b]
7649                  ==> (g has_real_derivative f(x))
7650                      (atreal x within real_interval[a,b])`,
7651   MESON_TAC[REAL_INTEGRAL_HAS_REAL_DERIVATIVE]);;
7652
7653 let REAL_ANTIDERIVATIVE_INTEGRAL_CONTINUOUS = prove
7654  (`!f a b.
7655      (f real_continuous_on real_interval[a,b])
7656      ==> ?g. !u v. u IN real_interval[a,b] /\
7657                    v IN real_interval[a,b] /\ u <= v
7658                    ==> (f has_real_integral (g(v) - g(u)))
7659                        (real_interval[u,v])`,
7660   REPEAT STRIP_TAC THEN
7661   FIRST_ASSUM(MP_TAC o MATCH_MP REAL_ANTIDERIVATIVE_CONTINUOUS) THEN
7662   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real->real` THEN
7663   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS THEN
7664   ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real` THEN
7665   STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_DERIVATIVE_WITHIN_SUBSET THEN
7666   EXISTS_TAC `real_interval[a:real,b]` THEN CONJ_TAC THENL
7667    [FIRST_X_ASSUM MATCH_MP_TAC; ALL_TAC] THEN
7668   REPEAT(POP_ASSUM MP_TAC) THEN
7669   REWRITE_TAC[SUBSET_REAL_INTERVAL; IN_REAL_INTERVAL] THEN REAL_ARITH_TAC);;
7670
7671 let HAS_REAL_INTEGRAL_AFFINITY = prove
7672  (`!f:real->real i a b m c.
7673         (f has_real_integral i) (real_interval[a,b]) /\ ~(m = &0)
7674         ==> ((\x. f(m * x + c)) has_real_integral (inv(abs(m)) * i))
7675             (IMAGE (\x. inv m * (x - c)) (real_interval[a,b]))`,
7676   REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_INTEGRAL] THEN
7677   DISCH_THEN(MP_TAC o SPEC `lift c` o MATCH_MP HAS_INTEGRAL_AFFINITY) THEN
7678   REWRITE_TAC[DIMINDEX_1; REAL_POW_1; has_real_integral] THEN
7679   REWRITE_TAC[o_DEF; DROP_ADD; DROP_CMUL; LIFT_DROP; LIFT_CMUL] THEN
7680   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
7681   REWRITE_TAC[INTERVAL_REAL_INTERVAL; GSYM IMAGE_o; LIFT_DROP] THEN
7682   AP_THM_TAC THEN AP_TERM_TAC THEN
7683   REWRITE_TAC[FUN_EQ_THM; o_DEF; LIFT_CMUL; LIFT_SUB] THEN VECTOR_ARITH_TAC);;
7684
7685 let REAL_INTEGRABLE_AFFINITY = prove
7686  (`!f a b m c.
7687         f real_integrable_on real_interval[a,b] /\ ~(m = &0)
7688         ==> (\x. f(m * x + c)) real_integrable_on
7689             (IMAGE (\x. inv m * (x - c)) (real_interval[a,b]))`,
7690   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_AFFINITY]);;
7691
7692 let HAS_REAL_INTEGRAL_STRETCH = prove
7693  (`!f:real->real i a b m.
7694         (f has_real_integral i) (real_interval[a,b]) /\ ~(m = &0)
7695         ==> ((\x. f(m * x)) has_real_integral (inv(abs(m)) * i))
7696             (IMAGE (\x. inv m * x) (real_interval[a,b]))`,
7697   MP_TAC HAS_REAL_INTEGRAL_AFFINITY THEN
7698   REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
7699   DISCH_THEN(MP_TAC o SPEC `&0`) THEN
7700   REWRITE_TAC[REAL_ADD_RID; REAL_SUB_RZERO]);;
7701
7702 let REAL_INTEGRABLE_STRETCH = prove
7703  (`!f a b m.
7704         f real_integrable_on real_interval[a,b] /\ ~(m = &0)
7705         ==> (\x. f(m * x)) real_integrable_on
7706             (IMAGE (\x. inv m * x) (real_interval[a,b]))`,
7707   REWRITE_TAC[real_integrable_on] THEN MESON_TAC[HAS_REAL_INTEGRAL_STRETCH]);;
7708
7709 let HAS_REAL_INTEGRAL_REFLECT_LEMMA = prove
7710  (`!f:real->real i a b.
7711      (f has_real_integral i) (real_interval[a,b])
7712      ==> ((\x. f(--x)) has_real_integral i) (real_interval[--b,--a])`,
7713   REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_INTEGRAL] THEN
7714   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_REFLECT_LEMMA) THEN
7715   REWRITE_TAC[LIFT_NEG; o_DEF; DROP_NEG]);;
7716
7717 let HAS_REAL_INTEGRAL_REFLECT = prove
7718  (`!f:real->real i a b.
7719      ((\x. f(--x)) has_real_integral i) (real_interval[--b,--a]) <=>
7720      (f has_real_integral i) (real_interval[a,b])`,
7721   REPEAT GEN_TAC THEN EQ_TAC THEN
7722   DISCH_THEN(MP_TAC o MATCH_MP HAS_REAL_INTEGRAL_REFLECT_LEMMA) THEN
7723   REWRITE_TAC[REAL_NEG_NEG; ETA_AX]);;
7724
7725 let REAL_INTEGRABLE_REFLECT = prove
7726  (`!f:real->real a b.
7727      (\x. f(--x)) real_integrable_on (real_interval[--b,--a]) <=>
7728      f real_integrable_on (real_interval[a,b])`,
7729   REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL_REFLECT]);;
7730
7731 let REAL_INTEGRAL_REFLECT = prove
7732  (`!f:real->real a b.
7733      real_integral (real_interval[--b,--a]) (\x. f(--x)) =
7734      real_integral (real_interval[a,b]) f`,
7735   REWRITE_TAC[real_integral; HAS_REAL_INTEGRAL_REFLECT]);;
7736
7737 let HAS_REAL_INTEGRAL_REFLECT_GEN = prove
7738  (`!f i s. ((\x. f(--x)) has_real_integral i) s <=>
7739            (f has_real_integral i) (IMAGE (--) s)`,
7740   REWRITE_TAC[has_real_integral; o_DEF; GSYM DROP_NEG;
7741               HAS_INTEGRAL_REFLECT_GEN; GSYM IMAGE_o; GSYM LIFT_NEG]);;
7742
7743 let REAL_INTEGRABLE_REFLECT_GEN = prove
7744  (`!f s. (\x. f(--x)) real_integrable_on s <=>
7745          f real_integrable_on (IMAGE (--) s)`,
7746   REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL_REFLECT_GEN]);;
7747
7748 let REAL_INTEGRAL_REFLECT_GEN = prove
7749  (`!f s. real_integral s (\x. f(--x)) = real_integral (IMAGE (--) s) f`,
7750    REWRITE_TAC[real_integral; HAS_REAL_INTEGRAL_REFLECT_GEN]);;
7751
7752 let REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR = prove
7753  (`!f:real->real f' a b.
7754         a <= b /\ f real_continuous_on real_interval[a,b] /\
7755         (!x. x IN real_interval(a,b)
7756              ==> (f has_real_derivative f'(x)) (atreal x))
7757         ==> (f' has_real_integral (f(b) - f(a))) (real_interval[a,b])`,
7758   REWRITE_TAC[has_real_integral; HAS_REAL_VECTOR_DERIVATIVE_AT] THEN
7759   REPEAT GEN_TAC THEN REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; LIFT_SUB] THEN
7760   REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE; LIFT_DROP] THEN
7761   GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o BINOP_CONV) [GSYM LIFT_DROP] THEN
7762   REWRITE_TAC[REAL_CONTINUOUS_ON; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN
7763   DISCH_THEN(MP_TAC o MATCH_MP FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR) THEN
7764   REWRITE_TAC[o_DEF; LIFT_DROP]);;
7765
7766 let REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG = prove
7767  (`!f f' s a b.
7768         COUNTABLE s /\
7769         a <= b /\ f real_continuous_on real_interval[a,b] /\
7770         (!x. x IN real_interval(a,b) DIFF s
7771              ==> (f has_real_derivative f'(x)) (atreal x))
7772         ==> (f' has_real_integral (f(b) - f(a))) (real_interval[a,b])`,
7773   REWRITE_TAC[has_real_integral; HAS_REAL_VECTOR_DERIVATIVE_AT] THEN
7774   REPEAT GEN_TAC THEN REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; LIFT_SUB] THEN
7775   REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE; IMP_CONJ; IN_DIFF] THEN
7776   SUBGOAL_THEN `!x. drop x IN s <=> x IN IMAGE lift s`
7777     (fun th -> REWRITE_TAC[th]) THENL [SET_TAC[LIFT_DROP]; ALL_TAC] THEN
7778   SUBGOAL_THEN `COUNTABLE s <=> COUNTABLE(IMAGE lift s)` SUBST1_TAC THENL
7779    [EQ_TAC THEN SIMP_TAC[COUNTABLE_IMAGE] THEN
7780     DISCH_THEN(MP_TAC o ISPEC `drop` o MATCH_MP COUNTABLE_IMAGE) THEN
7781     REWRITE_TAC[GSYM IMAGE_o; IMAGE_LIFT_DROP];
7782     ALL_TAC] THEN
7783   REWRITE_TAC[IMP_IMP; GSYM IN_DIFF; GSYM CONJ_ASSOC] THEN
7784   REWRITE_TAC[REAL_CONTINUOUS_ON; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN
7785   REWRITE_TAC[LIFT_DROP] THEN
7786   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o LAND_CONV o BINOP_CONV)
7787    [GSYM LIFT_DROP] THEN
7788   DISCH_THEN(MP_TAC o
7789     MATCH_MP FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG) THEN
7790   REWRITE_TAC[o_DEF; LIFT_DROP]);;
7791
7792 let REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG = prove
7793  (`!f f' s a b.
7794         COUNTABLE s /\
7795         a <= b /\ f real_continuous_on real_interval[a,b] /\
7796         (!x. x IN real_interval[a,b] DIFF s
7797              ==> (f has_real_derivative f'(x)) (atreal x))
7798         ==> (f' has_real_integral (f(b) - f(a))) (real_interval[a,b])`,
7799   REPEAT STRIP_TAC THEN
7800   MATCH_MP_TAC REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG THEN
7801   EXISTS_TAC `s:real->bool` THEN ASM_REWRITE_TAC[] THEN GEN_TAC THEN
7802   DISCH_THEN(fun th -> FIRST_X_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN
7803   SIMP_TAC[IN_REAL_INTERVAL; IN_DIFF] THEN REAL_ARITH_TAC);;
7804
7805 let REAL_INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT = prove
7806  (`!f:real->real a b.
7807         f real_integrable_on real_interval[a,b]
7808         ==> (\x. real_integral (real_interval[a,x]) f)
7809             real_continuous_on real_interval[a,b]`,
7810   REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_CONTINUOUS_ON] THEN
7811   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_INTEGRABLE_ON]) THEN
7812   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN
7813   DISCH_THEN(MP_TAC o MATCH_MP INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT) THEN
7814   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] CONTINUOUS_ON_EQ) THEN
7815   GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[o_DEF] THEN
7816   GEN_REWRITE_TAC I [GSYM DROP_EQ] THEN
7817   REWRITE_TAC[INTERVAL_REAL_INTERVAL; LIFT_DROP; GSYM o_DEF] THEN
7818   CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_INTEGRAL THEN
7819   MATCH_MP_TAC REAL_INTEGRABLE_SUBINTERVAL THEN
7820   MAP_EVERY EXISTS_TAC [`a:real`; `b:real`] THEN
7821   ASM_REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN
7822   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN
7823   REWRITE_TAC[LIFT_DROP] THEN REAL_ARITH_TAC);;
7824
7825 let REAL_INDEFINITE_INTEGRAL_CONTINUOUS_LEFT = prove
7826  (`!f:real->real a b.
7827         f real_integrable_on real_interval[a,b]
7828         ==> (\x. real_integral (real_interval[x,b]) f)
7829             real_continuous_on real_interval[a,b]`,
7830   REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_CONTINUOUS_ON] THEN
7831   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_INTEGRABLE_ON]) THEN
7832   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN
7833   DISCH_THEN(MP_TAC o MATCH_MP INDEFINITE_INTEGRAL_CONTINUOUS_LEFT) THEN
7834   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] CONTINUOUS_ON_EQ) THEN
7835   GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[o_DEF] THEN
7836   GEN_REWRITE_TAC I [GSYM DROP_EQ] THEN
7837   REWRITE_TAC[INTERVAL_REAL_INTERVAL; LIFT_DROP; GSYM o_DEF] THEN
7838   CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_INTEGRAL THEN
7839   MATCH_MP_TAC REAL_INTEGRABLE_SUBINTERVAL THEN
7840   MAP_EVERY EXISTS_TAC [`a:real`; `b:real`] THEN
7841   ASM_REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN
7842   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN
7843   REWRITE_TAC[LIFT_DROP] THEN REAL_ARITH_TAC);;
7844
7845 let HAS_REAL_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL = prove
7846  (`!f:real->real a b k y.
7847         COUNTABLE k /\ f real_continuous_on real_interval[a,b] /\ f a = y /\
7848         (!x. x IN (real_interval[a,b] DIFF k)
7849              ==> (f has_real_derivative &0)
7850                  (atreal x within real_interval[a,b]))
7851         ==> !x. x IN real_interval[a,b] ==> f x = y`,
7852   REWRITE_TAC[has_real_integral; HAS_REAL_VECTOR_DERIVATIVE_WITHIN] THEN
7853   REPEAT GEN_TAC THEN REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; LIFT_SUB] THEN
7854   REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE; IMP_CONJ; IN_DIFF] THEN
7855   REWRITE_TAC[REAL_CONTINUOUS_ON; IMP_IMP; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN
7856   REWRITE_TAC[GSYM IMP_CONJ; LIFT_DROP; has_vector_derivative] THEN
7857   REWRITE_TAC[LIFT_NUM; VECTOR_MUL_RZERO] THEN STRIP_TAC THEN
7858   MP_TAC(ISPECL
7859    [`lift o f o drop`; `lift a`; `lift b`; `IMAGE lift k`; `lift y`]
7860    HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL) THEN
7861   ASM_SIMP_TAC[COUNTABLE_IMAGE; o_THM; LIFT_DROP; LIFT_EQ; IN_DIFF] THEN
7862   DISCH_THEN MATCH_MP_TAC THEN REPEAT STRIP_TAC THEN
7863   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM SET_TAC[LIFT_DROP]);;
7864
7865 let HAS_REAL_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX = prove
7866  (`!f:real->real s k c y.
7867       is_realinterval s /\ COUNTABLE k /\ f real_continuous_on s /\
7868       c IN s /\ f c = y /\
7869       (!x. x IN (s DIFF k) ==> (f has_real_derivative &0) (atreal x within s))
7870       ==> !x. x IN s ==> f x = y`,
7871   REWRITE_TAC[has_real_integral; HAS_REAL_VECTOR_DERIVATIVE_WITHIN] THEN
7872   REWRITE_TAC[IS_REALINTERVAL_CONVEX; REAL_CONTINUOUS_ON] THEN
7873   REPEAT GEN_TAC THEN REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; LIFT_SUB] THEN
7874   REWRITE_TAC[REAL_INTERVAL_INTERVAL; FORALL_IN_IMAGE; IMP_CONJ; IN_DIFF] THEN
7875   REWRITE_TAC[REAL_CONTINUOUS_ON; IMP_IMP; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN
7876   REWRITE_TAC[GSYM IMP_CONJ; LIFT_DROP; has_vector_derivative] THEN
7877   REWRITE_TAC[LIFT_NUM; VECTOR_MUL_RZERO] THEN STRIP_TAC THEN
7878   MP_TAC(ISPECL
7879    [`lift o f o drop`; `IMAGE lift s`; `IMAGE lift k`; `lift c`; `lift y`]
7880    HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX) THEN
7881   ASM_SIMP_TAC[COUNTABLE_IMAGE; o_THM; LIFT_DROP; LIFT_EQ; IN_DIFF] THEN
7882   ASM_REWRITE_TAC[LIFT_IN_IMAGE_LIFT; FORALL_IN_IMAGE; LIFT_DROP] THEN
7883   ASM_SIMP_TAC[IMP_CONJ; FORALL_IN_IMAGE; LIFT_IN_IMAGE_LIFT]);;
7884
7885 let HAS_REAL_DERIVATIVE_INDEFINITE_INTEGRAL = prove
7886  (`!f a b.
7887         f real_integrable_on real_interval[a,b]
7888         ==> ?k. real_negligible k /\
7889                 !x. x IN real_interval[a,b] DIFF k
7890                     ==> ((\x. real_integral(real_interval[a,x]) f)
7891                          has_real_derivative
7892                          f(x)) (atreal x within real_interval[a,b])`,
7893   REPEAT STRIP_TAC THEN
7894   MP_TAC(ISPECL [`lift o f o drop`; `lift a`; `lift b`]
7895         HAS_VECTOR_DERIVATIVE_INDEFINITE_INTEGRAL) THEN
7896   ASM_REWRITE_TAC[GSYM REAL_INTEGRABLE_ON; GSYM IMAGE_LIFT_REAL_INTERVAL] THEN
7897   REWRITE_TAC[IN_DIFF; FORALL_IN_IMAGE; IMP_CONJ] THEN
7898   DISCH_THEN(X_CHOOSE_THEN `k:real^1->bool` STRIP_ASSUME_TAC) THEN
7899   EXISTS_TAC `IMAGE drop k` THEN
7900   ASM_REWRITE_TAC[real_negligible; HAS_REAL_VECTOR_DERIVATIVE_WITHIN] THEN
7901   ASM_REWRITE_TAC[GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN
7902   REWRITE_TAC[IN_IMAGE; GSYM LIFT_EQ; LIFT_DROP; UNWIND_THM1] THEN
7903   X_GEN_TAC `x:real` THEN REPEAT DISCH_TAC THEN
7904   FIRST_X_ASSUM(MP_TAC o SPEC `x:real`) THEN ASM_REWRITE_TAC[] THEN
7905   REWRITE_TAC[o_THM; LIFT_DROP] THEN MATCH_MP_TAC(REWRITE_RULE
7906    [TAUT `a /\ b /\ c /\ d ==> e <=> a /\ b /\ c ==> d ==> e`]
7907         HAS_VECTOR_DERIVATIVE_TRANSFORM_WITHIN) THEN
7908   EXISTS_TAC `&1` THEN ASM_SIMP_TAC[FUN_IN_IMAGE; REAL_LT_01] THEN
7909   REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE] THEN
7910   X_GEN_TAC `y:real` THEN REPEAT DISCH_TAC THEN
7911   REWRITE_TAC[GSYM DROP_EQ; LIFT_DROP; o_THM] THEN
7912   REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL] THEN CONV_TAC SYM_CONV THEN
7913   MATCH_MP_TAC REAL_INTEGRAL THEN
7914   MATCH_MP_TAC REAL_INTEGRABLE_SUBINTERVAL THEN
7915   MAP_EVERY EXISTS_TAC [`a:real`; `b:real`] THEN
7916   ASM_REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN
7917   RULE_ASSUM_TAC(REWRITE_RULE[IN_REAL_INTERVAL]) THEN
7918   ASM_REAL_ARITH_TAC);;
7919
7920 let HAS_REAL_INTEGRAL_RESTRICT = prove
7921  (`!f:real->real s t.
7922         s SUBSET t
7923         ==> (((\x. if x IN s then f x else &0) has_real_integral i) t <=>
7924              (f has_real_integral i) s)`,
7925   REPEAT STRIP_TAC THEN REWRITE_TAC[has_real_integral; o_DEF] THEN
7926   MP_TAC(ISPECL [`lift o f o drop`; `IMAGE lift s`; `IMAGE lift t`; `lift i`]
7927         HAS_INTEGRAL_RESTRICT) THEN
7928   ASM_SIMP_TAC[IMAGE_SUBSET; IN_IMAGE_LIFT_DROP; o_DEF] THEN
7929   DISCH_THEN(SUBST1_TAC o SYM) THEN
7930   ONCE_REWRITE_TAC[COND_RAND] THEN REWRITE_TAC[LIFT_NUM]);;
7931
7932 let HAS_REAL_INTEGRAL_RESTRICT_UNIV = prove
7933  (`!f:real->real s i.
7934         ((\x. if x IN s then f x else &0) has_real_integral i) (:real) <=>
7935          (f has_real_integral i) s`,
7936   SIMP_TAC[HAS_REAL_INTEGRAL_RESTRICT; SUBSET_UNIV]);;
7937
7938 let HAS_REAL_INTEGRAL_SPIKE_SET_EQ = prove
7939  (`!f s t y.
7940         real_negligible(s DIFF t UNION t DIFF s)
7941         ==> ((f has_real_integral y) s <=> (f has_real_integral y) t)`,
7942   REPEAT STRIP_TAC THEN
7943   ONCE_REWRITE_TAC[GSYM HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN
7944   MATCH_MP_TAC HAS_REAL_INTEGRAL_SPIKE_EQ THEN
7945   EXISTS_TAC `s DIFF t UNION t DIFF s:real->bool` THEN
7946   ASM_REWRITE_TAC[] THEN SET_TAC[]);;
7947
7948 let HAS_REAL_INTEGRAL_SPIKE_SET = prove
7949  (`!f s t y.
7950         real_negligible(s DIFF t UNION t DIFF s) /\
7951         (f has_real_integral y) s
7952         ==> (f has_real_integral y) t`,
7953   MESON_TAC[HAS_REAL_INTEGRAL_SPIKE_SET_EQ]);;
7954
7955 let REAL_INTEGRABLE_SPIKE_SET = prove
7956  (`!f s t.
7957         real_negligible(s DIFF t UNION t DIFF s)
7958         ==> f real_integrable_on s ==> f real_integrable_on t`,
7959   REWRITE_TAC[real_integrable_on] THEN
7960   MESON_TAC[HAS_REAL_INTEGRAL_SPIKE_SET_EQ]);;
7961
7962 let REAL_INTEGRABLE_SPIKE_SET_EQ = prove
7963  (`!f s t.
7964         real_negligible(s DIFF t UNION t DIFF s)
7965         ==> (f real_integrable_on s <=> f real_integrable_on t)`,
7966   MESON_TAC[REAL_INTEGRABLE_SPIKE_SET; UNION_COMM]);;
7967
7968 let REAL_INTEGRAL_SPIKE_SET = prove
7969  (`!f s t.
7970         real_negligible(s DIFF t UNION t DIFF s)
7971         ==> real_integral s f = real_integral t f`,
7972   REPEAT STRIP_TAC THEN REWRITE_TAC[real_integral] THEN
7973   AP_TERM_TAC THEN ABS_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_SPIKE_SET_EQ THEN
7974   ASM_MESON_TAC[]);;
7975
7976 let HAS_REAL_INTEGRAL_OPEN_INTERVAL = prove
7977  (`!f a b y. (f has_real_integral y) (real_interval(a,b)) <=>
7978              (f has_real_integral y) (real_interval[a,b])`,
7979   REWRITE_TAC[has_real_integral; IMAGE_LIFT_REAL_INTERVAL] THEN
7980   REWRITE_TAC[HAS_INTEGRAL_OPEN_INTERVAL]);;
7981
7982 let REAL_INTEGRABLE_ON_OPEN_INTERVAL = prove
7983  (`!f a b. f real_integrable_on real_interval(a,b) <=>
7984            f real_integrable_on real_interval[a,b]`,
7985   REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL_OPEN_INTERVAL]);;
7986
7987 let REAL_INTEGRAL_OPEN_INTERVAL = prove
7988  (`!f a b. real_integral(real_interval(a,b)) f =
7989            real_integral(real_interval[a,b]) f`,
7990   REWRITE_TAC[real_integral; HAS_REAL_INTEGRAL_OPEN_INTERVAL]);;
7991
7992 let HAS_REAL_INTEGRAL_ON_SUPERSET = prove
7993  (`!f s t.
7994         (!x. ~(x IN s) ==> f x = &0) /\ s SUBSET t /\ (f has_real_integral i) s
7995         ==> (f has_real_integral i) t`,
7996   REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET] THEN
7997   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
7998   ONCE_REWRITE_TAC[GSYM HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN
7999   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN
8000   AP_TERM_TAC THEN ABS_TAC THEN ASM_MESON_TAC[]);;
8001
8002 let REAL_INTEGRABLE_ON_SUPERSET = prove
8003  (`!f s t.
8004         (!x. ~(x IN s) ==> f x = &0) /\ s SUBSET t /\ f real_integrable_on s
8005         ==> f real_integrable_on t`,
8006   REWRITE_TAC[real_integrable_on] THEN
8007   MESON_TAC[HAS_REAL_INTEGRAL_ON_SUPERSET]);;
8008
8009 let REAL_INTEGRABLE_RESTRICT_UNIV = prove
8010  (`!f s. (\x. if x IN s then f x else &0) real_integrable_on (:real) <=>
8011          f real_integrable_on s`,
8012   REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL_RESTRICT_UNIV]);;
8013
8014 let REAL_INTEGRAL_RESTRICT_UNIV = prove
8015  (`!f s.
8016      real_integral (:real) (\x. if x IN s then f x else &0) =
8017      real_integral s f`,
8018   REWRITE_TAC[real_integral; HAS_REAL_INTEGRAL_RESTRICT_UNIV]);;
8019
8020 let REAL_INTEGRAL_RESTRICT = prove
8021  (`!f s t.
8022         s SUBSET t
8023         ==> real_integral t (\x. if x IN s then f x else &0) =
8024             real_integral s f`,
8025   SIMP_TAC[real_integral; HAS_REAL_INTEGRAL_RESTRICT]);;
8026
8027 let HAS_REAL_INTEGRAL_RESTRICT_INTER = prove
8028  (`!f s t.
8029         ((\x. if x IN s then f x else &0) has_real_integral i) t <=>
8030         (f has_real_integral i) (s INTER t)`,
8031   REPEAT GEN_TAC THEN
8032   ONCE_REWRITE_TAC[GSYM HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN
8033   REWRITE_TAC[IN_INTER] THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
8034   REWRITE_TAC[FUN_EQ_THM] THEN MESON_TAC[]);;
8035
8036 let REAL_INTEGRAL_RESTRICT_INTER = prove
8037  (`!f s t.
8038         real_integral t (\x. if x IN s then f x else &0) =
8039         real_integral (s INTER t) f`,
8040   REWRITE_TAC[real_integral; HAS_REAL_INTEGRAL_RESTRICT_INTER]);;
8041
8042 let REAL_INTEGRABLE_RESTRICT_INTER = prove
8043  (`!f s t.
8044         (\x. if x IN s then f x else &0) real_integrable_on t <=>
8045         f real_integrable_on (s INTER t)`,
8046   REWRITE_TAC[real_integrable_on; HAS_REAL_INTEGRAL_RESTRICT_INTER]);;
8047
8048 let REAL_NEGLIGIBLE_ON_INTERVALS = prove
8049  (`!s. real_negligible s <=>
8050          !a b:real. real_negligible(s INTER real_interval[a,b])`,
8051   GEN_TAC THEN REWRITE_TAC[real_negligible] THEN
8052   GEN_REWRITE_TAC LAND_CONV [NEGLIGIBLE_ON_INTERVALS] THEN
8053   REWRITE_TAC[FORALL_LIFT; GSYM IMAGE_LIFT_REAL_INTERVAL] THEN
8054   REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN AP_TERM_TAC THEN SET_TAC[LIFT_DROP]);;
8055
8056 let HAS_REAL_INTEGRAL_SUBSET_LE = prove
8057  (`!f:real->real s t i j.
8058         s SUBSET t /\ (f has_real_integral i) s /\ (f has_real_integral j) t /\
8059         (!x. x IN t ==> &0 <= f x)
8060         ==> i <= j`,
8061   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_LE THEN
8062   MAP_EVERY EXISTS_TAC
8063    [`\x:real. if x IN s then f(x) else &0`;
8064     `\x:real. if x IN t then f(x) else &0`; `(:real)`] THEN
8065   ASM_REWRITE_TAC[HAS_REAL_INTEGRAL_RESTRICT_UNIV; IN_UNIV] THEN
8066   X_GEN_TAC `x:real` THEN
8067   REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_LE_REFL]) THEN
8068   ASM SET_TAC[]);;
8069
8070 let REAL_INTEGRAL_SUBSET_LE = prove
8071  (`!f:real->real s t.
8072         s SUBSET t /\ f real_integrable_on s /\ f real_integrable_on t /\
8073         (!x. x IN t ==> &0 <= f(x))
8074         ==> real_integral s f <= real_integral t f`,
8075   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_INTEGRAL_SUBSET_LE THEN
8076   ASM_MESON_TAC[REAL_INTEGRABLE_INTEGRAL]);;
8077
8078 let REAL_INTEGRABLE_ON_SUBINTERVAL = prove
8079  (`!f:real->real s a b.
8080         f real_integrable_on s /\ real_interval[a,b] SUBSET s
8081         ==> f real_integrable_on real_interval[a,b]`,
8082   REWRITE_TAC[REAL_INTEGRABLE_ON; IMAGE_LIFT_REAL_INTERVAL] THEN
8083   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
8084   EXISTS_TAC `IMAGE lift s` THEN ASM_REWRITE_TAC[] THEN
8085   REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL] THEN
8086   ASM_SIMP_TAC[IMAGE_SUBSET]);;
8087
8088 let REAL_INTEGRABLE_STRADDLE = prove
8089  (`!f s.
8090         (!e. &0 < e
8091              ==> ?g h i j. (g has_real_integral i) s /\
8092                            (h has_real_integral j) s /\
8093                            abs(i - j) < e /\
8094                            !x. x IN s ==> g x <= f x /\ f x <= h x)
8095         ==> f real_integrable_on s`,
8096   REWRITE_TAC[REAL_INTEGRABLE_ON; has_real_integral] THEN
8097   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_STRADDLE THEN
8098   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8099   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
8100   REWRITE_TAC[EXISTS_DROP; FORALL_IN_IMAGE] THEN
8101   SIMP_TAC[LEFT_IMP_EXISTS_THM; GSYM DROP_SUB; LIFT_DROP; GSYM ABS_DROP] THEN
8102   MAP_EVERY X_GEN_TAC
8103    [`g:real->real`; `h:real->real`; `i:real^1`; `j:real^1`] THEN
8104   STRIP_TAC THEN MAP_EVERY EXISTS_TAC
8105    [`lift o g o drop`; `lift o h o drop`; `i:real^1`; `j:real^1`] THEN
8106   ASM_REWRITE_TAC[o_THM; LIFT_DROP]);;
8107
8108 let HAS_REAL_INTEGRAL_STRADDLE_NULL = prove
8109  (`!f g s. (!x. x IN s ==> &0 <= f x /\ f x <= g x) /\
8110            (g has_real_integral &0) s
8111            ==> (f has_real_integral &0) s`,
8112   REPEAT STRIP_TAC THEN REWRITE_TAC[HAS_REAL_INTEGRAL_INTEGRABLE_INTEGRAL] THEN
8113   MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
8114    [MATCH_MP_TAC REAL_INTEGRABLE_STRADDLE THEN
8115     GEN_TAC THEN DISCH_TAC THEN
8116     MAP_EVERY EXISTS_TAC
8117      [`(\x. &0):real->real`; `g:real->real`;
8118       `&0:real`; `&0:real`] THEN
8119     ASM_REWRITE_TAC[HAS_REAL_INTEGRAL_0; REAL_SUB_REFL; REAL_ABS_NUM];
8120     DISCH_TAC THEN REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
8121      [MATCH_MP_TAC(ISPECL [`f:real->real`; `g:real->real`]
8122         HAS_REAL_INTEGRAL_LE);
8123       MATCH_MP_TAC(ISPECL [`(\x. &0):real->real`; `f:real->real`]
8124         HAS_REAL_INTEGRAL_LE)] THEN
8125     EXISTS_TAC `s:real->bool` THEN
8126     ASM_SIMP_TAC[GSYM HAS_REAL_INTEGRAL_INTEGRAL; HAS_REAL_INTEGRAL_0]]);;
8127
8128 let HAS_REAL_INTEGRAL_UNION = prove
8129  (`!f i j s t.
8130         (f has_real_integral i) s /\ (f has_real_integral j) t /\
8131         real_negligible(s INTER t)
8132         ==> (f has_real_integral (i + j)) (s UNION t)`,
8133   REPEAT GEN_TAC THEN
8134   REWRITE_TAC[has_real_integral; real_negligible; LIFT_ADD; IMAGE_UNION] THEN
8135   DISCH_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_UNION THEN POP_ASSUM MP_TAC THEN
8136   REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THEN REWRITE_TAC[] THEN
8137   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[LIFT_DROP]);;
8138
8139 let HAS_REAL_INTEGRAL_UNIONS = prove
8140  (`!f:real->real i t.
8141         FINITE t /\
8142         (!s. s IN t ==> (f has_real_integral (i s)) s) /\
8143         (!s s'. s IN t /\ s' IN t /\ ~(s = s') ==> real_negligible(s INTER s'))
8144         ==> (f has_real_integral (sum t i)) (UNIONS t)`,
8145   REPEAT GEN_TAC THEN
8146   REWRITE_TAC[has_real_integral; real_negligible; LIFT_ADD; IMAGE_UNIONS] THEN
8147   SIMP_TAC[LIFT_SUM] THEN DISCH_TAC THEN
8148   MP_TAC(ISPECL [`lift o f o drop`; `\s. lift(i(IMAGE drop s))`;
8149                  `IMAGE (IMAGE lift) t`]
8150     HAS_INTEGRAL_UNIONS) THEN
8151   ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM;
8152                IMAGE_LIFT_DROP; GSYM IMAGE_o] THEN
8153   ASM_SIMP_TAC[LIFT_EQ; SET_RULE
8154    `(!x y. f x = f y <=> x = y)
8155     ==> (IMAGE f s = IMAGE f t <=> s = t) /\
8156         (IMAGE f s INTER IMAGE f t = IMAGE f (s INTER t))`] THEN
8157   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
8158   W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhand o snd) THEN
8159   ANTS_TAC THENL [ASM SET_TAC[LIFT_DROP]; ALL_TAC] THEN
8160   DISCH_THEN SUBST1_TAC THEN
8161   REWRITE_TAC[o_DEF; GSYM IMAGE_o; IMAGE_LIFT_DROP]);;
8162
8163 let REAL_MONOTONE_CONVERGENCE_INCREASING = prove
8164  (`!f:num->real->real g s.
8165         (!k. (f k) real_integrable_on s) /\
8166         (!k x. x IN s ==> f k x <= f (SUC k) x) /\
8167         (!x. x IN s ==> ((\k. f k x) ---> g x) sequentially) /\
8168         real_bounded {real_integral s (f k) | k IN (:num)}
8169         ==> g real_integrable_on s /\
8170             ((\k. real_integral s (f k)) ---> real_integral s g) sequentially`,
8171   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN
8172   REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN
8173   MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`;
8174                  `lift o g o drop`;  `IMAGE lift s`]
8175                 MONOTONE_CONVERGENCE_INCREASING) THEN
8176   ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF] THEN
8177   SUBGOAL_THEN
8178    `!k:num. real_integral s (f k) =
8179             drop(integral (IMAGE lift s) (lift o f k o drop))`
8180    (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th])
8181   THENL
8182    [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN
8183     ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF];
8184     ALL_TAC] THEN
8185   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN
8186   REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; GSYM ABS_DROP] THEN
8187   DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN ANTS_TAC THENL
8188    [REWRITE_TAC[bounded] THEN EXISTS_TAC `B:real` THEN
8189     RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN
8190     ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV];
8191     ALL_TAC] THEN
8192   REWRITE_TAC[o_DEF; LIFT_DROP] THEN
8193   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
8194   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
8195   ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN REWRITE_TAC[LIFT_DROP] THEN
8196   CONV_TAC SYM_CONV THEN REWRITE_TAC[GSYM o_DEF] THEN
8197   MATCH_MP_TAC REAL_INTEGRAL THEN ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF]);;
8198
8199 let REAL_MONOTONE_CONVERGENCE_DECREASING = prove
8200  (`!f:num->real->real g s.
8201         (!k. (f k) real_integrable_on s) /\
8202         (!k x. x IN s ==> f (SUC k) x <= f k x) /\
8203         (!x. x IN s ==> ((\k. f k x) ---> g x) sequentially) /\
8204         real_bounded {real_integral s (f k) | k IN (:num)}
8205         ==> g real_integrable_on s /\
8206             ((\k. real_integral s (f k)) ---> real_integral s g) sequentially`,
8207   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN
8208   REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN
8209   MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`;
8210                  `lift o g o drop`;  `IMAGE lift s`]
8211                 MONOTONE_CONVERGENCE_DECREASING) THEN
8212   ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF] THEN
8213   SUBGOAL_THEN
8214    `!k:num. real_integral s (f k) =
8215             drop(integral (IMAGE lift s) (lift o f k o drop))`
8216    (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th])
8217   THENL
8218    [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN
8219     ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF];
8220     ALL_TAC] THEN
8221   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN
8222   REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; GSYM ABS_DROP] THEN
8223   DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN ANTS_TAC THENL
8224    [REWRITE_TAC[bounded] THEN EXISTS_TAC `B:real` THEN
8225     RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN
8226     ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV];
8227     ALL_TAC] THEN
8228   REWRITE_TAC[o_DEF; LIFT_DROP] THEN
8229   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
8230   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
8231   ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN REWRITE_TAC[LIFT_DROP] THEN
8232   CONV_TAC SYM_CONV THEN REWRITE_TAC[GSYM o_DEF] THEN
8233   MATCH_MP_TAC REAL_INTEGRAL THEN ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF]);;
8234
8235 let REAL_BEPPO_LEVI_INCREASING = prove
8236  (`!f s. (!k. (f k) real_integrable_on s) /\
8237          (!k x. x IN s ==> f k x <= f (SUC k) x) /\
8238          real_bounded {real_integral s (f k) | k IN (:num)}
8239          ==> ?g k. real_negligible k /\
8240                    !x. x IN (s DIFF k) ==> ((\k. f k x) ---> g x) sequentially`,
8241   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN
8242   REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN
8243   MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`;
8244                  `IMAGE lift s`]
8245                 BEPPO_LEVI_INCREASING) THEN
8246   ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF] THEN
8247   SUBGOAL_THEN
8248    `!k:num. real_integral s (f k) =
8249             drop(integral (IMAGE lift s) (lift o f k o drop))`
8250    (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th])
8251   THENL
8252    [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN
8253     ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF];
8254     ALL_TAC] THEN
8255   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN
8256   REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; GSYM ABS_DROP] THEN
8257   DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN ANTS_TAC THENL
8258    [REWRITE_TAC[bounded] THEN EXISTS_TAC `B:real` THEN
8259     RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN
8260     ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV];
8261     ALL_TAC] THEN
8262   REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_DIFF; IMP_CONJ; FORALL_IN_IMAGE] THEN
8263   MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `k:real^1->bool`] THEN
8264   REWRITE_TAC[IMP_IMP; LIFT_DROP] THEN STRIP_TAC THEN
8265   MAP_EVERY EXISTS_TAC [`drop o g o lift`; `IMAGE drop k`] THEN
8266   ASM_REWRITE_TAC[real_negligible; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN
8267   ASM_REWRITE_TAC[IN_IMAGE_LIFT_DROP; o_THM; LIFT_DROP]);;
8268
8269 let REAL_BEPPO_LEVI_DECREASING = prove
8270  (`!f s. (!k. (f k) real_integrable_on s) /\
8271          (!k x. x IN s ==> f (SUC k) x <= f k x) /\
8272          real_bounded {real_integral s (f k) | k IN (:num)}
8273          ==> ?g k. real_negligible k /\
8274                    !x. x IN (s DIFF k) ==> ((\k. f k x) ---> g x) sequentially`,
8275   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN
8276   REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN
8277   MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`;
8278                  `IMAGE lift s`]
8279                 BEPPO_LEVI_DECREASING) THEN
8280   ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF] THEN
8281   SUBGOAL_THEN
8282    `!k:num. real_integral s (f k) =
8283             drop(integral (IMAGE lift s) (lift o f k o drop))`
8284    (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th])
8285   THENL
8286    [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN
8287     ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF];
8288     ALL_TAC] THEN
8289   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN
8290   REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; GSYM ABS_DROP] THEN
8291   DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN ANTS_TAC THENL
8292    [REWRITE_TAC[bounded] THEN EXISTS_TAC `B:real` THEN
8293     RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN
8294     ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV];
8295     ALL_TAC] THEN
8296   REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_DIFF; IMP_CONJ; FORALL_IN_IMAGE] THEN
8297   MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `k:real^1->bool`] THEN
8298   REWRITE_TAC[IMP_IMP; LIFT_DROP] THEN STRIP_TAC THEN
8299   MAP_EVERY EXISTS_TAC [`drop o g o lift`; `IMAGE drop k`] THEN
8300   ASM_REWRITE_TAC[real_negligible; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN
8301   ASM_REWRITE_TAC[IN_IMAGE_LIFT_DROP; o_THM; LIFT_DROP]);;
8302
8303 let REAL_BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING = prove
8304  (`!f s.
8305      (!k. (f k) real_integrable_on s) /\
8306      (!k x. x IN s ==> f k x <= f (SUC k) x) /\
8307      real_bounded {real_integral s (f k) | k IN (:num)}
8308      ==> ?g k. real_negligible k /\
8309                (!x. x IN (s DIFF k) ==> ((\k. f k x) ---> g x) sequentially) /\
8310                g real_integrable_on s /\
8311                ((\k. real_integral s (f k)) ---> real_integral s g)
8312                sequentially`,
8313   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN
8314   REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN
8315   MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`;
8316                  `IMAGE lift s`]
8317                 BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING) THEN
8318   ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF] THEN
8319   SUBGOAL_THEN
8320    `!k:num. real_integral s (f k) =
8321             drop(integral (IMAGE lift s) (lift o f k o drop))`
8322    (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th])
8323   THENL
8324    [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN
8325     ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF];
8326     ALL_TAC] THEN
8327   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN
8328   REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; GSYM ABS_DROP] THEN
8329   DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN ANTS_TAC THENL
8330    [REWRITE_TAC[bounded] THEN EXISTS_TAC `B:real` THEN
8331     RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN
8332     ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV];
8333     ALL_TAC] THEN
8334   REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_DIFF; IMP_CONJ; FORALL_IN_IMAGE] THEN
8335   MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `k:real^1->bool`] THEN
8336   REWRITE_TAC[IMP_IMP; LIFT_DROP] THEN STRIP_TAC THEN
8337   MAP_EVERY EXISTS_TAC [`drop o g o lift`; `IMAGE drop k`] THEN
8338   ASM_REWRITE_TAC[real_negligible; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN
8339   ASM_REWRITE_TAC[IN_IMAGE_LIFT_DROP; o_THM; LIFT_DROP; ETA_AX] THEN
8340   SUBGOAL_THEN
8341    `real_integral s (drop o g o lift) =
8342             drop(integral (IMAGE lift s) (lift o (drop o g o lift) o drop))`
8343   SUBST1_TAC THENL
8344    [MATCH_MP_TAC REAL_INTEGRAL THEN
8345     ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF; LIFT_DROP; ETA_AX];
8346     ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]]);;
8347
8348 let REAL_BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING = prove
8349  (`!f s.
8350      (!k. (f k) real_integrable_on s) /\
8351      (!k x. x IN s ==> f (SUC k) x <= f k x) /\
8352      real_bounded {real_integral s (f k) | k IN (:num)}
8353      ==> ?g k. real_negligible k /\
8354                (!x. x IN (s DIFF k) ==> ((\k. f k x) ---> g x) sequentially) /\
8355                g real_integrable_on s /\
8356                ((\k. real_integral s (f k)) ---> real_integral s g)
8357                sequentially`,
8358   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN
8359   REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN
8360   MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`;
8361                  `IMAGE lift s`]
8362                 BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING) THEN
8363   ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF] THEN
8364   SUBGOAL_THEN
8365    `!k:num. real_integral s (f k) =
8366             drop(integral (IMAGE lift s) (lift o f k o drop))`
8367    (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th])
8368   THENL
8369    [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN
8370     ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF];
8371     ALL_TAC] THEN
8372   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN
8373   REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; GSYM ABS_DROP] THEN
8374   DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN ANTS_TAC THENL
8375    [REWRITE_TAC[bounded] THEN EXISTS_TAC `B:real` THEN
8376     RULE_ASSUM_TAC(REWRITE_RULE[o_DEF]) THEN
8377     ASM_REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV];
8378     ALL_TAC] THEN
8379   REWRITE_TAC[LEFT_IMP_EXISTS_THM; IN_DIFF; IMP_CONJ; FORALL_IN_IMAGE] THEN
8380   MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `k:real^1->bool`] THEN
8381   REWRITE_TAC[IMP_IMP; LIFT_DROP] THEN STRIP_TAC THEN
8382   MAP_EVERY EXISTS_TAC [`drop o g o lift`; `IMAGE drop k`] THEN
8383   ASM_REWRITE_TAC[real_negligible; GSYM IMAGE_o; IMAGE_LIFT_DROP] THEN
8384   ASM_REWRITE_TAC[IN_IMAGE_LIFT_DROP; o_THM; LIFT_DROP; ETA_AX] THEN
8385   SUBGOAL_THEN
8386    `real_integral s (drop o g o lift) =
8387             drop(integral (IMAGE lift s) (lift o (drop o g o lift) o drop))`
8388   SUBST1_TAC THENL
8389    [MATCH_MP_TAC REAL_INTEGRAL THEN
8390     ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF; LIFT_DROP; ETA_AX];
8391     ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX]]);;
8392
8393 let REAL_INTEGRAL_ABS_BOUND_INTEGRAL = prove
8394  (`!f:real->real g s.
8395         f real_integrable_on s /\ g real_integrable_on s /\
8396         (!x. x IN s ==> abs(f x) <= g x)
8397         ==> abs(real_integral s f) <= real_integral s g`,
8398   SIMP_TAC[REAL_INTEGRAL; GSYM ABS_DROP] THEN
8399   SIMP_TAC[REAL_INTEGRABLE_ON; INTEGRAL_NORM_BOUND_INTEGRAL] THEN
8400   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
8401   ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; NORM_LIFT]);;
8402
8403 let ABSOLUTELY_REAL_INTEGRABLE_LE = prove
8404  (`!f:real->real s.
8405         f absolutely_real_integrable_on s
8406         ==> abs(real_integral s f) <= real_integral s (\x. abs(f x))`,
8407   SIMP_TAC[absolutely_real_integrable_on] THEN
8408   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_ABS_BOUND_INTEGRAL THEN
8409   ASM_REWRITE_TAC[REAL_LE_REFL]);;
8410
8411 let ABSOLUTELY_REAL_INTEGRABLE_0 = prove
8412  (`!s. (\x. &0) absolutely_real_integrable_on s`,
8413   REWRITE_TAC[absolutely_real_integrable_on; REAL_ABS_NUM;
8414               REAL_INTEGRABLE_0]);;
8415
8416 let ABSOLUTELY_REAL_INTEGRABLE_CONST = prove
8417  (`!a b c. (\x. c) absolutely_real_integrable_on real_interval[a,b]`,
8418   REWRITE_TAC[absolutely_real_integrable_on; REAL_INTEGRABLE_CONST]);;
8419
8420 let ABSOLUTELY_REAL_INTEGRABLE_LMUL = prove
8421  (`!f s c. f absolutely_real_integrable_on s
8422            ==> (\x. c * f(x)) absolutely_real_integrable_on s`,
8423   SIMP_TAC[absolutely_real_integrable_on;
8424            REAL_INTEGRABLE_LMUL; REAL_ABS_MUL]);;
8425
8426 let ABSOLUTELY_REAL_INTEGRABLE_RMUL = prove
8427  (`!f s c. f absolutely_real_integrable_on s
8428            ==> (\x. f(x) * c) absolutely_real_integrable_on s`,
8429   SIMP_TAC[absolutely_real_integrable_on;
8430            REAL_INTEGRABLE_RMUL; REAL_ABS_MUL]);;
8431
8432 let ABSOLUTELY_REAL_INTEGRABLE_NEG = prove
8433  (`!f s. f absolutely_real_integrable_on s
8434          ==> (\x. --f(x)) absolutely_real_integrable_on s`,
8435   SIMP_TAC[absolutely_real_integrable_on; REAL_INTEGRABLE_NEG; REAL_ABS_NEG]);;
8436
8437 let ABSOLUTELY_REAL_INTEGRABLE_ABS = prove
8438  (`!f s. f absolutely_real_integrable_on s
8439          ==> (\x. abs(f x)) absolutely_real_integrable_on s`,
8440   SIMP_TAC[absolutely_real_integrable_on; REAL_ABS_ABS]);;
8441
8442 let ABSOLUTELY_REAL_INTEGRABLE_ON_SUBINTERVAL = prove
8443  (`!f:real->real s a b.
8444         f absolutely_real_integrable_on s /\ real_interval[a,b] SUBSET s
8445         ==> f absolutely_real_integrable_on real_interval[a,b]`,
8446   REWRITE_TAC[absolutely_real_integrable_on] THEN
8447   MESON_TAC[REAL_INTEGRABLE_ON_SUBINTERVAL]);;
8448
8449 let ABSOLUTELY_REAL_INTEGRABLE_RESTRICT_UNIV = prove
8450  (`!f s. (\x. if x IN s then f x else &0)
8451               absolutely_real_integrable_on (:real) <=>
8452          f absolutely_real_integrable_on s`,
8453   REWRITE_TAC[absolutely_real_integrable_on; REAL_INTEGRABLE_RESTRICT_UNIV;
8454               COND_RAND; REAL_ABS_NUM]);;
8455
8456 let ABSOLUTELY_REAL_INTEGRABLE_ADD = prove
8457  (`!f:real->real g s.
8458         f absolutely_real_integrable_on s /\
8459         g absolutely_real_integrable_on s
8460         ==> (\x. f(x) + g(x)) absolutely_real_integrable_on s`,
8461   REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_ON] THEN
8462   SIMP_TAC[o_DEF; LIFT_ADD; ABSOLUTELY_INTEGRABLE_ADD]);;
8463
8464 let ABSOLUTELY_REAL_INTEGRABLE_SUB = prove
8465  (`!f:real->real g s.
8466         f absolutely_real_integrable_on s /\
8467         g absolutely_real_integrable_on s
8468         ==> (\x. f(x) - g(x)) absolutely_real_integrable_on s`,
8469   REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_ON] THEN
8470   SIMP_TAC[o_DEF; LIFT_SUB; ABSOLUTELY_INTEGRABLE_SUB]);;
8471
8472 let ABSOLUTELY_REAL_INTEGRABLE_LINEAR = prove
8473  (`!f h s.
8474         f absolutely_real_integrable_on s /\ linear(lift o h o drop)
8475         ==> (h o f) absolutely_real_integrable_on s`,
8476   REPEAT GEN_TAC THEN REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_ON] THEN
8477   DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_LINEAR) THEN
8478   REWRITE_TAC[o_DEF; LIFT_DROP]);;
8479
8480 let ABSOLUTELY_REAL_INTEGRABLE_SUM = prove
8481  (`!f:A->real->real s t.
8482         FINITE t /\
8483         (!a. a IN t ==> (f a) absolutely_real_integrable_on s)
8484         ==>  (\x. sum t (\a. f a x)) absolutely_real_integrable_on s`,
8485   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
8486   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
8487   SIMP_TAC[SUM_CLAUSES; ABSOLUTELY_REAL_INTEGRABLE_0; IN_INSERT;
8488            ABSOLUTELY_REAL_INTEGRABLE_ADD; ETA_AX]);;
8489
8490 let ABSOLUTELY_REAL_INTEGRABLE_MAX = prove
8491  (`!f:real->real g:real->real s.
8492         f absolutely_real_integrable_on s /\ g absolutely_real_integrable_on s
8493         ==> (\x. max (f x) (g x))
8494             absolutely_real_integrable_on s`,
8495   REPEAT STRIP_TAC THEN
8496   REWRITE_TAC[REAL_ARITH `max a b = &1 / &2 * ((a + b) + abs(a - b))`] THEN
8497   MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_LMUL THEN
8498   ASM_SIMP_TAC[ABSOLUTELY_REAL_INTEGRABLE_SUB; ABSOLUTELY_REAL_INTEGRABLE_ADD;
8499                ABSOLUTELY_REAL_INTEGRABLE_ABS]);;
8500
8501 let ABSOLUTELY_REAL_INTEGRABLE_MIN = prove
8502  (`!f:real->real g:real->real s.
8503         f absolutely_real_integrable_on s /\ g absolutely_real_integrable_on s
8504         ==> (\x. min (f x) (g x))
8505             absolutely_real_integrable_on s`,
8506   REPEAT STRIP_TAC THEN
8507   REWRITE_TAC[REAL_ARITH `min a b = &1 / &2 * ((a + b) - abs(a - b))`] THEN
8508   MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_LMUL THEN
8509   ASM_SIMP_TAC[ABSOLUTELY_REAL_INTEGRABLE_SUB; ABSOLUTELY_REAL_INTEGRABLE_ADD;
8510                ABSOLUTELY_REAL_INTEGRABLE_ABS]);;
8511
8512 let ABSOLUTELY_REAL_INTEGRABLE_IMP_INTEGRABLE = prove
8513  (`!f s. f absolutely_real_integrable_on s ==> f real_integrable_on s`,
8514   SIMP_TAC[absolutely_real_integrable_on]);;
8515
8516 let ABSOLUTELY_REAL_INTEGRABLE_CONTINUOUS = prove
8517  (`!f a b.
8518         f real_continuous_on real_interval[a,b]
8519         ==> f absolutely_real_integrable_on real_interval[a,b]`,
8520   REWRITE_TAC[REAL_CONTINUOUS_ON; ABSOLUTELY_REAL_INTEGRABLE_ON;
8521               has_real_integral;
8522               GSYM integrable_on; GSYM EXISTS_LIFT] THEN
8523   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; ABSOLUTELY_INTEGRABLE_CONTINUOUS]);;
8524
8525 let NONNEGATIVE_ABSOLUTELY_REAL_INTEGRABLE = prove
8526  (`!f s.
8527         (!x. x IN s ==> &0 <= f(x)) /\
8528         f real_integrable_on s
8529         ==> f absolutely_real_integrable_on s`,
8530   SIMP_TAC[absolutely_real_integrable_on] THEN
8531   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRABLE_EQ THEN
8532   EXISTS_TAC `f:real->real` THEN ASM_SIMP_TAC[real_abs]);;
8533
8534 let ABSOLUTELY_REAL_INTEGRABLE_INTEGRABLE_BOUND = prove
8535  (`!f:real->real g s.
8536         (!x. x IN s ==> abs(f x) <= g x) /\
8537         f real_integrable_on s /\ g real_integrable_on s
8538         ==> f absolutely_real_integrable_on s`,
8539   REWRITE_TAC[REAL_INTEGRABLE_ON; ABSOLUTELY_REAL_INTEGRABLE_ON] THEN
8540   REPEAT STRIP_TAC THEN
8541   MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
8542   EXISTS_TAC `lift o g o drop` THEN ASM_REWRITE_TAC[FORALL_IN_IMAGE] THEN
8543   ASM_REWRITE_TAC[o_DEF; LIFT_DROP; NORM_LIFT]);;
8544
8545 let ABSOLUTELY_REAL_INTEGRABLE_ABSOLUTELY_REAL_INTEGRABLE_BOUND = prove
8546  (`!f:real->real g:real->real s.
8547         (!x. x IN s ==> abs(f x) <= abs(g x)) /\
8548         f real_integrable_on s /\ g absolutely_real_integrable_on s
8549         ==> f absolutely_real_integrable_on s`,
8550   REPEAT STRIP_TAC THEN
8551   MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_INTEGRABLE_BOUND THEN
8552   EXISTS_TAC `\x:real. abs(g x)` THEN ASM_REWRITE_TAC[] THEN
8553   RULE_ASSUM_TAC(REWRITE_RULE[absolutely_real_integrable_on]) THEN
8554   ASM_REWRITE_TAC[]);;
8555
8556 let ABSOLUTELY_REAL_INTEGRABLE_ABSOLUTELY_REAL_INTEGRABLE_UBOUND = prove
8557  (`!f:real->real g:real->real s.
8558         (!x. x IN s ==> f x <= g x) /\
8559         f real_integrable_on s /\ g absolutely_real_integrable_on s
8560         ==> g absolutely_real_integrable_on s`,
8561   REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_ON; REAL_INTEGRABLE_ON] THEN
8562   REPEAT STRIP_TAC THEN MATCH_MP_TAC
8563    ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_UBOUND THEN
8564   EXISTS_TAC `lift o g o drop` THEN ASM_REWRITE_TAC[] THEN
8565   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
8566   ASM_REWRITE_TAC[IMP_IMP; DIMINDEX_1; FORALL_1; o_THM; LIFT_DROP;
8567                   GSYM drop]);;
8568
8569 let ABSOLUTELY_REAL_INTEGRABLE_ABSOLUTELY_REAL_INTEGRABLE_LBOUND = prove
8570  (`!f:real->real g:real->real s.
8571         (!x. x IN s ==> f x <= g x) /\
8572         f absolutely_real_integrable_on s /\ g real_integrable_on s
8573         ==> g absolutely_real_integrable_on s`,
8574   REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_ON; REAL_INTEGRABLE_ON] THEN
8575   REPEAT STRIP_TAC THEN MATCH_MP_TAC
8576    ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_LBOUND THEN
8577   EXISTS_TAC `lift o f o drop` THEN ASM_REWRITE_TAC[] THEN
8578   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
8579   ASM_REWRITE_TAC[IMP_IMP; DIMINDEX_1; FORALL_1; o_THM; LIFT_DROP;
8580                   GSYM drop]);;
8581
8582 let ABSOLUTELY_REAL_INTEGRABLE_INF = prove
8583  (`!fs s:real->bool k:A->bool.
8584         FINITE k /\ ~(k = {}) /\
8585         (!i. i IN k ==> (\x. fs x i) absolutely_real_integrable_on s)
8586         ==> (\x. inf (IMAGE (fs x) k)) absolutely_real_integrable_on s`,
8587   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
8588   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[IMAGE_CLAUSES] THEN
8589   SIMP_TAC[INF_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
8590   MAP_EVERY X_GEN_TAC [`a:A`; `k:A->bool`] THEN
8591   ASM_CASES_TAC `k:A->bool = {}` THEN ASM_REWRITE_TAC[] THEN
8592   SIMP_TAC[IN_SING; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
8593   REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
8594   REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_MIN THEN
8595   CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INSERT] THEN
8596   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
8597   ASM_REWRITE_TAC[IN_INSERT]);;
8598
8599 let ABSOLUTELY_REAL_INTEGRABLE_SUP = prove
8600  (`!fs s:real->bool k:A->bool.
8601         FINITE k /\ ~(k = {}) /\
8602         (!i. i IN k ==> (\x. fs x i) absolutely_real_integrable_on s)
8603         ==> (\x. sup (IMAGE (fs x) k)) absolutely_real_integrable_on s`,
8604   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
8605   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[IMAGE_CLAUSES] THEN
8606   SIMP_TAC[SUP_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
8607   MAP_EVERY X_GEN_TAC [`a:A`; `k:A->bool`] THEN
8608   ASM_CASES_TAC `k:A->bool = {}` THEN ASM_REWRITE_TAC[] THEN
8609   SIMP_TAC[IN_SING; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
8610   REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
8611   REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_MAX THEN
8612   CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INSERT] THEN
8613   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
8614   ASM_REWRITE_TAC[IN_INSERT]);;
8615
8616 let REAL_DOMINATED_CONVERGENCE = prove
8617  (`!f:num->real->real g h s.
8618         (!k. (f k) real_integrable_on s) /\ h real_integrable_on s /\
8619         (!k x. x IN s ==> abs(f k x) <= h x) /\
8620         (!x. x IN s ==> ((\k. f k x) ---> g x) sequentially)
8621         ==> g real_integrable_on s /\
8622             ((\k. real_integral s (f k)) ---> real_integral s g) sequentially`,
8623   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_INTEGRABLE_ON; TENDSTO_REAL] THEN
8624   REWRITE_TAC[o_DEF] THEN STRIP_TAC THEN
8625   MP_TAC(ISPECL [`\n x. lift(f (n:num) (drop x))`;
8626                  `lift o g o drop`;  `lift o h o drop`; `IMAGE lift s`]
8627                 DOMINATED_CONVERGENCE) THEN
8628   ASM_REWRITE_TAC[FORALL_IN_IMAGE; LIFT_DROP; o_DEF; NORM_LIFT] THEN
8629   SUBGOAL_THEN
8630    `!k:num. real_integral s (f k) =
8631             drop(integral (IMAGE lift s) (lift o f k o drop))`
8632    (fun th -> RULE_ASSUM_TAC(REWRITE_RULE[th]) THEN REWRITE_TAC[th])
8633   THENL
8634    [GEN_TAC THEN MATCH_MP_TAC REAL_INTEGRAL THEN
8635     ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF];
8636     ALL_TAC] THEN
8637   REWRITE_TAC[o_DEF; LIFT_DROP] THEN
8638   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
8639   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
8640   ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN REWRITE_TAC[LIFT_DROP] THEN
8641   CONV_TAC SYM_CONV THEN REWRITE_TAC[GSYM o_DEF] THEN
8642   MATCH_MP_TAC REAL_INTEGRAL THEN ASM_REWRITE_TAC[REAL_INTEGRABLE_ON; o_DEF]);;
8643
8644 let HAS_REAL_MEASURE_HAS_MEASURE = prove
8645  (`!s m. s has_real_measure m <=> (IMAGE lift s) has_measure m`,
8646   REWRITE_TAC[has_real_measure; has_measure; has_real_integral] THEN
8647   REWRITE_TAC[o_DEF; LIFT_NUM]);;
8648
8649 let REAL_MEASURABLE_MEASURABLE = prove
8650  (`!s. real_measurable s <=> measurable(IMAGE lift s)`,
8651   REWRITE_TAC[real_measurable; measurable; HAS_REAL_MEASURE_HAS_MEASURE]);;
8652
8653 let REAL_MEASURE_MEASURE = prove
8654  (`!s. real_measure s = measure (IMAGE lift s)`,
8655   REWRITE_TAC[real_measure; measure; HAS_REAL_MEASURE_HAS_MEASURE]);;
8656
8657 let HAS_REAL_MEASURE_MEASURE = prove
8658  (`!s. real_measurable s <=> s has_real_measure (real_measure s)`,
8659   REWRITE_TAC[real_measure; real_measurable] THEN MESON_TAC[]);;
8660
8661 let HAS_REAL_MEASURE_UNIQUE = prove
8662  (`!s m1 m2. s has_real_measure m1 /\ s has_real_measure m2 ==> m1 = m2`,
8663   REWRITE_TAC[has_real_measure] THEN MESON_TAC[HAS_REAL_INTEGRAL_UNIQUE]);;
8664
8665 let REAL_MEASURE_UNIQUE = prove
8666  (`!s m. s has_real_measure m ==> real_measure s = m`,
8667   MESON_TAC[HAS_REAL_MEASURE_UNIQUE; HAS_REAL_MEASURE_MEASURE;
8668             real_measurable]);;
8669
8670 let HAS_REAL_MEASURE_REAL_MEASURABLE_REAL_MEASURE = prove
8671  (`!s m. s has_real_measure m <=> real_measurable s /\ real_measure s = m`,
8672   REWRITE_TAC[HAS_REAL_MEASURE_MEASURE] THEN MESON_TAC[REAL_MEASURE_UNIQUE]);;
8673
8674 let HAS_REAL_MEASURE_IMP_REAL_MEASURABLE = prove
8675  (`!s m. s has_real_measure m ==> real_measurable s`,
8676   REWRITE_TAC[real_measurable] THEN MESON_TAC[]);;
8677
8678 let HAS_REAL_MEASURE = prove
8679  (`!s m. s has_real_measure m <=>
8680               ((\x. if x IN s then &1 else &0) has_real_integral m) (:real)`,
8681   SIMP_TAC[HAS_REAL_INTEGRAL_RESTRICT_UNIV; has_real_measure]);;
8682
8683 let REAL_MEASURABLE = prove
8684  (`!s. real_measurable s <=> (\x. &1) real_integrable_on s`,
8685   REWRITE_TAC[real_measurable; real_integrable_on;
8686               has_real_measure; EXISTS_DROP; LIFT_DROP]);;
8687
8688 let REAL_MEASURABLE_REAL_INTEGRABLE = prove
8689  (`real_measurable s <=>
8690     (\x. if x IN s then &1 else &0) real_integrable_on UNIV`,
8691   REWRITE_TAC[real_measurable; real_integrable_on; HAS_REAL_MEASURE]);;
8692
8693 let REAL_MEASURE_REAL_INTEGRAL = prove
8694  (`!s. real_measurable s ==> real_measure s = real_integral s (\x. &1)`,
8695   REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
8696   MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
8697   ASM_REWRITE_TAC[GSYM has_real_measure; GSYM HAS_REAL_MEASURE_MEASURE]);;
8698
8699 let REAL_MEASURE_REAL_INTEGRAL_UNIV = prove
8700  (`!s. real_measurable s
8701        ==> real_measure s =
8702            real_integral UNIV (\x. if x IN s then &1 else &0)`,
8703   REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
8704   MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
8705   ASM_REWRITE_TAC[GSYM HAS_REAL_MEASURE; GSYM HAS_REAL_MEASURE_MEASURE]);;
8706
8707 let REAL_INTEGRAL_REAL_MEASURE = prove
8708  (`!s. real_measurable s ==> real_integral s (\x. &1) = real_measure s`,
8709   SIMP_TAC[GSYM DROP_EQ; LIFT_DROP; REAL_MEASURE_REAL_INTEGRAL]);;
8710
8711 let REAL_INTEGRAL_REAL_MEASURE_UNIV = prove
8712  (`!s. real_measurable s
8713        ==> real_integral UNIV (\x. if x IN s then &1 else &0) =
8714            real_measure s`,
8715   SIMP_TAC[REAL_MEASURE_REAL_INTEGRAL_UNIV]);;
8716
8717 let HAS_REAL_MEASURE_REAL_INTERVAL = prove
8718  (`(!a b. real_interval[a,b] has_real_measure (max (b - a) (&0))) /\
8719    (!a b. real_interval(a,b) has_real_measure (max (b - a) (&0)))`,
8720   REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; IMAGE_LIFT_REAL_INTERVAL] THEN
8721   REWRITE_TAC[HAS_MEASURE_MEASURABLE_MEASURE; MEASURABLE_INTERVAL;
8722               MEASURE_INTERVAL] THEN
8723   REWRITE_TAC[CONTENT_CLOSED_INTERVAL_CASES; DIMINDEX_1; FORALL_1] THEN
8724   REWRITE_TAC[PRODUCT_1; GSYM drop; LIFT_DROP] THEN REAL_ARITH_TAC);;
8725
8726 let REAL_MEASURABLE_REAL_INTERVAL = prove
8727  (`(!a b. real_measurable (real_interval[a,b])) /\
8728    (!a b. real_measurable (real_interval(a,b)))`,
8729   REWRITE_TAC[real_measurable] THEN
8730   MESON_TAC[HAS_REAL_MEASURE_REAL_INTERVAL]);;
8731
8732 let REAL_MEASURE_REAL_INTERVAL = prove
8733  (`(!a b. real_measure(real_interval[a,b]) = max (b - a) (&0)) /\
8734    (!a b. real_measure(real_interval(a,b)) = max (b - a) (&0))`,
8735   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN
8736   REWRITE_TAC[HAS_REAL_MEASURE_REAL_INTERVAL]);;
8737
8738 let REAL_MEASURABLE_INTER = prove
8739  (`!s t. real_measurable s /\ real_measurable t
8740          ==> real_measurable (s INTER t)`,
8741   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_MEASURABLE_MEASURABLE] THEN
8742   DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_INTER) THEN
8743   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[LIFT_DROP]);;
8744
8745 let REAL_MEASURABLE_UNION = prove
8746  (`!s t. real_measurable s /\ real_measurable t
8747          ==> real_measurable (s UNION t)`,
8748   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_MEASURABLE_MEASURABLE] THEN
8749   DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_UNION) THEN
8750   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[LIFT_DROP]);;
8751
8752 let HAS_REAL_MEASURE_DISJOINT_UNION = prove
8753  (`!s1 s2 m1 m2. s1 has_real_measure m1 /\ s2 has_real_measure m2 /\
8754                  DISJOINT s1 s2
8755                  ==> (s1 UNION s2) has_real_measure (m1 + m2)`,
8756   REPEAT GEN_TAC THEN
8757   REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; IMAGE_UNION] THEN
8758   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_MEASURE_DISJOINT_UNION THEN
8759   ASM SET_TAC[LIFT_DROP]);;
8760
8761 let REAL_MEASURE_DISJOINT_UNION = prove
8762  (`!s t. real_measurable s /\ real_measurable t /\ DISJOINT s t
8763          ==> real_measure(s UNION t) = real_measure s + real_measure t`,
8764   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN
8765   ASM_SIMP_TAC[HAS_REAL_MEASURE_DISJOINT_UNION;
8766                GSYM HAS_REAL_MEASURE_MEASURE]);;
8767
8768 let HAS_REAL_MEASURE_POS_LE = prove
8769  (`!m s. s has_real_measure m ==> &0 <= m`,
8770   REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; HAS_MEASURE_POS_LE]);;
8771
8772 let REAL_MEASURE_POS_LE = prove
8773  (`!s. real_measurable s ==> &0 <= real_measure s`,
8774   REWRITE_TAC[HAS_REAL_MEASURE_MEASURE; HAS_REAL_MEASURE_POS_LE]);;
8775
8776 let HAS_REAL_MEASURE_SUBSET = prove
8777  (`!s1 s2 m1 m2.
8778         s1 has_real_measure m1 /\ s2 has_real_measure m2 /\ s1 SUBSET s2
8779         ==> m1 <= m2`,
8780   REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE] THEN REPEAT STRIP_TAC THEN
8781   MATCH_MP_TAC(ISPECL [`IMAGE lift s1`; `IMAGE lift s2`]
8782     HAS_MEASURE_SUBSET) THEN
8783   ASM SET_TAC[HAS_MEASURE_SUBSET]);;
8784
8785 let REAL_MEASURE_SUBSET = prove
8786  (`!s t. real_measurable s /\ real_measurable t /\ s SUBSET t
8787          ==> real_measure s <= real_measure t`,
8788   REWRITE_TAC[HAS_REAL_MEASURE_MEASURE] THEN
8789   MESON_TAC[HAS_REAL_MEASURE_SUBSET]);;
8790
8791 let HAS_REAL_MEASURE_0 = prove
8792  (`!s. s has_real_measure &0 <=> real_negligible s`,
8793   REWRITE_TAC[real_negligible; HAS_REAL_MEASURE_HAS_MEASURE] THEN
8794   REWRITE_TAC[HAS_MEASURE_0]);;
8795
8796 let REAL_MEASURE_EQ_0 = prove
8797  (`!s. real_negligible s ==> real_measure s = &0`,
8798   MESON_TAC[REAL_MEASURE_UNIQUE; HAS_REAL_MEASURE_0]);;
8799
8800 let HAS_REAL_MEASURE_EMPTY = prove
8801  (`{} has_real_measure &0`,
8802   REWRITE_TAC[HAS_REAL_MEASURE_0; REAL_NEGLIGIBLE_EMPTY]);;
8803
8804 let REAL_MEASURE_EMPTY = prove
8805  (`real_measure {} = &0`,
8806   SIMP_TAC[REAL_MEASURE_EQ_0; REAL_NEGLIGIBLE_EMPTY]);;
8807
8808 let REAL_MEASURABLE_EMPTY = prove
8809  (`real_measurable {}`,
8810   REWRITE_TAC[real_measurable] THEN MESON_TAC[HAS_REAL_MEASURE_EMPTY]);;
8811
8812 let REAL_MEASURABLE_REAL_MEASURE_EQ_0 = prove
8813  (`!s. real_measurable s ==> (real_measure s = &0 <=> real_negligible s)`,
8814   REWRITE_TAC[HAS_REAL_MEASURE_MEASURE; GSYM HAS_REAL_MEASURE_0] THEN
8815   MESON_TAC[REAL_MEASURE_UNIQUE]);;
8816
8817 let REAL_MEASURABLE_REAL_MEASURE_POS_LT = prove
8818  (`!s. real_measurable s ==> (&0 < real_measure s <=> ~real_negligible s)`,
8819   SIMP_TAC[REAL_LT_LE; REAL_MEASURE_POS_LE;
8820            GSYM REAL_MEASURABLE_REAL_MEASURE_EQ_0] THEN
8821   REWRITE_TAC[EQ_SYM_EQ]);;
8822
8823 let REAL_NEGLIGIBLE_REAL_INTERVAL = prove
8824  (`(!a b. real_negligible(real_interval[a,b]) <=> real_interval(a,b) = {}) /\
8825    (!a b. real_negligible(real_interval(a,b)) <=> real_interval(a,b) = {})`,
8826   REWRITE_TAC[real_negligible; IMAGE_LIFT_REAL_INTERVAL] THEN
8827   REWRITE_TAC[NEGLIGIBLE_INTERVAL] THEN
8828   REWRITE_TAC[REAL_INTERVAL_EQ_EMPTY; INTERVAL_EQ_EMPTY_1; LIFT_DROP]);;
8829
8830 let REAL_MEASURABLE_UNIONS = prove
8831  (`!f. FINITE f /\ (!s. s IN f ==> real_measurable s)
8832        ==> real_measurable (UNIONS f)`,
8833   REWRITE_TAC[REAL_MEASURABLE_MEASURABLE; IMAGE_UNIONS] THEN
8834   REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_UNIONS THEN
8835   ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE]);;
8836
8837 let HAS_REAL_MEASURE_DIFF_SUBSET = prove
8838  (`!s1 s2 m1 m2.
8839         s1 has_real_measure m1 /\ s2 has_real_measure m2 /\ s2 SUBSET s1
8840         ==> (s1 DIFF s2) has_real_measure (m1 - m2)`,
8841   REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE] THEN REPEAT STRIP_TAC THEN
8842   SIMP_TAC[IMAGE_DIFF_INJ; LIFT_EQ] THEN
8843   MATCH_MP_TAC HAS_MEASURE_DIFF_SUBSET THEN
8844   ASM_SIMP_TAC[IMAGE_SUBSET]);;
8845
8846 let REAL_MEASURABLE_DIFF = prove
8847  (`!s t. real_measurable s /\ real_measurable t
8848          ==> real_measurable (s DIFF t)`,
8849   SIMP_TAC[REAL_MEASURABLE_MEASURABLE; IMAGE_DIFF_INJ; LIFT_EQ] THEN
8850   REWRITE_TAC[MEASURABLE_DIFF]);;
8851
8852 let REAL_MEASURE_DIFF_SUBSET = prove
8853  (`!s t. real_measurable s /\ real_measurable t /\ t SUBSET s
8854          ==> real_measure(s DIFF t) = real_measure s - real_measure t`,
8855   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN
8856   ASM_SIMP_TAC[HAS_REAL_MEASURE_DIFF_SUBSET; GSYM HAS_REAL_MEASURE_MEASURE]);;
8857
8858 let HAS_REAL_MEASURE_UNION_REAL_NEGLIGIBLE = prove
8859  (`!s t m.
8860         s has_real_measure m /\ real_negligible t
8861         ==> (s UNION t) has_real_measure m`,
8862   REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; real_negligible; IMAGE_UNION] THEN
8863   REWRITE_TAC[HAS_MEASURE_UNION_NEGLIGIBLE]);;
8864
8865 let HAS_REAL_MEASURE_DIFF_REAL_NEGLIGIBLE = prove
8866  (`!s t m.
8867         s has_real_measure m /\ real_negligible t
8868         ==> (s DIFF t) has_real_measure m`,
8869   REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; real_negligible] THEN
8870   SIMP_TAC[IMAGE_DIFF_INJ; LIFT_EQ] THEN
8871   REWRITE_TAC[HAS_MEASURE_DIFF_NEGLIGIBLE]);;
8872
8873 let HAS_REAL_MEASURE_UNION_REAL_NEGLIGIBLE_EQ = prove
8874  (`!s t m.
8875      real_negligible t
8876      ==> ((s UNION t) has_real_measure m <=> s has_real_measure m)`,
8877   REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; real_negligible; IMAGE_UNION] THEN
8878   REWRITE_TAC[HAS_MEASURE_UNION_NEGLIGIBLE_EQ]);;
8879
8880 let HAS_REAL_MEASURE_DIFF_REAL_NEGLIGIBLE_EQ = prove
8881  (`!s t m.
8882      real_negligible t
8883      ==> ((s DIFF t) has_real_measure m <=> s has_real_measure m)`,
8884   REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; real_negligible] THEN
8885   SIMP_TAC[IMAGE_DIFF_INJ; LIFT_EQ] THEN
8886   REWRITE_TAC[HAS_MEASURE_DIFF_NEGLIGIBLE_EQ]);;
8887
8888 let HAS_REAL_MEASURE_ALMOST = prove
8889  (`!s s' t m. s has_real_measure m /\ real_negligible t /\
8890               s UNION t = s' UNION t
8891               ==> s' has_real_measure m`,
8892   REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; real_negligible; IMAGE_UNION] THEN
8893   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_MEASURE_ALMOST THEN
8894   MAP_EVERY EXISTS_TAC [`IMAGE lift s`; `IMAGE lift t`] THEN ASM SET_TAC[]);;
8895
8896 let HAS_REAL_MEASURE_ALMOST_EQ = prove
8897  (`!s s' t. real_negligible t /\ s UNION t = s' UNION t
8898             ==> (s has_real_measure m <=> s' has_real_measure m)`,
8899   MESON_TAC[HAS_REAL_MEASURE_ALMOST]);;
8900
8901 let REAL_MEASURABLE_ALMOST = prove
8902  (`!s s' t. real_measurable s /\ real_negligible t /\ s UNION t = s' UNION t
8903             ==> real_measurable s'`,
8904   REWRITE_TAC[real_measurable] THEN MESON_TAC[HAS_REAL_MEASURE_ALMOST]);;
8905
8906 let HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNION = prove
8907  (`!s1 s2 m1 m2.
8908         s1 has_real_measure m1 /\ s2 has_real_measure m2 /\
8909         real_negligible(s1 INTER s2)
8910         ==> (s1 UNION s2) has_real_measure (m1 + m2)`,
8911   REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE; real_negligible; IMAGE_UNION] THEN
8912   SIMP_TAC[IMAGE_INTER_INJ; LIFT_EQ] THEN
8913   REWRITE_TAC[HAS_MEASURE_NEGLIGIBLE_UNION]);;
8914
8915 let REAL_MEASURE_REAL_NEGLIGIBLE_UNION = prove
8916  (`!s t. real_measurable s /\ real_measurable t /\ real_negligible(s INTER t)
8917          ==> real_measure(s UNION t) = real_measure s + real_measure t`,
8918   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN
8919   ASM_SIMP_TAC[HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNION;
8920                GSYM HAS_REAL_MEASURE_MEASURE]);;
8921
8922 let HAS_REAL_MEASURE_REAL_NEGLIGIBLE_SYMDIFF = prove
8923  (`!s t m.
8924         s has_real_measure m /\
8925         real_negligible((s DIFF t) UNION (t DIFF s))
8926         ==> t has_real_measure m`,
8927   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_REAL_MEASURE_ALMOST THEN
8928   MAP_EVERY EXISTS_TAC
8929     [`s:real->bool`; `(s DIFF t) UNION (t DIFF s):real->bool`] THEN
8930   ASM_REWRITE_TAC[] THEN SET_TAC[]);;
8931
8932 let REAL_MEASURABLE_REAL_NEGLIGIBLE_SYMDIFF = prove
8933  (`!s t. real_measurable s /\ real_negligible((s DIFF t) UNION (t DIFF s))
8934          ==> real_measurable t`,
8935   REWRITE_TAC[real_measurable] THEN
8936   MESON_TAC[HAS_REAL_MEASURE_REAL_NEGLIGIBLE_SYMDIFF]);;
8937
8938 let REAL_MEASURE_REAL_NEGLIGIBLE_SYMDIFF = prove
8939  (`!s t. (real_measurable s \/ real_measurable t) /\
8940          real_negligible((s DIFF t) UNION (t DIFF s))
8941          ==> real_measure s = real_measure t`,
8942   MESON_TAC[HAS_REAL_MEASURE_REAL_NEGLIGIBLE_SYMDIFF; REAL_MEASURE_UNIQUE;
8943             UNION_COMM; HAS_REAL_MEASURE_MEASURE]);;
8944
8945 let HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS = prove
8946  (`!m f. FINITE f /\
8947          (!s. s IN f ==> s has_real_measure (m s)) /\
8948          (!s t. s IN f /\ t IN f /\ ~(s = t) ==> real_negligible(s INTER t))
8949          ==> (UNIONS f) has_real_measure (sum f m)`,
8950   GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN
8951   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
8952   SIMP_TAC[SUM_CLAUSES; UNIONS_0; UNIONS_INSERT; HAS_REAL_MEASURE_EMPTY] THEN
8953   REWRITE_TAC[IN_INSERT] THEN
8954   MAP_EVERY X_GEN_TAC [`s:real->bool`; `f:(real->bool)->bool`] THEN
8955   STRIP_TAC THEN STRIP_TAC THEN
8956   MATCH_MP_TAC HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNION THEN
8957   REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN
8958   REWRITE_TAC[INTER_UNIONS] THEN MATCH_MP_TAC REAL_NEGLIGIBLE_UNIONS THEN
8959   ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
8960   ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN REPEAT STRIP_TAC THEN
8961   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]);;
8962
8963 let REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS = prove
8964  (`!m f. FINITE f /\
8965          (!s. s IN f ==> s has_real_measure (m s)) /\
8966          (!s t. s IN f /\ t IN f /\ ~(s = t) ==> real_negligible(s INTER t))
8967          ==> real_measure(UNIONS f) = sum f m`,
8968   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN
8969   ASM_SIMP_TAC[HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS]);;
8970
8971 let HAS_REAL_MEASURE_DISJOINT_UNIONS = prove
8972  (`!m f. FINITE f /\
8973          (!s. s IN f ==> s has_real_measure (m s)) /\
8974          (!s t. s IN f /\ t IN f /\ ~(s = t) ==> DISJOINT s t)
8975          ==> (UNIONS f) has_real_measure (sum f m)`,
8976   REWRITE_TAC[DISJOINT] THEN REPEAT STRIP_TAC THEN
8977   MATCH_MP_TAC HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS THEN
8978   ASM_SIMP_TAC[REAL_NEGLIGIBLE_EMPTY]);;
8979
8980 let REAL_MEASURE_DISJOINT_UNIONS = prove
8981  (`!m f:(real->bool)->bool.
8982         FINITE f /\
8983         (!s. s IN f ==> s has_real_measure (m s)) /\
8984         (!s t. s IN f /\ t IN f /\ ~(s = t) ==> DISJOINT s t)
8985         ==> real_measure(UNIONS f) = sum f m`,
8986   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN
8987   ASM_SIMP_TAC[HAS_REAL_MEASURE_DISJOINT_UNIONS]);;
8988
8989 let HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE = prove
8990  (`!f:A->(real->bool) s.
8991         FINITE s /\
8992         (!x. x IN s ==> real_measurable(f x)) /\
8993         (!x y. x IN s /\ y IN s /\ ~(x = y)
8994                ==> real_negligible((f x) INTER (f y)))
8995         ==> (UNIONS (IMAGE f s)) has_real_measure
8996             (sum s (\x. real_measure(f x)))`,
8997   REPEAT STRIP_TAC THEN
8998   SUBGOAL_THEN
8999    `sum s (\x. real_measure(f x)) =
9000     sum (IMAGE (f:A->real->bool) s) real_measure`
9001   SUBST1_TAC THENL
9002    [CONV_TAC SYM_CONV THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN
9003     MATCH_MP_TAC SUM_IMAGE_NONZERO THEN ASM_REWRITE_TAC[] THEN
9004     MAP_EVERY X_GEN_TAC [`x:A`; `y:A`] THEN STRIP_TAC THEN
9005     FIRST_X_ASSUM(MP_TAC o SPECL [`x:A`; `y:A`]) THEN
9006     ASM_SIMP_TAC[INTER_ACI; REAL_MEASURABLE_REAL_MEASURE_EQ_0];
9007     MATCH_MP_TAC HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS THEN
9008     ASM_SIMP_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_IMAGE] THEN
9009     ASM_MESON_TAC[FINITE_IMAGE; HAS_REAL_MEASURE_MEASURE]]);;
9010
9011 let REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE = prove
9012  (`!f:A->real->bool s.
9013         FINITE s /\
9014         (!x. x IN s ==> real_measurable(f x)) /\
9015         (!x y. x IN s /\ y IN s /\ ~(x = y)
9016                ==> real_negligible((f x) INTER (f y)))
9017         ==> real_measure(UNIONS (IMAGE f s)) = sum s (\x. real_measure(f x))`,
9018   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN
9019   ASM_SIMP_TAC[HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE]);;
9020
9021 let HAS_REAL_MEASURE_DISJOINT_UNIONS_IMAGE = prove
9022  (`!f:A->real->bool s.
9023         FINITE s /\
9024         (!x. x IN s ==> real_measurable(f x)) /\
9025         (!x y. x IN s /\ y IN s /\ ~(x = y) ==> DISJOINT (f x) (f y))
9026         ==> (UNIONS (IMAGE f s)) has_real_measure
9027             (sum s (\x. real_measure(f x)))`,
9028   REWRITE_TAC[DISJOINT] THEN REPEAT STRIP_TAC THEN
9029   MATCH_MP_TAC HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE THEN
9030   ASM_SIMP_TAC[REAL_NEGLIGIBLE_EMPTY]);;
9031
9032 let REAL_MEASURE_DISJOINT_UNIONS_IMAGE = prove
9033  (`!f:A->real->bool s.
9034         FINITE s /\
9035         (!x. x IN s ==> real_measurable(f x)) /\
9036         (!x y. x IN s /\ y IN s /\ ~(x = y) ==> DISJOINT (f x) (f y))
9037         ==> real_measure(UNIONS (IMAGE f s)) = sum s (\x. real_measure(f x))`,
9038   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN
9039   ASM_SIMP_TAC[HAS_REAL_MEASURE_DISJOINT_UNIONS_IMAGE]);;
9040
9041 let HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE_STRONG = prove
9042  (`!f:A->real->bool s.
9043         FINITE {x | x IN s /\ ~(f x = {})} /\
9044         (!x. x IN s ==> real_measurable(f x)) /\
9045         (!x y. x IN s /\ y IN s /\ ~(x = y)
9046                ==> real_negligible((f x) INTER (f y)))
9047         ==> (UNIONS (IMAGE f s)) has_real_measure
9048             (sum s (\x. real_measure(f x)))`,
9049   REPEAT STRIP_TAC THEN
9050   MP_TAC(ISPECL [`f:A->real->bool`;
9051                  `{x | x IN s /\ ~((f:A->real->bool) x = {})}`]
9052         HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE) THEN
9053   ASM_SIMP_TAC[IN_ELIM_THM; FINITE_RESTRICT] THEN
9054   MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THENL
9055    [GEN_REWRITE_TAC I [EXTENSION] THEN
9056     REWRITE_TAC[IN_UNIONS; IN_IMAGE; IN_ELIM_THM] THEN
9057     MESON_TAC[NOT_IN_EMPTY];
9058     CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_SUPERSET THEN
9059     SIMP_TAC[SUBSET; IN_ELIM_THM; TAUT `a /\ ~(a /\ b) <=> a /\ ~b`] THEN
9060     REWRITE_TAC[REAL_MEASURE_EMPTY]]);;
9061
9062 let REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE_STRONG = prove
9063  (`!f:A->real->bool s.
9064         FINITE {x | x IN s /\ ~(f x = {})} /\
9065         (!x. x IN s ==> real_measurable(f x)) /\
9066         (!x y. x IN s /\ y IN s /\ ~(x = y)
9067                ==> real_negligible((f x) INTER (f y)))
9068         ==> real_measure(UNIONS (IMAGE f s)) = sum s (\x. real_measure(f x))`,
9069   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN
9070   ASM_SIMP_TAC[HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE_STRONG]);;
9071
9072 let HAS_REAL_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG = prove
9073  (`!f:A->real->bool s.
9074         FINITE {x | x IN s /\ ~(f x = {})} /\
9075         (!x. x IN s ==> real_measurable(f x)) /\
9076         (!x y. x IN s /\ y IN s /\ ~(x = y) ==> DISJOINT (f x) (f y))
9077         ==> (UNIONS (IMAGE f s)) has_real_measure
9078             (sum s (\x. real_measure(f x)))`,
9079   REWRITE_TAC[DISJOINT] THEN REPEAT STRIP_TAC THEN
9080   MATCH_MP_TAC HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE_STRONG THEN
9081   ASM_SIMP_TAC[REAL_NEGLIGIBLE_EMPTY]);;
9082
9083 let REAL_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG = prove
9084  (`!f:A->real->bool s.
9085         FINITE {x | x IN s /\ ~(f x = {})} /\
9086         (!x. x IN s ==> real_measurable(f x)) /\
9087         (!x y. x IN s /\ y IN s /\ ~(x = y) ==> DISJOINT (f x) (f y))
9088         ==> real_measure(UNIONS (IMAGE f s)) = sum s (\x. real_measure(f x))`,
9089   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN
9090   ASM_SIMP_TAC[HAS_REAL_MEASURE_DISJOINT_UNIONS_IMAGE_STRONG]);;
9091
9092 let REAL_MEASURE_UNION = prove
9093  (`!s t. real_measurable s /\ real_measurable t
9094          ==> real_measure(s UNION t) =
9095              real_measure(s) + real_measure(t) - real_measure(s INTER t)`,
9096   REPEAT STRIP_TAC THEN
9097   ONCE_REWRITE_TAC[SET_RULE
9098    `s UNION t = (s INTER t) UNION (s DIFF t) UNION (t DIFF s)`] THEN
9099   ONCE_REWRITE_TAC[REAL_ARITH `a + b - c:real = c + (a - c) + (b - c)`] THEN
9100   MP_TAC(ISPECL [`s DIFF t:real->bool`; `t DIFF s:real->bool`]
9101         REAL_MEASURE_DISJOINT_UNION) THEN
9102   ASM_SIMP_TAC[REAL_MEASURABLE_DIFF] THEN
9103   ANTS_TAC THENL [SET_TAC[]; ALL_TAC] THEN
9104   MP_TAC(ISPECL [`s INTER t:real->bool`;
9105                  `(s DIFF t) UNION (t DIFF s):real->bool`]
9106                 REAL_MEASURE_DISJOINT_UNION) THEN
9107   ASM_SIMP_TAC[REAL_MEASURABLE_DIFF;
9108                REAL_MEASURABLE_UNION; REAL_MEASURABLE_INTER] THEN
9109   ANTS_TAC THENL [SET_TAC[]; ALL_TAC] THEN
9110   REPEAT(DISCH_THEN SUBST1_TAC) THEN AP_TERM_TAC THEN BINOP_TAC THEN
9111   REWRITE_TAC[REAL_EQ_SUB_LADD] THEN MATCH_MP_TAC EQ_TRANS THENL
9112    [EXISTS_TAC `real_measure((s DIFF t) UNION (s INTER t):real->bool)`;
9113     EXISTS_TAC `real_measure((t DIFF s) UNION (s INTER t):real->bool)`] THEN
9114   (CONJ_TAC THENL
9115     [CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_MEASURE_DISJOINT_UNION THEN
9116      ASM_SIMP_TAC[REAL_MEASURABLE_DIFF; REAL_MEASURABLE_INTER];
9117      AP_TERM_TAC] THEN
9118    SET_TAC[]));;
9119
9120 let REAL_MEASURE_UNION_LE = prove
9121  (`!s t. real_measurable s /\ real_measurable t
9122          ==> real_measure(s UNION t) <= real_measure s + real_measure t`,
9123   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[REAL_MEASURE_UNION] THEN
9124   REWRITE_TAC[REAL_ARITH `a + b - c <= a + b <=> &0 <= c`] THEN
9125   MATCH_MP_TAC REAL_MEASURE_POS_LE THEN ASM_SIMP_TAC[REAL_MEASURABLE_INTER]);;
9126
9127 let REAL_MEASURE_UNIONS_LE = prove
9128  (`!f. FINITE f /\ (!s. s IN f ==> real_measurable s)
9129        ==> real_measure(UNIONS f) <= sum f (\s. real_measure s)`,
9130   REWRITE_TAC[IMP_CONJ] THEN
9131   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
9132   SIMP_TAC[UNIONS_0; UNIONS_INSERT; SUM_CLAUSES] THEN
9133   REWRITE_TAC[REAL_MEASURE_EMPTY; REAL_LE_REFL] THEN
9134   MAP_EVERY X_GEN_TAC [`s:real->bool`; `f:(real->bool)->bool`] THEN
9135   REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THEN
9136   MATCH_MP_TAC REAL_LE_TRANS THEN
9137   EXISTS_TAC `real_measure(s) + real_measure(UNIONS f)` THEN
9138   ASM_SIMP_TAC[REAL_MEASURE_UNION_LE; REAL_MEASURABLE_UNIONS] THEN
9139   REWRITE_TAC[REAL_LE_LADD] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
9140   ASM_SIMP_TAC[]);;
9141
9142 let REAL_MEASURE_UNIONS_LE_IMAGE = prove
9143  (`!f:A->bool s:A->(real->bool).
9144         FINITE f /\ (!a. a IN f ==> real_measurable(s a))
9145         ==> real_measure(UNIONS (IMAGE s f)) <= sum f (\a. real_measure(s a))`,
9146   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
9147   EXISTS_TAC `sum (IMAGE s (f:A->bool)) (\k:real->bool. real_measure k)` THEN
9148   ASM_SIMP_TAC[REAL_MEASURE_UNIONS_LE; FORALL_IN_IMAGE; FINITE_IMAGE] THEN
9149   GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM o_DEF] THEN
9150   REWRITE_TAC[ETA_AX] THEN MATCH_MP_TAC SUM_IMAGE_LE THEN
9151   ASM_SIMP_TAC[REAL_MEASURE_POS_LE]);;
9152
9153 let REAL_NEGLIGIBLE_OUTER = prove
9154  (`!s. real_negligible s <=>
9155        !e. &0 < e
9156            ==> ?t. s SUBSET t /\ real_measurable t /\ real_measure t < e`,
9157   REWRITE_TAC[real_negligible; REAL_MEASURABLE_MEASURABLE;
9158               REAL_MEASURE_MEASURE; SUBSET_LIFT_IMAGE;
9159               NEGLIGIBLE_OUTER; EXISTS_LIFT_IMAGE]);;
9160
9161 let REAL_NEGLIGIBLE_OUTER_LE = prove
9162  (`!s. real_negligible s <=>
9163        !e. &0 < e
9164            ==> ?t. s SUBSET t /\ real_measurable t /\ real_measure t <= e`,
9165   REWRITE_TAC[real_negligible; REAL_MEASURABLE_MEASURABLE;
9166               REAL_MEASURE_MEASURE; SUBSET_LIFT_IMAGE;
9167               NEGLIGIBLE_OUTER_LE; EXISTS_LIFT_IMAGE]);;
9168
9169 let REAL_MEASURABLE_INNER_OUTER = prove
9170  (`!s. real_measurable s <=>
9171                 !e. &0 < e
9172                     ==> ?t u. t SUBSET s /\ s SUBSET u /\
9173                               real_measurable t /\ real_measurable u /\
9174                               abs(real_measure t - real_measure u) < e`,
9175   GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL
9176    [GEN_TAC THEN DISCH_TAC THEN REPEAT(EXISTS_TAC `s:real->bool`) THEN
9177     ASM_REWRITE_TAC[SUBSET_REFL; REAL_SUB_REFL; REAL_ABS_NUM];
9178     ALL_TAC] THEN
9179   REWRITE_TAC[REAL_MEASURABLE_REAL_INTEGRABLE] THEN
9180   MATCH_MP_TAC REAL_INTEGRABLE_STRADDLE THEN
9181   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
9182   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN
9183   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
9184   MAP_EVERY X_GEN_TAC [`t:real->bool`; `u:real->bool`] THEN STRIP_TAC THEN
9185   MAP_EVERY EXISTS_TAC
9186    [`(\x. if x IN t then &1 else &0):real->real`;
9187     `(\x. if x IN u then &1 else &0):real->real`;
9188     `real_measure(t:real->bool)`;
9189     `real_measure(u:real->bool)`] THEN
9190   ASM_REWRITE_TAC[GSYM HAS_REAL_MEASURE; GSYM HAS_REAL_MEASURE_MEASURE] THEN
9191   ASM_REWRITE_TAC[GSYM LIFT_SUB; NORM_LIFT] THEN REPEAT STRIP_TAC THEN
9192   REPEAT(COND_CASES_TAC THEN
9193          ASM_REWRITE_TAC[DROP_VEC; REAL_POS; REAL_LE_REFL]) THEN
9194   ASM SET_TAC[]);;
9195
9196 let HAS_REAL_MEASURE_INNER_OUTER = prove
9197  (`!s m. s has_real_measure m <=>
9198                 (!e. &0 < e ==> ?t. t SUBSET s /\ real_measurable t /\
9199                                     m - e < real_measure t) /\
9200                 (!e. &0 < e ==> ?u. s SUBSET u /\ real_measurable u /\
9201                                     real_measure u < m + e)`,
9202   REPEAT GEN_TAC THEN
9203   GEN_REWRITE_TAC LAND_CONV
9204       [HAS_REAL_MEASURE_REAL_MEASURABLE_REAL_MEASURE] THEN EQ_TAC THENL
9205    [REPEAT STRIP_TAC THEN EXISTS_TAC `s:real->bool` THEN
9206     ASM_REWRITE_TAC[SUBSET_REFL] THEN ASM_REAL_ARITH_TAC;
9207     ALL_TAC] THEN
9208   DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "t") (LABEL_TAC "u")) THEN
9209   MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
9210    [GEN_REWRITE_TAC I [REAL_MEASURABLE_INNER_OUTER] THEN
9211     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
9212     REMOVE_THEN "u" (MP_TAC o SPEC `e / &2`) THEN
9213     REMOVE_THEN "t" (MP_TAC o SPEC `e / &2`) THEN
9214     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
9215     REWRITE_TAC[IMP_IMP; LEFT_AND_EXISTS_THM] THEN
9216     REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN
9217     REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
9218     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
9219      `&0 < e /\ t <= u /\ m - e / &2 < t /\ u < m + e / &2
9220                           ==> abs(t - u) < e`) THEN
9221     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_MEASURE_SUBSET THEN
9222     ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
9223     DISCH_TAC THEN MATCH_MP_TAC(REAL_ARITH
9224      `~(&0 < x - y) /\ ~(&0 < y - x) ==> x = y`) THEN
9225     CONJ_TAC THEN DISCH_TAC THENL
9226      [REMOVE_THEN "u" (MP_TAC o SPEC `real_measure(s:real->bool) - m`) THEN
9227       ASM_REWRITE_TAC[REAL_SUB_ADD2; GSYM REAL_NOT_LE];
9228       REMOVE_THEN "t" (MP_TAC o SPEC `m - real_measure(s:real->bool)`) THEN
9229       ASM_REWRITE_TAC[REAL_SUB_SUB2; GSYM REAL_NOT_LE]] THEN
9230     ASM_MESON_TAC[REAL_MEASURE_SUBSET]]);;
9231
9232 let HAS_REAL_MEASURE_INNER_OUTER_LE = prove
9233  (`!s:real->bool m.
9234         s has_real_measure m <=>
9235                 (!e. &0 < e ==> ?t. t SUBSET s /\ real_measurable t /\
9236                                     m - e <= real_measure t) /\
9237                 (!e. &0 < e ==> ?u. s SUBSET u /\ real_measurable u /\
9238                                     real_measure u <= m + e)`,
9239   REWRITE_TAC[HAS_REAL_MEASURE_INNER_OUTER] THEN
9240   MESON_TAC[REAL_ARITH `&0 < e /\ m - e / &2 <= t ==> m - e < t`;
9241             REAL_ARITH `&0 < e /\ u <= m + e / &2 ==> u < m + e`;
9242             REAL_ARITH `&0 < e <=> &0 < e / &2`; REAL_LT_IMP_LE]);;
9243
9244 let HAS_REAL_MEASURE_AFFINITY = prove
9245  (`!s m c y. s has_real_measure y
9246              ==> (IMAGE (\x. m * x + c) s) has_real_measure abs(m) * y`,
9247   REPEAT GEN_TAC THEN REWRITE_TAC[HAS_REAL_MEASURE_HAS_MEASURE] THEN
9248   DISCH_THEN(MP_TAC o SPECL [`m:real`; `lift c`] o MATCH_MP
9249     HAS_MEASURE_AFFINITY) THEN
9250   REWRITE_TAC[DIMINDEX_1; REAL_POW_1; GSYM IMAGE_o] THEN
9251   MATCH_MP_TAC EQ_IMP THEN REPEAT(AP_THM_TAC THEN AP_TERM_TAC) THEN
9252   SIMP_TAC[FUN_EQ_THM; FORALL_DROP; o_THM; LIFT_DROP; LIFT_ADD; LIFT_CMUL]);;
9253
9254 let HAS_REAL_MEASURE_SCALING = prove
9255  (`!s m y. s has_real_measure y
9256            ==> (IMAGE (\x. m * x) s) has_real_measure abs(m) * y`,
9257   ONCE_REWRITE_TAC[REAL_ARITH `m * x = m * x + &0`] THEN
9258   REWRITE_TAC[REAL_ARITH `abs m * x + &0 = abs m * x`] THEN
9259   REWRITE_TAC[HAS_REAL_MEASURE_AFFINITY]);;
9260
9261 let HAS_REAL_MEASURE_TRANSLATION = prove
9262  (`!s m a. s has_real_measure m ==> (IMAGE (\x. a + x) s) has_real_measure m`,
9263   REPEAT GEN_TAC THEN
9264   ONCE_REWRITE_TAC[REAL_ARITH `a + x = &1 * x + a`] THEN
9265   GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [REAL_ARITH `m = abs(&1) * m`] THEN
9266   REWRITE_TAC[HAS_REAL_MEASURE_AFFINITY]);;
9267
9268 let REAL_NEGLIGIBLE_TRANSLATION = prove
9269  (`!s a. real_negligible s ==> real_negligible (IMAGE (\x. a + x) s)`,
9270   SIMP_TAC[GSYM HAS_REAL_MEASURE_0; HAS_REAL_MEASURE_TRANSLATION]);;
9271
9272 let HAS_REAL_MEASURE_TRANSLATION_EQ = prove
9273  (`!s m. (IMAGE (\x. a + x) s) has_real_measure m <=> s has_real_measure m`,
9274   REPEAT GEN_TAC THEN EQ_TAC THEN
9275   REWRITE_TAC[HAS_REAL_MEASURE_TRANSLATION] THEN
9276   DISCH_THEN(MP_TAC o SPEC `--a:real` o
9277     MATCH_MP HAS_REAL_MEASURE_TRANSLATION) THEN
9278   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
9279   REWRITE_TAC[GSYM IMAGE_o; o_DEF; REAL_ARITH `--a + a + b:real = b`] THEN
9280   SET_TAC[]);;
9281
9282 let REAL_NEGLIGIBLE_TRANSLATION_REV = prove
9283  (`!s a. real_negligible (IMAGE (\x. a + x) s) ==> real_negligible s`,
9284   SIMP_TAC[GSYM HAS_REAL_MEASURE_0; HAS_REAL_MEASURE_TRANSLATION_EQ]);;
9285
9286 let REAL_NEGLIGIBLE_TRANSLATION_EQ = prove
9287  (`!s a. real_negligible (IMAGE (\x. a + x) s) <=> real_negligible s`,
9288   SIMP_TAC[GSYM HAS_REAL_MEASURE_0; HAS_REAL_MEASURE_TRANSLATION_EQ]);;
9289
9290 let REAL_MEASURABLE_TRANSLATION = prove
9291  (`!s. real_measurable (IMAGE (\x. a + x) s) <=> real_measurable s`,
9292   REWRITE_TAC[real_measurable; HAS_REAL_MEASURE_TRANSLATION_EQ]);;
9293
9294 let REAL_MEASURE_TRANSLATION = prove
9295  (`!s. real_measurable s
9296        ==> real_measure(IMAGE (\x. a + x) s) = real_measure s`,
9297   REWRITE_TAC[HAS_REAL_MEASURE_MEASURE] THEN REPEAT STRIP_TAC THEN
9298   MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN
9299   ASM_REWRITE_TAC[HAS_REAL_MEASURE_TRANSLATION_EQ]);;
9300
9301 let HAS_REAL_MEASURE_SCALING_EQ = prove
9302  (`!s m c. ~(c = &0)
9303            ==> ((IMAGE (\x. c * x) s) has_real_measure (abs(c) * m) <=>
9304                 s has_real_measure m)`,
9305   REPEAT STRIP_TAC THEN EQ_TAC THEN REWRITE_TAC[HAS_REAL_MEASURE_SCALING] THEN
9306   DISCH_THEN(MP_TAC o SPEC `inv(c:real)` o
9307     MATCH_MP HAS_REAL_MEASURE_SCALING) THEN
9308   REWRITE_TAC[GSYM IMAGE_o; o_DEF; GSYM REAL_ABS_MUL] THEN
9309   REWRITE_TAC[GSYM REAL_POW_MUL; REAL_MUL_ASSOC] THEN
9310   ASM_SIMP_TAC[GSYM REAL_ABS_MUL; REAL_MUL_LINV] THEN
9311   REWRITE_TAC[REAL_POW_ONE; REAL_ABS_NUM; REAL_MUL_LID] THEN
9312   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN SET_TAC[]);;
9313
9314 let REAL_MEASURABLE_SCALING = prove
9315  (`!s c. real_measurable s ==> real_measurable (IMAGE (\x. c * x) s)`,
9316   REWRITE_TAC[real_measurable] THEN MESON_TAC[HAS_REAL_MEASURE_SCALING]);;
9317
9318 let REAL_MEASURABLE_SCALING_EQ = prove
9319  (`!s c. ~(c = &0)
9320          ==> (real_measurable (IMAGE (\x. c * x) s) <=> real_measurable s)`,
9321   REPEAT STRIP_TAC THEN EQ_TAC THEN REWRITE_TAC[REAL_MEASURABLE_SCALING] THEN
9322   DISCH_THEN(MP_TAC o SPEC `inv c:real` o MATCH_MP REAL_MEASURABLE_SCALING) THEN
9323   REWRITE_TAC[GSYM IMAGE_o; o_DEF; GSYM REAL_ABS_MUL] THEN
9324   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
9325   ASM_SIMP_TAC[REAL_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_LID] THEN
9326   SET_TAC[]);;
9327
9328 let REAL_MEASURE_SCALING = prove
9329  (`!s. real_measurable s
9330        ==> real_measure(IMAGE (\x. c * x) s) = abs(c) * real_measure s`,
9331   REWRITE_TAC[HAS_REAL_MEASURE_MEASURE] THEN REPEAT STRIP_TAC THEN
9332   MATCH_MP_TAC REAL_MEASURE_UNIQUE THEN
9333   ASM_SIMP_TAC[HAS_REAL_MEASURE_SCALING]);;
9334
9335 let HAS_REAL_MEASURE_NESTED_UNIONS = prove
9336  (`!s B. (!n. real_measurable(s n)) /\
9337          (!n. real_measure(s n) <= B) /\
9338          (!n. s(n) SUBSET s(SUC n))
9339          ==> real_measurable(UNIONS { s(n) | n IN (:num) }) /\
9340              ((\n. real_measure(s n))
9341                    ---> real_measure(UNIONS { s(n) | n IN (:num) }))
9342              sequentially`,
9343   REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL; o_DEF] THEN
9344   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
9345   ASM_SIMP_TAC[REAL_MEASURE_MEASURE] THEN POP_ASSUM MP_TAC THEN
9346   REWRITE_TAC[REAL_MEASURABLE_MEASURABLE] THEN
9347   REPEAT(DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC)) THEN
9348   MP_TAC(ISPECL [`IMAGE lift o (s:num->real->bool)`; `B:real`]
9349         HAS_MEASURE_NESTED_UNIONS) THEN
9350   ASM_SIMP_TAC[o_THM; IMAGE_SUBSET] THEN
9351   REWRITE_TAC[SET_RULE `{IMAGE f (s n) | P n} = IMAGE (IMAGE f) {s n | P n}`;
9352               GSYM IMAGE_UNIONS] THEN
9353   SIMP_TAC[REAL_MEASURE_MEASURE; REAL_MEASURABLE_MEASURABLE]);;
9354
9355 let REAL_MEASURABLE_NESTED_UNIONS = prove
9356  (`!s B. (!n. real_measurable(s n)) /\
9357          (!n. real_measure(s n) <= B) /\
9358          (!n. s(n) SUBSET s(SUC n))
9359          ==> real_measurable(UNIONS { s(n) | n IN (:num) })`,
9360   REPEAT GEN_TAC THEN
9361   DISCH_THEN(MP_TAC o MATCH_MP HAS_REAL_MEASURE_NESTED_UNIONS) THEN
9362   SIMP_TAC[]);;
9363
9364 let HAS_REAL_MEASURE_COUNTABLE_REAL_NEGLIGIBLE_UNIONS = prove
9365  (`!s:num->real->bool B.
9366         (!n. real_measurable(s n)) /\
9367         (!m n. ~(m = n) ==> real_negligible(s m INTER s n)) /\
9368         (!n. sum (0..n) (\k. real_measure(s k)) <= B)
9369         ==> real_measurable(UNIONS { s(n) | n IN (:num) }) /\
9370             ((\n. real_measure(s n)) real_sums
9371              real_measure(UNIONS { s(n) | n IN (:num) })) (from 0)`,
9372   REPEAT GEN_TAC THEN STRIP_TAC THEN
9373   MP_TAC(ISPECL [`\n. UNIONS (IMAGE s (0..n)):real->bool`; `B:real`]
9374                HAS_REAL_MEASURE_NESTED_UNIONS) THEN
9375   REWRITE_TAC[real_sums; FROM_0; INTER_UNIV] THEN
9376   SUBGOAL_THEN
9377    `!n. (UNIONS (IMAGE s (0..n)):real->bool) has_real_measure
9378         (sum(0..n) (\k. real_measure(s k)))`
9379   MP_TAC THENL
9380    [GEN_TAC THEN MATCH_MP_TAC HAS_REAL_MEASURE_REAL_NEGLIGIBLE_UNIONS_IMAGE THEN
9381     ASM_SIMP_TAC[FINITE_NUMSEG];
9382     ALL_TAC] THEN
9383   DISCH_THEN(fun th -> ASSUME_TAC th THEN
9384     ASSUME_TAC(GEN `n:num` (MATCH_MP REAL_MEASURE_UNIQUE
9385      (SPEC `n:num` th)))) THEN
9386   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
9387    [CONJ_TAC THENL [ASM_MESON_TAC[real_measurable]; ALL_TAC] THEN
9388     GEN_TAC THEN MATCH_MP_TAC SUBSET_UNIONS THEN
9389     MATCH_MP_TAC IMAGE_SUBSET THEN
9390     REWRITE_TAC[SUBSET; IN_NUMSEG] THEN ARITH_TAC;
9391     ALL_TAC] THEN
9392   SIMP_TAC[LIFT_SUM; FINITE_NUMSEG; o_DEF] THEN
9393   SUBGOAL_THEN
9394    `UNIONS {UNIONS (IMAGE s (0..n)) | n IN (:num)}:real->bool =
9395     UNIONS (IMAGE s (:num))`
9396    (fun th -> REWRITE_TAC[th] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
9397               REWRITE_TAC[]) THEN
9398   GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `x:real` THEN
9399   REWRITE_TAC[IN_UNIONS] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
9400   REWRITE_TAC[EXISTS_IN_IMAGE; EXISTS_IN_UNIONS; IN_UNIV] THEN
9401   REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE] THEN
9402   REWRITE_TAC[IN_NUMSEG; LE_0] THEN MESON_TAC[LE_REFL]);;
9403
9404 let REAL_NEGLIGIBLE_COUNTABLE_UNIONS = prove
9405  (`!s:num->real->bool.
9406         (!n. real_negligible(s n))
9407         ==> real_negligible(UNIONS {s(n) | n IN (:num)})`,
9408   REPEAT STRIP_TAC THEN
9409   MP_TAC(ISPECL [`s:num->real->bool`; `&0`]
9410     HAS_REAL_MEASURE_COUNTABLE_REAL_NEGLIGIBLE_UNIONS) THEN
9411   ASM_SIMP_TAC[REAL_MEASURE_EQ_0; SUM_0; REAL_LE_REFL; LIFT_NUM] THEN
9412   ANTS_TAC THENL
9413    [ASM_MESON_TAC[HAS_REAL_MEASURE_0; real_measurable; INTER_SUBSET;
9414                   REAL_NEGLIGIBLE_SUBSET];
9415     ALL_TAC] THEN
9416   SIMP_TAC[GSYM REAL_MEASURABLE_REAL_MEASURE_EQ_0] THEN
9417   STRIP_TAC THEN
9418   MATCH_MP_TAC REAL_SERIES_UNIQUE THEN REWRITE_TAC[LIFT_NUM] THEN
9419   MAP_EVERY EXISTS_TAC [`(\k. &0):num->real`; `from 0`] THEN
9420   ASM_REWRITE_TAC[REAL_SERIES_0]);;
9421
9422 let REAL_MEASURABLE_COUNTABLE_UNIONS_STRONG = prove
9423  (`!s:num->real->bool B.
9424         (!n. real_measurable(s n)) /\
9425         (!n. real_measure(UNIONS {s k | k <= n}) <= B)
9426         ==> real_measurable(UNIONS { s(n) | n IN (:num) })`,
9427   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN STRIP_TAC THEN
9428   MP_TAC(ISPECL [`\n. UNIONS (IMAGE s (0..n)):real->bool`; `B:real`]
9429                REAL_MEASURABLE_NESTED_UNIONS) THEN
9430   SUBGOAL_THEN
9431    `UNIONS {UNIONS (IMAGE s (0..n)) | n IN (:num)}:real->bool =
9432     UNIONS (IMAGE s (:num))`
9433    (fun th -> REWRITE_TAC[th])
9434   THENL
9435    [GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `x:real` THEN
9436     REWRITE_TAC[IN_UNIONS] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
9437     REWRITE_TAC[EXISTS_IN_IMAGE; EXISTS_IN_UNIONS; IN_UNIV] THEN
9438     REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE] THEN
9439     REWRITE_TAC[IN_NUMSEG; LE_0] THEN MESON_TAC[LE_REFL];
9440     ALL_TAC] THEN
9441   DISCH_THEN MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
9442    [GEN_TAC THEN MATCH_MP_TAC REAL_MEASURABLE_UNIONS THEN
9443     ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE; FINITE_NUMSEG];
9444     ONCE_REWRITE_TAC[GSYM SIMPLE_IMAGE] THEN
9445     ASM_REWRITE_TAC[IN_NUMSEG; LE_0];
9446     GEN_TAC THEN MATCH_MP_TAC SUBSET_UNIONS THEN
9447     MATCH_MP_TAC IMAGE_SUBSET THEN
9448     REWRITE_TAC[SUBSET; IN_NUMSEG; LE_0] THEN ARITH_TAC]);;
9449
9450 let HAS_REAL_MEASURE_COUNTABLE_REAL_NEGLIGIBLE_UNIONS_BOUNDED = prove
9451  (`!s. (!n. real_measurable(s n)) /\
9452        (!m n. ~(m = n) ==> real_negligible(s m INTER s n)) /\
9453        real_bounded(UNIONS { s(n) | n IN (:num) })
9454        ==> real_measurable(UNIONS { s(n) | n IN (:num) }) /\
9455            ((\n. real_measure(s n)) real_sums
9456             real_measure(UNIONS { s(n) | n IN (:num) })) (from 0)`,
9457   REPEAT GEN_TAC THEN REWRITE_TAC[TENDSTO_REAL; o_DEF] THEN
9458   REWRITE_TAC[REAL_BOUNDED] THEN
9459   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
9460   ASM_SIMP_TAC[REAL_MEASURE_MEASURE] THEN POP_ASSUM MP_TAC THEN
9461   REWRITE_TAC[REAL_MEASURABLE_MEASURABLE; real_negligible] THEN
9462   REPEAT(DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC)) THEN
9463   MP_TAC(ISPEC `IMAGE lift o (s:num->real->bool)`
9464         HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS_BOUNDED) THEN
9465   ASM_SIMP_TAC[o_THM; IMAGE_SUBSET] THEN
9466   REWRITE_TAC[SET_RULE `{IMAGE f (s n) | P n} = IMAGE (IMAGE f) {s n | P n}`;
9467               GSYM IMAGE_UNIONS] THEN
9468   ASM_SIMP_TAC[GSYM IMAGE_INTER_INJ; LIFT_EQ] THEN
9469   SIMP_TAC[REAL_SUMS; o_DEF; REAL_MEASURE_MEASURE;
9470            REAL_MEASURABLE_MEASURABLE]);;
9471
9472 let REAL_MEASURABLE_COUNTABLE_UNIONS = prove
9473  (`!s B. (!n. real_measurable(s n)) /\
9474          (!n. sum (0..n) (\k. real_measure(s k)) <= B)
9475          ==> real_measurable(UNIONS { s(n) | n IN (:num) })`,
9476   REPEAT STRIP_TAC THEN
9477   MATCH_MP_TAC REAL_MEASURABLE_COUNTABLE_UNIONS_STRONG THEN
9478   EXISTS_TAC `B:real` THEN ASM_REWRITE_TAC[] THEN
9479   X_GEN_TAC `n:num` THEN MATCH_MP_TAC REAL_LE_TRANS THEN
9480   EXISTS_TAC `sum(0..n) (\k. real_measure(s k:real->bool))` THEN
9481   ASM_REWRITE_TAC[] THEN
9482   W(MP_TAC o PART_MATCH (rand o rand) REAL_MEASURE_UNIONS_LE_IMAGE o
9483        rand o snd) THEN
9484   ASM_REWRITE_TAC[FINITE_NUMSEG] THEN
9485   ONCE_REWRITE_TAC[GSYM SIMPLE_IMAGE] THEN
9486   REWRITE_TAC[IN_NUMSEG; LE_0]);;
9487
9488 let REAL_MEASURABLE_COUNTABLE_UNIONS_BOUNDED = prove
9489  (`!s. (!n. real_measurable(s n)) /\
9490        real_bounded(UNIONS { s(n) | n IN (:num) })
9491        ==> real_measurable(UNIONS { s(n) | n IN (:num) })`,
9492   REWRITE_TAC[REAL_MEASURABLE_MEASURABLE; REAL_BOUNDED] THEN
9493   SIMP_TAC[IMAGE_INTER_INJ; LIFT_EQ; IMAGE_UNIONS] THEN
9494   REWRITE_TAC[SET_RULE `IMAGE f {g x | x IN s} = {f(g x) | x IN s}`] THEN
9495   REWRITE_TAC[MEASURABLE_COUNTABLE_UNIONS_BOUNDED]);;
9496
9497 let REAL_MEASURABLE_COUNTABLE_INTERS = prove
9498  (`!s. (!n. real_measurable(s n))
9499        ==> real_measurable(INTERS { s(n) | n IN (:num) })`,
9500   REPEAT STRIP_TAC THEN
9501   SUBGOAL_THEN `INTERS { s(n):real->bool | n IN (:num) } =
9502                 s 0 DIFF (UNIONS {s 0 DIFF s n | n IN (:num)})`
9503   SUBST1_TAC THENL
9504    [GEN_REWRITE_TAC I [EXTENSION] THEN
9505     REWRITE_TAC[IN_INTERS; IN_DIFF; IN_UNIONS] THEN
9506     REWRITE_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; EXISTS_IN_IMAGE] THEN
9507     ASM SET_TAC[];
9508     ALL_TAC] THEN
9509   MATCH_MP_TAC REAL_MEASURABLE_DIFF THEN ASM_REWRITE_TAC[] THEN
9510   MATCH_MP_TAC REAL_MEASURABLE_COUNTABLE_UNIONS_STRONG THEN
9511   EXISTS_TAC `real_measure(s 0:real->bool)` THEN
9512   ASM_SIMP_TAC[REAL_MEASURABLE_DIFF; LE_0] THEN
9513   GEN_TAC THEN MATCH_MP_TAC REAL_MEASURE_SUBSET THEN
9514   ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
9515    [ALL_TAC;
9516     REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IN_ELIM_THM; IN_DIFF] THEN
9517     MESON_TAC[IN_DIFF]] THEN
9518   ONCE_REWRITE_TAC[GSYM IN_NUMSEG_0] THEN
9519   ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
9520   ASM_SIMP_TAC[FORALL_IN_IMAGE; FINITE_IMAGE; FINITE_NUMSEG;
9521                REAL_MEASURABLE_DIFF; REAL_MEASURABLE_UNIONS]);;
9522
9523 let REAL_NEGLIGIBLE_COUNTABLE = prove
9524  (`!s. COUNTABLE s ==> real_negligible s`,
9525   REPEAT STRIP_TAC THEN REWRITE_TAC[real_negligible] THEN
9526   MATCH_MP_TAC NEGLIGIBLE_COUNTABLE THEN ASM_SIMP_TAC[COUNTABLE_IMAGE]);;
9527
9528 let REAL_MEASURABLE_COMPACT = prove
9529  (`!s. real_compact s ==> real_measurable s`,
9530   REWRITE_TAC[REAL_MEASURABLE_MEASURABLE; real_compact; MEASURABLE_COMPACT]);;
9531
9532 let REAL_MEASURABLE_OPEN = prove
9533  (`!s. real_bounded s /\ real_open s ==> real_measurable s`,
9534   REWRITE_TAC[REAL_MEASURABLE_MEASURABLE; REAL_OPEN; REAL_BOUNDED;
9535               MEASURABLE_OPEN]);;
9536
9537 let HAS_REAL_INTEGRAL_NEGLIGIBLE_EQ = prove
9538  (`!f s. (!x. x IN s ==> &0 <= f(x))
9539          ==> ((f has_real_integral &0) s <=>
9540               real_negligible {x | x IN s /\ ~(f x = &0)})`,
9541   REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
9542    [ALL_TAC;
9543     MATCH_MP_TAC HAS_REAL_INTEGRAL_NEGLIGIBLE THEN
9544     EXISTS_TAC `{x | x IN s /\ ~((f:real->real) x = &0)}` THEN
9545     ASM_REWRITE_TAC[IN_DIFF; IN_ELIM_THM] THEN MESON_TAC[]] THEN
9546   MATCH_MP_TAC REAL_NEGLIGIBLE_SUBSET THEN EXISTS_TAC
9547    `UNIONS {{x:real | x IN s /\ abs(f x) >= &1 / (&n + &1)} |
9548             n IN (:num)}` THEN
9549   CONJ_TAC THENL
9550    [MATCH_MP_TAC REAL_NEGLIGIBLE_COUNTABLE_UNIONS THEN
9551     X_GEN_TAC `n:num` THEN REWRITE_TAC[GSYM HAS_REAL_MEASURE_0] THEN
9552     REWRITE_TAC[HAS_REAL_MEASURE] THEN
9553     MATCH_MP_TAC HAS_REAL_INTEGRAL_STRADDLE_NULL THEN
9554     EXISTS_TAC `\x:real. if x IN s then (&n + &1) * f(x) else &0` THEN
9555     CONJ_TAC THENL
9556      [REWRITE_TAC[IN_UNIV; IN_ELIM_THM; real_ge] THEN
9557       X_GEN_TAC `x:real` THEN COND_CASES_TAC THEN
9558       ASM_SIMP_TAC[REAL_POS] THENL
9559        [ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
9560         ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
9561         MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ a <= abs x ==> a <= x`) THEN
9562         ASM_SIMP_TAC[];
9563         COND_CASES_TAC THEN REWRITE_TAC[REAL_POS] THEN
9564         ASM_SIMP_TAC[REAL_POS; REAL_LE_MUL; REAL_LE_ADD]];
9565       REWRITE_TAC[HAS_REAL_INTEGRAL_RESTRICT_UNIV] THEN
9566       SUBST1_TAC(REAL_ARITH `&0 = (&n + &1) * &0`) THEN
9567       MATCH_MP_TAC HAS_REAL_INTEGRAL_LMUL THEN ASM_REWRITE_TAC[]];
9568     REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `x:real` THEN
9569     REWRITE_TAC[REAL_ABS_NZ] THEN ONCE_REWRITE_TAC[REAL_ARCH_INV] THEN
9570     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `n:num`
9571       STRIP_ASSUME_TAC)) THEN
9572     REWRITE_TAC[IN_UNIONS; EXISTS_IN_GSPEC] THEN
9573     EXISTS_TAC `n - 1` THEN ASM_SIMP_TAC[IN_UNIV; IN_ELIM_THM; real_ge] THEN
9574     ASM_SIMP_TAC[REAL_OF_NUM_ADD; SUB_ADD; LE_1] THEN
9575     ASM_SIMP_TAC[real_div; REAL_MUL_LID; REAL_LT_IMP_LE]]);;
9576
9577 (* ------------------------------------------------------------------------- *)
9578 (* Integration by parts.                                                     *)
9579 (* ------------------------------------------------------------------------- *)
9580
9581 let REAL_INTEGRATION_BY_PARTS = prove
9582  (`!f g f' g' a b c.
9583         a <= b /\ COUNTABLE c /\
9584         (\x. f x * g x) real_continuous_on real_interval[a,b] /\
9585         (!x. x IN real_interval(a,b) DIFF c
9586              ==> (f has_real_derivative f'(x)) (atreal x) /\
9587                  (g has_real_derivative g'(x)) (atreal x)) /\
9588         ((\x. f(x) * g'(x)) has_real_integral ((f b * g b - f a * g a) - y))
9589             (real_interval[a,b])
9590         ==> ((\x. f'(x) * g(x)) has_real_integral y) (real_interval[a,b])`,
9591   REPEAT STRIP_TAC THEN
9592   MP_TAC(ISPECL [`\x. (f:real->real)(x) * g(x)`;
9593                  `\x. (f:real->real)(x) * g'(x) + f'(x) * g(x)`;
9594                  `c:real->bool`; `a:real`; `b:real`]
9595     REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG) THEN
9596   ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_MUL_ATREAL] THEN
9597   FIRST_ASSUM(fun th -> MP_TAC th THEN REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN
9598         DISCH_THEN(MP_TAC o MATCH_MP HAS_REAL_INTEGRAL_SUB)) THEN
9599   REWRITE_TAC[REAL_ARITH `b - a - (b - a - y):real = y`; REAL_ADD_SUB]);;
9600
9601 let REAL_INTEGRATION_BY_PARTS_SIMPLE = prove
9602  (`!f g f' g' a b.
9603         a <= b /\
9604         (!x. x IN real_interval[a,b]
9605              ==> (f has_real_derivative f'(x))
9606                     (atreal x within real_interval[a,b]) /\
9607                  (g has_real_derivative g'(x))
9608                     (atreal x within real_interval[a,b])) /\
9609         ((\x. f(x) * g'(x)) has_real_integral ((f b * g b - f a * g a) - y))
9610             (real_interval[a,b])
9611         ==> ((\x. f'(x) * g(x)) has_real_integral y) (real_interval[a,b])`,
9612   REPEAT STRIP_TAC THEN
9613   MP_TAC(ISPECL [`\x. (f:real->real)(x) * g(x)`;
9614                  `\x. (f:real->real)(x) * g'(x) + f'(x) * g(x)`;
9615                  `a:real`; `b:real`] REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN
9616   ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_MUL_WITHIN] THEN
9617   FIRST_ASSUM(fun th -> MP_TAC th THEN REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN
9618         DISCH_THEN(MP_TAC o MATCH_MP HAS_REAL_INTEGRAL_SUB)) THEN
9619   REWRITE_TAC[REAL_ARITH `b - a - (b - a - y):real = y`; REAL_ADD_SUB]);;
9620
9621 let REAL_INTEGRABLE_BY_PARTS = prove
9622  (`!f g f' g' a b c.
9623         COUNTABLE c /\
9624         (\x. f x * g x) real_continuous_on real_interval[a,b] /\
9625         (!x. x IN real_interval(a,b) DIFF c
9626              ==> (f has_real_derivative f'(x)) (atreal x) /\
9627                  (g has_real_derivative g'(x)) (atreal x)) /\
9628         (\x. f(x) * g'(x)) real_integrable_on real_interval[a,b]
9629         ==> (\x. f'(x) * g(x)) real_integrable_on real_interval[a,b]`,
9630   REPEAT GEN_TAC THEN DISJ_CASES_TAC(REAL_ARITH `b <= a \/ a <= b`) THEN
9631   ASM_SIMP_TAC[REAL_INTEGRABLE_ON_NULL] THEN
9632   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
9633   REWRITE_TAC[real_integrable_on] THEN
9634   DISCH_THEN(X_CHOOSE_THEN `y:real` STRIP_ASSUME_TAC) THEN
9635   EXISTS_TAC `((f:real->real) b * g b - f a * g a) - y` THEN
9636   MATCH_MP_TAC REAL_INTEGRATION_BY_PARTS THEN MAP_EVERY EXISTS_TAC
9637    [`f:real->real`; `g':real->real`; `c:real->bool`] THEN
9638   ASM_REWRITE_TAC[REAL_ARITH `b - a - ((b - a) - y):real = y`]);;
9639
9640 let REAL_INTEGRABLE_BY_PARTS_EQ = prove
9641  (`!f g f' g' a b c.
9642         COUNTABLE c /\
9643         (\x. f x * g x) real_continuous_on real_interval[a,b] /\
9644         (!x. x IN real_interval(a,b) DIFF c
9645              ==> (f has_real_derivative f'(x)) (atreal x) /\
9646                  (g has_real_derivative g'(x)) (atreal x))
9647         ==> ((\x. f(x) * g'(x)) real_integrable_on real_interval[a,b] <=>
9648              (\x. f'(x) * g(x)) real_integrable_on real_interval[a,b])`,
9649   REPEAT STRIP_TAC THEN EQ_TAC THENL
9650    [ASM_MESON_TAC[REAL_INTEGRABLE_BY_PARTS]; DISCH_TAC] THEN
9651   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
9652   MATCH_MP_TAC REAL_INTEGRABLE_BY_PARTS THEN
9653   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN ASM_MESON_TAC[]);;
9654
9655 (* ------------------------------------------------------------------------- *)
9656 (* Change of variable in real integral (one that we know exists).            *)
9657 (* ------------------------------------------------------------------------- *)
9658
9659 let HAS_REAL_INTEGRAL_SUBSTITUTION_STRONG = prove
9660  (`!f g g' a b c d k.
9661         COUNTABLE k /\
9662         f real_integrable_on real_interval[c,d] /\
9663         g real_continuous_on real_interval[a,b] /\
9664         IMAGE g (real_interval[a,b]) SUBSET real_interval[c,d] /\
9665         (!x. x IN real_interval[a,b] DIFF k
9666                   ==> (g has_real_derivative g'(x))
9667                        (atreal x within real_interval[a,b]) /\
9668                       f real_continuous
9669                         (atreal(g x)) within real_interval[c,d]) /\
9670         a <= b /\ c <= d /\ g a <= g b
9671         ==> ((\x. f(g x) * g'(x)) has_real_integral
9672              real_integral (real_interval[g a,g b]) f) (real_interval[a,b])`,
9673   REPEAT STRIP_TAC THEN
9674   ABBREV_TAC `ff = \x. real_integral (real_interval[c,x]) f` THEN
9675   MP_TAC(ISPECL
9676    [`(ff:real->real) o (g:real->real)`;
9677     `\x:real. (f:real->real)(g x) * g'(x)`; `k:real->bool`; `a:real`; `b:real`]
9678    REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG) THEN
9679   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
9680    [CONJ_TAC THENL
9681      [MATCH_MP_TAC REAL_CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN
9682       MATCH_MP_TAC REAL_CONTINUOUS_ON_SUBSET THEN
9683       EXISTS_TAC `real_interval [c,d]` THEN ASM_REWRITE_TAC[] THEN
9684       EXPAND_TAC "ff" THEN
9685       MATCH_MP_TAC REAL_INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT THEN
9686       ASM_REWRITE_TAC[];
9687       X_GEN_TAC `x:real` THEN REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN
9688       FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REWRITE_RULE[SUBSET]
9689         REAL_INTERVAL_OPEN_SUBSET_CLOSED)) THEN
9690       SUBGOAL_THEN `(ff o g has_real_derivative f (g x:real) * g' x)
9691                     (atreal x within real_interval[a,b])`
9692       MP_TAC THENL
9693        [MATCH_MP_TAC REAL_DIFF_CHAIN_WITHIN THEN
9694         ASM_SIMP_TAC[HAS_REAL_DERIVATIVE_ATREAL_WITHIN; IN_DIFF] THEN
9695         MP_TAC(ISPECL [`f:real->real`; `c:real`; `d:real`; `(g:real->real) x`]
9696           REAL_INTEGRAL_HAS_REAL_DERIVATIVE_POINTWISE) THEN
9697         ASM_SIMP_TAC[REAL_CONTINUOUS_ATREAL_WITHINREAL; IN_DIFF] THEN
9698         ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
9699         ASM_MESON_TAC[HAS_REAL_DERIVATIVE_WITHIN_SUBSET];
9700         DISCH_THEN(MP_TAC o SPEC `real_interval(a,b)` o MATCH_MP
9701          (REWRITE_RULE[IMP_CONJ] HAS_REAL_DERIVATIVE_WITHIN_SUBSET)) THEN
9702         REWRITE_TAC[REAL_INTERVAL_OPEN_SUBSET_CLOSED] THEN
9703         REWRITE_TAC[HAS_REAL_DERIVATIVE_WITHINREAL] THEN
9704         ASM_SIMP_TAC[REALLIM_WITHIN_REAL_OPEN; REAL_OPEN_REAL_INTERVAL] THEN
9705         REWRITE_TAC[HAS_REAL_DERIVATIVE_ATREAL]]];
9706     EXPAND_TAC "ff" THEN
9707     MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
9708     REWRITE_TAC[o_DEF] THEN MATCH_MP_TAC(REAL_ARITH
9709      `z + w:real = y ==> y - z = w`) THEN
9710     MATCH_MP_TAC REAL_INTEGRAL_COMBINE THEN ASM_REWRITE_TAC[] THEN
9711     CONJ_TAC THENL
9712      [ALL_TAC;
9713       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
9714         REAL_INTEGRABLE_SUBINTERVAL))] THEN
9715     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
9716     REWRITE_TAC[FORALL_IN_IMAGE; IN_REAL_INTERVAL; SUBSET] THEN
9717     ASM_MESON_TAC[REAL_LE_REFL; REAL_LE_TRANS]]);;
9718
9719 let HAS_REAL_INTEGRAL_SUBSTITUTION = prove
9720  (`!f g g' a b c d k.
9721         COUNTABLE k /\
9722         f real_continuous_on real_interval[c,d] /\
9723         g real_continuous_on real_interval[a,b] /\
9724         IMAGE g (real_interval[a,b]) SUBSET real_interval[c,d] /\
9725         (!x. x IN real_interval[a,b] DIFF k
9726                   ==> (g has_real_derivative g'(x)) (atreal x)) /\
9727         a <= b /\ c <= d /\ g a <= g b
9728         ==> ((\x. f(g x) * g'(x)) has_real_integral
9729              real_integral (real_interval[g a,g b]) f) (real_interval[a,b])`,
9730   REPEAT STRIP_TAC THEN
9731   MP_TAC(ISPECL [`f:real->real`; `c:real`; `d:real`]
9732         REAL_INTEGRAL_HAS_REAL_DERIVATIVE) THEN
9733   ASM_REWRITE_TAC[] THEN
9734   ABBREV_TAC `h = \u. real_integral (real_interval[c,u]) f` THEN DISCH_TAC THEN
9735   MP_TAC(ISPECL
9736    [`(h:real->real) o (g:real->real)`;
9737     `\x:real. (f:real->real)(g x) * g' x`;
9738     `k:real->bool`; `a:real`; `b:real`]
9739         REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG) THEN
9740   MP_TAC(ISPECL
9741    [`h:real->real`; `f:real->real`;
9742     `(g:real->real) a`; `(g:real->real) b`]
9743         REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN
9744   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
9745    [X_GEN_TAC `x:real` THEN STRIP_TAC THEN
9746     FIRST_X_ASSUM(MP_TAC o SPEC `x:real`) THEN ANTS_TAC THENL
9747      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
9748        `x IN s ==> s SUBSET t ==> x IN t`));
9749       MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT]
9750        HAS_REAL_DERIVATIVE_WITHIN_SUBSET)] THEN
9751     REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN DISJ2_TAC THEN
9752     MATCH_MP_TAC(REAL_ARITH
9753      `(c <= ga /\ ga <= d) /\ (c <= gb /\ gb <= d) /\ ga <= gb
9754       ==> c <= ga /\ ga <= gb /\ gb <= d`) THEN
9755     ASM_REWRITE_TAC[GSYM IN_REAL_INTERVAL] THEN CONJ_TAC THEN
9756     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
9757     REWRITE_TAC[FORALL_IN_IMAGE] THEN DISCH_THEN MATCH_MP_TAC THEN
9758     ASM_REWRITE_TAC[IN_REAL_INTERVAL; REAL_LE_REFL];
9759     DISCH_THEN(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN
9760     REWRITE_TAC[o_THM] THEN DISCH_THEN MATCH_MP_TAC THEN CONJ_TAC THENL
9761      [MATCH_MP_TAC REAL_CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN
9762       EXPAND_TAC "h" THEN
9763       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
9764         REAL_CONTINUOUS_ON_SUBSET)) THEN
9765       MATCH_MP_TAC REAL_INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT THEN
9766       ASM_SIMP_TAC[REAL_INTEGRABLE_CONTINUOUS];
9767       X_GEN_TAC `x:real` THEN REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN
9768       FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REWRITE_RULE[SUBSET]
9769         REAL_INTERVAL_OPEN_SUBSET_CLOSED)) THEN
9770       SUBGOAL_THEN
9771        `(h o (g:real->real) has_real_derivative f(g x) * g' x)
9772         (atreal x within real_interval[a,b])`
9773       MP_TAC THENL
9774        [MATCH_MP_TAC REAL_DIFF_CHAIN_WITHIN THEN
9775         ASM_SIMP_TAC[IN_DIFF; HAS_REAL_DERIVATIVE_ATREAL_WITHIN] THEN
9776         FIRST_X_ASSUM(MP_TAC o SPEC `(g:real->real) x`) THEN
9777         ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
9778         MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT]
9779           HAS_REAL_DERIVATIVE_WITHIN_SUBSET) THEN
9780         ASM_REWRITE_TAC[];
9781         REWRITE_TAC[HAS_REAL_DERIVATIVE_WITHINREAL; HAS_REAL_DERIVATIVE_ATREAL;
9782                     REALLIM_WITHINREAL_WITHIN; REALLIM_ATREAL_AT] THEN
9783         REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; TENDSTO_REAL] THEN
9784         MATCH_MP_TAC EQ_IMP THEN MATCH_MP_TAC LIM_WITHIN_INTERIOR THEN
9785         REWRITE_TAC[INTERIOR_INTERVAL; GSYM IMAGE_LIFT_REAL_INTERVAL] THEN
9786         ASM_SIMP_TAC[FUN_IN_IMAGE]]]]);;
9787
9788 let REAL_INTEGRAL_SUBSTITUTION = prove
9789  (`!f g g' a b c d k.
9790         COUNTABLE k /\
9791         f real_continuous_on real_interval[c,d] /\
9792         g real_continuous_on real_interval[a,b] /\
9793         IMAGE g (real_interval[a,b]) SUBSET real_interval[c,d] /\
9794         (!x. x IN real_interval[a,b] DIFF k
9795                   ==> (g has_real_derivative g'(x)) (atreal x)) /\
9796         a <= b /\ c <= d /\ g a <= g b
9797         ==> real_integral (real_interval[a,b]) (\x. f(g x) * g'(x)) =
9798             real_integral (real_interval[g a,g b]) f`,
9799   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
9800   ASM_MESON_TAC[HAS_REAL_INTEGRAL_SUBSTITUTION]);;
9801
9802 let HAS_REAL_INTEGRAL_SUBSTITUTION_SIMPLE = prove
9803  (`!f g g' a b c d.
9804         f real_continuous_on real_interval[c,d] /\
9805         (!x. x IN real_interval[a,b]
9806                   ==> (g has_real_derivative g'(x))
9807                       (atreal x within real_interval[a,b])) /\
9808         IMAGE g (real_interval[a,b]) SUBSET real_interval[c,d] /\
9809         a <= b /\ c <= d /\ g a <= g b
9810         ==> ((\x. f(g x) * g'(x)) has_real_integral
9811              real_integral (real_interval[g a,g b]) f) (real_interval[a,b])`,
9812   REPEAT STRIP_TAC THEN
9813   FIRST_ASSUM(MP_TAC o MATCH_MP REAL_INTEGRAL_HAS_REAL_DERIVATIVE) THEN
9814   ABBREV_TAC `h = \u. real_integral (real_interval[c,u]) f` THEN
9815   DISCH_TAC THEN
9816   MP_TAC(ISPECL
9817    [`(h:real->real) o (g:real->real)`;
9818     `\x:real. (f:real->real)(g x) * g' x`;
9819     `a:real`; `b:real`]
9820         REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN
9821   MP_TAC(ISPECL
9822    [`h:real->real`; `f:real->real`; `(g:real->real) a`; `(g:real->real) b`]
9823         REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN
9824   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
9825    [X_GEN_TAC `x:real` THEN STRIP_TAC THEN
9826     FIRST_X_ASSUM(MP_TAC o SPEC `x:real`) THEN ANTS_TAC THENL
9827      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
9828        `x IN s ==> s SUBSET t ==> x IN t`));
9829       MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT]
9830        HAS_REAL_DERIVATIVE_WITHIN_SUBSET)] THEN
9831     REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN DISJ2_TAC THEN
9832     MATCH_MP_TAC(REAL_ARITH
9833      `(c <= ga /\ ga <= d) /\ (c <= gb /\ gb <= d) /\ ga <= gb
9834       ==> c <= ga /\ ga <= gb /\ gb <= d`) THEN
9835     ASM_REWRITE_TAC[GSYM IN_REAL_INTERVAL] THEN CONJ_TAC THEN
9836     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
9837     REWRITE_TAC[FORALL_IN_IMAGE] THEN DISCH_THEN MATCH_MP_TAC THEN
9838     ASM_REWRITE_TAC[IN_REAL_INTERVAL; REAL_LE_REFL];
9839     DISCH_THEN(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN
9840     REWRITE_TAC[o_THM] THEN DISCH_THEN MATCH_MP_TAC THEN
9841     X_GEN_TAC `x:real` THEN STRIP_TAC THEN
9842     MATCH_MP_TAC REAL_DIFF_CHAIN_WITHIN THEN ASM_SIMP_TAC[] THEN
9843     FIRST_X_ASSUM(MP_TAC o SPEC `(g:real->real) x`) THEN
9844     ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
9845     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT]
9846       HAS_REAL_DERIVATIVE_WITHIN_SUBSET) THEN
9847     ASM_REWRITE_TAC[]]);;
9848
9849 let REAL_INTEGRAL_SUBSTITUTION_SIMPLE = prove
9850  (`!f g g' a b c d.
9851         f real_continuous_on real_interval[c,d] /\
9852         (!x. x IN real_interval[a,b]
9853                   ==> (g has_real_derivative g'(x))
9854                       (atreal x within real_interval[a,b])) /\
9855         IMAGE g (real_interval[a,b]) SUBSET real_interval[c,d] /\
9856         a <= b /\ c <= d /\ g a <= g b
9857         ==> real_integral (real_interval[a,b]) (\x. f(g x) * g'(x)) =
9858             real_integral (real_interval[g a,g b]) f`,
9859   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
9860   ASM_MESON_TAC[HAS_REAL_INTEGRAL_SUBSTITUTION_SIMPLE]);;
9861
9862 (* ------------------------------------------------------------------------- *)
9863 (* Drop the k'th coordinate, or insert t at the k'th coordinate.             *)
9864 (* ------------------------------------------------------------------------- *)
9865
9866 let dropout = new_definition
9867  `(dropout:num->real^N->real^M) k x =
9868         lambda i. if i < k then x$i else x$(i + 1)`;;
9869
9870 let pushin = new_definition
9871  `pushin k t x = lambda i. if i < k then x$i
9872                            else if i = k then t
9873                            else x$(i - 1)`;;
9874
9875 let DROPOUT_PUSHIN = prove
9876  (`!k t x.
9877         dimindex(:M) + 1 = dimindex(:N)
9878         ==> (dropout k:real^N->real^M) (pushin k t x) = x`,
9879   REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o SYM) THEN
9880   ASM_SIMP_TAC[CART_EQ; dropout; pushin; LAMBDA_BETA;
9881                ARITH_RULE `1 <= n + 1`; ADD_SUB;
9882                ARITH_RULE `m <= n ==> m <= n + 1 /\ m + 1 <= n + 1`] THEN
9883   ARITH_TAC);;
9884
9885 let PUSHIN_DROPOUT = prove
9886  (`!k x.
9887         dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N)
9888         ==> pushin k (x$k) ((dropout k:real^N->real^M) x) = x`,
9889   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN(ASSUME_TAC o GSYM)) THEN
9890   ASM_SIMP_TAC[CART_EQ; dropout; pushin; LAMBDA_BETA;
9891                ARITH_RULE `i <= n + 1 ==> i - 1 <= n`] THEN
9892   X_GEN_TAC `i:num` THEN STRIP_TAC THEN
9893   ASM_CASES_TAC `i:num = k` THEN ASM_REWRITE_TAC[LT_REFL] THEN
9894   FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE
9895    `~(i:num = k) ==> i < k \/ k < i`)) THEN
9896   ASM_SIMP_TAC[ARITH_RULE `i:num < k ==> ~(k < i)`] THEN
9897   W(MP_TAC o PART_MATCH (lhs o rand) LAMBDA_BETA o lhand o snd) THEN
9898   (ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_THEN SUBST1_TAC]) THEN
9899   ASM_SIMP_TAC[ARITH_RULE `k < i ==> ~(i - 1 < k)`] THEN
9900   AP_TERM_TAC THEN ASM_ARITH_TAC);;
9901
9902 let DROPOUT_GALOIS = prove
9903  (`!k x:real^N y:real^M.
9904         dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N)
9905         ==> (y = dropout k x <=> (?t. x = pushin k t y))`,
9906   REPEAT STRIP_TAC THEN EQ_TAC THENL
9907    [DISCH_THEN SUBST1_TAC THEN
9908     EXISTS_TAC `(x:real^N)$k` THEN ASM_SIMP_TAC[PUSHIN_DROPOUT];
9909     DISCH_THEN(X_CHOOSE_THEN `t:real` SUBST1_TAC) THEN
9910     ASM_SIMP_TAC[DROPOUT_PUSHIN]]);;
9911
9912 let IN_IMAGE_DROPOUT = prove
9913  (`!x s.
9914         dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N)
9915         ==> (x IN IMAGE (dropout k:real^N->real^M) s <=>
9916              ?t. (pushin k t x) IN s)`,
9917   SIMP_TAC[IN_IMAGE; DROPOUT_GALOIS] THEN MESON_TAC[]);;
9918
9919 let CLOSED_INTERVAL_DROPOUT = prove
9920  (`!k a b. dimindex(:M) + 1 = dimindex(:N) /\
9921            1 <= k /\ k <= dimindex(:N) /\
9922            a$k <= b$k
9923            ==> interval[dropout k a,dropout k b] =
9924                IMAGE (dropout k:real^N->real^M) (interval[a,b])`,
9925   REPEAT STRIP_TAC THEN
9926   ASM_SIMP_TAC[EXTENSION; IN_IMAGE_DROPOUT; IN_INTERVAL] THEN
9927   X_GEN_TAC `x:real^M` THEN
9928   SIMP_TAC[pushin; dropout; LAMBDA_BETA] THEN EQ_TAC THENL
9929    [DISCH_TAC THEN EXISTS_TAC `(a:real^N)$k` THEN X_GEN_TAC `i:num` THEN
9930     STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
9931      [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
9932       DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC;
9933       COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN
9934       FIRST_X_ASSUM(MP_TAC o SPEC `i - 1`) THEN
9935       COND_CASES_TAC THENL [ASM_ARITH_TAC; ASM_REWRITE_TAC[]] THEN
9936       ANTS_TAC THENL [ASM_ARITH_TAC; ASM_SIMP_TAC[SUB_ADD]]];
9937     DISCH_THEN(X_CHOOSE_TAC `t:real`) THEN X_GEN_TAC `i:num` THEN
9938     STRIP_TAC THEN COND_CASES_TAC THENL
9939      [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
9940       DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC;
9941       FIRST_X_ASSUM(MP_TAC o SPEC `i + 1`) THEN
9942       ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
9943       COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL [ASM_ARITH_TAC; ALL_TAC] THEN
9944       COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL [ASM_ARITH_TAC; ALL_TAC] THEN
9945       ASM_REWRITE_TAC[ADD_SUB]]]);;
9946
9947 let IMAGE_DROPOUT_CLOSED_INTERVAL = prove
9948  (`!k a b. dimindex(:M) + 1 = dimindex(:N) /\
9949            1 <= k /\ k <= dimindex(:N)
9950            ==> IMAGE (dropout k:real^N->real^M) (interval[a,b]) =
9951                   if a$k <= b$k then interval[dropout k a,dropout k b]
9952                   else {}`,
9953   REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
9954   ASM_SIMP_TAC[CLOSED_INTERVAL_DROPOUT; IMAGE_EQ_EMPTY] THEN
9955   REWRITE_TAC[INTERVAL_EQ_EMPTY; GSYM REAL_NOT_LE] THEN ASM_MESON_TAC[]);;
9956
9957 let LINEAR_DROPOUT = prove
9958  (`!k. dimindex(:M) < dimindex(:N)
9959        ==> linear(dropout k :real^N->real^M)`,
9960   GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (ARITH_RULE
9961    `m < n ==> !i:num. i <= m ==> i <= n /\ i + 1 <= n`)) THEN
9962   SIMP_TAC[linear; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
9963            dropout; LAMBDA_BETA] THEN
9964   REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
9965   ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
9966                ARITH_RULE `1 <= i + 1`]);;
9967
9968 let DROPOUT_EQ = prove
9969  (`!x y k. dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) /\
9970            x$k = y$k /\ (dropout k:real^N->real^M) x = dropout k y
9971            ==> x = y`,
9972   SIMP_TAC[CART_EQ; dropout; VEC_COMPONENT; LAMBDA_BETA; IN_ELIM_THM] THEN
9973   MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`; `k:num`] THEN
9974   STRIP_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
9975   ASM_CASES_TAC `i:num = k` THEN ASM_REWRITE_TAC[] THEN
9976   FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE
9977    `~(i:num = k) ==> i < k \/ k < i`))
9978   THENL
9979    [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_SIMP_TAC[];
9980     FIRST_X_ASSUM(MP_TAC o SPEC `i - 1`) THEN
9981     ASM_SIMP_TAC[SUB_ADD; ARITH_RULE `k < i ==> ~(i - 1 < k)`]] THEN
9982   DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC);;
9983
9984 let DROPOUT_0 = prove
9985  (`dropout k (vec 0:real^N) = vec 0`,
9986   SIMP_TAC[dropout; VEC_COMPONENT; CART_EQ; COND_ID; LAMBDA_BETA]);;
9987
9988 let DOT_DROPOUT = prove
9989  (`!k x y:real^N.
9990         dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N)
9991         ==> (dropout k x:real^M) dot (dropout k y) = x dot y - x$k * y$k`,
9992   REPEAT STRIP_TAC THEN SIMP_TAC[dot; dropout; LAMBDA_BETA] THEN
9993   REWRITE_TAC[TAUT `(if p then x else y:real) * (if p then a else b) =
9994                     (if p then x * a else y * b)`] THEN
9995   SIMP_TAC[SUM_CASES; FINITE_NUMSEG] THEN
9996   SUBGOAL_THEN
9997    `(!i. i IN 1..dimindex(:M) /\ i < k <=> i IN 1..k-1) /\
9998     (!i.  i IN 1..dimindex(:M) /\ ~(i < k) <=> i IN k..dimindex(:M))`
9999   (fun th -> REWRITE_TAC[th])
10000   THENL [REWRITE_TAC[IN_NUMSEG] THEN ASM_ARITH_TAC; ALL_TAC] THEN
10001   REWRITE_TAC[SIMPLE_IMAGE; IMAGE_ID] THEN
10002   REWRITE_TAC[GSYM(SPEC `1` SUM_OFFSET)] THEN
10003   W(MP_TAC o PART_MATCH (rhs o rand) SUM_UNION o lhs o snd) THEN
10004   ANTS_TAC THENL
10005    [REWRITE_TAC[FINITE_NUMSEG; DISJOINT_NUMSEG] THEN ARITH_TAC;
10006     DISCH_THEN(SUBST1_TAC o SYM)] THEN
10007   MP_TAC(ISPECL [`\i. (x:real^N)$i * (y:real^N)$i`;
10008                  `1..dimindex(:N)`;
10009                  `k:num`] SUM_DELETE) THEN
10010   ASM_REWRITE_TAC[IN_NUMSEG; FINITE_NUMSEG] THEN
10011   DISCH_THEN(SUBST1_TAC o SYM) THEN
10012   AP_THM_TAC THEN AP_TERM_TAC THEN
10013   REWRITE_TAC[EXTENSION; IN_NUMSEG; IN_UNION; IN_DELETE] THEN ASM_ARITH_TAC);;
10014
10015 let DOT_PUSHIN = prove
10016  (`!k a b x y:real^M.
10017         dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N)
10018         ==> (pushin k a x:real^N) dot (pushin k b y) = x dot y + a * b`,
10019   REPEAT STRIP_TAC THEN
10020   MATCH_MP_TAC EQ_TRANS THEN
10021   EXISTS_TAC `(dropout k (pushin k a (x:real^M):real^N):real^M) dot
10022               (dropout k (pushin k b (y:real^M):real^N):real^M) +
10023               a * b` THEN
10024   CONJ_TAC THENL [ALL_TAC; ASM_SIMP_TAC[DROPOUT_PUSHIN]] THEN
10025   ASM_SIMP_TAC[DOT_DROPOUT] THEN
10026   MATCH_MP_TAC(REAL_RING
10027    `a':real = a /\ b' = b ==> x = x - a' * b' + a * b`) THEN
10028   ASM_SIMP_TAC[pushin; LAMBDA_BETA; LT_REFL]);;
10029
10030 let DROPOUT_ADD = prove
10031  (`!k x y:real^N. dropout k (x + y) = dropout k x + dropout k y`,
10032   SIMP_TAC[dropout; VECTOR_ADD_COMPONENT; CART_EQ; LAMBDA_BETA] THEN
10033   MESON_TAC[]);;
10034
10035 let DROPOUT_SUB = prove
10036  (`!k x y:real^N. dropout k (x - y) = dropout k x - dropout k y`,
10037   SIMP_TAC[dropout; VECTOR_SUB_COMPONENT; CART_EQ; LAMBDA_BETA] THEN
10038   MESON_TAC[]);;
10039
10040 let DROPOUT_MUL = prove
10041  (`!k c x:real^N. dropout k (c % x) = c % dropout k x`,
10042   SIMP_TAC[dropout; VECTOR_MUL_COMPONENT; CART_EQ; LAMBDA_BETA] THEN
10043   MESON_TAC[]);;
10044
10045 (* ------------------------------------------------------------------------- *)
10046 (* Take slice of set s at x$k = t and drop the k'th coordinate.              *)
10047 (* ------------------------------------------------------------------------- *)
10048
10049 let slice = new_definition
10050  `slice k t s = IMAGE (dropout k) (s INTER {x | x$k = t})`;;
10051
10052 let IN_SLICE = prove
10053  (`!s:real^N->bool y:real^M.
10054         dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N)
10055         ==> (y IN slice k t s <=> pushin k t y IN s)`,
10056   SIMP_TAC[slice; IN_IMAGE_DROPOUT; IN_INTER; IN_ELIM_THM] THEN
10057   REPEAT STRIP_TAC THEN REWRITE_TAC[pushin] THEN
10058   ASM_SIMP_TAC[LAMBDA_BETA; LT_REFL] THEN MESON_TAC[]);;
10059
10060 let INTERVAL_INTER_HYPERPLANE = prove
10061  (`!k t a b:real^N.
10062         1 <= k /\ k <= dimindex(:N)
10063         ==> interval[a,b] INTER {x | x$k = t} =
10064                 if a$k <= t /\ t <= b$k
10065                 then interval[(lambda i. if i = k then t else a$i),
10066                               (lambda i. if i = k then t else b$i)]
10067                 else {}`,
10068   REPEAT STRIP_TAC THEN
10069   REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL; IN_ELIM_THM] THEN
10070   X_GEN_TAC `x:real^N` THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
10071    [ALL_TAC; ASM_MESON_TAC[NOT_IN_EMPTY]] THEN
10072   SIMP_TAC[IN_INTERVAL; LAMBDA_BETA] THEN
10073   EQ_TAC THEN STRIP_TAC THENL [ASM_MESON_TAC[REAL_LE_ANTISYM]; ALL_TAC] THEN
10074   CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LE_ANTISYM]] THEN
10075   X_GEN_TAC `i:num` THEN STRIP_TAC THEN
10076   FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
10077   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC);;
10078
10079 let SLICE_INTERVAL = prove
10080  (`!k a b t. dimindex(:M) + 1 = dimindex(:N) /\
10081              1 <= k /\ k <= dimindex(:N)
10082              ==> slice k t (interval[a,b]) =
10083                  if a$k <= t /\ t <= b$k
10084                  then interval[(dropout k:real^N->real^M) a,dropout k b]
10085                  else {}`,
10086   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[slice; INTERVAL_INTER_HYPERPLANE] THEN
10087   COND_CASES_TAC THEN ASM_REWRITE_TAC[IMAGE_CLAUSES] THEN
10088   ASM_SIMP_TAC[IMAGE_DROPOUT_CLOSED_INTERVAL; LAMBDA_BETA; REAL_LE_REFL] THEN
10089   MATCH_MP_TAC(MESON[]
10090    `a = a' /\ b = b' ==> interval[a,b] = interval[a',b']`) THEN
10091   SIMP_TAC[CART_EQ; LAMBDA_BETA; dropout] THEN
10092   SUBGOAL_THEN
10093    `!i. i <= dimindex(:M) ==> i <= dimindex(:N) /\ i + 1 <= dimindex(:N)`
10094   MP_TAC THENL
10095    [ASM_ARITH_TAC;
10096     ASM_SIMP_TAC[LAMBDA_BETA; ARITH_RULE `1 <= i + 1`] THEN ARITH_TAC]);;
10097
10098 let SLICE_DIFF = prove
10099  (`!k a s t.
10100         dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N)
10101         ==> (slice k a:(real^N->bool)->(real^M->bool)) (s DIFF t) =
10102              (slice k a s) DIFF (slice k a t)`,
10103   REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN
10104   SIMP_TAC[SET_RULE `(s DIFF t) INTER u = (s INTER u) DIFF (t INTER u)`] THEN
10105   MATCH_MP_TAC(SET_RULE
10106    `(!x y. x IN a /\ y IN a /\ f x = f y ==> x = y)
10107     ==> IMAGE f ((s INTER a) DIFF (t INTER a)) =
10108         IMAGE f (s INTER a) DIFF IMAGE f (t INTER a)`) THEN
10109   REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[DROPOUT_EQ]);;
10110
10111 let SLICE_UNIV = prove
10112  (`!k a. dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N)
10113         ==> slice k a (:real^N) = (:real^M)`,
10114   REPEAT STRIP_TAC THEN
10115   SIMP_TAC[EXTENSION; IN_UNIV; IN_IMAGE; slice; INTER_UNIV; IN_ELIM_THM] THEN
10116   X_GEN_TAC `y:real^M` THEN EXISTS_TAC `(pushin k a:real^M->real^N) y` THEN
10117   ASM_SIMP_TAC[DROPOUT_PUSHIN] THEN
10118   ASM_SIMP_TAC[pushin; LAMBDA_BETA; LT_REFL]);;
10119
10120 let SLICE_EMPTY = prove
10121  (`!k a. slice k a {} = {}`,
10122   REWRITE_TAC[slice; INTER_EMPTY; IMAGE_CLAUSES]);;
10123
10124 let SLICE_SUBSET = prove
10125  (`!s t k a. s SUBSET t ==> slice k a s SUBSET slice k a t`,
10126   REWRITE_TAC[slice] THEN SET_TAC[]);;
10127
10128 let SLICE_UNIONS = prove
10129  (`!s k a. slice k a (UNIONS s) = UNIONS (IMAGE (slice k a) s)`,
10130   REPEAT GEN_TAC THEN REWRITE_TAC[slice; INTER_UNIONS; IMAGE_UNIONS] THEN
10131   ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[GSYM IMAGE_o] THEN
10132   AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
10133   REWRITE_TAC[FUN_EQ_THM; o_THM; slice]);;
10134
10135 let SLICE_UNION = prove
10136  (`!k a s t.
10137         dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N)
10138         ==> (slice k a:(real^N->bool)->(real^M->bool)) (s UNION t) =
10139              (slice k a s) UNION (slice k a t)`,
10140   REPEAT GEN_TAC THEN REWRITE_TAC[slice; IMAGE_UNION;
10141         SET_RULE `(s UNION t) INTER u = (s INTER u) UNION (t INTER u)`] THEN
10142   ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[GSYM IMAGE_o] THEN
10143   AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
10144   REWRITE_TAC[FUN_EQ_THM; o_THM; slice]);;
10145
10146 let SLICE_INTER = prove
10147  (`!k a s t.
10148         dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N)
10149         ==> (slice k a:(real^N->bool)->(real^M->bool)) (s INTER t) =
10150              (slice k a s) INTER (slice k a t)`,
10151   REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN
10152   MATCH_MP_TAC(SET_RULE
10153     `(!x y. x IN u /\ y IN u /\ f x = f y ==> x = y)
10154      ==> IMAGE f ((s INTER t) INTER u) =
10155          IMAGE f (s INTER u) INTER IMAGE f (t INTER u)`) THEN
10156   REWRITE_TAC[IN_ELIM_THM] THEN ASM_MESON_TAC[DROPOUT_EQ]);;
10157
10158 let CONVEX_SLICE = prove
10159  (`!k t s. dimindex(:M) < dimindex(:N) /\ convex s
10160            ==> convex((slice k t:(real^N->bool)->(real^M->bool)) s)`,
10161   REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN
10162   MATCH_MP_TAC CONVEX_LINEAR_IMAGE THEN ASM_SIMP_TAC[LINEAR_DROPOUT] THEN
10163   MATCH_MP_TAC CONVEX_INTER THEN ASM_REWRITE_TAC[CONVEX_STANDARD_HYPERPLANE]);;
10164
10165 let COMPACT_SLICE = prove
10166  (`!k t s. dimindex(:M) < dimindex(:N) /\ compact s
10167            ==> compact((slice k t:(real^N->bool)->(real^M->bool)) s)`,
10168   REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN
10169   MATCH_MP_TAC COMPACT_LINEAR_IMAGE THEN ASM_SIMP_TAC[LINEAR_DROPOUT] THEN
10170   REWRITE_TAC[COMPACT_EQ_BOUNDED_CLOSED] THEN CONJ_TAC THENL
10171    [MATCH_MP_TAC BOUNDED_INTER THEN ASM_SIMP_TAC[COMPACT_IMP_BOUNDED];
10172     MATCH_MP_TAC CLOSED_INTER THEN
10173     ASM_SIMP_TAC[COMPACT_IMP_CLOSED; CLOSED_STANDARD_HYPERPLANE]]);;
10174
10175 let CLOSED_SLICE = prove
10176  (`!k t s. dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) /\
10177            closed s
10178            ==> closed((slice k t:(real^N->bool)->(real^M->bool)) s)`,
10179   REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN
10180   SUBGOAL_THEN
10181    `closed(IMAGE (dropout k:real^N->real^M)
10182                  (IMAGE (\x. x - t % basis k)
10183                         (s INTER {x | x$k = t})))`
10184   MP_TAC THENL
10185    [ALL_TAC;
10186     REWRITE_TAC[GSYM IMAGE_o] THEN MATCH_MP_TAC EQ_IMP THEN
10187     AP_TERM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
10188     REWRITE_TAC[FUN_EQ_THM; o_THM; dropout] THEN
10189     SUBGOAL_THEN
10190      `!i. i <= dimindex(:M) ==> i <= dimindex(:N) /\ i + 1 <= dimindex(:N)`
10191     MP_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
10192     SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; CART_EQ;
10193              LAMBDA_BETA; BASIS_COMPONENT; ARITH_RULE `1 <= i + 1`] THEN
10194     SIMP_TAC[ARITH_RULE `i:num < k ==> ~(i = k)`;
10195              ARITH_RULE `~(i < k) ==> ~(i + 1 = k)`] THEN
10196     REWRITE_TAC[REAL_MUL_RZERO; REAL_SUB_RZERO]] THEN
10197   MATCH_MP_TAC CLOSED_INJECTIVE_IMAGE_SUBSET_SUBSPACE THEN
10198   EXISTS_TAC `{x:real^N | x$k = &0}` THEN
10199   ASM_SIMP_TAC[SUBSPACE_SPECIAL_HYPERPLANE; LINEAR_DROPOUT;
10200                ARITH_RULE `m + 1 = n ==> m < n`] THEN
10201   REPEAT CONJ_TAC THENL
10202    [ONCE_REWRITE_TAC[VECTOR_ARITH `x - t % b:real^N = --(t % b) + x`] THEN
10203     ASM_SIMP_TAC[CLOSED_TRANSLATION_EQ; CLOSED_INTER;
10204                  CLOSED_STANDARD_HYPERPLANE];
10205     MATCH_MP_TAC(SET_RULE
10206      `IMAGE f t SUBSET u ==> IMAGE f (s INTER t) SUBSET u`) THEN
10207     REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10208     ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_MUL_COMPONENT; BASIS_COMPONENT;
10209                  REAL_MUL_RID; REAL_SUB_REFL];
10210     REWRITE_TAC[IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
10211     MATCH_MP_TAC DROPOUT_EQ THEN EXISTS_TAC `k:num` THEN
10212     ASM_REWRITE_TAC[DROPOUT_0; VEC_COMPONENT]]);;
10213
10214 let OPEN_SLICE = prove
10215  (`!k t s. dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) /\
10216            open s
10217            ==> open((slice k t:(real^N->bool)->(real^M->bool)) s)`,
10218   REWRITE_TAC[OPEN_CLOSED] THEN REPEAT STRIP_TAC THEN
10219   SUBGOAL_THEN `closed(slice k t ((:real^N) DIFF s):real^M->bool)`
10220   MP_TAC THENL
10221    [ASM_SIMP_TAC[CLOSED_SLICE];
10222    ASM_SIMP_TAC[SLICE_DIFF; SLICE_UNIV]]);;
10223
10224 let BOUNDED_SLICE = prove
10225  (`!k t s. dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) /\
10226            bounded s
10227            ==> bounded((slice k t:(real^N->bool)->(real^M->bool)) s)`,
10228   REPEAT STRIP_TAC THEN
10229   FIRST_ASSUM(MP_TAC o MATCH_MP BOUNDED_SUBSET_CLOSED_INTERVAL) THEN
10230   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
10231   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN
10232   MATCH_MP_TAC BOUNDED_SUBSET THEN
10233   EXISTS_TAC `(slice k t:(real^N->bool)->(real^M->bool)) (interval[a,b])` THEN
10234   ASM_SIMP_TAC[SLICE_SUBSET] THEN ASM_SIMP_TAC[SLICE_INTERVAL] THEN
10235   MESON_TAC[BOUNDED_EMPTY; BOUNDED_INTERVAL]);;
10236
10237 let SLICE_CBALL = prove
10238  (`!k t x r.
10239         dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N)
10240         ==> (slice k t:(real^N->bool)->(real^M->bool)) (cball(x,r)) =
10241                 if abs(t - x$k) <= r
10242                 then cball(dropout k x,sqrt(r pow 2 - (t - x$k) pow 2))
10243                 else {}`,
10244   REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN COND_CASES_TAC THENL
10245    [ALL_TAC;
10246     REWRITE_TAC[IMAGE_EQ_EMPTY] THEN
10247     REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; NOT_IN_EMPTY; IN_CBALL] THEN
10248     X_GEN_TAC `y:real^N` THEN REWRITE_TAC[dist] THEN
10249     DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
10250     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
10251      `~(a <= r) ==> a <= b ==> b <= r ==> F`)) THEN
10252     ASM_MESON_TAC[VECTOR_SUB_COMPONENT; COMPONENT_LE_NORM; NORM_SUB]] THEN
10253   FIRST_ASSUM(ASSUME_TAC o MATCH_MP(REAL_ARITH `abs(x) <= r ==> &0 <= r`)) THEN
10254   REWRITE_TAC[EXTENSION; IN_IMAGE; IN_CBALL] THEN X_GEN_TAC `y:real^M` THEN
10255   ASM_SIMP_TAC[DROPOUT_GALOIS; LEFT_AND_EXISTS_THM] THEN
10256   ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2] THEN
10257   REWRITE_TAC[IN_CBALL; IN_INTER; IN_ELIM_THM] THEN
10258   ASM_SIMP_TAC[pushin; LAMBDA_BETA; LT_REFL] THEN
10259   ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[UNWIND_THM2] THEN
10260   ASM_REWRITE_TAC[dist; NORM_LE_SQUARE; GSYM pushin] THEN
10261   ASM_SIMP_TAC[SQRT_POW_2; SQRT_POS_LE; REAL_SUB_LE; GSYM REAL_LE_SQUARE_ABS;
10262                REAL_ARITH `abs(x) <= r ==> abs(x) <= abs(r)`] THEN
10263   REWRITE_TAC[VECTOR_ARITH
10264    `(x - y:real^N) dot (x - y) = x dot x + y dot y - &2 * x dot y`] THEN
10265   ASM_SIMP_TAC[DOT_DROPOUT; DOT_PUSHIN] THEN MATCH_MP_TAC(REAL_FIELD
10266      `a = t * k + b
10267       ==> (xx + (yy + t * t) - &2 * a <= r pow 2 <=>
10268            xx - k * k + yy - &2 * b <= r pow 2 - (t - k) pow 2)`) THEN
10269   SUBGOAL_THEN
10270    `y:real^M = dropout k (pushin k t y:real^N)`
10271    (fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [th])
10272   THENL
10273    [CONV_TAC SYM_CONV THEN MATCH_MP_TAC DROPOUT_PUSHIN THEN ASM_ARITH_TAC;
10274     ASM_SIMP_TAC[DOT_DROPOUT] THEN
10275     ASM_SIMP_TAC[pushin; LAMBDA_BETA; LT_REFL] THEN REAL_ARITH_TAC]);;
10276
10277 let SLICE_BALL = prove
10278  (`!k t x r.
10279         dimindex(:M) + 1 = dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N)
10280         ==> (slice k t:(real^N->bool)->(real^M->bool)) (ball(x,r)) =
10281                 if abs(t - x$k) < r
10282                 then ball(dropout k x,sqrt(r pow 2 - (t - x$k) pow 2))
10283                 else {}`,
10284   REPEAT STRIP_TAC THEN REWRITE_TAC[slice] THEN COND_CASES_TAC THENL
10285    [ALL_TAC;
10286     REWRITE_TAC[IMAGE_EQ_EMPTY] THEN
10287     REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_INTER; NOT_IN_EMPTY; IN_BALL] THEN
10288     X_GEN_TAC `y:real^N` THEN REWRITE_TAC[dist] THEN
10289     DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
10290     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
10291      `~(a < r) ==> a <= b ==> b < r ==> F`)) THEN
10292     ASM_MESON_TAC[VECTOR_SUB_COMPONENT; COMPONENT_LE_NORM; NORM_SUB]] THEN
10293   FIRST_ASSUM(ASSUME_TAC o MATCH_MP(REAL_ARITH `abs(x) < r ==> &0 < r`)) THEN
10294   REWRITE_TAC[EXTENSION; IN_IMAGE; IN_BALL] THEN X_GEN_TAC `y:real^M` THEN
10295   ASM_SIMP_TAC[DROPOUT_GALOIS; LEFT_AND_EXISTS_THM] THEN
10296   ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[UNWIND_THM2] THEN
10297   REWRITE_TAC[IN_BALL; IN_INTER; IN_ELIM_THM] THEN
10298   ASM_SIMP_TAC[pushin; LAMBDA_BETA; LT_REFL] THEN
10299   ONCE_REWRITE_TAC[CONJ_SYM] THEN REWRITE_TAC[UNWIND_THM2] THEN
10300   ASM_REWRITE_TAC[dist; NORM_LT_SQUARE; GSYM pushin] THEN
10301   ASM_SIMP_TAC[SQRT_POW_2; SQRT_POS_LT; REAL_SUB_LT; GSYM REAL_LT_SQUARE_ABS;
10302    REAL_LT_IMP_LE; REAL_ARITH `abs(x) < r ==> abs(x) < abs(r)`] THEN
10303   REWRITE_TAC[VECTOR_ARITH
10304    `(x - y:real^N) dot (x - y) = x dot x + y dot y - &2 * x dot y`] THEN
10305   ASM_SIMP_TAC[DOT_DROPOUT; DOT_PUSHIN] THEN MATCH_MP_TAC(REAL_FIELD
10306      `a = t * k + b
10307       ==> (xx + (yy + t * t) - &2 * a < r pow 2 <=>
10308            xx - k * k + yy - &2 * b < r pow 2 - (t - k) pow 2)`) THEN
10309   SUBGOAL_THEN
10310    `y:real^M = dropout k (pushin k t y:real^N)`
10311    (fun th -> GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [th])
10312   THENL
10313    [CONV_TAC SYM_CONV THEN MATCH_MP_TAC DROPOUT_PUSHIN THEN ASM_ARITH_TAC;
10314     ASM_SIMP_TAC[DOT_DROPOUT] THEN
10315     ASM_SIMP_TAC[pushin; LAMBDA_BETA; LT_REFL] THEN REAL_ARITH_TAC]);;
10316
10317 (* ------------------------------------------------------------------------- *)
10318 (* Weak but useful versions of Fubini's theorem.                             *)
10319 (* ------------------------------------------------------------------------- *)
10320
10321 let FUBINI_CLOSED_INTERVAL = prove
10322  (`!k a b:real^N.
10323         dimindex(:M) + 1 = dimindex(:N) /\
10324         1 <= k /\ k <= dimindex(:N) /\
10325         a$k <= b$k
10326         ==> ((\t. measure (slice k t (interval[a,b]) :real^M->bool))
10327              has_real_integral
10328              (measure(interval[a,b]))) (:real)`,
10329   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[SLICE_INTERVAL] THEN
10330   ONCE_REWRITE_TAC[COND_RAND] THEN
10331   REWRITE_TAC[MEASURE_EMPTY; MEASURE_INTERVAL] THEN
10332   REWRITE_TAC[GSYM IN_REAL_INTERVAL] THEN
10333   SIMP_TAC[HAS_REAL_INTEGRAL_RESTRICT; SUBSET_UNIV] THEN
10334   SUBGOAL_THEN
10335    `content(interval[a:real^N,b]) =
10336     content(interval[dropout k a:real^M,dropout k b]) * (b$k - a$k)`
10337   SUBST1_TAC THEN ASM_SIMP_TAC[HAS_REAL_INTEGRAL_CONST] THEN
10338   REWRITE_TAC[CONTENT_CLOSED_INTERVAL_CASES] THEN
10339   GEN_REWRITE_TAC (RAND_CONV o RATOR_CONV) [COND_RAND] THEN
10340   GEN_REWRITE_TAC RAND_CONV [COND_RATOR] THEN
10341   REWRITE_TAC[REAL_MUL_LZERO] THEN MATCH_MP_TAC(TAUT
10342    `(p <=> p') /\ x = x'
10343     ==> (if p then x else y) = (if p' then x' else y)`) THEN
10344   CONJ_TAC THENL
10345    [SIMP_TAC[dropout; LAMBDA_BETA] THEN EQ_TAC THEN DISCH_TAC THEN
10346     X_GEN_TAC `i:num` THEN STRIP_TAC THENL
10347      [COND_CASES_TAC THEN REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
10348       ASM_ARITH_TAC;
10349       ASM_CASES_TAC `i:num = k` THEN ASM_REWRITE_TAC[] THEN
10350       ASM_CASES_TAC `i:num < k` THENL
10351        [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[];
10352         FIRST_X_ASSUM(MP_TAC o SPEC `i - 1`) THEN
10353         COND_CASES_TAC THENL [ASM_ARITH_TAC; ASM_SIMP_TAC[SUB_ADD]]] THEN
10354       DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC];
10355     ALL_TAC] THEN
10356   SUBGOAL_THEN `1..dimindex(:N) =
10357                 (1..(k-1)) UNION
10358                 (k INSERT (IMAGE (\x. x + 1) (k..dimindex(:M))))`
10359   SUBST1_TAC THENL
10360    [REWRITE_TAC[EXTENSION; IN_NUMSEG; IN_UNION; IN_INSERT; IN_IMAGE] THEN
10361     ASM_SIMP_TAC[ARITH_RULE
10362      `1 <= k
10363       ==> (x = y + 1 /\ k <= y /\ y <= n <=>
10364            y = x - 1 /\ k + 1 <= x /\ x <= n + 1)`] THEN
10365     REWRITE_TAC[CONJ_ASSOC; LEFT_EXISTS_AND_THM; EXISTS_REFL] THEN
10366     ASM_ARITH_TAC;
10367     ALL_TAC] THEN
10368   REWRITE_TAC[SET_RULE `s UNION (x INSERT t) = x INSERT (s UNION t)`] THEN
10369   SIMP_TAC[PRODUCT_CLAUSES; FINITE_NUMSEG; FINITE_UNION; FINITE_IMAGE] THEN
10370   ASM_SIMP_TAC[IN_NUMSEG; IN_UNION; IN_IMAGE; ARITH_RULE
10371    `1 <= k ==> ~(k <= k - 1)`] THEN
10372   COND_CASES_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
10373   GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN AP_TERM_TAC THEN
10374   MP_TAC(ISPECL [`1`; `k - 1`; `dimindex(:M)`] NUMSEG_COMBINE_R) THEN
10375   ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_THEN(SUBST1_TAC o SYM)] THEN
10376   W(MP_TAC o PART_MATCH (lhs o rand) PRODUCT_UNION o lhand o snd) THEN
10377   SIMP_TAC[FINITE_NUMSEG; FINITE_IMAGE; IN_NUMSEG; SET_RULE
10378             `DISJOINT s (IMAGE f t) <=> !x. x IN t ==> ~(f x IN s)`] THEN
10379   ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_THEN SUBST1_TAC] THEN
10380   W(MP_TAC o PART_MATCH (lhs o rand) PRODUCT_UNION o rand o snd) THEN
10381   SIMP_TAC[FINITE_NUMSEG; FINITE_IMAGE; IN_NUMSEG; SET_RULE
10382             `DISJOINT s t <=> !x. ~(x IN s /\ x IN t)`] THEN
10383   ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_THEN SUBST1_TAC] THEN
10384   ASM_SIMP_TAC[PRODUCT_IMAGE; EQ_ADD_RCANCEL; SUB_ADD] THEN
10385   BINOP_TAC THEN MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN
10386   SIMP_TAC[dropout; LAMBDA_BETA; o_THM] THEN
10387   REPEAT STRIP_TAC THEN BINOP_TAC THEN
10388   (W(MP_TAC o PART_MATCH (lhs o rand) LAMBDA_BETA o rand o snd) THEN
10389    ANTS_TAC THENL [ASM_ARITH_TAC; DISCH_THEN SUBST1_TAC] THEN
10390    REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
10391    ASM_ARITH_TAC));;
10392
10393 let MEASURABLE_OUTER_INTERVALS_BOUNDED_EXPLICIT_SPECIAL = prove
10394  (`!s a b e.
10395         2 <= dimindex(:N) /\ 1 <= k /\ k <= dimindex(:N) /\
10396         measurable s /\ s SUBSET interval[a,b] /\ &0 < e
10397         ==> ?f:num->real^N->bool.
10398               (!i. (f i) SUBSET interval[a,b] /\
10399                    ?c d. c$k <= d$k /\ f i = interval[c,d]) /\
10400               (!i j. ~(i = j) ==> negligible(f i INTER f j)) /\
10401               s SUBSET UNIONS {f n | n IN (:num)} /\
10402               measurable(UNIONS {f n | n IN (:num)}) /\
10403               measure(UNIONS {f n | n IN (:num)}) <= measure s + e`,
10404   let lemma = prove
10405    (`UNIONS {if n IN s then f n else {} | n IN (:num)} =
10406      UNIONS (IMAGE f s)`,
10407    SIMP_TAC[EXTENSION; IN_UNIONS; IN_ELIM_THM; IN_UNIV; EXISTS_IN_IMAGE] THEN
10408    MESON_TAC[NOT_IN_EMPTY]) in
10409   REPEAT GEN_TAC THEN
10410   REPLICATE_TAC 3 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
10411   DISCH_TAC THEN
10412   FIRST_ASSUM(MP_TAC o MATCH_MP MEASURABLE_OUTER_INTERVALS_BOUNDED) THEN
10413   DISCH_THEN(X_CHOOSE_THEN `d:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
10414   ASM_CASES_TAC `FINITE(d:(real^N->bool)->bool)` THENL
10415    [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN
10416     DISCH_THEN(X_CHOOSE_THEN `f:num->real^N->bool`
10417      (fun th -> SUBST_ALL_TAC(CONJUNCT2 th) THEN ASSUME_TAC(CONJUNCT1 th))) THEN
10418      RULE_ASSUM_TAC(REWRITE_RULE[IMP_CONJ; FORALL_IN_IMAGE;
10419        RIGHT_FORALL_IMP_THM; IN_UNIV]) THEN
10420     EXISTS_TAC `\k. if k IN 1..CARD(d:(real^N->bool)->bool) then f k
10421                     else ({}:real^N->bool)` THEN
10422     REWRITE_TAC[] THEN CONJ_TAC THENL
10423      [X_GEN_TAC `i:num` THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
10424        [ASM_MESON_TAC[REAL_NOT_LT; IN_NUMSEG; REAL_NOT_LE; INTERVAL_EQ_EMPTY];
10425         REWRITE_TAC[EMPTY_SUBSET] THEN CONV_TAC(ONCE_DEPTH_CONV SYM_CONV) THEN
10426         EXISTS_TAC `(lambda i. if i = k then &0 else &1):real^N` THEN
10427         EXISTS_TAC `(lambda i. if i = k then &1 else &0):real^N` THEN
10428         REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN CONJ_TAC THENL
10429          [SIMP_TAC[LAMBDA_BETA; ASSUME `1 <= k`; ASSUME `k <= dimindex(:N)`;
10430                    REAL_POS];
10431           ALL_TAC] THEN
10432         SUBGOAL_THEN `?j. 1 <= j /\ j <= dimindex(:N) /\ ~(j = k)` MP_TAC THENL
10433          [MATCH_MP_TAC(MESON[] `P(k - 1) \/ P(k + 1) ==> ?i. P i`) THEN
10434           ASM_ARITH_TAC;
10435           MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[LAMBDA_BETA] THEN
10436           REAL_ARITH_TAC]];
10437       ALL_TAC] THEN
10438     CONJ_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[lemma]] THEN
10439     REPEAT GEN_TAC THEN
10440       REPEAT(COND_CASES_TAC THEN
10441              ASM_REWRITE_TAC[INTER_EMPTY; NEGLIGIBLE_EMPTY]);
10442     MP_TAC(ISPEC `d:(real^N->bool)->bool` COUNTABLE_AS_INJECTIVE_IMAGE) THEN
10443     ASM_REWRITE_TAC[INFINITE] THEN MATCH_MP_TAC MONO_EXISTS THEN
10444     X_GEN_TAC `f:num->real^N->bool` THEN
10445     DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC ASSUME_TAC) THEN
10446     RULE_ASSUM_TAC(REWRITE_RULE[IMP_CONJ; FORALL_IN_IMAGE;
10447        RIGHT_FORALL_IMP_THM; IN_UNIV]) THEN
10448     RULE_ASSUM_TAC(REWRITE_RULE[GSYM SIMPLE_IMAGE]) THEN
10449     ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
10450      [ASM_MESON_TAC[REAL_NOT_LT; IN_NUMSEG; REAL_NOT_LE; INTERVAL_EQ_EMPTY];
10451         ALL_TAC] THEN
10452     MAP_EVERY X_GEN_TAC [`i:num`; `j:num`]] THEN
10453   (DISCH_TAC THEN
10454    SUBGOAL_THEN `negligible(interior((f:num->real^N->bool) i) INTER
10455                             interior(f j))`
10456    MP_TAC THENL [ASM_MESON_TAC[NEGLIGIBLE_EMPTY]; ALL_TAC] THEN
10457    REWRITE_TAC[GSYM INTERIOR_INTER] THEN
10458    REWRITE_TAC[GSYM HAS_MEASURE_0] THEN
10459    MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT]
10460      HAS_MEASURE_NEGLIGIBLE_SYMDIFF) THEN
10461    SIMP_TAC[INTERIOR_SUBSET; SET_RULE
10462       `interior(s) SUBSET s
10463        ==> (interior s DIFF s) UNION (s DIFF interior s) =
10464            s DIFF interior s`] THEN
10465    SUBGOAL_THEN `(?c d. (f:num->real^N->bool) i = interval[c,d]) /\
10466                  (?c d. (f:num->real^N->bool) j = interval[c,d])`
10467    STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
10468    ASM_REWRITE_TAC[INTER_INTERVAL; NEGLIGIBLE_FRONTIER_INTERVAL;
10469                    INTERIOR_CLOSED_INTERVAL]));;
10470
10471 let REAL_MONOTONE_CONVERGENCE_INCREASING_AE = prove
10472  (`!f:num->real->real g s.
10473         (!k. (f k) real_integrable_on s) /\
10474         (!k x. x IN s ==> f k x <= f (SUC k) x) /\
10475         (?t. real_negligible t /\
10476              !x. x IN (s DIFF t) ==> ((\k. f k x) ---> g x) sequentially) /\
10477         real_bounded {real_integral s (f k) | k IN (:num)}
10478         ==> g real_integrable_on s /\
10479             ((\k. real_integral s (f k)) ---> real_integral s g) sequentially`,
10480   REPEAT GEN_TAC THEN STRIP_TAC THEN
10481   SUBGOAL_THEN
10482    `g real_integrable_on (s DIFF t) /\
10483     ((\k. real_integral (s DIFF t) (f k)) ---> real_integral (s DIFF t) g)
10484     sequentially`
10485   MP_TAC THENL
10486    [MATCH_MP_TAC REAL_MONOTONE_CONVERGENCE_INCREASING THEN
10487     REPEAT CONJ_TAC THENL
10488      [UNDISCH_TAC `!k:num. f k real_integrable_on s` THEN
10489       MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
10490       MATCH_MP_TAC REAL_INTEGRABLE_SPIKE_SET;
10491       ASM_SIMP_TAC[IN_DIFF];
10492       ASM_REWRITE_TAC[];
10493       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_bounded]) THEN
10494       REWRITE_TAC[real_bounded; FORALL_IN_GSPEC; IN_UNIV] THEN
10495       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
10496       MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC EQ_IMP THEN
10497       AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
10498       MATCH_MP_TAC REAL_INTEGRAL_SPIKE_SET];
10499     MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THENL
10500      [MATCH_MP_TAC REAL_INTEGRABLE_SPIKE_SET_EQ THEN
10501       MATCH_MP_TAC REAL_NEGLIGIBLE_SUBSET THEN
10502       EXISTS_TAC `t:real->bool` THEN ASM_REWRITE_TAC[] THEN SET_TAC[];
10503       AP_THM_TAC THEN BINOP_TAC THENL
10504        [ABS_TAC; ALL_TAC] THEN
10505       MATCH_MP_TAC REAL_INTEGRAL_SPIKE_SET]] THEN
10506   MATCH_MP_TAC REAL_NEGLIGIBLE_SUBSET THEN
10507   EXISTS_TAC `t:real->bool` THEN ASM_REWRITE_TAC[] THEN SET_TAC[]);;
10508
10509 let FUBINI_SIMPLE_LEMMA = prove
10510  (`!k s:real^N->bool e.
10511         &0 < e /\
10512         dimindex(:M) + 1 = dimindex(:N) /\
10513         1 <= k /\ k <= dimindex(:N) /\
10514         bounded s /\ measurable s /\
10515         (!t. measurable(slice k t s:real^M->bool)) /\
10516         (\t. measure (slice k t s:real^M->bool)) real_integrable_on (:real)
10517         ==> real_integral(:real) (\t. measure (slice k t s :real^M->bool))
10518                 <= measure s + e`,
10519   REPEAT STRIP_TAC THEN
10520   FIRST_ASSUM(MP_TAC o MATCH_MP BOUNDED_SUBSET_CLOSED_INTERVAL) THEN
10521   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
10522   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN
10523   MP_TAC(ISPECL [`s:real^N->bool`; `a:real^N`; `b:real^N`; `e:real`]
10524         MEASURABLE_OUTER_INTERVALS_BOUNDED_EXPLICIT_SPECIAL) THEN
10525   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
10526    [SUBGOAL_THEN `1 <= dimindex(:M)` MP_TAC THENL
10527      [REWRITE_TAC[DIMINDEX_GE_1]; ASM_ARITH_TAC];
10528     ALL_TAC] THEN
10529   DISCH_THEN(X_CHOOSE_THEN `d:num->(real^N->bool)` STRIP_ASSUME_TAC) THEN
10530   SUBGOAL_THEN `!t n:num. measurable((slice k t:(real^N->bool)->real^M->bool)
10531                                      (d n))`
10532   ASSUME_TAC THENL
10533    [MAP_EVERY X_GEN_TAC [`t:real`; `n:num`] THEN
10534     FIRST_X_ASSUM(STRIP_ASSUME_TAC o CONJUNCT2 o SPEC `n:num`) THEN
10535     ASM_SIMP_TAC[SLICE_INTERVAL] THEN
10536     MESON_TAC[MEASURABLE_EMPTY; MEASURABLE_INTERVAL];
10537     ALL_TAC] THEN
10538   MATCH_MP_TAC REAL_LE_TRANS THEN
10539   EXISTS_TAC `measure(UNIONS {d n | n IN (:num)}:real^N->bool)` THEN
10540   ASM_REWRITE_TAC[] THEN
10541   MP_TAC(ISPECL
10542        [`\n t. sum(0..n)
10543            (\m. measure((slice k t:(real^N->bool)->real^M->bool)
10544                        (d m)))`;
10545         `\t. measure((slice k t:(real^N->bool)->real^M->bool)
10546                    (UNIONS {d n | n IN (:num)}))`; `(:real)`]
10547          REAL_MONOTONE_CONVERGENCE_INCREASING_AE) THEN
10548   REWRITE_TAC[] THEN ANTS_TAC THENL
10549    [CONJ_TAC THENL
10550      [X_GEN_TAC `i:num` THEN MATCH_MP_TAC REAL_INTEGRABLE_SUM THEN
10551       ASM_REWRITE_TAC[FINITE_NUMSEG] THEN X_GEN_TAC `j:num` THEN
10552       DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o CONJUNCT2 o SPEC `j:num`) THEN
10553       REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
10554       MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN STRIP_TAC THEN
10555       MP_TAC(ISPECL [`k:num`; `u:real^N`; `v:real^N`]
10556         FUBINI_CLOSED_INTERVAL) THEN
10557       ASM_REWRITE_TAC[] THEN MESON_TAC[real_integrable_on];
10558       ALL_TAC] THEN
10559     CONJ_TAC THENL
10560      [REPEAT STRIP_TAC THEN REWRITE_TAC[SUM_CLAUSES_NUMSEG; LE_0] THEN
10561       REWRITE_TAC[REAL_LE_ADDR] THEN MATCH_MP_TAC MEASURE_POS_LE THEN
10562       ASM_REWRITE_TAC[];
10563       ALL_TAC] THEN
10564     CONJ_TAC THENL
10565      [ALL_TAC;
10566       REWRITE_TAC[real_bounded; FORALL_IN_GSPEC; IN_UNIV] THEN
10567       EXISTS_TAC `measure(interval[a:real^N,b])` THEN X_GEN_TAC `i:num` THEN
10568       W(MP_TAC o PART_MATCH (lhand o rand) REAL_INTEGRAL_SUM o
10569         rand o lhand o snd) THEN
10570       ANTS_TAC THENL
10571        [REWRITE_TAC[FINITE_NUMSEG] THEN X_GEN_TAC `j:num` THEN DISCH_TAC THEN
10572         SUBGOAL_THEN `?u v. u$k <= v$k /\
10573                             (d:num->real^N->bool) j = interval[u,v]`
10574         STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
10575         ASM_REWRITE_TAC[] THEN REWRITE_TAC[real_integrable_on] THEN
10576         EXISTS_TAC `measure(interval[u:real^N,v])` THEN
10577         MATCH_MP_TAC FUBINI_CLOSED_INTERVAL THEN ASM_REWRITE_TAC[];
10578         ALL_TAC] THEN
10579       DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
10580       EXISTS_TAC `abs(sum(0..i) (\m. measure(d m:real^N->bool)))` THEN
10581       CONJ_TAC THENL
10582        [MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
10583         MATCH_MP_TAC SUM_EQ_NUMSEG THEN
10584         X_GEN_TAC `j:num` THEN STRIP_TAC THEN REWRITE_TAC[] THEN
10585         MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
10586         SUBGOAL_THEN `?u v. u$k <= v$k /\
10587                             (d:num->real^N->bool) j = interval[u,v]`
10588         STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
10589         ASM_REWRITE_TAC[] THEN
10590         MATCH_MP_TAC FUBINI_CLOSED_INTERVAL THEN ASM_REWRITE_TAC[];
10591         ALL_TAC] THEN
10592       MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= a ==> abs x <= a`) THEN
10593       CONJ_TAC THENL
10594        [MATCH_MP_TAC SUM_POS_LE THEN REWRITE_TAC[FINITE_NUMSEG] THEN
10595         ASM_MESON_TAC[MEASURE_POS_LE; MEASURABLE_INTERVAL];
10596         ALL_TAC] THEN
10597       W(MP_TAC o PART_MATCH (rhs o rand) MEASURE_NEGLIGIBLE_UNIONS_IMAGE o
10598         lhand o snd) THEN
10599       ANTS_TAC THENL
10600        [ASM_SIMP_TAC[FINITE_NUMSEG] THEN ASM_MESON_TAC[MEASURABLE_INTERVAL];
10601         ALL_TAC] THEN
10602       DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC MEASURE_SUBSET THEN
10603       REWRITE_TAC[MEASURABLE_INTERVAL] THEN CONJ_TAC THENL
10604        [MATCH_MP_TAC MEASURABLE_UNIONS THEN
10605         ASM_SIMP_TAC[FINITE_NUMSEG; FINITE_IMAGE; FORALL_IN_IMAGE] THEN
10606         ASM_MESON_TAC[MEASURABLE_INTERVAL];
10607         REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_IMAGE] THEN ASM_MESON_TAC[]]] THEN
10608     EXISTS_TAC
10609      `(IMAGE (\i. (interval_lowerbound(d i):real^N)$k) (:num)) UNION
10610       (IMAGE (\i. (interval_upperbound(d i):real^N)$k) (:num))` THEN
10611     CONJ_TAC THENL
10612      [MATCH_MP_TAC REAL_NEGLIGIBLE_COUNTABLE THEN
10613       SIMP_TAC[COUNTABLE_UNION; COUNTABLE_IMAGE; NUM_COUNTABLE];
10614       ALL_TAC] THEN
10615     X_GEN_TAC `t:real` THEN
10616     REWRITE_TAC[IN_DIFF; IN_UNION; IN_IMAGE] THEN
10617     GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [IN_UNIV] THEN
10618     REWRITE_TAC[DE_MORGAN_THM; NOT_EXISTS_THM] THEN DISCH_TAC THEN
10619     MP_TAC(ISPEC `\n:num. (slice k t:(real^N->bool)->real^M->bool)
10620                           (d n)`
10621        HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS_BOUNDED) THEN
10622     ASM_REWRITE_TAC[SLICE_UNIONS] THEN ANTS_TAC THENL
10623      [ALL_TAC;
10624       DISCH_THEN(MP_TAC o CONJUNCT2) THEN
10625       GEN_REWRITE_TAC (LAND_CONV o RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN
10626       REWRITE_TAC[GSYM REAL_SUMS; real_sums; FROM_INTER_NUMSEG] THEN
10627       REWRITE_TAC[SIMPLE_IMAGE; GSYM IMAGE_o; o_DEF]] THEN
10628     CONJ_TAC THENL
10629      [ALL_TAC;
10630       MATCH_MP_TAC BOUNDED_SUBSET THEN
10631       EXISTS_TAC `(slice k t:(real^N->bool)->real^M->bool) (interval[a,b])` THEN
10632       CONJ_TAC THENL
10633        [ASM_SIMP_TAC[SLICE_INTERVAL] THEN
10634         MESON_TAC[BOUNDED_INTERVAL; BOUNDED_EMPTY];
10635         REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC] THEN
10636         ASM_MESON_TAC[SLICE_SUBSET]]] THEN
10637     MAP_EVERY X_GEN_TAC [`i:num`; `j:num`] THEN DISCH_TAC THEN
10638     FIRST_X_ASSUM(MP_TAC o SPECL [`i:num`; `j:num`]) THEN
10639     ASM_REWRITE_TAC[] THEN
10640     ASM_CASES_TAC `(d:num->real^N->bool) i = {}` THENL
10641      [ASM_REWRITE_TAC[INTER_EMPTY; NEGLIGIBLE_EMPTY; SLICE_EMPTY];
10642       UNDISCH_TAC `~((d:num->real^N->bool) i = {})`] THEN
10643     ASM_CASES_TAC `(d:num->real^N->bool) j = {}` THENL
10644      [ASM_REWRITE_TAC[INTER_EMPTY; NEGLIGIBLE_EMPTY; SLICE_EMPTY];
10645       UNDISCH_TAC `~((d:num->real^N->bool) j = {})`] THEN
10646     FIRST_ASSUM(fun th ->
10647       MAP_EVERY (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)
10648        [SPEC `i:num` th; SPEC `j:num` th]) THEN
10649     REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
10650     MAP_EVERY X_GEN_TAC [`w:real^N`; `x:real^N`] THEN STRIP_TAC THEN
10651     MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN STRIP_TAC THEN
10652     ASM_SIMP_TAC[SLICE_INTERVAL; INTERVAL_NE_EMPTY] THEN
10653     DISCH_TAC THEN DISCH_TAC THEN
10654     REPEAT(COND_CASES_TAC THEN
10655            ASM_REWRITE_TAC[INTER_EMPTY; NEGLIGIBLE_EMPTY]) THEN
10656     REWRITE_TAC[INTER_INTERVAL; NEGLIGIBLE_INTERVAL; INTERVAL_EQ_EMPTY] THEN
10657     ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> ~(a /\ b ==> ~c)`] THEN
10658     SIMP_TAC[LAMBDA_BETA] THEN REWRITE_TAC[NOT_IMP] THEN
10659     DISCH_THEN(X_CHOOSE_THEN `l:num` STRIP_ASSUME_TAC) THEN
10660     SUBGOAL_THEN `~(l:num = k)` ASSUME_TAC THENL
10661      [FIRST_X_ASSUM(CONJUNCTS_THEN
10662        (fun th -> MP_TAC(SPEC `i:num` th) THEN MP_TAC(SPEC `j:num` th))) THEN
10663       ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN
10664       REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
10665       REWRITE_TAC[] THEN DISCH_THEN SUBST_ALL_TAC THEN ASM_REAL_ARITH_TAC;
10666       ALL_TAC] THEN
10667     FIRST_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE
10668      `~(l:num = k) ==> l < k \/ k < l`))
10669     THENL
10670      [EXISTS_TAC `l:num` THEN
10671       MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN
10672       CONJ_TAC THENL [ASM_ARITH_TAC; SIMP_TAC[dropout; LAMBDA_BETA]] THEN
10673       ASM_REWRITE_TAC[];
10674       ALL_TAC] THEN
10675     EXISTS_TAC `l - 1` THEN
10676     MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN
10677     CONJ_TAC THENL [ASM_ARITH_TAC; SIMP_TAC[dropout; LAMBDA_BETA]] THEN
10678     ASM_SIMP_TAC[ARITH_RULE `k < l ==> ~(l - 1 < k)`] THEN
10679     ASM_SIMP_TAC[SUB_ADD];
10680     ALL_TAC] THEN
10681   STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
10682    `real_integral (:real)
10683         (\t. measure ((slice k t :(real^N->bool)->real^M->bool)
10684                       (UNIONS {d n | n IN (:num)})))` THEN
10685   CONJ_TAC THENL
10686    [MATCH_MP_TAC REAL_INTEGRAL_LE THEN ASM_REWRITE_TAC[] THEN
10687     X_GEN_TAC `t:real` THEN DISCH_TAC THEN MATCH_MP_TAC MEASURE_SUBSET THEN
10688     ASM_SIMP_TAC[SLICE_SUBSET; SLICE_UNIONS] THEN
10689     ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[GSYM IMAGE_o] THEN
10690     ONCE_REWRITE_TAC[GSYM SIMPLE_IMAGE] THEN
10691     MATCH_MP_TAC MEASURABLE_COUNTABLE_UNIONS_BOUNDED THEN
10692     ASM_REWRITE_TAC[o_THM] THEN
10693     MATCH_MP_TAC BOUNDED_SUBSET THEN
10694     EXISTS_TAC `(slice k t:(real^N->bool)->real^M->bool) (interval[a,b])` THEN
10695     CONJ_TAC THENL
10696      [ASM_SIMP_TAC[SLICE_INTERVAL] THEN
10697       MESON_TAC[BOUNDED_INTERVAL; BOUNDED_EMPTY];
10698       REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC] THEN
10699       ASM_MESON_TAC[SLICE_SUBSET]];
10700     MATCH_MP_TAC REAL_EQ_IMP_LE THEN
10701     MATCH_MP_TAC(ISPEC `sequentially` REALLIM_UNIQUE) THEN
10702     EXISTS_TAC `\n. real_integral (:real)
10703        (\t. sum (0..n) (\m. measure((slice k t:(real^N->bool)->real^M->bool)
10704
10705                          (d m))))` THEN
10706     ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
10707     MP_TAC(ISPEC `d:num->(real^N->bool)`
10708      HAS_MEASURE_COUNTABLE_NEGLIGIBLE_UNIONS_BOUNDED) THEN
10709     ANTS_TAC THENL
10710      [ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
10711        [ASM_MESON_TAC[MEASURABLE_INTERVAL]; ALL_TAC] THEN
10712       MATCH_MP_TAC BOUNDED_SUBSET THEN EXISTS_TAC `interval[a:real^N,b]` THEN
10713       REWRITE_TAC[BOUNDED_INTERVAL; UNIONS_SUBSET; IN_ELIM_THM] THEN
10714       ASM_MESON_TAC[];
10715       ALL_TAC] THEN
10716     ASM_REWRITE_TAC[] THEN
10717     GEN_REWRITE_TAC (LAND_CONV o RATOR_CONV o LAND_CONV) [GSYM o_DEF] THEN
10718     REWRITE_TAC[GSYM REAL_SUMS] THEN
10719     REWRITE_TAC[real_sums; FROM_INTER_NUMSEG] THEN
10720     MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN
10721     AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
10722     X_GEN_TAC `i:num` THEN REWRITE_TAC[] THEN
10723     W(MP_TAC o PART_MATCH (lhand o rand) REAL_INTEGRAL_SUM o rand o snd) THEN
10724     ANTS_TAC THENL
10725      [REWRITE_TAC[FINITE_NUMSEG] THEN X_GEN_TAC `j:num` THEN DISCH_TAC THEN
10726       SUBGOAL_THEN `?u v. u$k <= v$k /\
10727                           (d:num->real^N->bool) j = interval[u,v]`
10728       STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
10729       ASM_REWRITE_TAC[] THEN REWRITE_TAC[real_integrable_on] THEN
10730       EXISTS_TAC `measure(interval[u:real^N,v])` THEN
10731       MATCH_MP_TAC FUBINI_CLOSED_INTERVAL THEN ASM_REWRITE_TAC[];
10732       ALL_TAC] THEN
10733     DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN
10734     X_GEN_TAC `j:num` THEN STRIP_TAC THEN REWRITE_TAC[] THEN
10735     CONV_TAC SYM_CONV THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
10736     SUBGOAL_THEN `?u v. u$k <= v$k /\
10737                           (d:num->real^N->bool) j = interval[u,v]`
10738     STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
10739     ASM_REWRITE_TAC[] THEN
10740     MATCH_MP_TAC FUBINI_CLOSED_INTERVAL THEN ASM_REWRITE_TAC[]]);;
10741
10742 let FUBINI_SIMPLE = prove
10743  (`!k s:real^N->bool.
10744         dimindex(:M) + 1 = dimindex(:N) /\
10745         1 <= k /\ k <= dimindex(:N) /\
10746         bounded s /\
10747         measurable s /\
10748         (!t. measurable(slice k t s :real^M->bool)) /\
10749         (\t. measure (slice k t s :real^M->bool)) real_integrable_on (:real)
10750         ==> measure s =
10751               real_integral(:real)(\t. measure (slice k t s :real^M->bool))`,
10752   REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL
10753    [ASM_REWRITE_TAC[SLICE_EMPTY; MEASURE_EMPTY; REAL_INTEGRAL_0];
10754     ALL_TAC] THEN
10755   FIRST_ASSUM(MP_TAC o MATCH_MP BOUNDED_SUBSET_CLOSED_INTERVAL) THEN
10756   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
10757   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN
10758   SUBGOAL_THEN `~(interval[a:real^N,b] = {})` MP_TAC THENL
10759    [ASM SET_TAC[]; REWRITE_TAC[INTERVAL_NE_EMPTY] THEN DISCH_TAC] THEN
10760   MATCH_MP_TAC(REAL_ARITH `~(&0 < b - a) /\ ~(&0 < a - b) ==> a:real = b`) THEN
10761   CONJ_TAC THEN MATCH_MP_TAC(MESON[]
10762      `(!e. x - y = e ==> ~(&0 < e)) ==> ~(&0 < x - y)`) THEN
10763   X_GEN_TAC `e:real` THEN REPEAT STRIP_TAC THENL
10764    [MP_TAC(ISPECL [`k:num`; `s:real^N->bool`; `e / &2`]
10765       FUBINI_SIMPLE_LEMMA) THEN
10766     ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC;
10767     ALL_TAC] THEN
10768   MP_TAC(ISPECL [`k:num`; `interval[a:real^N,b] DIFF s`; `e / &2`]
10769     FUBINI_SIMPLE_LEMMA) THEN
10770   ASM_REWRITE_TAC[NOT_IMP; GSYM CONJ_ASSOC] THEN
10771   CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
10772   CONJ_TAC THENL [SIMP_TAC[BOUNDED_DIFF; BOUNDED_INTERVAL]; ALL_TAC] THEN
10773   CONJ_TAC THENL
10774    [ASM_SIMP_TAC[MEASURABLE_DIFF; MEASURABLE_INTERVAL]; ALL_TAC] THEN
10775   ASM_SIMP_TAC[SLICE_DIFF] THEN
10776   MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
10777    [X_GEN_TAC `t:real` THEN MATCH_MP_TAC MEASURABLE_DIFF THEN
10778     ASM_SIMP_TAC[SLICE_INTERVAL] THEN
10779     MESON_TAC[MEASURABLE_EMPTY; MEASURABLE_INTERVAL];
10780     DISCH_TAC] THEN
10781   SUBGOAL_THEN
10782    `!t. measure(slice k t (interval[a:real^N,b]) DIFF
10783                 slice k t (s:real^N->bool) :real^M->bool) =
10784         measure(slice k t (interval[a:real^N,b]):real^M->bool) -
10785         measure(slice k t s :real^M->bool)`
10786    (fun th -> REWRITE_TAC[th])
10787   THENL
10788    [X_GEN_TAC `t:real` THEN MATCH_MP_TAC MEASURE_DIFF_SUBSET THEN
10789     ASM_SIMP_TAC[SLICE_SUBSET] THEN
10790     ASM_SIMP_TAC[SLICE_INTERVAL] THEN
10791     MESON_TAC[MEASURABLE_EMPTY; MEASURABLE_INTERVAL];
10792     ALL_TAC] THEN
10793   MP_TAC(ISPECL [`k:num`; `a:real^N`; `b:real^N`] FUBINI_CLOSED_INTERVAL) THEN
10794   ASM_SIMP_TAC[] THEN DISCH_TAC THEN CONJ_TAC THENL
10795    [MATCH_MP_TAC REAL_INTEGRABLE_SUB THEN ASM_MESON_TAC[real_integrable_on];
10796     ALL_TAC] THEN
10797   REWRITE_TAC[REAL_NOT_LE] THEN
10798   ASM_SIMP_TAC[MEASURE_DIFF_SUBSET; MEASURABLE_INTERVAL] THEN
10799   W(MP_TAC o PART_MATCH (lhs o rand) REAL_INTEGRAL_SUB o rand o snd) THEN
10800   ANTS_TAC THENL
10801    [ASM_MESON_TAC[real_integrable_on]; DISCH_THEN SUBST1_TAC] THEN
10802   FIRST_ASSUM(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN
10803   ASM_REAL_ARITH_TAC);;
10804
10805 let FUBINI_SIMPLE_ALT = prove
10806  (`!k s:real^N->bool.
10807         dimindex(:M) + 1 = dimindex(:N) /\
10808         1 <= k /\ k <= dimindex(:N) /\
10809         bounded s /\
10810         measurable s /\
10811         (!t. measurable(slice k t s :real^M->bool)) /\
10812         ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real)
10813         ==> measure s = B`,
10814   REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC
10815    `real_integral (:real)
10816                  (\t. measure (slice k t (s:real^N->bool) :real^M->bool))` THEN
10817   CONJ_TAC THENL
10818    [MATCH_MP_TAC FUBINI_SIMPLE THEN ASM_REWRITE_TAC[] THEN
10819     ASM_MESON_TAC[real_integrable_on];
10820     MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN ASM_REWRITE_TAC[]]);;
10821
10822 let FUBINI_SIMPLE_COMPACT_STRONG = prove
10823  (`!k s:real^N->bool.
10824         dimindex(:M) + 1 = dimindex(:N) /\
10825         1 <= k /\ k <= dimindex(:N) /\
10826         compact s /\
10827         ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real)
10828         ==> measurable s /\ measure s = B`,
10829   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[MEASURABLE_COMPACT] THEN
10830   MATCH_MP_TAC FUBINI_SIMPLE_ALT THEN
10831   EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[] THEN
10832   ASM_SIMP_TAC[COMPACT_IMP_BOUNDED; MEASURABLE_COMPACT] THEN
10833   GEN_TAC THEN MATCH_MP_TAC MEASURABLE_COMPACT THEN
10834   MATCH_MP_TAC COMPACT_SLICE THEN ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC);;
10835
10836 let FUBINI_SIMPLE_COMPACT = prove
10837  (`!k s:real^N->bool.
10838         dimindex(:M) + 1 = dimindex(:N) /\
10839         1 <= k /\ k <= dimindex(:N) /\
10840         compact s /\
10841         ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real)
10842         ==> measure s = B`,
10843   REPEAT GEN_TAC THEN
10844   DISCH_THEN(MP_TAC o MATCH_MP FUBINI_SIMPLE_COMPACT_STRONG) THEN SIMP_TAC[]);;
10845
10846 let FUBINI_SIMPLE_CONVEX_STRONG = prove
10847  (`!k s:real^N->bool.
10848         dimindex(:M) + 1 = dimindex(:N) /\
10849         1 <= k /\ k <= dimindex(:N) /\
10850         bounded s /\ convex s /\
10851         ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real)
10852         ==> measurable s /\ measure s = B`,
10853   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[MEASURABLE_CONVEX] THEN
10854   MATCH_MP_TAC FUBINI_SIMPLE_ALT THEN
10855   EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[] THEN
10856   ASM_SIMP_TAC[MEASURABLE_CONVEX] THEN
10857   GEN_TAC THEN MATCH_MP_TAC MEASURABLE_CONVEX THEN CONJ_TAC THENL
10858    [MATCH_MP_TAC CONVEX_SLICE; MATCH_MP_TAC BOUNDED_SLICE] THEN
10859   ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC);;
10860
10861 let FUBINI_SIMPLE_CONVEX = prove
10862  (`!k s:real^N->bool.
10863         dimindex(:M) + 1 = dimindex(:N) /\
10864         1 <= k /\ k <= dimindex(:N) /\
10865         bounded s /\ convex s /\
10866         ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real)
10867         ==> measure s = B`,
10868   REPEAT GEN_TAC THEN
10869   DISCH_THEN(MP_TAC o MATCH_MP FUBINI_SIMPLE_CONVEX_STRONG) THEN SIMP_TAC[]);;
10870
10871 let FUBINI_SIMPLE_OPEN_STRONG = prove
10872  (`!k s:real^N->bool.
10873         dimindex(:M) + 1 = dimindex(:N) /\
10874         1 <= k /\ k <= dimindex(:N) /\
10875         bounded s /\ open s /\
10876         ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real)
10877         ==> measurable s /\ measure s = B`,
10878   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[MEASURABLE_OPEN] THEN
10879   MATCH_MP_TAC FUBINI_SIMPLE_ALT THEN
10880   EXISTS_TAC `k:num` THEN ASM_REWRITE_TAC[] THEN
10881   ASM_SIMP_TAC[MEASURABLE_OPEN] THEN
10882   GEN_TAC THEN MATCH_MP_TAC MEASURABLE_OPEN THEN CONJ_TAC THENL
10883    [MATCH_MP_TAC BOUNDED_SLICE; MATCH_MP_TAC OPEN_SLICE] THEN
10884   ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC);;
10885
10886 let FUBINI_SIMPLE_OPEN = prove
10887  (`!k s:real^N->bool.
10888         dimindex(:M) + 1 = dimindex(:N) /\
10889         1 <= k /\ k <= dimindex(:N) /\
10890         bounded s /\ open s /\
10891         ((\t. measure (slice k t s :real^M->bool)) has_real_integral B) (:real)
10892         ==> measure s = B`,
10893   REPEAT GEN_TAC THEN
10894   DISCH_THEN(MP_TAC o MATCH_MP FUBINI_SIMPLE_OPEN_STRONG) THEN SIMP_TAC[]);;
10895
10896 (* ------------------------------------------------------------------------- *)
10897 (* Scaled integer, and hence rational, values are dense in the reals.        *)
10898 (* ------------------------------------------------------------------------- *)
10899
10900 let REAL_OPEN_SET_RATIONAL = prove
10901  (`!s. real_open s /\ ~(s = {}) ==> ?x. rational x /\ x IN s`,
10902   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
10903   MP_TAC(ISPEC `IMAGE lift s` OPEN_SET_RATIONAL_COORDINATES) THEN
10904   ASM_REWRITE_TAC[GSYM REAL_OPEN; IMAGE_EQ_EMPTY; EXISTS_IN_IMAGE] THEN
10905   SIMP_TAC[DIMINDEX_1; FORALL_1; GSYM drop; LIFT_DROP]);;
10906
10907 let REAL_OPEN_RATIONAL = prove
10908  (`!P. real_open {x | P x} /\ (?x. P x) ==> ?x. rational x /\ P x`,
10909   REPEAT STRIP_TAC THEN
10910   MP_TAC(SPEC `{x:real | P x}` REAL_OPEN_SET_RATIONAL) THEN
10911   ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN ASM_MESON_TAC[]);;
10912
10913 let REAL_OPEN_SET_EXISTS_RATIONAL = prove
10914  (`!s. real_open s ==> ((?x. rational x /\ x IN s) <=> (?x. x IN s))`,
10915   REPEAT STRIP_TAC THEN EQ_TAC THEN
10916   ASM_MESON_TAC[REAL_OPEN_SET_RATIONAL; GSYM MEMBER_NOT_EMPTY]);;
10917
10918 let REAL_OPEN_EXISTS_RATIONAL = prove
10919  (`!P. real_open {x | P x} ==> ((?x. rational x /\ P x) <=> (?x. P x))`,
10920   GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP REAL_OPEN_SET_EXISTS_RATIONAL) THEN
10921   REWRITE_TAC[IN_ELIM_THM]);;
10922
10923 (* ------------------------------------------------------------------------- *)
10924 (* Hence a criterion for two functions to agree.                             *)
10925 (* ------------------------------------------------------------------------- *)
10926
10927 let CONTINUOUS_ON_CONST_DYADIC_RATIONALS = prove
10928  (`!f:real^M->real^N a.
10929      f continuous_on (:real^M) /\
10930      (!x. (!i. 1 <= i /\ i <= dimindex(:M) ==> integer(x$i)) ==> f(x) = a) /\
10931      (!x. f(x) = a ==> f(inv(&2) % x) = a)
10932      ==> !x. f(x) = a`,
10933   REPEAT GEN_TAC THEN STRIP_TAC THEN MP_TAC(ISPECL
10934    [`f:real^M->real^N`;
10935     `{ inv(&2 pow n) % x:real^M |n,x|
10936        !i. 1 <= i /\ i <= dimindex(:M) ==> integer(x$i) }`;
10937     `a:real^N`] CONTINUOUS_CONSTANT_ON_CLOSURE) THEN
10938   ASM_REWRITE_TAC[FORALL_IN_GSPEC; CLOSURE_DYADIC_RATIONALS; IN_UNIV] THEN
10939   DISCH_THEN MATCH_MP_TAC THEN
10940   INDUCT_TAC THEN ASM_REWRITE_TAC[real_pow; REAL_INV_1; VECTOR_MUL_LID] THEN
10941   ASM_SIMP_TAC[REAL_INV_MUL; GSYM VECTOR_MUL_ASSOC]);;
10942
10943 let REAL_CONTINUOUS_ON_CONST_DYADIC_RATIONALS = prove
10944  (`!f a.
10945      f real_continuous_on (:real) /\
10946      (!x. integer(x) ==> f(x) = a) /\
10947      (!x. f(x) = a ==> f(x / &2) = a)
10948      ==> !x. f(x) = a`,
10949   REPEAT STRIP_TAC THEN
10950   MP_TAC(ISPECL [`lift o f o drop`; `lift a`]
10951     CONTINUOUS_ON_CONST_DYADIC_RATIONALS) THEN
10952   ASM_REWRITE_TAC[GSYM REAL_CONTINUOUS_ON; GSYM IMAGE_LIFT_UNIV] THEN
10953   ASM_SIMP_TAC[o_THM; DIMINDEX_1; FORALL_1; GSYM drop; LIFT_EQ; DROP_CMUL;
10954                REAL_ARITH `inv(&2) * x = x / &2`] THEN
10955   ASM_MESON_TAC[LIFT_DROP]);;
10956
10957 (* ------------------------------------------------------------------------- *)
10958 (* Various sufficient conditions for additivity to imply linearity.          *)
10959 (* ------------------------------------------------------------------------- *)
10960
10961 let CONTINUOUS_ADDITIVE_IMP_LINEAR = prove
10962  (`!f:real^M->real^N.
10963         f continuous_on (:real^M) /\
10964         (!x y. f(x + y) = f(x) + f(y))
10965         ==> linear f`,
10966   GEN_TAC THEN STRIP_TAC THEN
10967   SUBGOAL_THEN `(f:real^M->real^N) (vec 0) = vec 0` ASSUME_TAC THENL
10968    [FIRST_ASSUM(MP_TAC o repeat (SPEC `vec 0:real^M`)) THEN
10969     REWRITE_TAC[VECTOR_ADD_LID] THEN VECTOR_ARITH_TAC;
10970     ALL_TAC] THEN
10971   ASM_REWRITE_TAC[linear] THEN
10972   ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN X_GEN_TAC `x:real^M` THEN
10973   MP_TAC(ISPECL [`\c. norm((f:real^M->real^N)(c % x) - c % f(x))`; `&0`]
10974         REAL_CONTINUOUS_ON_CONST_DYADIC_RATIONALS) THEN
10975   REWRITE_TAC[NORM_EQ_0; VECTOR_SUB_EQ] THEN DISCH_THEN MATCH_MP_TAC THEN
10976   REPEAT CONJ_TAC THENL
10977    [RULE_ASSUM_TAC(REWRITE_RULE[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]) THEN
10978     RULE_ASSUM_TAC(REWRITE_RULE[IN_UNIV; WITHIN_UNIV]) THEN
10979     REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; IN_UNIV] THEN
10980     GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
10981     MATCH_MP_TAC REAL_CONTINUOUS_CONTINUOUS_WITHINREAL_COMPOSE THEN
10982     SIMP_TAC[REAL_CONTINUOUS_NORM_WITHIN] THEN MATCH_MP_TAC CONTINUOUS_SUB THEN
10983     ASM_SIMP_TAC[REWRITE_RULE[GSYM REAL_CONTINUOUS_CONTINUOUS1]CONTINUOUS_VMUL;
10984                  REAL_CONTINUOUS_WITHIN_ID; CONTINUOUS_AT_WITHIN;
10985                  REWRITE_RULE[o_DEF] CONTINUOUS_WITHINREAL_COMPOSE];
10986     MATCH_MP_TAC FORALL_INTEGER THEN CONJ_TAC THENL
10987      [INDUCT_TAC THEN ASM_SIMP_TAC[VECTOR_MUL_LZERO; GSYM REAL_OF_NUM_SUC] THEN
10988       ASM_REWRITE_TAC[VECTOR_ADD_RDISTRIB; VECTOR_MUL_LID];
10989       X_GEN_TAC `c:real` THEN
10990       FIRST_X_ASSUM(MP_TAC o SPECL [`c % x:real^M`; `--(c % x):real^M`]) THEN
10991       ASM_REWRITE_TAC[VECTOR_ADD_RINV; VECTOR_MUL_LNEG; IMP_IMP] THEN
10992       VECTOR_ARITH_TAC];
10993     X_GEN_TAC `c:real` THEN
10994     FIRST_X_ASSUM(MP_TAC o funpow 2 (SPEC `c / &2 % x:real^M`)) THEN
10995     REWRITE_TAC[VECTOR_ARITH `c / &2 % x + c / &2 % x:real^N = c % x`] THEN
10996     REWRITE_TAC[IMP_IMP] THEN VECTOR_ARITH_TAC]);;
10997
10998 let OSTROWSKI_THEOREM = prove
10999  (`!f:real^M->real^N B s.
11000         (!x y. f(x + y) = f(x) + f(y)) /\
11001         (!x. x IN s ==> norm(f x) <= B) /\
11002         measurable s /\ &0 < measure s
11003         ==> linear f`,
11004   REPEAT GEN_TAC THEN
11005   REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
11006   DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC o
11007     MATCH_MP STEINHAUS) THEN
11008   SUBGOAL_THEN `!x y. (f:real^M->real^N)(x - y) = f x - f y` ASSUME_TAC THENL
11009    [ASM_MESON_TAC[VECTOR_ARITH `x - y:real^M = z <=> x = y + z`];
11010     ALL_TAC] THEN
11011   SUBGOAL_THEN `!n x. &n % (f:real^M->real^N) x = f(&n % x)` ASSUME_TAC THENL
11012    [INDUCT_TAC THENL
11013      [ASM_MESON_TAC[VECTOR_SUB_REFL; VECTOR_MUL_LZERO];
11014       ASM_REWRITE_TAC[GSYM REAL_OF_NUM_SUC; VECTOR_ADD_RDISTRIB] THEN
11015       REWRITE_TAC[VECTOR_MUL_LID]];
11016     ALL_TAC] THEN
11017   MATCH_MP_TAC CONTINUOUS_ADDITIVE_IMP_LINEAR THEN ASM_REWRITE_TAC[] THEN
11018   SUBGOAL_THEN `!x. norm(x) < d ==> norm((f:real^M->real^N) x) <= &2 * B`
11019   ASSUME_TAC THENL
11020    [X_GEN_TAC `z:real^M` THEN DISCH_TAC THEN
11021     FIRST_X_ASSUM(MP_TAC o SPEC `z:real^M` o GEN_REWRITE_RULE I [SUBSET]) THEN
11022     ASM_REWRITE_TAC[IN_BALL_0] THEN SPEC_TAC(`z:real^M`,`z:real^M`) THEN
11023     ASM_REWRITE_TAC[FORALL_IN_GSPEC] THEN REWRITE_TAC[IN_ELIM_THM] THEN
11024     REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN(ANTE_RES_THEN MP_TAC)) THEN
11025     CONV_TAC NORM_ARITH;
11026     ALL_TAC] THEN
11027   REWRITE_TAC[continuous_on; IN_UNIV; dist] THEN
11028   MAP_EVERY X_GEN_TAC [`x:real^M`; `e:real`] THEN DISCH_TAC THEN
11029   MP_TAC(SPEC `e:real` REAL_ARCH) THEN ASM_REWRITE_TAC[] THEN
11030   DISCH_THEN(X_CHOOSE_THEN `n:num` MP_TAC o SPEC `max (&1) (&2 * B)`) THEN
11031   ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[] THENL
11032    [REAL_ARITH_TAC; DISCH_TAC] THEN
11033   EXISTS_TAC `d / &n` THEN
11034   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; LE_1] THEN
11035   X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN
11036   SUBGOAL_THEN `norm(&n % (f:real^M->real^N)(y - x)) <= &2 * B` MP_TAC THENL
11037    [ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
11038     SIMP_TAC[NORM_MUL; REAL_ABS_NUM] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
11039     ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; LE_1];
11040     SIMP_TAC[NORM_MUL; REAL_ABS_NUM] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
11041     ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN
11042     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LET_TRANS) THEN
11043     ASM_SIMP_TAC[REAL_LT_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN
11044     ASM_REAL_ARITH_TAC]);;
11045
11046 let MEASURABLE_ADDITIVE_IMP_LINEAR = prove
11047  (`!f:real^M->real^N.
11048         f measurable_on (:real^M) /\ (!x y. f(x + y) = f(x) + f(y))
11049         ==> linear f`,
11050   REPEAT STRIP_TAC THEN MATCH_MP_TAC OSTROWSKI_THEOREM THEN
11051   FIRST_X_ASSUM(MP_TAC o MATCH_MP MEASURABLE_ON_NORM) THEN
11052   REWRITE_TAC[MEASURABLE_ON_PREIMAGE_HALFSPACE_COMPONENT_LE] THEN
11053   REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; LIFT_DROP] THEN
11054   DISCH_TAC THEN
11055   ASM_CASES_TAC `!b. negligible {x | norm((f:real^M->real^N) x) <= b}` THENL
11056    [FIRST_X_ASSUM(MP_TAC o MATCH_MP NEGLIGIBLE_COUNTABLE_UNIONS o
11057         GEN `n:num` o SPEC `&n:real`) THEN
11058     REWRITE_TAC[UNIONS_GSPEC; IN_ELIM_THM; IN_UNIV; REAL_ARCH_SIMPLE] THEN
11059     SIMP_TAC[SET_RULE `{x | T} = (:real^M)`; OPEN_NOT_NEGLIGIBLE;
11060              OPEN_UNIV; UNIV_NOT_EMPTY];
11061     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN
11062     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
11063     ONCE_REWRITE_TAC[NEGLIGIBLE_ON_INTERVALS] THEN
11064     REWRITE_TAC[NOT_FORALL_THM; LEFT_IMP_EXISTS_THM] THEN
11065     MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN
11066     EXISTS_TAC `{x:real^M | norm(f x:real^N) <= B} INTER interval[a,b]` THEN
11067     ASM_SIMP_TAC[IN_ELIM_THM; IN_INTER] THEN
11068     MATCH_MP_TAC(MESON[MEASURABLE_MEASURE_POS_LT]
11069      `measurable s /\ ~negligible s ==> measurable s /\ &0 < measure s`) THEN
11070     ASM_REWRITE_TAC[] THEN
11071     MATCH_MP_TAC MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE THEN
11072     ASM_REWRITE_TAC[MEASURABLE_INTERVAL]]);;
11073
11074 let REAL_CONTINUOUS_ADDITIVE_IMP_LINEAR = prove
11075  (`!f. f real_continuous_on (:real) /\
11076        (!x y. f(x + y) = f(x) + f(y))
11077        ==> !a x. f(a * x) = a * f(x)`,
11078   GEN_TAC THEN STRIP_TAC THEN
11079   MP_TAC(ISPEC `lift o f o drop` CONTINUOUS_ADDITIVE_IMP_LINEAR) THEN
11080   ASM_REWRITE_TAC[GSYM REAL_CONTINUOUS_ON; GSYM IMAGE_LIFT_UNIV] THEN
11081   ASM_REWRITE_TAC[linear; GSYM FORALL_DROP; o_THM; DROP_ADD; LIFT_DROP;
11082                   DROP_CMUL; GSYM LIFT_ADD; GSYM LIFT_CMUL; LIFT_EQ]);;
11083
11084 (* ------------------------------------------------------------------------- *)
11085 (* Extending a continuous function in a periodic way.                        *)
11086 (* ------------------------------------------------------------------------- *)
11087
11088 let REAL_CONTINUOUS_FLOOR = prove
11089  (`!x. ~(integer x) ==> floor real_continuous (atreal x)`,
11090   REPEAT STRIP_TAC THEN REWRITE_TAC[real_continuous_atreal] THEN
11091   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11092   EXISTS_TAC `min (x - floor x) ((floor x + &1) - x)` THEN
11093   ASM_REWRITE_TAC[REAL_LT_MIN; REAL_SUB_LT; REAL_FLOOR_LT; FLOOR] THEN
11094   REPEAT STRIP_TAC THEN
11095   MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x = y ==> abs(x - y) < e`) THEN
11096   ASM_REWRITE_TAC[GSYM FLOOR_UNIQUE; FLOOR] THEN
11097   MP_TAC(ISPEC `x:real` FLOOR) THEN ASM_REAL_ARITH_TAC);;
11098
11099 let REAL_CONTINUOUS_FRAC = prove
11100  (`!x. ~(integer x) ==> frac real_continuous (atreal x)`,
11101   REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN
11102   REWRITE_TAC[FRAC_FLOOR] THEN MATCH_MP_TAC REAL_CONTINUOUS_SUB THEN
11103   ASM_SIMP_TAC[REAL_CONTINUOUS_FLOOR; REAL_CONTINUOUS_AT_ID]);;
11104
11105 let REAL_CONTINUOUS_ON_COMPOSE_FRAC = prove
11106  (`!f. f real_continuous_on real_interval[&0,&1] /\ f(&1) = f(&0)
11107        ==> (f o frac) real_continuous_on (:real)`,
11108   REPEAT STRIP_TAC THEN
11109   UNDISCH_TAC `f real_continuous_on real_interval[&0,&1]` THEN
11110   REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; WITHINREAL_UNIV] THEN
11111   DISCH_TAC THEN X_GEN_TAC `x:real` THEN DISCH_TAC THEN
11112   ASM_CASES_TAC `integer x` THENL
11113    [ALL_TAC;
11114     MATCH_MP_TAC REAL_CONTINUOUS_ATREAL_COMPOSE THEN
11115     ASM_SIMP_TAC[REAL_CONTINUOUS_FRAC] THEN
11116     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE LAND_CONV [IN_REAL_INTERVAL] o
11117                   SPEC `frac x`) THEN
11118     ASM_SIMP_TAC[FLOOR_FRAC; REAL_LT_IMP_LE] THEN
11119     REWRITE_TAC[real_continuous_atreal; real_continuous_withinreal] THEN
11120     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
11121     ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN
11122     DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
11123     EXISTS_TAC `min d (min (frac x) (&1 - frac x))` THEN
11124     ASM_SIMP_TAC[REAL_LT_MIN; REAL_SUB_LT; FLOOR_FRAC; REAL_FRAC_POS_LT] THEN
11125     REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
11126     ASM_REAL_ARITH_TAC] THEN
11127   ASM_SIMP_TAC[real_continuous_atreal; REAL_FRAC_ZERO; REAL_FLOOR_REFL] THEN
11128   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11129   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (BINDER_CONV o LAND_CONV)
11130      [IN_REAL_INTERVAL]) THEN
11131   DISCH_THEN(fun th -> MP_TAC(SPEC `&1` th) THEN MP_TAC(SPEC `&0` th)) THEN
11132   REWRITE_TAC[REAL_LE_REFL; REAL_POS] THEN
11133   REWRITE_TAC[IMP_IMP; real_continuous_withinreal; AND_FORALL_THM] THEN
11134   DISCH_THEN(MP_TAC o SPEC `e:real`) THEN
11135   ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN
11136   DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC)
11137                (X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC)) THEN
11138   EXISTS_TAC `min (&1) (min d1 d2)` THEN
11139   ASM_REWRITE_TAC[REAL_LT_01; REAL_LT_MIN; o_DEF] THEN
11140   X_GEN_TAC `y:real` THEN STRIP_TAC THEN
11141   DISJ_CASES_TAC(REAL_ARITH `x <= y \/ y < x`) THENL
11142    [SUBGOAL_THEN `floor y = floor x` ASSUME_TAC THENL
11143      [REWRITE_TAC[GSYM FLOOR_UNIQUE; FLOOR] THEN
11144       ASM_SIMP_TAC[REAL_FLOOR_REFL] THEN ASM_REAL_ARITH_TAC;
11145       ASM_SIMP_TAC[FRAC_FLOOR; REAL_FLOOR_REFL; REAL_SUB_REFL] THEN
11146       FIRST_X_ASSUM(fun th -> MATCH_MP_TAC th THEN ASM_REAL_ARITH_TAC)];
11147     SUBGOAL_THEN `floor y = floor x - &1` ASSUME_TAC THENL
11148      [REWRITE_TAC[GSYM FLOOR_UNIQUE; FLOOR] THEN
11149       ASM_SIMP_TAC[REAL_FLOOR_REFL; INTEGER_CLOSED] THEN ASM_REAL_ARITH_TAC;
11150       ASM_SIMP_TAC[FRAC_FLOOR; REAL_FLOOR_REFL; REAL_SUB_REFL] THEN
11151       FIRST_X_ASSUM(fun th -> MATCH_MP_TAC th THEN ASM_REAL_ARITH_TAC)]]);;
11152
11153 let REAL_TIETZE_PERIODIC_INTERVAL = prove
11154  (`!f a b.
11155         f real_continuous_on real_interval[a,b] /\ f(a) = f(b)
11156         ==> ?g. g real_continuous_on (:real) /\
11157                 (!x. x IN real_interval[a,b] ==> g(x) = f(x)) /\
11158                 (!x. g(x + (b - a)) = g x)`,
11159   REPEAT STRIP_TAC THEN DISJ_CASES_TAC(REAL_ARITH `b:real <= a \/ a < b`) THENL
11160    [EXISTS_TAC `\x:real. (f:real->real) a` THEN
11161     REWRITE_TAC[IN_REAL_INTERVAL; REAL_CONTINUOUS_ON_CONST] THEN
11162     ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_ANTISYM];
11163     EXISTS_TAC `(f:real->real) o (\y. a + (b - a) * y) o frac o
11164                 (\x. (x - a) / (b - a))` THEN
11165     REWRITE_TAC[o_THM] THEN REPEAT CONJ_TAC THENL
11166      [REWRITE_TAC[o_ASSOC] THEN MATCH_MP_TAC REAL_CONTINUOUS_ON_COMPOSE THEN
11167       SIMP_TAC[real_div; REAL_CONTINUOUS_ON_RMUL; REAL_CONTINUOUS_ON_SUB;
11168                REAL_CONTINUOUS_ON_CONST; REAL_CONTINUOUS_ON_ID] THEN
11169       MATCH_MP_TAC REAL_CONTINUOUS_ON_SUBSET THEN EXISTS_TAC `(:real)` THEN
11170       REWRITE_TAC[SUBSET_UNIV] THEN
11171       MATCH_MP_TAC REAL_CONTINUOUS_ON_COMPOSE_FRAC THEN
11172       ASM_SIMP_TAC[o_THM; REAL_MUL_RZERO; REAL_MUL_RID; REAL_SUB_ADD2;
11173                    REAL_ADD_RID] THEN
11174       MATCH_MP_TAC REAL_CONTINUOUS_ON_COMPOSE THEN
11175       SIMP_TAC[REAL_CONTINUOUS_ON_LMUL; REAL_CONTINUOUS_ON_ADD;
11176                REAL_CONTINUOUS_ON_CONST; REAL_CONTINUOUS_ON_ID] THEN
11177       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
11178         REAL_CONTINUOUS_ON_SUBSET)) THEN
11179       REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_REAL_INTERVAL] THEN
11180       ASM_SIMP_TAC[REAL_LE_ADDR; REAL_LE_MUL; REAL_LT_IMP_LE; REAL_SUB_LT] THEN
11181       REWRITE_TAC[REAL_ARITH
11182        `a + (b - a) * x <= b <=> &0 <= (b - a) * (&1 - x)`] THEN
11183        ASM_SIMP_TAC[REAL_LE_ADDR; REAL_LE_MUL; REAL_LT_IMP_LE; REAL_SUB_LE];
11184       X_GEN_TAC `x:real` THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN
11185       STRIP_TAC THEN ASM_CASES_TAC `x:real = b` THENL
11186        [ASM_SIMP_TAC[REAL_DIV_REFL; REAL_LT_IMP_NZ; REAL_SUB_LT] THEN
11187         ASM_REWRITE_TAC[FRAC_NUM; REAL_MUL_RZERO; REAL_ADD_RID];
11188         SUBGOAL_THEN `frac((x - a) / (b - a)) = (x - a) / (b - a)`
11189         SUBST1_TAC THENL
11190          [REWRITE_TAC[REAL_FRAC_EQ] THEN
11191           ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LT_LDIV_EQ; REAL_SUB_LT] THEN
11192           ASM_REAL_ARITH_TAC;
11193           AP_TERM_TAC THEN UNDISCH_TAC `a:real < b` THEN CONV_TAC REAL_FIELD]];
11194       ASM_SIMP_TAC[REAL_FIELD
11195         `a < b ==> ((x + b - a) - a) / (b - a) = &1 + (x - a) / (b - a)`] THEN
11196       REWRITE_TAC[REAL_FRAC_ADD; FRAC_NUM; FLOOR_FRAC; REAL_ADD_LID]]]);;
11197
11198 (* ------------------------------------------------------------------------- *)
11199 (* A variant of REAL_CONTINUOUS_ADDITIVE_IMP_LINEAR for intervals.           *)
11200 (* ------------------------------------------------------------------------- *)
11201
11202 let REAL_CONTINUOUS_ADDITIVE_EXTEND = prove
11203  (`!f. f real_continuous_on real_interval[&0,&1] /\
11204        (!x y. &0 <= x /\ &0 <= y /\ x + y <= &1
11205               ==> f(x + y) = f(x) + f(y))
11206        ==> ?g.  g real_continuous_on (:real) /\
11207                 (!x y. g(x + y) = g(x) + g(y)) /\
11208                 (!x. x IN real_interval[&0,&1] ==> g x = f x)`,
11209   REPEAT STRIP_TAC THEN SUBGOAL_THEN `f(&0) = &0` ASSUME_TAC THENL
11210    [FIRST_ASSUM(MP_TAC o ISPECL [`&0`; `&0`]) THEN
11211     REWRITE_TAC[REAL_ADD_LID] THEN REAL_ARITH_TAC;
11212     ALL_TAC] THEN
11213   EXISTS_TAC `\x. f(&1) * floor(x) + f(frac x)` THEN
11214   REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
11215    [UNDISCH_TAC `f real_continuous_on real_interval[&0,&1]` THEN
11216     REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN; WITHINREAL_UNIV] THEN
11217     DISCH_TAC THEN X_GEN_TAC `x:real` THEN DISCH_TAC THEN
11218     ASM_CASES_TAC `integer x` THENL
11219      [ALL_TAC;
11220       MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN CONJ_TAC THEN
11221       ASM_SIMP_TAC[REAL_CONTINUOUS_LMUL; REAL_CONTINUOUS_FLOOR; ETA_AX] THEN
11222       MATCH_MP_TAC(REWRITE_RULE[o_DEF] REAL_CONTINUOUS_ATREAL_COMPOSE) THEN
11223       ASM_SIMP_TAC[REAL_CONTINUOUS_FRAC] THEN
11224       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE LAND_CONV [IN_REAL_INTERVAL] o
11225                     SPEC `frac x`) THEN
11226       ASM_SIMP_TAC[FLOOR_FRAC; REAL_LT_IMP_LE] THEN
11227       REWRITE_TAC[real_continuous_atreal; real_continuous_withinreal] THEN
11228       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
11229       ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN
11230       DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
11231       EXISTS_TAC `min d (min (frac x) (&1 - frac x))` THEN
11232       ASM_SIMP_TAC[REAL_LT_MIN; REAL_SUB_LT; FLOOR_FRAC; REAL_FRAC_POS_LT] THEN
11233       REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
11234       ASM_REAL_ARITH_TAC] THEN
11235     ASM_SIMP_TAC[real_continuous_atreal; REAL_FRAC_ZERO; REAL_FLOOR_REFL] THEN
11236     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11237     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (BINDER_CONV o LAND_CONV)
11238        [IN_REAL_INTERVAL]) THEN
11239     DISCH_THEN(fun th -> MP_TAC(SPEC `&1` th) THEN MP_TAC(SPEC `&0` th)) THEN
11240     REWRITE_TAC[REAL_LE_REFL; REAL_POS] THEN
11241     REWRITE_TAC[IMP_IMP; real_continuous_withinreal; AND_FORALL_THM] THEN
11242     DISCH_THEN(MP_TAC o SPEC `e:real`) THEN
11243     ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN
11244     DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC)
11245                  (X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC)) THEN
11246     EXISTS_TAC `min (&1) (min d1 d2)` THEN
11247     ASM_REWRITE_TAC[REAL_LT_01; REAL_LT_MIN] THEN
11248     X_GEN_TAC `y:real` THEN STRIP_TAC THEN
11249     DISJ_CASES_TAC(REAL_ARITH `x <= y \/ y < x`) THENL
11250      [SUBGOAL_THEN `floor y = floor x` ASSUME_TAC THENL
11251        [REWRITE_TAC[GSYM FLOOR_UNIQUE; FLOOR] THEN
11252         ASM_SIMP_TAC[REAL_FLOOR_REFL] THEN ASM_REAL_ARITH_TAC;
11253         ASM_SIMP_TAC[FRAC_FLOOR; REAL_FLOOR_REFL] THEN
11254         REWRITE_TAC[REAL_ARITH `(a + x) - (a + &0) = x - &0`] THEN
11255         FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC];
11256       SUBGOAL_THEN `floor y = floor x - &1` ASSUME_TAC THENL
11257        [REWRITE_TAC[GSYM FLOOR_UNIQUE; FLOOR] THEN
11258         ASM_SIMP_TAC[REAL_FLOOR_REFL; INTEGER_CLOSED] THEN ASM_REAL_ARITH_TAC;
11259         ASM_SIMP_TAC[FRAC_FLOOR; REAL_FLOOR_REFL] THEN
11260         REWRITE_TAC[REAL_ARITH `(f1 * (x - &1) + f) - (f1 * x + &0) =
11261                                 f - f1`] THEN
11262         FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC]];
11263     REPEAT GEN_TAC THEN REWRITE_TAC[REAL_FLOOR_ADD; REAL_FRAC_ADD] THEN
11264     COND_CASES_TAC THEN
11265     ASM_SIMP_TAC[REAL_LT_IMP_LE; FLOOR_FRAC; REAL_LE_ADD] THENL
11266      [REAL_ARITH_TAC; ALL_TAC] THEN
11267     REWRITE_TAC[REAL_ARITH
11268      `f1 * ((x + y) + &1) + g = (f1 * x + z) + f1 * y + h <=>
11269       f1 / &2 + g / &2 = z / &2 + h / &2`] THEN
11270     SUBGOAL_THEN
11271      `!t. &0 <= t /\ t <= &1 ==> f(t) / &2 = f(t / &2)`
11272     ASSUME_TAC THENL
11273      [GEN_TAC THEN FIRST_ASSUM(MP_TAC o ISPECL [`t / &2`; `t / &2`]) THEN
11274       REWRITE_TAC[REAL_HALF] THEN REAL_ARITH_TAC;
11275       ALL_TAC] THEN
11276     ASM_SIMP_TAC[REAL_POS; REAL_LE_REFL; FLOOR_FRAC; REAL_LT_IMP_LE;
11277                  REAL_ARITH `~(x + y < &1) ==> &0 <= (x + y) - &1`;
11278                  REAL_ARITH `x < &1 /\ y < &1 ==> (x + y) - &1 <= &1`] THEN
11279     MATCH_MP_TAC(MESON[]
11280      `f(a + b) = f a + f b /\ f(c + d) = f(c) + f(d) /\ a + b = c + d
11281       ==> (f:real->real)(a) + f(b) = f(c) + f(d)`) THEN
11282     REPEAT CONJ_TAC THEN TRY REAL_ARITH_TAC THEN
11283     FIRST_X_ASSUM MATCH_MP_TAC THEN
11284     MAP_EVERY (MP_TAC o C SPEC FLOOR_FRAC) [`x:real`; `y:real`] THEN
11285     ASM_REAL_ARITH_TAC;
11286     GEN_TAC THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN ASM_CASES_TAC `x = &1` THEN
11287     ASM_REWRITE_TAC[FLOOR_NUM; FRAC_NUM; REAL_MUL_RID; REAL_ADD_RID] THEN
11288     STRIP_TAC THEN SUBGOAL_THEN `floor x = &0` ASSUME_TAC THENL
11289      [ASM_REWRITE_TAC[GSYM FLOOR_UNIQUE; INTEGER_CLOSED];
11290       ASM_REWRITE_TAC[FRAC_FLOOR; REAL_SUB_RZERO]] THEN
11291     ASM_REAL_ARITH_TAC]);;
11292
11293 let REAL_CONTINUOUS_ADDITIVE_IMP_LINEAR_INTERVAL = prove
11294  (`!f b. (f ---> &0) (atreal (&0) within {x | &0 <= x}) /\
11295          (!x y. &0 <= x /\ &0 <= y /\ x + y <= b ==> f(x + y) = f(x) + f(y))
11296          ==> !a x. &0 <= x /\ x <= b /\
11297                    &0 <= a * x /\ a * x <= b
11298                    ==> f(a * x) = a * f(x)`,
11299   SUBGOAL_THEN
11300    `!f. (f ---> &0) (atreal (&0) within {x | &0 <= x}) /\
11301         (!x y. &0 <= x /\ &0 <= y /\ x + y <= &1 ==> f(x + y) = f(x) + f(y))
11302         ==> !a x. &0 <= x /\ x <= &1 /\ &0 <= a * x /\ a * x <= &1
11303                   ==> f(a * x) = a * f(x)`
11304   ASSUME_TAC THENL
11305    [SUBGOAL_THEN
11306      `!f. f real_continuous_on real_interval[&0,&1] /\
11307           (!x y. &0 <= x /\ &0 <= y /\ x + y <= &1 ==> f(x + y) = f(x) + f(y))
11308           ==> !a x. &0 <= x /\ x <= &1 /\ &0 <= a * x /\ a * x <= &1
11309                     ==> f(a * x) = a * f(x)`
11310     (fun th -> GEN_TAC THEN STRIP_TAC THEN MATCH_MP_TAC th) THENL
11311      [REPEAT STRIP_TAC THEN
11312       MP_TAC(ISPEC `f:real->real` REAL_CONTINUOUS_ADDITIVE_EXTEND) THEN
11313       ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN
11314       DISCH_THEN(X_CHOOSE_THEN `g:real->real` STRIP_ASSUME_TAC) THEN
11315       MP_TAC(ISPEC `g:real->real` REAL_CONTINUOUS_ADDITIVE_IMP_LINEAR) THEN
11316       ASM_MESON_TAC[];
11317       ASM_REWRITE_TAC[real_continuous_on; IN_REAL_INTERVAL] THEN
11318       X_GEN_TAC `x:real` THEN STRIP_TAC THEN
11319       X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11320       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REALLIM_WITHINREAL]) THEN
11321       DISCH_THEN(MP_TAC o SPEC `e:real`) THEN
11322       ASM_REWRITE_TAC[REAL_SUB_RZERO] THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN
11323       DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
11324       EXISTS_TAC `d:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN
11325       X_GEN_TAC `y:real` THEN STRIP_TAC THEN
11326       REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC
11327        (REAL_ARITH `y = x \/ y < x \/ x < y`) THENL
11328        [ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_ABS_NUM];
11329         SUBGOAL_THEN `(f:real->real)(y + (x - y)) = f(y) + f(x - y)`
11330         MP_TAC THENL
11331          [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC;
11332           REWRITE_TAC[REAL_SUB_ADD2] THEN DISCH_THEN SUBST1_TAC THEN
11333           REWRITE_TAC[REAL_ADD_SUB2; REAL_ABS_NEG] THEN
11334           FIRST_X_ASSUM MATCH_MP_TAC THEN
11335           REWRITE_TAC[IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC];
11336         SUBGOAL_THEN `(f:real->real)(x + (y - x)) = f(x) + f(y - x)`
11337         MP_TAC THENL
11338          [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC;
11339           REWRITE_TAC[REAL_SUB_ADD2] THEN DISCH_THEN SUBST1_TAC THEN
11340           REWRITE_TAC[REAL_ADD_SUB] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
11341           REWRITE_TAC[IN_ELIM_THM] THEN ASM_REAL_ARITH_TAC]]];
11342     REPEAT GEN_TAC THEN STRIP_TAC THEN REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC
11343      (REAL_ARITH `b < &0 \/ b = &0 \/ &0 < b`)
11344     THENL
11345      [ASM_REAL_ARITH_TAC;
11346       ASM_SIMP_TAC[REAL_ARITH
11347        `a <= x /\ x <= a /\ a <= y /\ y <= a <=> x = a /\ y = a`] THEN
11348       FIRST_X_ASSUM(MP_TAC o SPECL [`&0`; `&0`]) THEN
11349       ASM_REWRITE_TAC[REAL_ADD_LID; REAL_LE_REFL] THEN CONV_TAC REAL_RING;
11350       ALL_TAC] THEN
11351     FIRST_X_ASSUM(MP_TAC o ISPEC `(\x. f(b * x)):real->real`) THEN
11352     REWRITE_TAC[] THEN ANTS_TAC THENL
11353      [ALL_TAC;
11354       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `a:real` THEN
11355       DISCH_THEN(fun th -> X_GEN_TAC `x:real` THEN STRIP_TAC THEN
11356                            MP_TAC(ISPEC `x / b:real` th)) THEN
11357       ASM_SIMP_TAC[REAL_FIELD `&0 < b ==> b * a * x / b = a * x`;
11358                    REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN
11359       DISCH_THEN MATCH_MP_TAC THEN
11360       REWRITE_TAC[REAL_ARITH `a * x / b:real = (a * x) / b`] THEN
11361       ASM_SIMP_TAC[REAL_LE_RDIV_EQ; REAL_LE_LDIV_EQ] THEN
11362       ASM_REAL_ARITH_TAC] THEN
11363     CONJ_TAC THENL
11364      [ALL_TAC;
11365       REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_ADD_LDISTRIB] THEN
11366       FIRST_X_ASSUM MATCH_MP_TAC THEN
11367       ASM_SIMP_TAC[REAL_ARITH `b * x + b * y <= b <=> &0 <= b * (&1 - (x + y))`;
11368                    REAL_LE_MUL; REAL_LT_IMP_LE; REAL_SUB_LE]] THEN
11369     REWRITE_TAC[REALLIM_WITHINREAL] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11370     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REALLIM_WITHINREAL]) THEN
11371     DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[REAL_SUB_RZERO] THEN
11372     REWRITE_TAC[REAL_SUB_RZERO; IN_ELIM_THM] THEN
11373     DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
11374     EXISTS_TAC `d / b:real` THEN ASM_SIMP_TAC[REAL_LT_DIV] THEN
11375     REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
11376     ASM_SIMP_TAC[REAL_LE_MUL; REAL_LT_IMP_LE; REAL_ABS_MUL] THEN
11377     ASM_SIMP_TAC[REAL_ARITH `&0 < b ==> abs b * x = x * b`] THEN
11378     ASM_SIMP_TAC[REAL_LT_MUL; GSYM REAL_LT_RDIV_EQ]]);;
11379
11380 (* ------------------------------------------------------------------------- *)
11381 (* More Steinhaus variants.                                                  *)
11382 (* ------------------------------------------------------------------------- *)
11383
11384 let STEINHAUS_TRIVIAL = prove
11385  (`!s e. ~(negligible s) /\ &0 < e
11386          ==> ?x y:real^N. x IN s /\ y IN s /\ ~(x = y) /\ norm(x - y) < e`,
11387   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
11388   ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[] THEN DISCH_TAC THEN
11389   MATCH_MP_TAC NEGLIGIBLE_COUNTABLE THEN
11390   MATCH_MP_TAC DISCRETE_IMP_COUNTABLE THEN
11391   ASM_MESON_TAC[REAL_NOT_LT]);;
11392
11393 let REAL_STEINHAUS = prove
11394  (`!s. real_measurable s /\ &0 < real_measure s
11395        ==> ?d. &0 < d /\
11396                real_interval(--d,d) SUBSET {x - y | x IN s /\ y IN s}`,
11397   GEN_TAC THEN SIMP_TAC[IMP_CONJ; REAL_MEASURE_MEASURE] THEN
11398   REWRITE_TAC[IMP_IMP; REAL_MEASURABLE_MEASURABLE] THEN
11399   DISCH_THEN(MP_TAC o MATCH_MP STEINHAUS) THEN
11400   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN
11401   REWRITE_TAC[SUBSET; BALL_INTERVAL; IN_INTERVAL_1; IN_REAL_INTERVAL] THEN
11402   REWRITE_TAC[SET_RULE `{g x y | x IN IMAGE f s /\ y IN IMAGE f t} =
11403                         {g (f x) (f y) | x IN s /\ y IN t}`] THEN
11404   REWRITE_TAC[GSYM LIFT_SUB] THEN
11405   REWRITE_TAC[SET_RULE `{lift(f x y) | P x y} = IMAGE lift {f x y | P x y}`;
11406               IN_IMAGE_LIFT_DROP; GSYM FORALL_DROP] THEN
11407   REWRITE_TAC[DROP_SUB; DROP_VEC; LIFT_DROP; DROP_ADD] THEN
11408   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
11409   ASM_REAL_ARITH_TAC);;
11410
11411 (* ------------------------------------------------------------------------- *)
11412 (* Bernstein polynomials.                                                    *)
11413 (* ------------------------------------------------------------------------- *)
11414
11415 let bernstein = new_definition
11416  `bernstein n k x = &(binom(n,k)) * x pow k * (&1 - x) pow (n - k)`;;
11417
11418 let BERNSTEIN_CONV =
11419   GEN_REWRITE_CONV I [bernstein] THENC
11420   COMB2_CONV (RAND_CONV(RAND_CONV NUM_BINOM_CONV))
11421              (RAND_CONV(RAND_CONV NUM_SUB_CONV)) THENC
11422   REAL_POLY_CONV;;
11423
11424 (* ------------------------------------------------------------------------- *)
11425 (* Lemmas about Bernstein polynomials.                                       *)
11426 (* ------------------------------------------------------------------------- *)
11427
11428 let BERNSTEIN_POS = prove
11429  (`!n k x. &0 <= x /\ x <= &1 ==> &0 <= bernstein n k x`,
11430   REPEAT STRIP_TAC THEN REWRITE_TAC[bernstein] THEN
11431   MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[REAL_POS] THEN
11432   MATCH_MP_TAC REAL_LE_MUL THEN CONJ_TAC THEN
11433   MATCH_MP_TAC REAL_POW_LE THEN ASM_REAL_ARITH_TAC);;
11434
11435 let SUM_BERNSTEIN = prove
11436  (`!n. sum (0..n) (\k. bernstein n k x) = &1`,
11437   REWRITE_TAC[bernstein; GSYM REAL_BINOMIAL_THEOREM] THEN
11438   REWRITE_TAC[REAL_SUB_ADD2; REAL_POW_ONE]);;
11439
11440 let BERNSTEIN_LEMMA = prove
11441  (`!n x. sum(0..n) (\k. (&k - &n * x) pow 2 * bernstein n k x) =
11442          &n * x * (&1 - x)`,
11443   REPEAT STRIP_TAC THEN
11444   SUBGOAL_THEN
11445     `!x y. sum(0..n) (\k. &(binom(n,k)) * x pow k * y pow (n - k)) =
11446            (x + y) pow n`
11447   (LABEL_TAC "0") THENL [ASM_REWRITE_TAC[REAL_BINOMIAL_THEOREM]; ALL_TAC] THEN
11448   SUBGOAL_THEN
11449    `!x y. sum(0..n) (\k. &k * &(binom(n,k)) * x pow (k - 1) * y pow (n - k)) =
11450           &n * (x + y) pow (n - 1)`
11451   (LABEL_TAC "1") THENL
11452    [REPEAT GEN_TAC THEN MATCH_MP_TAC REAL_DERIVATIVE_UNIQUE_ATREAL THEN
11453     MAP_EVERY EXISTS_TAC
11454      [`\x. sum(0..n) (\k. &(binom(n,k)) * x pow k * y pow (n - k))`;
11455       `x:real`] THEN
11456     CONJ_TAC THENL
11457      [MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUM THEN REWRITE_TAC[FINITE_NUMSEG];
11458       ASM_REWRITE_TAC[]] THEN
11459     REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN CONV_TAC REAL_RING;
11460     ALL_TAC] THEN
11461   SUBGOAL_THEN
11462    `!x y. sum(0..n)
11463         (\k. &k * &(k - 1) * &(binom(n,k)) * x pow (k - 2) * y pow (n - k)) =
11464           &n * &(n - 1) * (x + y) pow (n - 2)`
11465   (LABEL_TAC "2") THENL
11466    [REPEAT GEN_TAC THEN MATCH_MP_TAC REAL_DERIVATIVE_UNIQUE_ATREAL THEN
11467     MAP_EVERY EXISTS_TAC
11468      [`\x. sum(0..n) (\k. &k * &(binom(n,k)) * x pow (k - 1) * y pow (n - k))`;
11469       `x:real`] THEN
11470     CONJ_TAC THENL
11471      [MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUM THEN REWRITE_TAC[FINITE_NUMSEG];
11472       ASM_REWRITE_TAC[]] THEN
11473     REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN
11474     REWRITE_TAC[ARITH_RULE `n - 1 - 1 = n - 2`] THEN CONV_TAC REAL_RING;
11475     ALL_TAC] THEN
11476   REWRITE_TAC[REAL_ARITH
11477    `(a - b) pow 2 * x =
11478     a * (a - &1) * x + (&1 - &2 * b) * a * x + b * b * x`] THEN
11479   REWRITE_TAC[SUM_ADD_NUMSEG; SUM_LMUL; SUM_BERNSTEIN] THEN
11480   SUBGOAL_THEN `sum(0..n) (\k. &k * bernstein n k x) = &n * x` SUBST1_TAC THENL
11481    [REMOVE_THEN "1" (MP_TAC o SPECL [`x:real`; `&1 - x`]) THEN
11482     REWRITE_TAC[REAL_SUB_ADD2; REAL_POW_ONE; bernstein; REAL_MUL_RID] THEN
11483     DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[GSYM SUM_RMUL] THEN
11484     MATCH_MP_TAC SUM_EQ_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
11485     REWRITE_TAC[REAL_ARITH
11486      `(k * b * xk * y) * x:real = k * b * (x * xk) * y`] THEN
11487     REWRITE_TAC[GSYM(CONJUNCT2 real_pow)] THEN
11488     DISJ_CASES_TAC(ARITH_RULE `k = 0 \/ SUC(k - 1) = k`) THEN
11489     ASM_REWRITE_TAC[REAL_MUL_LZERO];
11490     ALL_TAC] THEN
11491   SUBGOAL_THEN
11492   `sum(0..n) (\k. &k * (&k - &1) * bernstein n k x) = &n * (&n - &1) * x pow 2`
11493   SUBST1_TAC THENL [ALL_TAC; CONV_TAC REAL_RING] THEN
11494   REMOVE_THEN "2" (MP_TAC o SPECL [`x:real`; `&1 - x`]) THEN
11495   REWRITE_TAC[REAL_SUB_ADD2; REAL_POW_ONE; bernstein; REAL_MUL_RID] THEN
11496   ASM_CASES_TAC `n = 0` THEN
11497   ASM_REWRITE_TAC[SUM_SING_NUMSEG; REAL_MUL_LZERO] THEN
11498   ASM_SIMP_TAC[GSYM REAL_OF_NUM_SUB; LE_1; REAL_MUL_ASSOC] THEN
11499   DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[GSYM SUM_RMUL] THEN
11500   MATCH_MP_TAC SUM_EQ_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
11501   REWRITE_TAC[REAL_ARITH `((((k * k1) * b) * xk) * y) * x2:real =
11502                             k * k1 * b * y * (x2 * xk)`] THEN
11503   REWRITE_TAC[GSYM REAL_POW_ADD; GSYM REAL_MUL_ASSOC] THEN
11504   REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC
11505    (ARITH_RULE `k = 0 \/ k = 1 \/ 1 <= k /\ 2 + k - 2 = k`) THEN
11506   ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; SUB_REFL; REAL_SUB_REFL] THEN
11507   ASM_SIMP_TAC[GSYM REAL_OF_NUM_SUB] THEN REWRITE_TAC[REAL_MUL_AC]);;
11508
11509 (* ------------------------------------------------------------------------- *)
11510 (* Explicit Bernstein version of 1D Weierstrass approximation theorem        *)
11511 (* ------------------------------------------------------------------------- *)
11512
11513 let BERNSTEIN_WEIERSTRASS = prove
11514  (`!f e.
11515       f real_continuous_on real_interval[&0,&1] /\ &0 < e
11516       ==> ?N. !n x. N <= n /\ x IN real_interval[&0,&1]
11517                     ==> abs(f x -
11518                             sum(0..n) (\k. f(&k / &n) * bernstein n k x)) < e`,
11519   REPEAT STRIP_TAC THEN
11520   SUBGOAL_THEN `real_bounded(IMAGE f (real_interval[&0,&1]))` MP_TAC THENL
11521    [MATCH_MP_TAC REAL_COMPACT_IMP_BOUNDED THEN
11522     MATCH_MP_TAC REAL_COMPACT_CONTINUOUS_IMAGE THEN
11523     ASM_REWRITE_TAC[REAL_COMPACT_INTERVAL];
11524     REWRITE_TAC[REAL_BOUNDED_POS; LEFT_IMP_EXISTS_THM; FORALL_IN_IMAGE] THEN
11525     REWRITE_TAC[IN_REAL_INTERVAL] THEN X_GEN_TAC `M:real` THEN STRIP_TAC] THEN
11526   SUBGOAL_THEN `f real_uniformly_continuous_on real_interval[&0,&1]`
11527   MP_TAC THENL
11528    [ASM_SIMP_TAC[REAL_COMPACT_UNIFORMLY_CONTINUOUS; REAL_COMPACT_INTERVAL];
11529     REWRITE_TAC[real_uniformly_continuous_on] THEN
11530     DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
11531     ASM_REWRITE_TAC[REAL_HALF; IN_REAL_INTERVAL] THEN
11532     DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC)] THEN
11533   SUBGOAL_THEN
11534    `!n x. 0 < n /\ &0 <= x /\ x <= &1
11535           ==> abs(f x - sum(0..n) (\k. f(&k / &n) * bernstein n k x))
11536                 <= e / &2 + (&2 * M) / (d pow 2 * &n)`
11537   ASSUME_TAC THENL
11538    [REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
11539     EXISTS_TAC `abs(sum(0..n) (\k. (f x - f(&k / &n)) * bernstein n k x))` THEN
11540     CONJ_TAC THENL
11541      [REWRITE_TAC[REAL_SUB_RDISTRIB; SUM_SUB_NUMSEG; SUM_LMUL] THEN
11542       REWRITE_TAC[SUM_BERNSTEIN; REAL_MUL_RID; REAL_LE_REFL];
11543       ALL_TAC] THEN
11544     W(MP_TAC o PART_MATCH lhand SUM_ABS_NUMSEG o lhand o snd) THEN
11545     MATCH_MP_TAC(REAL_ARITH `a <= b ==> x <= a ==> x <= b`) THEN
11546     REWRITE_TAC[REAL_ABS_MUL] THEN
11547     ASM_SIMP_TAC[BERNSTEIN_POS; REAL_ARITH `&0 <= x ==> abs x = x`] THEN
11548     MATCH_MP_TAC REAL_LE_TRANS THEN
11549     EXISTS_TAC
11550      `sum(0..n) (\k. (e / &2 + &2 * M / d pow 2 * (x - &k / &n) pow 2) *
11551                      bernstein n k x)` THEN
11552     CONJ_TAC THENL
11553      [MATCH_MP_TAC SUM_LE_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
11554       REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_RMUL THEN
11555       ASM_SIMP_TAC[BERNSTEIN_POS] THEN
11556       SUBGOAL_THEN `&0 <= &k / &n /\ &k / &n <= &1` STRIP_ASSUME_TAC THENL
11557        [ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_OF_NUM_LT] THEN
11558         ASM_REWRITE_TAC[REAL_OF_NUM_MUL; REAL_OF_NUM_LE; MULT_CLAUSES];
11559         ALL_TAC] THEN
11560       DISJ_CASES_TAC(REAL_ARITH
11561         `abs(x - &k / &n) < d \/ d <= abs(x - &k / &n)`)
11562       THENL
11563        [MATCH_MP_TAC(REAL_ARITH `x < e /\ &0 <= d ==> x <= e + d`) THEN
11564         ASM_SIMP_TAC[REAL_ARITH `&0 <= &2 * x <=> &0 <= x`] THEN
11565         ASM_SIMP_TAC[REAL_LE_MUL; REAL_LE_DIV; REAL_POW_2; REAL_LE_SQUARE;
11566                      REAL_LT_IMP_LE];
11567         MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= d ==> x <= e / &2 + d`) THEN
11568         ASM_REWRITE_TAC[] THEN
11569         MATCH_MP_TAC(REAL_ARITH
11570          `abs(x) <= M /\ abs(y) <= M /\ M * &1 <= M * b / d
11571           ==> abs(x - y) <= &2 * M / d * b`) THEN
11572         ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_POW_LT; REAL_LE_RDIV_EQ] THEN
11573         REWRITE_TAC[REAL_MUL_LID; GSYM REAL_LE_SQUARE_ABS] THEN
11574         ASM_REAL_ARITH_TAC];
11575       REWRITE_TAC[REAL_ADD_RDISTRIB; SUM_ADD_NUMSEG; SUM_LMUL] THEN
11576       REWRITE_TAC[SUM_BERNSTEIN; REAL_MUL_RID; REAL_LE_LADD] THEN
11577       REWRITE_TAC[GSYM REAL_MUL_ASSOC; SUM_LMUL] THEN
11578       REWRITE_TAC[real_div; REAL_INV_MUL; GSYM REAL_MUL_ASSOC] THEN
11579       ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_OF_NUM_LT; ARITH; REAL_POW_LT;
11580                    REAL_LT_INV_EQ] THEN
11581       MATCH_MP_TAC REAL_LE_LCANCEL_IMP THEN EXISTS_TAC `&n pow 2` THEN
11582       ASM_SIMP_TAC[GSYM SUM_LMUL; REAL_POW_LT; REAL_OF_NUM_LT; REAL_FIELD
11583         `&0 < n ==> n pow 2 * inv(n) = n`] THEN
11584       REWRITE_TAC[REAL_MUL_ASSOC; GSYM REAL_POW_MUL] THEN
11585       ASM_SIMP_TAC[REAL_OF_NUM_LT; REAL_FIELD
11586         `&0 < n ==> n * (x - k * inv n) = n * x - k`] THEN
11587       ONCE_REWRITE_TAC[REAL_ARITH `(x - y:real) pow 2 = (y - x) pow 2`] THEN
11588       REWRITE_TAC[BERNSTEIN_LEMMA; REAL_ARITH
11589         `&n * x <= &n <=> &n * x <= &n * &1 * &1`] THEN
11590       MATCH_MP_TAC REAL_LE_LMUL THEN REWRITE_TAC[REAL_POS] THEN
11591       MATCH_MP_TAC REAL_LE_MUL2 THEN ASM_REAL_ARITH_TAC];
11592     MP_TAC(ISPEC `(e / &4 * d pow 2) / (&2 * M)` REAL_ARCH_INV) THEN
11593     ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_OF_NUM_LT; ARITH; REAL_LT_MUL] THEN
11594     ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ; REAL_POW_LT; REAL_MUL_LZERO] THEN
11595     REWRITE_TAC[real_div; REAL_MUL_LZERO] THEN
11596     REWRITE_TAC[REAL_ARITH `(x * &2 * m) * i = (&2 * m) * (i * x)`] THEN
11597     REWRITE_TAC[GSYM REAL_INV_MUL] THEN
11598     ASM_SIMP_TAC[GSYM real_div; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
11599     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
11600     MAP_EVERY X_GEN_TAC [`n:num`; `x:real`] THEN STRIP_TAC THEN
11601     FIRST_X_ASSUM(MP_TAC o SPECL [`n:num`; `x:real`]) THEN ASM_SIMP_TAC[] THEN
11602     ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
11603     MATCH_MP_TAC(REAL_ARITH
11604      `&0 < e /\ k < e / &4 ==> x <= e / &2 + k ==> x < e`) THEN
11605     ASM_SIMP_TAC[] THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
11606      `x < e ==> y <= x ==> y < e`)) THEN
11607     ASM_SIMP_TAC[real_div; REAL_LE_LMUL_EQ; REAL_LT_MUL;
11608                  REAL_OF_NUM_LT; ARITH] THEN
11609     MATCH_MP_TAC REAL_LE_INV2 THEN
11610     ASM_SIMP_TAC[REAL_LE_LMUL_EQ; REAL_LT_MUL; REAL_POW_LT;
11611                  REAL_OF_NUM_LT; LE_1; REAL_OF_NUM_LE]]);;
11612
11613 (* ------------------------------------------------------------------------- *)
11614 (* General Stone-Weierstrass theorem.                                        *)
11615 (* ------------------------------------------------------------------------- *)
11616
11617 let STONE_WEIERSTRASS_ALT = prove
11618  (`!(P:(real^N->real)->bool) (s:real^N->bool).
11619         compact s /\
11620         (!c. P(\x. c)) /\
11621         (!f g. P(f) /\ P(g) ==> P(\x. f x + g x)) /\
11622         (!f g. P(f) /\ P(g) ==> P(\x. f x * g x)) /\
11623         (!x y. x IN s /\ y IN s /\ ~(x = y)
11624                ==> ?f. (!x. x IN s ==> f real_continuous (at x within s)) /\
11625                        P(f) /\ ~(f x = f y))
11626         ==> !f e. (!x. x IN s ==> f real_continuous (at x within s)) /\ &0 < e
11627                   ==> ?g. P(g) /\ !x. x IN s ==> abs(f x - g x) < e`,
11628   REPEAT GEN_TAC THEN STRIP_TAC THEN MAP_EVERY ABBREV_TAC
11629    [`C = \f. !x:real^N. x IN s ==> f real_continuous at x within s`;
11630     `A = \f. C f /\
11631              !e. &0 < e
11632                ==> ?g. P(g) /\ !x:real^N. x IN s ==> abs(f x - g x) < e`] THEN
11633   SUBGOAL_THEN `!f:real^N->real. C(f) ==> A(f)` MP_TAC THENL
11634    [ALL_TAC; MAP_EVERY EXPAND_TAC ["A"; "C"] THEN SIMP_TAC[]] THEN
11635   SUBGOAL_THEN `!c:real. A(\x:real^N. c)` (LABEL_TAC "const") THENL
11636    [MAP_EVERY EXPAND_TAC ["A"; "C"] THEN X_GEN_TAC `c:real` THEN
11637     ASM_REWRITE_TAC[REAL_CONTINUOUS_CONST] THEN X_GEN_TAC `e:real` THEN
11638     DISCH_TAC THEN EXISTS_TAC `(\x. c):real^N->real` THEN
11639     ASM_REWRITE_TAC[REAL_SUB_REFL; REAL_ABS_0];
11640     ALL_TAC] THEN
11641   SUBGOAL_THEN `!f g:real^N->real. A(f) /\ A(g) ==> A(\x. f x + g x)`
11642   (LABEL_TAC "add") THENL
11643    [MAP_EVERY EXPAND_TAC ["A"; "C"] THEN SIMP_TAC[REAL_CONTINUOUS_ADD] THEN
11644     MAP_EVERY X_GEN_TAC [`f:real^N->real`; `g:real^N->real`] THEN
11645     DISCH_THEN(fun th -> REPEAT STRIP_TAC THEN MP_TAC th) THEN
11646     DISCH_THEN(CONJUNCTS_THEN (MP_TAC o SPEC `e / &2` o CONJUNCT2)) THEN
11647     ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN
11648     X_GEN_TAC `g':real^N->real` THEN STRIP_TAC THEN
11649     X_GEN_TAC `f':real^N->real` THEN STRIP_TAC THEN
11650     EXISTS_TAC `(\x. f' x + g' x):real^N->real` THEN
11651     ASM_SIMP_TAC[REAL_ARITH
11652      `abs(f - f') < e / &2 /\ abs(g - g') < e / &2
11653       ==> abs((f + g) - (f' + g')) < e`];
11654     ALL_TAC] THEN
11655   SUBGOAL_THEN `!f:real^N->real. A(f) ==> C(f)` (LABEL_TAC "AC") THENL
11656    [EXPAND_TAC "A" THEN SIMP_TAC[]; ALL_TAC] THEN
11657   SUBGOAL_THEN `!f:real^N->real. C(f) ==> real_bounded(IMAGE f s)`
11658   (LABEL_TAC "bound") THENL
11659    [GEN_TAC THEN EXPAND_TAC "C" THEN
11660     REWRITE_TAC[REAL_BOUNDED; GSYM IMAGE_o] THEN
11661     REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1] THEN
11662     REWRITE_TAC[GSYM CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
11663     ASM_SIMP_TAC[COMPACT_IMP_BOUNDED; COMPACT_CONTINUOUS_IMAGE];
11664     ALL_TAC] THEN
11665   SUBGOAL_THEN `!f g:real^N->real. A(f) /\ A(g) ==> A(\x. f x * g x)`
11666   (LABEL_TAC "mul") THENL
11667    [MAP_EVERY X_GEN_TAC [`f:real^N->real`; `g:real^N->real`] THEN
11668     DISCH_THEN(fun th -> STRIP_ASSUME_TAC th THEN MP_TAC th) THEN
11669     MAP_EVERY EXPAND_TAC ["A"; "C"] THEN SIMP_TAC[REAL_CONTINUOUS_MUL] THEN
11670     REWRITE_TAC[IMP_CONJ] THEN
11671     MAP_EVERY (DISCH_THEN o LABEL_TAC) ["cf"; "af"; "cg"; "ag"] THEN
11672     SUBGOAL_THEN
11673      `real_bounded(IMAGE (f:real^N->real) s) /\
11674       real_bounded(IMAGE (g:real^N->real) s)`
11675     MP_TAC THENL
11676      [ASM_SIMP_TAC[]; REWRITE_TAC[REAL_BOUNDED_POS_LT; FORALL_IN_IMAGE]] THEN
11677     DISCH_THEN(CONJUNCTS_THEN2
11678      (X_CHOOSE_THEN `Bf:real` STRIP_ASSUME_TAC)
11679      (X_CHOOSE_THEN `Bg:real` STRIP_ASSUME_TAC)) THEN
11680     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11681     REMOVE_THEN "ag" (MP_TAC o SPEC `e / &2 / Bf`) THEN
11682     ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; LEFT_IMP_EXISTS_THM] THEN
11683     X_GEN_TAC `g':real^N->real` THEN STRIP_TAC THEN
11684     REMOVE_THEN "af" (MP_TAC o SPEC `e / &2 / (Bg + e / &2 / Bf)`) THEN
11685     ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; REAL_LT_ADD] THEN
11686     DISCH_THEN(X_CHOOSE_THEN `f':real^N->real` STRIP_ASSUME_TAC) THEN
11687     EXISTS_TAC `(\x. f'(x) * g'(x)):real^N->real` THEN
11688     ASM_SIMP_TAC[REAL_ARITH
11689      `f * g - f' * g':real = f * (g - g') + g' * (f - f')`] THEN
11690     X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
11691     SUBGOAL_THEN `e = Bf * e / &2 / Bf +
11692                       (Bg + e / &2 / Bf) * e / &2 / (Bg + e / &2 / Bf)`
11693     SUBST1_TAC THENL
11694      [MATCH_MP_TAC(REAL_ARITH `a = e / &2 /\ b = e / &2 ==> e = a + b`) THEN
11695       CONJ_TAC THEN MAP_EVERY MATCH_MP_TAC [REAL_DIV_LMUL; REAL_LT_IMP_NZ] THEN
11696       ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_ADD; REAL_HALF];
11697       MATCH_MP_TAC(REAL_ARITH
11698        `abs a < c /\ abs b < d ==> abs(a + b) < c + d`) THEN
11699       REWRITE_TAC[REAL_ABS_MUL] THEN CONJ_TAC THEN
11700       MATCH_MP_TAC REAL_LT_MUL2 THEN ASM_SIMP_TAC[REAL_ABS_POS] THEN
11701       MATCH_MP_TAC(REAL_ARITH
11702        `!g. abs(g) < Bg /\ abs(g - g') < e ==> abs(g') < Bg + e`) THEN
11703       EXISTS_TAC `(g:real^N->real) x` THEN ASM_SIMP_TAC[]];
11704     ALL_TAC] THEN
11705   SUBGOAL_THEN
11706    `!x y. x IN s /\ y IN s /\ ~(x = y)
11707           ==> ?f:real^N->real. A(f) /\ ~(f x = f y)`
11708   (LABEL_TAC "sep") THENL
11709    [MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
11710     FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN
11711     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN
11712     MAP_EVERY EXPAND_TAC ["A"; "C"] THEN
11713     ASM_MESON_TAC[REAL_SUB_REFL; REAL_ABS_0];
11714     ALL_TAC] THEN
11715   SUBGOAL_THEN `!f. A(f) ==> A(\x:real^N. abs(f x))` (LABEL_TAC "abs") THENL
11716    [SUBGOAL_THEN `!f. A(f) /\ (!x. x IN s ==> abs(f x) <= &1 / &4)
11717                       ==> A(\x:real^N. abs(f x))`
11718     ASSUME_TAC THENL
11719      [ALL_TAC;
11720       REPEAT STRIP_TAC THEN
11721       SUBGOAL_THEN `real_bounded(IMAGE (f:real^N->real) s)` MP_TAC THENL
11722        [ASM_SIMP_TAC[]; REWRITE_TAC[REAL_BOUNDED_POS_LT; FORALL_IN_IMAGE]] THEN
11723       DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
11724       SUBGOAL_THEN `A(\x:real^N. (&4 * B) * abs(inv(&4 * B) * f x)):bool`
11725       MP_TAC THENL
11726        [USE_THEN "mul" MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
11727         FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[REAL_ABS_MUL] THEN
11728         ASM_SIMP_TAC[REAL_ARITH `&0 < B ==> abs(B) = B`;
11729                      REAL_LT_INV_EQ; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN
11730         ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
11731         ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ; REAL_LT_MUL;
11732                      REAL_OF_NUM_LT; ARITH; REAL_MUL_ASSOC] THEN
11733         CONV_TAC REAL_RAT_REDUCE_CONV THEN
11734         ASM_SIMP_TAC[REAL_MUL_LID; REAL_LT_IMP_LE];
11735         ASM_SIMP_TAC[REAL_ABS_MUL; REAL_ARITH `&0 < B ==> abs(B) = B`;
11736                      REAL_LT_INV_EQ; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN
11737         ASM_SIMP_TAC[REAL_MUL_ASSOC; REAL_MUL_RINV; REAL_MUL_LID;
11738                      REAL_ARITH `&0 < B ==> ~(&4 * B = &0)`]]] THEN
11739     X_GEN_TAC `f:real^N->real` THEN MAP_EVERY EXPAND_TAC ["A"; "C"] THEN
11740     DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THENL
11741      [DISCH_THEN(MP_TAC o CONJUNCT1 o CONJUNCT1) THEN
11742       MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
11743       REWRITE_TAC[] THEN
11744       MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT; o_DEF]
11745         REAL_CONTINUOUS_WITHIN_COMPOSE) THEN
11746       REWRITE_TAC[real_continuous_withinreal] THEN
11747       MESON_TAC[ARITH_RULE `abs(x - y) < d ==> abs(abs x - abs y) < d`];
11748       ALL_TAC] THEN
11749     DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
11750     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
11751     DISCH_THEN(fun t -> X_GEN_TAC `e:real` THEN DISCH_TAC THEN MP_TAC t) THEN
11752     DISCH_THEN(MP_TAC o SPEC `min (e / &2) (&1 / &4)`) THEN
11753     ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
11754     REWRITE_TAC[REAL_LT_MIN; FORALL_AND_THM;
11755                 TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN
11756     DISCH_THEN(X_CHOOSE_THEN `p:real^N->real` STRIP_ASSUME_TAC) THEN
11757     MP_TAC(ISPECL [`\x. abs(x - &1 / &2)`; `e / &2`]
11758      BERNSTEIN_WEIERSTRASS) THEN
11759     REWRITE_TAC[] THEN ANTS_TAC THENL
11760      [ASM_REWRITE_TAC[real_continuous_on; REAL_HALF] THEN
11761       MESON_TAC[ARITH_RULE
11762        `abs(x - y) < d ==> abs(abs(x - a) - abs(y - a)) < d`];
11763       ALL_TAC] THEN
11764     DISCH_THEN(X_CHOOSE_THEN `n:num` (MP_TAC o SPEC `n:num`)) THEN
11765     REWRITE_TAC[LE_REFL] THEN DISCH_TAC THEN
11766     EXISTS_TAC `\x:real^N. sum(0..n) (\k. abs(&k / &n - &1 / &2) *
11767                                           bernstein n k (&1 / &2 + p x))` THEN
11768     REWRITE_TAC[] THEN CONJ_TAC THENL
11769      [SUBGOAL_THEN
11770        `!m c z. P(\x:real^N.
11771             sum(0..m) (\k. c k * bernstein (z m) k (&1 / &2 + p x)))`
11772        (fun th -> REWRITE_TAC[th]) THEN
11773       SUBGOAL_THEN
11774        `!m k. P(\x:real^N. bernstein m k (&1 / &2 + p x))`
11775       ASSUME_TAC THENL
11776        [ALL_TAC; INDUCT_TAC THEN ASM_SIMP_TAC[SUM_CLAUSES_NUMSEG; LE_0]] THEN
11777       REPEAT GEN_TAC THEN REWRITE_TAC[bernstein] THEN
11778       REWRITE_TAC[REAL_ARITH `&1 - (&1 / &2 + p) = &1 / &2 + -- &1 * p`] THEN
11779       REPEAT(FIRST_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]) THEN
11780       SUBGOAL_THEN
11781        `!f:real^N->real k. P(f) ==> P(\x. f(x) pow k)`
11782        (fun th -> ASM_SIMP_TAC[th]) THEN
11783       GEN_TAC THEN INDUCT_TAC THEN ASM_SIMP_TAC[real_pow];
11784       REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH
11785        `!p. abs(abs(p x) - s) < e / &2 /\
11786             abs(f x - p x) < e / &2
11787             ==> abs(abs(f x) - s) < e`) THEN
11788       EXISTS_TAC `p:real^N->real` THEN ASM_SIMP_TAC[] THEN
11789       GEN_REWRITE_TAC (PAT_CONV `\x. abs(abs x - a) < e`)
11790         [REAL_ARITH `x = (&1 / &2 + x) - &1 / &2`] THEN
11791       FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN
11792       MATCH_MP_TAC(REAL_ARITH
11793        `!f. abs(f) <= &1 / &4 /\ abs(f - p) < &1 / &4
11794             ==> &0 <= &1 / &2 + p /\ &1 / &2 + p <= &1`) THEN
11795       EXISTS_TAC `(f:real^N->real) x` THEN ASM_SIMP_TAC[]];
11796     ALL_TAC] THEN
11797   SUBGOAL_THEN `!f:real^N->real g. A(f) /\ A(g) ==> A(\x. max (f x) (g x))`
11798   (LABEL_TAC "max") THENL
11799    [REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_ARITH
11800      `max a b = inv(&2) * (a + b + abs(a + -- &1 * b))`] THEN
11801     REPEAT(FIRST_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[]);
11802     ALL_TAC] THEN
11803   SUBGOAL_THEN `!f:real^N->real g. A(f) /\ A(g) ==> A(\x. min (f x) (g x))`
11804   (LABEL_TAC "min") THENL
11805    [ASM_SIMP_TAC[REAL_ARITH `min a b = -- &1 * (max(-- &1 * a) (-- &1 * b))`];
11806     ALL_TAC] THEN
11807   SUBGOAL_THEN
11808    `!t. FINITE t /\ (!f. f IN t ==> A(f)) ==> A(\x:real^N. sup {f(x) | f IN t})`
11809   (LABEL_TAC "sup") THENL
11810    [REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
11811     ASM_SIMP_TAC[FORALL_IN_INSERT; SIMPLE_IMAGE; IMAGE_CLAUSES] THEN
11812     ASM_SIMP_TAC[SUP_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
11813     MAP_EVERY X_GEN_TAC [`f:real^N->real`; `t:(real^N->real)->bool`] THEN
11814     ASM_CASES_TAC `t:(real^N->real)->bool = {}` THEN ASM_SIMP_TAC[ETA_AX];
11815     ALL_TAC] THEN
11816   SUBGOAL_THEN
11817    `!t. FINITE t /\ (!f. f IN t ==> A(f)) ==> A(\x:real^N. inf {f(x) | f IN t})`
11818   (LABEL_TAC "inf") THENL
11819    [REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
11820     ASM_SIMP_TAC[FORALL_IN_INSERT; SIMPLE_IMAGE; IMAGE_CLAUSES] THEN
11821     ASM_SIMP_TAC[INF_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
11822     MAP_EVERY X_GEN_TAC [`f:real^N->real`; `t:(real^N->real)->bool`] THEN
11823     ASM_CASES_TAC `t:(real^N->real)->bool = {}` THEN ASM_SIMP_TAC[ETA_AX];
11824     ALL_TAC] THEN
11825   SUBGOAL_THEN
11826    `!f:real^N->real e.
11827       C(f) /\ &0 < e ==> ?g. A(g) /\ !x. x IN s ==> abs(f x - g x) < e`
11828   ASSUME_TAC THENL
11829    [ALL_TAC;
11830     X_GEN_TAC `f:real^N->real` THEN DISCH_TAC THEN EXPAND_TAC "A" THEN
11831     CONJ_TAC THENL [FIRST_X_ASSUM ACCEPT_TAC; ALL_TAC] THEN
11832     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11833     FIRST_X_ASSUM(MP_TAC o SPECL [`f:real^N->real`; `e / &2`]) THEN
11834     ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN
11835     X_GEN_TAC `h:real^N->real` THEN EXPAND_TAC "A" THEN
11836     DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
11837     DISCH_THEN(MP_TAC o SPEC `e / &2` o CONJUNCT2) THEN
11838     ASM_REWRITE_TAC[REAL_HALF] THEN MATCH_MP_TAC MONO_EXISTS THEN
11839     ASM_MESON_TAC[REAL_ARITH
11840      `abs(f - h) < e / &2 /\ abs(h - g) < e / &2 ==> abs(f - g) < e`]] THEN
11841   MAP_EVERY X_GEN_TAC [`f:real^N->real`; `e:real`] THEN EXPAND_TAC "C" THEN
11842   STRIP_TAC THEN
11843   SUBGOAL_THEN
11844    `!x y. x IN s /\ y IN s
11845           ==> ?h:real^N->real. A(h) /\ h(x) = f(x) /\ h(y) = f(y)`
11846   MP_TAC THENL
11847    [REPEAT STRIP_TAC THEN ASM_CASES_TAC `y:real^N = x` THENL
11848      [EXISTS_TAC `\z:real^N. (f:real^N->real) x` THEN ASM_SIMP_TAC[];
11849       SUBGOAL_THEN `?h:real^N->real. A(h) /\ ~(h x = h y)`
11850       STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
11851       EXISTS_TAC `\z. (f y - f x) / (h y - h x) * (h:real^N->real)(z) +
11852                       (f x - (f y - f x) / (h y - h x) * h(x))` THEN
11853       ASM_SIMP_TAC[] THEN
11854       UNDISCH_TAC `~((h:real^N->real) x = h y)` THEN CONV_TAC REAL_FIELD];
11855       ALL_TAC] THEN
11856   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
11857   REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
11858   X_GEN_TAC `f2:real^N->real^N->real^N->real` THEN DISCH_TAC THEN
11859   ABBREV_TAC `G = \x y.
11860     {z | z IN s /\ (f2:real^N->real^N->real^N->real) x y z < f(z) + e}` THEN
11861   SUBGOAL_THEN `!x y:real^N. x IN s /\ y IN s ==> x IN G x y /\ y IN G x y`
11862   ASSUME_TAC THENL
11863    [EXPAND_TAC "G" THEN REWRITE_TAC[IN_ELIM_THM] THEN
11864     ASM_SIMP_TAC[REAL_LT_ADDR];
11865     ALL_TAC] THEN
11866   SUBGOAL_THEN
11867    `!x. x IN s ==> ?f1. A(f1) /\ f1 x = f x /\
11868                         !y:real^N. y IN s ==> f1 y < f y + e`
11869   MP_TAC THENL
11870    [REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o
11871      GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN
11872     DISCH_THEN(MP_TAC o SPEC
11873      `{(G:real^N->real^N->real^N->bool) x y | y IN s}`) THEN
11874     REWRITE_TAC[SIMPLE_IMAGE; UNIONS_IMAGE; FORALL_IN_IMAGE; ETA_AX] THEN
11875     ANTS_TAC THENL
11876      [CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
11877       EXPAND_TAC "G" THEN REWRITE_TAC[] THEN X_GEN_TAC `w:real^N` THEN
11878       DISCH_TAC THEN
11879       MP_TAC(ISPECL [`lift o (\z:real^N. f2 (x:real^N) (w:real^N) z - f z)`;
11880                      `s:real^N->bool`;
11881                      `{x:real^1 | x$1 < e}`] CONTINUOUS_OPEN_IN_PREIMAGE) THEN
11882       REWRITE_TAC[OPEN_HALFSPACE_COMPONENT_LT; IN_ELIM_THM] THEN
11883       REWRITE_TAC[GSYM drop; LIFT_DROP; o_DEF] THEN
11884       REWRITE_TAC[LIFT_SUB; GSYM REAL_CONTINUOUS_CONTINUOUS1;
11885                   REAL_ARITH `x < y + e <=> x - y < e`] THEN
11886       DISCH_THEN MATCH_MP_TAC THEN MATCH_MP_TAC CONTINUOUS_ON_SUB THEN
11887       ONCE_REWRITE_TAC[GSYM o_DEF] THEN
11888       REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
11889       REWRITE_TAC[GSYM REAL_CONTINUOUS_CONTINUOUS1; ETA_AX] THEN
11890       ASM_MESON_TAC[];
11891       ALL_TAC] THEN
11892     ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN
11893     REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE; UNIONS_IMAGE] THEN
11894     DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
11895     EXISTS_TAC `\z:real^N. inf {f2 (x:real^N) (y:real^N) z | y IN t}` THEN
11896     REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
11897      [GEN_REWRITE_TAC RAND_CONV [REAL_ARITH `x = min x x`] THEN
11898       REWRITE_TAC[REAL_MIN_INF; INSERT_AC] THEN AP_TERM_TAC THEN ASM SET_TAC[];
11899       REMOVE_THEN "inf" (MP_TAC o SPEC
11900        `IMAGE (\y z. (f2:real^N->real^N->real^N->real) x y z) t`) THEN
11901       ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN
11902       REWRITE_TAC[SIMPLE_IMAGE; ETA_AX] THEN
11903       ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
11904       REWRITE_TAC[GSYM IMAGE_o; o_DEF];
11905       SUBGOAL_THEN `~(t:real^N->bool = {})` ASSUME_TAC THENL
11906        [ASM SET_TAC[]; ALL_TAC] THEN
11907       ASM_SIMP_TAC[REAL_INF_LT_FINITE; SIMPLE_IMAGE;
11908                    FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
11909       REWRITE_TAC[EXISTS_IN_IMAGE] THEN
11910       X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
11911       UNDISCH_TAC
11912        `s SUBSET {y:real^N | ?z:real^N. z IN t /\ y IN G (x:real^N) z}` THEN
11913       REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
11914       DISCH_THEN(MP_TAC o SPEC `y:real^N`) THEN ASM_REWRITE_TAC[] THEN
11915       EXPAND_TAC "G" THEN REWRITE_TAC[IN_ELIM_THM] THEN ASM_REWRITE_TAC[]];
11916     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
11917      [RIGHT_IMP_EXISTS_THM] THEN
11918     REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
11919     X_GEN_TAC `f1:real^N->real^N->real` THEN DISCH_TAC] THEN
11920   ABBREV_TAC `H = \x:real^N. {z:real^N | z IN s /\ f z - e < f1 x z}` THEN
11921   SUBGOAL_THEN `!x:real^N. x IN s ==> x IN (H x)` ASSUME_TAC THENL
11922    [EXPAND_TAC "H" THEN REWRITE_TAC[IN_ELIM_THM] THEN
11923     ASM_SIMP_TAC[REAL_ARITH `x - e < x <=> &0 < e`];
11924     ALL_TAC] THEN
11925   FIRST_ASSUM(MP_TAC o
11926   GEN_REWRITE_RULE I [COMPACT_EQ_HEINE_BOREL_SUBTOPOLOGY]) THEN
11927   DISCH_THEN(MP_TAC o SPEC
11928    `{(H:real^N->real^N->bool) x | x IN s}`) THEN
11929   REWRITE_TAC[SIMPLE_IMAGE; UNIONS_IMAGE; FORALL_IN_IMAGE; ETA_AX] THEN
11930   ANTS_TAC THENL
11931    [CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN EXPAND_TAC "H" THEN
11932     REWRITE_TAC[] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
11933     MP_TAC(ISPECL [`lift o (\z:real^N. f z - f1 (x:real^N) z)`;
11934                    `s:real^N->bool`;
11935                    `{x:real^1 | x$1 < e}`] CONTINUOUS_OPEN_IN_PREIMAGE) THEN
11936     REWRITE_TAC[OPEN_HALFSPACE_COMPONENT_LT; IN_ELIM_THM] THEN
11937     REWRITE_TAC[GSYM drop; LIFT_DROP; o_DEF] THEN
11938     GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV)
11939      [REAL_ARITH `x - y < z <=> x - z < y`] THEN
11940     DISCH_THEN MATCH_MP_TAC THEN
11941     REWRITE_TAC[LIFT_SUB; GSYM REAL_CONTINUOUS_CONTINUOUS1;
11942                 REAL_ARITH `x < y + e <=> x - y < e`] THEN
11943     MATCH_MP_TAC CONTINUOUS_ON_SUB THEN
11944     ONCE_REWRITE_TAC[GSYM o_DEF] THEN
11945     REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
11946     REWRITE_TAC[GSYM REAL_CONTINUOUS_CONTINUOUS1; ETA_AX] THEN
11947     ASM_MESON_TAC[];
11948     ALL_TAC] THEN
11949   ONCE_REWRITE_TAC[TAUT `a /\ b /\ c <=> b /\ a /\ c`] THEN
11950   REWRITE_TAC[EXISTS_FINITE_SUBSET_IMAGE; UNIONS_IMAGE] THEN
11951   DISCH_THEN(X_CHOOSE_THEN `t:real^N->bool` STRIP_ASSUME_TAC) THEN
11952   EXISTS_TAC `\z:real^N. sup {f1 (x:real^N) z | x IN t}` THEN
11953   REWRITE_TAC[] THEN CONJ_TAC THENL
11954    [REMOVE_THEN "sup" (MP_TAC o SPEC `IMAGE (f1:real^N->real^N->real) t`) THEN
11955     ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE] THEN
11956     REWRITE_TAC[SIMPLE_IMAGE; ETA_AX] THEN
11957     ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
11958     REWRITE_TAC[GSYM IMAGE_o; o_DEF];
11959     ALL_TAC] THEN
11960   X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
11961   SUBGOAL_THEN `~(t:real^N->bool = {})` ASSUME_TAC THENL
11962    [ASM SET_TAC[]; ALL_TAC] THEN
11963   REWRITE_TAC[SIMPLE_IMAGE; REAL_ARITH
11964    `abs(f - s) < e <=> f - e < s /\ s < f + e`] THEN
11965   ASM_SIMP_TAC[REAL_SUP_LT_FINITE; REAL_LT_SUP_FINITE;
11966                FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
11967   REWRITE_TAC[EXISTS_IN_IMAGE; FORALL_IN_IMAGE] THEN
11968   CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
11969   UNDISCH_TAC `s SUBSET {y:real^N | ?x:real^N. x IN t /\ y IN H x}` THEN
11970   REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
11971   DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
11972   EXPAND_TAC "H" THEN REWRITE_TAC[IN_ELIM_THM] THEN ASM_REWRITE_TAC[]);;
11973
11974 let STONE_WEIERSTRASS = prove
11975  (`!(P:(real^N->real)->bool) (s:real^N->bool).
11976         compact s /\
11977         (!f. P(f) ==> !x. x IN s ==> f real_continuous (at x within s)) /\
11978         (!c. P(\x. c)) /\
11979         (!f g. P(f) /\ P(g) ==> P(\x. f x + g x)) /\
11980         (!f g. P(f) /\ P(g) ==> P(\x. f x * g x)) /\
11981         (!x y. x IN s /\ y IN s /\ ~(x = y) ==> ?f. P(f) /\ ~(f x = f y))
11982         ==> !f e. (!x. x IN s ==> f real_continuous (at x within s)) /\ &0 < e
11983                   ==> ?g. P(g) /\ !x. x IN s ==> abs(f x - g x) < e`,
11984   REPEAT GEN_TAC THEN STRIP_TAC THEN
11985   MATCH_MP_TAC STONE_WEIERSTRASS_ALT THEN ASM_SIMP_TAC[] THEN
11986   MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
11987   FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN
11988   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN ASM_MESON_TAC[]);;
11989
11990 (* ------------------------------------------------------------------------- *)
11991 (* Real and complex versions of Stone-Weierstrass theorem.                   *)
11992 (* ------------------------------------------------------------------------- *)
11993
11994 let REAL_STONE_WEIERSTRASS_ALT = prove
11995  (`!P s. real_compact s /\
11996          (!c. P (\x. c)) /\
11997          (!f g. P f /\ P g ==> P (\x. f x + g x)) /\
11998          (!f g. P f /\ P g ==> P (\x. f x * g x)) /\
11999          (!x y. x IN s /\ y IN s /\ ~(x = y)
12000                 ==> ?f. f real_continuous_on s /\ P f /\ ~(f x = f y))
12001          ==> !f e. f real_continuous_on s /\ &0 < e
12002                    ==> ?g. P g /\ !x. x IN s ==> abs(f x - g x) < e`,
12003   REPEAT STRIP_TAC THEN
12004   MP_TAC(ISPECL
12005    [`\f. (P:(real->real)->bool)(f o lift)`;
12006     `IMAGE lift s`] STONE_WEIERSTRASS_ALT) THEN
12007   ASM_SIMP_TAC[GSYM real_compact; o_DEF] THEN
12008   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
12009   REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN ANTS_TAC THENL
12010    [X_GEN_TAC `x:real` THEN DISCH_TAC THEN
12011     X_GEN_TAC `y:real` THEN REWRITE_TAC[LIFT_EQ] THEN STRIP_TAC THEN
12012     FIRST_X_ASSUM(MP_TAC o SPECL [`x:real`; `y:real`]) THEN
12013     ASM_REWRITE_TAC[] THEN
12014     DISCH_THEN(X_CHOOSE_THEN `g:real->real` STRIP_ASSUME_TAC) THEN
12015     EXISTS_TAC `(g:real->real) o drop` THEN
12016     ASM_REWRITE_TAC[o_THM; LIFT_DROP; ETA_AX] THEN
12017     UNDISCH_TAC `g real_continuous_on s` THEN
12018     REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
12019     REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS_WITHINREAL] THEN
12020     REWRITE_TAC[real_continuous_within; continuous_within] THEN
12021     REWRITE_TAC[o_THM; LIFT_DROP; DIST_LIFT];
12022     DISCH_THEN(MP_TAC o SPEC `(f:real->real) o drop`) THEN ANTS_TAC THENL
12023      [UNDISCH_TAC `f real_continuous_on s` THEN
12024       REWRITE_TAC[REAL_CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
12025       REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS_WITHINREAL] THEN
12026       REWRITE_TAC[real_continuous_within; continuous_within] THEN
12027       REWRITE_TAC[o_THM; LIFT_DROP; DIST_LIFT];
12028       DISCH_THEN(MP_TAC o SPEC `e:real`) THEN
12029       ASM_REWRITE_TAC[o_DEF; LIFT_DROP] THEN
12030       DISCH_THEN(X_CHOOSE_THEN `g:real^1->real` STRIP_ASSUME_TAC) THEN
12031       EXISTS_TAC `(g:real^1->real) o lift` THEN ASM_REWRITE_TAC[o_DEF]]]);;
12032
12033 let REAL_STONE_WEIERSTRASS = prove
12034  (`!P s. real_compact s /\
12035          (!f. P f ==> f real_continuous_on s) /\
12036          (!c. P (\x. c)) /\
12037          (!f g. P f /\ P g ==> P (\x. f x + g x)) /\
12038          (!f g. P f /\ P g ==> P (\x. f x * g x)) /\
12039          (!x y. x IN s /\ y IN s /\ ~(x = y) ==> ?f. P f /\ ~(f x = f y))
12040          ==> !f e. f real_continuous_on s /\ &0 < e
12041                    ==> ?g. P g /\ !x. x IN s ==> abs(f x - g x) < e`,
12042   REPEAT GEN_TAC THEN STRIP_TAC THEN
12043   MATCH_MP_TAC REAL_STONE_WEIERSTRASS_ALT THEN ASM_SIMP_TAC[] THEN
12044   MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN STRIP_TAC THEN
12045   FIRST_X_ASSUM(MP_TAC o SPECL [`x:real`; `y:real`]) THEN
12046   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN ASM_MESON_TAC[]);;
12047
12048 let COMPLEX_STONE_WEIERSTRASS_ALT = prove
12049  (`!P s. compact s /\
12050          (!c. P (\x. c)) /\
12051          (!f. P f ==> P(\x. cnj(f x))) /\
12052          (!f g. P f /\ P g ==> P (\x. f x + g x)) /\
12053          (!f g. P f /\ P g ==> P (\x. f x * g x)) /\
12054          (!x y. x IN s /\ y IN s /\ ~(x = y)
12055                 ==> ?f. P f /\ f continuous_on s /\ ~(f x = f y))
12056          ==> !f:real^N->complex e.
12057                 f continuous_on s /\ &0 < e
12058                 ==> ?g. P g /\ !x. x IN s ==> norm(f x - g x) < e`,
12059   REPEAT GEN_TAC THEN STRIP_TAC THEN
12060   SUBGOAL_THEN `!f. P f ==> P(\x:real^N. Cx(Re(f x)))` ASSUME_TAC THENL
12061    [ASM_SIMP_TAC[CX_RE_CNJ; SIMPLE_COMPLEX_ARITH
12062      `x / Cx(&2) = inv(Cx(&2)) * x`];
12063     ALL_TAC] THEN
12064   SUBGOAL_THEN `!f. P f ==> P(\x:real^N. Cx(Im(f x)))` ASSUME_TAC THENL
12065    [ASM_SIMP_TAC[CX_IM_CNJ; SIMPLE_COMPLEX_ARITH
12066      `x - y = x + --Cx(&1) * y /\ x / Cx(&2) = inv(Cx(&2)) * x`] THEN
12067     REPEAT STRIP_TAC THEN REPEAT(FIRST_ASSUM MATCH_MP_TAC ORELSE CONJ_TAC) THEN
12068     ASM_SIMP_TAC[];
12069     ALL_TAC] THEN
12070   MP_TAC(ISPECL [`\x. x IN {Re o f | P (f:real^N->complex)}`; `s:real^N->bool`]
12071         STONE_WEIERSTRASS_ALT) THEN
12072   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
12073   REWRITE_TAC[EXISTS_IN_GSPEC; IMP_IMP; GSYM CONJ_ASSOC] THEN ANTS_TAC THENL
12074    [ASM_REWRITE_TAC[IMP_IMP; RIGHT_IMP_FORALL_THM; IN_ELIM_THM] THEN
12075     REPEAT CONJ_TAC THENL
12076      [X_GEN_TAC `c:real` THEN EXISTS_TAC `\x:real^N. Cx(c)` THEN
12077       ASM_REWRITE_TAC[FUN_EQ_THM; o_THM; RE_CX];
12078       MAP_EVERY X_GEN_TAC [`f:real^N->complex`; `g:real^N->complex`] THEN
12079       DISCH_TAC THEN EXISTS_TAC `(\x. f x + g x):real^N->complex` THEN
12080       ASM_SIMP_TAC[o_THM; RE_ADD; FUN_EQ_THM];
12081       MAP_EVERY X_GEN_TAC [`f:real^N->complex`; `g:real^N->complex`] THEN
12082       STRIP_TAC THEN
12083       EXISTS_TAC `\x:real^N. Cx(Re(f x)) * Cx(Re(g x))` THEN
12084       ASM_SIMP_TAC[FUN_EQ_THM; RE_CX; o_THM; RE_MUL_CX];
12085       MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
12086       FIRST_X_ASSUM(MP_TAC o SPECL  [`x:real^N`; `y:real^N`]) THEN
12087       ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
12088       X_GEN_TAC `f:real^N->complex` THEN
12089       REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
12090       GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [COMPLEX_EQ] THEN
12091       REWRITE_TAC[DE_MORGAN_THM] THEN STRIP_TAC THENL
12092        [EXISTS_TAC `\x:real^N. Re(f x)` THEN ASM_REWRITE_TAC[o_DEF] THEN
12093         CONJ_TAC THENL
12094          [ALL_TAC; EXISTS_TAC `f:real^N->complex` THEN ASM_REWRITE_TAC[]];
12095         EXISTS_TAC `\x:real^N. Im(f x)` THEN ASM_REWRITE_TAC[o_DEF] THEN
12096         CONJ_TAC THENL
12097          [ALL_TAC;
12098           EXISTS_TAC `\x:real^N. Cx(Im(f x))` THEN ASM_SIMP_TAC[RE_CX]]] THEN
12099       X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN REWRITE_TAC[GSYM o_DEF] THEN
12100       MATCH_MP_TAC REAL_CONTINUOUS_CONTINUOUS_WITHIN_COMPOSE THEN
12101       SIMP_TAC[REAL_CONTINUOUS_COMPLEX_COMPONENTS_AT;
12102                REAL_CONTINUOUS_AT_WITHIN] THEN
12103       ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]];
12104     DISCH_THEN(LABEL_TAC "*") THEN X_GEN_TAC `f:real^N->complex` THEN
12105     DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
12106     REMOVE_THEN "*"
12107      (fun th -> MP_TAC(ISPEC `Re o (f:real^N->complex)` th) THEN
12108                 MP_TAC(ISPEC `Im o (f:real^N->complex)` th)) THEN
12109     MATCH_MP_TAC(TAUT `(p1 /\ p2) /\ (q1 /\ q2 ==> r)
12110                        ==> (p1 ==> q1) ==> (p2 ==> q2) ==> r`) THEN
12111     CONJ_TAC THENL
12112      [CONJ_TAC THEN X_GEN_TAC `a:real^N` THEN DISCH_TAC THEN
12113       MATCH_MP_TAC REAL_CONTINUOUS_CONTINUOUS_WITHIN_COMPOSE THEN
12114       SIMP_TAC[REAL_CONTINUOUS_COMPLEX_COMPONENTS_AT;
12115                REAL_CONTINUOUS_AT_WITHIN] THEN
12116       ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN];
12117       ALL_TAC] THEN
12118     REWRITE_TAC[AND_FORALL_THM] THEN
12119     DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
12120     ASM_REWRITE_TAC[REAL_HALF; o_THM] THEN
12121     DISCH_THEN(CONJUNCTS_THEN2
12122      (X_CHOOSE_THEN `g:real^N->complex` STRIP_ASSUME_TAC)
12123      (X_CHOOSE_THEN `h:real^N->complex` STRIP_ASSUME_TAC)) THEN
12124     EXISTS_TAC `\x:real^N. Cx(Re(h x)) + ii * Cx(Re(g x))` THEN
12125     ASM_SIMP_TAC[] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
12126     GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o LAND_CONV) [COMPLEX_EXPAND] THEN
12127     MATCH_MP_TAC(NORM_ARITH
12128      `norm(x1 - x2) < e / &2 /\ norm(y1 - y2) < e / &2
12129       ==> norm((x1 + y1) - (x2 + y2)) < e`) THEN
12130     ASM_SIMP_TAC[GSYM CX_SUB; COMPLEX_NORM_CX; GSYM COMPLEX_SUB_LDISTRIB;
12131                  COMPLEX_NORM_MUL; COMPLEX_NORM_II; REAL_MUL_LID]]);;
12132
12133 let COMPLEX_STONE_WEIERSTRASS = prove
12134  (`!P s. compact s /\
12135          (!f. P f ==> f continuous_on s) /\
12136          (!c. P (\x. c)) /\
12137          (!f. P f ==> P(\x. cnj(f x))) /\
12138          (!f g. P f /\ P g ==> P (\x. f x + g x)) /\
12139          (!f g. P f /\ P g ==> P (\x. f x * g x)) /\
12140          (!x y. x IN s /\ y IN s /\ ~(x = y) ==> ?f. P f /\ ~(f x = f y))
12141          ==> !f:real^N->complex e.
12142                 f continuous_on s /\ &0 < e
12143                 ==> ?g. P g /\ !x. x IN s ==> norm(f x - g x) < e`,
12144   REPEAT GEN_TAC THEN STRIP_TAC THEN
12145   MATCH_MP_TAC COMPLEX_STONE_WEIERSTRASS_ALT THEN ASM_SIMP_TAC[] THEN
12146   MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
12147   FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN
12148   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN ASM_MESON_TAC[]);;
12149
12150 (* ------------------------------------------------------------------------- *)
12151 (* Stone-Weierstrass for R^n -> R polynomials.                               *)
12152 (* ------------------------------------------------------------------------- *)
12153
12154 let real_polynomial_function_RULES,
12155     real_polynomial_function_INDUCT,
12156     real_polynomial_function_CASES = new_inductive_definition
12157  `(!i. 1 <= i /\ i <= dimindex(:N)
12158        ==> real_polynomial_function(\x:real^N. x$i)) /\
12159   (!c. real_polynomial_function(\x:real^N. c)) /\
12160   (!f g. real_polynomial_function f /\ real_polynomial_function g
12161          ==> real_polynomial_function(\x:real^N. f x + g x)) /\
12162   (!f g. real_polynomial_function f /\ real_polynomial_function g
12163          ==> real_polynomial_function(\x:real^N. f x * g x))`;;
12164
12165 let REAL_CONTINUOUS_REAL_POLYMONIAL_FUNCTION = prove
12166  (`!f x:real^N.
12167         real_polynomial_function f ==> f real_continuous at x`,
12168   REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
12169   MATCH_MP_TAC real_polynomial_function_INDUCT THEN
12170   SIMP_TAC[REAL_CONTINUOUS_ADD; REAL_CONTINUOUS_MUL;
12171            REAL_CONTINUOUS_CONST; REAL_CONTINUOUS_AT_COMPONENT]);;
12172
12173 let STONE_WEIERSTRASS_REAL_POLYNOMIAL_FUNCTION = prove
12174  (`!f:real^N->real s e.
12175         compact s /\
12176         (!x. x IN s ==> f real_continuous at x within s) /\
12177         &0 < e
12178         ==> ?g. real_polynomial_function g /\
12179                 !x. x IN s ==> abs(f x - g x) < e`,
12180   REPEAT STRIP_TAC THEN
12181   MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
12182         STONE_WEIERSTRASS) THEN
12183   ASM_REWRITE_TAC[real_polynomial_function_RULES] THEN
12184   SIMP_TAC[REAL_CONTINUOUS_REAL_POLYMONIAL_FUNCTION;
12185            REAL_CONTINUOUS_AT_WITHIN] THEN
12186   MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN
12187   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
12188   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [CART_EQ] THEN
12189   REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN
12190   X_GEN_TAC `i:num` THEN STRIP_TAC THEN EXISTS_TAC `\x:real^N. x$i` THEN
12191   ASM_SIMP_TAC[real_polynomial_function_RULES]);;
12192
12193 (* ------------------------------------------------------------------------- *)
12194 (*  Stone-Weierstrass for real^M->real^N polynomials.                        *)
12195 (* ------------------------------------------------------------------------- *)
12196
12197 let vector_polynomial_function = new_definition
12198  `vector_polynomial_function (f:real^M->real^N) <=>
12199         !i. 1 <= i /\ i <= dimindex(:N)
12200             ==> real_polynomial_function(\x. f(x)$i)`;;
12201
12202 let REAL_POLYNOMIAL_FUNCTION_DROP = prove
12203  (`!f. real_polynomial_function(drop o f) <=> vector_polynomial_function f`,
12204   REWRITE_TAC[vector_polynomial_function; DIMINDEX_1; FORALL_1] THEN
12205   REWRITE_TAC[o_DEF; drop]);;
12206
12207 let VECTOR_POLYNOMIAL_FUNCTION_LIFT = prove
12208  (`!f. vector_polynomial_function(lift o f) <=> real_polynomial_function f`,
12209   REWRITE_TAC[GSYM REAL_POLYNOMIAL_FUNCTION_DROP; o_DEF; LIFT_DROP; ETA_AX]);;
12210
12211 let VECTOR_POLYNOMIAL_FUNCTION_CONST = prove
12212  (`!c. vector_polynomial_function(\x. c)`,
12213   SIMP_TAC[vector_polynomial_function; real_polynomial_function_RULES]);;
12214
12215 let VECTOR_POLYNOMIAL_FUNCTION_ID = prove
12216  (`vector_polynomial_function(\x. x)`,
12217   SIMP_TAC[vector_polynomial_function; real_polynomial_function_RULES]);;
12218
12219 let VECTOR_POLYNOMIAL_FUNCTION_COMPONENT = prove
12220  (`!f:real^M->real^N i.
12221         1 <= i /\ i <= dimindex(:N) /\ vector_polynomial_function f
12222         ==> vector_polynomial_function(\x. lift(f x$i))`,
12223   SIMP_TAC[vector_polynomial_function; FORALL_1; DIMINDEX_1; GSYM drop;
12224            LIFT_DROP]);;
12225
12226 let VECTOR_POLYNOMIAL_FUNCTION_ADD = prove
12227  (`!f g:real^M->real^N.
12228         vector_polynomial_function f /\ vector_polynomial_function g
12229         ==> vector_polynomial_function (\x. f x + g x)`,
12230
12231   REWRITE_TAC[vector_polynomial_function] THEN
12232   SIMP_TAC[VECTOR_ADD_COMPONENT; real_polynomial_function_RULES]);;
12233
12234 let VECTOR_POLYNOMIAL_FUNCTION_MUL = prove
12235  (`!f g:real^M->real^N.
12236         vector_polynomial_function(lift o f) /\ vector_polynomial_function g
12237         ==> vector_polynomial_function (\x. f x % g x)`,
12238   REWRITE_TAC[vector_polynomial_function; o_DEF; VECTOR_MUL_COMPONENT] THEN
12239   REWRITE_TAC[FORALL_1; DIMINDEX_1; GSYM drop; LIFT_DROP; ETA_AX] THEN
12240   SIMP_TAC[real_polynomial_function_RULES]);;
12241
12242 let VECTOR_POLYNOMIAL_FUNCTION_CMUL = prove
12243  (`!f:real^M->real^N c.
12244         vector_polynomial_function f
12245         ==> vector_polynomial_function (\x. c % f x)`,
12246   SIMP_TAC[VECTOR_POLYNOMIAL_FUNCTION_CONST; VECTOR_POLYNOMIAL_FUNCTION_MUL;
12247            ETA_AX; o_DEF]);;
12248
12249 let VECTOR_POLYNOMIAL_FUNCTION_NEG = prove
12250  (`!f:real^M->real^N.
12251         vector_polynomial_function f
12252         ==> vector_polynomial_function (\x. --(f x))`,
12253   REWRITE_TAC[VECTOR_ARITH `--x:real^N = --(&1) % x`] THEN
12254   REWRITE_TAC[VECTOR_POLYNOMIAL_FUNCTION_CMUL]);;
12255
12256 let VECTOR_POLYNOMIAL_FUNCTION_SUB = prove
12257  (`!f g:real^M->real^N.
12258         vector_polynomial_function f /\ vector_polynomial_function g
12259         ==> vector_polynomial_function (\x. f x - g x)`,
12260   SIMP_TAC[VECTOR_SUB; VECTOR_POLYNOMIAL_FUNCTION_ADD;
12261            VECTOR_POLYNOMIAL_FUNCTION_NEG]);;
12262
12263 let VECTOR_POLYNOMIAL_FUNCTION_VSUM = prove
12264  (`!f:real^M->A->real^N s.
12265         FINITE s /\ (!i. i IN s ==> vector_polynomial_function (\x. f x i))
12266         ==> vector_polynomial_function (\x. vsum s (f x))`,
12267   GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
12268   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
12269   SIMP_TAC[VSUM_CLAUSES; FORALL_IN_INSERT; VECTOR_POLYNOMIAL_FUNCTION_CONST;
12270            VECTOR_POLYNOMIAL_FUNCTION_ADD]);;
12271
12272 let REAL_VECTOR_POLYNOMIAL_FUNCTION_o = prove
12273  (`!f:real^M->real^N g.
12274         vector_polynomial_function f /\ real_polynomial_function g
12275         ==> real_polynomial_function(g o f)`,
12276   GEN_TAC THEN REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN DISCH_TAC THEN
12277   MATCH_MP_TAC real_polynomial_function_INDUCT THEN
12278   REWRITE_TAC[o_DEF; real_polynomial_function_RULES] THEN
12279   ASM_REWRITE_TAC[GSYM vector_polynomial_function]);;
12280
12281 let VECTOR_POLYNOMIAL_FUNCTION_o = prove
12282  (`!f:real^M->real^N g:real^N->real^P.
12283         vector_polynomial_function f /\ vector_polynomial_function g
12284         ==> vector_polynomial_function(g o f)`,
12285   REPEAT GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
12286   DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
12287     REAL_VECTOR_POLYNOMIAL_FUNCTION_o)) THEN
12288   SIMP_TAC[vector_polynomial_function; o_DEF]);;
12289
12290 let REAL_POLYNOMIAL_FUNCTION_1 = prove
12291  (`!f. real_polynomial_function f <=>
12292        ?a n. f = \x. sum(0..n) (\i. a i * drop x pow i)`,
12293   REWRITE_TAC[TAUT `(p <=> q) <=> (p ==> q) /\ (q ==> p)`] THEN
12294   REWRITE_TAC[FORALL_AND_THM] THEN CONJ_TAC THENL
12295    [MATCH_MP_TAC real_polynomial_function_INDUCT THEN
12296     REWRITE_TAC[DIMINDEX_1; FORALL_1; FUN_EQ_THM] THEN CONJ_TAC THENL
12297      [MAP_EVERY EXISTS_TAC [`\i. if i = 1 then &1 else &0`; `1`] THEN
12298       SIMP_TAC[SUM_CLAUSES_LEFT; LE_0; ARITH_EQ; REAL_MUL_LZERO; drop] THEN
12299       SIMP_TAC[ARITH; SUM_SING_NUMSEG] THEN REAL_ARITH_TAC;
12300       ALL_TAC] THEN
12301     CONJ_TAC THENL
12302      [X_GEN_TAC `c:real` THEN
12303       MAP_EVERY EXISTS_TAC [`(\i. c):num->real`; `0`] THEN
12304       REWRITE_TAC[SUM_SING_NUMSEG; real_pow] THEN REAL_ARITH_TAC;
12305       ALL_TAC] THEN
12306     CONJ_TAC THEN
12307     MAP_EVERY X_GEN_TAC [`f:real^1->real`; `g:real^1->real`] THEN
12308     REWRITE_TAC[IMP_CONJ; LEFT_IMP_EXISTS_THM] THEN
12309     MAP_EVERY X_GEN_TAC [`a:num->real`; `m:num`] THEN STRIP_TAC THEN
12310     MAP_EVERY X_GEN_TAC [`b:num->real`; `n:num`] THEN STRIP_TAC THEN
12311     ASM_REWRITE_TAC[] THENL
12312      [MAP_EVERY EXISTS_TAC
12313        [`\i:num. (if i <= m then a i else &0) + (if i <= n then b i else &0)`;
12314         `MAX m n`] THEN
12315       GEN_TAC THEN REWRITE_TAC[REAL_ADD_RDISTRIB; SUM_ADD_NUMSEG] THEN
12316       REWRITE_TAC[COND_RAND; COND_RATOR; REAL_MUL_LZERO] THEN
12317       REWRITE_TAC[GSYM SUM_RESTRICT_SET] THEN BINOP_TAC THEN
12318       BINOP_TAC THEN REWRITE_TAC[] THEN
12319       REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_NUMSEG] THEN ARITH_TAC;
12320       REWRITE_TAC[GSYM SUM_RMUL] THEN REWRITE_TAC[GSYM SUM_LMUL] THEN
12321       SIMP_TAC[SUM_SUM_PRODUCT; FINITE_NUMSEG] THEN
12322       EXISTS_TAC `\k. sum {x | x IN {i,j | i IN 0..m /\ j IN 0..n} /\
12323                                FST x + SND x = k}
12324                           (\(i,j). a i * b j)` THEN
12325       EXISTS_TAC `m + n:num` THEN X_GEN_TAC `x:real^1` THEN
12326       MP_TAC(ISPECL
12327        [`\(i:num,j). i + j`;
12328         `\(i,j). (a i * drop x pow i) * (b j * drop x pow j)`;
12329         `{i,j | i IN 0..m /\ j IN 0..n}`; `0..m+n`] SUM_GROUP) THEN
12330       SIMP_TAC[FINITE_PRODUCT; FINITE_NUMSEG; FORALL_IN_IMAGE;
12331                FORALL_IN_GSPEC; SUBSET; IN_NUMSEG; LE_0; LE_ADD2] THEN
12332       DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN
12333       X_GEN_TAC `k:num` THEN STRIP_TAC THEN REWRITE_TAC[GSYM SUM_RMUL] THEN
12334       MATCH_MP_TAC(MESON[SUM_EQ] `s = t /\ (!x. x IN t ==> f x = g x)
12335                                   ==> sum s f = sum t g`) THEN
12336       SIMP_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET; FORALL_IN_GSPEC; IMP_CONJ] THEN
12337       SIMP_TAC[IN_ELIM_PAIR_THM; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
12338       FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
12339       REWRITE_TAC[REAL_POW_ADD] THEN REAL_ARITH_TAC];
12340     REPEAT STRIP_TAC THEN
12341     ASM_REWRITE_TAC[GSYM VECTOR_POLYNOMIAL_FUNCTION_LIFT] THEN
12342     SIMP_TAC[LIFT_SUM; o_DEF; FINITE_NUMSEG; FORALL_1; DIMINDEX_1] THEN
12343     MATCH_MP_TAC VECTOR_POLYNOMIAL_FUNCTION_VSUM THEN
12344     REWRITE_TAC[FINITE_NUMSEG; LIFT_CMUL] THEN
12345     X_GEN_TAC `i:num` THEN STRIP_TAC THEN
12346     MATCH_MP_TAC VECTOR_POLYNOMIAL_FUNCTION_MUL THEN
12347     REWRITE_TAC[GSYM REAL_POLYNOMIAL_FUNCTION_DROP; o_DEF; LIFT_DROP] THEN
12348     REWRITE_TAC[real_polynomial_function_RULES] THEN
12349     SPEC_TAC(`i:num`,`k:num`) THEN REWRITE_TAC[drop] THEN
12350     INDUCT_TAC THEN
12351     ASM_SIMP_TAC[real_polynomial_function_RULES; real_pow; DIMINDEX_1;
12352                  ARITH]]);;
12353
12354 let CONTINUOUS_VECTOR_POLYNOMIAL_FUNCTION = prove
12355  (`!f:real^M->real^N x.
12356         vector_polynomial_function f ==> f continuous at x`,
12357   REWRITE_TAC[vector_polynomial_function; CONTINUOUS_COMPONENTWISE] THEN
12358   REPEAT STRIP_TAC THEN
12359   MATCH_MP_TAC REAL_CONTINUOUS_REAL_POLYMONIAL_FUNCTION THEN
12360   ASM_SIMP_TAC[]);;
12361
12362 let CONTINUOUS_ON_VECTOR_POLYNOMIAL_FUNCTION = prove
12363  (`!f:real^M->real^N s.
12364         vector_polynomial_function f ==> f continuous_on s`,
12365   SIMP_TAC[CONTINUOUS_AT_IMP_CONTINUOUS_ON;
12366            CONTINUOUS_VECTOR_POLYNOMIAL_FUNCTION]);;
12367
12368 let HAS_VECTOR_DERIVATIVE_VECTOR_POLYNOMIAL_FUNCTION = prove
12369  (`!p:real^1->real^N.
12370         vector_polynomial_function p
12371         ==> ?p'. vector_polynomial_function p' /\
12372                  !x. (p has_vector_derivative p'(x)) (at x)`,
12373   let lemma = prove
12374    (`!p:real^1->real.
12375           real_polynomial_function p
12376           ==> ?p'. real_polynomial_function p' /\
12377                  !x. ((p o lift) has_real_derivative (p'(lift x))) (atreal x)`,
12378     MATCH_MP_TAC
12379      (derive_strong_induction(real_polynomial_function_RULES,
12380                               real_polynomial_function_INDUCT)) THEN
12381     REWRITE_TAC[DIMINDEX_1; FORALL_1; o_DEF; GSYM drop; LIFT_DROP] THEN
12382     CONJ_TAC THENL
12383      [EXISTS_TAC `\x:real^1. &1` THEN
12384       REWRITE_TAC[real_polynomial_function_RULES; HAS_REAL_DERIVATIVE_ID];
12385       ALL_TAC] THEN
12386     CONJ_TAC THENL
12387      [X_GEN_TAC `c:real` THEN EXISTS_TAC `\x:real^1. &0` THEN
12388       REWRITE_TAC[real_polynomial_function_RULES; HAS_REAL_DERIVATIVE_CONST];
12389       ALL_TAC] THEN
12390     CONJ_TAC THEN
12391     MAP_EVERY X_GEN_TAC [`f:real^1->real`; `g:real^1->real`] THEN
12392     DISCH_THEN(CONJUNCTS_THEN2
12393      (CONJUNCTS_THEN2 ASSUME_TAC
12394        (X_CHOOSE_THEN `f':real^1->real` STRIP_ASSUME_TAC))
12395      (CONJUNCTS_THEN2 ASSUME_TAC
12396        (X_CHOOSE_THEN `g':real^1->real` STRIP_ASSUME_TAC)))
12397     THENL
12398      [EXISTS_TAC `\x. (f':real^1->real) x + g' x`;
12399       EXISTS_TAC `\x. (f:real^1->real) x * g' x + f' x * g x`] THEN
12400     ASM_SIMP_TAC[real_polynomial_function_RULES; HAS_REAL_DERIVATIVE_ADD;
12401                  HAS_REAL_DERIVATIVE_MUL_ATREAL]) in
12402   GEN_TAC THEN REWRITE_TAC[vector_polynomial_function] THEN DISCH_TAC THEN
12403   SUBGOAL_THEN
12404    `!i. 1 <= i /\ i <= dimindex(:N)
12405         ==> ?q. real_polynomial_function q /\
12406                 (!x. ((\x. lift(((p x):real^N)$i)) has_vector_derivative
12407                       lift(q x)) (at x))`
12408   MP_TAC THENL
12409    [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
12410     FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
12411     ASM_REWRITE_TAC[] THEN
12412     DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN
12413     REWRITE_TAC[HAS_REAL_VECTOR_DERIVATIVE_AT] THEN
12414     REWRITE_TAC[o_DEF; LIFT_DROP; FORALL_DROP];
12415     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
12416     REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
12417     X_GEN_TAC `q:num->real^1->real` THEN DISCH_TAC THEN
12418     EXISTS_TAC `(\x. lambda i. (q:num->real^1->real) i x):real^1->real^N` THEN
12419     ASM_SIMP_TAC[LAMBDA_BETA; ETA_AX] THEN
12420     REWRITE_TAC[has_vector_derivative; has_derivative_at] THEN
12421     ONCE_REWRITE_TAC[LIM_COMPONENTWISE] THEN X_GEN_TAC `x:real^1` THEN
12422     SIMP_TAC[LINEAR_VMUL_DROP; LINEAR_ID] THEN X_GEN_TAC `i:num` THEN
12423     STRIP_TAC THEN
12424     REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN
12425     ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
12426     FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN
12427     REWRITE_TAC[has_vector_derivative; has_derivative_at] THEN
12428     ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; VEC_COMPONENT; VECTOR_SUB_COMPONENT;
12429                  VECTOR_ADD_COMPONENT; LAMBDA_BETA; REAL_TENDSTO] THEN
12430     SIMP_TAC[DROP_ADD; DROP_VEC; LIFT_DROP; DROP_CMUL; DROP_SUB; o_DEF]]);;
12431
12432 let STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION = prove
12433  (`!f:real^M->real^N s e.
12434         compact s /\ f continuous_on s /\ &0 < e
12435         ==> ?g. vector_polynomial_function g /\
12436                 !x. x IN s ==> norm(f x - g x) < e`,
12437   REPEAT STRIP_TAC THEN
12438   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I
12439    [CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]) THEN
12440   REWRITE_TAC[CONTINUOUS_COMPONENTWISE] THEN
12441   REWRITE_TAC[IMP_IMP; RIGHT_IMP_FORALL_THM] THEN DISCH_TAC THEN
12442   SUBGOAL_THEN
12443    `!i. 1 <= i /\ i <= dimindex(:N)
12444         ==> ?g. real_polynomial_function g /\
12445                 !x. x IN s ==> abs((f:real^M->real^N) x$i - g x) <
12446                                e / &(dimindex(:N))`
12447   MP_TAC THENL
12448    [REPEAT STRIP_TAC THEN
12449     MATCH_MP_TAC STONE_WEIERSTRASS_REAL_POLYNOMIAL_FUNCTION THEN
12450     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; DIMINDEX_GE_1; LE_1];
12451     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
12452      [RIGHT_IMP_EXISTS_THM] THEN
12453     REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
12454     X_GEN_TAC `g:num->real^M->real` THEN DISCH_TAC THEN
12455     EXISTS_TAC `(\x. lambda i. g i x):real^M->real^N` THEN
12456     ASM_SIMP_TAC[vector_polynomial_function; LAMBDA_BETA; ETA_AX] THEN
12457     X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
12458     W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN
12459     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LET_TRANS) THEN
12460     MATCH_MP_TAC SUM_BOUND_LT_GEN THEN
12461     REWRITE_TAC[FINITE_NUMSEG; CARD_NUMSEG_1; NUMSEG_EMPTY; NOT_LT] THEN
12462     ASM_SIMP_TAC[IN_NUMSEG; DIMINDEX_GE_1; LAMBDA_BETA;
12463                  VECTOR_SUB_COMPONENT]]);;
12464
12465 let STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION_SUBSPACE = prove
12466  (`!f:real^M->real^N s e t.
12467         compact s /\ f continuous_on s /\ &0 < e /\
12468         subspace t /\ IMAGE f s SUBSET t
12469         ==> ?g. vector_polynomial_function g /\ IMAGE g s SUBSET t /\
12470                 !x. x IN s ==> norm(f x - g x) < e`,
12471   REPEAT STRIP_TAC THEN
12472   FIRST_ASSUM(MP_TAC o MATCH_MP ORTHONORMAL_BASIS_SUBSPACE) THEN
12473   DISCH_THEN(X_CHOOSE_THEN `bas:real^N->bool` MP_TAC) THEN
12474   ASM_CASES_TAC `FINITE(bas:real^N->bool)` THENL
12475    [ALL_TAC; ASM_MESON_TAC[HAS_SIZE]] THEN
12476   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN
12477   ABBREV_TAC `n = CARD(bas:real^N->bool)` THEN
12478   REWRITE_TAC[INJECTIVE_ON_ALT; LEFT_IMP_EXISTS_THM] THEN
12479   X_GEN_TAC `b:num->real^N` THEN
12480   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC) THEN
12481   ASM_SIMP_TAC[REWRITE_RULE[INJECTIVE_ON_ALT] HAS_SIZE_IMAGE_INJ_EQ] THEN
12482   REWRITE_TAC[HAS_SIZE; FINITE_NUMSEG; CARD_NUMSEG_1] THEN
12483   ASM_CASES_TAC `dim(t:real^N->bool) = n` THEN ASM_REWRITE_TAC[] THEN
12484   REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN STRIP_TAC THEN
12485   MP_TAC(ISPEC `t:real^N->bool` DIM_SUBSET_UNIV) THEN ASM_REWRITE_TAC[] THEN
12486   DISCH_TAC THEN MP_TAC(ISPECL
12487    [`(\x. lambda i. (f x:real^N) dot (b i)):real^M->real^N`;
12488     `s:real^M->bool`; `e:real`]
12489    STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION) THEN
12490   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
12491    [ONCE_REWRITE_TAC[CONTINUOUS_ON_COMPONENTWISE_LIFT] THEN
12492     SIMP_TAC[LAMBDA_BETA] THEN REPEAT STRIP_TAC THEN
12493     MATCH_MP_TAC CONTINUOUS_ON_LIFT_DOT2 THEN
12494     ASM_REWRITE_TAC[CONTINUOUS_ON_CONST];
12495     DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC)] THEN
12496   EXISTS_TAC `(\x. vsum(1..n) (\i. (g x:real^N)$i % b i)):real^M->real^N` THEN
12497   REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
12498    [MATCH_MP_TAC VECTOR_POLYNOMIAL_FUNCTION_VSUM THEN
12499     REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
12500     REPEAT STRIP_TAC THEN MATCH_MP_TAC VECTOR_POLYNOMIAL_FUNCTION_MUL THEN
12501     REWRITE_TAC[VECTOR_POLYNOMIAL_FUNCTION_CONST; o_DEF] THEN
12502     MATCH_MP_TAC VECTOR_POLYNOMIAL_FUNCTION_COMPONENT THEN
12503     ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC;
12504     REPEAT STRIP_TAC THEN MATCH_MP_TAC SUBSPACE_VSUM THEN
12505     ASM_SIMP_TAC[SUBSPACE_MUL; FINITE_NUMSEG];
12506     X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
12507     FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN
12508     ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[DOT_SYM] THEN
12509     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN
12510     SUBGOAL_THEN
12511      `vsum(IMAGE b (1..n)) (\v. (v dot f x) % v) = (f:real^M->real^N) x`
12512      (fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [SYM th])
12513     THENL
12514      [MATCH_MP_TAC ORTHONORMAL_BASIS_EXPAND THEN
12515       ASM_REWRITE_TAC[FORALL_IN_IMAGE] THEN ASM SET_TAC[];
12516       ASM_SIMP_TAC[REWRITE_RULE[INJECTIVE_ON_ALT] VSUM_IMAGE;
12517                    FINITE_NUMSEG] THEN
12518       REWRITE_TAC[GSYM VSUM_SUB_NUMSEG; o_DEF; GSYM VECTOR_SUB_RDISTRIB] THEN
12519       REWRITE_TAC[NORM_LE; GSYM NORM_POW_2] THEN
12520       W(MP_TAC o PART_MATCH (lhs o rand) NORM_VSUM_PYTHAGOREAN o
12521         lhand o snd) THEN
12522       RULE_ASSUM_TAC(REWRITE_RULE[PAIRWISE_IMAGE]) THEN
12523       RULE_ASSUM_TAC(REWRITE_RULE[pairwise]) THEN
12524       ASM_SIMP_TAC[pairwise; ORTHOGONAL_MUL; FINITE_NUMSEG] THEN
12525       DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[NORM_MUL] THEN
12526       REWRITE_TAC[NORM_POW_2] THEN GEN_REWRITE_TAC RAND_CONV [dot] THEN
12527       SIMP_TAC[GSYM REAL_POW_2; VECTOR_SUB_COMPONENT; LAMBDA_BETA] THEN
12528       MATCH_MP_TAC SUM_LE_INCLUDED THEN EXISTS_TAC `\n:num. n` THEN
12529       REWRITE_TAC[FINITE_NUMSEG; REAL_LE_POW_2] THEN
12530       ONCE_REWRITE_TAC[TAUT `p /\ q /\ r <=> q /\ p /\ r`] THEN
12531       REWRITE_TAC[UNWIND_THM2] THEN
12532       ONCE_REWRITE_TAC[TAUT `p ==> q /\ r <=> p ==> q /\ (q ==> r)`] THEN
12533       RULE_ASSUM_TAC(REWRITE_RULE[IN_NUMSEG]) THEN
12534       ASM_SIMP_TAC[LAMBDA_BETA; UNWIND_THM2; IN_NUMSEG] THEN
12535       REWRITE_TAC[REAL_MUL_RID; REAL_POW2_ABS; REAL_LE_REFL] THEN
12536       ASM_ARITH_TAC]]);;
12537
12538 let STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION_AFFINE = prove
12539  (`!f:real^M->real^N s e t.
12540         compact s /\ f continuous_on s /\ &0 < e /\
12541         affine t /\ IMAGE f s SUBSET t
12542         ==> ?g. vector_polynomial_function g /\ IMAGE g s SUBSET t /\
12543                 !x. x IN s ==> norm(f x - g x) < e`,
12544   REPEAT GEN_TAC THEN ASM_CASES_TAC `t:real^N->bool = {}` THEN
12545   ASM_REWRITE_TAC[SUBSET_EMPTY; IMAGE_EQ_EMPTY] THENL
12546    [MESON_TAC[VECTOR_POLYNOMIAL_FUNCTION_CONST; NOT_IN_EMPTY];
12547     STRIP_TAC] THEN
12548   MP_TAC(ISPEC `t:real^N->bool` AFFINE_TRANSLATION_SUBSPACE) THEN
12549   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
12550   MAP_EVERY X_GEN_TAC [`a:real^N`; `u:real^N->bool`] THEN STRIP_TAC THEN
12551   FIRST_X_ASSUM SUBST_ALL_TAC THEN
12552   MP_TAC(ISPECL
12553    [`(\x. f x - a):real^M->real^N`; `s:real^M->bool`; `e:real`;
12554    `u:real^N->bool`] STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION_SUBSPACE) THEN
12555   ASM_SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST] THEN
12556   FIRST_ASSUM(MP_TAC o ISPEC `\x:real^N. x - a` o MATCH_MP IMAGE_SUBSET) THEN
12557   REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_ADD_SUB; IMAGE_ID] THEN
12558   DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
12559   DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^N` STRIP_ASSUME_TAC) THEN
12560   EXISTS_TAC `(\x. g x + a):real^M->real^N` THEN
12561   ASM_SIMP_TAC[VECTOR_POLYNOMIAL_FUNCTION_ADD;
12562                VECTOR_POLYNOMIAL_FUNCTION_CONST;
12563                VECTOR_ARITH `a - (b + c):real^N = a - c - b`] THEN
12564   FIRST_ASSUM(MP_TAC o ISPEC `\x:real^N. a + x` o MATCH_MP IMAGE_SUBSET) THEN
12565   REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_ADD_AC]);;
12566
12567 (* ------------------------------------------------------------------------- *)
12568 (* One application is to pick a smooth approximation to a path, or just pick *)
12569 (* a smooth path anyway in an open connected set.                            *)
12570 (* ------------------------------------------------------------------------- *)
12571
12572 let PATH_VECTOR_POLYNOMIAL_FUNCTION = prove
12573  (`!g:real^1->real^N. vector_polynomial_function g ==> path g`,
12574   SIMP_TAC[path; CONTINUOUS_ON_VECTOR_POLYNOMIAL_FUNCTION]);;
12575
12576 let PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION = prove
12577  (`!g:real^1->real^N e.
12578         path g /\ &0 < e
12579         ==> ?p. vector_polynomial_function p /\
12580                 pathstart p = pathstart g /\
12581                 pathfinish p = pathfinish g /\
12582                 !t. t IN interval[vec 0,vec 1] ==> norm(p t - g t) < e`,
12583   REWRITE_TAC[path] THEN REPEAT STRIP_TAC THEN
12584   MP_TAC(ISPECL [`g:real^1->real^N`; `interval[vec 0:real^1,vec 1]`; `e / &4`]
12585         STONE_WEIERSTRASS_VECTOR_POLYNOMIAL_FUNCTION) THEN
12586   ASM_REWRITE_TAC[COMPACT_INTERVAL; REAL_ARITH `&0 < x / &4 <=> &0 < x`] THEN
12587   DISCH_THEN(X_CHOOSE_THEN `q:real^1->real^N` STRIP_ASSUME_TAC) THEN
12588   EXISTS_TAC `\t. (q:real^1->real^N)(t) + (g(vec 0:real^1) - q(vec 0)) +
12589                 drop t % ((g(vec 1) - q(vec 1)) - (g(vec 0) - q(vec 0)))` THEN
12590   REWRITE_TAC[pathstart; pathfinish; DROP_VEC] THEN REPEAT CONJ_TAC THENL
12591    [SIMP_TAC[vector_polynomial_function; VECTOR_ADD_COMPONENT;
12592              VECTOR_MUL_COMPONENT; VECTOR_SUB_COMPONENT] THEN
12593     REPEAT STRIP_TAC THEN
12594     RULE_ASSUM_TAC(REWRITE_RULE[vector_polynomial_function]) THEN
12595     MATCH_MP_TAC(el 2 (CONJUNCTS real_polynomial_function_RULES)) THEN
12596     ASM_SIMP_TAC[real_polynomial_function_RULES; drop; DIMINDEX_1; ARITH];
12597     VECTOR_ARITH_TAC;
12598     VECTOR_ARITH_TAC;
12599     REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[VECTOR_SUB_LDISTRIB] THEN
12600     MATCH_MP_TAC(NORM_ARITH
12601      `norm(x - a) < e / &4 /\ norm b < e / &4 /\ norm c <= &1 * e / &4 /\
12602         norm d <= &1 * e / &4
12603       ==> norm((a + b + c - d) - x:real^N) < e`) THEN
12604     ASM_SIMP_TAC[NORM_MUL; IN_INTERVAL_1; DROP_VEC; REAL_POS] THEN
12605     CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
12606     ASM_SIMP_TAC[REAL_LT_IMP_LE; IN_INTERVAL_1; DROP_VEC; REAL_POS;
12607                  REAL_LE_REFL; NORM_POS_LE] THEN
12608     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN
12609     ASM_REAL_ARITH_TAC]);;
12610
12611 let CONNECTED_OPEN_VECTOR_POLYNOMIAL_CONNECTED = prove
12612  (`!s:real^N->bool.
12613         open s /\ connected s
12614         ==> !x y. x IN s /\ y IN s
12615                   ==> ?g. vector_polynomial_function g /\
12616                           path_image g SUBSET s /\
12617                           pathstart g = x /\
12618                           pathfinish g = y`,
12619   REPEAT STRIP_TAC THEN
12620   SUBGOAL_THEN `path_connected(s:real^N->bool)` MP_TAC THENL
12621    [ASM_SIMP_TAC[CONNECTED_OPEN_PATH_CONNECTED];
12622     REWRITE_TAC[path_connected]] THEN
12623   DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `y:real^N`]) THEN
12624   ASM_REWRITE_TAC[] THEN
12625   DISCH_THEN(X_CHOOSE_THEN `p:real^1->real^N` STRIP_ASSUME_TAC) THEN
12626   SUBGOAL_THEN
12627    `?e. &0 < e /\ !x. x IN path_image p ==> ball(x:real^N,e) SUBSET s`
12628   STRIP_ASSUME_TAC THENL
12629    [ASM_CASES_TAC `s = (:real^N)` THEN ASM_REWRITE_TAC[SUBSET_UNIV] THENL
12630      [MESON_TAC[REAL_LT_01]; ALL_TAC] THEN
12631     EXISTS_TAC `setdist(path_image p,(:real^N) DIFF s)` THEN CONJ_TAC THENL
12632      [ASM_REWRITE_TAC[REAL_ARITH `&0 < x <=> &0 <= x /\ ~(x = &0)`] THEN
12633       ASM_SIMP_TAC[SETDIST_POS_LE; SETDIST_EQ_0_COMPACT_CLOSED;
12634                    COMPACT_PATH_IMAGE; GSYM OPEN_CLOSED] THEN
12635       ASM_SIMP_TAC[PATH_IMAGE_NONEMPTY] THEN ASM SET_TAC[];
12636       X_GEN_TAC `z:real^N` THEN DISCH_TAC THEN REWRITE_TAC[SUBSET] THEN
12637       X_GEN_TAC `w:real^N` THEN REWRITE_TAC[IN_BALL; GSYM REAL_NOT_LE] THEN
12638       MATCH_MP_TAC(SET_RULE
12639        `(w IN (UNIV DIFF s) ==> p) ==> (~p ==> w IN s)`) THEN
12640       ASM_SIMP_TAC[SETDIST_LE_DIST]];
12641     MP_TAC(ISPECL [`p:real^1->real^N`; `e:real`]
12642       PATH_APPROX_VECTOR_POLYNOMIAL_FUNCTION) THEN
12643     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN
12644     X_GEN_TAC `q:real^1->real^N` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
12645     REWRITE_TAC[path_image; FORALL_IN_IMAGE; SUBSET] THEN RULE_ASSUM_TAC
12646      (REWRITE_RULE[SUBSET; path_image; FORALL_IN_IMAGE;IN_BALL; dist]) THEN
12647     ASM_MESON_TAC[NORM_SUB]]);;
12648
12649 (* ------------------------------------------------------------------------- *)
12650 (* Lipschitz property for real and vector polynomials.                       *)
12651 (* ------------------------------------------------------------------------- *)
12652
12653 let LIPSCHITZ_REAL_POLYNOMIAL_FUNCTION = prove
12654  (`!f:real^N->real s.
12655         real_polynomial_function f /\ bounded s
12656         ==> ?B. &0 < B /\
12657                 !x y. x IN s /\ y IN s ==> abs(f x - f y) <= B * norm(x - y)`,
12658   ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN GEN_TAC THEN
12659   ASM_CASES_TAC `bounded(s:real^N->bool)` THEN ASM_REWRITE_TAC[] THEN
12660   ASM_CASES_TAC `s:real^N->bool = {}` THENL
12661    [ASM_REWRITE_TAC[NOT_IN_EMPTY] THEN MESON_TAC[REAL_LT_01]; ALL_TAC] THEN
12662   MATCH_MP_TAC real_polynomial_function_INDUCT THEN REPEAT CONJ_TAC THENL
12663    [REPEAT STRIP_TAC THEN EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
12664     ASM_SIMP_TAC[REAL_MUL_LID; GSYM VECTOR_SUB_COMPONENT; COMPONENT_LE_NORM];
12665     GEN_TAC THEN EXISTS_TAC `&1` THEN
12666     SIMP_TAC[REAL_LT_01; REAL_SUB_REFL; REAL_ABS_NUM; REAL_MUL_LID;
12667              NORM_POS_LE];
12668     ALL_TAC; ALL_TAC] THEN
12669   MAP_EVERY X_GEN_TAC [`f:real^N->real`; `g:real^N->real`] THEN
12670   DISCH_THEN(CONJUNCTS_THEN2
12671     (X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC)
12672     (X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC))
12673   THENL
12674    [EXISTS_TAC `B1 + B2:real` THEN ASM_SIMP_TAC[REAL_LT_ADD] THEN
12675     REPEAT STRIP_TAC THEN MATCH_MP_TAC(REAL_ARITH
12676      `abs(f - f') <= B1 * n /\ abs(g - g') <= B2 * n
12677       ==> abs((f + g) - (f' + g')) <= (B1 + B2) * n`) THEN
12678     ASM_SIMP_TAC[];
12679     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
12680     DISCH_THEN(X_CHOOSE_TAC `a:real^N`) THEN
12681     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
12682     DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
12683     EXISTS_TAC `B1 * (abs(g(a:real^N)) + B2 * &2 * B) +
12684                 B2 * (abs(f a) + B1 * &2 * B)` THEN
12685     CONJ_TAC THENL
12686      [MATCH_MP_TAC REAL_LT_ADD THEN CONJ_TAC THEN MATCH_MP_TAC REAL_LT_MUL THEN
12687       ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
12688        `&0 < x ==> &0 < abs a + x`) THEN
12689       MATCH_MP_TAC REAL_LT_MUL THEN ASM_REAL_ARITH_TAC;
12690       REPEAT STRIP_TAC THEN REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
12691        `abs((f - f') * g) <= a * n /\ abs((g - g') * f') <= b * n
12692         ==> abs(f * g - f' * g') <= (a + b) * n`) THEN
12693       ONCE_REWRITE_TAC[REAL_ARITH `(a * b) * c:real = (a * c) * b`] THEN
12694       REWRITE_TAC[REAL_ABS_MUL] THEN
12695       CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
12696       ASM_SIMP_TAC[REAL_ABS_POS] THEN MATCH_MP_TAC(REAL_ARITH
12697        `abs(g x - g a) <= C * norm(x - a) /\
12698         C * norm(x - a:real^N) <= C * B ==> abs(g x) <= abs(g a) + C * B`) THEN
12699       ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN MATCH_MP_TAC(NORM_ARITH
12700        `norm x <= B /\ norm a <= B ==> norm(x - a:real^N) <= &2 * B`) THEN
12701       ASM_SIMP_TAC[]]]);;
12702
12703 let LIPSCHITZ_VECTOR_POLYNOMIAL_FUNCTION = prove
12704  (`!f:real^M->real^N s.
12705         vector_polynomial_function f /\ bounded s
12706         ==> ?B. &0 < B /\
12707                 !x y. x IN s /\ y IN s ==> norm(f x - f y) <= B * norm(x - y)`,
12708   REWRITE_TAC[vector_polynomial_function] THEN REPEAT STRIP_TAC THEN
12709   SUBGOAL_THEN
12710    `?b. !i. 1 <= i /\ i <= dimindex(:N)
12711             ==> &0 < (b:real^N)$i /\
12712                 !x y. x IN s /\ y IN s
12713                       ==> abs((f:real^M->real^N) x$i - f y$i) <=
12714                           b$i * norm(x - y)`
12715   STRIP_ASSUME_TAC THENL
12716    [REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN REPEAT STRIP_TAC THEN
12717     MATCH_MP_TAC LIPSCHITZ_REAL_POLYNOMIAL_FUNCTION THEN
12718     ASM_SIMP_TAC[LIPSCHITZ_REAL_POLYNOMIAL_FUNCTION];
12719     EXISTS_TAC `&1 + sum(1..dimindex(:N)) (\i. (b:real^N)$i)` THEN
12720     CONJ_TAC THENL
12721      [MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> &0 < &1 + x`) THEN
12722       MATCH_MP_TAC SUM_POS_LE_NUMSEG THEN ASM_SIMP_TAC[REAL_LT_IMP_LE];
12723       REPEAT STRIP_TAC THEN
12724       W(MP_TAC o PART_MATCH lhand NORM_LE_L1 o lhand o snd) THEN
12725       MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
12726       REWRITE_TAC[REAL_ADD_RDISTRIB; GSYM SUM_RMUL; REAL_MUL_LID] THEN
12727       MATCH_MP_TAC(NORM_ARITH `x <= y ==> x <= norm(a:real^N) + y`) THEN
12728       MATCH_MP_TAC SUM_LE_NUMSEG THEN
12729       ASM_SIMP_TAC[VECTOR_SUB_COMPONENT]]]);;
12730
12731 (* ------------------------------------------------------------------------- *)
12732 (* Differentiability of real and vector polynomial functions.                *)
12733 (* ------------------------------------------------------------------------- *)
12734
12735 let DIFFERENTIABLE_REAL_POLYNOMIAL_FUNCTION_AT = prove
12736  (`!f:real^N->real a.
12737         real_polynomial_function f ==> (lift o f) differentiable (at a)`,
12738   ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN GEN_TAC THEN
12739   MATCH_MP_TAC real_polynomial_function_INDUCT THEN
12740   REWRITE_TAC[o_DEF; LIFT_ADD; LIFT_CMUL] THEN
12741   REWRITE_TAC[DIFFERENTIABLE_LIFT_COMPONENT; DIFFERENTIABLE_CONST] THEN
12742   SIMP_TAC[DIFFERENTIABLE_ADD] THEN REPEAT STRIP_TAC THEN
12743   MATCH_MP_TAC DIFFERENTIABLE_MUL_AT THEN
12744   ASM_REWRITE_TAC[o_DEF]);;
12745
12746 let DIFFERENTIABLE_ON_REAL_POLYNOMIAL_FUNCTION = prove
12747  (`!f:real^N->real s.
12748         real_polynomial_function f ==> (lift o f) differentiable_on s`,
12749   SIMP_TAC[DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON;
12750            DIFFERENTIABLE_REAL_POLYNOMIAL_FUNCTION_AT]);;
12751
12752 let DIFFERENTIABLE_VECTOR_POLYNOMIAL_FUNCTION = prove
12753  (`!f:real^M->real^N a.
12754         vector_polynomial_function f ==> f differentiable (at a)`,
12755   REWRITE_TAC[vector_polynomial_function] THEN REPEAT STRIP_TAC THEN
12756   ONCE_REWRITE_TAC[DIFFERENTIABLE_COMPONENTWISE_AT] THEN
12757   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN
12758   MATCH_MP_TAC DIFFERENTIABLE_REAL_POLYNOMIAL_FUNCTION_AT THEN
12759   ASM_SIMP_TAC[]);;
12760
12761 let DIFFERENTIABLE_ON_VECTOR_POLYNOMIAL_FUNCTION = prove
12762  (`!f:real^M->real^N s.
12763         vector_polynomial_function f ==> f differentiable_on s`,
12764   SIMP_TAC[DIFFERENTIABLE_AT_IMP_DIFFERENTIABLE_ON;
12765            DIFFERENTIABLE_VECTOR_POLYNOMIAL_FUNCTION]);;
12766
12767 (* ------------------------------------------------------------------------- *)
12768 (* Non-trivial algebraic variety has empty interior.                         *)
12769 (* ------------------------------------------------------------------------- *)
12770
12771 let NOWHERE_DENSE_ALGEBRAIC_VARIETY = prove
12772  (`!f c. real_polynomial_function f /\ ~(!x. f x = c)
12773          ==> interior {x:real^N | f(x) = c} = {}`,
12774   REPEAT STRIP_TAC THEN
12775   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_FORALL_THM]) THEN
12776   DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN
12777   REWRITE_TAC[EXTENSION; NOT_IN_EMPTY] THEN X_GEN_TAC `x:real^N` THEN
12778   REWRITE_TAC[IN_INTERIOR] THEN
12779   DISCH_THEN(X_CHOOSE_THEN `e:real` STRIP_ASSUME_TAC) THEN
12780   SUBGOAL_THEN
12781    `?a n. !t. f(x + t % (y - x):real^N) - c = sum(0..n) (\i. a i * t pow i)`
12782   STRIP_ASSUME_TAC THENL
12783    [REWRITE_TAC[FORALL_DROP;
12784                 GSYM(REWRITE_RULE[FUN_EQ_THM] REAL_POLYNOMIAL_FUNCTION_1)] THEN
12785     REWRITE_TAC[real_sub] THEN
12786     MATCH_MP_TAC(el 2 (CONJUNCTS real_polynomial_function_RULES)) THEN
12787     REWRITE_TAC[real_polynomial_function_RULES] THEN
12788     ONCE_REWRITE_TAC[GSYM o_DEF] THEN
12789     MATCH_MP_TAC REAL_VECTOR_POLYNOMIAL_FUNCTION_o THEN
12790     ASM_REWRITE_TAC[] THEN
12791     MATCH_MP_TAC VECTOR_POLYNOMIAL_FUNCTION_ADD THEN
12792     REWRITE_TAC[VECTOR_POLYNOMIAL_FUNCTION_CONST] THEN
12793     MATCH_MP_TAC VECTOR_POLYNOMIAL_FUNCTION_MUL THEN
12794     SIMP_TAC[o_DEF; LIFT_DROP; VECTOR_POLYNOMIAL_FUNCTION_SUB;
12795              VECTOR_POLYNOMIAL_FUNCTION_ID; VECTOR_POLYNOMIAL_FUNCTION_CONST];
12796     FIRST_X_ASSUM(MP_TAC o GEN `t:real` o SPEC
12797      `x + t % (y - x):real^N` o GEN_REWRITE_RULE I [SUBSET]) THEN
12798     ASM_REWRITE_TAC[IN_BALL; IN_ELIM_THM] THEN
12799     ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN
12800     ASM_REWRITE_TAC[NORM_ARITH `dist(x:real^N,x + y) = norm y`] THEN
12801     SIMP_TAC[SET_RULE `(!x. P x ==> Q x) <=> {x | P x} SUBSET {x | Q x}`] THEN
12802     MATCH_MP_TAC(MESON[FINITE_SUBSET; INFINITE]
12803      `FINITE t /\ INFINITE s ==> ~(s SUBSET t)`) THEN
12804     REWRITE_TAC[REAL_POLYFUN_FINITE_ROOTS] THEN CONJ_TAC THENL
12805      [FIRST_X_ASSUM(MP_TAC o SPEC `&1`) THEN
12806       ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
12807       SIMP_TAC[NOT_EXISTS_THM; TAUT `~(p /\ ~q) <=> p ==> q`] THEN
12808       DISCH_THEN(K ALL_TAC) THEN REWRITE_TAC[REAL_MUL_LZERO; SUM_0] THEN
12809       ASM_REWRITE_TAC[REAL_SUB_0; VECTOR_ARITH `x + &1 % (y - x):real^N = y`];
12810       ASM_CASES_TAC `y:real^N = x` THENL
12811        [ASM_REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_SUB_REFL; NORM_0] THEN
12812         REWRITE_TAC[UNIV_GSPEC; real_INFINITE];
12813         ASM_SIMP_TAC[NORM_MUL; GSYM REAL_LT_RDIV_EQ; NORM_POS_LT;
12814                      VECTOR_SUB_EQ; GSYM NORM_LIFT] THEN
12815         MATCH_MP_TAC INFINITE_SUPERSET THEN EXISTS_TAC
12816          `IMAGE drop (ball(vec 0:real^1,e / norm(y - x:real^N)))` THEN
12817         CONJ_TAC THENL
12818          [MP_TAC(ISPEC `drop` INFINITE_IMAGE_INJ) THEN
12819           SIMP_TAC[DROP_EQ] THEN DISCH_THEN MATCH_MP_TAC THEN
12820           REWRITE_TAC[INFINITE; FINITE_BALL; REAL_NOT_LE] THEN
12821           ASM_SIMP_TAC[REAL_LT_DIV; NORM_POS_LT; VECTOR_SUB_EQ];
12822           REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_BALL_0;
12823                       IN_ELIM_THM; LIFT_DROP]]]]]);;
12824
12825 (* ------------------------------------------------------------------------- *)
12826 (* Bernoulli polynomials, defined recursively. We don't explicitly introduce *)
12827 (* a definition for Bernoulli numbers, but use "bernoulli n (&0)" for that.  *)
12828 (* ------------------------------------------------------------------------- *)
12829
12830 let bernoulli = define
12831  `(!x. bernoulli 0 x = &1) /\
12832   (!n x. bernoulli (n + 1) x =
12833           x pow (n + 1) -
12834           sum(0..n) (\k. &(binom(n+2,k)) * bernoulli k x) / (&n + &2))`;;
12835
12836 let BERNOULLI_CONV =
12837   let btm = `bernoulli` in
12838   let rec bernoullis n =
12839     if n < 0 then [] else
12840     if n = 0 then [CONJUNCT1 bernoulli] else
12841     let ths = bernoullis (n - 1) in
12842     let th1 = SPEC(mk_small_numeral (n - 1)) (CONJUNCT2 bernoulli) in
12843     let th2 =
12844       CONV_RULE(BINDER_CONV (COMB2_CONV (RAND_CONV(LAND_CONV NUM_ADD_CONV))
12845        (RAND_CONV(LAND_CONV EXPAND_SUM_CONV) THENC
12846         NUM_REDUCE_CONV THENC
12847         ONCE_DEPTH_CONV NUM_BINOM_CONV THENC
12848         REWRITE_CONV ths THENC
12849         REAL_POLY_CONV))) th1 in
12850     th2::ths in
12851   fun tm -> match tm with
12852              Comb(Comb(b,n),x) when b = btm ->
12853                 let th = hd(bernoullis(dest_small_numeral n)) in
12854                 (REWR_CONV th THENC REAL_POLY_CONV) tm
12855            | _ -> failwith "BERNOULLI_CONV";;
12856
12857 let BERNOULLI,BERNOULLI_EXPANSION = (CONJ_PAIR o prove)
12858  (`(!n x. sum(0..n) (\k. &(binom(n,k)) * bernoulli k x) - bernoulli n x =
12859           &n * x pow (n - 1)) /\
12860    (!n x. bernoulli n x =
12861           sum(0..n) (\k. &(binom(n,k)) * bernoulli k (&0) * x pow (n - k)))`,
12862   let lemma = prove
12863    (`(!n x. sum (0..n) (\k. &(binom(n,k)) * B k x) - B n x =
12864             &n * x pow (n - 1)) <=>
12865      (!x. B 0 x = &1) /\
12866      (!n x. B (n + 1) x =
12867             x pow (n + 1) -
12868             sum(0..n) (\k. &(binom(n+2,k)) * B k x) / (&n + &2))`,
12869     let cth = MESON[num_CASES] `(!n. P n) <=> P 0 /\ (!n. P(SUC n))` in
12870     GEN_REWRITE_TAC LAND_CONV [cth] THEN
12871     GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [cth] THEN
12872     SIMP_TAC[SUM_CLAUSES_NUMSEG; LE_0; BINOM_REFL; BINOM_PENULT; SUC_SUB1] THEN
12873     CONV_TAC NUM_REDUCE_CONV THEN
12874     REWRITE_TAC[REAL_MUL_LID; REAL_MUL_LZERO; REAL_SUB_REFL] THEN
12875     SIMP_TAC[ADD1; ARITH_RULE `(n + 1) + 1 = n + 2`; GSYM REAL_OF_NUM_ADD] THEN
12876     BINOP_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
12877     CONV_TAC REAL_FIELD) in
12878   REWRITE_TAC[lemma; bernoulli] THEN
12879   SUBGOAL_THEN
12880    `!n x. sum(0..n) (\k. &(binom(n,k)) *
12881                          sum (0..k)
12882                              (\l. &(binom(k,l)) *
12883                                   bernoulli l (&0) * x pow (k - l))) -
12884    sum(0..n) (\k. &(binom(n,k)) * bernoulli k (&0) * x pow (n - k)) =
12885    &n * x pow (n - 1)`
12886   MP_TAC THENL
12887    [REPEAT GEN_TAC THEN MP_TAC(ISPECL
12888      [`\n. bernoulli n (&0)`; `n:num`; `x:real`; `&1`] APPELL_SEQUENCE) THEN
12889     REWRITE_TAC[REAL_POW_ONE; REAL_MUL_RID] THEN DISCH_THEN SUBST1_TAC THEN
12890     ONCE_REWRITE_TAC[REAL_ARITH `x + &1 = &1 + x`] THEN
12891     GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [GSYM APPELL_SEQUENCE] THEN
12892     REWRITE_TAC[REAL_POW_ONE; REAL_MUL_RID; GSYM SUM_SUB_NUMSEG] THEN
12893     REWRITE_TAC[GSYM REAL_SUB_LDISTRIB; GSYM REAL_SUB_RDISTRIB] THEN
12894     REWRITE_TAC[REWRITE_RULE[GSYM lemma] bernoulli] THEN
12895     REWRITE_TAC[REAL_POW_ZERO; COND_RAND; COND_RATOR] THEN
12896     REWRITE_TAC[ARITH_RULE `i - 1 = 0 <=> i = 0 \/ i = 1`] THEN
12897     REWRITE_TAC[MESON[]
12898      `(if p \/ q then x else y) = if q then x else if p then x else y`] THEN
12899     SIMP_TAC[REAL_MUL_LZERO; REAL_MUL_RZERO; COND_ID; SUM_DELTA] THEN
12900     REWRITE_TAC[IN_NUMSEG; LE_0; BINOM_1] THEN
12901     ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[REAL_MUL_LZERO] THEN
12902     ASM_SIMP_TAC[LE_1] THEN REAL_ARITH_TAC;
12903     REWRITE_TAC[lemma] THEN STRIP_TAC THEN
12904      MATCH_MP_TAC num_WF THEN MATCH_MP_TAC num_INDUCTION THEN
12905     ASM_SIMP_TAC[ADD1; bernoulli;
12906            ARITH_RULE `m < n + 1 <=> m <= n`]]);;
12907
12908 let BERNOULLI_ALT = prove
12909  (`!n x. sum(0..n) (\k. &(binom(n+1,k)) * bernoulli k x) =
12910          (&n + &1) * x pow n`,
12911   REPEAT GEN_TAC THEN
12912   MP_TAC(SPECL [`SUC n`; `x:real`] BERNOULLI) THEN
12913   REWRITE_TAC[SUM_CLAUSES_NUMSEG; LE_0; SUC_SUB1; BINOM_REFL] THEN
12914   REWRITE_TAC[ADD1; GSYM REAL_OF_NUM_ADD] THEN REAL_ARITH_TAC);;
12915
12916 let BERNOULLI_ADD = prove
12917  (`!n x y. bernoulli n (x + y) =
12918            sum(0..n) (\k. &(binom(n,k)) * bernoulli k x * y pow (n - k))`,
12919   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[BERNOULLI_EXPANSION] THEN
12920   REWRITE_TAC[APPELL_SEQUENCE]);;
12921
12922 let bernoulli_number = prove
12923  (`bernoulli 0 (&0) = &1 /\
12924   (!n. bernoulli (n + 1) (&0) =
12925        --sum(0..n) (\k. &(binom(n+2,k)) * bernoulli k (&0)) / (&n + &2))`,
12926   REWRITE_TAC[bernoulli; REAL_POW_ADD] THEN REAL_ARITH_TAC);;
12927
12928 let BERNOULLI_NUMBER = prove
12929  (`!n. sum (0..n) (\k. &(binom (n,k)) * bernoulli k (&0)) - bernoulli n (&0) =
12930        if n = 1 then &1 else &0`,
12931   REWRITE_TAC[BERNOULLI] THEN
12932   MATCH_MP_TAC num_INDUCTION THEN REWRITE_TAC[ARITH; REAL_MUL_LZERO] THEN
12933   MATCH_MP_TAC num_INDUCTION THEN REWRITE_TAC[SUC_SUB1] THEN
12934   REWRITE_TAC[ARITH_RULE `SUC n = 1 <=> n = 0`] THEN
12935   CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[real_pow; REAL_MUL_LID] THEN
12936   REWRITE_TAC[NOT_SUC; REAL_MUL_LZERO; REAL_MUL_RZERO]);;
12937
12938 let BERNOULLI_NUMBER_ALT = prove
12939  (`!n. sum(0..n) (\k. &(binom(n+1,k)) * bernoulli k (&0)) =
12940        if n = 0 then &1 else &0`,
12941   REWRITE_TAC[BERNOULLI_ALT] THEN INDUCT_TAC THEN
12942   REWRITE_TAC[real_pow; REAL_MUL_LZERO; REAL_MUL_RZERO; NOT_SUC] THEN
12943   REWRITE_TAC[REAL_ADD_LID; REAL_MUL_RID]);;
12944
12945 let BERNOULLI_SUB_ADD1 = prove
12946  (`!n x. bernoulli n (x + &1) - bernoulli n x = &n * x pow (n - 1)`,
12947   REWRITE_TAC[BERNOULLI_ADD; REAL_POW_ONE; REAL_MUL_RID] THEN
12948   REWRITE_TAC[BERNOULLI]);;
12949
12950 let BERNOULLI_1 = prove
12951  (`!n. bernoulli n (&1) =
12952        if n = 1 then bernoulli n (&0) + &1 else bernoulli n (&0)`,
12953   GEN_TAC THEN
12954   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM REAL_ADD_LID] THEN
12955   COND_CASES_TAC THENL
12956    [REWRITE_TAC[REAL_ARITH `x = y + &1 <=> x - y = &1`];
12957     ONCE_REWRITE_TAC[GSYM REAL_SUB_0]] THEN
12958   REWRITE_TAC[BERNOULLI_SUB_ADD1; REAL_POW_ZERO] THEN
12959   ASM_REWRITE_TAC[SUB_REFL; REAL_MUL_RID] THEN
12960   ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[REAL_MUL_LZERO] THEN
12961   COND_CASES_TAC THEN REWRITE_TAC[] THEN ASM_ARITH_TAC);;
12962
12963 let SUM_OF_POWERS = prove
12964  (`!m n. sum(0..n) (\k. &k pow m) =
12965          (bernoulli (m + 1) (&n + &1) - bernoulli (m + 1) (&0)) / (&m + &1)`,
12966   REPEAT GEN_TAC THEN
12967   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o BINDER_CONV o RAND_CONV)
12968    [GSYM SUC_SUB1] THEN
12969   REWRITE_TAC[REAL_FIELD `x = y / (&m + &1) <=> (&m + &1) * x = y`] THEN
12970   REWRITE_TAC[GSYM SUM_LMUL; REAL_OF_NUM_SUC; GSYM BERNOULLI_SUB_ADD1] THEN
12971   REWRITE_TAC[ADD1; SUM_DIFFS_ALT; LE_0]);;
12972
12973 let HAS_REAL_DERIVATIVE_BERNOULLI = prove
12974  (`!n x. ((bernoulli n) has_real_derivative (&n * bernoulli (n - 1) x))
12975          (atreal x)`,
12976   INDUCT_TAC THEN GEN_TAC THEN
12977   GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
12978   ONCE_REWRITE_TAC[BERNOULLI_EXPANSION] THEN
12979   REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH; SUB_REFL; CONJUNCT1 real_pow] THEN
12980   REWRITE_TAC[HAS_REAL_DERIVATIVE_CONST; REAL_MUL_LZERO; LE_0] THEN
12981   GEN_REWRITE_TAC (RATOR_CONV o RAND_CONV) [GSYM REAL_ADD_RID] THEN
12982   MATCH_MP_TAC HAS_REAL_DERIVATIVE_ADD THEN
12983   REWRITE_TAC[HAS_REAL_DERIVATIVE_CONST; SUC_SUB1; GSYM SUM_LMUL] THEN
12984   MATCH_MP_TAC HAS_REAL_DERIVATIVE_SUM THEN
12985   REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
12986   X_GEN_TAC `k:num` THEN STRIP_TAC THEN REAL_DIFF_TAC THEN
12987   REWRITE_TAC[ADD1; BINOM_TOP_STEP_REAL] THEN
12988   ASM_SIMP_TAC[GSYM REAL_OF_NUM_ADD; GSYM REAL_OF_NUM_SUB; ARITH_RULE
12989    `k <= n ==> ~(k = n + 1) /\ (n + 1) - k - 1 = n - k /\ k <= n + 1`] THEN
12990   UNDISCH_TAC `k:num <= n` THEN REWRITE_TAC[GSYM REAL_OF_NUM_LE] THEN
12991   CONV_TAC REAL_FIELD);;
12992
12993 add_real_differentiation_theorems
12994  (CONJUNCTS(REWRITE_RULE[FORALL_AND_THM]
12995   (MATCH_MP HAS_REAL_DERIVATIVE_CHAIN_UNIV
12996    (SPEC `n:num` HAS_REAL_DERIVATIVE_BERNOULLI))));;
12997
12998 let REAL_DIFFERENTIABLE_ON_BERNOULLI = prove
12999  (`!n s. (bernoulli n) real_differentiable_on s`,
13000   REWRITE_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE; real_differentiable] THEN
13001   MESON_TAC[HAS_REAL_DERIVATIVE_BERNOULLI;
13002             HAS_REAL_DERIVATIVE_ATREAL_WITHIN]);;
13003
13004 let REAL_CONTINUOUS_ON_BERNOULLI = prove
13005  (`!n s. (bernoulli n) real_continuous_on s`,
13006   MESON_TAC[REAL_DIFFERENTIABLE_ON_BERNOULLI;
13007             REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON]);;
13008
13009 let HAS_REAL_INTEGRAL_BERNOULLI = prove
13010  (`!n. ((bernoulli n) has_real_integral (if n = 0 then &1 else &0))
13011        (real_interval[&0,&1])`,
13012   REPEAT STRIP_TAC THEN MP_TAC(SPECL
13013    [`\x. bernoulli (n + 1) x / (&n + &1)`; `bernoulli n`; `&0`; `&1`]
13014         REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN
13015   REWRITE_TAC[REAL_POS] THEN ANTS_TAC THENL
13016    [REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN
13017     REWRITE_TAC[ADD_SUB; GSYM REAL_OF_NUM_ADD] THEN CONV_TAC REAL_FIELD;
13018     REWRITE_TAC[BERNOULLI_1; ARITH_RULE `n + 1 = 1 <=> n = 0`] THEN
13019     ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[REAL_SUB_REFL] THEN
13020     REWRITE_TAC[REAL_ADD_LID; ADD_CLAUSES; REAL_DIV_1; REAL_ADD_SUB]]);;
13021
13022 let POLYNOMIAL_FUNCTION_BERNOULLI = prove
13023  (`!n. polynomial_function(bernoulli n)`,
13024   GEN_TAC THEN GEN_REWRITE_TAC RAND_CONV [GSYM ETA_AX] THEN
13025   ONCE_REWRITE_TAC[BERNOULLI_EXPANSION] THEN
13026   MATCH_MP_TAC POLYNOMIAL_FUNCTION_SUM THEN
13027   SIMP_TAC[FINITE_NUMSEG; POLYNOMIAL_FUNCTION_MUL; POLYNOMIAL_FUNCTION_POW;
13028            POLYNOMIAL_FUNCTION_ID; POLYNOMIAL_FUNCTION_CONST]);;
13029
13030 let BERNOULLI_UNIQUE = prove
13031  (`!p n. polynomial_function p /\
13032          (!x. p(x + &1) - p(x) = &n * x pow (n - 1)) /\
13033          (real_integral (real_interval[&0,&1]) p = if n = 0 then &1 else &0)
13034          ==> p = bernoulli n`,
13035   REPEAT STRIP_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN
13036   ONCE_REWRITE_TAC[GSYM REAL_SUB_0] THEN
13037   MP_TAC(SPECL [`\x. p x - bernoulli n x`; `p(&0) - bernoulli n (&0)`]
13038    POLYNOMIAL_FUNCTION_FINITE_ROOTS) THEN
13039   ASM_SIMP_TAC[POLYNOMIAL_FUNCTION_SUB;
13040                POLYNOMIAL_FUNCTION_BERNOULLI; ETA_AX] THEN
13041   MATCH_MP_TAC(TAUT `~p /\ (q ==> r) ==> (p <=> ~q) ==> r`) THEN
13042   CONJ_TAC THENL
13043    [REWRITE_TAC[GSYM INFINITE] THEN
13044     MATCH_MP_TAC INFINITE_SUPERSET THEN
13045     EXISTS_TAC `IMAGE (&) (:num)` THEN
13046     SIMP_TAC[INFINITE_IMAGE_INJ; REAL_OF_NUM_EQ; num_INFINITE;
13047              SUBSET; FORALL_IN_IMAGE; IN_UNIV; IN_ELIM_THM] THEN
13048     CONV_TAC(BINDER_CONV SYM_CONV) THEN INDUCT_TAC THEN
13049     ASM_REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN
13050     ASM_MESON_TAC[BERNOULLI_SUB_ADD1; REAL_ARITH
13051      `p - b:real = p' - b' <=> p' - p = b' - b`];
13052     DISCH_TAC THEN X_GEN_TAC `x:real` THEN ONCE_ASM_REWRITE_TAC[] THEN
13053     MATCH_MP_TAC HAS_REAL_INTEGRAL_UNIQUE THEN
13054     EXISTS_TAC `\x. p x - bernoulli n x` THEN
13055     EXISTS_TAC `real_interval[&0,&1]` THEN CONJ_TAC THENL
13056      [GEN_REWRITE_TAC LAND_CONV [REAL_ARITH `x = x * (&1 - &0)`] THEN
13057       ONCE_ASM_REWRITE_TAC[] THEN
13058       MATCH_MP_TAC HAS_REAL_INTEGRAL_CONST THEN REWRITE_TAC[REAL_POS];
13059       GEN_REWRITE_TAC LAND_CONV
13060        [GSYM(SPEC `if n = 0 then &1 else &0` REAL_SUB_REFL)] THEN
13061       MATCH_MP_TAC HAS_REAL_INTEGRAL_SUB THEN
13062       REWRITE_TAC[ETA_AX; HAS_REAL_INTEGRAL_BERNOULLI] THEN
13063       ASM_REWRITE_TAC[HAS_REAL_INTEGRAL_INTEGRABLE_INTEGRAL] THEN
13064       MATCH_MP_TAC REAL_INTEGRABLE_CONTINUOUS THEN
13065       ASM_SIMP_TAC[REAL_CONTINUOUS_ON_POLYNOMIAL_FUNCTION]]]);;
13066
13067 let BERNOULLI_RAABE_2 = prove
13068  (`!n x. bernoulli n ((x + &1) / &2) + bernoulli n (x / &2) =
13069          &2 / &2 pow n * bernoulli n x`,
13070   GEN_TAC THEN ASM_CASES_TAC `n = 0` THEN
13071   ASM_REWRITE_TAC[bernoulli] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
13072   SIMP_TAC[REAL_LT_POW2; REAL_FIELD
13073    `&0 < p ==> (x = &2 / p * y <=> p / &2 * x = y)`] THEN
13074   GEN_REWRITE_TAC I [GSYM FUN_EQ_THM] THEN
13075   REWRITE_TAC[ETA_AX] THEN  MATCH_MP_TAC BERNOULLI_UNIQUE THEN
13076   REPEAT CONJ_TAC THENL
13077    [MATCH_MP_TAC POLYNOMIAL_FUNCTION_LMUL THEN
13078     MATCH_MP_TAC POLYNOMIAL_FUNCTION_ADD THEN CONJ_TAC THEN
13079     MATCH_MP_TAC(REWRITE_RULE[o_DEF] POLYNOMIAL_FUNCTION_o) THEN
13080     REWRITE_TAC[POLYNOMIAL_FUNCTION_BERNOULLI; real_div] THEN
13081     SIMP_TAC[POLYNOMIAL_FUNCTION_ADD; POLYNOMIAL_FUNCTION_CONST;
13082              POLYNOMIAL_FUNCTION_ID; POLYNOMIAL_FUNCTION_RMUL];
13083     REWRITE_TAC[REAL_ARITH `((x + &1) + &1) / &2 = x / &2 + &1`] THEN
13084     REWRITE_TAC[REAL_ARITH `a * (x + y) - a * (y + z):real = a * (x - z)`] THEN
13085     REWRITE_TAC[BERNOULLI_SUB_ADD1; REAL_POW_DIV] THEN GEN_TAC THEN
13086     REWRITE_TAC[REAL_ARITH `a / b * c * d / e:real = c * (a / b / e) * d`] THEN
13087     ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[REAL_MUL_LZERO] THEN
13088     MATCH_MP_TAC(REAL_RING `b = &1 ==> a * b * c = a * c`) THEN
13089     REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC; GSYM REAL_INV_MUL] THEN
13090     REWRITE_TAC[GSYM(CONJUNCT2 real_pow)] THEN
13091     ASM_SIMP_TAC[ARITH_RULE `~(n = 0) ==> SUC(n - 1) = n`] THEN
13092     REWRITE_TAC[GSYM real_div] THEN MATCH_MP_TAC REAL_DIV_REFL THEN
13093     REWRITE_TAC[REAL_POW_EQ_0] THEN REAL_ARITH_TAC;
13094     SUBGOAL_THEN
13095      `(bernoulli n) real_integrable_on real_interval[&0,&1 / &2] /\
13096       (bernoulli n) real_integrable_on real_interval[&1 / &2,&1]`
13097     MP_TAC THENL
13098      [CONJ_TAC THEN MATCH_MP_TAC REAL_INTEGRABLE_CONTINUOUS THEN
13099       SIMP_TAC[REAL_CONTINUOUS_ON_POLYNOMIAL_FUNCTION;
13100                POLYNOMIAL_FUNCTION_BERNOULLI];
13101       DISCH_THEN(CONJUNCTS_THEN(MP_TAC o
13102        MATCH_MP (REWRITE_RULE[IMP_CONJ] HAS_REAL_INTEGRAL_AFFINITY) o
13103        MATCH_MP REAL_INTEGRABLE_INTEGRAL))] THEN
13104     REWRITE_TAC[REAL_ARITH `m * (x - c):real = m * x + m * --c`] THEN
13105     REWRITE_TAC[IMAGE_AFFINITY_REAL_INTERVAL; IMP_IMP] THEN
13106     DISCH_THEN(CONJUNCTS_THEN2
13107      (MP_TAC o SPECL [`inv(&2)`; `inv(&2)`])
13108      (MP_TAC o SPECL [`inv(&2)`; `&0`])) THEN
13109     REWRITE_TAC[REAL_INTERVAL_EQ_EMPTY] THEN
13110     CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN
13111     DISCH_THEN(MP_TAC o MATCH_MP HAS_REAL_INTEGRAL_ADD) THEN
13112     DISCH_THEN(MP_TAC o SPEC `&2 pow n / &2` o
13113         MATCH_MP HAS_REAL_INTEGRAL_LMUL) THEN
13114     REWRITE_TAC[REAL_ARITH `&1 / &2 * x + &1 / &2 = (x + &1) / &2`;
13115                 REAL_ARITH `&1 / &2 * x + &0 = x / &2`] THEN
13116     DISCH_THEN(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN
13117     ASM_REWRITE_TAC[REAL_ENTIRE] THEN DISJ2_TAC THEN
13118     REWRITE_TAC[REAL_ARITH `&2 * x + &2 * y = &0 <=> y + x = &0`] THEN
13119     IMP_REWRITE_TAC[REAL_INTEGRAL_COMBINE] THEN
13120     CONV_TAC REAL_RAT_REDUCE_CONV THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
13121     REWRITE_TAC[GSYM HAS_REAL_INTEGRAL_INTEGRABLE_INTEGRAL] THEN
13122     ASM_MESON_TAC[HAS_REAL_INTEGRAL_BERNOULLI]]);;
13123
13124 let BERNOULLI_HALF = prove
13125  (`!n. bernoulli n (&1 / &2) = (&2 / &2 pow n - &1) * bernoulli n (&0)`,
13126   GEN_TAC THEN
13127   MP_TAC(ISPECL [`n:num`; `&1`] BERNOULLI_RAABE_2) THEN
13128   CONV_TAC REAL_RAT_REDUCE_CONV THEN
13129   REWRITE_TAC[REAL_ARITH `a + b:real = c * a <=> b = (c - &1) * a`] THEN
13130   DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[BERNOULLI_1] THEN
13131   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;
13132
13133 let BERNOULLI_REFLECT = prove
13134  (`!n x. bernoulli n (&1 - x) = --(&1) pow n * bernoulli n x`,
13135   ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN GEN_TAC THEN
13136   SUBGOAL_THEN
13137    `!n. sum(0..n) (\k. &(binom(n + 1,k)) *
13138                        (bernoulli k (&1 - x) - --(&1) pow k * bernoulli k x)) =
13139         &0`
13140   ASSUME_TAC THENL
13141    [REWRITE_TAC[SUM_SUB_NUMSEG; REAL_SUB_LDISTRIB] THEN
13142     X_GEN_TAC `n:num` THEN REWRITE_TAC[REAL_SUB_0; BERNOULLI_ALT] THEN
13143     TRANS_TAC EQ_TRANS
13144      `--(&1) pow n * (bernoulli (n + 1) x - bernoulli (n + 1) (x - &1))` THEN
13145     CONJ_TAC THENL
13146      [MP_TAC(ISPECL [`n + 1`; `x - &1`] BERNOULLI_SUB_ADD1) THEN
13147       REWRITE_TAC[REAL_ARITH `x - a + a:real = x`] THEN
13148       DISCH_THEN SUBST1_TAC THEN
13149       REWRITE_TAC[ADD_SUB; REAL_ARITH `&1 - x = --(&1) * (x - &1)`] THEN
13150       REWRITE_TAC[REAL_POW_MUL; REAL_MUL_AC; GSYM REAL_OF_NUM_ADD];
13151       MATCH_MP_TAC(REAL_FIELD
13152        `z pow 2 = &1 /\ z * x = y ==> z * y = x`) THEN
13153       REWRITE_TAC[REAL_POW_POW] THEN CONJ_TAC THENL
13154        [REWRITE_TAC[REAL_POW_NEG; EVEN_MULT; ARITH; REAL_POW_ONE];
13155         REWRITE_TAC[GSYM SUM_LMUL]] THEN
13156       MP_TAC(ISPECL [`SUC n`; `x:real`; `--(&1)`] BERNOULLI_ADD) THEN
13157       REWRITE_TAC[SUM_CLAUSES_NUMSEG; LE_0; BINOM_REFL; SUB_REFL] THEN
13158       REWRITE_TAC[GSYM real_sub; ADD1; REAL_MUL_LID; CONJUNCT1 real_pow] THEN
13159       DISCH_THEN SUBST1_TAC THEN
13160       MATCH_MP_TAC(REAL_ARITH `--s' = s ==> s = b - (s' + b * &1)`) THEN
13161       REWRITE_TAC[GSYM SUM_NEG] THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN
13162       X_GEN_TAC `k:num` THEN STRIP_TAC THEN REWRITE_TAC[] THEN
13163       MATCH_MP_TAC(REAL_RING
13164        `--(&1) pow 1 * p = q * r ==> --(b * k * p) = q * b * r * k`) THEN
13165       REWRITE_TAC[GSYM REAL_POW_ADD] THEN REWRITE_TAC[REAL_POW_NEG] THEN
13166       REWRITE_TAC[EVEN_ADD; EVEN_SUB; REAL_POW_ONE; ARITH] THEN
13167       ASM_SIMP_TAC[ARITH_RULE `k <= n ==> ~(n + 1 <= k)`] THEN
13168       REWRITE_TAC[TAUT `~(~p <=> q) <=> (p <=> q)`]];
13169     MATCH_MP_TAC num_WF THEN MATCH_MP_TAC num_INDUCTION THEN
13170     REWRITE_TAC[bernoulli; CONJUNCT1 real_pow; REAL_MUL_LID] THEN
13171     X_GEN_TAC `n:num` THEN DISCH_THEN(K ALL_TAC) THEN
13172     REWRITE_TAC[LT_SUC_LE] THEN DISCH_THEN
13173      (fun th -> FIRST_X_ASSUM(MP_TAC o SPEC `SUC n`) THEN ASSUME_TAC th) THEN
13174     REWRITE_TAC[SUM_CLAUSES_NUMSEG; LE_0] THEN
13175     ASM_SIMP_TAC[REAL_SUB_REFL; REAL_MUL_RZERO; SUM_0; REAL_ADD_LID] THEN
13176     REWRITE_TAC[GSYM ADD1; BINOM_PENULT; GSYM REAL_OF_NUM_SUC] THEN
13177     REWRITE_TAC[REAL_ENTIRE; REAL_SUB_0] THEN
13178     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]);;
13179
13180 let BERNOULLI_1_0 = prove
13181  (`!n. bernoulli n (&1) = --(&1) pow n * bernoulli n (&0)`,
13182   GEN_TAC THEN SUBST1_TAC(REAL_ARITH `&0 = &1 - &1`) THEN
13183   REWRITE_TAC[BERNOULLI_REFLECT; REAL_MUL_ASSOC; GSYM REAL_POW_MUL] THEN
13184   CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[REAL_POW_ONE; REAL_MUL_LID]);;
13185
13186 let BERNOULLI_NUMBER_ZERO = prove
13187  (`!n. ODD n /\ ~(n = 1) ==> bernoulli n (&0) = &0`,
13188   REPEAT STRIP_TAC THEN
13189   MP_TAC(SPEC `n:num` BERNOULLI_1) THEN
13190   MP_TAC(SPEC `n:num` BERNOULLI_1_0) THEN
13191   ASM_REWRITE_TAC[REAL_POW_NEG; REAL_POW_ONE; GSYM NOT_ODD] THEN
13192   REAL_ARITH_TAC);;
13193
13194 let BERNOULLI_EVEN_BOUND = prove
13195  (`!n x. EVEN n /\ x IN real_interval[&0,&1]
13196          ==> abs(bernoulli n x) <= abs(bernoulli n (&0))`,
13197   let lemma = prove
13198    (`(!n x. x IN real_interval(&0,&1 / &2)
13199             ==> ~(bernoulli (2 * n + 1) x = &0)) /\
13200      (!n x y. x IN real_interval(&0,&1 / &2) /\
13201               y IN real_interval(&0,&1 / &2) /\
13202               bernoulli (2 * n) x = &0 /\ bernoulli (2 * n) y = &0
13203               ==> x = y)`,
13204     REWRITE_TAC[AND_FORALL_THM; IN_REAL_INTERVAL] THEN INDUCT_TAC THENL
13205      [CONV_TAC NUM_REDUCE_CONV THEN
13206       CONV_TAC(ONCE_DEPTH_CONV BERNOULLI_CONV) THEN REAL_ARITH_TAC;
13207       POP_ASSUM MP_TAC THEN REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN
13208     MATCH_MP_TAC(TAUT `q /\ (q ==> p) ==> p /\ q`) THEN CONJ_TAC THENL
13209      [MATCH_MP_TAC REAL_WLOG_LT THEN REWRITE_TAC[] THEN
13210       CONJ_TAC THENL [REWRITE_TAC[CONJ_ACI; EQ_SYM_EQ]; ALL_TAC] THEN
13211       MAP_EVERY X_GEN_TAC [`x:real`; `y:real`] THEN REPEAT STRIP_TAC THEN
13212       MP_TAC(ISPECL
13213        [`\x. bernoulli (2 * SUC n) x / (&2 * &n + &2)`;
13214         `bernoulli (2 * n + 1)`; `x:real`; `y:real`]
13215           REAL_ROLLE_SIMPLE) THEN
13216       ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
13217        [REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN
13218         REWRITE_TAC[GSYM REAL_OF_NUM_MUL; GSYM REAL_OF_NUM_SUC;
13219                     ARITH_RULE `2 * SUC n - 1 = 2 * n + 1`] THEN
13220         CONV_TAC REAL_FIELD;
13221         REWRITE_TAC[IN_REAL_INTERVAL; LEFT_IMP_EXISTS_THM] THEN
13222         X_GEN_TAC `z:real` THEN
13223         DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
13224         ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN DISCH_TAC THEN
13225         FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_REAL_INTERVAL] THEN
13226         ASM_REAL_ARITH_TAC];
13227       POP_ASSUM_LIST(K ALL_TAC) THEN DISCH_TAC THEN
13228       X_GEN_TAC `x:real` THEN REPEAT STRIP_TAC THEN
13229       MP_TAC(ISPECL
13230        [`\x. bernoulli (2 * SUC n + 1) x / (&2 * &n + &3)`;
13231         `bernoulli (2 * SUC n)`; `&0`; `x:real`]
13232           REAL_ROLLE_SIMPLE) THEN
13233       ASM_REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL
13234        [REWRITE_TAC[real_div; REAL_MUL_LZERO; REAL_ENTIRE] THEN DISJ1_TAC THEN
13235         MATCH_MP_TAC BERNOULLI_NUMBER_ZERO THEN
13236         REWRITE_TAC[ODD_ADD; ODD_MULT; ADD1; ARITH] THEN ARITH_TAC;
13237         REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN
13238         SIMP_TAC[ADD_SUB; GSYM REAL_OF_NUM_MUL; GSYM REAL_OF_NUM_ADD; ADD1] THEN
13239         CONV_TAC REAL_FIELD;
13240         REWRITE_TAC[IN_REAL_INTERVAL; NOT_EXISTS_THM] THEN
13241         X_GEN_TAC `u:real` THEN STRIP_TAC] THEN
13242       MP_TAC(ISPECL
13243        [`\x. bernoulli (2 * SUC n + 1) x / (&2 * &n + &3)`;
13244         `bernoulli (2 * SUC n)`; `x:real`; `&1 / &2`]
13245           REAL_ROLLE_SIMPLE) THEN
13246       ASM_REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL
13247        [REWRITE_TAC[real_div; REAL_MUL_LZERO] THEN CONV_TAC SYM_CONV THEN
13248         REWRITE_TAC[REAL_ENTIRE] THEN DISJ1_TAC THEN
13249         CONV_TAC REAL_RAT_REDUCE_CONV THEN REWRITE_TAC[BERNOULLI_HALF] THEN
13250         REWRITE_TAC[REAL_ENTIRE] THEN DISJ2_TAC THEN
13251         MATCH_MP_TAC BERNOULLI_NUMBER_ZERO THEN
13252         REWRITE_TAC[ODD_ADD; ODD_MULT; ADD1; ARITH] THEN ARITH_TAC;
13253         REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN
13254         SIMP_TAC[ADD_SUB; GSYM REAL_OF_NUM_MUL;
13255                  GSYM REAL_OF_NUM_ADD; ADD1] THEN
13256         CONV_TAC REAL_FIELD;
13257         REWRITE_TAC[IN_REAL_INTERVAL; NOT_EXISTS_THM] THEN
13258         X_GEN_TAC `v:real` THEN STRIP_TAC] THEN
13259       FIRST_X_ASSUM(MP_TAC o SPECL [`u:real`; `v:real`]) THEN
13260       ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC]) in
13261   REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN
13262   ASM_CASES_TAC `n = 0` THEN ASM_REWRITE_TAC[bernoulli; REAL_LE_REFL] THEN
13263   MP_TAC(ISPECL [`\x. abs(bernoulli n x)`; `real_interval[&0,&1]`]
13264         REAL_CONTINUOUS_ATTAINS_SUP) THEN
13265   REWRITE_TAC[REAL_COMPACT_INTERVAL; REAL_INTERVAL_NE_EMPTY; REAL_POS] THEN
13266   ANTS_TAC THENL
13267    [MATCH_MP_TAC REAL_CONTINUOUS_ON_ABS THEN
13268     MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON THEN
13269     REWRITE_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE] THEN
13270     REPEAT STRIP_TAC THEN REAL_DIFFERENTIABLE_TAC;
13271     REWRITE_TAC[IN_REAL_INTERVAL] THEN
13272     DISCH_THEN(X_CHOOSE_THEN `z:real` MP_TAC)] THEN
13273   ASM_CASES_TAC `z = &0` THEN ASM_SIMP_TAC[] THEN
13274   ASM_CASES_TAC `z = &1` THEN ASM_REWRITE_TAC[BERNOULLI_1_0] THEN
13275   ASM_SIMP_TAC[REAL_ABS_MUL; REAL_ABS_POW; REAL_ABS_NEG; REAL_POW_ONE;
13276                REAL_ABS_NUM; REAL_MUL_LID] THEN
13277   STRIP_TAC THEN
13278   MP_TAC(ISPECL [`bernoulli n`; `&n * bernoulli (n - 1) z`;
13279                  `z:real`; `real_interval(&0,&1)`]
13280         REAL_DERIVATIVE_ZERO_MAXMIN) THEN
13281   REWRITE_TAC[REAL_OPEN_REAL_INTERVAL; IN_REAL_INTERVAL] THEN ANTS_TAC THENL
13282    [CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
13283     REWRITE_TAC[HAS_REAL_DERIVATIVE_BERNOULLI] THEN
13284     ASM_CASES_TAC `&0 <= bernoulli n z` THENL
13285      [DISJ1_TAC; DISJ2_TAC] THEN
13286     X_GEN_TAC `y:real` THEN STRIP_TAC THEN
13287     FIRST_X_ASSUM(MP_TAC o SPEC `y:real`) THEN
13288     ASM_REAL_ARITH_TAC;
13289     ALL_TAC] THEN
13290   ASM_REWRITE_TAC[REAL_ENTIRE; REAL_OF_NUM_EQ] THEN DISCH_TAC THEN
13291   ASM_CASES_TAC `z = &1 / &2` THENL
13292    [MATCH_MP_TAC(REAL_ARITH `!z. x <= z /\ z <= &1 * y ==> x <= y`) THEN
13293     EXISTS_TAC `abs(bernoulli n (&1 / &2))` THEN
13294     CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
13295     REWRITE_TAC[BERNOULLI_HALF; REAL_ABS_MUL] THEN
13296     MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[REAL_ABS_POS] THEN
13297     MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= &1 ==> abs(x - &1) <= &1`) THEN
13298     SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_LT_POW2] THEN
13299     REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; REAL_POS] THEN
13300     MATCH_MP_TAC(REAL_ARITH `&2 pow 1 <= x ==> &2 <= x`) THEN
13301     MATCH_MP_TAC REAL_POW_MONO THEN REWRITE_TAC[REAL_OF_NUM_LE] THEN
13302     ASM_ARITH_TAC;
13303     ALL_TAC] THEN
13304   SUBGOAL_THEN
13305    `&0 < z /\ z < &1 / &2 \/ &1 / &2 < z /\ z < &1`
13306   STRIP_ASSUME_TAC THENL
13307    [ASM_REAL_ARITH_TAC;
13308     MP_TAC(ISPECL [`(n - 2) DIV 2`; `z:real`] (CONJUNCT1 lemma)) THEN
13309     ASM_REWRITE_TAC[IN_REAL_INTERVAL];
13310     MP_TAC(ISPECL [`(n - 2) DIV 2`; `&1 - z`] (CONJUNCT1 lemma)) THEN
13311     ASM_REWRITE_TAC[IN_REAL_INTERVAL] THEN
13312     ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[BERNOULLI_REFLECT]] THEN
13313     REWRITE_TAC[REAL_ENTIRE; REAL_POW_EQ_0] THEN
13314     CONV_TAC REAL_RAT_REDUCE_CONV] THEN
13315   SUBGOAL_THEN `2 * (n - 2) DIV 2 + 1 = n - 1`
13316    (fun th -> ASM_REWRITE_TAC[th]) THEN
13317   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EVEN_EXISTS]) THEN
13318   DISCH_THEN(CHOOSE_THEN SUBST_ALL_TAC) THEN
13319   UNDISCH_TAC `~(2 * m = 0)` THEN SPEC_TAC(`m:num`,`m:num`) THEN
13320   INDUCT_TAC THEN REWRITE_TAC[MULT_CLAUSES; ADD_SUB2] THEN
13321   SIMP_TAC[DIV_MULT; ARITH_EQ] THEN ARITH_TAC);;
13322
13323 let BERNOULLI_NUMBER_EQ_0 = prove
13324  (`!n. bernoulli n (&0) = &0 <=> ODD n /\ ~(n = 1)`,
13325   GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[BERNOULLI_NUMBER_ZERO] THEN
13326   ASM_CASES_TAC `n = 1` THEN
13327   ASM_REWRITE_TAC[BERNOULLI_CONV `bernoulli 1 (&0)`] THEN
13328   CONV_TAC REAL_RAT_REDUCE_CONV THEN DISCH_TAC THEN
13329   DISJ_CASES_TAC(SPEC `n:num` EVEN_OR_ODD) THEN ASM_REWRITE_TAC[] THEN
13330   MP_TAC(ISPECL [`n:num`; `\k. &(binom(n,n - k)) * bernoulli (n - k) (&0)`]
13331         REAL_POLYFUN_FINITE_ROOTS) THEN
13332   MATCH_MP_TAC(TAUT `q /\ ~p ==> (p <=> q) ==> r`) THEN CONJ_TAC THENL
13333    [EXISTS_TAC `n:num` THEN SIMP_TAC[IN_NUMSEG; LE_0; LE_REFL; SUB_REFL] THEN
13334     REWRITE_TAC[binom; REAL_MUL_RID; bernoulli] THEN REAL_ARITH_TAC;
13335     REWRITE_TAC[GSYM INFINITE] THEN MATCH_MP_TAC INFINITE_SUPERSET THEN
13336     EXISTS_TAC `real_interval[&0,&1]` THEN
13337     REWRITE_TAC[real_interval; INFINITE; FINITE_REAL_INTERVAL] THEN
13338     CONV_TAC REAL_RAT_REDUCE_CONV THEN
13339     REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN
13340     X_GEN_TAC `x:real` THEN STRIP_TAC THEN
13341     MP_TAC(ISPECL [`n:num`; `x:real`] BERNOULLI_EVEN_BOUND) THEN
13342     ASM_REWRITE_TAC[IN_REAL_INTERVAL;
13343       REAL_ARITH `abs x <= abs(&0) <=> x = &0`] THEN
13344     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EQ_TRANS) THEN
13345     GEN_REWRITE_TAC RAND_CONV [BERNOULLI_EXPANSION] THEN
13346     MATCH_MP_TAC SUM_EQ_GENERAL_INVERSES THEN
13347     REPEAT(EXISTS_TAC `\k:num. n - k`) THEN
13348     SIMP_TAC[IN_NUMSEG; ARITH_RULE `k:num <= n ==> n - (n - k) = k`] THEN
13349     REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN ARITH_TAC]);;
13350
13351 (* ------------------------------------------------------------------------- *)
13352 (* This is a simple though sub-optimal bound (we can actually get            *)
13353 (* |B_{2n+1}(x)| <= (2n + 1) / (2 pi) * |B_{2n}(0)| with more work).         *)
13354 (* ------------------------------------------------------------------------- *)
13355
13356 let BERNOULLI_BOUND = prove
13357  (`!n x. x IN real_interval[&0,&1]
13358          ==> abs(bernoulli n x)
13359              <= max (&n / &2) (&1) * abs(bernoulli (2 * n DIV 2) (&0))`,
13360   REPEAT STRIP_TAC THEN DISJ_CASES_TAC(SPEC `n:num` EVEN_OR_ODD) THENL
13361    [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EVEN_EXISTS]);
13362     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [ODD_EXISTS])] THEN
13363   DISCH_THEN(X_CHOOSE_THEN `m:num` SUBST_ALL_TAC) THENL
13364    [REWRITE_TAC[ARITH_RULE `(2 * m) DIV 2 = m`] THEN
13365     MATCH_MP_TAC(REAL_ARITH
13366      `&1 * y <= max x (&1) * y /\ a <= y ==> a <= max x (&1) * y`) THEN
13367     SIMP_TAC[REAL_LE_RMUL; REAL_ABS_POS; REAL_ARITH `y <= max x y`] THEN
13368     MATCH_MP_TAC BERNOULLI_EVEN_BOUND THEN ASM_REWRITE_TAC[EVEN_MULT; ARITH];
13369     POP_ASSUM MP_TAC THEN SPEC_TAC(`x:real`,`x:real`) THEN
13370     MATCH_MP_TAC(MESON[]
13371      `!Q. ((!x. P x /\ Q x ==> R x) ==> (!x. P x ==> R x)) /\
13372           (!x. P x /\ Q x ==> R x)
13373           ==> !x. P x ==> R x`) THEN
13374     EXISTS_TAC `\x. x IN real_interval[&0,&1 / &2]` THEN CONJ_TAC THENL
13375      [REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN
13376       ASM_CASES_TAC `x <= &1 / &2` THEN ASM_SIMP_TAC[] THEN
13377       FIRST_ASSUM(MP_TAC o SPEC `&1 - x`) THEN
13378       ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
13379       REWRITE_TAC[BERNOULLI_REFLECT; REAL_ABS_MUL; REAL_ABS_POW] THEN
13380       REWRITE_TAC[REAL_ABS_NEG; REAL_ABS_NUM; REAL_MUL_LID; REAL_POW_ONE];
13381       REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN
13382       REWRITE_TAC[ARITH_RULE `SUC(2 * m) DIV 2 = m`] THEN
13383       REWRITE_TAC[GSYM REAL_OF_NUM_SUC; GSYM REAL_OF_NUM_MUL] THEN
13384       REWRITE_TAC[ADD1; REAL_ARITH `(x + &1) + &1 = x + &2`] THEN
13385       ASM_CASES_TAC `m = 0` THENL
13386        [ASM_REWRITE_TAC[MULT_CLAUSES; ADD_CLAUSES] THEN
13387         CONV_TAC(ONCE_DEPTH_CONV BERNOULLI_CONV) THEN ASM_REAL_ARITH_TAC;
13388         MP_TAC(ISPECL [`\x. bernoulli (2 * m + 1) x / &(2 * m + 1)`;
13389                        `bernoulli (2 * m)`; `&0`; `x:real`]
13390           REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN
13391         ASM_SIMP_TAC[BERNOULLI_NUMBER_ZERO; ODD_ADD; ODD_MULT; ARITH;
13392                      ARITH_RULE `2 * m + 1 = 1 <=> m = 0`] THEN
13393         ANTS_TAC THENL
13394          [REPEAT STRIP_TAC THEN REAL_DIFF_TAC THEN REWRITE_TAC[ADD_SUB] THEN
13395           REWRITE_TAC[GSYM REAL_OF_NUM_ADD; GSYM REAL_OF_NUM_MUL] THEN
13396           CONV_TAC REAL_FIELD;
13397           DISCH_THEN(MP_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN
13398           REWRITE_TAC[GSYM REAL_OF_NUM_ADD; GSYM REAL_OF_NUM_MUL] THEN
13399           REWRITE_TAC[REAL_FIELD
13400            `i = b / (&2 * &m + &1) - &0 / (&2 * &m + &1) <=>
13401             b = (&2 * &m + &1) * i`] THEN DISCH_THEN SUBST1_TAC THEN
13402           REWRITE_TAC[real_max; REAL_ARITH `(x + &1) / &2 <= &1 <=> x <= &1`;
13403                       REAL_OF_NUM_MUL; REAL_OF_NUM_LE] THEN
13404           ASM_REWRITE_TAC[ARITH_RULE `2 * m <= 1 <=> m = 0`] THEN
13405           REWRITE_TAC[GSYM REAL_OF_NUM_MUL; real_div; GSYM REAL_MUL_ASSOC] THEN
13406           REWRITE_TAC[REAL_ABS_MUL; REAL_ARITH
13407            `abs(&2 * &n + &1) = &2 * &n + &1`] THEN
13408           MATCH_MP_TAC REAL_LE_LMUL THEN
13409           CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN
13410           TRANS_TAC REAL_LE_TRANS
13411             `real_integral (real_interval [&0,x])
13412                            (\x. abs(bernoulli (2 * m) (&0)))` THEN
13413           CONJ_TAC THENL
13414            [MATCH_MP_TAC REAL_INTEGRAL_ABS_BOUND_INTEGRAL THEN
13415             SIMP_TAC[REAL_INTEGRABLE_CONST; REAL_INTEGRABLE_CONTINUOUS;
13416                      REAL_CONTINUOUS_ON_BERNOULLI] THEN
13417             REPEAT STRIP_TAC THEN MATCH_MP_TAC BERNOULLI_EVEN_BOUND THEN
13418             REWRITE_TAC[EVEN_MULT; ARITH; IN_REAL_INTERVAL] THEN
13419             RULE_ASSUM_TAC(REWRITE_RULE[IN_REAL_INTERVAL]) THEN
13420             ASM_REAL_ARITH_TAC;
13421             ASM_SIMP_TAC[REAL_INTEGRAL_CONST] THEN
13422             REWRITE_TAC[REAL_ARITH `a * (x - &0) = x * a`] THEN
13423             MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[REAL_ABS_POS] THEN
13424             ASM_REAL_ARITH_TAC]]]]]);;
13425
13426 (* ------------------------------------------------------------------------- *)
13427 (* Absolutely integrable functions remain so modified by Bernolli sawtooth.  *)
13428 (* ------------------------------------------------------------------------- *)
13429
13430 let ABSOLUTELY_INTEGRABLE_ON_MUL_BERNOULLI_FRAC = prove
13431  (`!f:real^1->real^N s n.
13432         f absolutely_integrable_on s
13433         ==> (\x. bernoulli n (frac(drop x)) % f x)
13434             absolutely_integrable_on s`,
13435   REPEAT GEN_TAC THEN
13436   ONCE_REWRITE_TAC[GSYM ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV] THEN
13437   DISCH_TAC THEN MP_TAC(ISPECL
13438    [`\x y:real^N. drop(x) % y`;
13439     `\x:real^1. lift(bernoulli n (frac (drop x)))`;
13440     `\x. if x IN s then (f:real^1->real^N) x else vec 0`; `(:real^1)`]
13441    ABSOLUTELY_INTEGRABLE_BOUNDED_MEASURABLE_PRODUCT) THEN
13442   ASM_REWRITE_TAC[LIFT_DROP; BILINEAR_DROP_MUL] THEN
13443   ONCE_REWRITE_TAC[COND_RAND] THEN REWRITE_TAC[VECTOR_MUL_RZERO] THEN
13444   DISCH_THEN MATCH_MP_TAC THEN CONJ_TAC THENL
13445    [SUBGOAL_THEN
13446      `(\x. lift(bernoulli n (frac (drop x)))) =
13447       (lift o bernoulli n o drop) o (lift o frac o drop)`
13448     SUBST1_TAC THENL [REWRITE_TAC[o_DEF; LIFT_DROP]; ALL_TAC] THEN
13449     MATCH_MP_TAC MEASURABLE_ON_COMPOSE_CONTINUOUS THEN CONJ_TAC THENL
13450      [MATCH_MP_TAC
13451         CONTINUOUS_AE_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET THEN
13452       EXISTS_TAC `IMAGE lift integer` THEN
13453       SIMP_TAC[LEBESGUE_MEASURABLE_UNIV; NEGLIGIBLE_COUNTABLE;
13454                COUNTABLE_IMAGE; COUNTABLE_INTEGER] THEN
13455       MATCH_MP_TAC CONTINUOUS_AT_IMP_CONTINUOUS_ON THEN
13456       REWRITE_TAC[FORALL_LIFT; IN_DIFF; IN_UNIV; LIFT_IN_IMAGE_LIFT] THEN
13457       REWRITE_TAC[IN] THEN
13458       REWRITE_TAC[GSYM REAL_CONTINUOUS_CONTINUOUS_ATREAL] THEN
13459       REWRITE_TAC[REAL_CONTINUOUS_FRAC];
13460       MP_TAC(SPECL [`n:num`; `(:real)`] REAL_CONTINUOUS_ON_BERNOULLI) THEN
13461       REWRITE_TAC[REAL_CONTINUOUS_ON; IMAGE_LIFT_UNIV]];
13462     REWRITE_TAC[bounded; FORALL_IN_IMAGE; IN_UNIV; NORM_LIFT] THEN
13463     SUBGOAL_THEN `real_compact (IMAGE (bernoulli n) (real_interval[&0,&1]))`
13464     MP_TAC THENL
13465      [MATCH_MP_TAC REAL_COMPACT_CONTINUOUS_IMAGE THEN
13466       REWRITE_TAC[REAL_CONTINUOUS_ON_BERNOULLI; REAL_COMPACT_INTERVAL];
13467       DISCH_THEN(MP_TAC o MATCH_MP REAL_COMPACT_IMP_BOUNDED) THEN
13468       REWRITE_TAC[real_bounded; FORALL_IN_IMAGE; IN_REAL_INTERVAL] THEN
13469       MESON_TAC[FLOOR_FRAC; REAL_LT_IMP_LE]]]);;
13470
13471 (* ------------------------------------------------------------------------- *)
13472 (* The Euler-Maclaurin summation formula for real and complex functions.     *)
13473 (* ------------------------------------------------------------------------- *)
13474
13475 let REAL_EULER_MACLAURIN = prove
13476  (`!f m n p.
13477     m <= n /\
13478     (!k x. k <= 2 * p + 1 /\ x IN real_interval[&m,&n]
13479            ==> ((f k) has_real_derivative f (k + 1) x)
13480                (atreal x within real_interval [&m,&n]))
13481     ==> (\x. bernoulli (2 * p + 1) (frac x) * f (2 * p + 1) x)
13482         real_integrable_on real_interval[&m,&n] /\
13483         sum(m..n) (\i. f 0 (&i)) =
13484         real_integral (real_interval [&m,&n]) (f 0) +
13485         (f 0 (&m) + f 0 (&n)) / &2 +
13486         sum (1..p) (\k. bernoulli (2 * k) (&0) / &(FACT(2 * k)) *
13487                         (f (2 * k - 1) (&n) - f (2 * k - 1) (&m))) +
13488         real_integral (real_interval [&m,&n])
13489                       (\x. bernoulli (2 * p + 1) (frac x) * f (2 * p + 1) x) /
13490         &(FACT(2 * p + 1))`,
13491   let lemma = prove
13492    (`!f k m n.
13493           f real_continuous_on real_interval[&m,&n] /\ m < n
13494           ==> ((\x. bernoulli k (frac x) * f x) has_real_integral
13495                sum(m..n-1) (\j. real_integral (real_interval[&j,&j + &1])
13496                                              (\x. bernoulli k (x - &j) * f x)))
13497               (real_interval[&m,&n])`,
13498     REPLICATE_TAC 3 GEN_TAC THEN INDUCT_TAC THEN REWRITE_TAC[CONJUNCT1 LT] THEN
13499     REWRITE_TAC[GSYM REAL_OF_NUM_SUC; LT_SUC_LE; SUC_SUB1] THEN STRIP_TAC THEN
13500     ASM_CASES_TAC `m:num = n` THENL
13501      [ASM_REWRITE_TAC[SUM_SING_NUMSEG] THEN (**** one ***) ALL_TAC;
13502       SUBGOAL_THEN `0 < n` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
13503       ASM_SIMP_TAC[SUM_CLAUSES_RIGHT] THEN
13504       MATCH_MP_TAC HAS_REAL_INTEGRAL_COMBINE THEN EXISTS_TAC `&n` THEN
13505       ASM_REWRITE_TAC[REAL_OF_NUM_LE; REAL_ARITH `x <= x + &1`] THEN
13506       CONJ_TAC THENL
13507        [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[LT_LE] THEN
13508         FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
13509           REAL_CONTINUOUS_ON_SUBSET)) THEN
13510         REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN
13511         ASM_REWRITE_TAC[REAL_OF_NUM_LE; REAL_ARITH `x <= x + &1`; LE_REFL];
13512         ALL_TAC]] THEN
13513     MATCH_MP_TAC(MESON[REAL_INTEGRAL_SPIKE; HAS_REAL_INTEGRAL_INTEGRAL;
13514                        REAL_INTEGRABLE_SPIKE]
13515      `!t. g real_integrable_on s /\ real_negligible t /\
13516           (!x. x IN s DIFF t ==> f x = g x)
13517           ==>  (f has_real_integral (real_integral s g)) s`) THEN
13518     EXISTS_TAC `{&n + &1}` THEN REWRITE_TAC[REAL_NEGLIGIBLE_SING] THEN
13519     (CONJ_TAC THENL
13520       [MATCH_MP_TAC REAL_INTEGRABLE_CONTINUOUS THEN
13521        MATCH_MP_TAC REAL_CONTINUOUS_ON_MUL THEN CONJ_TAC THENL
13522         [MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON THEN
13523          REWRITE_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE] THEN
13524          REPEAT STRIP_TAC THEN REAL_DIFFERENTIABLE_TAC;
13525          FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
13526            REAL_CONTINUOUS_ON_SUBSET)) THEN
13527          REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN
13528          REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE] THEN ASM_ARITH_TAC];
13529        REWRITE_TAC[IN_DIFF; IN_SING; IN_REAL_INTERVAL] THEN
13530        X_GEN_TAC `x:real` THEN STRIP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
13531        AP_TERM_TAC THEN     REWRITE_TAC[GSYM FRAC_UNIQUE] THEN
13532        REWRITE_TAC[REAL_ARITH `x - (x - &n) = &n`; INTEGER_CLOSED] THEN
13533        ASM_REAL_ARITH_TAC])) in
13534   let step = prove
13535    (`!f f' k m n.
13536           m < n /\
13537           (!x. x IN real_interval[&m,&n]
13538                ==> (f has_real_derivative f' x)
13539                    (atreal x within real_interval[&m,&n])) /\
13540           f' real_continuous_on real_interval[&m,&n]
13541           ==> real_integral (real_interval[&m,&n])
13542                             (\x. bernoulli (k + 1) (frac x) * f' x) =
13543               (bernoulli (k + 1) (&0) * (f(&n) - f(&m)) +
13544                (if k = 0 then sum(m+1..n) (\i. f(&i)) else &0)) -
13545               (&k + &1) *
13546               real_integral (real_interval[&m,&n])
13547                             (\x. bernoulli k (frac x) * f x)`,
13548     REPEAT STRIP_TAC THEN
13549     SUBGOAL_THEN `f real_continuous_on real_interval[&m,&n]` ASSUME_TAC THENL
13550      [ASM_MESON_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE;
13551                     real_differentiable;
13552                     REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON];
13553       ASM_SIMP_TAC[REWRITE_RULE[HAS_REAL_INTEGRAL_INTEGRABLE_INTEGRAL]
13554        lemma]] THEN
13555     TRANS_TAC EQ_TRANS
13556       `sum(m..n-1)
13557           (\j. (bernoulli (k + 1) (&0) * (f (&j + &1) - f (&j)) +
13558                 (if k = 0 then f (&j + &1) else &0)) -
13559                (&k + &1) *
13560                real_integral (real_interval[&j,&j + &1])
13561                              (\x. bernoulli k (x - &j) * f x))` THEN
13562     CONJ_TAC THENL
13563      [MATCH_MP_TAC SUM_EQ_NUMSEG THEN X_GEN_TAC `j:num` THEN STRIP_TAC THEN
13564       REWRITE_TAC[] THEN MATCH_MP_TAC REAL_INTEGRAL_UNIQUE THEN
13565       MATCH_MP_TAC(ONCE_REWRITE_RULE[REAL_MUL_SYM]
13566         REAL_INTEGRATION_BY_PARTS_SIMPLE) THEN
13567       MAP_EVERY EXISTS_TAC
13568        [`f:real->real`; `\x. (&k + &1) * bernoulli k (x - &j)`] THEN
13569       REWRITE_TAC[REAL_ADD_SUB; REAL_SUB_REFL; BERNOULLI_1] THEN
13570       REPEAT CONJ_TAC THENL
13571        [REAL_ARITH_TAC;
13572         X_GEN_TAC `x:real` THEN DISCH_TAC THEN
13573         CONJ_TAC THENL
13574          [FIRST_X_ASSUM(MP_TAC o SPEC `x:real`) THEN ANTS_TAC THENL
13575            [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
13576              `x IN s ==> s SUBSET t ==> x IN t`));
13577             MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT]
13578               HAS_REAL_DERIVATIVE_WITHIN_SUBSET)] THEN
13579           REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN
13580           REWRITE_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_ADD] THEN ASM_ARITH_TAC;
13581           REAL_DIFF_TAC THEN  REWRITE_TAC[GSYM REAL_OF_NUM_ADD; ADD_SUB] THEN
13582           REAL_ARITH_TAC];
13583         REWRITE_TAC[ARITH_RULE `k + 1 = 1 <=> k = 0`] THEN
13584         ASM_CASES_TAC `k = 0` THEN ASM_REWRITE_TAC[] THENL
13585          [REWRITE_TAC[REAL_ARITH
13586            `(b + &1) * f1 - b * f0 - ((b * (f1 - f0) + f1) - w):real = w`];
13587           REWRITE_TAC[REAL_ARITH
13588            `b * f1 - b * f0 - ((b * (f1 - f0) + &0) - w) = w`]] THEN
13589         REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN
13590         MATCH_MP_TAC HAS_REAL_INTEGRAL_LMUL THEN
13591         MATCH_MP_TAC REAL_INTEGRABLE_INTEGRAL THEN
13592         MATCH_MP_TAC REAL_INTEGRABLE_CONTINUOUS THEN
13593         MATCH_MP_TAC REAL_CONTINUOUS_ON_MUL THEN
13594         (CONJ_TAC THENL
13595           [MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON THEN
13596            REWRITE_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE] THEN
13597            REPEAT STRIP_TAC THEN REAL_DIFFERENTIABLE_TAC;
13598            FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
13599              REAL_CONTINUOUS_ON_SUBSET)) THEN
13600            REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN
13601            REWRITE_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_ADD] THEN ASM_ARITH_TAC])];
13602       REWRITE_TAC[SUM_ADD_NUMSEG; SUM_LMUL; SUM_SUB_NUMSEG] THEN
13603       AP_THM_TAC THEN AP_TERM_TAC THEN BINOP_TAC THENL
13604        [AP_TERM_TAC THEN REWRITE_TAC[GSYM SUM_SUB_NUMSEG] THEN
13605         REWRITE_TAC[REAL_OF_NUM_ADD; SUM_DIFFS_ALT] THEN
13606         COND_CASES_TAC THENL [ALL_TAC; ASM_ARITH_TAC] THEN
13607         AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
13608         ASM_ARITH_TAC;
13609         ASM_CASES_TAC `k = 0` THEN ASM_REWRITE_TAC[SUM_0] THEN
13610         REWRITE_TAC[GSYM(SPEC `1` SUM_OFFSET); REAL_OF_NUM_ADD] THEN
13611         AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN ASM_ARITH_TAC]]) in
13612   REPEAT GEN_TAC THEN STRIP_TAC THEN
13613   FIRST_X_ASSUM(DISJ_CASES_TAC o MATCH_MP (ARITH_RULE
13614    `m:num <= n ==> m = n \/ m < n`))
13615   THENL
13616    [ASM_SIMP_TAC[REAL_INTEGRABLE_ON_NULL; REAL_LE_REFL] THEN
13617     ASM_REWRITE_TAC[SUM_SING_NUMSEG; REAL_SUB_REFL; REAL_MUL_LZERO] THEN
13618     SIMP_TAC[REAL_INTEGRAL_NULL; REAL_LE_REFL; REAL_ARITH `(x + x) / &2 = x`;
13619              REAL_MUL_RZERO; SUM_0; real_div; REAL_MUL_LZERO] THEN
13620     REAL_ARITH_TAC;
13621     ALL_TAC] THEN
13622   CONJ_TAC THENL
13623    [REWRITE_TAC[real_integrable_on] THEN
13624     MP_TAC(ISPECL [`f (2 * p + 1):real->real`; `2 * p + 1`; `m:num`; `n:num`]
13625         lemma) THEN
13626     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ALL_TAC; MESON_TAC[]] THEN
13627     MATCH_MP_TAC REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON THEN
13628     REWRITE_TAC[REAL_DIFFERENTIABLE_ON_DIFFERENTIABLE] THEN
13629     REWRITE_TAC[real_differentiable] THEN ASM_MESON_TAC[LE_REFL];
13630     ALL_TAC] THEN
13631   ASM_SIMP_TAC[SUM_CLAUSES_LEFT; LT_IMP_LE] THEN
13632   SUBGOAL_THEN
13633    `!k:num.  k <= 2 * p + 1
13634              ==> (f k) real_differentiable_on real_interval[&m,&n]`
13635   ASSUME_TAC THENL [ASM_MESON_TAC[real_differentiable_on]; ALL_TAC] THEN
13636   MP_TAC(ISPECL [`(f:num->real->real) 0`; `(f:num->real->real) (0 + 1)`;
13637                  `0`; `m:num`; `n:num`] step) THEN
13638   ASM_SIMP_TAC[REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON;
13639                ARITH_RULE `0 + 1 <= 2 * p + 1`; LE_0] THEN
13640   CONV_TAC NUM_REDUCE_CONV THEN REWRITE_TAC[CONJUNCT1 bernoulli] THEN
13641   REWRITE_TAC[REAL_ADD_LID; REAL_MUL_LID; ETA_AX] THEN
13642   REWRITE_TAC[BERNOULLI_CONV `bernoulli 1 (&0)`] THEN
13643   MATCH_MP_TAC(REAL_ARITH
13644    `i' = r ==> i' = (-- &1 / &2 * (n - m) + s) - i
13645                ==> m + s = i + (m + n) / &2 + r`) THEN
13646   POP_ASSUM_LIST(MP_TAC o end_itlist CONJ o rev) THEN
13647   SPEC_TAC(`p:num`,`p:num`) THEN INDUCT_TAC THENL
13648    [REWRITE_TAC[SUM_CLAUSES_NUMSEG] THEN CONV_TAC NUM_REDUCE_CONV THEN
13649     REAL_ARITH_TAC;
13650     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
13651      [ARITH_RULE `2 * SUC p + 1 = 2 * p + 3`] THEN
13652     FIRST_X_ASSUM(fun th -> STRIP_TAC THEN MP_TAC th) THEN
13653     ASM_SIMP_TAC[ARITH_RULE `k <= 2 * p + 1 ==> k <= 2 * p + 3`] THEN
13654     DISCH_TAC] THEN
13655   ASM_REWRITE_TAC[SUM_CLAUSES_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN
13656   REWRITE_TAC[GSYM REAL_ADD_ASSOC] THEN AP_TERM_TAC THEN
13657   MP_TAC(ISPECL [`(f:num->real->real) (2 * p + 1)`;
13658                  `(f:num->real->real) ((2 * p + 1) + 1)`;
13659                  `2 * p + 1`; `m:num`; `n:num`] step) THEN
13660   ASM_SIMP_TAC[REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON;
13661                ARITH_RULE `(2 * p + 1) + 1 <= 2 * p + 3`;
13662                ARITH_RULE `2 * p + 1 <= 2 * p + 3`] THEN
13663   REWRITE_TAC[ADD_EQ_0; ARITH_EQ; REAL_ADD_RID] THEN
13664   REWRITE_TAC[GSYM REAL_OF_NUM_ADD; GSYM REAL_OF_NUM_MUL] THEN
13665   REWRITE_TAC[REAL_FIELD
13666    `x = y - ((&2 * &p + &1) + &1) * z <=> z = (y - x) / (&2 * &p + &2)`] THEN
13667   DISCH_THEN SUBST1_TAC THEN
13668   REWRITE_TAC[ARITH_RULE `2 * SUC p - 1 = 2 * p + 1`] THEN
13669   REWRITE_TAC[ARITH_RULE `(2 * p + 1) + 1 = 2 * SUC p`] THEN
13670   REWRITE_TAC[ARITH_RULE `2 * SUC p = SUC(2 * p + 1)`] THEN
13671   REWRITE_TAC[ARITH_RULE `SUC(2 * p + 1) + 1 = SUC(SUC(2 * p + 1))`] THEN
13672   REWRITE_TAC[FACT; GSYM REAL_OF_NUM_MUL; GSYM REAL_OF_NUM_ADD;
13673               GSYM REAL_OF_NUM_SUC] THEN
13674   MATCH_MP_TAC(REAL_FIELD
13675    `~(t = &0) /\
13676     i2 = &0 - (&2 * &p + &3) * i1
13677     ==> (b * (fn - fm) - i1) / (&2 * &p + &2) / t =
13678         b / (((&2 * &p + &1) + &1) * t) * (fn - fm) +
13679         i2 / ((((&2 * &p + &1) + &1) + &1) * ((&2 * &p + &1) + &1) * t)`) THEN
13680   REWRITE_TAC[REAL_OF_NUM_EQ; FACT_NZ] THEN
13681   MP_TAC(ISPECL [`(f:num->real->real) (SUC(2 * p + 1))`;
13682                  `(f:num->real->real) (SUC(2 * p + 1) + 1)`;
13683                  `SUC(2 * p + 1)`; `m:num`; `n:num`] step) THEN
13684   ASM_SIMP_TAC[REAL_DIFFERENTIABLE_ON_IMP_REAL_CONTINUOUS_ON; NOT_SUC;
13685                ARITH_RULE `SUC(2 * p + 1) + 1 <= 2 * p + 3`;
13686                ARITH_RULE `SUC(2 * p + 1) <= 2 * p + 3`] THEN
13687   REWRITE_TAC[ADD1; GSYM ADD_ASSOC; REAL_OF_NUM_ADD] THEN
13688   CONV_TAC NUM_REDUCE_CONV THEN
13689   REWRITE_TAC[GSYM REAL_OF_NUM_ADD; REAL_ADD_RID; GSYM REAL_OF_NUM_MUL] THEN
13690   DISCH_THEN SUBST1_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
13691   REWRITE_TAC[REAL_ENTIRE] THEN DISJ1_TAC THEN
13692   REWRITE_TAC[BERNOULLI_NUMBER_EQ_0] THEN
13693   REWRITE_TAC[ODD_ADD; ODD_MULT; ARITH] THEN ARITH_TAC);;
13694
13695 let REAL_EULER_MACLAURIN_ANTIDERIVATIVE = prove
13696  (`!f m n p.
13697      m <= n /\
13698      (!k x. k <= 2 * p + 2 /\ x IN real_interval[&m,&n]
13699             ==> ((f k) has_real_derivative f (k + 1) x)
13700                 (atreal x within real_interval [&m,&n]))
13701      ==> ((\x. bernoulli (2 * p + 1) (frac x) * f (2 * p + 2) x)
13702           real_integrable_on real_interval[&m,&n]) /\
13703          sum(m..n) (\i. f 1 (&i)) =
13704          (f 0 (&n) - f 0 (&m)) +
13705          (f 1 (&m) + f 1 (&n)) / &2 +
13706          sum (1..p) (\k. bernoulli (2 * k) (&0) / &(FACT(2 * k)) *
13707                          (f (2 * k) (&n) - f (2 * k) (&m))) +
13708          real_integral (real_interval [&m,&n])
13709                        (\x. bernoulli (2 * p + 1) (frac x) * f (2 * p + 2) x) /
13710          &(FACT(2 * p + 1))`,
13711   REPEAT GEN_TAC THEN STRIP_TAC THEN
13712   MP_TAC(ISPECL [`\n. (f:num->real->real)(SUC n)`; `m:num`; `n:num`; `p:num`]
13713         REAL_EULER_MACLAURIN) THEN
13714   ASM_SIMP_TAC[ARITH_RULE `k <= 2 * p + 1 ==> SUC k <= 2 * p + 2`;
13715                ARITH_RULE `SUC(k + 1) = SUC k + 1`;
13716                ARITH_RULE `SUC(2 * p) + 1 = 2 * p + 2`] THEN
13717   CONV_TAC NUM_REDUCE_CONV THEN DISCH_THEN(SUBST1_TAC o CONJUNCT2) THEN
13718   MP_TAC(ISPECL
13719    [`f 0:real->real`; `f (0 + 1):real->real`; `&m`; `&n`]
13720         REAL_FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN
13721   ASM_SIMP_TAC[REAL_OF_NUM_LE; LE_0] THEN CONV_TAC NUM_REDUCE_CONV THEN
13722   DISCH_THEN(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN
13723   AP_TERM_TAC THEN AP_TERM_TAC THEN
13724   REWRITE_TAC[ARITH_RULE `SUC(2 * p) + 1 = 2 * p + 2`] THEN
13725   AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC SUM_EQ_NUMSEG THEN
13726   SIMP_TAC[ARITH_RULE `1 <= k ==> SUC(2 * k - 1) = 2 * k`]);;
13727
13728 let COMPLEX_EULER_MACLAURIN_ANTIDERIVATIVE = prove
13729  (`!f m n p.
13730      m <= n /\
13731      (!k x. k <= 2 * p + 2 /\ &m <= x /\ x <= &n
13732             ==> ((f k) has_complex_derivative f (k + 1) (Cx x)) (at(Cx x)))
13733      ==> (\x. Cx(bernoulli (2 * p + 1) (frac(drop x))) *
13734                        f (2 * p + 2) (Cx(drop x)))
13735          integrable_on interval[lift(&m),lift(&n)] /\
13736          vsum(m..n) (\i. f 1 (Cx(&i))) =
13737          (f 0 (Cx(&n)) - f 0 (Cx(&m))) +
13738          (f 1 (Cx(&m)) + f 1 (Cx(&n))) / Cx(&2) +
13739          vsum (1..p) (\k. Cx(bernoulli (2 * k) (&0) / &(FACT(2 * k))) *
13740                           (f (2 * k) (Cx(&n)) - f (2 * k) (Cx(&m)))) +
13741          integral (interval[lift(&m),lift(&n)])
13742                   (\x. Cx(bernoulli (2 * p + 1) (frac(drop x))) *
13743                        f (2 * p + 2) (Cx(drop x))) /
13744          Cx(&(FACT(2 * p + 1)))`,
13745   let lemma_re,lemma_im = (CONJ_PAIR o prove)
13746    (`((f has_complex_derivative f') (at (Cx x))
13747       ==> ((Re o f o Cx) has_real_derivative (Re f')) (atreal x)) /\
13748      ((f has_complex_derivative f') (at (Cx x))
13749       ==> ((Im o f o Cx) has_real_derivative (Im f')) (atreal x))`,
13750     REPEAT GEN_TAC THEN CONJ_TAC THEN
13751     REWRITE_TAC[HAS_COMPLEX_DERIVATIVE_AT; HAS_REAL_DERIVATIVE_ATREAL] THEN
13752     REWRITE_TAC[LIM_AT; REALLIM_ATREAL; o_THM] THEN
13753     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
13754     ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
13755     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN
13756     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `y:real` THEN
13757     STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `Cx y`) THEN
13758     ASM_REWRITE_TAC[DIST_CX; dist] THEN
13759     REWRITE_TAC[GSYM RE_SUB; GSYM IM_SUB; CX_SUB;
13760                 GSYM RE_DIV_CX; GSYM IM_SUB; GSYM IM_DIV_CX] THEN
13761     MESON_TAC[COMPLEX_NORM_GE_RE_IM; REAL_LET_TRANS])
13762   and ilemma = prove
13763    (`f integrable_on interval[lift a,lift b]
13764      ==> Re(integral (interval[lift a,lift b]) f) =
13765          real_integral (real_interval[a,b]) (\x. Re(f(lift x))) /\
13766          Im(integral (interval[lift a,lift b]) f) =
13767          real_integral (real_interval[a,b]) (\x. Im(f(lift x)))`,
13768     REPEAT STRIP_TAC THEN REWRITE_TAC[RE_DEF; IM_DEF] THEN
13769     ASM_SIMP_TAC[INTEGRAL_COMPONENT] THEN
13770     IMP_REWRITE_TAC[REAL_INTEGRAL] THEN
13771     REWRITE_TAC[o_DEF; IMAGE_LIFT_REAL_INTERVAL; LIFT_DROP] THEN
13772     REWRITE_TAC[REAL_INTEGRABLE_ON] THEN
13773     REWRITE_TAC[o_DEF; IMAGE_LIFT_REAL_INTERVAL; LIFT_DROP] THEN
13774     RULE_ASSUM_TAC(ONCE_REWRITE_RULE[INTEGRABLE_COMPONENTWISE]) THEN
13775     FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[DIMINDEX_2; ARITH]) in
13776   REPEAT GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[COMPLEX_EQ] THEN
13777   MAP_EVERY (MP_TAC o C SPEC REAL_EULER_MACLAURIN_ANTIDERIVATIVE)
13778    [`\n:num. (Im o f n o Cx)`; `\n:num. (Re o f n o Cx)`] THEN
13779   REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN
13780   DISCH_THEN(MP_TAC o SPECL [`m:num`; `n:num`; `p:num`]) THEN
13781   ASM_SIMP_TAC[lemma_re; lemma_im; HAS_REAL_DERIVATIVE_ATREAL_WITHIN;
13782                o_THM; IN_REAL_INTERVAL] THEN
13783   SIMP_TAC[RE_VSUM; IM_VSUM; FINITE_NUMSEG] THEN
13784   DISCH_THEN(CONJUNCTS_THEN(ASSUME_TAC o CONJUNCT1)) THEN
13785   SIMP_TAC[RE_DIV_CX; IM_DIV_CX; RE_VSUM; IM_VSUM; FINITE_NUMSEG; RE_ADD;
13786            RE_SUB;IM_ADD; IM_SUB; RE_MUL_CX; IM_MUL_CX; RE_CX; IM_CX] THEN
13787   MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
13788    [ONCE_REWRITE_TAC[INTEGRABLE_COMPONENTWISE] THEN
13789     REWRITE_TAC[DIMINDEX_2; FORALL_2; GSYM RE_DEF; GSYM IM_DEF] THEN
13790     REWRITE_TAC[RE_MUL_CX; IM_MUL_CX] THEN
13791     ASM_REWRITE_TAC[REWRITE_RULE[o_DEF] (GSYM REAL_INTEGRABLE_ON);
13792                     GSYM IMAGE_LIFT_REAL_INTERVAL];
13793     SIMP_TAC[ilemma] THEN REWRITE_TAC[RE_MUL_CX; IM_MUL_CX; LIFT_DROP]]);;
13794
13795 (* ------------------------------------------------------------------------- *)
13796 (* Specific properties of complex measurable functions.                      *)
13797 (* ------------------------------------------------------------------------- *)
13798
13799 let MEASURABLE_ON_COMPLEX_MUL = prove
13800  (`!f g:real^N->complex s.
13801          f measurable_on s /\ g measurable_on s
13802          ==> (\x. f x * g x) measurable_on s`,
13803   REPEAT STRIP_TAC THEN MATCH_MP_TAC MEASURABLE_ON_COMBINE THEN
13804   ASM_REWRITE_TAC[COMPLEX_VEC_0; COMPLEX_MUL_LZERO] THEN
13805   MATCH_MP_TAC CONTINUOUS_ON_COMPLEX_MUL THEN
13806   CONJ_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_ON THEN
13807   REWRITE_TAC[LINEAR_FSTCART; LINEAR_SNDCART]);;
13808
13809 let MEASURABLE_ON_COMPLEX_INV = prove
13810  (`!f:real^N->real^2.
13811      f measurable_on (:real^N) /\ negligible {x | f x = Cx(&0)}
13812      ==> (\x. inv(f x)) measurable_on (:real^N)`,
13813   GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
13814   REWRITE_TAC[measurable_on; IN_UNIV; LEFT_IMP_EXISTS_THM] THEN
13815   MAP_EVERY X_GEN_TAC [`k:real^N->bool`; `g:num->real^N->complex`] THEN
13816   STRIP_TAC THEN EXISTS_TAC `k UNION {x:real^N | f x = Cx(&0)}` THEN
13817   ASM_SIMP_TAC[NEGLIGIBLE_UNION] THEN
13818   SUBGOAL_THEN
13819    `!n. ?h. h continuous_on (:real^N) /\
13820             !x. x IN {x | g n x IN (:complex) DIFF ball(Cx(&0),inv(&n + &1))}
13821                 ==> (h:real^N->complex) x = inv(g n x)`
13822
13823   MP_TAC THENL
13824    [X_GEN_TAC `n:num` THEN MATCH_MP_TAC TIETZE_UNBOUNDED THEN CONJ_TAC THENL
13825      [REWRITE_TAC[SUBTOPOLOGY_UNIV; GSYM CLOSED_IN] THEN
13826       MATCH_MP_TAC CONTINUOUS_CLOSED_PREIMAGE_UNIV THEN
13827       REWRITE_TAC[GSYM OPEN_CLOSED; OPEN_BALL; ETA_AX] THEN
13828       ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_UNIV; IN_UNIV];
13829       REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
13830       GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC CONTINUOUS_AT_WITHIN THEN
13831       MATCH_MP_TAC CONTINUOUS_COMPLEX_INV_AT THEN CONJ_TAC THENL
13832        [REWRITE_TAC[ETA_AX] THEN
13833         ASM_MESON_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_AT; OPEN_UNIV; IN_UNIV];
13834         RULE_ASSUM_TAC(REWRITE_RULE[IN_ELIM_THM; IN_UNIV; IN_DIFF]) THEN
13835         FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [IN_BALL]) THEN
13836         SIMP_TAC[CONTRAPOS_THM; DIST_REFL; REAL_LT_INV_EQ] THEN
13837         REAL_ARITH_TAC]];
13838     REWRITE_TAC[SKOLEM_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
13839     X_GEN_TAC `h:num->real^N->complex` THEN
13840     REWRITE_TAC[FORALL_AND_THM; IN_ELIM_THM; IN_DIFF; IN_UNION; IN_UNIV] THEN
13841     REWRITE_TAC[IN_BALL; DE_MORGAN_THM; REAL_NOT_LT] THEN
13842     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^N` THEN
13843     STRIP_TAC THEN MATCH_MP_TAC LIM_TRANSFORM THEN
13844     EXISTS_TAC `\n. inv((g:num->real^N->complex) n x)` THEN
13845     ASM_SIMP_TAC[o_DEF; LIM_COMPLEX_INV] THEN
13846     MATCH_MP_TAC LIM_EVENTUALLY THEN
13847     REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
13848     SUBGOAL_THEN `&0 < norm((f:real^N->complex) x)` ASSUME_TAC THENL
13849      [ASM_REWRITE_TAC[COMPLEX_NORM_NZ]; ALL_TAC] THEN
13850     FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
13851     ASM_REWRITE_TAC[LIM_SEQUENTIALLY] THEN
13852     DISCH_THEN(MP_TAC o SPEC `norm((f:real^N->complex) x) / &2`) THEN
13853     ASM_REWRITE_TAC[REAL_HALF] THEN
13854     DISCH_THEN(X_CHOOSE_THEN `N1:num` (LABEL_TAC "*")) THEN
13855     MP_TAC(SPEC `norm((f:real^N->complex) x) / &2` REAL_ARCH_INV) THEN
13856     ASM_REWRITE_TAC[REAL_HALF] THEN
13857     DISCH_THEN(X_CHOOSE_THEN `N2:num` STRIP_ASSUME_TAC) THEN
13858     EXISTS_TAC `N1 + N2 + 1` THEN X_GEN_TAC `n:num` THEN STRIP_TAC THEN
13859     REWRITE_TAC[VECTOR_SUB_EQ] THEN CONV_TAC SYM_CONV THEN
13860     FIRST_X_ASSUM MATCH_MP_TAC THEN
13861     REWRITE_TAC[GSYM COMPLEX_VEC_0; DIST_0] THEN
13862     REMOVE_THEN "*" (MP_TAC o SPEC `n:num`) THEN
13863     ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
13864     DISCH_THEN(MP_TAC o MATCH_MP (NORM_ARITH
13865      `dist(g,f) < norm(f) / &2 ==> norm(f) / &2 <= norm g`)) THEN
13866     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN
13867     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
13868      `x < y ==> z <= x ==> z <= y`)) THEN
13869     MATCH_MP_TAC REAL_LE_INV2 THEN
13870     ASM_REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
13871     ASM_ARITH_TAC]);;
13872
13873 let MEASURABLE_ON_COMPLEX_DIV = prove
13874  (`!f g:real^N->complex s.
13875         f measurable_on s /\ g measurable_on (:real^N) /\
13876         negligible {x | g(x) = Cx(&0)}
13877         ==> (\x. f(x) / g(x)) measurable_on s`,
13878   let lemma = prove
13879    (`!f g:real^N->complex.
13880         f measurable_on (:real^N) /\ g measurable_on (:real^N) /\
13881         negligible {x | g(x) = Cx(&0)}
13882         ==> (\x. f(x) / g(x)) measurable_on (:real^N)`,
13883     REPEAT STRIP_TAC THEN REWRITE_TAC[complex_div] THEN
13884     ASM_SIMP_TAC[MEASURABLE_ON_COMPLEX_MUL; MEASURABLE_ON_COMPLEX_INV]) in
13885   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM MEASURABLE_ON_UNIV] THEN
13886   REWRITE_TAC[IN_UNIV; ETA_AX] THEN DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN
13887   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
13888   REWRITE_TAC[FUN_EQ_THM; complex_div; COMPLEX_VEC_0] THEN
13889   GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[COMPLEX_MUL_LZERO]);;
13890
13891 (* ------------------------------------------------------------------------- *)
13892 (* Measurable real->real functions.                                          *)
13893 (* ------------------------------------------------------------------------- *)
13894
13895 parse_as_infix("real_measurable_on",(12,"right"));;
13896
13897 let real_measurable_on = new_definition
13898  `f real_measurable_on s <=>
13899         (lift o f o drop) measurable_on (IMAGE lift s)`;;
13900
13901 let real_lebesgue_measurable = new_definition
13902  `real_lebesgue_measurable s <=>
13903       (\x. if x IN s then &1 else &0) real_measurable_on (:real)`;;
13904
13905 let REAL_MEASURABLE_ON_UNIV = prove
13906  (`(\x.  if x IN s then f(x) else &0) real_measurable_on (:real) <=>
13907    f real_measurable_on s`,
13908   REWRITE_TAC[real_measurable_on; o_DEF; IMAGE_LIFT_UNIV] THEN
13909   SIMP_TAC[COND_RAND; LIFT_NUM; MEASURABLE_ON_UNIV; GSYM IN_IMAGE_LIFT_DROP]);;
13910
13911 let REAL_LEBESGUE_MEASURABLE = prove
13912  (`!s. real_lebesgue_measurable s <=> lebesgue_measurable (IMAGE lift s)`,
13913   REWRITE_TAC[real_lebesgue_measurable; lebesgue_measurable; COND_RAND;
13914     COND_RAND; real_measurable_on; indicator; IMAGE_LIFT_UNIV; o_DEF] THEN
13915   REWRITE_TAC[LIFT_NUM; IN_IMAGE_LIFT_DROP]);;
13916
13917 let REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE = prove
13918  (`!f g s.
13919         f real_measurable_on s /\
13920         g real_integrable_on s /\
13921         (!x. x IN s ==> abs(f x) <= g x)
13922         ==> f real_integrable_on s`,
13923   REWRITE_TAC[real_measurable_on; REAL_INTEGRABLE_ON] THEN
13924   REPEAT STRIP_TAC THEN
13925   MATCH_MP_TAC MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE THEN
13926   EXISTS_TAC `lift o g o drop` THEN
13927   ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; NORM_LIFT]);;
13928
13929 let REAL_MEASURABLE_BOUNDED_AE_BY_INTEGRABLE_IMP_INTEGRABLE = prove
13930  (`!f g s k.
13931       f real_measurable_on s /\ g real_integrable_on s /\ real_negligible k /\
13932       (!x. x IN s DIFF k ==> abs(f x) <= g x)
13933       ==> f real_integrable_on s`,
13934   REPEAT STRIP_TAC THEN
13935   MATCH_MP_TAC REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE THEN
13936   EXISTS_TAC
13937    `\x. if x IN k then abs(f x) else (g:real->real) x` THEN
13938   ASM_SIMP_TAC[COND_RAND; IN_DIFF; LIFT_DROP; REAL_LE_REFL; COND_ID] THEN
13939   MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] REAL_INTEGRABLE_SPIKE) THEN
13940   MAP_EVERY EXISTS_TAC [`g:real->real`; `k:real->bool`] THEN
13941   ASM_SIMP_TAC[IN_DIFF]);;
13942
13943 let REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE = prove
13944  (`!f g s.
13945         f real_measurable_on s /\
13946         g real_integrable_on s /\
13947         (!x. x IN s ==> abs(f x) <= g x)
13948         ==> f absolutely_real_integrable_on s`,
13949   REWRITE_TAC[real_measurable_on; REAL_INTEGRABLE_ON;
13950               ABSOLUTELY_REAL_INTEGRABLE_ON] THEN
13951   REPEAT STRIP_TAC THEN
13952   MATCH_MP_TAC MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE THEN
13953   EXISTS_TAC `lift o g o drop` THEN
13954   ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; NORM_LIFT]);;
13955
13956 let INTEGRABLE_SUBINTERVALS_IMP_REAL_MEASURABLE = prove
13957  (`!f. (!a b. f real_integrable_on real_interval[a,b])
13958        ==> f real_measurable_on (:real)`,
13959   REWRITE_TAC[real_measurable_on; REAL_INTEGRABLE_ON; IMAGE_LIFT_UNIV] THEN
13960   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN
13961   MATCH_MP_TAC INTEGRABLE_SUBINTERVALS_IMP_MEASURABLE THEN
13962   ASM_REWRITE_TAC[FORALL_LIFT]);;
13963
13964 let INTEGRABLE_IMP_REAL_MEASURABLE = prove
13965  (`!f:real->real s.
13966         f real_integrable_on s ==> f real_measurable_on s`,
13967   REWRITE_TAC[real_measurable_on; REAL_INTEGRABLE_ON] THEN
13968   REWRITE_TAC[INTEGRABLE_IMP_MEASURABLE]);;
13969
13970 let ABSOLUTELY_REAL_INTEGRABLE_REAL_MEASURABLE = prove
13971  (`!f s. f absolutely_real_integrable_on s <=>
13972          f real_measurable_on s /\ (\x. abs(f x)) real_integrable_on s`,
13973   REPEAT GEN_TAC THEN REWRITE_TAC[absolutely_real_integrable_on] THEN
13974   MATCH_MP_TAC(TAUT `(a ==> b) /\ (b /\ c ==> a) ==> (a /\ c <=> b /\ c)`) THEN
13975   REWRITE_TAC[INTEGRABLE_IMP_REAL_MEASURABLE] THEN STRIP_TAC THEN
13976   MATCH_MP_TAC REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_INTEGRABLE THEN
13977   EXISTS_TAC `\x. abs((f:real->real) x)` THEN ASM_REWRITE_TAC[REAL_LE_REFL]);;
13978
13979 let REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS = prove
13980  (`!f g. f real_measurable_on (:real) /\ g real_continuous_on (:real)
13981          ==> (g o f) real_measurable_on (:real)`,
13982   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_CONTINUOUS_ON; real_measurable_on] THEN
13983   REWRITE_TAC[IMAGE_LIFT_UNIV] THEN
13984   DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_COMPOSE_CONTINUOUS) THEN
13985   REWRITE_TAC[o_DEF; LIFT_DROP]);;
13986
13987 let REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_0 = prove
13988  (`!f:real->real g:real->real s.
13989         f real_measurable_on s /\ g real_continuous_on (:real) /\ g(&0) = &0
13990         ==> (g o f) real_measurable_on s`,
13991   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV] THEN
13992   ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> c ==> a /\ b ==> d`] THEN
13993   DISCH_TAC THEN
13994   DISCH_THEN(MP_TAC o MATCH_MP REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS) THEN
13995   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
13996   REWRITE_TAC[FUN_EQ_THM; o_DEF] THEN ASM_MESON_TAC[]);;
13997
13998 let REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_OPEN_INTERVAL = prove
13999  (`!f:real->real g:real->real a b.
14000         f real_measurable_on (:real) /\
14001         (!x. f(x) IN real_interval(a,b)) /\
14002         g real_continuous_on real_interval(a,b)
14003         ==> (g o f) real_measurable_on (:real)`,
14004   REPEAT GEN_TAC THEN
14005   MP_TAC(ISPECL [`lift o f o drop`; `lift o g o drop`; `lift a`; `lift b`]
14006         MEASURABLE_ON_COMPOSE_CONTINUOUS_OPEN_INTERVAL) THEN
14007   REWRITE_TAC[real_measurable_on; REAL_CONTINUOUS_ON] THEN
14008   REWRITE_TAC[o_DEF; LIFT_DROP; IMAGE_LIFT_UNIV; IMAGE_LIFT_REAL_INTERVAL] THEN
14009   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
14010   ASM_REWRITE_TAC[GSYM FORALL_DROP] THEN REPEAT GEN_TAC THEN
14011   REWRITE_TAC[INTERVAL_REAL_INTERVAL; LIFT_DROP] THEN ASM SET_TAC[]);;
14012
14013 let REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET = prove
14014  (`!f:real->real g:real->real s.
14015         real_closed s /\
14016         f real_measurable_on (:real) /\
14017         (!x. f(x) IN s) /\
14018         g real_continuous_on s
14019         ==> (g o f) real_measurable_on (:real)`,
14020   REPEAT GEN_TAC THEN
14021   MP_TAC(ISPECL [`lift o f o drop`; `lift o g o drop`; `IMAGE lift s`]
14022         MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET) THEN
14023   REWRITE_TAC[real_measurable_on; REAL_CONTINUOUS_ON; REAL_CLOSED] THEN
14024   REWRITE_TAC[o_DEF; LIFT_DROP; IMAGE_LIFT_UNIV; IMAGE_LIFT_REAL_INTERVAL] THEN
14025   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
14026   ASM_REWRITE_TAC[GSYM FORALL_DROP] THEN REPEAT GEN_TAC THEN
14027   REWRITE_TAC[INTERVAL_REAL_INTERVAL; LIFT_DROP] THEN ASM SET_TAC[]);;
14028
14029 let REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET_0 = prove
14030  (`!f:real->real g:real->real s t.
14031         real_closed s /\
14032         f real_measurable_on t /\
14033         (!x. f(x) IN s) /\
14034         g real_continuous_on s /\
14035         &0 IN s /\ g(&0) = &0
14036         ==> (g o f) real_measurable_on t`,
14037   REPEAT GEN_TAC THEN
14038   MP_TAC(ISPECL [`lift o f o drop`; `lift o g o drop`;
14039                  `IMAGE lift s`; `IMAGE lift t`]
14040         MEASURABLE_ON_COMPOSE_CONTINUOUS_CLOSED_SET_0) THEN
14041   REWRITE_TAC[real_measurable_on; REAL_CONTINUOUS_ON; REAL_CLOSED] THEN
14042   REWRITE_TAC[o_DEF; LIFT_DROP; IMAGE_LIFT_UNIV; IMAGE_LIFT_REAL_INTERVAL] THEN
14043   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
14044   ASM_REWRITE_TAC[GSYM FORALL_DROP] THEN
14045   ASM_SIMP_TAC[FUN_IN_IMAGE; LIFT_DROP; GSYM LIFT_NUM]);;
14046
14047 let CONTINUOUS_IMP_REAL_MEASURABLE_ON = prove
14048  (`!f. f real_continuous_on (:real) ==> f real_measurable_on (:real)`,
14049   REWRITE_TAC[REAL_CONTINUOUS_ON; real_measurable_on] THEN
14050   REWRITE_TAC[CONTINUOUS_IMP_MEASURABLE_ON; IMAGE_LIFT_UNIV]);;
14051
14052 let REAL_MEASURABLE_ON_CONST = prove
14053  (`!k:real. (\x. k) real_measurable_on (:real)`,
14054   SIMP_TAC[real_measurable_on; o_DEF; MEASURABLE_ON_CONST; IMAGE_LIFT_UNIV]);;
14055
14056 let REAL_MEASURABLE_ON_0 = prove
14057  (`!s. (\x. &0) real_measurable_on s`,
14058   GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV] THEN
14059   REWRITE_TAC[REAL_MEASURABLE_ON_CONST; COND_ID]);;
14060
14061 let REAL_MEASURABLE_ON_LMUL = prove
14062  (`!c f s. f real_measurable_on s ==> (\x. c * f x) real_measurable_on s`,
14063   REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN
14064   DISCH_THEN(MP_TAC o SPEC `c:real` o MATCH_MP MEASURABLE_ON_CMUL) THEN
14065   REWRITE_TAC[o_DEF; LIFT_CMUL; LIFT_DROP]);;
14066
14067 let REAL_MEASURABLE_ON_RMUL = prove
14068  (`!c f s. f real_measurable_on s ==> (\x. f x * c) real_measurable_on s`,
14069   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
14070   REWRITE_TAC[REAL_MEASURABLE_ON_LMUL]);;
14071
14072 let REAL_MEASURABLE_ON_NEG = prove
14073  (`!f s. f real_measurable_on s ==> (\x. --(f x)) real_measurable_on s`,
14074   REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN
14075   DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_NEG) THEN
14076   REWRITE_TAC[o_DEF; LIFT_NEG; LIFT_DROP]);;
14077
14078 let REAL_MEASURABLE_ON_NEG_EQ = prove
14079  (`!f s. (\x. --(f x)) real_measurable_on s <=> f real_measurable_on s`,
14080   REPEAT GEN_TAC THEN EQ_TAC THEN
14081   DISCH_THEN(MP_TAC o MATCH_MP REAL_MEASURABLE_ON_NEG) THEN
14082   REWRITE_TAC[REAL_NEG_NEG; ETA_AX]);;
14083
14084 let REAL_MEASURABLE_ON_ABS = prove
14085  (`!f s. f real_measurable_on s ==> (\x. abs(f x)) real_measurable_on s`,
14086   REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN
14087   DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_NORM) THEN
14088   REWRITE_TAC[o_DEF; NORM_LIFT]);;
14089
14090 let REAL_MEASURABLE_ON_ADD = prove
14091  (`!f g s. f real_measurable_on s /\ g real_measurable_on s
14092            ==> (\x. f x + g x) real_measurable_on s`,
14093   REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN
14094   DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_ADD) THEN
14095   REWRITE_TAC[o_DEF; LIFT_ADD; LIFT_DROP]);;
14096
14097 let REAL_MEASURABLE_ON_SUB = prove
14098  (`!f g s.
14099         f real_measurable_on s /\ g real_measurable_on s
14100         ==> (\x. f x - g x) real_measurable_on s`,
14101   REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN
14102   DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_SUB) THEN
14103   REWRITE_TAC[o_DEF; LIFT_SUB; LIFT_DROP]);;
14104
14105 let REAL_MEASURABLE_ON_MAX = prove
14106  (`!f g s.
14107         f real_measurable_on s /\ g real_measurable_on s
14108         ==> (\x. max (f x) (g x)) real_measurable_on s`,
14109   REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN
14110   DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_MAX) THEN
14111   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
14112   SIMP_TAC[FUN_EQ_THM; o_THM; CART_EQ; LAMBDA_BETA; DIMINDEX_1; FORALL_1] THEN
14113   REWRITE_TAC[GSYM drop; LIFT_DROP]);;
14114
14115 let REAL_MEASURABLE_ON_MIN = prove
14116  (`!f g s.
14117         f real_measurable_on s /\ g real_measurable_on s
14118         ==> (\x. min (f x) (g x)) real_measurable_on s`,
14119   REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN
14120   DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_MIN) THEN
14121   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
14122   SIMP_TAC[FUN_EQ_THM; o_THM; CART_EQ; LAMBDA_BETA; DIMINDEX_1; FORALL_1] THEN
14123   REWRITE_TAC[GSYM drop; LIFT_DROP]);;
14124
14125 let REAL_MEASURABLE_ON_MUL = prove
14126  (`!f g s.
14127         f real_measurable_on s /\ g real_measurable_on s
14128         ==> (\x. f x * g x) real_measurable_on s`,
14129   REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on] THEN
14130   DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_DROP_MUL) THEN
14131   REWRITE_TAC[o_DEF; LIFT_CMUL; LIFT_DROP]);;
14132
14133 let REAL_MEASURABLE_ON_SPIKE_SET = prove
14134  (`!f:real->real s t.
14135         real_negligible (s DIFF t UNION t DIFF s)
14136         ==> f real_measurable_on s
14137             ==> f real_measurable_on t`,
14138   REWRITE_TAC[real_measurable_on; real_negligible] THEN
14139   REPEAT GEN_TAC THEN DISCH_TAC THEN
14140   MATCH_MP_TAC MEASURABLE_ON_SPIKE_SET THEN POP_ASSUM MP_TAC THEN
14141   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] NEGLIGIBLE_SUBSET) THEN
14142   SET_TAC[]);;
14143
14144 let REAL_MEASURABLE_ON_RESTRICT = prove
14145  (`!f s. f real_measurable_on (:real) /\
14146          real_lebesgue_measurable s
14147          ==> (\x. if x IN s then f(x) else &0) real_measurable_on (:real)`,
14148   REPEAT GEN_TAC THEN
14149   REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE;
14150               IMAGE_LIFT_UNIV] THEN
14151   REWRITE_TAC[o_DEF; COND_RAND; LIFT_NUM; GSYM IN_IMAGE_LIFT_DROP] THEN
14152   DISCH_THEN(MP_TAC o MATCH_MP MEASURABLE_ON_RESTRICT) THEN
14153   REWRITE_TAC[]);;
14154
14155 let REAL_MEASURABLE_ON_LIMIT = prove
14156  (`!f g s k.
14157         (!n. (f n) real_measurable_on s) /\
14158         real_negligible k /\
14159         (!x. x IN s DIFF k ==> ((\n. f n x) ---> g x) sequentially)
14160         ==> g real_measurable_on s`,
14161   REWRITE_TAC[real_measurable_on; real_negligible; TENDSTO_REAL] THEN
14162   REWRITE_TAC[o_DEF] THEN REPEAT STRIP_TAC THEN
14163   MATCH_MP_TAC MEASURABLE_ON_LIMIT THEN MAP_EVERY EXISTS_TAC
14164    [`\n:num. lift o f n o drop`; `IMAGE lift k`] THEN
14165   ASM_REWRITE_TAC[] THEN
14166   SIMP_TAC[LIFT_DROP; SET_RULE `(!x. drop(lift x) = x)
14167             ==> IMAGE lift s DIFF IMAGE lift t = IMAGE lift (s DIFF t)`] THEN
14168   ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_DEF; LIFT_DROP]);;
14169
14170 let ABSOLUTELY_REAL_INTEGRABLE_BOUNDED_MEASURABLE_PRODUCT = prove
14171  (`!f g s. f real_measurable_on s /\ real_bounded (IMAGE f s) /\
14172            g absolutely_real_integrable_on s
14173            ==> (\x. f x * g x) absolutely_real_integrable_on s`,
14174   REPEAT STRIP_TAC THEN
14175   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_BOUNDED_POS]) THEN
14176   REWRITE_TAC[LEFT_IMP_EXISTS_THM; FORALL_IN_IMAGE] THEN
14177   X_GEN_TAC `B:real` THEN STRIP_TAC THEN MATCH_MP_TAC
14178    REAL_MEASURABLE_BOUNDED_BY_INTEGRABLE_IMP_ABSOLUTELY_INTEGRABLE THEN
14179   EXISTS_TAC `\x. B * abs((g:real->real) x)` THEN
14180   ASM_SIMP_TAC[REAL_MEASURABLE_ON_MUL; INTEGRABLE_IMP_REAL_MEASURABLE;
14181     ABSOLUTELY_REAL_INTEGRABLE_IMP_INTEGRABLE; REAL_INTEGRABLE_LMUL;
14182     ABSOLUTELY_REAL_INTEGRABLE_ABS] THEN
14183   ASM_SIMP_TAC[REAL_ABS_MUL; REAL_LE_RMUL; REAL_ABS_POS]);;
14184
14185 let REAL_COMPLEX_MEASURABLE_ON = prove
14186  (`!f s. f real_measurable_on s <=>
14187          (Cx o f o drop) measurable_on (IMAGE lift s)`,
14188   ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV;
14189                    GSYM MEASURABLE_ON_UNIV] THEN
14190   ONCE_REWRITE_TAC[MEASURABLE_ON_COMPONENTWISE] THEN
14191   REWRITE_TAC[FORALL_2; DIMINDEX_2; GSYM RE_DEF; GSYM IM_DEF] THEN
14192   REPEAT GEN_TAC THEN REWRITE_TAC[real_measurable_on; IMAGE_LIFT_UNIV] THEN
14193   REWRITE_TAC[o_DEF; IN_IMAGE_LIFT_DROP] THEN
14194   REWRITE_TAC[COND_RAND; COND_RATOR; LIFT_NUM; COMPLEX_VEC_0] THEN
14195   REWRITE_TAC[RE_CX; IM_CX; COND_ID; MEASURABLE_ON_CONST; LIFT_NUM]);;
14196
14197 let REAL_MEASURABLE_ON_INV = prove
14198  (`!f. f real_measurable_on (:real) /\ real_negligible {x | f x = &0}
14199        ==> (\x. inv(f x)) real_measurable_on (:real)`,
14200   GEN_TAC THEN REWRITE_TAC[REAL_COMPLEX_MEASURABLE_ON] THEN
14201   REWRITE_TAC[o_DEF; CX_INV; IMAGE_LIFT_UNIV] THEN STRIP_TAC THEN
14202   MATCH_MP_TAC MEASURABLE_ON_COMPLEX_INV THEN ASM_REWRITE_TAC[CX_INJ] THEN
14203   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_negligible]) THEN
14204   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
14205   MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
14206   REWRITE_TAC[IN_ELIM_THM; LIFT_DROP] THEN MESON_TAC[LIFT_DROP]);;
14207
14208 let REAL_MEASURABLE_ON_DIV = prove
14209  (`!f g. f real_measurable_on s /\ g real_measurable_on (:real) /\
14210          real_negligible {x | g(x) = &0}
14211          ==> (\x. f(x) / g(x)) real_measurable_on s`,
14212   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_COMPLEX_MEASURABLE_ON] THEN
14213   REWRITE_TAC[o_DEF; CX_DIV; IMAGE_LIFT_UNIV] THEN STRIP_TAC THEN
14214   MATCH_MP_TAC MEASURABLE_ON_COMPLEX_DIV THEN ASM_REWRITE_TAC[CX_INJ] THEN
14215   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [real_negligible]) THEN
14216   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN
14217   MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
14218   REWRITE_TAC[IN_ELIM_THM; LIFT_DROP] THEN MESON_TAC[LIFT_DROP]);;
14219
14220 let REAL_MEASURABLE_ON_RPOW = prove
14221  (`!f r s. f real_measurable_on s /\ &0 < r
14222            ==> (\x. f x rpow r) real_measurable_on s`,
14223   REPEAT STRIP_TAC THEN
14224   SUBGOAL_THEN `(\x. f x rpow r) = (\x. x rpow r) o (f:real->real)`
14225   SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
14226   MATCH_MP_TAC REAL_MEASURABLE_ON_COMPOSE_CONTINUOUS_0 THEN
14227   ASM_SIMP_TAC[REAL_CONTINUOUS_ON_RPOW; RPOW_ZERO;
14228                REAL_LT_IMP_LE; REAL_LT_IMP_NZ]);;
14229
14230 (* ------------------------------------------------------------------------- *)
14231 (* Properties of real Lebesgue measurable sets.                              *)
14232 (* ------------------------------------------------------------------------- *)
14233
14234 let REAL_MEASURABLE_IMP_REAL_LEBESGUE_MEASURABLE = prove
14235  (`!s. real_measurable s ==> real_lebesgue_measurable s`,
14236   REWRITE_TAC[REAL_LEBESGUE_MEASURABLE; REAL_MEASURABLE_MEASURABLE;
14237               MEASURABLE_IMP_LEBESGUE_MEASURABLE]);;
14238
14239 let REAL_LEBESGUE_MEASURABLE_EMPTY = prove
14240  (`real_lebesgue_measurable {}`,
14241   REWRITE_TAC[REAL_LEBESGUE_MEASURABLE; IMAGE_CLAUSES;
14242               LEBESGUE_MEASURABLE_EMPTY]);;
14243
14244 let REAL_LEBESGUE_MEASURABLE_UNIV = prove
14245  (`real_lebesgue_measurable (:real)`,
14246   REWRITE_TAC[REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV;
14247               LEBESGUE_MEASURABLE_UNIV]);;
14248
14249 let REAL_LEBESGUE_MEASURABLE_COMPACT = prove
14250  (`!s. real_compact s ==> real_lebesgue_measurable s`,
14251   SIMP_TAC[REAL_MEASURABLE_IMP_REAL_LEBESGUE_MEASURABLE;
14252            REAL_MEASURABLE_COMPACT]);;
14253
14254 let REAL_LEBESGUE_MEASURABLE_INTERVAL = prove
14255  (`(!a b. real_lebesgue_measurable(real_interval[a,b])) /\
14256    (!a b. real_lebesgue_measurable(real_interval(a,b)))`,
14257   SIMP_TAC[REAL_MEASURABLE_IMP_REAL_LEBESGUE_MEASURABLE;
14258            REAL_MEASURABLE_REAL_INTERVAL]);;
14259
14260 let REAL_LEBESGUE_MEASURABLE_INTER = prove
14261  (`!s t. real_lebesgue_measurable s /\ real_lebesgue_measurable t
14262          ==> real_lebesgue_measurable(s INTER t)`,
14263   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LEBESGUE_MEASURABLE] THEN
14264   DISCH_THEN(MP_TAC o MATCH_MP LEBESGUE_MEASURABLE_INTER) THEN
14265   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN MP_TAC LIFT_DROP THEN SET_TAC[]);;
14266
14267 let REAL_LEBESGUE_MEASURABLE_UNION = prove
14268  (`!s t:real->bool.
14269         real_lebesgue_measurable s /\ real_lebesgue_measurable t
14270         ==> real_lebesgue_measurable(s UNION t)`,
14271   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_LEBESGUE_MEASURABLE] THEN
14272   DISCH_THEN(MP_TAC o MATCH_MP LEBESGUE_MEASURABLE_UNION) THEN
14273   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN MP_TAC LIFT_DROP THEN SET_TAC[]);;
14274
14275 let REAL_LEBESGUE_MEASURABLE_COMPL = prove
14276  (`!s. real_lebesgue_measurable((:real) DIFF s) <=>
14277        real_lebesgue_measurable s`,
14278   GEN_TAC THEN REWRITE_TAC[REAL_LEBESGUE_MEASURABLE] THEN
14279   GEN_REWRITE_TAC (RAND_CONV) [GSYM LEBESGUE_MEASURABLE_COMPL] THEN
14280   AP_TERM_TAC THEN MP_TAC LIFT_DROP THEN SET_TAC[]);;
14281
14282 let REAL_LEBESGUE_MEASURABLE_DIFF = prove
14283  (`!s t:real->bool.
14284         real_lebesgue_measurable s /\ real_lebesgue_measurable t
14285         ==> real_lebesgue_measurable(s DIFF t)`,
14286   ONCE_REWRITE_TAC[SET_RULE `s DIFF t = s INTER (UNIV DIFF t)`] THEN
14287   SIMP_TAC[REAL_LEBESGUE_MEASURABLE_COMPL; REAL_LEBESGUE_MEASURABLE_INTER]);;
14288
14289 let REAL_LEBESGUE_MEASURABLE_ON_SUBINTERVALS = prove
14290  (`!s. real_lebesgue_measurable s <=>
14291        !a b. real_lebesgue_measurable(s INTER real_interval[a,b])`,
14292   GEN_TAC THEN REWRITE_TAC[REAL_LEBESGUE_MEASURABLE] THEN
14293   GEN_REWRITE_TAC LAND_CONV [LEBESGUE_MEASURABLE_ON_SUBINTERVALS] THEN
14294   REWRITE_TAC[FORALL_DROP; GSYM IMAGE_DROP_INTERVAL] THEN
14295   REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN AP_TERM_TAC THEN
14296   MP_TAC LIFT_DROP THEN SET_TAC[]);;
14297
14298 let REAL_LEBESGUE_MEASURABLE_CLOSED = prove
14299  (`!s. real_closed s ==> real_lebesgue_measurable s`,
14300   REWRITE_TAC[REAL_LEBESGUE_MEASURABLE; REAL_CLOSED;
14301               LEBESGUE_MEASURABLE_CLOSED]);;
14302
14303 let REAL_LEBESGUE_MEASURABLE_OPEN = prove
14304  (`!s. real_open s ==> real_lebesgue_measurable s`,
14305   REWRITE_TAC[REAL_LEBESGUE_MEASURABLE; REAL_OPEN;
14306               LEBESGUE_MEASURABLE_OPEN]);;
14307
14308 let REAL_LEBESGUE_MEASURABLE_UNIONS = prove
14309  (`!f. FINITE f /\ (!s. s IN f ==> real_lebesgue_measurable s)
14310        ==> real_lebesgue_measurable (UNIONS f)`,
14311   REWRITE_TAC[IMP_CONJ] THEN
14312   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
14313   SIMP_TAC[UNIONS_0; UNIONS_INSERT; REAL_LEBESGUE_MEASURABLE_EMPTY] THEN
14314   REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THEN
14315   MATCH_MP_TAC REAL_LEBESGUE_MEASURABLE_UNION THEN ASM_SIMP_TAC[]);;
14316
14317 let REAL_LEBESGUE_MEASURABLE_COUNTABLE_UNIONS_EXPLICIT = prove
14318  (`!s:num->real->bool.
14319         (!n. real_lebesgue_measurable(s n))
14320         ==> real_lebesgue_measurable(UNIONS {s n | n IN (:num)})`,
14321   GEN_TAC THEN REWRITE_TAC[REAL_LEBESGUE_MEASURABLE] THEN DISCH_THEN(MP_TAC o
14322     MATCH_MP LEBESGUE_MEASURABLE_COUNTABLE_UNIONS_EXPLICIT) THEN
14323   REWRITE_TAC[IMAGE_UNIONS; SIMPLE_IMAGE] THEN
14324   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN SET_TAC[]);;
14325
14326 let REAL_LEBESGUE_MEASURABLE_COUNTABLE_UNIONS = prove
14327  (`!f:(real->bool)->bool.
14328         COUNTABLE f /\ (!s. s IN f ==> real_lebesgue_measurable s)
14329         ==> real_lebesgue_measurable (UNIONS f)`,
14330   GEN_TAC THEN ASM_CASES_TAC `f:(real->bool)->bool = {}` THEN
14331   ASM_REWRITE_TAC[UNIONS_0; REAL_LEBESGUE_MEASURABLE_EMPTY] THEN STRIP_TAC THEN
14332   MP_TAC(ISPEC `f:(real->bool)->bool` COUNTABLE_AS_IMAGE) THEN
14333   ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
14334   ONCE_REWRITE_TAC[GSYM SIMPLE_IMAGE] THEN
14335   MATCH_MP_TAC REAL_LEBESGUE_MEASURABLE_COUNTABLE_UNIONS_EXPLICIT THEN
14336   GEN_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
14337   ASM_REWRITE_TAC[IN_IMAGE; IN_UNIV] THEN MESON_TAC[]);;
14338
14339 let REAL_LEBESGUE_MEASURABLE_COUNTABLE_INTERS = prove
14340  (`!f:(real->bool)->bool.
14341         COUNTABLE f /\ (!s. s IN f ==> real_lebesgue_measurable s)
14342         ==> real_lebesgue_measurable (INTERS f)`,
14343   REPEAT STRIP_TAC THEN
14344   REWRITE_TAC[INTERS_UNIONS; REAL_LEBESGUE_MEASURABLE_COMPL] THEN
14345   MATCH_MP_TAC REAL_LEBESGUE_MEASURABLE_COUNTABLE_UNIONS THEN
14346   ASM_SIMP_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; COUNTABLE_IMAGE;
14347                REAL_LEBESGUE_MEASURABLE_COMPL]);;
14348
14349 let REAL_LEBESGUE_MEASURABLE_COUNTABLE_INTERS_EXPLICIT = prove
14350  (`!s:num->real->bool.
14351         (!n. real_lebesgue_measurable(s n))
14352         ==> real_lebesgue_measurable(INTERS {s n | n IN (:num)})`,
14353   REPEAT STRIP_TAC THEN
14354   MATCH_MP_TAC REAL_LEBESGUE_MEASURABLE_COUNTABLE_INTERS THEN
14355   ASM_SIMP_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; COUNTABLE_IMAGE; NUM_COUNTABLE]);;
14356
14357 let REAL_LEBESGUE_MEASURABLE_INTERS = prove
14358  (`!f:(real->bool)->bool.
14359         FINITE f /\ (!s. s IN f ==> real_lebesgue_measurable s)
14360         ==> real_lebesgue_measurable (INTERS f)`,
14361   SIMP_TAC[REAL_LEBESGUE_MEASURABLE_COUNTABLE_INTERS; FINITE_IMP_COUNTABLE]);;
14362
14363 let REAL_LEBESGUE_MEASURABLE_IFF_MEASURABLE = prove
14364  (`!s. real_bounded s ==> (real_lebesgue_measurable s <=> real_measurable s)`,
14365   REWRITE_TAC[REAL_BOUNDED; REAL_LEBESGUE_MEASURABLE;
14366               REAL_MEASURABLE_MEASURABLE] THEN
14367   REWRITE_TAC[LEBESGUE_MEASURABLE_IFF_MEASURABLE]);;
14368
14369 let REAL_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET = prove
14370  (`!f s t. s SUBSET t /\ f real_measurable_on t /\
14371            real_lebesgue_measurable s
14372            ==> f real_measurable_on s`,
14373   REPEAT GEN_TAC THEN
14374   ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV] THEN
14375   REWRITE_TAC[IN_UNIV] THEN
14376   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
14377   DISCH_THEN(MP_TAC o MATCH_MP REAL_MEASURABLE_ON_RESTRICT) THEN
14378   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
14379   REWRITE_TAC[FUN_EQ_THM] THEN ASM SET_TAC[]);;
14380
14381 let REAL_MEASURABLE_ON_MEASURABLE_SUBSET = prove
14382  (`!f s t. s SUBSET t /\ f real_measurable_on t /\ real_measurable s
14383            ==> f real_measurable_on s`,
14384   MESON_TAC[REAL_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET;
14385             REAL_MEASURABLE_IMP_REAL_LEBESGUE_MEASURABLE]);;
14386
14387 let REAL_CONTINUOUS_IMP_REAL_MEASURABLE_ON_CLOSED_SUBSET = prove
14388  (`!f s. f real_continuous_on s /\ real_closed s ==> f real_measurable_on s`,
14389   REWRITE_TAC[REAL_CONTINUOUS_ON; REAL_CLOSED; real_measurable_on] THEN
14390   REWRITE_TAC[CONTINUOUS_IMP_MEASURABLE_ON_CLOSED_SUBSET]);;
14391
14392 let REAL_CONTINUOUS_AE_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET = prove
14393  (`!f s m.
14394         f real_continuous_on s DIFF m /\
14395         real_lebesgue_measurable s /\
14396         real_negligible m
14397         ==> f real_measurable_on s`,
14398   REWRITE_TAC[real_measurable_on; real_negligible; REAL_LEBESGUE_MEASURABLE;
14399               REAL_CONTINUOUS_ON] THEN
14400   SIMP_TAC[IMAGE_DIFF_INJ; LIFT_EQ] THEN
14401   REWRITE_TAC[CONTINUOUS_AE_IMP_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET]);;
14402
14403 let REAL_MEASURABLE_ON_CASES = prove
14404  (`!P f g s.
14405         real_lebesgue_measurable {x | P x} /\
14406         f real_measurable_on s /\ g real_measurable_on s
14407         ==> (\x. if P x then f x else g x) real_measurable_on s`,
14408   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV] THEN
14409   REPEAT STRIP_TAC THEN
14410   SUBGOAL_THEN
14411    `!x. (if x IN s then if P x then f x else g x else &0) =
14412         (if x IN {x | P x} then if x IN s then f x else &0 else &0) +
14413         (if x IN (:real) DIFF {x | P x}
14414          then if x IN s then g x else &0 else &0)`
14415    (fun th -> REWRITE_TAC[th])
14416   THENL
14417    [GEN_TAC THEN REWRITE_TAC[IN_UNIV; IN_ELIM_THM; IN_DIFF] THEN
14418     MESON_TAC[REAL_ADD_LID; REAL_ADD_RID];
14419     MATCH_MP_TAC REAL_MEASURABLE_ON_ADD THEN
14420     CONJ_TAC THEN MATCH_MP_TAC REAL_MEASURABLE_ON_RESTRICT THEN
14421     ASM_REWRITE_TAC[REAL_LEBESGUE_MEASURABLE_COMPL]]);;
14422
14423 (* ------------------------------------------------------------------------- *)
14424 (* Various common equivalent forms of function measurability.                *)
14425 (* ------------------------------------------------------------------------- *)
14426
14427 let REAL_MEASURABLE_ON_PREIMAGE_HALFSPACE_LT = prove
14428  (`!f. f real_measurable_on (:real) <=>
14429         !a. real_lebesgue_measurable {x | f(x) < a}`,
14430   REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV;
14431    MEASURABLE_ON_PREIMAGE_HALFSPACE_COMPONENT_LT] THEN
14432   REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; o_DEF; LIFT_DROP] THEN
14433   GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN AP_TERM_TAC THEN
14434   CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
14435   REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);;
14436
14437 let REAL_MEASURABLE_ON_PREIMAGE_HALFSPACE_LE = prove
14438  (`!f. f real_measurable_on (:real) <=>
14439         !a. real_lebesgue_measurable {x | f(x) <= a}`,
14440   REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV;
14441    MEASURABLE_ON_PREIMAGE_HALFSPACE_COMPONENT_LE] THEN
14442   REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; o_DEF; LIFT_DROP] THEN
14443   GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN AP_TERM_TAC THEN
14444   CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
14445   REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);;
14446
14447 let REAL_MEASURABLE_ON_PREIMAGE_HALFSPACE_GT = prove
14448  (`!f. f real_measurable_on (:real) <=>
14449         !a. real_lebesgue_measurable {x | f(x) > a}`,
14450   REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV;
14451    MEASURABLE_ON_PREIMAGE_HALFSPACE_COMPONENT_GT] THEN
14452   REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; o_DEF; LIFT_DROP] THEN
14453   GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN AP_TERM_TAC THEN
14454   CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
14455   REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);;
14456
14457 let REAL_MEASURABLE_ON_PREIMAGE_HALFSPACE_GE = prove
14458  (`!f. f real_measurable_on (:real) <=>
14459         !a. real_lebesgue_measurable {x | f(x) >= a}`,
14460   REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV;
14461    MEASURABLE_ON_PREIMAGE_HALFSPACE_COMPONENT_GE] THEN
14462   REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; o_DEF; LIFT_DROP] THEN
14463   GEN_TAC THEN AP_TERM_TAC THEN ABS_TAC THEN AP_TERM_TAC THEN
14464   CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
14465   REWRITE_TAC[IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);;
14466
14467 let REAL_MEASURABLE_ON_PREIMAGE_OPEN_INTERVAL = prove
14468  (`!f. f real_measurable_on (:real) <=>
14469        !a b. real_lebesgue_measurable {x | f(x) IN real_interval(a,b)}`,
14470   REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV;
14471               MEASURABLE_ON_PREIMAGE_OPEN_INTERVAL; FORALL_DROP] THEN
14472   GEN_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN AP_TERM_TAC THEN
14473   CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
14474   REWRITE_TAC[IN_ELIM_THM; o_DEF; GSYM IMAGE_DROP_INTERVAL; LIFT_DROP;
14475               FORALL_DROP; IN_IMAGE] THEN MESON_TAC[LIFT_DROP]);;
14476
14477 let REAL_MEASURABLE_ON_PREIMAGE_CLOSED_INTERVAL = prove
14478  (`!f. f real_measurable_on (:real) <=>
14479        !a b. real_lebesgue_measurable {x | f(x) IN real_interval[a,b]}`,
14480   REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV;
14481               MEASURABLE_ON_PREIMAGE_CLOSED_INTERVAL; FORALL_DROP] THEN
14482   GEN_TAC THEN REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN AP_TERM_TAC THEN
14483   CONV_TAC SYM_CONV THEN MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
14484   REWRITE_TAC[IN_ELIM_THM; o_DEF; GSYM IMAGE_DROP_INTERVAL; LIFT_DROP;
14485               FORALL_DROP; IN_IMAGE] THEN MESON_TAC[LIFT_DROP]);;
14486
14487 let REAL_MEASURABLE_ON_PREIMAGE_OPEN = prove
14488  (`!f. f real_measurable_on (:real) <=>
14489        !t. real_open t ==> real_lebesgue_measurable {x | f(x) IN t}`,
14490   REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV;
14491               MEASURABLE_ON_PREIMAGE_OPEN; REAL_OPEN] THEN
14492   GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL
14493    [X_GEN_TAC `t:real->bool` THEN DISCH_TAC THEN
14494     FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE lift t`) THEN
14495     ASM_REWRITE_TAC[];
14496     X_GEN_TAC `t:real^1->bool` THEN DISCH_TAC THEN
14497     FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE drop t`) THEN
14498     ASM_REWRITE_TAC[IMAGE_LIFT_DROP; GSYM IMAGE_o]] THEN
14499   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THENL
14500    [CONV_TAC SYM_CONV; ALL_TAC] THEN
14501   MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
14502   REWRITE_TAC[IN_IMAGE; o_DEF; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);;
14503
14504 let REAL_MEASURABLE_ON_PREIMAGE_CLOSED = prove
14505  (`!f. f real_measurable_on (:real) <=>
14506        !t. real_closed t ==> real_lebesgue_measurable {x | f(x) IN t}`,
14507   REWRITE_TAC[real_measurable_on; REAL_LEBESGUE_MEASURABLE; IMAGE_LIFT_UNIV;
14508               MEASURABLE_ON_PREIMAGE_CLOSED; REAL_CLOSED] THEN
14509   GEN_TAC THEN EQ_TAC THEN DISCH_TAC THENL
14510    [X_GEN_TAC `t:real->bool` THEN DISCH_TAC THEN
14511     FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE lift t`) THEN
14512     ASM_REWRITE_TAC[];
14513     X_GEN_TAC `t:real^1->bool` THEN DISCH_TAC THEN
14514     FIRST_X_ASSUM(MP_TAC o SPEC `IMAGE drop t`) THEN
14515     ASM_REWRITE_TAC[IMAGE_LIFT_DROP; GSYM IMAGE_o]] THEN
14516   MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THENL
14517    [CONV_TAC SYM_CONV; ALL_TAC] THEN
14518   MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN
14519   REWRITE_TAC[IN_IMAGE; o_DEF; IN_ELIM_THM] THEN MESON_TAC[LIFT_DROP]);;
14520
14521 let REAL_MEASURABLE_ON_SIMPLE_FUNCTION_LIMIT = prove
14522  (`!f. f real_measurable_on (:real) <=>
14523        ?g. (!n. (g n) real_measurable_on (:real)) /\
14524            (!n. FINITE(IMAGE (g n) (:real))) /\
14525            (!x. ((\n. g n x) ---> f x) sequentially)`,
14526   GEN_TAC THEN REWRITE_TAC[real_measurable_on; IMAGE_LIFT_UNIV] THEN
14527   GEN_REWRITE_TAC LAND_CONV [MEASURABLE_ON_SIMPLE_FUNCTION_LIMIT] THEN
14528   EQ_TAC THENL
14529    [DISCH_THEN(X_CHOOSE_THEN `g:num->real^1->real^1` STRIP_ASSUME_TAC) THEN
14530     EXISTS_TAC `\n:num. drop o g n o lift` THEN
14531     REWRITE_TAC[TENDSTO_REAL] THEN REPEAT CONJ_TAC THENL
14532      [ASM_REWRITE_TAC[o_DEF; LIFT_DROP; ETA_AX];
14533       GEN_TAC THEN REWRITE_TAC[IMAGE_o; IMAGE_LIFT_UNIV] THEN
14534       MATCH_MP_TAC FINITE_IMAGE THEN ASM_REWRITE_TAC[];
14535       X_GEN_TAC `x:real` THEN REWRITE_TAC[TENDSTO_REAL] THEN
14536       FIRST_X_ASSUM(MP_TAC o SPEC `lift x`) THEN
14537       REWRITE_TAC[o_DEF; LIFT_DROP]];
14538     DISCH_THEN(X_CHOOSE_THEN `g:num->real->real` STRIP_ASSUME_TAC) THEN
14539     EXISTS_TAC `\n:num. lift o g n o drop` THEN REPEAT CONJ_TAC THENL
14540      [ASM_REWRITE_TAC[];
14541       GEN_TAC THEN REWRITE_TAC[IMAGE_o; IMAGE_DROP_UNIV] THEN
14542       MATCH_MP_TAC FINITE_IMAGE THEN ASM_REWRITE_TAC[];
14543       X_GEN_TAC `x:real^1` THEN FIRST_X_ASSUM(MP_TAC o SPEC `drop x`) THEN
14544       REWRITE_TAC[TENDSTO_REAL; o_DEF; LIFT_DROP]]]);;
14545
14546 let REAL_LEBESGUE_MEASURABLE_PREIMAGE_OPEN = prove
14547  (`!f t. f real_measurable_on (:real) /\ real_open t
14548          ==> real_lebesgue_measurable {x | f(x) IN t}`,
14549   SIMP_TAC[REAL_MEASURABLE_ON_PREIMAGE_OPEN]);;
14550
14551 let REAL_LEBESGUE_MEASURABLE_PREIMAGE_CLOSED = prove
14552  (`!f t. f real_measurable_on (:real) /\ real_closed t
14553          ==> real_lebesgue_measurable {x | f(x) IN t}`,
14554   SIMP_TAC[REAL_MEASURABLE_ON_PREIMAGE_CLOSED]);;
14555
14556 (* ------------------------------------------------------------------------- *)
14557 (* Continuity of measure within a halfspace w.r.t. to the boundary.          *)
14558 (* ------------------------------------------------------------------------- *)
14559
14560 let REAL_CONTINUOUS_MEASURE_IN_HALFSPACE_LE = prove
14561  (`!(s:real^N->bool) a i.
14562         measurable s /\ 1 <= i /\ i <= dimindex(:N)
14563         ==> (\a. measure(s INTER {x | x$i <= a})) real_continuous atreal a`,
14564   REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS1] THEN
14565   REWRITE_TAC[continuous_atreal; o_THM] THEN
14566   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
14567   SUBGOAL_THEN
14568    `?u v:real^N. abs(measure(s INTER interval[u,v]) - measure s) < e / &2 /\
14569                  ~(interval(u,v) = {}) /\ u$i < a /\ a < v$i`
14570   STRIP_ASSUME_TAC THENL
14571    [MP_TAC(ISPECL [`s:real^N->bool`; `e / &2`] MEASURE_LIMIT) THEN
14572     ASM_REWRITE_TAC[REAL_HALF] THEN
14573     DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
14574     MP_TAC(ISPEC `ball(vec 0:real^N,B)` BOUNDED_SUBSET_CLOSED_INTERVAL) THEN
14575     REWRITE_TAC[BOUNDED_BALL; LEFT_IMP_EXISTS_THM] THEN
14576     MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN DISCH_TAC THEN
14577     EXISTS_TAC `(lambda j. min (a - &1) ((u:real^N)$j)):real^N` THEN
14578     EXISTS_TAC `(lambda j. max (a + &1) ((v:real^N)$j)):real^N` THEN
14579     CONJ_TAC THENL
14580      [FIRST_X_ASSUM MATCH_MP_TAC THEN FIRST_X_ASSUM
14581        (MATCH_MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ] SUBSET_TRANS)) THEN
14582       SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN REAL_ARITH_TAC;
14583       ASM_SIMP_TAC[INTERVAL_NE_EMPTY; LAMBDA_BETA] THEN REAL_ARITH_TAC];
14584     ALL_TAC] THEN
14585   MP_TAC(ISPECL
14586    [`indicator(s:real^N->bool)`; `u:real^N`; `v:real^N`; `u:real^N`;
14587     `(lambda j. if j = i then min ((v:real^N)$i) a else v$j):real^N`;
14588     `e / &2`]
14589       INDEFINITE_INTEGRAL_CONTINUOUS) THEN
14590   ASM_REWRITE_TAC[REAL_HALF] THEN ANTS_TAC THENL
14591    [ONCE_REWRITE_TAC[GSYM INTEGRABLE_RESTRICT_UNIV] THEN
14592     REWRITE_TAC[indicator; MESON[]
14593      `(if P then if Q then x else y else y) =
14594       (if P /\ Q then x else y)`] THEN
14595     REWRITE_TAC[GSYM IN_INTER; GSYM MEASURABLE_INTEGRABLE] THEN
14596     ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_INTERVAL] THEN
14597     RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN
14598     ASM_SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; REAL_LE_REFL; REAL_LT_IMP_LE] THEN
14599     X_GEN_TAC `j:num` THEN STRIP_TAC THEN
14600     FIRST_X_ASSUM(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN
14601     COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC;
14602     ALL_TAC] THEN
14603   DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
14604   EXISTS_TAC `min d (min (a - (u:real^N)$i) ((v:real^N)$i - a))` THEN
14605   ASM_REWRITE_TAC[REAL_LT_MIN; REAL_SUB_LT] THEN
14606   X_GEN_TAC `b:real` THEN STRIP_TAC THEN
14607   FIRST_X_ASSUM(MP_TAC o SPECL [`u:real^N`;
14608    `(lambda j. if j = i then min ((v:real^N)$i) b else v$j):real^N`]) THEN
14609   REWRITE_TAC[dist] THEN ANTS_TAC THENL
14610    [RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN
14611     ASM_SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; REAL_LE_REFL; REAL_LT_IMP_LE] THEN
14612     ASM_SIMP_TAC[VECTOR_SUB_REFL; NORM_0; REAL_LT_IMP_LE] THEN CONJ_TAC THENL
14613      [X_GEN_TAC `j:num` THEN STRIP_TAC THEN
14614       FIRST_X_ASSUM(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN
14615       COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC;
14616       ASM_SIMP_TAC[NORM_LE_SQUARE; dot; REAL_LT_IMP_LE] THEN
14617       MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
14618        `sum(1..dimindex(:N)) (\j. if j = i then d pow 2 else &0)` THEN
14619       CONJ_TAC THENL
14620        [MATCH_MP_TAC SUM_LE_NUMSEG THEN X_GEN_TAC `j:num` THEN STRIP_TAC THEN
14621         ASM_SIMP_TAC[LAMBDA_BETA; VECTOR_SUB_COMPONENT] THEN
14622         COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
14623         REWRITE_TAC[GSYM REAL_POW_2; GSYM REAL_LE_SQUARE_ABS] THEN
14624         ASM_REAL_ARITH_TAC;
14625         ASM_REWRITE_TAC[SUM_DELTA; IN_NUMSEG; REAL_LE_REFL]]];
14626     SUBGOAL_THEN
14627      `!b. integral
14628            (interval[u:real^N,
14629                      (lambda j. if j = i then min (v$i) b else (v:real^N)$j)])
14630            (indicator s) =
14631           lift(measure(s INTER interval[u,v] INTER {x | x$i <= b}))`
14632      (fun th -> REWRITE_TAC[th])
14633     THENL
14634      [GEN_TAC THEN
14635       ASM_SIMP_TAC[MEASURE_INTEGRAL; MEASURABLE_INTER_HALFSPACE_LE;
14636                    MEASURABLE_INTER; MEASURABLE_INTERVAL; LIFT_DROP] THEN
14637       ONCE_REWRITE_TAC[GSYM INTEGRAL_RESTRICT_UNIV] THEN
14638       AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN
14639       ASM_SIMP_TAC[INTERVAL_SPLIT; indicator] THEN
14640       REWRITE_TAC[IN_INTER] THEN MESON_TAC[];
14641       REWRITE_TAC[GSYM LIFT_SUB; NORM_LIFT] THEN
14642       SUBGOAL_THEN
14643        `!b. measure(s INTER {x:real^N | x$i <= b}) =
14644             measure((s INTER interval[u,v]) INTER {x | x$i <= b}) +
14645             measure((s DIFF interval[u,v]) INTER {x | x$i <= b})`
14646        (fun th -> REWRITE_TAC[th])
14647       THENL
14648        [GEN_TAC THEN CONV_TAC SYM_CONV THEN
14649         MATCH_MP_TAC MEASURE_NEGLIGIBLE_UNION_EQ THEN
14650         ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_INTER_HALFSPACE_LE;
14651                      MEASURABLE_INTERVAL; MEASURABLE_DIFF] THEN
14652         CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
14653         MATCH_MP_TAC(MESON[NEGLIGIBLE_EMPTY] `s = {} ==> negligible s`) THEN
14654         SET_TAC[];
14655         REWRITE_TAC[GSYM INTER_ASSOC] THEN MATCH_MP_TAC(REAL_ARITH
14656          `abs(nub - nua) < e / &2
14657           ==> abs(mub - mua) < e / &2
14658               ==> abs((mub + nub) - (mua + nua)) < e`) THEN
14659         FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
14660          `y < e ==> x <= y ==> x < e`)) THEN
14661         SUBGOAL_THEN
14662          `abs(measure(s INTER interval [u,v]) - measure s) =
14663           measure(s DIFF interval[u:real^N,v])`
14664         SUBST1_TAC THENL
14665          [MATCH_MP_TAC(REAL_ARITH
14666            `x + z = y /\ &0 <= z ==> abs(x - y) = z`) THEN
14667           ASM_SIMP_TAC[MEASURE_POS_LE; MEASURABLE_DIFF;
14668                        MEASURABLE_INTERVAL] THEN
14669           MATCH_MP_TAC MEASURE_NEGLIGIBLE_UNION_EQ THEN
14670           ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_DIFF;
14671                        MEASURABLE_INTERVAL] THEN
14672           CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
14673           MATCH_MP_TAC(MESON[NEGLIGIBLE_EMPTY] `s = {} ==> negligible s`) THEN
14674           SET_TAC[];
14675           MATCH_MP_TAC(REAL_ARITH
14676            `&0 <= x /\ x <= a /\ &0 <= y /\ y <= a ==> abs(x - y) <= a`) THEN
14677           ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_INTER_HALFSPACE_LE;
14678             MEASURABLE_INTERVAL; MEASURABLE_DIFF; MEASURE_POS_LE] THEN
14679           CONJ_TAC THEN MATCH_MP_TAC MEASURE_SUBSET THEN
14680           ASM_SIMP_TAC[MEASURABLE_INTER; MEASURABLE_INTER_HALFSPACE_LE;
14681             MEASURABLE_INTERVAL; MEASURABLE_DIFF; MEASURE_POS_LE] THEN
14682           SET_TAC[]]]]]);;
14683
14684 (* ------------------------------------------------------------------------- *)
14685 (* Second mean value theorem and monotone integrability.                     *)
14686 (* ------------------------------------------------------------------------- *)
14687
14688 let REAL_SECOND_MEAN_VALUE_THEOREM_FULL = prove
14689  (`!f g a b.
14690         ~(real_interval[a,b] = {}) /\
14691         f real_integrable_on real_interval[a,b] /\
14692         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
14693                ==> g x <= g y)
14694         ==> ?c. c IN real_interval[a,b] /\
14695                 ((\x. g x * f x) has_real_integral
14696                  (g(a) * real_integral (real_interval[a,c]) f +
14697                   g(b) * real_integral (real_interval[c,b]) f))
14698                 (real_interval[a,b])`,
14699   REPEAT STRIP_TAC THEN
14700   MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`;
14701                  `lift a`; `lift b`]
14702     SECOND_MEAN_VALUE_THEOREM_FULL) THEN
14703   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY] THEN
14704   ASM_REWRITE_TAC[GSYM REAL_INTEGRABLE_ON] THEN
14705   REWRITE_TAC[EXISTS_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
14706   ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP] THEN
14707   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real` THEN
14708   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
14709   REWRITE_TAC[HAS_REAL_INTEGRAL; IMAGE_LIFT_REAL_INTERVAL] THEN
14710   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN
14711   REWRITE_TAC[o_DEF; LIFT_CMUL; LIFT_ADD] THEN AP_TERM_TAC THEN
14712   BINOP_TAC THEN AP_TERM_TAC THEN ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN
14713   REWRITE_TAC[LIFT_DROP] THEN
14714   W(MP_TAC o PART_MATCH (lhs o rand) REAL_INTEGRAL o rand o snd) THEN
14715   REWRITE_TAC[o_DEF] THEN ANTS_TAC THEN SIMP_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN
14716   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
14717         REAL_INTEGRABLE_ON_SUBINTERVAL)) THEN
14718   REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN
14719   RULE_ASSUM_TAC(REWRITE_RULE[IN_REAL_INTERVAL; REAL_INTERVAL_EQ_EMPTY]) THEN
14720   ASM_REAL_ARITH_TAC);;
14721
14722 let REAL_SECOND_MEAN_VALUE_THEOREM = prove
14723  (`!f g a b.
14724         ~(real_interval[a,b] = {}) /\
14725         f real_integrable_on real_interval[a,b] /\
14726         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
14727                ==> g x <= g y)
14728         ==> ?c. c IN real_interval[a,b] /\
14729                 real_integral (real_interval[a,b]) (\x. g x * f x) =
14730                  g(a) * real_integral (real_interval[a,c]) f +
14731                  g(b) * real_integral (real_interval[c,b]) f`,
14732   REPEAT GEN_TAC THEN
14733   DISCH_THEN(MP_TAC o MATCH_MP REAL_SECOND_MEAN_VALUE_THEOREM_FULL) THEN
14734   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real` THEN
14735   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
14736   FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN
14737   REWRITE_TAC[]);;
14738
14739 let REAL_SECOND_MEAN_VALUE_THEOREM_GEN_FULL = prove
14740  (`!f g a b u v.
14741         ~(real_interval[a,b] = {}) /\
14742         f real_integrable_on real_interval[a,b] /\
14743         (!x. x IN real_interval(a,b) ==> u <= g x /\ g x <= v) /\
14744         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
14745                ==> g x <= g y)
14746         ==> ?c. c IN real_interval[a,b] /\
14747                 ((\x. g x * f x) has_real_integral
14748                  (u * real_integral (real_interval[a,c]) f +
14749                   v * real_integral (real_interval[c,b]) f))
14750                 (real_interval[a,b])`,
14751   REPEAT STRIP_TAC THEN
14752   MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`;
14753                  `lift a`; `lift b`; `u:real`; `v:real`]
14754     SECOND_MEAN_VALUE_THEOREM_GEN_FULL) THEN
14755   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY] THEN
14756   ASM_REWRITE_TAC[GSYM REAL_INTEGRABLE_ON] THEN
14757   REWRITE_TAC[EXISTS_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
14758   ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP] THEN
14759   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real` THEN
14760   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
14761   REWRITE_TAC[HAS_REAL_INTEGRAL; IMAGE_LIFT_REAL_INTERVAL] THEN
14762   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN
14763   REWRITE_TAC[o_DEF; LIFT_CMUL; LIFT_ADD] THEN AP_TERM_TAC THEN
14764   BINOP_TAC THEN AP_TERM_TAC THEN ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN
14765   REWRITE_TAC[LIFT_DROP] THEN
14766   W(MP_TAC o PART_MATCH (lhs o rand) REAL_INTEGRAL o rand o snd) THEN
14767   REWRITE_TAC[o_DEF] THEN ANTS_TAC THEN SIMP_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN
14768   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
14769         REAL_INTEGRABLE_ON_SUBINTERVAL)) THEN
14770   REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN
14771   RULE_ASSUM_TAC(REWRITE_RULE[IN_REAL_INTERVAL; REAL_INTERVAL_EQ_EMPTY]) THEN
14772   ASM_REAL_ARITH_TAC);;
14773
14774 let REAL_SECOND_MEAN_VALUE_THEOREM_GEN = prove
14775  (`!f g a b u v.
14776         ~(real_interval[a,b] = {}) /\
14777         f real_integrable_on real_interval[a,b] /\
14778         (!x. x IN real_interval(a,b) ==> u <= g x /\ g x <= v) /\
14779         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
14780                ==> g x <= g y)
14781         ==> ?c. c IN real_interval[a,b] /\
14782                 real_integral (real_interval[a,b]) (\x. g x * f x) =
14783                  u * real_integral (real_interval[a,c]) f +
14784                  v * real_integral (real_interval[c,b]) f`,
14785   REPEAT GEN_TAC THEN
14786   DISCH_THEN(MP_TAC o MATCH_MP REAL_SECOND_MEAN_VALUE_THEOREM_GEN_FULL) THEN
14787   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real` THEN
14788   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
14789   FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN
14790   REWRITE_TAC[]);;
14791
14792 let REAL_SECOND_MEAN_VALUE_THEOREM_BONNET_FULL = prove
14793  (`!f g a b.
14794         ~(real_interval[a,b] = {}) /\
14795         f real_integrable_on real_interval[a,b] /\
14796         (!x. x IN real_interval[a,b] ==> &0 <= g x) /\
14797         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
14798                ==> g x <= g y)
14799         ==> ?c. c IN real_interval[a,b] /\
14800                 ((\x. g x * f x) has_real_integral
14801                  (g(b) * real_integral (real_interval[c,b]) f))
14802                 (real_interval[a,b])`,
14803   REPEAT STRIP_TAC THEN
14804   MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`;
14805                  `lift a`; `lift b`]
14806     SECOND_MEAN_VALUE_THEOREM_BONNET_FULL) THEN
14807   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY] THEN
14808   ASM_REWRITE_TAC[GSYM REAL_INTEGRABLE_ON] THEN
14809   REWRITE_TAC[EXISTS_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
14810   ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP] THEN
14811   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real` THEN
14812   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
14813   REWRITE_TAC[HAS_REAL_INTEGRAL; IMAGE_LIFT_REAL_INTERVAL] THEN
14814   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN
14815   REWRITE_TAC[o_DEF; LIFT_CMUL; LIFT_ADD] THEN AP_TERM_TAC THEN
14816   AP_TERM_TAC THEN ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN
14817   REWRITE_TAC[LIFT_DROP] THEN
14818   W(MP_TAC o PART_MATCH (lhs o rand) REAL_INTEGRAL o rand o snd) THEN
14819   REWRITE_TAC[o_DEF] THEN ANTS_TAC THEN SIMP_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN
14820   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
14821         REAL_INTEGRABLE_ON_SUBINTERVAL)) THEN
14822   REWRITE_TAC[SUBSET_REAL_INTERVAL] THEN
14823   RULE_ASSUM_TAC(REWRITE_RULE[IN_REAL_INTERVAL; REAL_INTERVAL_EQ_EMPTY]) THEN
14824   ASM_REAL_ARITH_TAC);;
14825
14826 let REAL_SECOND_MEAN_VALUE_THEOREM_BONNET = prove
14827  (`!f g a b.
14828         ~(real_interval[a,b] = {}) /\
14829         f real_integrable_on real_interval[a,b] /\
14830         (!x. x IN real_interval[a,b] ==> &0 <= g x) /\
14831         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
14832                ==> g x <= g y)
14833         ==> ?c. c IN real_interval[a,b] /\
14834                 real_integral (real_interval[a,b]) (\x. g x * f x) =
14835                 g(b) * real_integral (real_interval[c,b]) f`,
14836   REPEAT GEN_TAC THEN
14837   DISCH_THEN(MP_TAC o MATCH_MP REAL_SECOND_MEAN_VALUE_THEOREM_BONNET_FULL) THEN
14838   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real` THEN
14839   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
14840   FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP REAL_INTEGRAL_UNIQUE) THEN
14841   REWRITE_TAC[]);;
14842
14843 let REAL_INTEGRABLE_INCREASING_PRODUCT = prove
14844  (`!f g a b.
14845         f real_integrable_on real_interval[a,b] /\
14846         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
14847                ==> g(x) <= g(y))
14848         ==> (\x. g(x) * f(x)) real_integrable_on real_interval[a,b]`,
14849   REPEAT STRIP_TAC THEN
14850   MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`;
14851                  `lift a`; `lift b`]
14852     INTEGRABLE_INCREASING_PRODUCT) THEN
14853   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL;
14854                   GSYM REAL_INTEGRABLE_ON] THEN
14855   ASM_SIMP_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
14856   ASM_SIMP_TAC[o_DEF; LIFT_DROP; REAL_INTEGRABLE_ON; LIFT_CMUL]);;
14857
14858 let REAL_INTEGRABLE_INCREASING_PRODUCT_UNIV = prove
14859  (`!f g B.
14860         f real_integrable_on (:real) /\
14861         (!x y. x <= y ==> g x <= g y) /\
14862         (!x. abs(g x) <= B)
14863          ==> (\x. g x * f x) real_integrable_on (:real)`,
14864   REPEAT STRIP_TAC THEN
14865   MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`; `B:real`]
14866     INTEGRABLE_INCREASING_PRODUCT_UNIV) THEN
14867   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_UNIV;
14868                   GSYM REAL_INTEGRABLE_ON] THEN
14869   ASM_SIMP_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
14870   ASM_SIMP_TAC[o_DEF; LIFT_DROP; REAL_INTEGRABLE_ON; LIFT_CMUL]);;
14871
14872 let REAL_INTEGRABLE_INCREASING = prove
14873  (`!f a b.
14874         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
14875                ==> f(x) <= f(y))
14876         ==> f real_integrable_on real_interval[a,b]`,
14877   REPEAT STRIP_TAC THEN
14878   MP_TAC(ISPECL [`lift o f o drop`; `lift a`; `lift b`]
14879     INTEGRABLE_INCREASING_1) THEN
14880   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL;
14881                   GSYM REAL_INTEGRABLE_ON] THEN
14882   DISCH_THEN MATCH_MP_TAC THEN
14883   ASM_SIMP_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
14884   ASM_SIMP_TAC[o_DEF; LIFT_DROP; REAL_INTEGRABLE_ON; LIFT_CMUL]);;
14885
14886 let REAL_INTEGRABLE_DECREASING_PRODUCT = prove
14887  (`!f g a b.
14888         f real_integrable_on real_interval[a,b] /\
14889         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
14890                ==> g(y) <= g(x))
14891         ==> (\x. g(x) * f(x)) real_integrable_on real_interval[a,b]`,
14892   REPEAT STRIP_TAC THEN
14893   MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`;
14894                  `lift a`; `lift b`]
14895     INTEGRABLE_DECREASING_PRODUCT) THEN
14896   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL;
14897                   GSYM REAL_INTEGRABLE_ON] THEN
14898   ASM_SIMP_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
14899   ASM_SIMP_TAC[o_DEF; LIFT_DROP; REAL_INTEGRABLE_ON; LIFT_CMUL]);;
14900
14901 let REAL_INTEGRABLE_DECREASING_PRODUCT_UNIV = prove
14902  (`!f g B.
14903         f real_integrable_on (:real) /\
14904         (!x y. x <= y ==> g y <= g x) /\
14905         (!x. abs(g x) <= B)
14906          ==> (\x. g x * f x) real_integrable_on (:real)`,
14907   REPEAT STRIP_TAC THEN
14908   MP_TAC(ISPECL [`lift o f o drop`; `(g:real->real) o drop`; `B:real`]
14909     INTEGRABLE_DECREASING_PRODUCT_UNIV) THEN
14910   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_UNIV;
14911                   GSYM REAL_INTEGRABLE_ON] THEN
14912   ASM_SIMP_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
14913   ASM_SIMP_TAC[o_DEF; LIFT_DROP; REAL_INTEGRABLE_ON; LIFT_CMUL]);;
14914
14915 let REAL_INTEGRABLE_DECREASING = prove
14916  (`!f a b.
14917         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
14918                ==> f(y) <= f(x))
14919         ==> f real_integrable_on real_interval[a,b]`,
14920   REPEAT STRIP_TAC THEN
14921   MP_TAC(ISPECL [`lift o f o drop`; `lift a`; `lift b`]
14922     INTEGRABLE_DECREASING_1) THEN
14923   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL;
14924                   GSYM REAL_INTEGRABLE_ON] THEN
14925   DISCH_THEN MATCH_MP_TAC THEN
14926   ASM_SIMP_TAC[FORALL_IN_IMAGE; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
14927   ASM_SIMP_TAC[o_DEF; LIFT_DROP; REAL_INTEGRABLE_ON; LIFT_CMUL]);;
14928
14929 (* ------------------------------------------------------------------------- *)
14930 (* Measurability and absolute integrability of monotone functions.           *)
14931 (* ------------------------------------------------------------------------- *)
14932
14933 let REAL_MEASURABLE_ON_INCREASING_UNIV = prove
14934  (`!f. (!x y. x <= y ==> f x <= f y) ==> f real_measurable_on (:real)`,
14935   REPEAT STRIP_TAC THEN
14936   REWRITE_TAC[REAL_MEASURABLE_ON_PREIMAGE_HALFSPACE_LE] THEN
14937   X_GEN_TAC `y:real` THEN
14938   REPEAT_TCL STRIP_THM_THEN ASSUME_TAC
14939    (SET_RULE `{x | (f:real->real) x <= y} = {} \/
14940               {x | (f:real->real) x <= y} = UNIV \/
14941               ?a b. f a <= y /\ ~(f b <= y)`) THEN
14942   ASM_REWRITE_TAC[REAL_LEBESGUE_MEASURABLE_EMPTY;
14943                   REAL_LEBESGUE_MEASURABLE_UNIV] THEN
14944   MP_TAC(ISPEC `{x | (f:real->real) x <= y}` SUP) THEN
14945   REWRITE_TAC[IN_ELIM_THM; EXTENSION; NOT_IN_EMPTY] THEN ANTS_TAC THENL
14946    [ASM_MESON_TAC[REAL_LE_TOTAL; REAL_LE_TRANS]; ALL_TAC] THEN
14947   ABBREV_TAC `s = sup {x | (f:real->real) x <= y}` THEN STRIP_TAC THEN
14948   SUBGOAL_THEN
14949     `(!x. (f:real->real) x <= y <=> x < s) \/
14950      (!x. (f:real->real) x <= y <=> x <= s)`
14951   STRIP_ASSUME_TAC THENL
14952    [ASM_CASES_TAC `(f:real->real) s <= y` THEN
14953     ASM_MESON_TAC[REAL_LE_TRANS; REAL_NOT_LE; REAL_LE_ANTISYM; REAL_LE_TOTAL];
14954     ASM_SIMP_TAC[REAL_OPEN_HALFSPACE_LT; REAL_LEBESGUE_MEASURABLE_OPEN];
14955     ASM_SIMP_TAC[REAL_CLOSED_HALFSPACE_LE; REAL_LEBESGUE_MEASURABLE_CLOSED]]);;
14956
14957 let REAL_MEASURABLE_ON_INCREASING = prove
14958  (`!f a b. (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
14959                   ==> f x <= f y)
14960            ==> f real_measurable_on real_interval[a,b]`,
14961   REWRITE_TAC[IN_REAL_INTERVAL] THEN REPEAT STRIP_TAC THEN
14962   ASM_CASES_TAC `real_interval[a,b] = {}` THENL
14963    [ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV] THEN
14964     ASM_REWRITE_TAC[NOT_IN_EMPTY; REAL_MEASURABLE_ON_0];
14965     RULE_ASSUM_TAC(REWRITE_RULE[REAL_INTERVAL_EQ_EMPTY; REAL_NOT_LT])] THEN
14966   ABBREV_TAC `g = \x. if x < a then f(a)
14967                       else if b < x then f(b)
14968                       else (f:real->real) x` THEN
14969   SUBGOAL_THEN `g real_measurable_on real_interval[a,b]` MP_TAC THENL
14970    [ALL_TAC;
14971     ONCE_REWRITE_TAC[GSYM REAL_MEASURABLE_ON_UNIV] THEN EXPAND_TAC "g" THEN
14972     SIMP_TAC[IN_REAL_INTERVAL; GSYM REAL_NOT_LT]] THEN
14973   MATCH_MP_TAC REAL_MEASURABLE_ON_LEBESGUE_MEASURABLE_SUBSET THEN
14974   EXISTS_TAC `(:real)` THEN
14975   REWRITE_TAC[SUBSET_UNIV; REAL_LEBESGUE_MEASURABLE_INTERVAL] THEN
14976   MATCH_MP_TAC REAL_MEASURABLE_ON_INCREASING_UNIV THEN EXPAND_TAC "g" THEN
14977   ASM_MESON_TAC[REAL_LT_LE; REAL_LE_TRANS; REAL_LE_TOTAL; REAL_LE_ANTISYM;
14978                 REAL_NOT_LT; REAL_LT_IMP_LE; REAL_LE_REFL]);;
14979
14980 let REAL_MEASURABLE_ON_DECREASING_UNIV = prove
14981  (`!f. (!x y. x <= y ==> f y <= f x) ==> f real_measurable_on (:real)`,
14982   REPEAT STRIP_TAC THEN
14983   GEN_REWRITE_TAC I [GSYM REAL_MEASURABLE_ON_NEG_EQ] THEN
14984   MATCH_MP_TAC REAL_MEASURABLE_ON_INCREASING_UNIV THEN
14985   ASM_SIMP_TAC[REAL_LE_NEG2]);;
14986
14987 let REAL_MEASURABLE_ON_DECREASING = prove
14988  (`!f a b. (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
14989                   ==> f y <= f x)
14990            ==> f real_measurable_on real_interval[a,b]`,
14991   REPEAT STRIP_TAC THEN
14992   GEN_REWRITE_TAC I [GSYM REAL_MEASURABLE_ON_NEG_EQ] THEN
14993   MATCH_MP_TAC REAL_MEASURABLE_ON_INCREASING THEN
14994   ASM_SIMP_TAC[REAL_LE_NEG2]);;
14995
14996 let ABSOLUTELY_REAL_INTEGRABLE_INCREASING_PRODUCT = prove
14997  (`!f g a b.
14998         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
14999                ==> f x <= f y) /\
15000         g absolutely_real_integrable_on real_interval[a,b]
15001         ==> (\x. f x * g x) absolutely_real_integrable_on real_interval[a,b]`,
15002   REPEAT STRIP_TAC THEN
15003   MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_BOUNDED_MEASURABLE_PRODUCT THEN
15004   ASM_SIMP_TAC[REAL_MEASURABLE_ON_INCREASING] THEN
15005   REWRITE_TAC[real_bounded; FORALL_IN_IMAGE] THEN
15006   EXISTS_TAC `abs((f:real->real) a) + abs((f:real->real) b)` THEN
15007   REPEAT STRIP_TAC THEN MATCH_MP_TAC
15008    (REAL_ARITH `a <= x /\ x <= b ==> abs x <= abs a + abs b`) THEN
15009   CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
15010   ASM_REWRITE_TAC[] THEN
15011   ASM_MESON_TAC[IN_REAL_INTERVAL; REAL_LE_TRANS; REAL_LE_REFL]);;
15012
15013 let ABSOLUTELY_REAL_INTEGRABLE_INCREASING = prove
15014  (`!f a b. (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
15015                   ==> f x <= f y)
15016            ==> f absolutely_real_integrable_on real_interval[a,b]`,
15017   REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN
15018   GEN_REWRITE_TAC (LAND_CONV o ABS_CONV) [GSYM REAL_MUL_RID] THEN
15019   MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_INCREASING_PRODUCT THEN
15020   ASM_REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_CONST]);;
15021
15022 let ABSOLUTELY_REAL_INTEGRABLE_DECREASING_PRODUCT = prove
15023  (`!f g a b.
15024         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
15025                ==> f y <= f x) /\
15026         g absolutely_real_integrable_on real_interval[a,b]
15027         ==> (\x. f x * g x) absolutely_real_integrable_on real_interval[a,b]`,
15028   REPEAT STRIP_TAC THEN
15029   MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_BOUNDED_MEASURABLE_PRODUCT THEN
15030   ASM_SIMP_TAC[REAL_MEASURABLE_ON_DECREASING] THEN
15031   REWRITE_TAC[real_bounded; FORALL_IN_IMAGE] THEN
15032   EXISTS_TAC `abs((f:real->real) a) + abs((f:real->real) b)` THEN
15033   REPEAT STRIP_TAC THEN MATCH_MP_TAC
15034    (REAL_ARITH `b <= x /\ x <= a ==> abs x <= abs a + abs b`) THEN
15035   CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
15036   ASM_REWRITE_TAC[] THEN
15037   ASM_MESON_TAC[IN_REAL_INTERVAL; REAL_LE_TRANS; REAL_LE_REFL]);;
15038
15039 let ABSOLUTELY_REAL_INTEGRABLE_DECREASING = prove
15040  (`!f a b. (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
15041                   ==> f y <= f x)
15042            ==> f absolutely_real_integrable_on real_interval[a,b]`,
15043   REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN
15044   GEN_REWRITE_TAC (LAND_CONV o ABS_CONV) [GSYM REAL_MUL_RID] THEN
15045   MATCH_MP_TAC ABSOLUTELY_REAL_INTEGRABLE_DECREASING_PRODUCT THEN
15046   ASM_REWRITE_TAC[ABSOLUTELY_REAL_INTEGRABLE_CONST]);;
15047
15048 (* ------------------------------------------------------------------------- *)
15049 (* Real functions of bounded variation.                                      *)
15050 (* ------------------------------------------------------------------------- *)
15051
15052 parse_as_infix("has_bounded_real_variation_on",(12,"right"));;
15053
15054 let has_bounded_real_variation_on = new_definition
15055  `f has_bounded_real_variation_on s <=>
15056   (lift o f o drop) has_bounded_variation_on (IMAGE lift s)`;;
15057
15058 let real_variation = new_definition
15059  `real_variation s f = vector_variation (IMAGE lift s) (lift o f o drop)`;;
15060
15061 let HAS_BOUNDED_REAL_VARIATION_ON_EQ = prove
15062  (`!f g s.
15063         (!x. x IN s ==> f x = g x) /\ f has_bounded_real_variation_on s
15064
15065
15066         ==> g has_bounded_real_variation_on s`,
15067   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
15068   REWRITE_TAC[IMP_CONJ; has_bounded_real_variation_on] THEN
15069   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_BOUNDED_VARIATION_ON_EQ) THEN
15070   ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP]);;
15071
15072 let HAS_BOUNDED_REAL_VARIATION_ON_SUBSET = prove
15073  (`!f s t. f has_bounded_real_variation_on s /\ t SUBSET s
15074            ==> f has_bounded_real_variation_on t`,
15075   REWRITE_TAC[has_bounded_real_variation_on] THEN
15076   MESON_TAC[HAS_BOUNDED_VARIATION_ON_SUBSET; IMAGE_SUBSET]);;
15077
15078 let HAS_BOUNDED_REAL_VARIATION_ON_LMUL = prove
15079  (`!f c s. f has_bounded_real_variation_on s
15080            ==> (\x. c * f x) has_bounded_real_variation_on s`,
15081   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN
15082   REWRITE_TAC[o_DEF; LIFT_CMUL; HAS_BOUNDED_VARIATION_ON_CMUL]);;
15083
15084 let HAS_BOUNDED_REAL_VARIATION_ON_RMUL = prove
15085  (`!f c s. f has_bounded_real_variation_on s
15086            ==> (\x. f x * c) has_bounded_real_variation_on s`,
15087   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
15088   REWRITE_TAC[HAS_BOUNDED_REAL_VARIATION_ON_LMUL]);;
15089
15090 let HAS_BOUNDED_REAL_VARIATION_ON_NEG = prove
15091  (`!f s. f has_bounded_real_variation_on s
15092          ==> (\x. --f x) has_bounded_real_variation_on s`,
15093   REWRITE_TAC[has_bounded_real_variation_on; o_DEF; LIFT_NEG] THEN
15094   REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_NEG]);;
15095
15096 let HAS_BOUNDED_REAL_VARIATION_ON_ADD = prove
15097  (`!f g s. f has_bounded_real_variation_on s /\
15098            g has_bounded_real_variation_on s
15099            ==> (\x. f x + g x) has_bounded_real_variation_on s`,
15100   REWRITE_TAC[has_bounded_real_variation_on; o_DEF; LIFT_ADD] THEN
15101   REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_ADD]);;
15102
15103 let HAS_BOUNDED_REAL_VARIATION_ON_SUB = prove
15104  (`!f g s. f has_bounded_real_variation_on s /\
15105            g has_bounded_real_variation_on s
15106            ==> (\x. f x - g x) has_bounded_real_variation_on s`,
15107   REWRITE_TAC[has_bounded_real_variation_on; o_DEF; LIFT_SUB] THEN
15108   REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_SUB]);;
15109
15110 let HAS_BOUNDED_REAL_VARIATION_ON_NULL = prove
15111  (`!f a b. b <= a ==> f has_bounded_real_variation_on real_interval[a,b]`,
15112   REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN
15113   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN
15114   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NULL THEN
15115   ASM_REWRITE_TAC[BOUNDED_INTERVAL; CONTENT_EQ_0_1; LIFT_DROP]);;
15116
15117 let HAS_BOUNDED_REAL_VARIATION_ON_EMPTY = prove
15118  (`!f. f has_bounded_real_variation_on {}`,
15119   REWRITE_TAC[IMAGE_CLAUSES; has_bounded_real_variation_on] THEN
15120   REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_EMPTY]);;
15121
15122 let HAS_BOUNDED_REAL_VARIATION_ON_ABS = prove
15123  (`!f s. f has_bounded_real_variation_on s
15124          ==> (\x. abs(f x)) has_bounded_real_variation_on s`,
15125   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN
15126   DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_ON_NORM) THEN
15127   REWRITE_TAC[o_DEF; NORM_REAL; GSYM drop; LIFT_DROP]);;
15128
15129 let HAS_BOUNDED_REAL_VARIATION_ON_MAX = prove
15130  (`!f g s. f has_bounded_real_variation_on s /\
15131            g has_bounded_real_variation_on s
15132            ==> (\x. max (f x) (g x)) has_bounded_real_variation_on s`,
15133   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN
15134   DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_ON_MAX) THEN
15135   REWRITE_TAC[o_DEF; LIFT_DROP]);;
15136
15137 let HAS_BOUNDED_REAL_VARIATION_ON_MIN = prove
15138  (`!f g s. f has_bounded_real_variation_on s /\
15139            g has_bounded_real_variation_on s
15140            ==> (\x. min (f x) (g x)) has_bounded_real_variation_on s`,
15141   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN
15142   DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_ON_MIN) THEN
15143   REWRITE_TAC[o_DEF; LIFT_DROP]);;
15144
15145 let HAS_BOUNDED_REAL_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL = prove
15146  (`!f a b. f has_bounded_real_variation_on real_interval[a,b]
15147            ==> real_bounded(IMAGE f (real_interval[a,b]))`,
15148   REPEAT GEN_TAC THEN
15149   REWRITE_TAC[has_bounded_real_variation_on; REAL_BOUNDED] THEN
15150   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN
15151   DISCH_THEN(MP_TAC o MATCH_MP
15152     HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL) THEN
15153   REWRITE_TAC[IMAGE_o; IMAGE_DROP_INTERVAL; LIFT_DROP]);;
15154
15155 let HAS_BOUNDED_REAL_VARIATION_ON_MUL = prove
15156  (`!f g a b.
15157         f has_bounded_real_variation_on real_interval[a,b] /\
15158         g has_bounded_real_variation_on real_interval[a,b]
15159         ==> (\x. f x * g x) has_bounded_real_variation_on real_interval[a,b]`,
15160   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN
15161   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN
15162   DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_ON_MUL) THEN
15163   REWRITE_TAC[o_DEF; LIFT_CMUL; LIFT_DROP]);;
15164
15165 let REAL_VARIATION_POS_LE = prove
15166  (`!f s. f has_bounded_real_variation_on s ==> &0 <= real_variation s f`,
15167   REWRITE_TAC[real_variation; has_bounded_real_variation_on] THEN
15168   REWRITE_TAC[VECTOR_VARIATION_POS_LE]);;
15169
15170 let REAL_VARIATION_GE_ABS_FUNCTION = prove
15171  (`!f s a b.
15172         f has_bounded_real_variation_on s /\ real_segment[a,b] SUBSET s
15173         ==> abs(f b - f a) <= real_variation s f`,
15174   REWRITE_TAC[has_bounded_real_variation_on] THEN REPEAT STRIP_TAC THEN
15175   MP_TAC(ISPECL
15176    [`lift o f o drop`; `IMAGE lift s`; `lift a`; `lift b`]
15177    VECTOR_VARIATION_GE_NORM_FUNCTION) THEN
15178   ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_SEGMENT;
15179                IMAGE_EQ_EMPTY; IMAGE_SUBSET] THEN
15180   REWRITE_TAC[real_variation; o_THM; LIFT_DROP; GSYM LIFT_SUB; NORM_LIFT]);;
15181
15182 let REAL_VARIATION_GE_FUNCTION = prove
15183  (`!f s a b.
15184         f has_bounded_real_variation_on s /\ real_segment[a,b] SUBSET s
15185         ==> f b - f a <= real_variation s f`,
15186   REPEAT STRIP_TAC THEN
15187   MATCH_MP_TAC(REAL_ARITH `abs x <= a ==> x <= a`) THEN
15188   ASM_MESON_TAC[REAL_VARIATION_GE_ABS_FUNCTION]);;
15189
15190 let REAL_VARIATION_MONOTONE = prove
15191  (`!f s t. f has_bounded_real_variation_on s /\ t SUBSET s
15192            ==> real_variation t f <= real_variation s f`,
15193   REWRITE_TAC[has_bounded_real_variation_on; real_variation] THEN
15194   REPEAT STRIP_TAC THEN MATCH_MP_TAC VECTOR_VARIATION_MONOTONE THEN
15195   ASM_SIMP_TAC[IMAGE_SUBSET]);;
15196
15197 let REAL_VARIATION_NEG = prove
15198  (`!f s. real_variation s (\x. --(f x)) = real_variation s f`,
15199   SIMP_TAC[real_variation; o_DEF; LIFT_NEG; VECTOR_VARIATION_NEG]);;
15200
15201 let REAL_VARIATION_TRIANGLE = prove
15202  (`!f g s. f has_bounded_real_variation_on s /\
15203            g has_bounded_real_variation_on s
15204            ==> real_variation s (\x. f x + g x)
15205                <= real_variation s f + real_variation s g`,
15206   REPEAT GEN_TAC THEN
15207   REWRITE_TAC[has_bounded_real_variation_on; real_variation] THEN
15208   DISCH_THEN(MP_TAC o MATCH_MP VECTOR_VARIATION_TRIANGLE) THEN
15209   REWRITE_TAC[o_DEF; LIFT_ADD]);;
15210
15211 let HAS_BOUNDED_REAL_VARIATION_ON_COMBINE = prove
15212  (`!f a b c.
15213         a <= c /\ c <= b
15214         ==> (f has_bounded_real_variation_on real_interval[a,b] <=>
15215              f has_bounded_real_variation_on real_interval[a,c] /\
15216              f has_bounded_real_variation_on real_interval[c,b])`,
15217   REWRITE_TAC[has_bounded_real_variation_on; IMAGE_LIFT_REAL_INTERVAL] THEN
15218   REPEAT STRIP_TAC THEN MP_TAC(ISPECL
15219    [`lift o f o drop`; `lift a`; `lift b`; `lift c`]
15220         HAS_BOUNDED_VARIATION_ON_COMBINE) THEN
15221   ASM_REWRITE_TAC[LIFT_DROP; has_bounded_real_variation_on;
15222       IMAGE_LIFT_REAL_INTERVAL]);;
15223
15224 let REAL_VARIATION_COMBINE = prove
15225  (`!f a b c.
15226         a <= c /\ c <= b /\
15227         f has_bounded_real_variation_on real_interval[a,b]
15228         ==> real_variation (real_interval[a,c]) f +
15229             real_variation (real_interval[c,b]) f =
15230             real_variation (real_interval[a,b]) f`,
15231   REWRITE_TAC[has_bounded_real_variation_on; IMAGE_LIFT_REAL_INTERVAL] THEN
15232   REPEAT STRIP_TAC THEN MP_TAC(ISPECL
15233    [`lift o f o drop`; `lift a`; `lift b`; `lift c`]
15234         VECTOR_VARIATION_COMBINE) THEN
15235   ASM_REWRITE_TAC[LIFT_DROP; real_variation; IMAGE_LIFT_REAL_INTERVAL]);;
15236
15237 let REAL_VARIATION_MINUS_FUNCTION_MONOTONE = prove
15238  (`!f a b c d.
15239         f has_bounded_real_variation_on real_interval[a,b] /\
15240         real_interval[c,d] SUBSET real_interval[a,b] /\
15241         ~(real_interval[c,d] = {})
15242         ==> real_variation (real_interval[c,d]) f - (f d - f c) <=
15243             real_variation (real_interval[a,b]) f - (f b - f a)`,
15244   REWRITE_TAC[has_bounded_real_variation_on; IMAGE_LIFT_REAL_INTERVAL] THEN
15245   REPEAT STRIP_TAC THEN
15246   MP_TAC(ISPECL
15247    [`lift o f o drop`; `lift a`; `lift b`; `lift c`; `lift d`]
15248    VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE) THEN
15249   ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; real_variation;
15250                 IMAGE_EQ_EMPTY; IMAGE_SUBSET] THEN
15251   REWRITE_TAC[o_THM; LIFT_DROP; DROP_SUB]);;
15252
15253 let INCREASING_BOUNDED_REAL_VARIATION = prove
15254  (`!f a b.
15255       (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
15256              ==> f x <= f y)
15257       ==> f has_bounded_real_variation_on real_interval[a,b]`,
15258   REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN
15259   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN
15260   MATCH_MP_TAC INCREASING_BOUNDED_VARIATION THEN
15261   REWRITE_TAC[IN_INTERVAL_1; GSYM FORALL_DROP; o_THM; LIFT_DROP] THEN
15262   RULE_ASSUM_TAC(REWRITE_RULE[IN_REAL_INTERVAL]) THEN ASM_MESON_TAC[]);;
15263
15264 let INCREASING_REAL_VARIATION = prove
15265  (`!f a b.
15266         ~(real_interval[a,b] = {}) /\
15267         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
15268                ==> f x <= f y)
15269         ==> real_variation (real_interval[a,b]) f = f b - f a`,
15270   REPEAT STRIP_TAC THEN
15271   REWRITE_TAC[real_variation; IMAGE_LIFT_REAL_INTERVAL] THEN
15272   MP_TAC(ISPECL [`lift o f o drop`; `lift a`; `lift b`]
15273         INCREASING_VECTOR_VARIATION) THEN
15274   REWRITE_TAC[o_THM; LIFT_DROP] THEN DISCH_THEN MATCH_MP_TAC THEN
15275   ASM_REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMAGE_EQ_EMPTY] THEN
15276   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
15277   REWRITE_TAC[LIFT_DROP] THEN ASM_MESON_TAC[]);;
15278
15279 let HAS_BOUNDED_REAL_VARIATION_AFFINITY2_EQ = prove
15280  (`!m c f s.
15281         (\x. f (m * x + c)) has_bounded_real_variation_on
15282
15283
15284         IMAGE (\x. inv m * x + --(inv m * c)) s <=>
15285         m = &0 \/ f has_bounded_real_variation_on s`,
15286   REPEAT GEN_TAC THEN
15287   MP_TAC(ISPECL [`m:real`; `lift c`; `lift o f o drop`; `IMAGE lift s`]
15288         HAS_BOUNDED_VARIATION_AFFINITY2_EQ) THEN
15289   REWRITE_TAC[o_DEF; has_bounded_real_variation_on; GSYM IMAGE_o;
15290    DROP_ADD; DROP_CMUL; LIFT_ADD; LIFT_CMUL; LIFT_NEG; LIFT_DROP]);;
15291
15292 let REAL_VARIATION_AFFINITY2 = prove
15293  (`!m c f s.
15294         real_variation (IMAGE (\x. inv m * x + --(inv m * c)) s)
15295                        (\x. f (m * x + c)) =
15296         if m = &0 then &0 else real_variation s f`,
15297   REPEAT GEN_TAC THEN
15298   MP_TAC(ISPECL [`m:real`; `lift c`; `lift o f o drop`; `IMAGE lift s`]
15299          VECTOR_VARIATION_AFFINITY2) THEN
15300   REWRITE_TAC[o_DEF; real_variation; GSYM IMAGE_o;
15301    DROP_ADD; DROP_CMUL; LIFT_ADD; LIFT_CMUL; LIFT_NEG; LIFT_DROP]);;
15302
15303 let HAS_BOUNDED_REAL_VARIATION_AFFINITY_EQ = prove
15304  (`!m c f s.
15305         (\x. f (m * x + c)) has_bounded_real_variation_on s <=>
15306         m = &0 \/ f has_bounded_real_variation_on IMAGE (\x. m * x + c) s`,
15307   REPEAT GEN_TAC THEN
15308   MP_TAC(ISPECL [`m:real`; `lift c`; `lift o f o drop`; `IMAGE lift s`]
15309         HAS_BOUNDED_VARIATION_AFFINITY_EQ) THEN
15310   REWRITE_TAC[o_DEF; has_bounded_real_variation_on; GSYM IMAGE_o;
15311    DROP_ADD; DROP_CMUL; LIFT_ADD; LIFT_CMUL; LIFT_NEG; LIFT_DROP]);;
15312
15313 let REAL_VARIATION_AFFINITY = prove
15314  (`!m c f s.
15315         real_variation s (\x. f (m * x + c)) =
15316         if m = &0 then &0 else real_variation (IMAGE (\x. m * x + c) s) f`,
15317   REPEAT GEN_TAC THEN
15318   MP_TAC(ISPECL [`m:real`; `lift c`; `lift o f o drop`; `IMAGE lift s`]
15319          VECTOR_VARIATION_AFFINITY) THEN
15320   REWRITE_TAC[o_DEF; real_variation; GSYM IMAGE_o;
15321    DROP_ADD; DROP_CMUL; LIFT_ADD; LIFT_CMUL; LIFT_NEG; LIFT_DROP]);;
15322
15323 let HAS_BOUNDED_REAL_VARIATION_TRANSLATION2_EQ = prove
15324  (`!a f s.
15325       (\x. f(a + x)) has_bounded_real_variation_on (IMAGE (\x. --a + x) s) <=>
15326       f has_bounded_real_variation_on s`,
15327   REPEAT GEN_TAC THEN
15328   MP_TAC(ISPECL [`lift a`; `lift o f o drop`; `IMAGE lift s`]
15329         HAS_BOUNDED_VARIATION_TRANSLATION2_EQ) THEN
15330   REWRITE_TAC[o_DEF; has_bounded_real_variation_on; GSYM IMAGE_o;
15331               DROP_ADD; LIFT_DROP; LIFT_ADD; LIFT_NEG]);;
15332
15333 let REAL_VARIATION_TRANSLATION2 = prove
15334  (`!a f s. real_variation (IMAGE (\x. --a + x) s) (\x. f(a + x)) =
15335            real_variation s f`,
15336   REPEAT GEN_TAC THEN
15337   MP_TAC(ISPECL [`lift a`; `lift o f o drop`; `IMAGE lift s`]
15338         VECTOR_VARIATION_TRANSLATION2) THEN
15339   REWRITE_TAC[o_DEF; real_variation; GSYM IMAGE_o;
15340               DROP_ADD; LIFT_DROP; LIFT_ADD; LIFT_NEG]);;
15341
15342 let HAS_BOUNDED_REAL_VARIATION_TRANSLATION_EQ = prove
15343  (`!a f s. (\x. f(a + x)) has_bounded_real_variation_on s <=>
15344            f has_bounded_real_variation_on (IMAGE (\x. a + x) s)`,
15345   REPEAT GEN_TAC THEN
15346   MP_TAC(ISPECL [`lift a`; `lift o f o drop`; `IMAGE lift s`]
15347         HAS_BOUNDED_VARIATION_TRANSLATION_EQ) THEN
15348   REWRITE_TAC[o_DEF; has_bounded_real_variation_on; GSYM IMAGE_o;
15349               DROP_ADD; LIFT_DROP; LIFT_ADD; LIFT_NEG]);;
15350
15351 let REAL_VARIATION_TRANSLATION = prove
15352  (`!a f s. real_variation s (\x. f(a + x)) =
15353            real_variation (IMAGE (\x. a + x) s) f`,
15354   REPEAT GEN_TAC THEN
15355   MP_TAC(ISPECL [`lift a`; `lift o f o drop`; `IMAGE lift s`]
15356         VECTOR_VARIATION_TRANSLATION) THEN
15357   REWRITE_TAC[o_DEF; real_variation; GSYM IMAGE_o;
15358               DROP_ADD; LIFT_DROP; LIFT_ADD; LIFT_NEG]);;
15359
15360 let HAS_BOUNDED_REAL_VARIATION_TRANSLATION_EQ_INTERVAL = prove
15361  (`!a f u v.
15362         (\x. f(a + x)) has_bounded_real_variation_on real_interval[u,v] <=>
15363         f has_bounded_real_variation_on real_interval[a+u,a+v]`,
15364   REWRITE_TAC[REAL_INTERVAL_TRANSLATION;
15365               HAS_BOUNDED_REAL_VARIATION_TRANSLATION_EQ]);;
15366
15367 let REAL_VARIATION_TRANSLATION_INTERVAL = prove
15368  (`!a f u v.
15369         real_variation (real_interval[u,v]) (\x. f(a + x)) =
15370         real_variation (real_interval[a+u,a+v]) f`,
15371   REWRITE_TAC[REAL_INTERVAL_TRANSLATION;
15372                 REAL_VARIATION_TRANSLATION]);;
15373
15374 let HAS_BOUNDED_REAL_VARIATION_TRANSLATION = prove
15375  (`!f s a. f has_bounded_real_variation_on s
15376            ==> (\x. f(a + x)) has_bounded_real_variation_on
15377                (IMAGE (\x. --a + x) s)`,
15378   REWRITE_TAC[HAS_BOUNDED_REAL_VARIATION_TRANSLATION2_EQ]);;
15379
15380 let HAS_BOUNDED_REAL_VARIATION_REFLECT2_EQ = prove
15381  (`!f s. (\x. f(--x)) has_bounded_real_variation_on (IMAGE (--) s) <=>
15382          f has_bounded_real_variation_on s`,
15383   REPEAT GEN_TAC THEN
15384   MP_TAC(ISPECL [`lift o f o drop`; `IMAGE lift s`]
15385         HAS_BOUNDED_VARIATION_REFLECT2_EQ) THEN
15386   REWRITE_TAC[o_DEF; has_bounded_real_variation_on; GSYM IMAGE_o;
15387               DROP_NEG; LIFT_DROP; LIFT_NEG]);;
15388
15389 let REAL_VARIATION_REFLECT2 = prove
15390  (`!f s. real_variation (IMAGE (--) s) (\x. f(--x)) =
15391          real_variation s f`,
15392   REPEAT GEN_TAC THEN
15393   MP_TAC(ISPECL [`lift o f o drop`; `IMAGE lift s`]
15394         VECTOR_VARIATION_REFLECT2) THEN
15395   REWRITE_TAC[o_DEF; real_variation; GSYM IMAGE_o;
15396               DROP_NEG; LIFT_DROP; LIFT_NEG]);;
15397
15398 let HAS_BOUNDED_REAL_VARIATION_REFLECT_EQ = prove
15399  (`!f s. (\x. f(--x)) has_bounded_real_variation_on s <=>
15400          f has_bounded_real_variation_on (IMAGE (--) s)`,
15401   REPEAT GEN_TAC THEN
15402   MP_TAC(ISPECL [`lift o f o drop`; `IMAGE lift s`]
15403         HAS_BOUNDED_VARIATION_REFLECT_EQ) THEN
15404   REWRITE_TAC[o_DEF; has_bounded_real_variation_on; GSYM IMAGE_o;
15405               DROP_NEG; LIFT_DROP; LIFT_NEG]);;
15406
15407 let REAL_VARIATION_REFLECT = prove
15408  (`!f s. real_variation s (\x. f(--x)) =
15409          real_variation (IMAGE (--) s) f`,
15410   REPEAT GEN_TAC THEN
15411   MP_TAC(ISPECL [`lift o f o drop`; `IMAGE lift s`]
15412         VECTOR_VARIATION_REFLECT) THEN
15413   REWRITE_TAC[o_DEF; real_variation; GSYM IMAGE_o;
15414               DROP_NEG; LIFT_DROP; LIFT_NEG]);;
15415
15416 let HAS_BOUNDED_REAL_VARIATION_REFLECT_EQ_INTERVAL = prove
15417  (`!f u v. (\x. f(--x)) has_bounded_real_variation_on real_interval[u,v] <=>
15418            f has_bounded_real_variation_on real_interval[--v,--u]`,
15419   REWRITE_TAC[GSYM REFLECT_REAL_INTERVAL;
15420               HAS_BOUNDED_REAL_VARIATION_REFLECT_EQ]);;
15421
15422 let REAL_VARIATION_REFLECT_INTERVAL = prove
15423  (`!f u v. real_variation (real_interval[u,v]) (\x. f(--x)) =
15424            real_variation (real_interval[--v,--u]) f`,
15425   REWRITE_TAC[GSYM REFLECT_REAL_INTERVAL; REAL_VARIATION_REFLECT]);;
15426
15427 let HAS_BOUNDED_REAL_VARIATION_DARBOUX = prove
15428  (`!f a b.
15429      f has_bounded_real_variation_on real_interval[a,b] <=>
15430      ?g h. (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
15431                   ==> g x <= g y) /\
15432            (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
15433                   ==> h x <= h y) /\
15434            (!x. f x = g x - h x)`,
15435   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN
15436   REWRITE_TAC[HAS_BOUNDED_VARIATION_DARBOUX; IMAGE_LIFT_REAL_INTERVAL] THEN
15437   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE;
15438               GSYM IMAGE_LIFT_REAL_INTERVAL; LIFT_DROP] THEN
15439   REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN
15440   EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM; o_THM] THENL
15441    [MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN
15442     STRIP_TAC THEN
15443     MAP_EVERY EXISTS_TAC [`drop o g o lift`; `drop o h o lift`] THEN
15444     ASM_REWRITE_TAC[o_THM] THEN REWRITE_TAC[GSYM LIFT_EQ; FORALL_DROP] THEN
15445     ASM_REWRITE_TAC[LIFT_DROP; LIFT_SUB];
15446     MAP_EVERY X_GEN_TAC [`g:real->real`; `h:real->real`] THEN
15447     STRIP_TAC THEN
15448     MAP_EVERY EXISTS_TAC [`lift o g o drop`; `lift o h o drop`] THEN
15449     ASM_REWRITE_TAC[o_THM; LIFT_DROP] THEN REWRITE_TAC[LIFT_SUB]]);;
15450
15451 let HAS_BOUNDED_REAL_VARIATION_DARBOUX_STRICT = prove
15452  (`!f a b.
15453      f has_bounded_real_variation_on real_interval[a,b] <=>
15454      ?g h. (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x < y
15455                   ==> g x < g y) /\
15456            (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x < y
15457                   ==> h x < h y) /\
15458            (!x. f x = g x - h x)`,
15459   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN
15460   REWRITE_TAC[HAS_BOUNDED_VARIATION_DARBOUX_STRICT;
15461               IMAGE_LIFT_REAL_INTERVAL] THEN
15462   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE;
15463               GSYM IMAGE_LIFT_REAL_INTERVAL; LIFT_DROP] THEN
15464   REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP; GSYM CONJ_ASSOC] THEN
15465   EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM; o_THM] THENL
15466    [MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN
15467     STRIP_TAC THEN
15468     MAP_EVERY EXISTS_TAC [`drop o g o lift`; `drop o h o lift`] THEN
15469     ASM_REWRITE_TAC[o_THM] THEN REWRITE_TAC[GSYM LIFT_EQ; FORALL_DROP] THEN
15470     ASM_REWRITE_TAC[LIFT_DROP; LIFT_SUB];
15471     MAP_EVERY X_GEN_TAC [`g:real->real`; `h:real->real`] THEN
15472     STRIP_TAC THEN
15473     MAP_EVERY EXISTS_TAC [`lift o g o drop`; `lift o h o drop`] THEN
15474     ASM_REWRITE_TAC[o_THM; LIFT_DROP] THEN REWRITE_TAC[LIFT_SUB]]);;
15475
15476 let INCREASING_LEFT_LIMIT = prove
15477  (`!f a b c.
15478         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
15479                ==> f x <= f y) /\
15480         c IN real_interval[a,b]
15481        ==> ?l. (f ---> l) (atreal c within real_interval[a,c])`,
15482   REPEAT STRIP_TAC THEN REWRITE_TAC[TENDSTO_REAL; GSYM EXISTS_LIFT] THEN
15483   REWRITE_TAC[LIM_WITHINREAL_WITHIN; IMAGE_LIFT_REAL_INTERVAL] THEN
15484   MATCH_MP_TAC INCREASING_LEFT_LIMIT_1 THEN EXISTS_TAC `lift b` THEN
15485   SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
15486   ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; FUN_IN_IMAGE]);;
15487
15488 let DECREASING_LEFT_LIMIT = prove
15489  (`!f a b c.
15490         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
15491                ==> f y <= f x) /\
15492         c IN real_interval[a,b]
15493         ==> ?l. (f ---> l) (atreal c within real_interval[a,c])`,
15494   REPEAT STRIP_TAC THEN REWRITE_TAC[TENDSTO_REAL; GSYM EXISTS_LIFT] THEN
15495   REWRITE_TAC[LIM_WITHINREAL_WITHIN; IMAGE_LIFT_REAL_INTERVAL] THEN
15496   MATCH_MP_TAC DECREASING_LEFT_LIMIT_1 THEN EXISTS_TAC `lift b` THEN
15497   SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
15498   ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; FUN_IN_IMAGE]);;
15499
15500 let INCREASING_RIGHT_LIMIT = prove
15501  (`!f a b c.
15502         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
15503                ==> f x <= f y) /\
15504         c IN real_interval[a,b]
15505        ==> ?l. (f ---> l) (atreal c within real_interval[c,b])`,
15506   REPEAT STRIP_TAC THEN REWRITE_TAC[TENDSTO_REAL; GSYM EXISTS_LIFT] THEN
15507   REWRITE_TAC[LIM_WITHINREAL_WITHIN; IMAGE_LIFT_REAL_INTERVAL] THEN
15508   MATCH_MP_TAC INCREASING_RIGHT_LIMIT_1 THEN EXISTS_TAC `lift a` THEN
15509   SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
15510   ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; FUN_IN_IMAGE]);;
15511
15512 let DECREASING_RIGHT_LIMIT = prove
15513  (`!f a b c.
15514         (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
15515                ==> f y <= f x) /\
15516         c IN real_interval[a,b]
15517         ==> ?l. (f ---> l) (atreal c within real_interval[c,b])`,
15518   REPEAT STRIP_TAC THEN REWRITE_TAC[TENDSTO_REAL; GSYM EXISTS_LIFT] THEN
15519   REWRITE_TAC[LIM_WITHINREAL_WITHIN; IMAGE_LIFT_REAL_INTERVAL] THEN
15520   MATCH_MP_TAC DECREASING_RIGHT_LIMIT_1 THEN EXISTS_TAC `lift a` THEN
15521   SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
15522   ASM_SIMP_TAC[FORALL_IN_IMAGE; o_THM; LIFT_DROP; FUN_IN_IMAGE]);;
15523
15524 let HAS_BOUNDED_REAL_VARIATION_LEFT_LIMIT = prove
15525  (`!f a b c.
15526         f has_bounded_real_variation_on real_interval[a,b] /\
15527         c IN real_interval[a,b]
15528         ==> ?l. (f ---> l) (atreal c within real_interval[a,c])`,
15529   REWRITE_TAC[has_bounded_real_variation_on] THEN REPEAT STRIP_TAC THEN
15530   REWRITE_TAC[TENDSTO_REAL; GSYM EXISTS_LIFT] THEN
15531   REWRITE_TAC[LIM_WITHINREAL_WITHIN; IMAGE_LIFT_REAL_INTERVAL] THEN
15532   MATCH_MP_TAC HAS_BOUNDED_VECTOR_VARIATION_LEFT_LIMIT THEN
15533   EXISTS_TAC `lift b` THEN
15534   ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; GSYM o_ASSOC; FUN_IN_IMAGE]);;
15535
15536 let HAS_BOUNDED_REAL_VARIATION_RIGHT_LIMIT = prove
15537  (`!f a b c.
15538         f has_bounded_real_variation_on real_interval[a,b] /\
15539         c IN real_interval[a,b]
15540         ==> ?l. (f ---> l) (atreal c within real_interval[c,b])`,
15541   REWRITE_TAC[has_bounded_real_variation_on] THEN REPEAT STRIP_TAC THEN
15542   REWRITE_TAC[TENDSTO_REAL; GSYM EXISTS_LIFT] THEN
15543   REWRITE_TAC[LIM_WITHINREAL_WITHIN; IMAGE_LIFT_REAL_INTERVAL] THEN
15544   MATCH_MP_TAC HAS_BOUNDED_VECTOR_VARIATION_RIGHT_LIMIT THEN
15545   EXISTS_TAC `lift a` THEN
15546   ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; GSYM o_ASSOC; FUN_IN_IMAGE]);;
15547
15548 let REAL_VARIATION_CONTINUOUS_LEFT = prove
15549  (`!f a b c.
15550         f has_bounded_real_variation_on real_interval[a,b] /\
15551         c IN real_interval[a,b]
15552         ==> ((\x. real_variation(real_interval[a,x]) f)
15553              real_continuous (atreal c within real_interval[a,c]) <=>
15554             f real_continuous (atreal c within real_interval[a,c]))`,
15555   REWRITE_TAC[has_bounded_real_variation_on; real_variation] THEN
15556   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL;
15557         REAL_CONTINUOUS_CONTINUOUS_WITHINREAL] THEN
15558   REWRITE_TAC[o_DEF; LIFT_DROP] THEN REPEAT STRIP_TAC THEN
15559   MATCH_MP_TAC VECTOR_VARIATION_CONTINUOUS_LEFT THEN
15560   EXISTS_TAC `lift b` THEN ASM_REWRITE_TAC[] THEN
15561   ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; FUN_IN_IMAGE]);;
15562
15563 let REAL_VARIATION_CONTINUOUS_RIGHT = prove
15564  (`!f a b c.
15565         f has_bounded_real_variation_on real_interval[a,b] /\
15566         c IN real_interval[a,b]
15567         ==> ((\x. real_variation(real_interval[a,x]) f)
15568              real_continuous (atreal c within real_interval[c,b]) <=>
15569             f real_continuous (atreal c within real_interval[c,b]))`,
15570   REWRITE_TAC[has_bounded_real_variation_on; real_variation] THEN
15571   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL;
15572         REAL_CONTINUOUS_CONTINUOUS_WITHINREAL] THEN
15573   REWRITE_TAC[o_DEF; LIFT_DROP] THEN REPEAT STRIP_TAC THEN
15574   MATCH_MP_TAC VECTOR_VARIATION_CONTINUOUS_RIGHT THEN
15575   ASM_REWRITE_TAC[] THEN
15576   ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; FUN_IN_IMAGE]);;
15577
15578 let REAL_VARIATION_CONTINUOUS = prove
15579  (`!f a b c.
15580         f has_bounded_real_variation_on real_interval[a,b] /\
15581         c IN real_interval[a,b]
15582         ==> ((\x. real_variation(real_interval[a,x]) f)
15583              real_continuous (atreal c within real_interval[a,b]) <=>
15584             f real_continuous (atreal c within real_interval[a,b]))`,
15585   REWRITE_TAC[has_bounded_real_variation_on; real_variation] THEN
15586   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL;
15587         REAL_CONTINUOUS_CONTINUOUS_WITHINREAL] THEN
15588   REWRITE_TAC[o_DEF; LIFT_DROP] THEN REPEAT STRIP_TAC THEN
15589   MATCH_MP_TAC VECTOR_VARIATION_CONTINUOUS THEN
15590   ASM_REWRITE_TAC[] THEN
15591   ASM_SIMP_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; FUN_IN_IMAGE]);;
15592
15593 let HAS_BOUNDED_REAL_VARIATION_DARBOUX_STRONG = prove
15594  (`!f a b.
15595      f has_bounded_real_variation_on real_interval[a,b]
15596      ==> ?g h.
15597           (!x. f x = g x - h x) /\
15598           (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
15599                  ==> g x <= g y) /\
15600           (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x <= y
15601                  ==> h x <= h y) /\
15602           (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x < y
15603                  ==> g x < g y) /\
15604           (!x y. x IN real_interval[a,b] /\ y IN real_interval[a,b] /\ x < y
15605                  ==> h x < h y) /\
15606           (!x. x IN real_interval[a,b] /\
15607                f real_continuous (atreal x within real_interval[a,x])
15608                ==> g real_continuous (atreal x within real_interval[a,x]) /\
15609                    h real_continuous (atreal x within real_interval[a,x])) /\
15610           (!x. x IN real_interval[a,b] /\
15611                f real_continuous (atreal x within real_interval[x,b])
15612                ==> g real_continuous (atreal x within real_interval[x,b]) /\
15613                    h real_continuous (atreal x within real_interval[x,b])) /\
15614           (!x. x IN real_interval[a,b] /\
15615                f real_continuous (atreal x within real_interval[a,b])
15616                ==> g real_continuous (atreal x within real_interval[a,b]) /\
15617                    h real_continuous (atreal x within real_interval[a,b]))`,
15618   REPEAT STRIP_TAC THEN
15619   MAP_EVERY EXISTS_TAC
15620    [`\x. x + real_variation (real_interval[a,x]) f`;
15621     `\x. x + real_variation (real_interval[a,x]) f - f x`] THEN
15622   REWRITE_TAC[REAL_ARITH `(x + l) - (x + l - f):real = f`] THEN
15623   REPEAT STRIP_TAC THENL
15624    [MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC[] THEN
15625     MATCH_MP_TAC REAL_VARIATION_MONOTONE;
15626     MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC[] THEN
15627     MATCH_MP_TAC(REAL_ARITH
15628      `!x. a - (b - x) <= c - (d - x) ==> a - b <= c - d`) THEN
15629     EXISTS_TAC `(f:real->real) a` THEN
15630     MATCH_MP_TAC REAL_VARIATION_MINUS_FUNCTION_MONOTONE;
15631     MATCH_MP_TAC REAL_LTE_ADD2 THEN ASM_REWRITE_TAC[] THEN
15632     MATCH_MP_TAC REAL_VARIATION_MONOTONE;
15633     MATCH_MP_TAC REAL_LTE_ADD2 THEN ASM_REWRITE_TAC[] THEN
15634     MATCH_MP_TAC(REAL_ARITH
15635      `!x. a - (b - x) <= c - (d - x) ==> a - b <= c - d`) THEN
15636     EXISTS_TAC `(f:real->real) a` THEN
15637     MATCH_MP_TAC REAL_VARIATION_MINUS_FUNCTION_MONOTONE;
15638     MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN
15639     REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID] THEN
15640     MP_TAC(ISPECL [`f:real->real`; `a:real`; `b:real`; `x:real`]
15641         REAL_VARIATION_CONTINUOUS_LEFT) THEN
15642     ASM_REWRITE_TAC[];
15643     MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN
15644     REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID] THEN
15645     MATCH_MP_TAC REAL_CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN
15646     MP_TAC(ISPECL [`f:real->real`; `a:real`; `b:real`; `x:real`]
15647         REAL_VARIATION_CONTINUOUS_LEFT) THEN
15648     ASM_REWRITE_TAC[];
15649     MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN
15650     REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID] THEN
15651     MP_TAC(ISPECL [`f:real->real`; `a:real`; `b:real`; `x:real`]
15652         REAL_VARIATION_CONTINUOUS_RIGHT) THEN
15653     ASM_REWRITE_TAC[];
15654     MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN
15655     REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID] THEN
15656     MATCH_MP_TAC REAL_CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN
15657     MP_TAC(ISPECL [`f:real->real`; `a:real`; `b:real`; `x:real`]
15658         REAL_VARIATION_CONTINUOUS_RIGHT) THEN
15659     ASM_REWRITE_TAC[];
15660     MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN
15661     REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID] THEN
15662     MP_TAC(ISPECL [`f:real->real`; `a:real`; `b:real`; `x:real`]
15663         REAL_VARIATION_CONTINUOUS) THEN
15664     ASM_REWRITE_TAC[];
15665     MATCH_MP_TAC REAL_CONTINUOUS_ADD THEN
15666     REWRITE_TAC[REAL_CONTINUOUS_WITHIN_ID] THEN
15667     MATCH_MP_TAC REAL_CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN
15668     MP_TAC(ISPECL [`f:real->real`; `a:real`; `b:real`; `x:real`]
15669         REAL_VARIATION_CONTINUOUS) THEN
15670     ASM_REWRITE_TAC[]] THEN
15671   (CONJ_TAC THENL
15672      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
15673        HAS_BOUNDED_REAL_VARIATION_ON_SUBSET));
15674       ALL_TAC] THEN
15675     RULE_ASSUM_TAC(REWRITE_RULE[IN_REAL_INTERVAL]) THEN
15676     REWRITE_TAC[SUBSET_REAL_INTERVAL; REAL_INTERVAL_EQ_EMPTY] THEN
15677     ASM_REAL_ARITH_TAC));;
15678
15679 let HAS_BOUNDED_REAL_VARIATION_COUNTABLE_DISCONTINUITIES = prove
15680  (`!f a b. f has_bounded_real_variation_on real_interval[a,b]
15681            ==> COUNTABLE {x | x IN real_interval[a,b] /\
15682                               ~(f real_continuous atreal x)}`,
15683   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_real_variation_on] THEN
15684   REWRITE_TAC[REAL_CONTINUOUS_CONTINUOUS_ATREAL] THEN
15685   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL] THEN DISCH_THEN(MP_TAC o
15686     MATCH_MP HAS_BOUNDED_VARIATION_COUNTABLE_DISCONTINUITIES) THEN
15687   DISCH_THEN(MP_TAC o ISPEC `drop` o MATCH_MP COUNTABLE_IMAGE) THEN
15688   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] COUNTABLE_SUBSET) THEN
15689   REWRITE_TAC[SUBSET; IN_IMAGE; EXISTS_LIFT; LIFT_DROP; UNWIND_THM1] THEN
15690   REWRITE_TAC[GSYM IMAGE_LIFT_REAL_INTERVAL; IN_ELIM_THM] THEN
15691   REWRITE_TAC[EXISTS_IN_IMAGE; GSYM CONJ_ASSOC; EXISTS_DROP; LIFT_DROP] THEN
15692   MESON_TAC[LIFT_DROP]);;
15693
15694 let REAL_INTEGRABLE_REAL_BOUNDED_VARIATION_PRODUCT = prove
15695  (`!f g a b.
15696         f real_integrable_on real_interval[a,b] /\
15697         g has_bounded_real_variation_on real_interval[a,b]
15698         ==> (\x. g x * f x) real_integrable_on real_interval[a,b]`,
15699   REPEAT GEN_TAC THEN
15700   REWRITE_TAC[has_bounded_real_variation_on; REAL_INTEGRABLE_ON] THEN
15701   REWRITE_TAC[IMAGE_LIFT_REAL_INTERVAL; o_DEF; LIFT_CMUL] THEN
15702   DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_BOUNDED_VARIATION_PRODUCT) THEN
15703   REWRITE_TAC[LIFT_DROP]);;
15704
15705 (* ------------------------------------------------------------------------- *)
15706 (* Lebesgue density theorem. This isn't about R specifically, but it's most  *)
15707 (* naturally stated as a real limit so it ends up here in this file.         *)
15708 (* ------------------------------------------------------------------------- *)
15709
15710 let LEBESGUE_DENSITY_THEOREM = prove
15711  (`!s:real^N->bool.
15712       lebesgue_measurable s
15713       ==> ?k. negligible k /\
15714               !x. ~(x IN k)
15715                   ==> ((\e. measure(s INTER cball(x,e)) / measure(cball(x,e)))
15716                        ---> (if x IN s then &1 else &0))
15717                       (atreal(&0) within {e | &0 < e})`,
15718   REPEAT STRIP_TAC THEN MP_TAC (ISPEC
15719    `indicator(s:real^N->bool)` ABSOLUTELY_INTEGRABLE_LEBESGUE_POINTS) THEN
15720   ANTS_TAC THENL
15721    [REPEAT GEN_TAC THEN REWRITE_TAC[indicator] THEN
15722     MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN CONJ_TAC THENL
15723      [MESON_TAC[VEC_COMPONENT; REAL_POS]; ALL_TAC] THEN
15724     REWRITE_TAC[INTEGRABLE_RESTRICT_INTER] THEN
15725     ONCE_REWRITE_TAC[GSYM INTEGRABLE_RESTRICT_UNIV] THEN
15726     REWRITE_TAC[GSYM MEASURABLE_INTEGRABLE] THEN
15727     MATCH_MP_TAC MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE THEN
15728     ASM_REWRITE_TAC[MEASURABLE_INTERVAL];
15729     ALL_TAC] THEN
15730   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^N->bool` THEN
15731   STRIP_TAC THEN ASM_REWRITE_TAC[REALLIM_WITHINREAL; IN_ELIM_THM] THEN
15732   X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN X_GEN_TAC `e:real` THEN
15733   STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL
15734    [`x:real^N`; `e / &(dimindex(:N)) pow dimindex(:N)`]) THEN
15735   ASM_SIMP_TAC[REAL_LT_DIV; REAL_POW_LT;
15736                REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1] THEN
15737   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN
15738   ASM_REWRITE_TAC[REAL_SUB_RZERO] THEN X_GEN_TAC `h:real` THEN STRIP_TAC THEN
15739   FIRST_X_ASSUM(MP_TAC o SPEC `h:real`) THEN
15740   ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
15741   SIMP_TAC[REAL_LT_RDIV_EQ;  REAL_POW_LT;
15742            REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1] THEN
15743   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN
15744   ASM_SIMP_TAC[MEASURE_CBALL_POS; REAL_FIELD
15745    `&0 < y ==> x / y - a = inv(y) * (x - a * y)`] THEN
15746   REWRITE_TAC[REAL_ABS_MUL; NORM_MUL] THEN ONCE_REWRITE_TAC
15747    [REAL_ARITH `x <= (abs a * b) * c <=> x <= (abs(a) * c) * b`] THEN
15748   MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[REAL_ABS_POS] THEN
15749   CONJ_TAC THENL
15750    [SIMP_TAC[GSYM REAL_LE_LDIV_EQ; REAL_POW_LT;
15751              REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1] THEN
15752     REWRITE_TAC[REAL_ABS_INV; real_div; GSYM REAL_INV_MUL] THEN
15753     MATCH_MP_TAC REAL_LE_INV2 THEN CONJ_TAC THENL
15754      [REWRITE_TAC[GSYM REAL_ABS_NZ; CONTENT_EQ_0] THEN
15755       REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT;
15756                   VECTOR_SUB_COMPONENT] THEN ASM_REAL_ARITH_TAC;
15757       SIMP_TAC[real_abs; CONTENT_POS_LE; MEASURE_POS_LE; MEASURABLE_CBALL] THEN
15758       MATCH_MP_TAC REAL_LE_TRANS THEN
15759       EXISTS_TAC `measure(interval[x - h / &(dimindex(:N)) % vec 1:real^N,
15760                                    x + h / &(dimindex(:N)) % vec 1]) *
15761                   &(dimindex (:N)) pow dimindex (:N)` THEN
15762       CONJ_TAC THENL
15763        [REWRITE_TAC[MEASURE_INTERVAL; CONTENT_CLOSED_INTERVAL_CASES] THEN
15764         REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT;
15765                     VECTOR_SUB_COMPONENT; REAL_MUL_RID] THEN
15766         ASM_SIMP_TAC[REAL_ARITH `x - h <= x + h <=> &0 <= h`;
15767                      REAL_LE_DIV; REAL_POS; REAL_LT_IMP_LE] THEN
15768         REWRITE_TAC[REAL_ARITH `(x + h) - (x - h) = &2 * h`;
15769                     PRODUCT_CONST_NUMSEG_1; REAL_POW_DIV; REAL_POW_MUL] THEN
15770         MATCH_MP_TAC(REAL_ARITH `x = y ==> y <= x`) THEN
15771         REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN AP_TERM_TAC THEN
15772         MATCH_MP_TAC REAL_DIV_RMUL THEN
15773         REWRITE_TAC[REAL_POW_EQ_0; REAL_OF_NUM_EQ; DIMINDEX_NONZERO];
15774         MATCH_MP_TAC REAL_LE_RMUL THEN SIMP_TAC[REAL_POS; REAL_POW_LE] THEN
15775         MATCH_MP_TAC MEASURE_SUBSET THEN
15776         REWRITE_TAC[MEASURABLE_INTERVAL; MEASURABLE_CBALL] THEN
15777         REWRITE_TAC[SUBSET; IN_INTERVAL; IN_CBALL] THEN
15778         X_GEN_TAC `y:real^N` THEN
15779         REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT;
15780                     VECTOR_SUB_COMPONENT; REAL_MUL_RID; REAL_ARITH
15781                      `x - h <= y /\ y <= x + h <=> abs(x - y) <= h`] THEN
15782         STRIP_TAC THEN REWRITE_TAC[dist] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
15783         EXISTS_TAC `sum(1..dimindex(:N)) (\i. abs((x - y:real^N)$i))` THEN
15784         REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_BOUND_GEN THEN
15785         ASM_REWRITE_TAC[CARD_NUMSEG_1; VECTOR_SUB_COMPONENT; IN_NUMSEG] THEN
15786         REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1]]];
15787     REWRITE_TAC[NORM_REAL; GSYM drop] THEN
15788     MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= abs y`) THEN
15789     MATCH_MP_TAC REAL_LE_TRANS THEN
15790     EXISTS_TAC `drop(integral (cball(x:real^N,h))
15791                    (\t. lift(norm(indicator s t - indicator s x))))` THEN
15792     CONJ_TAC THENL
15793      [ASM_SIMP_TAC[MEASURE_INTEGRAL; MEASURABLE_CBALL;
15794                    MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE] THEN
15795       REWRITE_TAC[GSYM INTEGRAL_RESTRICT_INTER; GSYM DROP_CMUL] THEN
15796       SIMP_TAC[GSYM INTEGRAL_CMUL; GSYM MEASURABLE; MEASURABLE_CBALL] THEN
15797       REWRITE_TAC[GSYM DROP_SUB; COND_RATOR; COND_RAND] THEN
15798       REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_MUL_LID] THEN
15799       ASM_SIMP_TAC[GSYM INTEGRAL_SUB; INTEGRABLE_RESTRICT_INTER;
15800                    GSYM MEASURABLE; MEASURABLE_CBALL; INTEGRABLE_ON_CONST;
15801                    MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE] THEN
15802       REWRITE_TAC[GSYM NORM_REAL; drop] THEN REWRITE_TAC[GSYM drop] THEN
15803       MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
15804       ASM_SIMP_TAC[INTEGRABLE_SUB; INTEGRABLE_RESTRICT_INTER;
15805                    GSYM MEASURABLE; MEASURABLE_CBALL; INTEGRABLE_ON_CONST;
15806                    MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE] THEN
15807       CONJ_TAC THENL
15808        [ALL_TAC;
15809         GEN_TAC THEN DISCH_TAC THEN
15810         REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[indicator]) THEN
15811         REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; LIFT_DROP; DROP_VEC] THEN
15812         REAL_ARITH_TAC];
15813       REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP] THEN
15814       MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN
15815       REPEAT CONJ_TAC THENL
15816        [REWRITE_TAC[SUBSET; IN_CBALL; IN_INTERVAL] THEN
15817         REWRITE_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT; VEC_COMPONENT;
15818                     VECTOR_SUB_COMPONENT; REAL_MUL_RID; REAL_ARITH
15819                        `x - h <= y /\ y <= x + h <=> abs(x - y) <= h`] THEN
15820         REWRITE_TAC[dist; GSYM VECTOR_SUB_COMPONENT] THEN
15821         MESON_TAC[REAL_LE_TRANS; COMPONENT_LE_NORM];
15822         ALL_TAC;
15823         ALL_TAC;
15824         REWRITE_TAC[LIFT_DROP; REAL_ABS_POS]]]] THEN
15825   REWRITE_TAC[GSYM NORM_REAL; drop] THEN
15826   MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
15827   MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN
15828   MATCH_MP_TAC(INST_TYPE [`:1`,`:P`]
15829     ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND) THEN
15830   EXISTS_TAC `(\x. vec 1):real^N->real^1` THEN
15831
15832   REWRITE_TAC[DROP_VEC; GSYM MEASURABLE; MEASURABLE_INTERVAL;
15833               MEASURABLE_CBALL] THEN
15834   (CONJ_TAC THENL
15835     [GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[indicator] THEN
15836      REPEAT(COND_CASES_TAC THEN
15837             ASM_REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB; DROP_VEC]) THEN
15838      CONV_TAC REAL_RAT_REDUCE_CONV;
15839      ALL_TAC]) THEN
15840   MATCH_MP_TAC INTEGRABLE_SUB THEN
15841   REWRITE_TAC[INTEGRABLE_ON_CONST; MEASURABLE_INTERVAL; MEASURABLE_CBALL] THEN
15842   REWRITE_TAC[indicator; INTEGRABLE_RESTRICT_INTER] THEN
15843   REWRITE_TAC[GSYM MEASURABLE] THEN
15844   ASM_SIMP_TAC[MEASURABLE_CBALL; MEASURABLE_INTERVAL;
15845                MEASURABLE_LEGESGUE_MEASURABLE_INTER_MEASURABLE]);;