Update from HH
[hl193./.git] / Multivariate / integration.ml
1 (* ========================================================================= *)
2 (* Kurzweil-Henstock gauge integration in many dimensions.                   *)
3 (*                                                                           *)
4 (*              (c) Copyright, John Harrison 1998-2008                       *)
5 (* ========================================================================= *)
6
7 needs "Library/products.ml";;
8 needs "Library/floor.ml";;
9 needs "Multivariate/derivatives.ml";;
10 prioritize_real();;
11
12 (* ------------------------------------------------------------------------- *)
13 (* Some useful lemmas about intervals.                                       *)
14 (* ------------------------------------------------------------------------- *)
15
16 let INTERIOR_SUBSET_UNION_INTERVALS = prove
17  (`!s i j. (?a b:real^N. i = interval[a,b]) /\ (?c d. j = interval[c,d]) /\
18            ~(interior j = {}) /\
19            i SUBSET j UNION s /\
20            interior(i) INTER interior(j) = {}
21            ==> interior i SUBSET interior s`,
22   REPEAT STRIP_TAC THEN
23   REPEAT(FIRST_X_ASSUM(SUBST_ALL_TAC o check (is_var o lhs o concl))) THEN
24   MATCH_MP_TAC INTERIOR_MAXIMAL THEN REWRITE_TAC[OPEN_INTERIOR] THEN
25   RULE_ASSUM_TAC(REWRITE_RULE[INTERIOR_CLOSED_INTERVAL]) THEN
26   SUBGOAL_THEN `interval(a:real^N,b) INTER interval[c,d] = {}` ASSUME_TAC THENL
27    [ASM_SIMP_TAC[INTER_INTERVAL_MIXED_EQ_EMPTY];
28     MP_TAC(ISPECL [`a:real^N`; `b:real^N`] INTERVAL_OPEN_SUBSET_CLOSED) THEN
29     REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN
30     REPEAT(POP_ASSUM MP_TAC) THEN SET_TAC[]]);;
31
32 let INTER_INTERIOR_UNIONS_INTERVALS = prove
33  (`!s f. FINITE f /\ open s /\
34          (!t. t IN f ==> ?a b:real^N. t = interval[a,b]) /\
35          (!t. t IN f ==> s INTER (interior t) = {})
36          ==> s INTER interior(UNIONS f) = {}`,
37   ONCE_REWRITE_TAC[TAUT
38     `a /\ b /\ c /\ d ==> e <=> a /\ b /\ c ==> ~e ==> ~d`] THEN
39   REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; GSYM MEMBER_NOT_EMPTY] THEN
40   SIMP_TAC[OPEN_CONTAINS_BALL_EQ; OPEN_INTER; OPEN_INTERIOR] THEN
41   SIMP_TAC[OPEN_SUBSET_INTERIOR; OPEN_BALL; SUBSET_INTER] THEN
42   REWRITE_TAC[GSYM SUBSET_INTER] THEN
43   GEN_TAC THEN ONCE_REWRITE_TAC[IMP_CONJ] THEN
44   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN CONJ_TAC THENL
45    [REWRITE_TAC[UNIONS_0; INTER_EMPTY; SUBSET_EMPTY] THEN
46     MESON_TAC[CENTRE_IN_BALL; NOT_IN_EMPTY];
47     ALL_TAC] THEN
48   MAP_EVERY X_GEN_TAC [`i:real^N->bool`; `f:(real^N->bool)->bool`] THEN
49   DISCH_TAC THEN
50   REWRITE_TAC[UNIONS_INSERT; IN_INSERT] THEN
51   REWRITE_TAC[TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
52   REWRITE_TAC[RIGHT_OR_DISTRIB; FORALL_AND_THM; EXISTS_OR_THM] THEN
53   REWRITE_TAC[GSYM CONJ_ASSOC; UNWIND_THM2] THEN
54   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
55   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
56   DISCH_THEN(MP_TAC o SPEC `i:real^N->bool`) THEN REWRITE_TAC[] THEN
57   DISCH_THEN(X_CHOOSE_THEN `a:real^N` (X_CHOOSE_THEN `b:real^N`
58     SUBST_ALL_TAC)) THEN
59   FIRST_X_ASSUM(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
60   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT
61    `(r ==> s \/ p) ==> (p ==> q) ==> r ==> s \/ q`) THEN
62   POP_ASSUM_LIST(K ALL_TAC) THEN STRIP_TAC THEN
63   ASM_CASES_TAC `(x:real^N) IN interval[a,b]` THENL
64    [ALL_TAC;
65     SUBGOAL_THEN
66      `?d. &0 < d /\ ball(x,d) SUBSET ((:real^N) DIFF interval[a,b])`
67     STRIP_ASSUME_TAC THENL
68      [ASM_MESON_TAC[closed; OPEN_CONTAINS_BALL; CLOSED_INTERVAL;
69                     IN_DIFF; IN_UNIV];
70       ALL_TAC] THEN
71     DISJ2_TAC THEN MAP_EVERY EXISTS_TAC [`x:real^N`; `min d e`] THEN
72     ASM_REWRITE_TAC[REAL_LT_MIN; SUBSET] THEN
73     REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET])) THEN
74     SIMP_TAC[IN_BALL; REAL_LT_MIN; IN_DIFF; IN_INTER; IN_UNIV; IN_UNION] THEN
75     ASM_MESON_TAC[]] THEN
76   ASM_CASES_TAC `(x:real^N) IN interval(a,b)` THENL
77    [DISJ1_TAC THEN
78     SUBGOAL_THEN
79      `?d. &0 < d /\ ball(x:real^N,d) SUBSET interval(a,b)`
80     STRIP_ASSUME_TAC THENL
81      [ASM_MESON_TAC[OPEN_CONTAINS_BALL; OPEN_INTERVAL]; ALL_TAC] THEN
82     MAP_EVERY EXISTS_TAC [`x:real^N`; `min d e`] THEN
83     ASM_REWRITE_TAC[REAL_LT_MIN; SUBSET] THEN
84     REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET])) THEN
85     SIMP_TAC[IN_BALL; REAL_LT_MIN; IN_DIFF; IN_INTER; IN_UNIV; IN_UNION] THEN
86     ASM_MESON_TAC[INTERVAL_OPEN_SUBSET_CLOSED; SUBSET];
87     ALL_TAC] THEN
88   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [IN_INTERVAL]) THEN
89   RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN ASM_SIMP_TAC[REAL_LT_LE] THEN
90   REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; LEFT_IMP_EXISTS_THM] THEN
91   X_GEN_TAC `k:num` THEN REWRITE_TAC[GSYM REAL_LT_LE; DE_MORGAN_THM] THEN
92   STRIP_TAC THEN DISJ2_TAC THENL
93    [EXISTS_TAC `x + --e / &2 % basis k :real^N`;
94     EXISTS_TAC `x + e / &2 % basis k :real^N`] THEN
95   EXISTS_TAC `e / &2` THEN ASM_REWRITE_TAC[REAL_HALF] THEN
96   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
97    `b1 SUBSET k INTER (i UNION s)
98     ==> b2 SUBSET b1 /\ b2 INTER i = {}
99         ==> b2 SUBSET k INTER s`)) THEN
100   (CONJ_TAC THENL
101     [REWRITE_TAC[SUBSET; IN_BALL] THEN
102      GEN_TAC THEN MATCH_MP_TAC(NORM_ARITH `norm(d) = e / &2 ==>
103         dist(x + d,y) < e / &2 ==> dist(x,y) < e`) THEN
104      ASM_SIMP_TAC[NORM_MUL; NORM_BASIS] THEN UNDISCH_TAC `&0 < e` THEN
105      REAL_ARITH_TAC;
106      ALL_TAC]) THEN
107   REWRITE_TAC[EXTENSION; IN_INTER; IN_INTERVAL; NOT_IN_EMPTY] THEN
108   X_GEN_TAC `y:real^N` THEN REWRITE_TAC[IN_BALL; dist] THEN
109   REWRITE_TAC[TAUT `~(a /\ b) <=> a ==> ~b`] THEN
110   W(MP_TAC o C ISPEC COMPONENT_LE_NORM o rand o lhand o lhand o snd) THEN
111   DISCH_THEN(MP_TAC o SPEC `k:num`) THEN ASM_REWRITE_TAC[IMP_IMP] THEN
112   DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH `x <= y /\ y < e ==> x < e`)) THEN
113   ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; VECTOR_ADD_COMPONENT;
114                VECTOR_MUL_COMPONENT; BASIS_COMPONENT] THEN
115   DISCH_THEN(fun th -> DISCH_THEN(MP_TAC o SPEC `k:num`) THEN MP_TAC th) THEN
116   ASM_REWRITE_TAC[] THEN UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC);;
117
118 (* ------------------------------------------------------------------------- *)
119 (* This lemma about iterations comes up in a few places.                     *)
120 (* ------------------------------------------------------------------------- *)
121
122 let ITERATE_NONZERO_IMAGE_LEMMA = prove
123  (`!op s f g a.
124       monoidal op /\ FINITE s /\
125       g(a) = neutral op /\
126       (!x y. x IN s /\ y IN s /\ f x = f y /\ ~(x = y) ==> g(f x) = neutral op)
127       ==> iterate op {f x | x | x IN s /\ ~(f x = a)} g =
128           iterate op s (g o f)`,
129   REPEAT STRIP_TAC THEN
130   GEN_REWRITE_TAC RAND_CONV [GSYM ITERATE_SUPPORT] THEN
131   REWRITE_TAC[support] THEN
132   ONCE_REWRITE_TAC[SET_RULE `{f x |x| x IN s /\ ~(f x = a)} =
133                              IMAGE f {x | x IN s /\ ~(f x = a)}`] THEN
134   W(fun (asl,w) -> FIRST_ASSUM(fun th ->
135    MP_TAC(PART_MATCH (rand o rand)
136        (MATCH_MP ITERATE_IMAGE th) (rand w)))) THEN
137   ANTS_TAC THENL
138    [REWRITE_TAC[IN_ELIM_THM; o_THM] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
139   DISCH_THEN(SUBST1_TAC o SYM) THEN
140   FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP ITERATE_SUPERSET) THEN
141   ASM_SIMP_TAC[FINITE_IMAGE; FINITE_RESTRICT] THEN
142   REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; SUBSET] THEN
143   REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; o_THM] THEN
144   ASM_MESON_TAC[]);;
145
146 (* ------------------------------------------------------------------------- *)
147 (* Bounds on intervals where they exist.                                     *)
148 (* ------------------------------------------------------------------------- *)
149
150 let interval_upperbound = new_definition
151   `(interval_upperbound:(real^M->bool)->real^M) s =
152         lambda i. sup {a | ?x. x IN s /\ (x$i = a)}`;;
153
154 let interval_lowerbound = new_definition
155   `(interval_lowerbound:(real^M->bool)->real^M) s =
156         lambda i. inf {a | ?x. x IN s /\ (x$i = a)}`;;
157
158 let INTERVAL_UPPERBOUND = prove
159  (`!a b:real^N. (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= b$i)
160                 ==> interval_upperbound(interval[a,b]) = b`,
161   SIMP_TAC[interval_upperbound; CART_EQ; LAMBDA_BETA] THEN
162   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_UNIQUE THEN
163   REWRITE_TAC[IN_ELIM_THM; IN_INTERVAL] THEN ASM_MESON_TAC[REAL_LE_REFL]);;
164
165 let INTERVAL_LOWERBOUND = prove
166  (`!a b:real^N. (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= b$i)
167                 ==> interval_lowerbound(interval[a,b]) = a`,
168   SIMP_TAC[interval_lowerbound; CART_EQ; LAMBDA_BETA] THEN
169   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_INF_UNIQUE THEN
170   REWRITE_TAC[IN_ELIM_THM; IN_INTERVAL] THEN ASM_MESON_TAC[REAL_LE_REFL]);;
171
172 let INTERVAL_UPPERBOUND_1 = prove
173  (`!a b. drop a <= drop b ==> interval_upperbound(interval[a,b]) = b`,
174   SIMP_TAC[INTERVAL_UPPERBOUND; DIMINDEX_1; FORALL_1; drop]);;
175
176 let INTERVAL_LOWERBOUND_1 = prove
177  (`!a b. drop a <= drop b ==> interval_lowerbound(interval[a,b]) = a`,
178   SIMP_TAC[INTERVAL_LOWERBOUND; DIMINDEX_1; FORALL_1; drop]);;
179
180 let INTERVAL_LOWERBOUND_NONEMPTY = prove
181  (`!a b:real^N.
182     ~(interval[a,b] = {}) ==> interval_lowerbound(interval[a,b]) = a`,
183   SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_NE_EMPTY]);;
184
185 let INTERVAL_UPPERBOUND_NONEMPTY = prove
186  (`!a b:real^N.
187     ~(interval[a,b] = {}) ==> interval_upperbound(interval[a,b]) = b`,
188   SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_NE_EMPTY]);;
189
190 (* ------------------------------------------------------------------------- *)
191 (* Content (length, area, volume...) of an interval.                         *)
192 (* ------------------------------------------------------------------------- *)
193
194 let content = new_definition
195    `content(s:real^M->bool) =
196        if s = {} then &0 else
197        product(1..dimindex(:M))
198               (\i. (interval_upperbound s)$i - (interval_lowerbound s)$i)`;;
199
200 let CONTENT_CLOSED_INTERVAL = prove
201  (`!a b:real^N. (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= b$i)
202                 ==> content(interval[a,b]) =
203                         product(1..dimindex(:N)) (\i. b$i - a$i)`,
204   SIMP_TAC[content; INTERVAL_UPPERBOUND; INTERVAL_EQ_EMPTY;
205            INTERVAL_LOWERBOUND] THEN
206   MESON_TAC[REAL_NOT_LT]);;
207
208 let CONTENT_1 = prove
209  (`!a b. drop a <= drop b ==> content(interval[a,b]) = drop b - drop a`,
210   SIMP_TAC[CONTENT_CLOSED_INTERVAL; FORALL_1; drop; DIMINDEX_1] THEN
211   REWRITE_TAC[PRODUCT_SING_NUMSEG]);;
212
213 let CONTENT_UNIT = prove
214  (`content(interval[vec 0:real^N,vec 1]) = &1`,
215   REWRITE_TAC[content] THEN COND_CASES_TAC THENL
216    [POP_ASSUM MP_TAC THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
217     SIMP_TAC[INTERVAL_NE_EMPTY; VEC_COMPONENT; REAL_POS];
218     MATCH_MP_TAC PRODUCT_EQ_1 THEN
219     SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND;
220              VEC_COMPONENT; REAL_POS; IN_NUMSEG; REAL_SUB_RZERO]]);;
221
222 let CONTENT_UNIT_1 = prove
223  (`content(interval[vec 0:real^1,vec 1]) = &1`,
224   MATCH_ACCEPT_TAC CONTENT_UNIT);;
225
226 let CONTENT_POS_LE = prove
227  (`!a b:real^N. &0 <= content(interval[a,b])`,
228   REPEAT GEN_TAC THEN REWRITE_TAC[content] THEN
229   COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN
230   MATCH_MP_TAC PRODUCT_POS_LE_NUMSEG THEN
231   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN
232   ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_SUB_LE]);;
233
234 let CONTENT_POS_LT = prove
235  (`!a b:real^N.
236         (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i)
237         ==> &0 < content(interval[a,b])`,
238   REPEAT STRIP_TAC THEN
239   ASM_SIMP_TAC[CONTENT_CLOSED_INTERVAL; REAL_LT_IMP_LE] THEN
240   MATCH_MP_TAC PRODUCT_POS_LT_NUMSEG THEN
241   ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_SUB_LT;
242                REAL_LT_IMP_LE]);;
243
244 let CONTENT_POS_LT_1 = prove
245  (`!a b. drop a < drop b ==> &0 < content(interval[a,b])`,
246   SIMP_TAC[CONTENT_POS_LT; FORALL_1; DIMINDEX_1; GSYM drop]);;
247
248 let CONTENT_EQ_0_GEN = prove
249  (`!s:real^N->bool.
250      bounded s
251      ==> (content s = &0 <=>
252           ?i a. 1 <= i /\ i <= dimindex(:N) /\ !x. x IN s ==> x$i = a)`,
253   REPEAT GEN_TAC THEN REWRITE_TAC[content] THEN
254   COND_CASES_TAC THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THENL
255    [MESON_TAC[DIMINDEX_GE_1; LE_REFL]; ALL_TAC] THEN
256   REWRITE_TAC[PRODUCT_EQ_0_NUMSEG; REAL_SUB_0] THEN DISCH_TAC THEN
257   AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
258   X_GEN_TAC `k:num` THEN
259   ASM_CASES_TAC `1 <= k` THEN ASM_REWRITE_TAC[] THEN
260   ASM_CASES_TAC `k <= dimindex(:N)` THEN ASM_REWRITE_TAC[] THEN
261   ASM_SIMP_TAC[interval_upperbound; interval_lowerbound; LAMBDA_BETA] THEN
262   W(MP_TAC o PART_MATCH (lhs o rand) REAL_SUP_EQ_INF o lhs o snd) THEN
263   ANTS_TAC THENL
264    [CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
265     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
266     REWRITE_TAC[IN_ELIM_THM] THEN
267     ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS];
268     DISCH_THEN SUBST1_TAC THEN ASM SET_TAC[]]);;
269
270 let CONTENT_EQ_0 = prove
271  (`!a b:real^N.
272         content(interval[a,b]) = &0 <=>
273         ?i. 1 <= i /\ i <= dimindex(:N) /\ b$i <= a$i`,
274   REPEAT GEN_TAC THEN REWRITE_TAC[content; INTERVAL_EQ_EMPTY] THEN
275   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
276    [ASM_MESON_TAC[REAL_LT_IMP_LE]; ALL_TAC] THEN
277   REWRITE_TAC[PRODUCT_EQ_0_NUMSEG; REAL_SUB_0] THEN
278   AP_TERM_TAC THEN ABS_TAC THEN POP_ASSUM MP_TAC THEN
279   REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN
280   SIMP_TAC[REAL_NOT_LT; INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN
281   MESON_TAC[REAL_NOT_LE; REAL_LE_LT]);;
282
283 let CONTENT_0_SUBSET_GEN = prove
284  (`!s t:real^N->bool.
285       s SUBSET t /\ bounded t /\ content t = &0 ==> content s = &0`,
286   REPEAT GEN_TAC THEN
287   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
288   SUBGOAL_THEN `bounded(s:real^N->bool)` ASSUME_TAC THENL
289    [ASM_MESON_TAC[BOUNDED_SUBSET]; ALL_TAC] THEN
290   ASM_SIMP_TAC[CONTENT_EQ_0_GEN] THEN ASM SET_TAC[]);;
291
292 let CONTENT_0_SUBSET = prove
293  (`!s a b:real^N.
294         s SUBSET interval[a,b] /\ content(interval[a,b]) = &0
295         ==> content s = &0`,
296   MESON_TAC[CONTENT_0_SUBSET_GEN; BOUNDED_INTERVAL]);;
297
298 let CONTENT_CLOSED_INTERVAL_CASES = prove
299  (`!a b:real^N.
300         content(interval[a,b]) =
301                 if !i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= b$i
302                 then product(1..dimindex(:N)) (\i. b$i - a$i)
303                 else &0`,
304   REPEAT GEN_TAC THEN COND_CASES_TAC THEN
305   ASM_SIMP_TAC[CONTENT_EQ_0; CONTENT_CLOSED_INTERVAL] THEN
306   ASM_MESON_TAC[REAL_LE_TOTAL]);;
307
308 let CONTENT_EQ_0_INTERIOR = prove
309  (`!a b:real^N.
310         content(interval[a,b]) = &0 <=> interior(interval[a,b]) = {}`,
311   REWRITE_TAC[CONTENT_EQ_0; INTERIOR_CLOSED_INTERVAL; INTERVAL_EQ_EMPTY]);;
312
313 let CONTENT_EQ_0_1 = prove
314  (`!a b:real^1.
315         content(interval[a,b]) = &0 <=> drop b <= drop a`,
316   REWRITE_TAC[CONTENT_EQ_0; drop; DIMINDEX_1; CONJ_ASSOC; LE_ANTISYM] THEN
317   MESON_TAC[]);;
318
319 let CONTENT_POS_LT_EQ = prove
320  (`!a b:real^N.
321         &0 < content(interval[a,b]) <=>
322         !i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i`,
323   REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[CONTENT_POS_LT] THEN
324   REWRITE_TAC[REAL_ARITH `&0 < x <=> &0 <= x /\ ~(x = &0)`] THEN
325   REWRITE_TAC[CONTENT_POS_LE; CONTENT_EQ_0] THEN MESON_TAC[REAL_NOT_LE]);;
326
327 let CONTENT_EMPTY = prove
328  (`content {} = &0`,
329   REWRITE_TAC[content]);;
330
331 let CONTENT_SUBSET = prove
332  (`!a b c d:real^N.
333         interval[a,b] SUBSET interval[c,d]
334         ==> content(interval[a,b]) <= content(interval[c,d])`,
335   REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [content] THEN
336   COND_CASES_TAC THEN ASM_REWRITE_TAC[CONTENT_POS_LE] THEN
337   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
338   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN
339   REWRITE_TAC[IN_INTERVAL] THEN DISCH_THEN(fun th ->
340     MP_TAC(SPEC `a:real^N` th) THEN MP_TAC(SPEC `b:real^N` th)) THEN
341   ASM_SIMP_TAC[REAL_LE_REFL; content] THEN REPEAT STRIP_TAC THEN
342   ONCE_REWRITE_TAC[TAUT `(if b then c else d) = (if ~b then d else c)`] THEN
343   REWRITE_TAC[INTERVAL_NE_EMPTY] THEN COND_CASES_TAC THENL
344    [ALL_TAC; ASM_MESON_TAC[REAL_LE_TRANS]] THEN
345   MATCH_MP_TAC PRODUCT_LE_NUMSEG THEN
346   ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN
347   REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN
348   MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
349   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
350   REAL_ARITH_TAC);;
351
352 let CONTENT_LT_NZ = prove
353  (`!a b. &0 < content(interval[a,b]) <=> ~(content(interval[a,b]) = &0)`,
354   REWRITE_TAC[CONTENT_POS_LT_EQ; CONTENT_EQ_0] THEN MESON_TAC[REAL_NOT_LE]);;
355
356 let INTERVAL_BOUNDS_NULL_1 = prove
357  (`!a b:real^1.
358         content(interval[a,b]) = &0
359         ==> interval_upperbound(interval[a,b]) =
360             interval_lowerbound(interval[a,b])`,
361   REPEAT GEN_TAC THEN ASM_CASES_TAC `interval[a:real^1,b] = {}` THENL
362    [ASM_REWRITE_TAC[interval_upperbound; interval_lowerbound] THEN
363     REWRITE_TAC[sup; inf; NOT_IN_EMPTY; EMPTY_GSPEC] THEN DISCH_TAC THEN
364     REPLICATE_TAC 2 (AP_TERM_TAC THEN ABS_TAC) THEN
365     MESON_TAC[REAL_ARITH `~(x <= x - &1) /\ ~(x + &1 <= x)`];
366     RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
367     ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1] THEN
368     REWRITE_TAC[CONTENT_EQ_0_1; GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC]);;
369
370 let INTERVAL_BOUNDS_EMPTY_1 = prove
371  (`interval_upperbound({}:real^1->bool) =
372    interval_lowerbound({}:real^1->bool)`,
373   MESON_TAC[INTERVAL_BOUNDS_NULL_1; CONTENT_EMPTY; EMPTY_AS_INTERVAL]);;
374
375 let CONTENT_PASTECART = prove
376  (`!a b:real^M c d:real^N.
377         content(interval[pastecart a c,pastecart b d]) =
378         content(interval[a,b]) * content(interval[c,d])`,
379   REPEAT GEN_TAC THEN
380   SIMP_TAC[CONTENT_CLOSED_INTERVAL_CASES; LAMBDA_BETA] THEN
381   MATCH_MP_TAC(MESON[REAL_MUL_LZERO; REAL_MUL_RZERO]
382    `(p <=> p1 /\ p2) /\ z = x * y
383     ==> (if p then z else &0) =
384         (if p1 then x else &0) * (if p2 then y else &0)`) THEN
385   CONJ_TAC THENL
386    [EQ_TAC THEN DISCH_TAC THEN TRY CONJ_TAC THEN X_GEN_TAC `i:num` THEN
387     STRIP_TAC THENL
388      [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
389       ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM] THEN
390       DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC;
391       FIRST_X_ASSUM(MP_TAC o SPEC `i + dimindex(:M)`) THEN
392       ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM] THEN
393       ANTS_TAC THENL [ASM_ARITH_TAC; REWRITE_TAC[ADD_SUB]] THEN
394       COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC;
395       RULE_ASSUM_TAC(REWRITE_RULE[DIMINDEX_FINITE_SUM]) THEN
396       ASM_CASES_TAC `i <= dimindex(:M)` THENL
397        [FIRST_X_ASSUM(MP_TAC o SPEC `i:num` o CONJUNCT1);
398         FIRST_X_ASSUM(MP_TAC o SPEC `i - dimindex(:M)` o CONJUNCT2)] THEN
399       ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM;
400                    ARITH_RULE `i:num <= m ==> i <= m + n`] THEN
401       DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC];
402     SIMP_TAC[DIMINDEX_FINITE_SUM; ARITH_RULE `1 <= n + 1`;
403              PRODUCT_ADD_SPLIT] THEN
404     BINOP_TAC THENL
405      [ALL_TAC;
406       ONCE_REWRITE_TAC[ADD_SYM] THEN REWRITE_TAC[PRODUCT_OFFSET]] THEN
407     MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN
408     SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM; ADD_SUB;
409              ARITH_RULE `i:num <= m ==> i <= m + n`;
410              ARITH_RULE `i:num <= n ==> i + m <= m + n`] THEN
411     REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
412     ASM_ARITH_TAC]);;
413
414 (* ------------------------------------------------------------------------- *)
415 (* The notion of a gauge --- simply an open set containing the point.        *)
416 (* ------------------------------------------------------------------------- *)
417
418 let gauge = new_definition
419   `gauge d <=> !x. x IN d(x) /\ open(d(x))`;;
420
421 let GAUGE_BALL_DEPENDENT = prove
422  (`!e. (!x. &0 < e(x)) ==> gauge(\x. ball(x,e(x)))`,
423   SIMP_TAC[gauge; OPEN_BALL; IN_BALL; DIST_REFL]);;
424
425 let GAUGE_BALL = prove
426  (`!e. &0 < e ==> gauge (\x. ball(x,e))`,
427   SIMP_TAC[gauge; OPEN_BALL; IN_BALL; DIST_REFL]);;
428
429 let GAUGE_TRIVIAL = prove
430  (`gauge (\x. ball(x,&1))`,
431   SIMP_TAC[GAUGE_BALL; REAL_LT_01]);;
432
433 let GAUGE_INTER = prove
434  (`!d1 d2. gauge d1 /\ gauge d2 ==> gauge (\x. (d1 x) INTER (d2 x))`,
435   SIMP_TAC[gauge; IN_INTER; OPEN_INTER]);;
436
437 let GAUGE_INTERS = prove
438  (`!s. FINITE s /\ (!d. d IN s ==> gauge (f d))
439        ==> gauge(\x. INTERS {f d x | d IN s})`,
440   REWRITE_TAC[gauge; IN_INTERS] THEN
441   REWRITE_TAC[SET_RULE `{f d x | d IN s} = IMAGE (\d. f d x) s`] THEN
442   SIMP_TAC[FORALL_IN_IMAGE; OPEN_INTERS; FINITE_IMAGE]);;
443
444 let GAUGE_EXISTENCE_LEMMA = prove
445  (`(!x. ?d. p x ==> &0 < d /\ q d x) <=>
446    (!x. ?d. &0 < d /\ (p x ==> q d x))`,
447   MESON_TAC[REAL_LT_01]);;
448
449 (* ------------------------------------------------------------------------- *)
450 (* Divisions.                                                                *)
451 (* ------------------------------------------------------------------------- *)
452
453 parse_as_infix("division_of",(12,"right"));;
454
455 let division_of = new_definition
456  `s division_of i <=>
457         FINITE s /\
458         (!k. k IN s
459              ==> k SUBSET i /\ ~(k = {}) /\ ?a b. k = interval[a,b]) /\
460         (!k1 k2. k1 IN s /\ k2 IN s /\ ~(k1 = k2)
461                  ==> interior(k1) INTER interior(k2) = {}) /\
462         (UNIONS s = i)`;;
463
464 let DIVISION_OF = prove
465  (`s division_of i <=>
466         FINITE s /\
467         (!k. k IN s ==> ~(k = {}) /\ ?a b. k = interval[a,b]) /\
468         (!k1 k2. k1 IN s /\ k2 IN s /\ ~(k1 = k2)
469                  ==> interior(k1) INTER interior(k2) = {}) /\
470         UNIONS s = i`,
471   REWRITE_TAC[division_of] THEN SET_TAC[]);;
472
473 let DIVISION_OF_FINITE = prove
474  (`!s i. s division_of i ==> FINITE s`,
475   MESON_TAC[division_of]);;
476
477 let DIVISION_OF_SELF = prove
478  (`!a b. ~(interval[a,b] = {}) ==> {interval[a,b]} division_of interval[a,b]`,
479   REWRITE_TAC[division_of; FINITE_INSERT; FINITE_RULES; IN_SING; UNIONS_1] THEN
480   MESON_TAC[SUBSET_REFL]);;
481
482 let DIVISION_OF_TRIVIAL = prove
483  (`!s. s division_of {} <=> s = {}`,
484   REWRITE_TAC[division_of; SUBSET_EMPTY; CONJ_ASSOC] THEN
485   REWRITE_TAC[TAUT `~(p /\ ~p)`; GSYM NOT_EXISTS_THM; MEMBER_NOT_EMPTY] THEN
486   REWRITE_TAC[AC CONJ_ACI `((a /\ b) /\ c) /\ d <=> b /\ a /\ c /\ d`] THEN
487   GEN_TAC THEN MATCH_MP_TAC(TAUT `(a ==> b) ==> (a /\ b <=> a)`) THEN
488   DISCH_THEN SUBST1_TAC THEN
489   REWRITE_TAC[FINITE_RULES; UNIONS_0; NOT_IN_EMPTY]);;
490
491 let EMPTY_DIVISION_OF = prove
492  (`!s. {} division_of s <=> s = {}`,
493   REWRITE_TAC[division_of; UNIONS_0; FINITE_EMPTY; NOT_IN_EMPTY] THEN
494   MESON_TAC[]);;
495
496 let DIVISION_OF_SING = prove
497  (`!s a. s division_of interval[a,a] <=> s = {interval[a,a]}`,
498   let lemma = prove
499    (`s SUBSET {{a}} /\ p /\ UNIONS s = {a} <=> s = {{a}} /\ p`,
500     EQ_TAC THEN STRIP_TAC THEN
501     ASM_REWRITE_TAC[SET_RULE `UNIONS {a} = a`] THEN ASM SET_TAC[]) in
502   REWRITE_TAC[division_of; INTERVAL_SING] THEN
503   REWRITE_TAC[SET_RULE `k SUBSET {a} /\ ~(k = {}) /\ p <=> k = {a} /\ p`] THEN
504   REWRITE_TAC[GSYM INTERVAL_SING] THEN
505   REWRITE_TAC[MESON[] `(k = interval[a,b] /\ ?c d. k = interval[c,d]) <=>
506                        (k = interval[a,b])`] THEN
507   REWRITE_TAC[SET_RULE `(!k. k IN s ==> k = a) <=> s SUBSET {a}`] THEN
508   REWRITE_TAC[INTERVAL_SING; lemma] THEN MESON_TAC[FINITE_RULES; IN_SING]);;
509
510 let ELEMENTARY_EMPTY = prove
511  (`?p. p division_of {}`,
512   REWRITE_TAC[DIVISION_OF_TRIVIAL; EXISTS_REFL]);;
513
514 let ELEMENTARY_INTERVAL = prove
515  (`!a b. ?p. p division_of interval[a,b]`,
516   MESON_TAC[DIVISION_OF_TRIVIAL; DIVISION_OF_SELF]);;
517
518 let DIVISION_CONTAINS = prove
519  (`!s i. s division_of i ==> !x. x IN i ==> ?k. x IN k /\ k IN s`,
520   REWRITE_TAC[division_of; EXTENSION; IN_UNIONS] THEN MESON_TAC[]);;
521
522 let FORALL_IN_DIVISION = prove
523  (`!P d i. d division_of i
524            ==> ((!x. x IN d ==> P x) <=>
525                (!a b. interval[a,b] IN d ==> P(interval[a,b])))`,
526   REWRITE_TAC[division_of] THEN MESON_TAC[]);;
527
528 let FORALL_IN_DIVISION_NONEMPTY = prove
529  (`!P d i.
530          d division_of i
531          ==> ((!x. x IN d ==> P x) <=>
532               (!a b. interval [a,b] IN d /\ ~(interval[a,b] = {})
533                      ==> P (interval [a,b])))`,
534   REWRITE_TAC[division_of] THEN MESON_TAC[]);;
535
536 let DIVISION_OF_SUBSET = prove
537  (`!p q:(real^N->bool)->bool.
538         p division_of (UNIONS p) /\ q SUBSET p ==> q division_of (UNIONS q)`,
539   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
540   REWRITE_TAC[division_of] THEN
541   REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THENL
542    [ASM_MESON_TAC[FINITE_SUBSET]; ASM SET_TAC[]; ASM SET_TAC[]]);;
543
544 let DIVISION_OF_UNION_SELF = prove
545  (`!p s. p division_of s ==> p division_of (UNIONS p)`,
546   REWRITE_TAC[division_of] THEN MESON_TAC[]);;
547
548 let DIVISION_OF_CONTENT_0 = prove
549  (`!a b d. content(interval[a,b]) = &0 /\ d division_of interval[a,b]
550            ==> !k. k IN d ==> content k = &0`,
551   REPEAT GEN_TAC THEN STRIP_TAC THEN
552   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
553   REWRITE_TAC[GSYM REAL_LE_ANTISYM; CONTENT_POS_LE] THEN
554   ASM_MESON_TAC[CONTENT_SUBSET; division_of]);;
555
556 let DIVISION_INTER = prove
557  (`!s1 s2:real^N->bool p1 p2.
558         p1 division_of s1 /\
559         p2 division_of s2
560         ==> {k1 INTER k2 | k1 IN p1 /\ k2 IN p2 /\ ~(k1 INTER k2 = {})}
561             division_of (s1 INTER s2)`,
562   let lemma = prove
563    (`{k1 INTER k2 | k1 IN p1 /\ k2 IN p2 /\ ~(k1 INTER k2 = {})} =
564         {s | s IN IMAGE (\(k1,k2). k1 INTER k2) (p1 CROSS p2) /\
565              ~(s = {})}`,
566     REWRITE_TAC[EXTENSION] THEN
567     REWRITE_TAC[IN_IMAGE; IN_ELIM_THM; EXISTS_PAIR_THM; IN_CROSS] THEN
568     MESON_TAC[]) in
569   REPEAT GEN_TAC THEN REWRITE_TAC[DIVISION_OF] THEN STRIP_TAC THEN
570   ASM_SIMP_TAC[lemma; FINITE_RESTRICT; FINITE_CROSS; FINITE_IMAGE] THEN
571   REWRITE_TAC[IN_ELIM_THM] THEN
572   REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; RIGHT_FORALL_IMP_THM] THEN
573   REWRITE_TAC[FORALL_PAIR_THM; IN_CROSS] THEN REPEAT CONJ_TAC THENL
574    [ASM_MESON_TAC[INTER_INTERVAL];
575     REPEAT STRIP_TAC THEN
576     MATCH_MP_TAC(SET_RULE
577      `(interior x1 INTER interior x2 = {} \/
578        interior y1 INTER interior y2 = {}) /\
579       interior(x1 INTER y1) SUBSET interior(x1) /\
580       interior(x1 INTER y1) SUBSET interior(y1) /\
581       interior(x2 INTER y2) SUBSET interior(x2) /\
582       interior(x2 INTER y2) SUBSET interior(y2)
583       ==> interior(x1 INTER y1) INTER interior(x2 INTER y2) = {}`) THEN
584     CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
585     REPEAT CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[];
586     REWRITE_TAC[SET_RULE `UNIONS {x | x IN s /\ ~(x = {})} = UNIONS s`] THEN
587     REPEAT(FIRST_X_ASSUM(SUBST_ALL_TAC o SYM)) THEN
588     GEN_REWRITE_TAC I [EXTENSION] THEN
589     REWRITE_TAC[IN_UNIONS; IN_IMAGE; EXISTS_PAIR_THM; IN_CROSS; IN_INTER] THEN
590     MESON_TAC[IN_INTER]]);;
591
592 let DIVISION_INTER_1 = prove
593  (`!d i a b:real^N.
594         d division_of i /\ interval[a,b] SUBSET i
595         ==> { interval[a,b] INTER k | k |
596                  k IN d /\ ~(interval[a,b] INTER k = {}) }
597             division_of interval[a,b]`,
598   REPEAT STRIP_TAC THEN
599   ASM_CASES_TAC `interval[a:real^N,b] = {}` THEN
600   ASM_REWRITE_TAC[INTER_EMPTY; SET_RULE `{{} | F} = {}`;
601                   DIVISION_OF_TRIVIAL] THEN
602   MP_TAC(ISPECL [`interval[a:real^N,b]`; `i:real^N->bool`;
603                  `{interval[a:real^N,b]}`; `d:(real^N->bool)->bool`]
604                 DIVISION_INTER) THEN
605   ASM_SIMP_TAC[DIVISION_OF_SELF; SET_RULE `s SUBSET t ==> s INTER t = s`] THEN
606   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN SET_TAC[]);;
607
608 let ELEMENTARY_INTER = prove
609  (`!s t. (?p. p division_of s) /\ (?p. p division_of t)
610          ==> ?p. p division_of (s INTER t)`,
611   MESON_TAC[DIVISION_INTER]);;
612
613 let ELEMENTARY_INTERS = prove
614  (`!f:(real^N->bool)->bool.
615         FINITE f /\ ~(f = {}) /\
616         (!s. s IN f ==> ?p. p division_of s)
617         ==> ?p. p division_of (INTERS f)`,
618   REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
619   REWRITE_TAC[INTERS_INSERT] THEN
620   MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `s:(real^N->bool)->bool`] THEN
621   ASM_CASES_TAC `s:(real^N->bool)->bool = {}` THEN ASM_REWRITE_TAC[] THENL
622    [REWRITE_TAC[INTERS_0; INTER_UNIV; IN_SING] THEN MESON_TAC[];
623     REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THEN
624     MATCH_MP_TAC ELEMENTARY_INTER THEN ASM_MESON_TAC[]]);;
625
626 let DIVISION_DISJOINT_UNION = prove
627  (`!s1 s2:real^N->bool p1 p2.
628         p1 division_of s1 /\
629         p2 division_of s2 /\
630         interior s1 INTER interior s2 = {}
631         ==> (p1 UNION p2) division_of (s1 UNION s2)`,
632   REPEAT GEN_TAC THEN REWRITE_TAC[division_of] THEN STRIP_TAC THEN
633   ASM_REWRITE_TAC[FINITE_UNION; IN_UNION; EXISTS_OR_THM; SET_RULE
634    `UNIONS {x | P x \/ Q x} = UNIONS {x | P x} UNION UNIONS {x | Q x}`] THEN
635   CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
636   CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
637   REPEAT STRIP_TAC THENL
638    [ASM SET_TAC[]; ALL_TAC; ALL_TAC; ASM SET_TAC[]] THEN
639   MATCH_MP_TAC(SET_RULE
640    `!s' t'. s SUBSET s' /\ t SUBSET t' /\ s' INTER t' = {}
641             ==> s INTER t = {}`)
642   THENL
643    [MAP_EVERY EXISTS_TAC
644      [`interior s1:real^N->bool`; `interior s2:real^N->bool`];
645     MAP_EVERY EXISTS_TAC
646      [`interior s2:real^N->bool`; `interior s1:real^N->bool`]] THEN
647   REPEAT CONJ_TAC THEN TRY(MATCH_MP_TAC SUBSET_INTERIOR) THEN
648   ASM SET_TAC[]);;
649
650 let PARTIAL_DIVISION_EXTEND_1 = prove
651  (`!a b c d:real^N.
652         interval[c,d] SUBSET interval[a,b] /\ ~(interval[c,d] = {})
653         ==> ?p. p division_of interval[a,b] /\
654                 interval[c,d] IN p`,
655   REPEAT STRIP_TAC THEN ASM_CASES_TAC `interval[a:real^N,b] = {}` THENL
656    [ASM SET_TAC[]; ALL_TAC] THEN
657   REPEAT(FIRST_X_ASSUM(STRIP_ASSUME_TAC o
658     GEN_REWRITE_RULE I [INTERVAL_NE_EMPTY])) THEN
659   EXISTS_TAC
660    `{interval
661       [(lambda i. if i < l then (c:real^N)$i else (a:real^N)$i):real^N,
662        (lambda i. if i < l then d$i else if i = l then c$l else b$i)] |
663        l IN 1..(dimindex(:N)+1)} UNION
664     {interval
665       [(lambda i. if i < l then c$i else if i = l then d$l else a$i),
666        (lambda i. if i < l then (d:real^N)$i else (b:real^N)$i):real^N] |
667        l IN 1..(dimindex(:N)+1)}` THEN
668   MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
669    [REWRITE_TAC[IN_UNION] THEN DISJ1_TAC THEN
670     REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `dimindex(:N)+1` THEN
671     REWRITE_TAC[IN_NUMSEG; LE_REFL; ARITH_RULE `1 <= n + 1`] THEN
672     AP_TERM_TAC THEN SIMP_TAC[CONS_11; PAIR_EQ; CART_EQ; LAMBDA_BETA] THEN
673     SIMP_TAC[ARITH_RULE `i <= n ==> i < n + 1`];
674     DISCH_TAC] THEN
675   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET_INTERVAL]) THEN
676   ASM_REWRITE_TAC[DIVISION_OF] THEN DISCH_TAC THEN REPEAT CONJ_TAC THENL
677    [REWRITE_TAC[SIMPLE_IMAGE] THEN
678     SIMP_TAC[FINITE_UNION; FINITE_IMAGE; FINITE_NUMSEG];
679     REWRITE_TAC[IN_UNION; TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
680     REWRITE_TAC[SIMPLE_IMAGE; FORALL_AND_THM; FORALL_IN_IMAGE] THEN
681     ASM_SIMP_TAC[IN_NUMSEG; INTERVAL_NE_EMPTY; LAMBDA_BETA] THEN
682     CONJ_TAC THEN X_GEN_TAC `l:num` THEN DISCH_TAC THEN
683     (CONJ_TAC THENL [ALL_TAC; MESON_TAC[]]) THEN
684     REPEAT STRIP_TAC THEN
685     REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[]) THEN
686     ASM_MESON_TAC[REAL_LE_TRANS];
687     REWRITE_TAC[IN_UNION; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
688     REWRITE_TAC[SET_RULE
689       `(!y. y IN {f x | x IN s} \/ y IN {g x | x IN s} ==> P y) <=>
690        (!x. x IN s ==> P(f x) /\ P(g x))`] THEN
691     REWRITE_TAC[AND_FORALL_THM; IN_NUMSEG] THEN
692     REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN
693     REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
694     MATCH_MP_TAC WLOG_LE THEN CONJ_TAC THENL
695      [REPEAT GEN_TAC THEN
696       REWRITE_TAC[TAUT `a ==> b ==> c <=> b ==> a ==> c`] THEN
697       REWRITE_TAC[INTER_ACI; CONJ_ACI] THEN MESON_TAC[];
698       ALL_TAC] THEN
699     MAP_EVERY X_GEN_TAC [`l:num`; `m:num`] THEN
700     DISCH_TAC THEN STRIP_TAC THEN STRIP_TAC THEN
701     ONCE_REWRITE_TAC[TAUT `(~p ==> q) <=> (~q ==> p)`] THEN
702      REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN
703     REWRITE_TAC[SET_RULE `s INTER t = {} <=> !x. ~(x IN s /\ x IN t)`] THEN
704     ASM_SIMP_TAC[IN_NUMSEG; INTERVAL_NE_EMPTY; LAMBDA_BETA; IN_INTERVAL;
705                  INTERIOR_CLOSED_INTERVAL] THEN
706     REWRITE_TAC[AND_FORALL_THM] THEN
707     REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN
708     REWRITE_TAC[NOT_FORALL_THM] THEN REPEAT CONJ_TAC THEN
709     DISCH_THEN(X_CHOOSE_THEN `x:real^N` (LABEL_TAC "*")) THEN
710     AP_TERM_TAC THEN SIMP_TAC[CONS_11; PAIR_EQ; CART_EQ; LAMBDA_BETA] THENL
711      (let tac1 =
712         UNDISCH_TAC `l:num <= m` THEN GEN_REWRITE_TAC LAND_CONV [LE_LT] THEN
713         STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
714         REMOVE_THEN "*" (MP_TAC o SPEC `l:num`) THEN
715         ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
716         ASM_REWRITE_TAC[LT_REFL] THEN REAL_ARITH_TAC
717       and tac2 =
718         UNDISCH_TAC `l:num <= m` THEN GEN_REWRITE_TAC LAND_CONV [LE_LT] THEN
719         STRIP_TAC THEN ASM_REWRITE_TAC[] THENL
720          [REMOVE_THEN "*" (MP_TAC o SPEC `l:num`) THEN ANTS_TAC THENL
721            [ASM_ARITH_TAC; ALL_TAC] THEN
722           ASM_REWRITE_TAC[LT_REFL] THEN REAL_ARITH_TAC;
723           ALL_TAC] THEN
724         FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
725         CONJ_TAC THEN X_GEN_TAC `i:num` THEN ASM_CASES_TAC `i:num = l` THEN
726         ASM_REWRITE_TAC[LT_REFL] THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN
727         DISCH_TAC THEN REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `l:num`)) THEN
728         ASM_REWRITE_TAC[LT_REFL] THEN REAL_ARITH_TAC in
729       [tac1; tac2; tac2; tac1]);
730     MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
731      [REWRITE_TAC[IMP_CONJ; SUBSET; FORALL_IN_UNIONS; SIMPLE_IMAGE] THEN
732       REWRITE_TAC[IN_UNIONS; IN_INSERT; IN_UNION; FORALL_IN_IMAGE;
733         RIGHT_FORALL_IMP_THM; FORALL_AND_THM;
734         TAUT `(a \/ b ==> c) <=> (a ==> c) /\ (b ==> c)`] THEN
735       ASM_SIMP_TAC[IN_INTERVAL; IN_NUMSEG; LAMBDA_BETA] THEN
736       REPEAT CONJ_TAC THEN GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
737       MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
738       ASM_MESON_TAC[REAL_LE_TRANS];
739       ALL_TAC] THEN
740     FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
741      `a IN s ==> (c DIFF a) SUBSET UNIONS s ==> c SUBSET UNIONS s`)) THEN
742     REWRITE_TAC[SUBSET; IN_DIFF; IN_INTERVAL] THEN X_GEN_TAC `x:real^N` THEN
743     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
744     REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
745     GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN
746     REWRITE_TAC[TAUT `a ==> ~(b /\ ~c) <=> a /\ b ==> c`] THEN
747     DISCH_THEN(X_CHOOSE_THEN `l:num` STRIP_ASSUME_TAC) THEN
748     REWRITE_TAC[IN_UNIONS; SIMPLE_IMAGE; EXISTS_IN_IMAGE; IN_UNION;
749                 EXISTS_OR_THM; RIGHT_OR_DISTRIB] THEN
750     REWRITE_TAC[OR_EXISTS_THM] THEN EXISTS_TAC `l:num` THEN
751     ASM_SIMP_TAC[IN_NUMSEG; IN_INTERVAL; LAMBDA_BETA;
752                  ARITH_RULE `x <= n ==> x <= n + 1`] THEN
753     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DE_MORGAN_THM]) THEN
754     MATCH_MP_TAC MONO_OR THEN REWRITE_TAC[REAL_NOT_LE] THEN
755     REPEAT STRIP_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[]) THEN
756     ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_LE_TRANS]]);;
757
758 let PARTIAL_DIVISION_EXTEND_INTERVAL = prove
759  (`!p a b:real^N.
760         p division_of (UNIONS p) /\ (UNIONS p) SUBSET interval[a,b]
761         ==> ?q. p SUBSET q /\ q division_of interval[a,b]`,
762   REPEAT GEN_TAC THEN ASM_CASES_TAC `p:(real^N->bool)->bool = {}` THEN
763   ASM_REWRITE_TAC[EMPTY_SUBSET] THENL
764    [MESON_TAC[ELEMENTARY_INTERVAL]; STRIP_TAC] THEN
765   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
766   SUBGOAL_THEN `!k:real^N->bool. k IN p ==> ?q. q division_of interval[a,b] /\
767                                                 k IN q`
768   MP_TAC THENL
769    [X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
770     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
771     DISCH_THEN(MP_TAC o SPEC `k:real^N->bool` o el 1 o CONJUNCTS) THEN
772     ASM_REWRITE_TAC[] THEN STRIP_TAC THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN
773     MATCH_MP_TAC PARTIAL_DIVISION_EXTEND_1 THEN ASM SET_TAC[];
774     ALL_TAC] THEN
775   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
776   REWRITE_TAC[SKOLEM_THM] THEN
777   DISCH_THEN(X_CHOOSE_TAC `q:(real^N->bool)->(real^N->bool)->bool`) THEN
778   SUBGOAL_THEN
779    `?d. d division_of INTERS {UNIONS(q i DELETE i) | (i:real^N->bool) IN p}`
780   MP_TAC THENL
781    [MATCH_MP_TAC ELEMENTARY_INTERS THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
782     ASM_SIMP_TAC[IMAGE_EQ_EMPTY; FINITE_IMAGE] THEN
783     REWRITE_TAC[FORALL_IN_IMAGE] THEN X_GEN_TAC `k:real^N->bool` THEN
784     DISCH_TAC THEN EXISTS_TAC `(q k) DELETE (k:real^N->bool)` THEN
785     MATCH_MP_TAC DIVISION_OF_SUBSET THEN
786     EXISTS_TAC `(q:(real^N->bool)->(real^N->bool)->bool) k` THEN
787     REWRITE_TAC[DELETE_SUBSET] THEN ASM_MESON_TAC[division_of];
788     ALL_TAC] THEN
789   DISCH_THEN(X_CHOOSE_TAC `d:(real^N->bool)->bool`) THEN
790   EXISTS_TAC `(d UNION p):(real^N->bool)->bool` THEN
791   REWRITE_TAC[SUBSET_UNION] THEN
792   SUBGOAL_THEN `interval[a:real^N,b] =
793                 INTERS {UNIONS (q i DELETE i) | i IN p} UNION
794                 UNIONS p`
795   SUBST1_TAC THENL
796    [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN MATCH_MP_TAC(SET_RULE
797      `~(s = {}) /\
798       (!i. i IN s ==> f i UNION i = t)
799      ==> t = INTERS (IMAGE f s) UNION (UNIONS s)`) THEN
800     ASM_REWRITE_TAC[] THEN X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
801     MATCH_MP_TAC(SET_RULE
802      `UNIONS k = s /\ i IN k ==> UNIONS (k DELETE i) UNION i = s`) THEN
803     ASM_MESON_TAC[division_of];
804     ALL_TAC] THEN
805   MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN ASM_REWRITE_TAC[] THEN
806   MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
807   ASM_REWRITE_TAC[OPEN_INTERIOR] THEN
808   CONJ_TAC THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
809   X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
810   MATCH_MP_TAC(SET_RULE
811    `!s. u SUBSET s /\ s INTER t = {} ==> u INTER t = {}`) THEN
812   EXISTS_TAC `interior(UNIONS(q k DELETE (k:real^N->bool)))` THEN
813   CONJ_TAC THENL
814    [MATCH_MP_TAC SUBSET_INTERIOR THEN
815     MATCH_MP_TAC(SET_RULE `x IN s ==> INTERS s SUBSET x`) THEN ASM SET_TAC[];
816     ALL_TAC] THEN
817   ONCE_REWRITE_TAC[INTER_COMM] THEN
818   MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
819   REWRITE_TAC[OPEN_INTERIOR; FINITE_DELETE; IN_DELETE] THEN
820   ASM_MESON_TAC[division_of]);;
821
822 let ELEMENTARY_BOUNDED = prove
823  (`!s. (?p. p division_of s) ==> bounded s`,
824   REWRITE_TAC[division_of] THEN
825   ASM_MESON_TAC[BOUNDED_UNIONS; BOUNDED_INTERVAL]);;
826
827 let ELEMENTARY_SUBSET_INTERVAL = prove
828  (`!s. (?p. p division_of s) ==> ?a b. s SUBSET interval[a,b]`,
829   MESON_TAC[ELEMENTARY_BOUNDED; BOUNDED_SUBSET_CLOSED_INTERVAL]);;
830
831 let DIVISION_UNION_INTERVALS_EXISTS = prove
832  (`!a b c d:real^N.
833         ~(interval[a,b] = {})
834         ==> ?p. (interval[a,b] INSERT p) division_of
835                 (interval[a,b] UNION interval[c,d])`,
836   REPEAT STRIP_TAC THEN
837   ASM_CASES_TAC `interval[c:real^N,d] = {}` THENL
838    [ASM_REWRITE_TAC[UNION_EMPTY] THEN ASM_MESON_TAC[DIVISION_OF_SELF];
839     ALL_TAC] THEN
840   ASM_CASES_TAC `interval[a:real^N,b] INTER interval[c,d] = {}` THENL
841    [EXISTS_TAC `{interval[c:real^N,d]}` THEN
842     ONCE_REWRITE_TAC[SET_RULE `{a,b} = {a} UNION {b}`] THEN
843     MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN
844     ASM_SIMP_TAC[DIVISION_OF_SELF] THEN
845     MATCH_MP_TAC(SET_RULE
846      `interior s SUBSET s /\ interior t SUBSET t /\ s INTER t = {}
847       ==> interior s INTER interior t = {}`) THEN
848     ASM_REWRITE_TAC[INTERIOR_SUBSET];
849     ALL_TAC] THEN
850   SUBGOAL_THEN
851    `?u v:real^N. interval[a,b] INTER interval[c,d] = interval[u,v]`
852   STRIP_ASSUME_TAC THENL [MESON_TAC[INTER_INTERVAL]; ALL_TAC] THEN
853   MP_TAC(ISPECL [`c:real^N`; `d:real^N`; `u:real^N`; `v:real^N`]
854                 PARTIAL_DIVISION_EXTEND_1) THEN
855   ANTS_TAC THENL [ASM_MESON_TAC[INTER_SUBSET]; ALL_TAC] THEN
856   DISCH_THEN(X_CHOOSE_THEN `p:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
857   EXISTS_TAC `p DELETE interval[u:real^N,v]` THEN
858   SUBGOAL_THEN `interval[a:real^N,b] UNION interval[c,d] =
859                 interval[a,b] UNION UNIONS(p DELETE interval[u,v])`
860   SUBST1_TAC THENL
861    [FIRST_ASSUM(SUBST1_TAC o SYM o last o CONJUNCTS o
862                 GEN_REWRITE_RULE I [division_of]) THEN
863     ASM SET_TAC[];
864     ALL_TAC] THEN
865   ONCE_REWRITE_TAC[SET_RULE `x INSERT s = {x} UNION s`] THEN
866   MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN
867   ASM_SIMP_TAC[DIVISION_OF_SELF] THEN CONJ_TAC THENL
868    [MATCH_MP_TAC DIVISION_OF_SUBSET THEN
869     EXISTS_TAC `p:(real^N->bool)->bool` THEN
870     ASM_MESON_TAC[DIVISION_OF_UNION_SELF; DELETE_SUBSET];
871     ALL_TAC] THEN
872   REWRITE_TAC[GSYM INTERIOR_INTER] THEN
873   MATCH_MP_TAC EQ_TRANS THEN
874   EXISTS_TAC `interior(interval[u:real^N,v] INTER
875               UNIONS (p DELETE interval[u,v]))` THEN
876   CONJ_TAC THENL
877    [AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE
878      `!cd. p SUBSET cd /\ uv = ab INTER cd
879            ==> (ab INTER p = uv INTER p)`) THEN
880     EXISTS_TAC `interval[c:real^N,d]` THEN
881     ASM_REWRITE_TAC[UNIONS_SUBSET; IN_DELETE] THEN
882     ASM_MESON_TAC[division_of];
883     REWRITE_TAC[INTERIOR_INTER] THEN
884     MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
885     REWRITE_TAC[IN_DELETE; OPEN_INTERIOR; FINITE_DELETE] THEN
886     ASM_MESON_TAC[division_of]]);;
887
888 let DIVISION_OF_UNIONS = prove
889  (`!f. FINITE f /\
890        (!p. p IN f ==> p division_of (UNIONS p)) /\
891        (!k1 k2. k1 IN UNIONS f /\ k2 IN UNIONS f /\ ~(k1 = k2)
892                 ==> interior k1 INTER interior k2 = {})
893        ==> (UNIONS f) division_of UNIONS(UNIONS f)`,
894   REWRITE_TAC[division_of] THEN
895   SIMP_TAC[FINITE_UNIONS] THEN REWRITE_TAC[FORALL_IN_UNIONS] THEN
896   GEN_TAC THEN DISCH_THEN(MP_TAC o el 1 o CONJUNCTS) THEN
897   MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN SET_TAC[]);;
898
899 let ELEMENTARY_UNION_INTERVAL_STRONG = prove
900  (`!p a b:real^N.
901         p division_of (UNIONS p)
902         ==> ?q. p SUBSET q /\ q division_of (interval[a,b] UNION UNIONS p)`,
903   REPEAT STRIP_TAC THEN ASM_CASES_TAC `p:(real^N->bool)->bool = {}` THENL
904    [ASM_REWRITE_TAC[UNIONS_0; UNION_EMPTY; EMPTY_SUBSET] THEN
905     MESON_TAC[ELEMENTARY_INTERVAL];
906     ALL_TAC] THEN
907   ASM_CASES_TAC `interval[a:real^N,b] = {}` THEN
908   ASM_REWRITE_TAC[UNION_EMPTY] THENL [ASM_MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN
909   ASM_CASES_TAC `interior(interval[a:real^N,b]) = {}` THENL
910    [EXISTS_TAC `interval[a:real^N,b] INSERT p` THEN
911     REWRITE_TAC[division_of] THEN
912     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
913     SIMP_TAC[FINITE_INSERT; UNIONS_INSERT] THEN ASM SET_TAC[];
914     ALL_TAC] THEN
915   ASM_CASES_TAC `interval[a:real^N,b] SUBSET UNIONS p` THENL
916    [ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s UNION t = t`] THEN
917     ASM_MESON_TAC[SUBSET_REFL];
918     ALL_TAC] THEN
919   SUBGOAL_THEN
920    `!k:real^N->bool. k IN p
921                      ==> ?q. ~(k IN q) /\ ~(q = {}) /\
922                              (k INSERT q) division_of (interval[a,b] UNION k)`
923   MP_TAC THENL
924    [X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
925     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
926     DISCH_THEN(MP_TAC o SPEC `k:real^N->bool` o CONJUNCT1 o CONJUNCT2) THEN
927     ASM_REWRITE_TAC[] THEN
928     REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
929     REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
930     MAP_EVERY X_GEN_TAC [`c:real^N`; `d:real^N`] THEN
931     DISCH_THEN SUBST_ALL_TAC THEN
932     ONCE_REWRITE_TAC[UNION_COMM] THEN
933     MP_TAC(ISPECL [`c:real^N`; `d:real^N`; `a:real^N`; `b:real^N`]
934         DIVISION_UNION_INTERVALS_EXISTS) THEN
935     ASM_REWRITE_TAC[] THEN
936     DISCH_THEN(X_CHOOSE_TAC `q:(real^N->bool)->bool`) THEN
937     EXISTS_TAC `q DELETE interval[c:real^N,d]` THEN
938     ASM_REWRITE_TAC[IN_DELETE; SET_RULE
939      `x INSERT (q DELETE x) = x INSERT q`] THEN
940     DISCH_TAC THEN
941     UNDISCH_TAC `(interval[c:real^N,d] INSERT q) division_of
942                  (interval [c,d] UNION interval [a,b])` THEN
943     ASM_SIMP_TAC[SET_RULE `s DELETE x = {} ==> x INSERT s = {x}`] THEN
944     REWRITE_TAC[division_of; UNIONS_1] THEN ASM SET_TAC[];
945     ALL_TAC] THEN
946   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
947   REWRITE_TAC[SKOLEM_THM] THEN
948   DISCH_THEN(X_CHOOSE_TAC `q:(real^N->bool)->(real^N->bool)->bool`) THEN
949   MP_TAC(ISPEC `IMAGE (UNIONS o (q:(real^N->bool)->(real^N->bool)->bool)) p`
950     ELEMENTARY_INTERS) THEN
951   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
952   ASM_SIMP_TAC[FINITE_IMAGE; IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN
953   ANTS_TAC THENL
954    [X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
955     EXISTS_TAC `(q:(real^N->bool)->(real^N->bool)->bool) k` THEN
956     REWRITE_TAC[o_THM] THEN MATCH_MP_TAC DIVISION_OF_SUBSET THEN
957     EXISTS_TAC `(k:real^N->bool) INSERT q k` THEN
958     CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_UNION_SELF]; SET_TAC[]];
959     DISCH_THEN(X_CHOOSE_TAC `r:(real^N->bool)->bool`)] THEN
960   EXISTS_TAC `p UNION r:(real^N->bool)->bool` THEN SIMP_TAC[SUBSET_UNION] THEN
961   SUBGOAL_THEN
962    `interval[a:real^N,b] UNION UNIONS p =
963     UNIONS p UNION INTERS(IMAGE (UNIONS o q) p)`
964   SUBST1_TAC THENL
965    [GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `y:real^N` THEN
966     REWRITE_TAC[IN_UNION] THEN
967     ASM_CASES_TAC `(y:real^N) IN UNIONS p` THEN ASM_REWRITE_TAC[IN_INTERS] THEN
968     REWRITE_TAC[FORALL_IN_UNIONS; IMP_CONJ; FORALL_IN_IMAGE;
969                 RIGHT_FORALL_IMP_THM] THEN
970     SUBGOAL_THEN
971      `!k. k IN p ==> UNIONS(k INSERT q k) = interval[a:real^N,b] UNION k`
972     MP_TAC THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
973     REWRITE_TAC[UNIONS_INSERT; o_THM] THEN
974     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EXTENSION] THEN
975     REWRITE_TAC[RIGHT_IMP_FORALL_THM; IN_UNION] THEN
976     ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
977     DISCH_THEN(MP_TAC o SPEC `y:real^N`) THEN
978     UNDISCH_TAC `~((y:real^N) IN UNIONS p)` THEN
979     SIMP_TAC[IN_UNIONS; NOT_EXISTS_THM; TAUT `~(a /\ b) <=> a ==> ~b`] THEN
980     ASM_CASES_TAC `(y:real^N) IN interval[a,b]` THEN
981     ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
982     ALL_TAC] THEN
983   MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN
984   ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[INTER_COMM] THEN
985   MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
986   ASM_REWRITE_TAC[OPEN_INTERIOR] THEN
987   CONJ_TAC THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
988   X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
989   ASM_SIMP_TAC[INTERIOR_FINITE_INTERS; FINITE_IMAGE] THEN
990   MATCH_MP_TAC(SET_RULE `(?x. x IN p /\ f x INTER s = {})
991                         ==> INTERS (IMAGE f p) INTER s = {}`) THEN
992   REWRITE_TAC[EXISTS_IN_IMAGE; o_THM] THEN EXISTS_TAC `k:real^N->bool` THEN
993   ASM_REWRITE_TAC[] THEN
994   ONCE_REWRITE_TAC[INTER_COMM] THEN
995   MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
996   ASM_REWRITE_TAC[OPEN_INTERIOR] THEN REPEAT CONJ_TAC THENL
997    [ASM_MESON_TAC[division_of; FINITE_INSERT; IN_INSERT];
998     ASM_MESON_TAC[division_of; FINITE_INSERT; IN_INSERT];
999     ALL_TAC] THEN
1000   FIRST_X_ASSUM(MP_TAC o SPEC `k:real^N->bool`) THEN
1001   ASM_REWRITE_TAC[division_of; IN_INSERT] THEN
1002   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]);;
1003
1004 let ELEMENTARY_UNION_INTERVAL = prove
1005  (`!p a b:real^N.
1006         p division_of (UNIONS p)
1007         ==> ?q. q division_of (interval[a,b] UNION UNIONS p)`,
1008   MESON_TAC[ELEMENTARY_UNION_INTERVAL_STRONG]);;
1009
1010 let ELEMENTARY_UNIONS_INTERVALS = prove
1011  (`!f. FINITE f /\
1012        (!s. s IN f ==> ?a b:real^N. s = interval[a,b])
1013        ==> (?p. p division_of (UNIONS f))`,
1014   REWRITE_TAC[IMP_CONJ] THEN
1015   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1016   REWRITE_TAC[UNIONS_0; UNIONS_INSERT; ELEMENTARY_EMPTY] THEN
1017   REWRITE_TAC[IN_INSERT; TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
1018   SIMP_TAC[FORALL_AND_THM; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
1019   REPEAT GEN_TAC THEN DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
1020   ASM_REWRITE_TAC[] THEN
1021   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
1022   DISCH_THEN(X_CHOOSE_TAC `p:(real^N->bool)->bool`) THEN
1023   SUBGOAL_THEN `UNIONS f:real^N->bool = UNIONS p` SUBST1_TAC THENL
1024    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
1025   MATCH_MP_TAC ELEMENTARY_UNION_INTERVAL THEN ASM_MESON_TAC[division_of]);;
1026
1027 let ELEMENTARY_UNION = prove
1028  (`!s t:real^N->bool.
1029         (?p. p division_of s) /\ (?p. p division_of t)
1030         ==> (?p. p division_of (s UNION t))`,
1031   REPEAT GEN_TAC THEN DISCH_THEN
1032    (CONJUNCTS_THEN2 (X_CHOOSE_TAC `p1:(real^N->bool)->bool`)
1033                     (X_CHOOSE_TAC `p2:(real^N->bool)->bool`)) THEN
1034   SUBGOAL_THEN `s UNION t :real^N->bool = UNIONS p1 UNION UNIONS p2`
1035   SUBST1_TAC THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
1036   REWRITE_TAC[SET_RULE `UNIONS p1 UNION UNIONS p2 = UNIONS(p1 UNION p2)`] THEN
1037   MATCH_MP_TAC ELEMENTARY_UNIONS_INTERVALS THEN
1038   REWRITE_TAC[IN_UNION; FINITE_UNION] THEN
1039   ASM_MESON_TAC[division_of]);;
1040
1041 let PARTIAL_DIVISION_EXTEND = prove
1042  (`!p q s t:real^N->bool.
1043         p division_of s /\ q division_of t /\ s SUBSET t
1044         ==> ?r. p SUBSET r /\ r division_of t`,
1045   REPEAT STRIP_TAC THEN
1046   SUBGOAL_THEN `?a b:real^N. t SUBSET interval[a,b]` MP_TAC THENL
1047    [ASM_MESON_TAC[ELEMENTARY_SUBSET_INTERVAL]; ALL_TAC] THEN
1048   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
1049   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN
1050   SUBGOAL_THEN `?r1. p SUBSET r1 /\ r1 division_of interval[a:real^N,b]`
1051   STRIP_ASSUME_TAC THENL
1052    [MATCH_MP_TAC PARTIAL_DIVISION_EXTEND_INTERVAL THEN
1053     ASM_MESON_TAC[division_of; SUBSET_TRANS];
1054     ALL_TAC] THEN
1055   SUBGOAL_THEN
1056    `?r2:(real^N->bool)->bool.
1057         r2 division_of (UNIONS(r1 DIFF p)) INTER (UNIONS q)`
1058   STRIP_ASSUME_TAC THENL
1059    [MATCH_MP_TAC ELEMENTARY_INTER THEN
1060     ASM_MESON_TAC[FINITE_DIFF; IN_DIFF; division_of;
1061                   ELEMENTARY_UNIONS_INTERVALS];
1062     ALL_TAC] THEN
1063   EXISTS_TAC `p UNION r2:(real^N->bool)->bool` THEN
1064   CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
1065   SUBGOAL_THEN
1066    `t:real^N->bool = UNIONS p UNION (UNIONS(r1 DIFF p) INTER UNIONS q)`
1067   SUBST1_TAC THENL
1068    [REPEAT(FIRST_X_ASSUM(MP_TAC o last o CONJUNCTS o
1069                 GEN_REWRITE_RULE I [division_of])) THEN
1070     REPEAT(POP_ASSUM MP_TAC) THEN SET_TAC[];
1071     MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN ASM_REWRITE_TAC[] THEN
1072     CONJ_TAC THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
1073     MATCH_MP_TAC(SET_RULE
1074      `!t'. t SUBSET t' /\ s INTER t' = {} ==> s INTER t = {}`) THEN
1075     EXISTS_TAC `interior(UNIONS(r1 DIFF p)):real^N->bool` THEN
1076     CONJ_TAC THENL [MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]; ALL_TAC] THEN
1077     REPEAT(MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
1078            REWRITE_TAC[OPEN_INTERIOR] THEN
1079            REPEAT(CONJ_TAC THENL
1080             [ASM_MESON_TAC[IN_DIFF; FINITE_DIFF; division_of]; ALL_TAC]) THEN
1081            REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC THEN
1082            ONCE_REWRITE_TAC[INTER_COMM]) THEN
1083     ASM_MESON_TAC[division_of; SUBSET]]);;
1084
1085 let INTERVAL_SUBDIVISION = prove
1086  (`!a b c:real^N.
1087         c IN interval[a,b]
1088         ==> IMAGE (\s. interval[(lambda i. if i IN s then c$i else a$i),
1089                                 (lambda i. if i IN s then b$i else c$i)])
1090                   {s | s SUBSET 1..dimindex(:N)}
1091             division_of interval[a,b]`,
1092   REPEAT STRIP_TAC THEN
1093   FIRST_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I [IN_INTERVAL]) THEN
1094   REWRITE_TAC[DIVISION_OF] THEN
1095   SIMP_TAC[FINITE_IMAGE; FINITE_POWERSET; FINITE_NUMSEG] THEN
1096   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
1097   REWRITE_TAC[FORALL_IN_GSPEC; SUBSET_INTERVAL; INTERVAL_NE_EMPTY] THEN
1098   REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN REPEAT CONJ_TAC THENL
1099    [SIMP_TAC[LAMBDA_BETA] THEN ASM_MESON_TAC[REAL_LE_TRANS];
1100     X_GEN_TAC `s:num->bool` THEN DISCH_TAC THEN
1101     X_GEN_TAC `s':num->bool` THEN DISCH_TAC THEN
1102     REWRITE_TAC[SET_RULE
1103      `(~p ==> s INTER t = {}) <=> (!x. x IN s /\ x IN t ==> p)`] THEN
1104     X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_INTERVAL; AND_FORALL_THM] THEN
1105     REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN
1106     SIMP_TAC[LAMBDA_BETA] THEN
1107     ASM_CASES_TAC `s':num->bool = s` THEN ASM_REWRITE_TAC[] THEN
1108     FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE
1109      `~(s' = s) ==> ?x. x IN s' /\ ~(x IN s) \/ x IN s /\ ~(x IN s')`)) THEN
1110     DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN
1111     DISCH_THEN(MP_TAC o SPEC `k:num`) THEN ASM_REWRITE_TAC[] THEN
1112     (ANTS_TAC THENL [ASM_MESON_TAC[SUBSET; IN_NUMSEG]; REAL_ARITH_TAC]);
1113     MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN
1114     GEN_REWRITE_TAC I [SUBSET] THENL
1115      [REWRITE_TAC[FORALL_IN_UNIONS] THEN ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
1116       REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN
1117       ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
1118       REWRITE_TAC[RIGHT_FORALL_IMP_THM; GSYM SUBSET] THEN
1119       SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN
1120       ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL];
1121       X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
1122       REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE; EXISTS_IN_GSPEC] THEN EXISTS_TAC
1123        `{i | i IN 1..dimindex(:N) /\ (c:real^N)$i <= (x:real^N)$i}` THEN
1124       CONJ_TAC THENL [SET_TAC[]; REWRITE_TAC[IN_INTERVAL]] THEN
1125       SIMP_TAC[LAMBDA_BETA; IN_ELIM_THM; IN_NUMSEG] THEN
1126       RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN
1127       ASM_MESON_TAC[REAL_LE_TOTAL]]]);;
1128
1129 let DIVISION_OF_NONTRIVIAL = prove
1130  (`!s a b:real^N.
1131         s division_of interval[a,b] /\ ~(content(interval[a,b]) = &0)
1132         ==> {k | k IN s /\ ~(content k = &0)} division_of interval[a,b]`,
1133   REPEAT GEN_TAC THEN WF_INDUCT_TAC `CARD(s:(real^N->bool)->bool)` THEN
1134   REPEAT STRIP_TAC THEN
1135   ASM_CASES_TAC `{k:real^N->bool | k IN s /\ ~(content k = &0)} = s` THEN
1136   ASM_REWRITE_TAC[] THEN
1137   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [EXTENSION]) THEN
1138   REWRITE_TAC[IN_ELIM_THM; NOT_FORALL_THM; LEFT_IMP_EXISTS_THM] THEN
1139   REWRITE_TAC[TAUT `~(a /\ ~b <=> a) <=> a /\ b`] THEN
1140   X_GEN_TAC `k:real^N->bool` THEN STRIP_TAC THEN
1141   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
1142   FIRST_X_ASSUM(MP_TAC o SPEC `s DELETE (k:real^N->bool)`) THEN
1143   ASM_SIMP_TAC[CARD_DELETE; ARITH_RULE `n - 1 < n <=> ~(n = 0)`] THEN
1144   ASM_SIMP_TAC[CARD_EQ_0] THEN ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
1145   ANTS_TAC THENL
1146    [ALL_TAC;
1147     MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
1148     ASM SET_TAC[]] THEN
1149   REWRITE_TAC[DIVISION_OF] THEN
1150   FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [division_of]) THEN
1151   ASM_SIMP_TAC[FINITE_DELETE; IN_DELETE] THEN
1152   FIRST_ASSUM(MP_TAC o C MATCH_MP (ASSUME `(k:real^N->bool) IN s`)) THEN
1153   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
1154   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
1155   MAP_EVERY X_GEN_TAC [`c:real^N`; `d:real^N`] THEN
1156   DISCH_THEN SUBST_ALL_TAC THEN
1157   MATCH_MP_TAC(SET_RULE
1158     `UNIONS s = i /\ k SUBSET UNIONS(s DELETE k)
1159      ==> UNIONS(s DELETE k) = i`) THEN
1160   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(MESON[CLOSED_LIMPT; SUBSET]
1161    `closed s /\ (!x. x IN k ==> x limit_point_of s) ==> k SUBSET s`) THEN
1162   CONJ_TAC THENL
1163    [MATCH_MP_TAC CLOSED_UNIONS THEN
1164     ASM_REWRITE_TAC[FINITE_DELETE; IN_DELETE] THEN
1165     ASM_MESON_TAC[CLOSED_INTERVAL];
1166     ALL_TAC] THEN
1167   X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
1168   X_GEN_TAC `e:real` THEN DISCH_TAC THEN REWRITE_TAC[dist] THEN
1169   SUBGOAL_THEN `?y:real^N. y IN UNIONS s /\ ~(y IN interval[c,d]) /\
1170                            ~(y = x) /\ norm(y - x) < e`
1171   MP_TAC THENL [ALL_TAC; SET_TAC[]] THEN ASM_REWRITE_TAC[] THEN
1172   MAP_EVERY UNDISCH_TAC
1173    [`~(content(interval[a:real^N,b]) = &0)`;
1174     `content(interval[c:real^N,d]) = &0`] THEN
1175   REWRITE_TAC[CONTENT_EQ_0; NOT_EXISTS_THM] THEN
1176   DISCH_THEN(X_CHOOSE_THEN `i:num` STRIP_ASSUME_TAC) THEN
1177   DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[REAL_NOT_LE] THEN
1178   DISCH_TAC THEN UNDISCH_TAC `~(interval[c:real^N,d] = {})` THEN
1179   REWRITE_TAC[INTERVAL_EQ_EMPTY; NOT_EXISTS_THM] THEN
1180   DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[REAL_NOT_LT] THEN
1181   ASM_SIMP_TAC[REAL_ARITH `a <= b ==> (b <= a <=> a = b)`] THEN
1182   DISCH_THEN(fun th -> SUBST_ALL_TAC th THEN ASSUME_TAC th) THEN
1183   UNDISCH_TAC `interval[c:real^N,d] SUBSET interval[a,b]` THEN
1184   REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
1185   ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
1186   MP_TAC(ASSUME `(x:real^N) IN interval[c,d]`) THEN
1187   GEN_REWRITE_TAC LAND_CONV [IN_INTERVAL] THEN
1188   DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
1189   ASM_SIMP_TAC[REAL_ARITH `d = c ==> (c <= x /\ x <= d <=> x = c)`] THEN
1190   DISCH_TAC THEN
1191   MP_TAC(ASSUME `(x:real^N) IN interval[a,b]`) THEN
1192   GEN_REWRITE_TAC LAND_CONV [IN_INTERVAL] THEN
1193   DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
1194   STRIP_TAC THEN EXISTS_TAC
1195    `(lambda j. if j = i then
1196                  if (c:real^N)$i <= ((a:real^N)$i + (b:real^N)$i) / &2
1197                  then c$i + min e (b$i - c$i) / &2
1198                  else c$i - min e (c$i - a$i) / &2
1199                else (x:real^N)$j):real^N` THEN
1200   SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; CART_EQ] THEN REPEAT CONJ_TAC THENL
1201    [X_GEN_TAC `j:num` THEN STRIP_TAC THEN
1202     UNDISCH_TAC `(x:real^N) IN interval[a,b]` THEN
1203     REWRITE_TAC[IN_INTERVAL] THEN DISCH_THEN(MP_TAC o SPEC `j:num`) THEN
1204     ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN REWRITE_TAC[] THEN
1205     FIRST_X_ASSUM SUBST_ALL_TAC THEN
1206     ASM_REAL_ARITH_TAC;
1207     DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
1208     ASM_REAL_ARITH_TAC;
1209     DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
1210     ASM_REAL_ARITH_TAC;
1211     REWRITE_TAC[vector_norm; dot] THEN
1212     SIMP_TAC[LAMBDA_BETA; VECTOR_SUB_COMPONENT; GSYM REAL_POW_2] THEN
1213     REWRITE_TAC[REAL_ARITH
1214      `((if p then x else y) - y) pow 2 = if p then (x - y) pow 2 else &0`] THEN
1215     ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG; POW_2_SQRT_ABS] THEN
1216     ASM_REAL_ARITH_TAC]);;
1217
1218 let DIVISION_OF_AFFINITY = prove
1219  (`!d s:real^N->bool m c.
1220     IMAGE (IMAGE (\x. m % x + c)) d division_of (IMAGE (\x. m % x + c) s) <=>
1221     if m = &0 then if s = {} then d = {}
1222                    else ~(d = {}) /\ !k. k IN d ==> ~(k = {})
1223     else d division_of s`,
1224   REPEAT GEN_TAC THEN ASM_CASES_TAC `m = &0` THEN ASM_REWRITE_TAC[] THENL
1225    [ASM_CASES_TAC `s:real^N->bool = {}` THEN
1226     ASM_REWRITE_TAC[IMAGE_CLAUSES; DIVISION_OF_TRIVIAL; IMAGE_EQ_EMPTY] THEN
1227     ASM_CASES_TAC `d:(real^N->bool)->bool = {}` THEN
1228     ASM_REWRITE_TAC[IMAGE_CLAUSES; EMPTY_DIVISION_OF; UNIONS_0;
1229                     IMAGE_EQ_EMPTY] THEN
1230     REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN
1231     ASM_SIMP_TAC[SET_RULE `~(s = {}) ==> IMAGE (\x. c) s = {c}`] THEN
1232     ASM_CASES_TAC `!k:real^N->bool. k IN d ==> ~(k = {})` THEN
1233     ASM_REWRITE_TAC[division_of] THENL
1234      [ALL_TAC;
1235       REWRITE_TAC[FORALL_IN_IMAGE] THEN ASM_MESON_TAC[IMAGE_EQ_EMPTY]] THEN
1236     SUBGOAL_THEN
1237      `IMAGE (IMAGE ((\x. c):real^N->real^N)) d = {{c}}`
1238     SUBST1_TAC THENL
1239      [GEN_REWRITE_TAC I [EXTENSION] THEN
1240       REWRITE_TAC[IN_IMAGE; IN_SING] THEN ASM SET_TAC[];
1241       SIMP_TAC[UNIONS_1; FINITE_SING; IN_SING; IMP_CONJ] THEN
1242       REWRITE_TAC[SUBSET_REFL; NOT_INSERT_EMPTY] THEN
1243       MESON_TAC[INTERVAL_SING]];
1244     REWRITE_TAC[division_of] THEN
1245     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
1246     REWRITE_TAC[IMAGE_EQ_EMPTY; GSYM INTERIOR_INTER] THEN
1247     ASM_SIMP_TAC[FINITE_IMAGE_INJ_EQ; GSYM IMAGE_UNIONS;
1248          VECTOR_ARITH `x + a:real^N = y + a <=> x = y`;
1249              VECTOR_MUL_LCANCEL;
1250      SET_RULE `(!x y. f x = f y <=> x = y)
1251                ==> (IMAGE f s SUBSET IMAGE f t <=> s SUBSET t) /\
1252                    (IMAGE f s = IMAGE f t <=> s = t) /\
1253                    (IMAGE f s INTER IMAGE f t = IMAGE f (s INTER t))`] THEN
1254     AP_TERM_TAC THEN BINOP_TAC THENL
1255      [AP_TERM_TAC THEN ABS_TAC THEN REPLICATE_TAC 3 AP_TERM_TAC THEN
1256       EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
1257       MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN
1258       ASM_SIMP_TAC[IMAGE_AFFINITY_INTERVAL] THENL [ALL_TAC; MESON_TAC[]] THEN
1259       FIRST_X_ASSUM(MP_TAC o AP_TERM
1260        `IMAGE (\x:real^N. inv m % x + --(inv m % c))`) THEN
1261       ASM_SIMP_TAC[GSYM IMAGE_o; AFFINITY_INVERSES] THEN
1262       ASM_REWRITE_TAC[IMAGE_I; IMAGE_AFFINITY_INTERVAL] THEN MESON_TAC[];
1263       SUBGOAL_THEN `(\x:real^N. m % x + c) = (\x. c + x) o (\x. m % x)`
1264       SUBST1_TAC THENL
1265        [REWRITE_TAC[FUN_EQ_THM; o_THM] THEN VECTOR_ARITH_TAC;
1266         REWRITE_TAC[IMAGE_o; INTERIOR_TRANSLATION] THEN
1267         ASM_SIMP_TAC[INTERIOR_INJECTIVE_LINEAR_IMAGE; LINEAR_SCALING;
1268                      VECTOR_MUL_LCANCEL; IMAGE_EQ_EMPTY]]]]);;
1269
1270 let DIVISION_OF_TRANSLATION = prove
1271  (`!d s:real^N->bool.
1272         IMAGE (IMAGE (\x. a + x)) d division_of (IMAGE (\x. a + x) s) <=>
1273         d division_of s`,
1274   ONCE_REWRITE_TAC[VECTOR_ARITH `a + x:real^N = &1 % x + a`] THEN
1275   REWRITE_TAC[DIVISION_OF_AFFINITY] THEN CONV_TAC REAL_RAT_REDUCE_CONV);;
1276
1277 let DIVISION_OF_REFLECT = prove
1278  (`!d s:real^N->bool.
1279         IMAGE (IMAGE (--)) d division_of IMAGE (--) s <=>
1280         d division_of s`,
1281   REPEAT GEN_TAC THEN SUBGOAL_THEN `(--) = \x:real^N. --(&1) % x + vec 0`
1282   SUBST1_TAC THENL
1283   [REWRITE_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC;
1284    REWRITE_TAC[DIVISION_OF_AFFINITY] THEN CONV_TAC REAL_RAT_REDUCE_CONV]);;
1285
1286 let ELEMENTARY_COMPACT = prove
1287  (`!s. (?d. d division_of s) ==> compact s`,
1288   REWRITE_TAC[division_of] THEN
1289   MESON_TAC[COMPACT_UNIONS; COMPACT_INTERVAL]);;
1290
1291 let OPEN_COUNTABLE_LIMIT_ELEMENTARY = prove
1292  (`!s:real^N->bool.
1293         open s
1294         ==> ?f. (!n. ?d. d division_of f n) /\
1295                 (!n. f n SUBSET f(SUC n)) /\
1296                 UNIONS {f n | n IN (:num)} = s`,
1297   REPEAT STRIP_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THENL
1298    [EXISTS_TAC `(\n. {}):num->real^N->bool` THEN
1299     REWRITE_TAC[ELEMENTARY_EMPTY; EMPTY_SUBSET; UNIONS_GSPEC] THEN
1300     ASM SET_TAC[];
1301     FIRST_ASSUM(MP_TAC o MATCH_MP OPEN_COUNTABLE_UNION_CLOSED_INTERVALS) THEN
1302     DISCH_THEN(X_CHOOSE_THEN `D:(real^N->bool)->bool` MP_TAC) THEN
1303     ASM_CASES_TAC `D:(real^N->bool)->bool = {}` THEN
1304     ASM_REWRITE_TAC[UNIONS_0] THEN
1305     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)] THEN
1306   MP_TAC(ISPEC `D:(real^N->bool)->bool` COUNTABLE_AS_IMAGE) THEN
1307   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
1308   X_GEN_TAC `f:num->real^N->bool` THEN DISCH_THEN SUBST1_TAC THEN
1309   REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN STRIP_TAC THEN
1310   EXISTS_TAC `\n. UNIONS {(f:num->real^N->bool) m | m <= n}` THEN
1311   REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
1312    [GEN_TAC THEN MATCH_MP_TAC ELEMENTARY_UNIONS_INTERVALS THEN
1313     ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
1314     SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG_LE] THEN ASM SET_TAC[];
1315     GEN_TAC THEN MATCH_MP_TAC SUBSET_UNIONS THEN
1316     ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN MATCH_MP_TAC IMAGE_SUBSET THEN
1317     REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ARITH_TAC;
1318     FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
1319     REWRITE_TAC[UNIONS_GSPEC; UNIONS_IMAGE] THEN
1320     REWRITE_TAC[IN_ELIM_THM; IN_UNIV; EXTENSION] THEN
1321     MESON_TAC[LE_REFL]]);;
1322
1323 (* ------------------------------------------------------------------------- *)
1324 (* Tagged (partial) divisions.                                               *)
1325 (* ------------------------------------------------------------------------- *)
1326
1327 parse_as_infix("tagged_partial_division_of",(12,"right"));;
1328 parse_as_infix("tagged_division_of",(12,"right"));;
1329
1330 let tagged_partial_division_of = new_definition
1331   `s tagged_partial_division_of i <=>
1332         FINITE s /\
1333         (!x k. (x,k) IN s
1334                ==> x IN k /\ k SUBSET i /\ ?a b. k = interval[a,b]) /\
1335         (!x1 k1 x2 k2. (x1,k1) IN s /\ (x2,k2) IN s /\ ~((x1,k1) = (x2,k2))
1336                        ==> (interior(k1) INTER interior(k2) = {}))`;;
1337
1338 let tagged_division_of = new_definition
1339   `s tagged_division_of i <=>
1340         s tagged_partial_division_of i /\ (UNIONS {k | ?x. (x,k) IN s} = i)`;;
1341
1342 let TAGGED_DIVISION_OF_FINITE = prove
1343  (`!s i. s tagged_division_of i ==> FINITE s`,
1344   SIMP_TAC[tagged_division_of; tagged_partial_division_of]);;
1345
1346 let TAGGED_DIVISION_OF = prove
1347  (`s tagged_division_of i <=>
1348         FINITE s /\
1349         (!x k. (x,k) IN s
1350                ==> x IN k /\ k SUBSET i /\ ?a b. k = interval[a,b]) /\
1351         (!x1 k1 x2 k2. (x1,k1) IN s /\ (x2,k2) IN s /\ ~((x1,k1) = (x2,k2))
1352                        ==> (interior(k1) INTER interior(k2) = {})) /\
1353         (UNIONS {k | ?x. (x,k) IN s} = i)`,
1354   REWRITE_TAC[tagged_division_of; tagged_partial_division_of; CONJ_ASSOC]);;
1355
1356 let DIVISION_OF_TAGGED_DIVISION = prove
1357  (`!s i. s tagged_division_of i ==> (IMAGE SND s) division_of i`,
1358   REWRITE_TAC[TAGGED_DIVISION_OF; division_of] THEN
1359   ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE; FORALL_PAIR_THM; PAIR_EQ] THEN
1360   REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM] THEN
1361   REPEAT GEN_TAC THEN STRIP_TAC THEN REPEAT CONJ_TAC THENL
1362    [ASM_MESON_TAC[MEMBER_NOT_EMPTY];
1363     REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1364     FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[];
1365     FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
1366     REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; IN_UNIONS] THEN
1367     REWRITE_TAC[FORALL_PAIR_THM; EXISTS_PAIR_THM] THEN MESON_TAC[]]);;
1368
1369 let PARTIAL_DIVISION_OF_TAGGED_DIVISION = prove
1370  (`!s i. s tagged_partial_division_of i
1371          ==> (IMAGE SND s) division_of UNIONS(IMAGE SND s)`,
1372   REWRITE_TAC[tagged_partial_division_of; division_of] THEN
1373   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
1374   REWRITE_TAC[FORALL_PAIR_THM; PAIR_EQ; DE_MORGAN_THM] THEN
1375   GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN REPEAT DISCH_TAC THEN
1376   REPEAT CONJ_TAC THENL
1377    [ASM_MESON_TAC[FINITE_IMAGE];
1378     ALL_TAC;
1379     ASM_MESON_TAC[]] THEN
1380   REPEAT GEN_TAC THEN STRIP_TAC THEN CONJ_TAC THENL
1381    [ALL_TAC; ASM_MESON_TAC[MEMBER_NOT_EMPTY]] THEN
1382   REWRITE_TAC[SUBSET; IN_UNIONS; IN_IMAGE; EXISTS_PAIR_THM] THEN
1383   CONV_TAC(ONCE_DEPTH_CONV UNWIND_CONV) THEN ASM SET_TAC[]);;
1384
1385 let TAGGED_PARTIAL_DIVISION_SUBSET = prove
1386  (`!s t i. s tagged_partial_division_of i /\ t SUBSET s
1387            ==> t tagged_partial_division_of i`,
1388   REWRITE_TAC[tagged_partial_division_of] THEN
1389   MESON_TAC[FINITE_SUBSET; SUBSET]);;
1390
1391 let VSUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA = prove
1392  (`!d:(real^M->bool)->real^N p i.
1393         p tagged_partial_division_of i /\
1394         (!u v. ~(interval[u,v] = {}) /\ content(interval[u,v]) = &0
1395                ==> d(interval[u,v]) = vec 0)
1396         ==> vsum p (\(x,k). d k) = vsum (IMAGE SND p) d`,
1397   REWRITE_TAC[CONTENT_EQ_0_INTERIOR] THEN REPEAT STRIP_TAC THEN
1398   SUBGOAL_THEN `(\(x:real^M,k:real^M->bool). d k:real^N) = d o SND`
1399   SUBST1_TAC THENL [SIMP_TAC[FUN_EQ_THM; FORALL_PAIR_THM; o_THM]; ALL_TAC] THEN
1400   CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_IMAGE_NONZERO THEN
1401   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [tagged_partial_division_of]) THEN
1402   MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
1403   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
1404   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
1405   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:real^M->bool` THEN
1406   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `y:real^M` THEN
1407   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k':real^M->bool` THEN
1408   ASM_CASES_TAC `k':real^M->bool = k` THEN
1409   ASM_REWRITE_TAC[PAIR_EQ; INTER_ACI] THEN
1410   RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN
1411   ASM_MESON_TAC[]);;
1412
1413 let VSUM_OVER_TAGGED_DIVISION_LEMMA = prove
1414  (`!d:(real^M->bool)->real^N p i.
1415         p tagged_division_of i /\
1416         (!u v. ~(interval[u,v] = {}) /\ content(interval[u,v]) = &0
1417                ==> d(interval[u,v]) = vec 0)
1418         ==> vsum p (\(x,k). d k) = vsum (IMAGE SND p) d`,
1419   REWRITE_TAC[tagged_division_of] THEN REPEAT STRIP_TAC THEN
1420   MATCH_MP_TAC VSUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA THEN
1421   EXISTS_TAC `i:real^M->bool` THEN ASM_REWRITE_TAC[]);;
1422
1423 let SUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA = prove
1424  (`!d:(real^N->bool)->real p i.
1425         p tagged_partial_division_of i /\
1426         (!u v. ~(interval[u,v] = {}) /\ content(interval[u,v]) = &0
1427                ==> d(interval[u,v]) = &0)
1428         ==> sum p (\(x,k). d k) = sum (IMAGE SND p) d`,
1429   REPEAT STRIP_TAC THEN
1430   FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o
1431     REWRITE_RULE[tagged_partial_division_of]) THEN
1432   ONCE_REWRITE_TAC[GSYM LIFT_EQ] THEN
1433   ASM_SIMP_TAC[LIFT_SUM; FINITE_IMAGE; o_DEF; LAMBDA_PAIR_THM] THEN
1434   MATCH_MP_TAC VSUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA THEN
1435   ASM_SIMP_TAC[GSYM DROP_EQ; DROP_VEC; LIFT_DROP] THEN ASM_MESON_TAC[]);;
1436
1437 let SUM_OVER_TAGGED_DIVISION_LEMMA = prove
1438  (`!d:(real^N->bool)->real p i.
1439         p tagged_division_of i /\
1440         (!u v. ~(interval[u,v] = {}) /\ content(interval[u,v]) = &0
1441                ==> d(interval[u,v]) = &0)
1442         ==> sum p (\(x,k). d k) = sum (IMAGE SND p) d`,
1443   REWRITE_TAC[tagged_division_of] THEN REPEAT STRIP_TAC THEN
1444   MATCH_MP_TAC SUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA THEN
1445   EXISTS_TAC `i:real^N->bool` THEN ASM_REWRITE_TAC[]);;
1446
1447 let TAG_IN_INTERVAL = prove
1448  (`!p i k. p tagged_division_of i /\ (x,k) IN p ==> x IN i`,
1449   REWRITE_TAC[TAGGED_DIVISION_OF] THEN SET_TAC[]);;
1450
1451 let TAGGED_DIVISION_OF_EMPTY = prove
1452  (`{} tagged_division_of {}`,
1453   REWRITE_TAC[tagged_division_of; tagged_partial_division_of] THEN
1454   REWRITE_TAC[FINITE_RULES; EXTENSION; NOT_IN_EMPTY; IN_UNIONS; IN_ELIM_THM]);;
1455
1456 let TAGGED_PARTIAL_DIVISION_OF_TRIVIAL = prove
1457  (`!p. p tagged_partial_division_of {} <=> p = {}`,
1458   REWRITE_TAC[tagged_partial_division_of; SUBSET_EMPTY; CONJ_ASSOC] THEN
1459   REWRITE_TAC[SET_RULE `x IN k /\ k = {} <=> F`] THEN
1460   REWRITE_TAC[GSYM FORALL_PAIR_THM; GSYM NOT_EXISTS_THM; MEMBER_NOT_EMPTY] THEN
1461   REWRITE_TAC[AC CONJ_ACI `(a /\ b) /\ c <=> b /\ a /\ c`] THEN
1462   GEN_TAC THEN MATCH_MP_TAC(TAUT `(a ==> b) ==> (a /\ b <=> a)`) THEN
1463   DISCH_THEN SUBST1_TAC THEN
1464   REWRITE_TAC[FINITE_RULES; UNIONS_0; NOT_IN_EMPTY]);;
1465
1466 let TAGGED_DIVISION_OF_TRIVIAL = prove
1467  (`!p. p tagged_division_of {} <=> p = {}`,
1468   REWRITE_TAC[tagged_division_of; TAGGED_PARTIAL_DIVISION_OF_TRIVIAL] THEN
1469   GEN_TAC THEN MATCH_MP_TAC(TAUT `(a ==> b) ==> (a /\ b <=> a)`) THEN
1470   DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[NOT_IN_EMPTY] THEN SET_TAC[]);;
1471
1472 let TAGGED_DIVISION_OF_SELF = prove
1473  (`!x a b. x IN interval[a,b]
1474            ==> {(x,interval[a,b])} tagged_division_of interval[a,b]`,
1475   REWRITE_TAC[TAGGED_DIVISION_OF; FINITE_INSERT; FINITE_RULES; IN_SING] THEN
1476   REWRITE_TAC[FORALL_PAIR_THM; PAIR_EQ] THEN REPEAT STRIP_TAC THEN
1477   ASM_REWRITE_TAC[SUBSET_REFL; UNWIND_THM2; SET_RULE `{k | k = a} = {a}`] THEN
1478   REWRITE_TAC[UNIONS_1] THEN ASM_MESON_TAC[]);;
1479
1480 let TAGGED_DIVISION_UNION = prove
1481  (`!s1 s2:real^N->bool p1 p2.
1482         p1 tagged_division_of s1 /\
1483         p2 tagged_division_of s2 /\
1484         interior s1 INTER interior s2 = {}
1485         ==> (p1 UNION p2) tagged_division_of (s1 UNION s2)`,
1486   REPEAT GEN_TAC THEN REWRITE_TAC[TAGGED_DIVISION_OF] THEN STRIP_TAC THEN
1487   ASM_REWRITE_TAC[FINITE_UNION; IN_UNION; EXISTS_OR_THM; SET_RULE
1488    `UNIONS {x | P x \/ Q x} = UNIONS {x | P x} UNION UNIONS {x | Q x}`] THEN
1489   CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
1490   REPEAT STRIP_TAC THENL
1491    [ASM_MESON_TAC[]; ALL_TAC;
1492     ONCE_REWRITE_TAC[INTER_COMM]; ASM_MESON_TAC[]] THEN
1493   MATCH_MP_TAC(SET_RULE
1494    `!s' t'. s SUBSET s' /\ t SUBSET t' /\ s' INTER t' = {}
1495             ==> s INTER t = {}`) THEN
1496   MAP_EVERY EXISTS_TAC
1497    [`interior s1:real^N->bool`; `interior s2:real^N->bool`] THEN
1498   ASM_SIMP_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN
1499   ASM_MESON_TAC[]);;
1500
1501 let TAGGED_DIVISION_UNIONS = prove
1502  (`!iset pfn. FINITE iset /\
1503               (!i:real^M->bool. i IN iset ==> pfn(i) tagged_division_of i) /\
1504               (!i1 i2. i1 IN iset /\ i2 IN iset /\ ~(i1 = i2)
1505                        ==> (interior(i1) INTER interior(i2) = {}))
1506               ==> UNIONS(IMAGE pfn iset) tagged_division_of (UNIONS iset)`,
1507   let lemma1 = prove
1508     (`(?t. (?x. (t = f x) /\ P x) /\ Q t) <=> ?x. P x /\ Q(f x)`,
1509      MESON_TAC[])
1510   and lemma2 = prove
1511    (`!s1 t1 s2 t2. s1 SUBSET t1 /\ s2 SUBSET t2 /\ (t1 INTER t2 = {})
1512                    ==> (s1 INTER s2 = {})`,
1513     SET_TAC[]) in
1514   REPEAT GEN_TAC THEN
1515   REWRITE_TAC[ONCE_REWRITE_RULE[EXTENSION] tagged_division_of] THEN
1516   REWRITE_TAC[tagged_partial_division_of; IN_UNIONS; IN_ELIM_THM] THEN
1517   REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNIONS; IN_IMAGE] THEN
1518   SIMP_TAC[FINITE_UNIONS; FINITE_IMAGE; FORALL_IN_IMAGE] THEN
1519   STRIP_TAC THEN REPEAT CONJ_TAC THENL
1520    [ASM_MESON_TAC[]; ALL_TAC; ASM_MESON_TAC[]] THEN
1521   REPEAT GEN_TAC THEN REWRITE_TAC[lemma1] THEN
1522   REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN
1523   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
1524   MAP_EVERY X_GEN_TAC [`i1:real^M->bool`; `i2:real^M->bool`] THEN
1525   ASM_CASES_TAC `i1 = i2:real^M->bool` THENL
1526    [ASM_MESON_TAC[]; ALL_TAC] THEN
1527   REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma2 THEN
1528   MAP_EVERY EXISTS_TAC
1529    [`interior(i1:real^M->bool)`; `interior(i2:real^M->bool)`] THEN
1530   ASM_MESON_TAC[SUBSET; SUBSET_INTERIOR]);;
1531
1532 let TAGGED_PARTIAL_DIVISION_OF_UNION_SELF = prove
1533  (`!p s. p tagged_partial_division_of s
1534          ==> p tagged_division_of (UNIONS(IMAGE SND p))`,
1535   SIMP_TAC[tagged_partial_division_of; TAGGED_DIVISION_OF] THEN
1536   REPEAT GEN_TAC THEN STRIP_TAC THEN REPEAT CONJ_TAC THENL
1537    [REPEAT STRIP_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
1538     REWRITE_TAC[SUBSET; IN_UNIONS; IN_IMAGE; EXISTS_PAIR_THM] THEN
1539     ASM_MESON_TAC[];
1540     ASM_MESON_TAC[];
1541     AP_TERM_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN
1542     REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; EXISTS_PAIR_THM] THEN MESON_TAC[]]);;
1543
1544 let TAGGED_DIVISION_OF_UNION_SELF = prove
1545  (`!p s. p tagged_division_of s
1546          ==> p tagged_division_of (UNIONS(IMAGE SND p))`,
1547   SIMP_TAC[TAGGED_DIVISION_OF] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
1548   MATCH_MP_TAC(TAUT `(c ==> a /\ b) /\ c ==> a /\ b /\ c`) THEN CONJ_TAC THENL
1549    [DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[] THEN ASM_MESON_TAC[];
1550     FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN AP_TERM_TAC THEN
1551     GEN_REWRITE_TAC I [EXTENSION] THEN
1552     REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; EXISTS_PAIR_THM] THEN MESON_TAC[]]);;
1553
1554 let TAGGED_DIVISION_UNION_IMAGE_SND = prove
1555  (`!p s. p tagged_division_of s ==> s = UNIONS(IMAGE SND p)`,
1556   MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF; tagged_division_of]);;
1557
1558 let TAGGED_DIVISION_OF_ALT = prove
1559  (`!p s. p tagged_division_of s <=>
1560          p tagged_partial_division_of s /\
1561          (!x. x IN s ==> ?t k. (t,k) IN p /\ x IN k)`,
1562   REWRITE_TAC[tagged_division_of; GSYM SUBSET_ANTISYM_EQ] THEN
1563   REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IN_ELIM_THM] THEN
1564   REWRITE_TAC[IN_UNIONS; EXISTS_PAIR_THM; IN_ELIM_THM] THEN
1565   REWRITE_TAC[tagged_partial_division_of; SUBSET] THEN MESON_TAC[]);;
1566
1567 let TAGGED_DIVISION_OF_ANOTHER = prove
1568  (`!p s s'.
1569         p tagged_partial_division_of s' /\
1570         (!t k. (t,k) IN p ==> k SUBSET s) /\
1571         (!x. x IN s ==> ?t k. (t,k) IN p /\ x IN k)
1572         ==> p tagged_division_of s`,
1573   REWRITE_TAC[TAGGED_DIVISION_OF_ALT; tagged_partial_division_of] THEN
1574   SET_TAC[]);;
1575
1576 let TAGGED_PARTIAL_DIVISION_OF_SUBSET = prove
1577  (`!p s t. p tagged_partial_division_of s /\ s SUBSET t
1578            ==> p tagged_partial_division_of t`,
1579   REWRITE_TAC[tagged_partial_division_of] THEN SET_TAC[]);;
1580
1581 let TAGGED_DIVISION_OF_NONTRIVIAL = prove
1582  (`!s a b:real^N.
1583         s tagged_division_of interval[a,b] /\ ~(content(interval[a,b]) = &0)
1584         ==> {(x,k) | (x,k) IN s /\ ~(content k = &0)}
1585             tagged_division_of interval[a,b]`,
1586   REPEAT STRIP_TAC THEN REWRITE_TAC[TAGGED_DIVISION_OF_ALT] THEN
1587   CONJ_TAC THENL
1588    [MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_SUBSET THEN
1589     EXISTS_TAC `s:(real^N#(real^N->bool))->bool` THEN
1590     RULE_ASSUM_TAC(REWRITE_RULE[tagged_division_of]) THEN
1591     ASM_REWRITE_TAC[] THEN SET_TAC[];
1592     FIRST_ASSUM(MP_TAC o MATCH_MP DIVISION_OF_TAGGED_DIVISION) THEN
1593     DISCH_THEN(MP_TAC o
1594      MATCH_MP(REWRITE_RULE[IMP_CONJ] DIVISION_OF_NONTRIVIAL)) THEN
1595     ASM_REWRITE_TAC[] THEN
1596     REWRITE_TAC[division_of] THEN DISCH_THEN(MP_TAC o last o CONJUNCTS) THEN
1597     REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET; IN_ELIM_PAIR_THM] THEN
1598     REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE; EXISTS_PAIR_THM; IN_ELIM_THM;
1599                 GSYM CONJ_ASSOC] THEN
1600     MESON_TAC[]]);;
1601
1602 (* ------------------------------------------------------------------------- *)
1603 (* Fine-ness of a partition w.r.t. a gauge.                                  *)
1604 (* ------------------------------------------------------------------------- *)
1605
1606 parse_as_infix("fine",(12,"right"));;
1607
1608 let fine = new_definition
1609   `d fine s <=> !x k. (x,k) IN s ==> k SUBSET d(x)`;;
1610
1611 let FINE_INTER = prove
1612  (`!p d1 d2. (\x. d1(x) INTER d2(x)) fine p <=> d1 fine p /\ d2 fine p`,
1613   let lemma = prove
1614    (`s SUBSET (t INTER u) <=> s SUBSET t /\ s SUBSET u`,SET_TAC[]) in
1615   REWRITE_TAC[fine; IN_INTER; lemma] THEN MESON_TAC[]);;
1616
1617 let FINE_INTERS = prove
1618  (`!f s p. (\x. INTERS {f d x | d IN s}) fine p <=>
1619            !d. d IN s ==> (f d) fine p`,
1620   REWRITE_TAC[fine; SET_RULE `s SUBSET INTERS u <=> !t. t IN u ==> s SUBSET t`;
1621               IN_ELIM_THM] THEN MESON_TAC[]);;
1622
1623 let FINE_UNION = prove
1624  (`!d p1 p2. d fine p1 /\ d fine p2 ==> d fine (p1 UNION p2)`,
1625   REWRITE_TAC[fine; IN_UNION] THEN MESON_TAC[]);;
1626
1627 let FINE_UNIONS = prove
1628  (`!d ps. (!p. p IN ps ==> d fine p) ==> d fine (UNIONS ps)`,
1629   REWRITE_TAC[fine; IN_UNIONS] THEN MESON_TAC[]);;
1630
1631 let FINE_SUBSET = prove
1632  (`!d p q. p SUBSET q /\ d fine q ==> d fine p`,
1633   REWRITE_TAC[fine; SUBSET] THEN MESON_TAC[]);;
1634
1635 (* ------------------------------------------------------------------------- *)
1636 (* Gauge integral. Define on compact intervals first, then use a limit.      *)
1637 (* ------------------------------------------------------------------------- *)
1638
1639 parse_as_infix("has_integral_compact_interval",(12,"right"));;
1640 parse_as_infix("has_integral",(12,"right"));;
1641 parse_as_infix("integrable_on",(12,"right"));;
1642
1643 let has_integral_compact_interval = new_definition
1644   `(f has_integral_compact_interval y) i <=>
1645         !e. &0 < e
1646             ==> ?d. gauge d /\
1647                     !p. p tagged_division_of i /\ d fine p
1648                         ==> norm(vsum p (\(x,k). content(k) % f(x)) - y) < e`;;
1649
1650 let has_integral_def = new_definition
1651   `(f has_integral y) i <=>
1652         if ?a b. i = interval[a,b] then (f has_integral_compact_interval y) i
1653         else !e. &0 < e
1654                  ==> ?B. &0 < B /\
1655                          !a b. ball(vec 0,B) SUBSET interval[a,b]
1656                                ==> ?z. ((\x. if x IN i then f(x) else vec 0)
1657                                         has_integral_compact_interval z)
1658                                         (interval[a,b]) /\
1659                                        norm(z - y) < e`;;
1660
1661 let has_integral = prove
1662  (`(f has_integral y) (interval[a,b]) <=>
1663         !e. &0 < e
1664             ==> ?d. gauge d /\
1665                     !p. p tagged_division_of interval[a,b] /\ d fine p
1666                         ==> norm(vsum p (\(x,k). content(k) % f(x)) - y) < e`,
1667   REWRITE_TAC[has_integral_def; has_integral_compact_interval] THEN
1668   MESON_TAC[]);;
1669
1670 let has_integral_alt = prove
1671  (`(f has_integral y) i <=>
1672         if ?a b. i = interval[a,b] then (f has_integral y) i
1673         else !e. &0 < e
1674                  ==> ?B. &0 < B /\
1675                          !a b. ball(vec 0,B) SUBSET interval[a,b]
1676                                ==> ?z. ((\x. if x IN i then f(x) else vec 0)
1677                                         has_integral z) (interval[a,b]) /\
1678                                        norm(z - y) < e`,
1679   REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [has_integral_def] THEN
1680   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
1681    [POP_ASSUM(REPEAT_TCL CHOOSE_THEN SUBST1_TAC); ALL_TAC] THEN
1682   REWRITE_TAC[has_integral_compact_interval; has_integral]);;
1683
1684 let integrable_on = new_definition
1685  `f integrable_on i <=> ?y. (f has_integral y) i`;;
1686
1687 let integral = new_definition
1688  `integral i f = @y. (f has_integral y) i`;;
1689
1690 let INTEGRABLE_INTEGRAL = prove
1691  (`!f i. f integrable_on i ==> (f has_integral (integral i f)) i`,
1692   REPEAT GEN_TAC THEN REWRITE_TAC[integrable_on; integral] THEN
1693   CONV_TAC(RAND_CONV SELECT_CONV) THEN REWRITE_TAC[]);;
1694
1695 let HAS_INTEGRAL_INTEGRABLE = prove
1696  (`!f i s. (f has_integral i) s ==> f integrable_on s`,
1697   REWRITE_TAC[integrable_on] THEN MESON_TAC[]);;
1698
1699 let HAS_INTEGRAL_INTEGRAL = prove
1700  (`!f s. f integrable_on s <=> (f has_integral (integral s f)) s`,
1701   MESON_TAC[INTEGRABLE_INTEGRAL; HAS_INTEGRAL_INTEGRABLE]);;
1702
1703 let VSUM_CONTENT_NULL = prove
1704  (`!f:real^M->real^N a b p.
1705         content(interval[a,b]) = &0 /\
1706         p tagged_division_of interval[a,b]
1707         ==> vsum p (\(x,k). content k % f x) = vec 0`,
1708   REPEAT STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ_0 THEN
1709   REWRITE_TAC[FORALL_PAIR_THM] THEN
1710   MAP_EVERY X_GEN_TAC [`p:real^M`; `k:real^M->bool`] THEN
1711   DISCH_TAC THEN REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN
1712   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
1713   DISCH_THEN(MP_TAC o CONJUNCT1 o CONJUNCT2) THEN
1714   DISCH_THEN(MP_TAC o SPECL [`p:real^M`; `k:real^M->bool`]) THEN
1715   ASM_MESON_TAC[CONTENT_SUBSET; CONTENT_POS_LE; REAL_ARITH
1716    `&0 <= x /\ x <= y /\ y = &0 ==> x = &0`]);;
1717
1718 (* ------------------------------------------------------------------------- *)
1719 (* Some basic combining lemmas.                                              *)
1720 (* ------------------------------------------------------------------------- *)
1721
1722 let TAGGED_DIVISION_UNIONS_EXISTS = prove
1723  (`!d iset i:real^M->bool.
1724         FINITE iset /\
1725         (!i. i IN iset ==> ?p. p tagged_division_of i /\ d fine p) /\
1726         (!i1 i2. i1 IN iset /\ i2 IN iset /\ ~(i1 = i2)
1727                  ==> (interior(i1) INTER interior(i2) = {})) /\
1728         (UNIONS iset = i)
1729         ==> ?p. p tagged_division_of i /\ d fine p`,
1730   REPEAT GEN_TAC THEN
1731   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
1732   REWRITE_TAC[SKOLEM_THM; LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN
1733   REPEAT STRIP_TAC THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
1734   EXISTS_TAC `UNIONS (IMAGE(p:(real^M->bool)->((real^M#(real^M->bool))->bool))
1735                       iset)` THEN
1736   ASM_SIMP_TAC[TAGGED_DIVISION_UNIONS] THEN
1737   ASM_MESON_TAC[FINE_UNIONS; IN_IMAGE]);;
1738
1739 (* ------------------------------------------------------------------------- *)
1740 (* The set we're concerned with must be closed.                              *)
1741 (* ------------------------------------------------------------------------- *)
1742
1743 let DIVISION_OF_CLOSED = prove
1744  (`!s i. s division_of i ==> closed i`,
1745   REWRITE_TAC[division_of] THEN MESON_TAC[CLOSED_UNIONS; CLOSED_INTERVAL]);;
1746
1747 (* ------------------------------------------------------------------------- *)
1748 (* General bisection principle for intervals; might be useful elsewhere.     *)
1749 (* ------------------------------------------------------------------------- *)
1750
1751 let INTERVAL_BISECTION_STEP = prove
1752  (`!P. P {} /\
1753        (!s t. P s /\ P t /\ interior(s) INTER interior(t) = {}
1754               ==> P(s UNION t))
1755        ==> !a b:real^N.
1756                 ~(P(interval[a,b]))
1757                 ==> ?c d. ~(P(interval[c,d])) /\
1758                           !i. 1 <= i /\ i <= dimindex(:N)
1759                               ==> a$i <= c$i /\ c$i <= d$i /\ d$i <= b$i /\
1760                                   &2 * (d$i - c$i) <= b$i - a$i`,
1761   REPEAT GEN_TAC THEN STRIP_TAC THEN REPEAT GEN_TAC THEN
1762   ASM_CASES_TAC `!i. 1 <= i /\ i <= dimindex(:N)
1763                      ==> (a:real^N)$i <= (b:real^N)$i` THENL
1764    [ALL_TAC;
1765     RULE_ASSUM_TAC(REWRITE_RULE[GSYM INTERVAL_NE_EMPTY]) THEN
1766     ASM_REWRITE_TAC[]] THEN
1767   SUBGOAL_THEN
1768    `!f. FINITE f /\
1769         (!s:real^N->bool. s IN f ==> P s) /\
1770         (!s:real^N->bool. s IN f ==> ?a b. s = interval[a,b]) /\
1771         (!s t. s IN f /\ t IN f /\ ~(s = t)
1772                ==> interior(s) INTER interior(t) = {})
1773         ==> P(UNIONS f)`
1774   ASSUME_TAC THENL
1775    [ONCE_REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1776     ASM_SIMP_TAC[UNIONS_0; UNIONS_INSERT; NOT_IN_EMPTY; FORALL_IN_INSERT] THEN
1777     REWRITE_TAC[IMP_IMP] THEN REPEAT GEN_TAC THEN DISCH_THEN(fun th ->
1778       FIRST_X_ASSUM MATCH_MP_TAC THEN STRIP_ASSUME_TAC th) THEN
1779     ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
1780     MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
1781     ASM_REWRITE_TAC[OPEN_INTERIOR] THEN REPEAT STRIP_TAC THEN
1782     FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_INSERT] THEN
1783     ASM_MESON_TAC[];
1784     ALL_TAC] THEN
1785   DISCH_TAC THEN
1786   FIRST_X_ASSUM(MP_TAC o SPEC
1787    `{ interval[c,d] |
1788       !i. 1 <= i /\ i <= dimindex(:N)
1789           ==> ((c:real^N)$i = (a:real^N)$i) /\ (d$i = (a$i + b$i) / &2) \/
1790               (c$i = (a$i + b$i) / &2) /\ ((d:real^N)$i = (b:real^N)$i)}`) THEN
1791   ONCE_REWRITE_TAC[IMP_CONJ] THEN ANTS_TAC THENL
1792    [MATCH_MP_TAC FINITE_SUBSET THEN
1793     EXISTS_TAC
1794      `IMAGE (\s. closed_interval
1795        [(lambda i. if i IN s then (a:real^N)$i else (a$i + b$i) / &2):real^N,
1796         (lambda i. if i IN s then (a$i + b$i) / &2 else (b:real^N)$i)])
1797          {s | s SUBSET (1..dimindex(:N))}` THEN
1798     CONJ_TAC THENL
1799      [SIMP_TAC[FINITE_POWERSET; FINITE_IMAGE; FINITE_NUMSEG]; ALL_TAC] THEN
1800     REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_IMAGE] THEN
1801     X_GEN_TAC `k:real^N->bool` THEN
1802     DISCH_THEN(X_CHOOSE_THEN `c:real^N` (X_CHOOSE_THEN `d:real^N`
1803       (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC))) THEN
1804     EXISTS_TAC `{i | 1 <= i /\ i <= dimindex(:N) /\
1805                      ((c:real^N)$i = (a:real^N)$i)}` THEN
1806     CONJ_TAC THENL [ALL_TAC; SIMP_TAC[IN_ELIM_THM; IN_NUMSEG]] THEN
1807     AP_TERM_TAC THEN REWRITE_TAC[CONS_11; PAIR_EQ] THEN
1808     SIMP_TAC[CART_EQ; LAMBDA_BETA; IN_ELIM_THM] THEN
1809     REPEAT(FIRST_X_ASSUM(MP_TAC o GEN `i:num` o SPEC `i:num`)) THEN
1810     REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN
1811     MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
1812     REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> (a ==> b /\ c)`] THEN
1813     MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
1814     COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
1815     SIMP_TAC[REAL_EQ_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
1816     REAL_ARITH_TAC;
1817     ALL_TAC] THEN
1818   GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN ANTS_TAC THENL
1819    [UNDISCH_TAC `~P(interval[a:real^N,b])` THEN MATCH_MP_TAC EQ_IMP THEN
1820     AP_TERM_TAC THEN AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN
1821     GEN_REWRITE_TAC I [EXTENSION] THEN
1822     REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN
1823     REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN
1824     ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c <=> b /\ a /\ c`] THEN
1825     GEN_REWRITE_TAC LAND_CONV [SWAP_EXISTS_THM] THEN
1826     GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [SWAP_EXISTS_THM] THEN
1827     REWRITE_TAC[UNWIND_THM2; IN_INTERVAL] THEN
1828     REWRITE_TAC[AND_FORALL_THM] THEN
1829     REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> (a ==> b /\ c)`] THEN
1830     REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN AP_TERM_TAC THEN
1831     GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `i:num` THEN
1832     REWRITE_TAC[] THEN
1833     MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> ((a ==> b) <=> (a ==> c))`) THEN
1834     STRIP_TAC THEN
1835     ONCE_REWRITE_TAC[TAUT `(a \/ b) /\ c <=> ~(a ==> ~c) \/ ~(b ==> ~c)`] THEN
1836     SIMP_TAC[] THEN
1837     REWRITE_TAC[TAUT `~(a ==> ~b) <=> a /\ b`; GSYM CONJ_ASSOC] THEN
1838     REWRITE_TAC[EXISTS_OR_THM; RIGHT_EXISTS_AND_THM] THEN
1839     REWRITE_TAC[LEFT_EXISTS_AND_THM; EXISTS_REFL] THEN
1840     SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
1841     REAL_ARITH_TAC;
1842     ALL_TAC] THEN
1843   REWRITE_TAC[FORALL_IN_GSPEC] THEN
1844   MATCH_MP_TAC(TAUT `b /\ (~a ==> e) /\ c ==> ~(a /\ b /\ c) ==> e`) THEN
1845   CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN CONJ_TAC THENL
1846    [REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
1847     REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
1848     DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN ASM_REWRITE_TAC[] THEN
1849     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN
1850     DISCH_THEN(fun th -> REPEAT DISCH_TAC THEN MP_TAC th) THEN
1851     FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
1852     REAL_ARITH_TAC;
1853     ALL_TAC] THEN
1854   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
1855   REWRITE_TAC[IMP_IMP; INTERIOR_CLOSED_INTERVAL] THEN
1856   REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
1857   MAP_EVERY X_GEN_TAC
1858    [`c1:real^N`; `d1:real^N`; `c2:real^N`; `d2:real^N`] THEN
1859   ASM_CASES_TAC `(c1 = c2:real^N) /\ (d1 = d2:real^N)` THENL
1860    [ASM_REWRITE_TAC[]; ALL_TAC] THEN
1861   DISCH_THEN(fun th ->
1862     DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (K ALL_TAC)) THEN MP_TAC th) THEN
1863   REWRITE_TAC[IMP_IMP] THEN
1864   UNDISCH_TAC `~((c1 = c2:real^N) /\ (d1 = d2:real^N))` THEN
1865   REWRITE_TAC[CART_EQ; INTERIOR_CLOSED_INTERVAL] THEN
1866   REWRITE_TAC[AND_FORALL_THM] THEN
1867   REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> (a ==> b /\ c)`] THEN
1868   REWRITE_TAC[NOT_FORALL_THM] THEN
1869   DISCH_THEN(X_CHOOSE_THEN `j:num` (fun th ->
1870     DISCH_THEN(MP_TAC o SPEC `j:num`) THEN MP_TAC th)) THEN
1871   REWRITE_TAC[NOT_IMP] THEN
1872   DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
1873   ASM_REWRITE_TAC[IMP_IMP] THEN
1874   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
1875   ASM_REWRITE_TAC[EXTENSION; IN_INTERVAL; NOT_IN_EMPTY; IN_INTER] THEN
1876   SIMP_TAC[REAL_EQ_RDIV_EQ; REAL_EQ_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
1877   REWRITE_TAC[
1878     REAL_ARITH `~((a * &2 = a + b) /\ (a + b = b * &2)) <=> ~(a = b)`;
1879     REAL_ARITH `~((a + b = a * &2) /\ (b * &2 = a + b)) <=> ~(a = b)`] THEN
1880   DISCH_THEN(fun th -> X_GEN_TAC `x:real^N` THEN MP_TAC th) THEN
1881   REWRITE_TAC[AND_FORALL_THM] THEN
1882   REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> (a ==> b /\ c)`] THEN
1883   ASM_REWRITE_TAC[CONTRAPOS_THM] THEN
1884   DISCH_THEN(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN
1885   REAL_ARITH_TAC);;
1886
1887 let INTERVAL_BISECTION = prove
1888  (`!P. P {} /\
1889        (!s t. P s /\ P t /\ interior(s) INTER interior(t) = {}
1890               ==> P(s UNION t))
1891        ==> !a b:real^N.
1892                 ~(P(interval[a,b]))
1893                 ==> ?x. x IN interval[a,b] /\
1894                         !e. &0 < e
1895                             ==> ?c d. x IN interval[c,d] /\
1896                                       interval[c,d] SUBSET ball(x,e) /\
1897                                       interval[c,d] SUBSET interval[a,b] /\
1898                                       ~P(interval[c,d])`,
1899   REPEAT STRIP_TAC THEN
1900   SUBGOAL_THEN
1901    `?A B. (A(0) = a:real^N) /\ (B(0) = b) /\
1902           !n. ~(P(interval[A(SUC n),B(SUC n)])) /\
1903               !i. 1 <= i /\ i <= dimindex(:N)
1904                        ==> A(n)$i <= A(SUC n)$i /\
1905                            A(SUC n)$i <= B(SUC n)$i /\
1906                            B(SUC n)$i <= B(n)$i /\
1907                            &2 * (B(SUC n)$i - A(SUC n)$i) <= B(n)$i - A(n)$i`
1908   STRIP_ASSUME_TAC THENL
1909    [MP_TAC(ISPEC `P:(real^N->bool)->bool` INTERVAL_BISECTION_STEP) THEN
1910     ASM_REWRITE_TAC[] THEN
1911     GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
1912     REWRITE_TAC[SKOLEM_THM] THEN
1913     DISCH_THEN(X_CHOOSE_THEN `C:real^N->real^N->real^N`
1914      (X_CHOOSE_THEN `D:real^N->real^N->real^N` ASSUME_TAC)) THEN
1915     MP_TAC(prove_recursive_functions_exist num_RECURSION
1916      `(E 0 = a:real^N,b:real^N) /\
1917       (!n. E(SUC n) = C (FST(E n)) (SND(E n)),
1918                       D (FST(E n)) (SND(E n)))`) THEN
1919     DISCH_THEN(X_CHOOSE_THEN `E:num->real^N#real^N` STRIP_ASSUME_TAC) THEN
1920     EXISTS_TAC `\n. FST((E:num->real^N#real^N) n)` THEN
1921     EXISTS_TAC `\n. SND((E:num->real^N#real^N) n)` THEN
1922     ASM_REWRITE_TAC[] THEN INDUCT_TAC THEN ASM_SIMP_TAC[];
1923     ALL_TAC] THEN
1924   SUBGOAL_THEN
1925    `!e. &0 < e
1926         ==> ?n:num. !x y. x IN interval[A(n),B(n)] /\ y IN interval[A(n),B(n)]
1927                           ==> dist(x,y:real^N) < e`
1928   ASSUME_TAC THENL
1929    [X_GEN_TAC `e:real` THEN DISCH_TAC THEN MP_TAC(SPEC
1930      `sum(1..dimindex(:N)) (\i. (b:real^N)$i - (a:real^N)$i) / e`
1931      REAL_ARCH_POW2) THEN
1932     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
1933     MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
1934     MATCH_MP_TAC REAL_LET_TRANS THEN
1935     EXISTS_TAC `sum(1..dimindex(:N))(\i. abs((x - y:real^N)$i))` THEN
1936     REWRITE_TAC[dist; NORM_LE_L1] THEN
1937     MATCH_MP_TAC REAL_LET_TRANS THEN
1938     EXISTS_TAC `sum(1..dimindex(:N))
1939                    (\i. (B:num->real^N)(n)$i - (A:num->real^N)(n)$i)` THEN
1940     CONJ_TAC THENL
1941      [MATCH_MP_TAC SUM_LE_NUMSEG THEN SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
1942       REPEAT STRIP_TAC THEN
1943       MATCH_MP_TAC(REAL_ARITH `a <= x /\ x <= b /\ a <= y /\ y <= b
1944                                ==> abs(x - y) <= b - a`) THEN
1945       UNDISCH_TAC `x IN interval[(A:num->real^N) n,B n]` THEN
1946       UNDISCH_TAC `y IN interval[(A:num->real^N) n,B n]` THEN
1947       REWRITE_TAC[IN_INTERVAL] THEN ASM_SIMP_TAC[];
1948       ALL_TAC] THEN
1949     MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC
1950      `sum(1..dimindex(:N)) (\i. (b:real^N)$i - (a:real^N)$i) /
1951       &2 pow n` THEN
1952     CONJ_TAC THENL
1953      [ALL_TAC;
1954       SIMP_TAC[REAL_LT_LDIV_EQ; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN
1955       ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
1956       ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ]] THEN
1957     REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
1958     REWRITE_TAC[GSYM SUM_LMUL] THEN MATCH_MP_TAC SUM_LE_NUMSEG THEN
1959     X_GEN_TAC `j:num` THEN STRIP_TAC THEN REWRITE_TAC[] THEN
1960     ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN
1961     SPEC_TAC(`n:num`,`m:num`) THEN INDUCT_TAC THEN
1962     ASM_REWRITE_TAC[real_pow; REAL_DIV_1; REAL_LE_REFL] THEN
1963     ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
1964     REWRITE_TAC[real_div; REAL_INV_MUL; REAL_MUL_ASSOC] THEN
1965     SIMP_TAC[GSYM real_div; REAL_LE_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
1966     ASM_MESON_TAC[REAL_LE_TRANS; REAL_MUL_SYM];
1967     ALL_TAC] THEN
1968   SUBGOAL_THEN `?a:real^N. !n:num. a IN interval[A(n),B(n)]` MP_TAC THENL
1969    [MATCH_MP_TAC DECREASING_CLOSED_NEST THEN
1970     ASM_REWRITE_TAC[CLOSED_INTERVAL] THEN CONJ_TAC THENL
1971      [REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN
1972       ASM_MESON_TAC[REAL_NOT_LT; REAL_LE_TRANS];
1973       ALL_TAC] THEN
1974     REWRITE_TAC[LE_EXISTS] THEN SIMP_TAC[LEFT_IMP_EXISTS_THM] THEN
1975     X_GEN_TAC `m:num` THEN ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
1976     REWRITE_TAC[GSYM LEFT_IMP_EXISTS_THM; EXISTS_REFL] THEN
1977     INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES; SUBSET_REFL] THEN
1978     MATCH_MP_TAC SUBSET_TRANS THEN
1979     EXISTS_TAC `interval[A(m + d:num):real^N,B(m + d)]` THEN
1980     ASM_REWRITE_TAC[] THEN
1981     REWRITE_TAC[SUBSET; IN_INTERVAL] THEN ASM_MESON_TAC[REAL_LE_TRANS];
1982     ALL_TAC] THEN
1983   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x0:real^N` THEN
1984   DISCH_TAC THEN CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
1985   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1986   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
1987   DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN
1988   MAP_EVERY EXISTS_TAC [`(A:num->real^N) n`; `(B:num->real^N) n`] THEN
1989   ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
1990    [REWRITE_TAC[SUBSET; IN_BALL] THEN ASM_MESON_TAC[];
1991     ALL_TAC;
1992     SPEC_TAC(`n:num`,`p:num`) THEN INDUCT_TAC THEN ASM_REWRITE_TAC[]] THEN
1993   SUBGOAL_THEN
1994    `!m n. m <= n ==> interval[(A:num->real^N) n,B n] SUBSET interval[A m,B m]`
1995    (fun th -> ASM_MESON_TAC[SUBSET; LE_0; th]) THEN
1996   MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
1997   REPEAT(CONJ_TAC THENL [SET_TAC[]; ALL_TAC]) THEN
1998   REWRITE_TAC[SUBSET_INTERVAL] THEN ASM_MESON_TAC[]);;
1999
2000 (* ------------------------------------------------------------------------- *)
2001 (* Cousin's lemma.                                                           *)
2002 (* ------------------------------------------------------------------------- *)
2003
2004 let FINE_DIVISION_EXISTS = prove
2005  (`!g a b:real^M.
2006         gauge g ==> ?p. p tagged_division_of (interval[a,b]) /\ g fine p`,
2007   REPEAT STRIP_TAC THEN
2008   MP_TAC(ISPEC `\s:real^M->bool. ?p. p tagged_division_of s /\ g fine p`
2009         INTERVAL_BISECTION) THEN
2010   REWRITE_TAC[] THEN ANTS_TAC THENL
2011    [MESON_TAC[TAGGED_DIVISION_UNION; FINE_UNION;
2012               TAGGED_DIVISION_OF_EMPTY; fine; NOT_IN_EMPTY];
2013     DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`])] THEN
2014   GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN
2015   REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN
2016   DISCH_THEN(X_CHOOSE_THEN `x:real^M` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
2017   FIRST_ASSUM(MP_TAC o SPEC `x:real^M` o REWRITE_RULE[gauge]) THEN
2018   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
2019   REWRITE_TAC[OPEN_CONTAINS_BALL; NOT_FORALL_THM] THEN
2020   DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN
2021   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN
2022   STRIP_TAC THEN ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN
2023   MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN STRIP_TAC THEN
2024   FIRST_X_ASSUM(MP_TAC o SPEC `{(x:real^M,interval[c:real^M,d])}`) THEN
2025   ASM_SIMP_TAC[TAGGED_DIVISION_OF_SELF] THEN
2026   REWRITE_TAC[fine; IN_SING; PAIR_EQ] THEN ASM_MESON_TAC[SUBSET_TRANS]);;
2027
2028 (* ------------------------------------------------------------------------- *)
2029 (* Basic theorems about integrals.                                           *)
2030 (* ------------------------------------------------------------------------- *)
2031
2032 let HAS_INTEGRAL_UNIQUE = prove
2033  (`!f:real^M->real^N i k1 k2.
2034         (f has_integral k1) i /\ (f has_integral k2) i ==> k1 = k2`,
2035   REPEAT GEN_TAC THEN
2036   SUBGOAL_THEN
2037    `!f:real^M->real^N a b k1 k2.
2038        (f has_integral k1) (interval[a,b]) /\
2039        (f has_integral k2) (interval[a,b])
2040        ==> k1 = k2`
2041   MP_TAC THENL
2042    [REPEAT GEN_TAC THEN REWRITE_TAC[has_integral] THEN
2043     REWRITE_TAC[AND_FORALL_THM] THEN
2044     REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN
2045     ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
2046     ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
2047     REWRITE_TAC[GSYM NORM_POS_LT] THEN DISCH_TAC THEN
2048     DISCH_THEN(MP_TAC o SPEC `norm(k1 - k2 :real^N) / &2`) THEN
2049     ASM_REWRITE_TAC[REAL_HALF] THEN
2050     DISCH_THEN(CONJUNCTS_THEN2
2051      (X_CHOOSE_THEN `d1:real^M->real^M->bool` STRIP_ASSUME_TAC)
2052      (X_CHOOSE_THEN `d2:real^M->real^M->bool` STRIP_ASSUME_TAC)) THEN
2053     MP_TAC(ISPEC `\x. ((d1:real^M->real^M->bool) x) INTER (d2 x)`
2054                  FINE_DIVISION_EXISTS) THEN
2055     ASM_SIMP_TAC[GAUGE_INTER] THEN
2056     DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN
2057     REPEAT(FIRST_X_ASSUM(MP_TAC o check (is_forall o concl))) THEN
2058     REWRITE_TAC[] THEN REWRITE_TAC[IMP_IMP; NOT_EXISTS_THM] THEN
2059     REWRITE_TAC[AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN
2060     GEN_TAC THEN
2061     MATCH_MP_TAC(TAUT
2062      `(f0 ==> f1 /\ f2) /\ ~(n1 /\ n2)
2063       ==> (t /\ f1 ==> n1) /\ (t /\ f2 ==> n2) ==> ~(t /\ f0)`) THEN
2064     CONJ_TAC THENL [SIMP_TAC[fine; SUBSET_INTER]; ALL_TAC] THEN
2065     MATCH_MP_TAC(REAL_ARITH `c <= a + b ==> ~(a < c / &2 /\ b < c / &2)`) THEN
2066     MESON_TAC[NORM_SUB; NORM_TRIANGLE; VECTOR_ARITH
2067      `k1 - k2:real^N = (k1 - x) + (x - k2)`];
2068     ALL_TAC] THEN
2069   DISCH_TAC THEN ONCE_REWRITE_TAC[has_integral_alt] THEN
2070   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
2071    [ASM_MESON_TAC[]; ALL_TAC] THEN
2072   DISCH_TAC THEN MATCH_MP_TAC(NORM_ARITH
2073    `~(&0 < norm(x - y)) ==> x = y`) THEN
2074   DISCH_TAC THEN
2075   FIRST_X_ASSUM(CONJUNCTS_THEN (MP_TAC o SPEC `norm(k1 - k2:real^N) / &2`)) THEN
2076   ASM_REWRITE_TAC[REAL_HALF] THEN
2077   DISCH_THEN(X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) THEN
2078   DISCH_THEN(X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC) THEN
2079   MP_TAC(ISPEC
2080    `ball(vec 0,B1) UNION ball(vec 0:real^M,B2)`
2081    BOUNDED_SUBSET_CLOSED_INTERVAL) THEN
2082   REWRITE_TAC[BOUNDED_UNION; BOUNDED_BALL; UNION_SUBSET; NOT_EXISTS_THM] THEN
2083   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
2084   DISCH_THEN(CONJUNCTS_THEN(ANTE_RES_THEN MP_TAC)) THEN
2085   DISCH_THEN(X_CHOOSE_THEN `w:real^N` STRIP_ASSUME_TAC) THEN
2086   DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
2087   SUBGOAL_THEN `w:real^N = z:real^N` SUBST_ALL_TAC THEN
2088   ASM_MESON_TAC[NORM_ARITH
2089    `~(norm(z - k1) < norm(k1 - k2) / &2 /\
2090       norm(z - k2) < norm(k1 - k2) / &2)`]);;
2091
2092 let INTEGRAL_UNIQUE = prove
2093  (`!f y k.
2094       (f has_integral y) k ==> integral k f = y`,
2095   REPEAT STRIP_TAC THEN REWRITE_TAC[integral] THEN
2096   MATCH_MP_TAC SELECT_UNIQUE THEN ASM_MESON_TAC[HAS_INTEGRAL_UNIQUE]);;
2097
2098 let HAS_INTEGRAL_INTEGRABLE_INTEGRAL = prove
2099  (`!f:real^M->real^N i s.
2100         (f has_integral i) s <=> f integrable_on s /\ integral s f = i`,
2101   MESON_TAC[INTEGRABLE_INTEGRAL; INTEGRAL_UNIQUE; integrable_on]);;
2102
2103 let INTEGRAL_EQ_HAS_INTEGRAL = prove
2104  (`!s f y. f integrable_on s ==> (integral s f = y <=> (f has_integral y) s)`,
2105   MESON_TAC[INTEGRABLE_INTEGRAL; INTEGRAL_UNIQUE]);;
2106
2107 let HAS_INTEGRAL_IS_0 = prove
2108  (`!f:real^M->real^N s.
2109         (!x. x IN s ==> (f(x) = vec 0)) ==> (f has_integral vec 0) s`,
2110   SUBGOAL_THEN
2111    `!f:real^M->real^N a b.
2112         (!x. x IN interval[a,b] ==> (f(x) = vec 0))
2113         ==> (f has_integral vec 0) (interval[a,b])`
2114   ASSUME_TAC THENL
2115    [REPEAT STRIP_TAC THEN REWRITE_TAC[has_integral] THEN
2116     REPEAT STRIP_TAC THEN EXISTS_TAC `\x:real^M. ball(x,&1)` THEN
2117     SIMP_TAC[gauge; OPEN_BALL; CENTRE_IN_BALL; REAL_LT_01] THEN
2118     REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_SUB_RZERO] THEN
2119     UNDISCH_TAC `&0 < e` THEN MATCH_MP_TAC(TAUT `(a <=> b) ==> b ==> a`) THEN
2120     AP_THM_TAC THEN AP_TERM_TAC THEN
2121     REWRITE_TAC[NORM_EQ_0; VECTOR_SUB_EQ; VECTOR_ADD_LID] THEN
2122     MATCH_MP_TAC VSUM_EQ_0 THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
2123     CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN
2124     X_GEN_TAC `x:real^M` THEN REPEAT STRIP_TAC THEN
2125     SUBGOAL_THEN `(x:real^M) IN interval[a,b]`
2126      (fun th -> ASM_SIMP_TAC[th; VECTOR_MUL_RZERO]) THEN
2127     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [tagged_division_of]) THEN
2128     REWRITE_TAC[tagged_partial_division_of; SUBSET] THEN ASM_MESON_TAC[];
2129     ALL_TAC] THEN
2130   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[has_integral_alt] THEN
2131   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
2132    [ASM_MESON_TAC[]; ALL_TAC] THEN
2133   GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
2134   REPEAT STRIP_TAC THEN EXISTS_TAC `vec 0:real^N` THEN
2135   ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN
2136   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]);;
2137
2138 let HAS_INTEGRAL_0 = prove
2139  (`!s. ((\x. vec 0) has_integral vec 0) s`,
2140   SIMP_TAC[HAS_INTEGRAL_IS_0]);;
2141
2142 let HAS_INTEGRAL_0_EQ = prove
2143  (`!i s. ((\x. vec 0) has_integral i) s <=> i = vec 0`,
2144   MESON_TAC[HAS_INTEGRAL_UNIQUE; HAS_INTEGRAL_0]);;
2145
2146 let HAS_INTEGRAL_LINEAR = prove
2147  (`!f:real^M->real^N y s h:real^N->real^P.
2148         (f has_integral y) s /\ linear h ==> ((h o f) has_integral h(y)) s`,
2149   SUBGOAL_THEN
2150     `!f:real^M->real^N y a b h:real^N->real^P.
2151           (f has_integral y) (interval[a,b]) /\ linear h
2152           ==> ((h o f) has_integral h(y)) (interval[a,b])`
2153   MP_TAC THENL
2154    [REPEAT GEN_TAC THEN REWRITE_TAC[has_integral] THEN STRIP_TAC THEN
2155     FIRST_ASSUM(MP_TAC o MATCH_MP LINEAR_BOUNDED_POS) THEN
2156     DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
2157     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2158     FIRST_X_ASSUM(MP_TAC o SPEC `e:real / B`) THEN
2159     ASM_SIMP_TAC[REAL_LT_DIV] THEN
2160     MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
2161     STRIP_TAC THEN ASM_SIMP_TAC[] THEN
2162     X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN
2163     FIRST_X_ASSUM(MP_TAC o SPEC `p:real^M#(real^M->bool)->bool`) THEN
2164     ASM_SIMP_TAC[REAL_LT_RDIV_EQ] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
2165     MATCH_MP_TAC(REAL_ARITH `x <= y ==> y < e ==> x < e`) THEN
2166     FIRST_ASSUM(fun th -> W(fun (asl,w) ->
2167       MP_TAC(PART_MATCH rand th (rand w)))) THEN
2168     MATCH_MP_TAC(REAL_ARITH `x <= y ==> y <= e ==> x <= e`) THEN
2169     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
2170     ASM_SIMP_TAC[LINEAR_SUB; LINEAR_VSUM; o_DEF; LAMBDA_PAIR_THM;
2171                  LINEAR_CMUL; REAL_LE_REFL];
2172     ALL_TAC] THEN
2173   DISCH_TAC THEN REPEAT GEN_TAC THEN
2174   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
2175   ONCE_REWRITE_TAC[has_integral_alt] THEN
2176   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
2177    [ASM_MESON_TAC[]; ALL_TAC] THEN
2178   DISCH_TAC THEN
2179   FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o MATCH_MP
2180     LINEAR_BOUNDED_POS) THEN
2181   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2182   FIRST_X_ASSUM(MP_TAC o SPEC `e / B:real`) THEN
2183   ASM_SIMP_TAC[REAL_LT_DIV] THEN
2184   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:real` THEN
2185   MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
2186   REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2187   MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
2188   DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
2189   EXISTS_TAC `(h:real^N->real^P) z` THEN
2190   SUBGOAL_THEN
2191    `(\x. if x IN s then ((h:real^N->real^P) o (f:real^M->real^N)) x else vec 0)
2192     = h o (\x. if x IN s then f x else vec 0)`
2193   SUBST1_TAC THENL
2194    [REWRITE_TAC[FUN_EQ_THM; o_THM] THEN ASM_MESON_TAC[LINEAR_0]; ALL_TAC] THEN
2195   ASM_SIMP_TAC[GSYM LINEAR_SUB] THEN
2196   MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `B * norm(z - y:real^N)` THEN
2197   ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
2198   ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ]);;
2199
2200 let HAS_INTEGRAL_CMUL = prove
2201  (`!(f:real^M->real^N) k s c.
2202         (f has_integral k) s
2203         ==> ((\x. c % f(x)) has_integral (c % k)) s`,
2204   REPEAT STRIP_TAC THEN MATCH_MP_TAC
2205    (REWRITE_RULE[o_DEF] HAS_INTEGRAL_LINEAR) THEN
2206   ASM_REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
2207
2208 let HAS_INTEGRAL_NEG = prove
2209  (`!f k s. (f has_integral k) s ==> ((\x. --(f x)) has_integral (--k)) s`,
2210   ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN REWRITE_TAC[HAS_INTEGRAL_CMUL]);;
2211
2212 let HAS_INTEGRAL_ADD = prove
2213  (`!f:real^M->real^N g s.
2214         (f has_integral k) s /\ (g has_integral l) s
2215         ==> ((\x. f(x) + g(x)) has_integral (k + l)) s`,
2216   SUBGOAL_THEN
2217    `!f:real^M->real^N g k l a b.
2218         (f has_integral k) (interval[a,b]) /\
2219         (g has_integral l) (interval[a,b])
2220         ==> ((\x. f(x) + g(x)) has_integral (k + l)) (interval[a,b])`
2221   ASSUME_TAC THENL
2222    [REPEAT GEN_TAC THEN REWRITE_TAC[has_integral; AND_FORALL_THM] THEN
2223     DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2224     FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
2225     DISCH_THEN(CONJUNCTS_THEN2
2226      (X_CHOOSE_THEN `d1:real^M->real^M->bool` STRIP_ASSUME_TAC)
2227      (X_CHOOSE_THEN `d2:real^M->real^M->bool` STRIP_ASSUME_TAC)) THEN
2228     EXISTS_TAC `\x. ((d1:real^M->real^M->bool) x) INTER (d2 x)` THEN
2229     ASM_SIMP_TAC[GAUGE_INTER] THEN
2230     REWRITE_TAC[tagged_division_of; tagged_partial_division_of] THEN
2231     SIMP_TAC[VSUM_ADD; VECTOR_ADD_LDISTRIB; LAMBDA_PAIR] THEN
2232     REWRITE_TAC[GSYM LAMBDA_PAIR] THEN
2233     REWRITE_TAC[GSYM tagged_partial_division_of] THEN
2234     REWRITE_TAC[GSYM tagged_division_of; FINE_INTER] THEN
2235     SIMP_TAC[VECTOR_ARITH `(a + b) - (c + d) = (a - c) + (b - d):real^N`] THEN
2236     REPEAT STRIP_TAC THEN MATCH_MP_TAC NORM_TRIANGLE_LT THEN
2237     MATCH_MP_TAC(REAL_ARITH `x < e / &2 /\ y < e / &2 ==> x + y < e`) THEN
2238     ASM_SIMP_TAC[];
2239     ALL_TAC] THEN
2240   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[has_integral_alt] THEN
2241   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
2242    [ASM_MESON_TAC[]; ALL_TAC] THEN
2243   DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2244   FIRST_X_ASSUM(CONJUNCTS_THEN (MP_TAC o SPEC `e / &2`)) THEN
2245   ASM_REWRITE_TAC[REAL_HALF] THEN
2246   DISCH_THEN(X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) THEN
2247   DISCH_THEN(X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC) THEN
2248   EXISTS_TAC `max B1 B2:real` THEN ASM_REWRITE_TAC[REAL_LT_MAX] THEN
2249   REWRITE_TAC[BALL_MAX_UNION; UNION_SUBSET] THEN
2250   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
2251   DISCH_THEN(CONJUNCTS_THEN(ANTE_RES_THEN MP_TAC)) THEN
2252   DISCH_THEN(X_CHOOSE_THEN `w:real^N` STRIP_ASSUME_TAC) THEN
2253   DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
2254   EXISTS_TAC `w + z:real^N` THEN
2255   SUBGOAL_THEN
2256     `(\x. if x IN s then (f:real^M->real^N) x + g x else vec 0) =
2257      (\x. (if x IN s then f x else vec 0) + (if x IN s then g x else vec 0))`
2258   SUBST1_TAC THENL
2259    [REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN COND_CASES_TAC THEN
2260     ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC;
2261     ALL_TAC] THEN
2262   ASM_SIMP_TAC[] THEN
2263   REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_NOT_LE])) THEN
2264   NORM_ARITH_TAC);;
2265
2266 let HAS_INTEGRAL_SUB = prove
2267  (`!f:real^M->real^N g s.
2268         (f has_integral k) s /\ (g has_integral l) s
2269         ==> ((\x. f(x) - g(x)) has_integral (k - l)) s`,
2270   SIMP_TAC[VECTOR_SUB; HAS_INTEGRAL_NEG; HAS_INTEGRAL_ADD]);;
2271
2272 let INTEGRAL_0 = prove
2273  (`!s. integral s (\x. vec 0) = vec 0`,
2274   MESON_TAC[INTEGRAL_UNIQUE; HAS_INTEGRAL_0]);;
2275
2276 let INTEGRAL_ADD = prove
2277  (`!f:real^M->real^N g k l s.
2278         f integrable_on s /\ g integrable_on s
2279         ==> integral s (\x. f x + g x) = integral s f + integral s g`,
2280   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
2281   MATCH_MP_TAC HAS_INTEGRAL_ADD THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);;
2282
2283 let INTEGRAL_CMUL = prove
2284  (`!f:real^M->real^N c s.
2285         f integrable_on s ==> integral s (\x. c % f(x)) = c % integral s f`,
2286   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
2287   MATCH_MP_TAC HAS_INTEGRAL_CMUL THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);;
2288
2289 let INTEGRAL_NEG = prove
2290  (`!f:real^M->real^N s.
2291         f integrable_on s ==> integral s (\x. --f(x)) = --integral s f`,
2292   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
2293   MATCH_MP_TAC HAS_INTEGRAL_NEG THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);;
2294
2295 let INTEGRAL_SUB = prove
2296  (`!f:real^M->real^N g k l s.
2297         f integrable_on s /\ g integrable_on s
2298         ==> integral s (\x. f x - g x) = integral s f - integral s g`,
2299   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
2300   MATCH_MP_TAC HAS_INTEGRAL_SUB THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);;
2301
2302 let INTEGRABLE_0 = prove
2303  (`!s. (\x. vec 0) integrable_on s`,
2304   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_0]);;
2305
2306 let INTEGRABLE_ADD = prove
2307  (`!f:real^M->real^N g s.
2308         f integrable_on s /\ g integrable_on s
2309         ==> (\x. f x + g x) integrable_on s`,
2310   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_ADD]);;
2311
2312 let INTEGRABLE_CMUL = prove
2313  (`!f:real^M->real^N c s.
2314         f integrable_on s ==> (\x. c % f(x)) integrable_on s`,
2315   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_CMUL]);;
2316
2317 let INTEGRABLE_CMUL_EQ = prove
2318  (`!f:real^M->real^N s c.
2319       (\x. c % f x) integrable_on s <=> c = &0 \/ f integrable_on s`,
2320   REPEAT(STRIP_TAC ORELSE EQ_TAC) THEN
2321   ASM_SIMP_TAC[INTEGRABLE_CMUL; VECTOR_MUL_LZERO; INTEGRABLE_0] THEN
2322   ASM_CASES_TAC `c = &0` THEN ASM_REWRITE_TAC[] THEN
2323   FIRST_X_ASSUM(MP_TAC o SPEC `inv c:real` o MATCH_MP INTEGRABLE_CMUL) THEN
2324   ASM_SIMP_TAC[VECTOR_MUL_ASSOC; VECTOR_MUL_LID; REAL_MUL_LINV; ETA_AX]);;
2325
2326 let INTEGRABLE_NEG = prove
2327  (`!f:real^M->real^N s.
2328         f integrable_on s ==> (\x. --f(x)) integrable_on s`,
2329   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_NEG]);;
2330
2331 let INTEGRABLE_SUB = prove
2332  (`!f:real^M->real^N g s.
2333         f integrable_on s /\ g integrable_on s
2334         ==> (\x. f x - g x) integrable_on s`,
2335   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_SUB]);;
2336
2337 let INTEGRABLE_LINEAR = prove
2338  (`!f h s. f integrable_on s /\ linear h ==> (h o f) integrable_on s`,
2339   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_LINEAR]);;
2340
2341 let INTEGRAL_LINEAR = prove
2342  (`!f:real^M->real^N s h:real^N->real^P.
2343         f integrable_on s /\ linear h
2344         ==> integral s (h o f) = h(integral s f)`,
2345   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_UNIQUE THEN
2346   MAP_EVERY EXISTS_TAC
2347    [`(h:real^N->real^P) o (f:real^M->real^N)`; `s:real^M->bool`] THEN
2348   CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC HAS_INTEGRAL_LINEAR] THEN
2349   ASM_SIMP_TAC[GSYM HAS_INTEGRAL_INTEGRAL; INTEGRABLE_LINEAR]);;
2350
2351 let HAS_INTEGRAL_VSUM = prove
2352  (`!f:A->real^M->real^N s t.
2353         FINITE t /\
2354         (!a. a IN t ==> ((f a) has_integral (i a)) s)
2355         ==> ((\x. vsum t (\a. f a x)) has_integral (vsum t i)) s`,
2356   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
2357   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2358   SIMP_TAC[VSUM_CLAUSES; HAS_INTEGRAL_0; IN_INSERT] THEN
2359   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_ADD THEN
2360   ASM_REWRITE_TAC[ETA_AX] THEN CONJ_TAC THEN
2361   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[]);;
2362
2363 let INTEGRAL_VSUM = prove
2364  (`!f:A->real^M->real^N s t.
2365         FINITE t /\
2366         (!a. a IN t ==> (f a) integrable_on s)
2367         ==> integral s (\x. vsum t (\a. f a x)) =
2368                 vsum t (\a. integral s (f a))`,
2369   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
2370   MATCH_MP_TAC HAS_INTEGRAL_VSUM THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);;
2371
2372 let INTEGRABLE_VSUM = prove
2373  (`!f:A->real^M->real^N s t.
2374         FINITE t /\
2375         (!a. a IN t ==> (f a) integrable_on s)
2376         ==>  (\x. vsum t (\a. f a x)) integrable_on s`,
2377   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_VSUM]);;
2378
2379 let HAS_INTEGRAL_EQ = prove
2380  (`!f:real^M->real^N g k s.
2381         (!x. x IN s ==> (f(x) = g(x))) /\
2382         (f has_integral k) s
2383         ==> (g has_integral k) s`,
2384   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
2385   DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o MATCH_MP HAS_INTEGRAL_IS_0) MP_TAC) THEN
2386   REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_SUB) THEN
2387   SIMP_TAC[VECTOR_ARITH `x - (x - y:real^N) = y`; ETA_AX; VECTOR_SUB_RZERO]);;
2388
2389 let INTEGRABLE_EQ = prove
2390  (`!f:real^M->real^N g s.
2391         (!x. x IN s ==> (f(x) = g(x))) /\
2392         f integrable_on s
2393         ==> g integrable_on s`,
2394   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_EQ]);;
2395
2396 let HAS_INTEGRAL_EQ_EQ = prove
2397  (`!f:real^M->real^N g k s.
2398         (!x. x IN s ==> (f(x) = g(x)))
2399         ==> ((f has_integral k) s <=> (g has_integral k) s)`,
2400   MESON_TAC[HAS_INTEGRAL_EQ]);;
2401
2402 let HAS_INTEGRAL_NULL = prove
2403  (`!f:real^M->real^N a b.
2404     content(interval[a,b]) = &0 ==> (f has_integral vec 0) (interval[a,b])`,
2405   REPEAT STRIP_TAC THEN REWRITE_TAC[has_integral] THEN
2406   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2407   EXISTS_TAC `\x:real^M. ball(x,&1)` THEN REWRITE_TAC[GAUGE_TRIVIAL] THEN
2408   REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_SUB_RZERO] THEN
2409   MATCH_MP_TAC(REAL_ARITH `x = &0 /\ &0 < e ==> x < e`) THEN
2410   ASM_REWRITE_TAC[NORM_EQ_0] THEN ASM_MESON_TAC[VSUM_CONTENT_NULL]);;
2411
2412 let HAS_INTEGRAL_NULL_EQ = prove
2413  (`!f a b i. content(interval[a,b]) = &0
2414              ==> ((f has_integral i) (interval[a,b]) <=> i = vec 0)`,
2415   ASM_MESON_TAC[INTEGRAL_UNIQUE; HAS_INTEGRAL_NULL]);;
2416
2417 let INTEGRAL_NULL = prove
2418  (`!f a b. content(interval[a,b]) = &0
2419            ==> integral(interval[a,b]) f = vec 0`,
2420   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
2421   ASM_MESON_TAC[HAS_INTEGRAL_NULL]);;
2422
2423 let INTEGRABLE_ON_NULL = prove
2424  (`!f a b. content(interval[a,b]) = &0
2425            ==> f integrable_on interval[a,b]`,
2426   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_NULL]);;
2427
2428 let HAS_INTEGRAL_EMPTY = prove
2429  (`!f. (f has_integral vec 0) {}`,
2430   MESON_TAC[HAS_INTEGRAL_NULL; CONTENT_EMPTY; EMPTY_AS_INTERVAL]);;
2431
2432 let HAS_INTEGRAL_EMPTY_EQ = prove
2433  (`!f i. (f has_integral i) {} <=> i = vec 0`,
2434   MESON_TAC[HAS_INTEGRAL_UNIQUE; HAS_INTEGRAL_EMPTY]);;
2435
2436 let INTEGRABLE_ON_EMPTY = prove
2437  (`!f. f integrable_on {}`,
2438   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_EMPTY]);;
2439
2440 let INTEGRAL_EMPTY = prove
2441  (`!f. integral {} f = vec 0`,
2442   MESON_TAC[EMPTY_AS_INTERVAL; INTEGRAL_UNIQUE; HAS_INTEGRAL_EMPTY]);;
2443
2444 let HAS_INTEGRAL_REFL = prove
2445  (`!f a. (f has_integral vec 0) (interval[a,a])`,
2446   REPEAT GEN_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_NULL THEN
2447   SIMP_TAC[INTERVAL_SING; INTERIOR_CLOSED_INTERVAL; CONTENT_EQ_0_INTERIOR]);;
2448
2449 let INTEGRABLE_ON_REFL = prove
2450  (`!f a. f integrable_on interval[a,a]`,
2451   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_REFL]);;
2452
2453 let INTEGRAL_REFL = prove
2454  (`!f a. integral (interval[a,a]) f = vec 0`,
2455   MESON_TAC[INTEGRAL_UNIQUE; HAS_INTEGRAL_REFL]);;
2456
2457 (* ------------------------------------------------------------------------- *)
2458 (* Cauchy-type criterion for integrability.                                  *)
2459 (* ------------------------------------------------------------------------- *)
2460
2461 let INTEGRABLE_CAUCHY = prove
2462  (`!f:real^M->real^N a b.
2463     f integrable_on interval[a,b] <=>
2464         !e. &0 < e
2465             ==> ?d. gauge d /\
2466                     !p1 p2. p1 tagged_division_of interval[a,b] /\ d fine p1 /\
2467                             p2 tagged_division_of interval[a,b] /\ d fine p2
2468                             ==> norm(vsum p1 (\(x,k). content k % f x) -
2469                                      vsum p2 (\(x,k). content k % f x)) < e`,
2470   REPEAT GEN_TAC THEN REWRITE_TAC[integrable_on; has_integral] THEN
2471   EQ_TAC THEN DISCH_TAC THENL
2472    [X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2473     FIRST_X_ASSUM(X_CHOOSE_THEN `y:real^N` (MP_TAC o SPEC `e / &2`)) THEN
2474     ASM_REWRITE_TAC[REAL_HALF] THEN MATCH_MP_TAC MONO_EXISTS THEN
2475     X_GEN_TAC `d:real^M->real^M->bool` THEN
2476     REWRITE_TAC[GSYM dist] THEN MESON_TAC[DIST_TRIANGLE_HALF_L];
2477     ALL_TAC] THEN
2478   FIRST_X_ASSUM(MP_TAC o GEN `n:num` o SPEC `inv(&n + &1)`) THEN
2479   REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`; SKOLEM_THM] THEN
2480   DISCH_THEN(X_CHOOSE_THEN `d:num->real^M->real^M->bool` MP_TAC) THEN
2481   REWRITE_TAC[FORALL_AND_THM] THEN
2482   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*")) THEN
2483   MP_TAC(GEN `n:num`
2484    (ISPECL [`\x. INTERS {(d:num->real^M->real^M->bool) i x | i IN 0..n}`;
2485             `a:real^M`; `b:real^M`]
2486      FINE_DIVISION_EXISTS)) THEN
2487   ASM_SIMP_TAC[GAUGE_INTERS; FINE_INTERS; FINITE_NUMSEG; SKOLEM_THM] THEN
2488   REWRITE_TAC[IN_NUMSEG; LE_0; FORALL_AND_THM] THEN
2489   DISCH_THEN(X_CHOOSE_THEN `p:num->(real^M#(real^M->bool))->bool`
2490     STRIP_ASSUME_TAC) THEN
2491   SUBGOAL_THEN
2492     `cauchy (\n. vsum (p n)
2493                    (\(x,k:real^M->bool). content k % (f:real^M->real^N) x))`
2494   MP_TAC THENL
2495    [REWRITE_TAC[cauchy] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2496     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN
2497     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
2498     MATCH_MP_TAC WLOG_LE THEN CONJ_TAC THENL
2499      [MESON_TAC[DIST_SYM]; ALL_TAC] THEN
2500     MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN REWRITE_TAC[GE] THEN
2501     REPEAT STRIP_TAC THEN
2502     MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `inv(&m + &1)` THEN
2503     CONJ_TAC THENL
2504      [REWRITE_TAC[dist] THEN ASM_MESON_TAC[LE_REFL]; ALL_TAC] THEN
2505     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `inv(&N)` THEN
2506     ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
2507     REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
2508     ASM_ARITH_TAC;
2509     ALL_TAC] THEN
2510   REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY; LIM_SEQUENTIALLY] THEN
2511   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN
2512   REWRITE_TAC[dist] THEN STRIP_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2513   MP_TAC(SPEC `e / &2` REAL_ARCH_INV) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
2514   DISCH_THEN(X_CHOOSE_THEN `N1:num` STRIP_ASSUME_TAC) THEN
2515   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
2516   DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN EXISTS_TAC
2517    `(d:num->real^M->real^M->bool) (N1 + N2)` THEN
2518   ASM_REWRITE_TAC[] THEN
2519   X_GEN_TAC `q:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
2520   REWRITE_TAC[GSYM dist] THEN MATCH_MP_TAC DIST_TRIANGLE_HALF_L THEN
2521   EXISTS_TAC `vsum (p(N1+N2:num))
2522                   (\(x,k:real^M->bool). content k % (f:real^M->real^N) x)` THEN
2523   CONJ_TAC THENL
2524    [REWRITE_TAC[dist] THEN MATCH_MP_TAC REAL_LTE_TRANS THEN
2525     EXISTS_TAC `inv(&(N1 + N2) + &1)` THEN CONJ_TAC THENL
2526      [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[LE_REFL]; ALL_TAC] THEN
2527     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `inv(&N1)` THEN
2528     ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
2529     REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
2530     ASM_ARITH_TAC;
2531     ONCE_REWRITE_TAC[DIST_SYM] THEN REWRITE_TAC[dist] THEN
2532     FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC]);;
2533
2534 (* ------------------------------------------------------------------------- *)
2535 (* Additivity of integral on abutting intervals.                             *)
2536 (* ------------------------------------------------------------------------- *)
2537
2538 let INTERVAL_SPLIT = prove
2539  (`!a b:real^N c k.
2540     1 <= k /\ k <= dimindex(:N)
2541     ==> interval[a,b] INTER {x | x$k <= c} =
2542         interval[a,(lambda i. if i = k then min (b$k) c else b$i)] /\
2543         interval[a,b] INTER {x | x$k >= c} =
2544         interval[(lambda i. if i = k then max (a$k) c else a$i),b]`,
2545   REPEAT STRIP_TAC THEN
2546   REWRITE_TAC[EXTENSION; IN_INTERVAL; IN_INTER; IN_ELIM_THM] THEN
2547   ASM_SIMP_TAC[LAMBDA_BETA] THEN X_GEN_TAC `y:real^N` THEN
2548   MATCH_MP_TAC(TAUT `(c ==> b) /\ (c ==> a) /\ (a /\ b ==> c)
2549                      ==> (a /\ b <=> c)`) THEN
2550   (CONJ_TAC THENL
2551     [ASM_MESON_TAC[REAL_MAX_LE; REAL_LE_MIN; real_ge];  ALL_TAC]) THEN
2552   REWRITE_TAC[LEFT_AND_FORALL_THM; real_ge] THEN CONJ_TAC THEN
2553   MATCH_MP_TAC MONO_FORALL THEN ASM_MESON_TAC[REAL_MAX_LE; REAL_LE_MIN]);;
2554
2555 let CONTENT_SPLIT = prove
2556  (`!a b:real^N k.
2557     1 <= k /\ k <= dimindex(:N)
2558     ==> content(interval[a,b]) =
2559         content(interval[a,b] INTER {x | x$k <= c}) +
2560         content(interval[a,b] INTER {x | x$k >= c})`,
2561   SIMP_TAC[INTERVAL_SPLIT; CONTENT_CLOSED_INTERVAL_CASES; LAMBDA_BETA] THEN
2562   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_ARITH
2563    `((a <= if p then b else c) <=> (p ==> a <= b) /\ (~p ==> a <= c)) /\
2564     ((if p then b else c) <= a <=> (p ==> b <= a) /\ (~p ==> c <= a))`] THEN
2565   REWRITE_TAC[REAL_LE_MIN; REAL_MAX_LE] THEN
2566   REWRITE_TAC[MESON[] `(i = k ==> p i k) <=> (i = k ==> p i i)`] THEN
2567   REWRITE_TAC[TAUT `(p ==> a /\ b) /\ (~p ==> a) <=> a /\ (p ==> b)`] THEN
2568   REWRITE_TAC[TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN
2569   REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN
2570   ASM_CASES_TAC
2571    `!i. 1 <= i /\ i <= dimindex(:N) ==> (a:real^N)$i <= (b:real^N)$i` THEN
2572   ASM_REWRITE_TAC[REAL_ADD_RID] THEN
2573   REWRITE_TAC[MESON[] `(!i. P i ==> i = k ==> Q i) <=> (P k ==> Q k)`] THEN
2574   ASM_REWRITE_TAC[] THEN
2575   REWRITE_TAC[REAL_ARITH `min b c = if c <= b then c else b`;
2576               REAL_ARITH `max a c = if a <= c then c else a`] THEN
2577   REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_ADD_LID; REAL_ADD_RID]) THEN
2578   REWRITE_TAC[MESON[] `(if i = k then a k else a i) = a i`] THENL
2579    [ALL_TAC; ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL]] THEN
2580   SUBGOAL_THEN `1..dimindex(:N) = k INSERT ((1..dimindex(:N)) DELETE k)`
2581   SUBST1_TAC THENL
2582    [REWRITE_TAC[EXTENSION; IN_INSERT; IN_DELETE; IN_NUMSEG] THEN
2583     ASM_MESON_TAC[];
2584     ALL_TAC] THEN
2585   SIMP_TAC[PRODUCT_CLAUSES; FINITE_DELETE; FINITE_NUMSEG; IN_DELETE] THEN
2586   MATCH_MP_TAC(REAL_RING
2587    `p'' = p /\ p':real = p
2588     ==> (b - a) * p = (c - a) * p' + (b - c) * p''`) THEN
2589   CONJ_TAC THEN MATCH_MP_TAC PRODUCT_EQ THEN SIMP_TAC[IN_DELETE]);;
2590
2591 let DIVISION_SPLIT_LEFT_INJ,DIVISION_SPLIT_RIGHT_INJ = (CONJ_PAIR o prove)
2592  (`(!d i k1 k2 k c.
2593         d division_of i /\ 1 <= k /\ k <= dimindex(:N) /\
2594         k1 IN d /\ k2 IN d /\ ~(k1 = k2) /\
2595         k1 INTER {x | x$k <= c} = k2 INTER {x | x$k <= c}
2596         ==> content(k1 INTER {x:real^N | x$k <= c}) = &0) /\
2597    (!d i k1 k2 k c.
2598         d division_of i /\ 1 <= k /\ k <= dimindex(:N) /\
2599         k1 IN d /\ k2 IN d /\ ~(k1 = k2) /\
2600         k1 INTER {x | x$k >= c} = k2 INTER {x | x$k >= c}
2601         ==> content(k1 INTER {x:real^N | x$k >= c}) = &0)`,
2602   let lemma = prove
2603    (`!a b:real^N c k.
2604       1 <= k /\ k <= dimindex(:N)
2605       ==> (content(interval[a,b] INTER {x | x$k <= c}) = &0 <=>
2606            interior(interval[a,b] INTER {x | x$k <= c}) = {}) /\
2607           (content(interval[a,b] INTER {x | x$k >= c}) = &0 <=>
2608            interior(interval[a,b] INTER {x | x$k >= c}) = {})`,
2609     SIMP_TAC[INTERVAL_SPLIT; CONTENT_EQ_0_INTERIOR]) in
2610   REPEAT STRIP_TAC THEN
2611   REWRITE_TAC[CONTENT_EQ_0_INTERIOR] THEN
2612   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
2613   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (MP_TAC o CONJUNCT1) o CONJUNCT2) THEN
2614   DISCH_THEN(MP_TAC o SPECL
2615     [`k1:real^N->bool`; `k2:real^N->bool`]) THEN
2616   ASM_REWRITE_TAC[PAIR_EQ] THEN DISCH_TAC THEN
2617   DISCH_THEN(MP_TAC o SPEC `k2:real^N->bool`) THEN
2618   ASM_REWRITE_TAC[] THEN
2619   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
2620   DISCH_THEN(X_CHOOSE_THEN `u:real^N` (X_CHOOSE_THEN `v:real^N`
2621     SUBST_ALL_TAC)) THEN
2622   ASM_SIMP_TAC[lemma] THEN
2623   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
2624    `s INTER t = {}
2625     ==> u SUBSET s /\ u SUBSET t ==> u = {}`)) THEN
2626   CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN ASM SET_TAC[]);;
2627
2628 let TAGGED_DIVISION_SPLIT_LEFT_INJ = prove
2629  (`!d i x1 k1 x2 k2 k c.
2630         d tagged_division_of i /\ 1 <= k /\ k <= dimindex(:N) /\
2631         (x1,k1) IN d /\ (x2,k2) IN d /\ ~(k1 = k2) /\
2632         k1 INTER {x | x$k <= c} = k2 INTER {x | x$k <= c}
2633         ==> content(k1 INTER {x:real^N | x$k <= c}) = &0`,
2634   REPEAT STRIP_TAC THEN
2635   FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_TAGGED_DIVISION) THEN
2636   MATCH_MP_TAC DIVISION_SPLIT_LEFT_INJ THEN
2637   EXISTS_TAC `IMAGE SND (d:(real^N#(real^N->bool))->bool)` THEN
2638   ASM_REWRITE_TAC[IN_IMAGE] THEN ASM_MESON_TAC[SND]);;
2639
2640 let TAGGED_DIVISION_SPLIT_RIGHT_INJ = prove
2641  (`!d i x1 k1 x2 k2 k c.
2642         d tagged_division_of i /\ 1 <= k /\ k <= dimindex(:N) /\
2643         (x1,k1) IN d /\ (x2,k2) IN d /\ ~(k1 = k2) /\
2644         k1 INTER {x | x$k >= c} = k2 INTER {x | x$k >= c}
2645         ==> content(k1 INTER {x:real^N | x$k >= c}) = &0`,
2646   REPEAT STRIP_TAC THEN
2647   FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_TAGGED_DIVISION) THEN
2648   MATCH_MP_TAC DIVISION_SPLIT_RIGHT_INJ THEN
2649   EXISTS_TAC `IMAGE SND (d:(real^N#(real^N->bool))->bool)` THEN
2650   ASM_REWRITE_TAC[IN_IMAGE] THEN ASM_MESON_TAC[SND]);;
2651
2652 let DIVISION_SPLIT = prove
2653  (`!p a b:real^N k c.
2654      p division_of interval[a,b] /\ 1 <= k /\ k <= dimindex(:N)
2655      ==> {l INTER {x | x$k <= c} |l| l IN p /\ ~(l INTER {x | x$k <= c} = {})}
2656          division_of (interval[a,b] INTER {x | x$k <= c}) /\
2657          {l INTER {x | x$k >= c} |l| l IN p /\ ~(l INTER {x | x$k >= c} = {})}
2658          division_of (interval[a,b] INTER {x | x$k >= c})`,
2659   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
2660   SIMP_TAC[division_of; FINITE_IMAGE] THEN
2661   SIMP_TAC[SET_RULE `(!x. x IN {f x | P x} ==> Q x) <=> (!x. P x ==> Q (f x))`;
2662            MESON[] `(!x y. x IN s /\ y IN t /\ Q x y ==> P x y) <=>
2663                     (!x. x IN s ==> !y. y IN t ==> Q x y ==> P x y)`;
2664            RIGHT_FORALL_IMP_THM] THEN
2665   REPEAT(MATCH_MP_TAC(TAUT
2666    `(a ==> a' /\ a'') /\ (b ==> b' /\ b'')
2667       ==> a /\ b ==> (a' /\ b') /\ (a'' /\ b'')`) THEN CONJ_TAC)
2668   THENL
2669    [ONCE_REWRITE_TAC[SET_RULE
2670     `{f x |x| x IN s /\ ~(f x = {})} = {y | y IN IMAGE f s /\ ~(y = {})}`] THEN
2671     SIMP_TAC[FINITE_RESTRICT; FINITE_IMAGE];
2672     REWRITE_TAC[AND_FORALL_THM] THEN
2673     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `l:real^N->bool` THEN
2674     DISCH_THEN(fun th -> CONJ_TAC THEN STRIP_TAC THEN MP_TAC th) THEN
2675     (ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_AND THEN
2676      CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
2677      STRIP_TAC THEN ASM_MESON_TAC[INTERVAL_SPLIT]);
2678     DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
2679     (REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2680      DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
2681      REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2682      DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
2683      DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
2684      ANTS_TAC THENL [ASM_MESON_TAC[PAIR_EQ]; ALL_TAC] THEN
2685      MATCH_MP_TAC(SET_RULE
2686       `s SUBSET s' /\ t SUBSET t'
2687        ==> s' INTER t' = {} ==> s INTER t = {}`) THEN
2688      CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]);
2689    DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[INTER_UNIONS] THEN
2690    ONCE_REWRITE_TAC[EXTENSION] THEN REWRITE_TAC[IN_UNIONS] THEN
2691    CONJ_TAC THEN GEN_TAC THEN AP_TERM_TAC THEN
2692    GEN_REWRITE_TAC I [FUN_EQ_THM] THEN GEN_TAC THEN
2693    REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN MESON_TAC[NOT_IN_EMPTY]]);;
2694
2695 let HAS_INTEGRAL_SPLIT = prove
2696  (`!f:real^M->real^N k a b c.
2697       (f has_integral i) (interval[a,b] INTER {x | x$k <= c}) /\
2698       (f has_integral j) (interval[a,b] INTER {x | x$k >= c}) /\
2699       1 <= k /\ k <= dimindex(:M)
2700       ==> (f has_integral (i + j)) (interval[a,b])`,
2701   let lemma1 = prove
2702    (`(!x k. (x,k) IN {x,f k | P x k} ==> Q x k) <=>
2703      (!x k. P x k ==> Q x (f k))`,
2704     REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN
2705     SET_TAC[]) in
2706   let lemma2 = prove
2707    (`!f:B->B s:(A#B)->bool.
2708       FINITE s ==> FINITE {x,f k | (x,k) IN s /\ P x k}`,
2709     REPEAT STRIP_TAC THEN MATCH_MP_TAC FINITE_SUBSET THEN
2710     EXISTS_TAC `IMAGE (\(x:A,k:B). x,(f k:B)) s` THEN
2711     ASM_SIMP_TAC[FINITE_IMAGE] THEN
2712     REWRITE_TAC[SUBSET; FORALL_PAIR_THM; lemma1; IN_IMAGE] THEN
2713     REWRITE_TAC[EXISTS_PAIR_THM; PAIR_EQ] THEN MESON_TAC[]) in
2714   let lemma3 = prove
2715    (`!f:real^M->real^N g:(real^M->bool)->(real^M->bool) p.
2716      FINITE p
2717      ==> vsum {x,g k |x,k| (x,k) IN p /\ ~(g k = {})}
2718               (\(x,k). content k % f x) =
2719          vsum (IMAGE (\(x,k). x,g k) p) (\(x,k). content k % f x)`,
2720     REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN
2721     ASM_SIMP_TAC[FINITE_IMAGE; lemma2] THEN
2722     REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE] THEN
2723     REWRITE_TAC[FORALL_PAIR_THM; SUBSET; IN_IMAGE; EXISTS_PAIR_THM] THEN
2724     REWRITE_TAC[IN_ELIM_THM; PAIR_EQ; VECTOR_MUL_EQ_0] THEN
2725     MESON_TAC[CONTENT_EMPTY]) in
2726   let lemma4 = prove
2727    (`(\(x,l). content (g l) % f x) =
2728      (\(x,l). content l % f x) o (\(x,l). x,g l)`,
2729     REWRITE_TAC[FUN_EQ_THM; o_THM; FORALL_PAIR_THM]) in
2730   REPEAT GEN_TAC THEN
2731   ASM_CASES_TAC `1 <= k /\ k <= dimindex(:M)` THEN ASM_REWRITE_TAC[] THEN
2732   ASM_SIMP_TAC[INTERVAL_SPLIT] THEN REWRITE_TAC[has_integral] THEN
2733   ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THEN FIRST_X_ASSUM STRIP_ASSUME_TAC THEN
2734   DISCH_TAC THEN X_GEN_TAC `e:real` THEN STRIP_TAC THEN
2735   FIRST_X_ASSUM(CONJUNCTS_THEN2 (MP_TAC o SPEC `e / &2`) STRIP_ASSUME_TAC) THEN
2736   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
2737   DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool`
2738    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "I2"))) THEN
2739   DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool`
2740    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "I1"))) THEN
2741   EXISTS_TAC `\x. if x$k = c then (d1(x:real^M) INTER d2(x)):real^M->bool
2742                   else ball(x,abs(x$k - c)) INTER d1(x) INTER d2(x)` THEN
2743   CONJ_TAC THENL
2744    [REWRITE_TAC[gauge] THEN GEN_TAC THEN
2745     RULE_ASSUM_TAC(REWRITE_RULE[gauge]) THEN COND_CASES_TAC THEN
2746     ASM_SIMP_TAC[OPEN_INTER; IN_INTER; OPEN_BALL; IN_BALL] THEN
2747     ASM_REWRITE_TAC[DIST_REFL; GSYM REAL_ABS_NZ; REAL_SUB_0];
2748     ALL_TAC] THEN
2749   X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
2750   SUBGOAL_THEN
2751     `(!x:real^M kk. (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k <= c} = {})
2752                     ==> x$k <= c) /\
2753      (!x:real^M kk. (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k >= c} = {})
2754                     ==> x$k >= c)`
2755   STRIP_ASSUME_TAC THENL
2756    [CONJ_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
2757     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
2758     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `kk:real^M->bool` THEN
2759     DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
2760     COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL; real_ge] THEN DISCH_THEN
2761      (MP_TAC o MATCH_MP (SET_RULE `k SUBSET (a INTER b) ==> k SUBSET a`)) THEN
2762     REWRITE_TAC[SUBSET; IN_BALL; dist] THEN DISCH_TAC THEN
2763     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
2764     DISCH_THEN(X_CHOOSE_THEN `u:real^M` MP_TAC) THEN
2765     REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
2766     FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M`) THEN ASM_REWRITE_TAC[] THEN
2767     ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
2768     REWRITE_TAC[REAL_NOT_LE; REAL_NOT_LT] THEN STRIP_TAC THEN
2769     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((x - u:real^M)$k)` THEN
2770     ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
2771     ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
2772     ASM_REAL_ARITH_TAC;
2773     ALL_TAC] THEN
2774   REMOVE_THEN "I2" (MP_TAC o SPEC
2775    `{(x:real^M,kk INTER {x:real^M | x$k >= c}) |x,kk|
2776      (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k >= c} = {})}`) THEN
2777   REMOVE_THEN "I1" (MP_TAC o SPEC
2778    `{(x:real^M,kk INTER {x:real^M | x$k <= c}) |x,kk|
2779      (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k <= c} = {})}`) THEN
2780   MATCH_MP_TAC(TAUT
2781    `(a /\ b) /\ (a' /\ b' ==> c) ==> (a ==> a') ==> (b ==> b') ==> c`) THEN
2782   CONJ_TAC THENL
2783    [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
2784     REWRITE_TAC[TAGGED_DIVISION_OF] THEN
2785     REPEAT(MATCH_MP_TAC(TAUT
2786      `(a ==> (a' /\ a'')) /\ (b ==> (b' /\ d) /\ (b'' /\ e))
2787       ==> a /\ b ==> ((a' /\ b') /\ d) /\ ((a'' /\ b'') /\ e)`) THEN
2788       CONJ_TAC) THEN
2789     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
2790     REWRITE_TAC[lemma1] THEN REWRITE_TAC[IMP_IMP] THENL
2791      [SIMP_TAC[lemma2];
2792       REWRITE_TAC[AND_FORALL_THM] THEN
2793       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
2794       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `kk:real^M->bool` THEN
2795       DISCH_THEN(fun th -> CONJ_TAC THEN STRIP_TAC THEN MP_TAC th) THEN
2796       (ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
2797         [SIMP_TAC[IN_INTER; IN_ELIM_THM] THEN ASM_MESON_TAC[]; ALL_TAC]) THEN
2798       (MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL [SET_TAC[]; ALL_TAC]) THEN
2799       ASM_MESON_TAC[INTERVAL_SPLIT];
2800       DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
2801       (REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2802        DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
2803        REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2804        DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
2805        ANTS_TAC THENL [ASM_MESON_TAC[PAIR_EQ]; ALL_TAC] THEN
2806        MATCH_MP_TAC(SET_RULE
2807         `s SUBSET s' /\ t SUBSET t'
2808          ==> s' INTER t' = {} ==> s INTER t = {}`) THEN
2809        CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]);
2810       ALL_TAC] THEN
2811     MATCH_MP_TAC(TAUT `(a ==> b /\ c) /\ d /\ e
2812                        ==> (a ==> (b /\ d) /\ (c /\ e))`) THEN
2813     CONJ_TAC THENL
2814      [DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
2815       DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[INTER_UNIONS] THEN
2816       ONCE_REWRITE_TAC[EXTENSION] THEN REWRITE_TAC[IN_UNIONS] THEN
2817       X_GEN_TAC `x:real^M` THEN AP_TERM_TAC THEN
2818       GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `kk:real^M->bool` THEN
2819       REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN MESON_TAC[NOT_IN_EMPTY];
2820       ALL_TAC] THEN
2821     CONJ_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
2822     REWRITE_TAC[fine; lemma1] THEN
2823     REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2824     DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
2825     ASM_SIMP_TAC[] THEN SET_TAC[];
2826     ALL_TAC] THEN
2827   DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH
2828    `x < e / &2 /\ y < e / &2 ==> x + y < e`)) THEN
2829   DISCH_THEN(MP_TAC o MATCH_MP NORM_TRIANGLE_LT) THEN
2830   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
2831   REWRITE_TAC[VECTOR_ARITH
2832    `(a - i) + (b - j) = c - (i + j) <=> a + b = c:real^N`] THEN
2833   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
2834  MATCH_MP_TAC EQ_TRANS THEN
2835   EXISTS_TAC
2836    `vsum p (\(x,l). content (l INTER {x:real^M | x$k <= c}) %
2837                      (f:real^M->real^N) x) +
2838     vsum p (\(x,l). content (l INTER {x:real^M | x$k >= c}) %
2839                      (f:real^M->real^N) x)` THEN
2840   CONJ_TAC THENL
2841    [ALL_TAC;
2842     ASM_SIMP_TAC[GSYM VSUM_ADD] THEN MATCH_MP_TAC VSUM_EQ THEN
2843     REWRITE_TAC[FORALL_PAIR_THM; GSYM VECTOR_ADD_RDISTRIB] THEN
2844     MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
2845     DISCH_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
2846     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
2847     DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `l:real^M->bool`] o
2848                el 1 o CONJUNCTS) THEN
2849     ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
2850     ASM_SIMP_TAC[GSYM CONTENT_SPLIT]] THEN
2851   ASM_SIMP_TAC[lemma3] THEN BINOP_TAC THEN
2852   (GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [lemma4] THEN
2853    MATCH_MP_TAC VSUM_IMAGE_NONZERO THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
2854    REWRITE_TAC[PAIR_EQ] THEN
2855    ASM_MESON_TAC[TAGGED_DIVISION_SPLIT_LEFT_INJ; VECTOR_MUL_LZERO;
2856                  TAGGED_DIVISION_SPLIT_RIGHT_INJ]));;
2857
2858 (* ------------------------------------------------------------------------- *)
2859 (* A sort of converse, integrability on subintervals.                        *)
2860 (* ------------------------------------------------------------------------- *)
2861
2862 let TAGGED_DIVISION_UNION_INTERVAL = prove
2863  (`!a b:real^N p1 p2 c k.
2864         1 <= k /\ k <= dimindex(:N) /\
2865         p1 tagged_division_of (interval[a,b] INTER {x | x$k <= c}) /\
2866         p2 tagged_division_of (interval[a,b] INTER {x | x$k >= c})
2867         ==> (p1 UNION p2) tagged_division_of (interval[a,b])`,
2868   REPEAT STRIP_TAC THEN SUBGOAL_THEN
2869    `interval[a,b] = (interval[a,b] INTER {x:real^N | x$k <= c}) UNION
2870                     (interval[a,b] INTER {x:real^N | x$k >= c})`
2871   SUBST1_TAC THENL
2872    [MATCH_MP_TAC(SET_RULE
2873      `(t UNION u = UNIV) ==> s = (s INTER t) UNION (s INTER u)`) THEN
2874     REWRITE_TAC[EXTENSION; IN_UNIV; IN_UNION; IN_ELIM_THM] THEN REAL_ARITH_TAC;
2875     ALL_TAC] THEN
2876   MATCH_MP_TAC TAGGED_DIVISION_UNION THEN ASM_REWRITE_TAC[] THEN
2877   ASM_SIMP_TAC[INTERVAL_SPLIT; INTERIOR_CLOSED_INTERVAL] THEN
2878   REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY; IN_INTERVAL] THEN
2879   GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN (MP_TAC o SPEC `k:num`)) THEN
2880     ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC);;
2881
2882 let HAS_INTEGRAL_SEPARATE_SIDES = prove
2883  (`!f:real^M->real^N i a b k.
2884         (f has_integral i) (interval[a,b]) /\
2885         1 <= k /\ k <= dimindex(:M)
2886         ==> !e. &0 < e
2887                 ==> ?d. gauge d /\
2888                         !p1 p2. p1 tagged_division_of
2889                                      (interval[a,b] INTER {x | x$k <= c}) /\
2890                                 d fine p1 /\
2891                                 p2 tagged_division_of
2892                                      (interval[a,b] INTER {x | x$k >= c}) /\
2893                                 d fine p2
2894                                 ==> norm((vsum p1 (\(x,k). content k % f x) +
2895                                           vsum p2 (\(x,k). content k % f x)) -
2896                                          i) < e`,
2897   REWRITE_TAC[has_integral] THEN REPEAT GEN_TAC THEN
2898   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
2899   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2900   ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
2901   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
2902   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
2903   SUBGOAL_THEN
2904    `vsum p1 (\(x,k). content k % f x) + vsum p2 (\(x,k). content k % f x) =
2905     vsum (p1 UNION p2) (\(x,k:real^M->bool). content k % (f:real^M->real^N) x)`
2906   SUBST1_TAC THENL
2907    [ALL_TAC; ASM_MESON_TAC[TAGGED_DIVISION_UNION_INTERVAL; FINE_UNION]] THEN
2908   CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_UNION_NONZERO THEN
2909   REPEAT(FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I
2910    [TAGGED_DIVISION_OF])) THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
2911   MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
2912   REWRITE_TAC[IN_INTER; VECTOR_MUL_EQ_0] THEN STRIP_TAC THEN DISJ1_TAC THEN
2913   SUBGOAL_THEN
2914    `(?a b:real^M. l = interval[a,b]) /\
2915     l SUBSET (interval[a,b] INTER {x | x$k <= c}) /\
2916     l SUBSET (interval[a,b] INTER {x | x$k >= c})`
2917   MP_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
2918   DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
2919   ASM_REWRITE_TAC[SET_RULE
2920    `s SUBSET t /\ s SUBSET u <=> s SUBSET (t INTER u)`] THEN
2921   ASM_SIMP_TAC[INTERVAL_SPLIT; INTER_INTERVAL] THEN
2922   DISCH_THEN(MP_TAC o MATCH_MP SUBSET_INTERIOR) THEN
2923   REWRITE_TAC[INTERIOR_CLOSED_INTERVAL; CONTENT_EQ_0_INTERIOR] THEN
2924   MATCH_MP_TAC(SET_RULE `t = {} ==> s SUBSET t ==> s = {}`) THEN
2925   REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN EXISTS_TAC `k:num` THEN
2926   ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC);;
2927
2928 let INTEGRABLE_SPLIT = prove
2929  (`!f:real^M->real^N a b.
2930         f integrable_on (interval[a,b]) /\ 1 <= k /\ k <= dimindex(:M)
2931         ==> f integrable_on (interval[a,b] INTER {x | x$k <= c}) /\
2932             f integrable_on (interval[a,b] INTER {x | x$k >= c})`,
2933   let lemma = prove
2934    (`b - a = c
2935      ==> norm(a:real^N) < e / &2 ==> norm(b) < e / &2 ==> norm(c) < e`,
2936     DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[GSYM dist] THEN
2937     REPEAT STRIP_TAC THEN MATCH_MP_TAC DIST_TRIANGLE_HALF_L THEN
2938     EXISTS_TAC `vec 0:real^N` THEN
2939     ASM_REWRITE_TAC[dist; VECTOR_SUB_LZERO; VECTOR_SUB_RZERO; NORM_NEG]) in
2940   REPEAT GEN_TAC THEN
2941   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [integrable_on] THEN
2942   REWRITE_TAC[LEFT_IMP_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
2943   X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN CONJ_TAC THEN
2944   ASM_SIMP_TAC[INTERVAL_SPLIT; INTEGRABLE_CAUCHY] THEN
2945   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2946   FIRST_ASSUM(MP_TAC o SPEC `e / &2` o
2947     MATCH_MP HAS_INTEGRAL_SEPARATE_SIDES) THEN
2948   MAP_EVERY ABBREV_TAC
2949    [`b' = (lambda i. if i = k then min ((b:real^M)$k) c else b$i):real^M`;
2950     `a' = (lambda i. if i = k then max ((a:real^M)$k) c else a$i):real^M`] THEN
2951   ASM_SIMP_TAC[REAL_HALF; INTERVAL_SPLIT] THEN
2952   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
2953   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
2954   FIRST_ASSUM(MP_TAC o MATCH_MP FINE_DIVISION_EXISTS) THENL
2955    [DISCH_THEN(MP_TAC o SPECL [`a':real^M`; `b:real^M`]) THEN
2956     RULE_ASSUM_TAC(ONCE_REWRITE_RULE[SWAP_FORALL_THM]);
2957     DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b':real^M`])] THEN
2958   DISCH_THEN(X_CHOOSE_THEN `p:(real^M#(real^M->bool))->bool`
2959     STRIP_ASSUME_TAC) THEN
2960   REPEAT STRIP_TAC THEN FIRST_X_ASSUM(fun th ->
2961     MP_TAC(SPECL [`p:(real^M#(real^M->bool))->bool`;
2962                   `p1:(real^M#(real^M->bool))->bool`] th) THEN
2963     MP_TAC(SPECL [`p:(real^M#(real^M->bool))->bool`;
2964                   `p2:(real^M#(real^M->bool))->bool`] th)) THEN
2965   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC lemma THEN VECTOR_ARITH_TAC);;
2966
2967 (* ------------------------------------------------------------------------- *)
2968 (* Generalized notion of additivity.                                         *)
2969 (* ------------------------------------------------------------------------- *)
2970
2971 let operative = new_definition
2972  `operative op (f:(real^N->bool)->A) <=>
2973     (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = neutral(op)) /\
2974     (!a b c k. 1 <= k /\ k <= dimindex(:N)
2975                ==> f(interval[a,b]) =
2976                    op (f(interval[a,b] INTER {x | x$k <= c}))
2977                       (f(interval[a,b] INTER {x | x$k >= c})))`;;
2978
2979 let OPERATIVE_TRIVIAL = prove
2980  (`!op f a b.
2981         operative op f /\ content(interval[a,b]) = &0
2982         ==> f(interval[a,b]) = neutral op`,
2983   REWRITE_TAC[operative] THEN MESON_TAC[]);;
2984
2985 let PROPERTY_EMPTY_INTERVAL = prove
2986  (`!P. (!a b:real^N. content(interval[a,b]) = &0 ==> P(interval[a,b]))
2987        ==> P {}`,
2988   MESON_TAC[EMPTY_AS_INTERVAL; CONTENT_EMPTY]);;
2989
2990 let OPERATIVE_EMPTY = prove
2991  (`!op f:(real^N->bool)->A. operative op f ==> f {} = neutral op`,
2992   REPEAT GEN_TAC THEN REWRITE_TAC[operative] THEN
2993   DISCH_THEN(ACCEPT_TAC o MATCH_MP PROPERTY_EMPTY_INTERVAL o CONJUNCT1));;
2994
2995 (* ------------------------------------------------------------------------- *)
2996 (* Using additivity of lifted function to encode definedness.                *)
2997 (* ------------------------------------------------------------------------- *)
2998
2999 let FORALL_OPTION = prove
3000  (`(!x. P x) <=> P NONE /\ !x. P(SOME x)`,
3001   MESON_TAC[cases "option"]);;
3002
3003 let EXISTS_OPTION = prove
3004  (`(?x. P x) <=> P NONE \/ ?x. P(SOME x)`,
3005   MESON_TAC[cases "option"]);;
3006
3007 let lifted = define
3008  `(lifted op NONE _ = NONE) /\
3009   (lifted op _ NONE = NONE) /\
3010   (lifted op (SOME x) (SOME y) = SOME(op x y))`;;
3011
3012 let NEUTRAL_LIFTED = prove
3013  (`!op. monoidal op ==> neutral(lifted op) = SOME(neutral op)`,
3014   REWRITE_TAC[neutral; monoidal] THEN REPEAT STRIP_TAC THEN
3015   MATCH_MP_TAC SELECT_UNIQUE THEN
3016   REWRITE_TAC[FORALL_OPTION; lifted; distinctness "option";
3017               injectivity "option"] THEN
3018   ASM_MESON_TAC[]);;
3019
3020 let MONOIDAL_LIFTED = prove
3021  (`!op. monoidal op ==> monoidal(lifted op)`,
3022   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[NEUTRAL_LIFTED; monoidal] THEN
3023   REWRITE_TAC[FORALL_OPTION; lifted; distinctness "option";
3024               injectivity "option"] THEN
3025   ASM_MESON_TAC[monoidal]);;
3026
3027 let ITERATE_SOME = prove
3028  (`!op. monoidal op
3029         ==> !f s. FINITE s
3030                   ==> iterate (lifted op) s (\x. SOME(f x)) =
3031                       SOME(iterate op s f)`,
3032   GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
3033   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
3034   ASM_SIMP_TAC[ITERATE_CLAUSES; MONOIDAL_LIFTED; NEUTRAL_LIFTED] THEN
3035   REWRITE_TAC[lifted]);;
3036
3037 (* ------------------------------------------------------------------------- *)
3038 (* Two key instances of additivity.                                          *)
3039 (* ------------------------------------------------------------------------- *)
3040
3041 let OPERATIVE_CONTENT = prove
3042  (`operative(+) content`,
3043   REWRITE_TAC[operative; NEUTRAL_REAL_ADD; CONTENT_SPLIT]);;
3044
3045 let OPERATIVE_INTEGRAL = prove
3046  (`!f:real^M->real^N.
3047        operative(lifted(+))
3048          (\i. if f integrable_on i then SOME(integral i f) else NONE)`,
3049   SIMP_TAC[operative; NEUTRAL_LIFTED; MONOIDAL_VECTOR_ADD] THEN
3050   REWRITE_TAC[NEUTRAL_VECTOR_ADD] THEN
3051   REPEAT STRIP_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN
3052   REWRITE_TAC[lifted; distinctness "option"; injectivity "option"] THENL
3053    [REWRITE_TAC[integral] THEN ASM_MESON_TAC[HAS_INTEGRAL_NULL_EQ];
3054     RULE_ASSUM_TAC(REWRITE_RULE[integrable_on]) THEN
3055     ASM_MESON_TAC[HAS_INTEGRAL_NULL];
3056     REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL)) THEN
3057     ASM_MESON_TAC[HAS_INTEGRAL_SPLIT; HAS_INTEGRAL_UNIQUE];
3058     ASM_MESON_TAC[INTEGRABLE_SPLIT; integrable_on];
3059     ASM_MESON_TAC[INTEGRABLE_SPLIT];
3060     ASM_MESON_TAC[INTEGRABLE_SPLIT];
3061     RULE_ASSUM_TAC(REWRITE_RULE[integrable_on]) THEN
3062     ASM_MESON_TAC[HAS_INTEGRAL_SPLIT]]);;
3063
3064 (* ------------------------------------------------------------------------- *)
3065 (* Points of division of a partition.                                        *)
3066 (* ------------------------------------------------------------------------- *)
3067
3068 let division_points = new_definition
3069  `division_points (k:real^N->bool) (d:(real^N->bool)->bool) =
3070     {j,x | 1 <= j /\ j <= dimindex(:N) /\
3071            (interval_lowerbound k)$j < x /\ x < (interval_upperbound k)$j /\
3072            ?i. i IN d /\
3073                ((interval_lowerbound i)$j = x \/
3074                 (interval_upperbound i)$j = x)}`;;
3075
3076 let DIVISION_POINTS_FINITE = prove
3077  (`!d i:real^N->bool. d division_of i ==> FINITE(division_points i d)`,
3078   REWRITE_TAC[division_of; division_points] THEN
3079   REPEAT STRIP_TAC THEN REWRITE_TAC[CONJ_ASSOC; GSYM IN_NUMSEG] THEN
3080   REWRITE_TAC[IN; GSYM CONJ_ASSOC] THEN
3081   MATCH_MP_TAC(REWRITE_RULE[IN] FINITE_PRODUCT_DEPENDENT) THEN
3082   REWRITE_TAC[ETA_AX; FINITE_NUMSEG] THEN
3083   X_GEN_TAC `j:num` THEN GEN_REWRITE_TAC LAND_CONV [GSYM IN] THEN
3084   REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN
3085   MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC
3086    `IMAGE (\i:real^N->bool. (interval_lowerbound i)$j) d UNION
3087     IMAGE (\i:real^N->bool. (interval_upperbound i)$j) d` THEN
3088   ASM_SIMP_TAC[FINITE_UNION; FINITE_IMAGE] THEN
3089   REWRITE_TAC[SUBSET; IN_IMAGE; IN_UNION; IN_ELIM_THM] THEN MESON_TAC[IN]);;
3090
3091 let DIVISION_POINTS_SUBSET = prove
3092  (`!a b:real^N c d k.
3093         d division_of interval[a,b] /\
3094         (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i) /\
3095         1 <= k /\ k <= dimindex(:N) /\ a$k < c /\ c < b$k
3096         ==> division_points (interval[a,b] INTER {x | x$k <= c})
3097                             {l INTER {x | x$k <= c} | l |
3098                              l IN d /\ ~(l INTER {x | x$k <= c} = {})}
3099             SUBSET division_points (interval[a,b]) d /\
3100             division_points (interval[a,b] INTER {x | x$k >= c})
3101                             {l INTER {x | x$k >= c} | l |
3102                              l IN d /\ ~(l INTER {x | x$k >= c} = {})}
3103             SUBSET division_points (interval[a,b]) d`,
3104   REPEAT STRIP_TAC THEN
3105   (REWRITE_TAC[SUBSET; division_points; FORALL_PAIR_THM] THEN
3106    MAP_EVERY X_GEN_TAC [`j:num`; `x:real`] THEN
3107    REWRITE_TAC[IN_ELIM_PAIR_THM] THEN REWRITE_TAC[IN_ELIM_THM] THEN
3108    ASM_SIMP_TAC[INTERVAL_SPLIT; INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND;
3109                 REAL_LT_IMP_LE] THEN
3110    ASM_SIMP_TAC[REAL_ARITH `a < c ==> max a c = c`;
3111                 REAL_ARITH `c < b ==> min b c = c`] THEN
3112    REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
3113    ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; LAMBDA_BETA;
3114      REAL_LT_IMP_LE; COND_ID;
3115      TAUT `(a <= if p then x else y) <=> (if p then a <= x else a <= y)`;
3116      TAUT `(if p then x else y) <= a <=> (if p then x <= a else y <= a)`] THEN
3117    REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
3118    DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THENL
3119     [DISCH_THEN(K ALL_TAC) THEN REPEAT(POP_ASSUM MP_TAC) THEN
3120      COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC;
3121      ALL_TAC] THEN
3122    REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
3123    MATCH_MP_TAC MONO_EXISTS THEN
3124    ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c <=> b /\ a /\ c`] THEN
3125    REWRITE_TAC[UNWIND_THM2] THEN SIMP_TAC[GSYM CONJ_ASSOC] THEN
3126    ONCE_REWRITE_TAC[IMP_CONJ] THEN
3127    FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
3128    MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN DISCH_TAC THEN
3129    ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
3130    SUBGOAL_THEN
3131     `!i. 1 <= i /\ i <= dimindex(:N) ==> (u:real^N)$i <= (v:real^N)$i`
3132    ASSUME_TAC THENL
3133     [REWRITE_TAC[GSYM INTERVAL_NE_EMPTY] THEN ASM_MESON_TAC[division_of];
3134      ALL_TAC] THEN
3135    REWRITE_TAC[INTERVAL_NE_EMPTY] THEN
3136    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3137    ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND] THEN
3138    ASM_SIMP_TAC[LAMBDA_BETA] THEN REPEAT(POP_ASSUM MP_TAC) THEN
3139    COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC));;
3140
3141 let DIVISION_POINTS_PSUBSET = prove
3142  (`!a b:real^N c d k.
3143         d division_of interval[a,b] /\
3144         (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i) /\
3145         1 <= k /\ k <= dimindex(:N) /\ a$k < c /\ c < b$k /\
3146         (?l. l IN d /\
3147              (interval_lowerbound l$k = c \/ interval_upperbound l$k = c))
3148         ==> division_points (interval[a,b] INTER {x | x$k <= c})
3149                             {l INTER {x | x$k <= c} | l |
3150                              l IN d /\ ~(l INTER {x | x$k <= c} = {})}
3151             PSUBSET division_points (interval[a,b]) d /\
3152             division_points (interval[a,b] INTER {x | x$k >= c})
3153                             {l INTER {x | x$k >= c} | l |
3154                              l IN d /\ ~(l INTER {x | x$k >= c} = {})}
3155             PSUBSET division_points (interval[a,b]) d`,
3156   REPEAT STRIP_TAC THEN
3157   ASM_SIMP_TAC[PSUBSET_MEMBER; DIVISION_POINTS_SUBSET] THENL
3158    [EXISTS_TAC `k,(interval_lowerbound l:real^N)$k`;
3159     EXISTS_TAC `k,(interval_lowerbound l:real^N)$k`;
3160     EXISTS_TAC `k,(interval_upperbound l:real^N)$k`;
3161     EXISTS_TAC `k,(interval_upperbound l:real^N)$k`] THEN
3162   ASM_REWRITE_TAC[division_points; IN_ELIM_PAIR_THM] THEN
3163   ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND; REAL_LT_IMP_LE] THEN
3164   (CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN
3165   ASM_SIMP_TAC[INTERVAL_SPLIT; INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND;
3166                REAL_LT_IMP_LE] THEN
3167   ASM_SIMP_TAC[REAL_ARITH `a < c ==> max a c = c`;
3168                REAL_ARITH `c < b ==> min b c = c`] THEN
3169   ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; LAMBDA_BETA;
3170     REAL_LT_IMP_LE; COND_ID;
3171     TAUT `(a <= if p then x else y) <=> (if p then a <= x else a <= y)`;
3172     TAUT `(if p then x else y) <= a <=> (if p then x <= a else y <= a)`] THEN
3173   REWRITE_TAC[REAL_LT_REFL]);;
3174
3175 (* ------------------------------------------------------------------------- *)
3176 (* Preservation by divisions and tagged divisions.                           *)
3177 (* ------------------------------------------------------------------------- *)
3178
3179 let OPERATIVE_DIVISION = prove
3180  (`!op d a b f:(real^N->bool)->A.
3181     monoidal op /\ operative op f /\ d division_of interval[a,b]
3182     ==> iterate(op) d f = f(interval[a,b])`,
3183   REPEAT GEN_TAC THEN CONV_TAC(RAND_CONV SYM_CONV) THEN WF_INDUCT_TAC
3184    `CARD (division_points (interval[a,b]:real^N->bool) d)` THEN
3185   POP_ASSUM(fun th -> REPEAT STRIP_TAC THEN MP_TAC th) THEN
3186   ASM_REWRITE_TAC[] THEN
3187   ASM_CASES_TAC `content(interval[a:real^N,b]) = &0` THENL
3188    [SUBGOAL_THEN `iterate op d (f:(real^N->bool)->A) = neutral op`
3189      (fun th -> ASM_MESON_TAC[th; operative]) THEN
3190     MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
3191      ITERATE_EQ_NEUTRAL) THEN
3192     FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
3193     ASM_MESON_TAC[operative; DIVISION_OF_CONTENT_0];
3194     ALL_TAC] THEN
3195   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM CONTENT_LT_NZ]) THEN
3196   REWRITE_TAC[CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
3197   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
3198   ASM_CASES_TAC `division_points (interval[a,b]:real^N->bool) d = {}` THENL
3199    [DISCH_THEN(K ALL_TAC) THEN
3200     SUBGOAL_THEN
3201      `!i. i IN d
3202           ==> ?u v:real^N. i = interval[u,v] /\
3203                            !j. 1 <= j /\ j <= dimindex(:N)
3204                                ==> u$j = (a:real^N)$j /\ v$j = a$j \/
3205                                    u$j = (b:real^N)$j /\ v$j = b$j \/
3206                                    u$j = a$j /\ v$j = b$j`
3207     (LABEL_TAC "*") THENL
3208      [FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
3209       MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN DISCH_TAC THEN
3210       MAP_EVERY EXISTS_TAC [`u:real^N`; `v:real^N`] THEN REWRITE_TAC[] THEN
3211       REPEAT STRIP_TAC THEN
3212       FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
3213       ASM_REWRITE_TAC[] THEN
3214       DISCH_THEN(MP_TAC o SPEC `interval[u:real^N,v]` o CONJUNCT1) THEN
3215       ASM_REWRITE_TAC[INTERVAL_NE_EMPTY] THEN
3216       DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (ASSUME_TAC o CONJUNCT1)) THEN
3217       ASM_REWRITE_TAC[SUBSET_INTERVAL] THEN STRIP_TAC THEN
3218       MATCH_MP_TAC(REAL_ARITH
3219        `a <= u /\ u <= v /\ v <= b /\ ~(a < u /\ u < b \/ a < v /\ v < b)
3220         ==> u = a /\ v = a \/ u = b /\ v = b \/ u = a /\ v = b`) THEN
3221       ASM_SIMP_TAC[] THEN DISCH_TAC THEN
3222       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
3223       REWRITE_TAC[division_points; NOT_IN_EMPTY; FORALL_PAIR_THM] THEN
3224       REWRITE_TAC[IN_ELIM_PAIR_THM] THEN DISCH_THEN(MP_TAC o SPEC `j:num`) THEN
3225       ASM_REWRITE_TAC[] THEN REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN
3226       REWRITE_TAC[NOT_EXISTS_THM] THEN ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
3227       DISCH_THEN(MP_TAC o SPEC `interval[u:real^N,v]`) THEN
3228       ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND;
3229                    REAL_LT_IMP_LE] THEN
3230       DISCH_THEN(fun th ->
3231         MP_TAC(SPEC `(u:real^N)$j` th) THEN
3232         MP_TAC(SPEC `(v:real^N)$j` th)) THEN
3233       FIRST_X_ASSUM(DISJ_CASES_THEN MP_TAC) THEN REAL_ARITH_TAC;
3234       ALL_TAC] THEN
3235     SUBGOAL_THEN `interval[a:real^N,b] IN d` MP_TAC THENL
3236      [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
3237       ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o last o CONJUNCTS) THEN
3238       REWRITE_TAC[EXTENSION; IN_INTERVAL; IN_UNIONS] THEN
3239       DISCH_THEN(MP_TAC o SPEC `inv(&2) % (a + b:real^N)`) THEN
3240       MATCH_MP_TAC(TAUT `b /\ (a ==> c) ==> (a <=> b) ==> c`) THEN
3241       CONJ_TAC THENL
3242        [SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
3243         X_GEN_TAC `j:num` THEN STRIP_TAC THEN
3244         FIRST_X_ASSUM(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN
3245         REAL_ARITH_TAC;
3246         ALL_TAC] THEN
3247       DISCH_THEN(X_CHOOSE_THEN `i:real^N->bool`
3248        (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
3249       REMOVE_THEN "*" (MP_TAC o SPEC `i:real^N->bool`) THEN
3250       ASM_REWRITE_TAC[] THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
3251       MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN
3252       DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC) THEN
3253       SIMP_TAC[IN_INTERVAL; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
3254       REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN
3255       REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN
3256       ASM_SIMP_TAC[REAL_ARITH
3257        `a < b
3258         ==> ((u = a /\ v = a \/ u = b /\ v = b \/ u = a /\ v = b) /\
3259              u <= inv(&2) * (a + b) /\ inv(&2) * (a +  b) <= v <=>
3260              u = a /\ v = b)`] THEN
3261       ASM_MESON_TAC[CART_EQ];
3262       ALL_TAC] THEN
3263     DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
3264     DISCH_THEN(SUBST1_TAC o MATCH_MP (SET_RULE
3265      `a IN d ==> d = a INSERT (d DELETE a)`)) THEN
3266     ASM_SIMP_TAC[ITERATE_CLAUSES; FINITE_DELETE; IN_DELETE] THEN
3267     SUBGOAL_THEN
3268      `iterate op (d DELETE interval[a,b]) (f:(real^N->bool)->A) = neutral op`
3269      (fun th -> ASM_MESON_TAC[th; monoidal]) THEN
3270     MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
3271      ITERATE_EQ_NEUTRAL) THEN
3272     ASM_REWRITE_TAC[] THEN X_GEN_TAC `l:real^N->bool` THEN
3273     REWRITE_TAC[IN_DELETE] THEN STRIP_TAC THEN
3274     SUBGOAL_THEN `content(l:real^N->bool) = &0`
3275      (fun th -> ASM_MESON_TAC[th; operative]) THEN
3276     REMOVE_THEN "*" (MP_TAC o SPEC `l:real^N->bool`) THEN
3277     ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
3278     MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN
3279     DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC) THEN
3280     UNDISCH_TAC `~(interval[u:real^N,v] = interval[a,b])` THEN
3281     ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
3282     REWRITE_TAC[] THEN DISCH_THEN(fun th -> AP_TERM_TAC THEN MP_TAC th) THEN
3283     REWRITE_TAC[CONS_11; PAIR_EQ; CART_EQ; CONTENT_EQ_0] THEN
3284     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
3285      [TAUT `a ==> b <=> ~a \/ b`] THEN
3286     REWRITE_TAC[NOT_FORALL_THM; OR_EXISTS_THM] THEN
3287     REWRITE_TAC[NOT_EXISTS_THM; AND_FORALL_THM] THEN
3288     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `j:num` THEN
3289     ASM_CASES_TAC `1 <= j /\ j <= dimindex(:N)` THEN ASM_REWRITE_TAC[] THEN
3290     FIRST_X_ASSUM(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN
3291     REAL_ARITH_TAC;
3292     ALL_TAC] THEN
3293   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
3294   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [division_points] THEN
3295   REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
3296   MAP_EVERY X_GEN_TAC [`whatever:num#real`; `k:num`; `c:real`] THEN
3297   ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND; REAL_LT_IMP_LE] THEN
3298   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (K ALL_TAC)) THEN
3299   DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
3300   MP_TAC(ISPECL [`a:real^N`; `b:real^N`; `c:real`; `d:(real^N->bool)->bool`;
3301         `k:num`] DIVISION_POINTS_PSUBSET) THEN
3302   ASM_REWRITE_TAC[] THEN
3303   DISCH_THEN(CONJUNCTS_THEN
3304    (MP_TAC o MATCH_MP (REWRITE_RULE [IMP_CONJ] CARD_PSUBSET))) THEN
3305   MP_TAC(ISPECL [`d:(real^N->bool)->bool`; `a:real^N`; `b:real^N`; `k:num`;
3306                  `c:real`]
3307       DIVISION_SPLIT) THEN
3308   ASM_SIMP_TAC[DIVISION_POINTS_FINITE] THEN
3309   ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
3310   ASM_SIMP_TAC[REAL_ARITH `a < c ==> max a c = c`;
3311                REAL_ARITH `c < b ==> min b c = c`] THEN
3312   MAP_EVERY ABBREV_TAC
3313    [`d1:(real^N->bool)->bool =
3314      {l INTER {x | x$k <= c} | l | l IN d /\ ~(l INTER {x | x$k <= c} = {})}`;
3315     `d2:(real^N->bool)->bool =
3316      {l INTER {x | x$k >= c} | l | l IN d /\ ~(l INTER {x | x$k >= c} = {})}`;
3317     `cb:real^N = (lambda i. if i = k then c else (b:real^N)$i)`;
3318     `ca:real^N = (lambda i. if i = k then c else (a:real^N)$i)`] THEN
3319   STRIP_TAC THEN STRIP_TAC THEN STRIP_TAC THEN DISCH_THEN(fun th ->
3320    MP_TAC(SPECL [`a:real^N`; `cb:real^N`; `d1:(real^N->bool)->bool`] th) THEN
3321    MP_TAC(SPECL [`ca:real^N`; `b:real^N`; `d2:(real^N->bool)->bool`] th)) THEN
3322   ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
3323   MATCH_MP_TAC EQ_TRANS THEN
3324   EXISTS_TAC `op (iterate op d1 (f:(real^N->bool)->A))
3325                  (iterate op d2 (f:(real^N->bool)->A))` THEN
3326   CONJ_TAC THENL
3327    [FIRST_ASSUM(MP_TAC o CONJUNCT2 o GEN_REWRITE_RULE I [operative]) THEN
3328     DISCH_THEN(MP_TAC o SPECL [`a:real^N`; `b:real^N`; `c:real`; `k:num`]) THEN
3329     ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
3330     ASM_SIMP_TAC[REAL_ARITH `a < c ==> max a c = c`;
3331                  REAL_ARITH `c < b ==> min b c = c`];
3332     ALL_TAC] THEN
3333   MATCH_MP_TAC EQ_TRANS THEN
3334   EXISTS_TAC
3335    `op (iterate op d (\l. f(l INTER {x | x$k <= c}):A))
3336        (iterate op d (\l. f(l INTER {x:real^N | x$k >= c})))` THEN
3337   CONJ_TAC THENL
3338    [ALL_TAC;
3339     ASM_SIMP_TAC[GSYM ITERATE_OP] THEN
3340     MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
3341      ITERATE_EQ) THEN
3342     ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION
3343      (ASSUME `d division_of interval[a:real^N,b]`)] THEN
3344     ASM_MESON_TAC[operative]] THEN
3345   MAP_EVERY EXPAND_TAC ["d1"; "d2"] THEN BINOP_TAC THEN
3346   GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM o_DEF] THEN
3347   MATCH_MP_TAC ITERATE_NONZERO_IMAGE_LEMMA THEN ASM_REWRITE_TAC[] THEN
3348   (CONJ_TAC THENL [ASM_MESON_TAC[OPERATIVE_EMPTY]; ALL_TAC] THEN
3349    MAP_EVERY X_GEN_TAC [`l:real^N->bool`; `m:real^N->bool`] THEN STRIP_TAC THEN
3350    MATCH_MP_TAC(MESON[OPERATIVE_TRIVIAL]
3351     `operative op f /\ (?a b. l = interval[a,b]) /\ content l = &0
3352      ==> f l = neutral op`) THEN
3353    ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
3354     [ALL_TAC; ASM_MESON_TAC[DIVISION_SPLIT_LEFT_INJ;
3355                                  DIVISION_SPLIT_RIGHT_INJ]] THEN
3356    SUBGOAL_THEN `?a b:real^N. m = interval[a,b]` STRIP_ASSUME_TAC THENL
3357     [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
3358    ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MESON_TAC[]));;
3359
3360 let OPERATIVE_TAGGED_DIVISION = prove
3361  (`!op d a b f:(real^N->bool)->A.
3362     monoidal op /\ operative op f /\ d tagged_division_of interval[a,b]
3363     ==> iterate(op) d (\(x,l). f l) = f(interval[a,b])`,
3364   let lemma = prove
3365    (`(\(x,l). f l) = (f o SND)`,
3366     REWRITE_TAC[FUN_EQ_THM; o_THM; FORALL_PAIR_THM]) in
3367   REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC
3368    `iterate op (IMAGE SND (d:(real^N#(real^N->bool)->bool))) f :A` THEN
3369   CONJ_TAC THENL
3370    [ALL_TAC;
3371     ASM_MESON_TAC[DIVISION_OF_TAGGED_DIVISION; OPERATIVE_DIVISION]] THEN
3372   REWRITE_TAC[lemma] THEN CONV_TAC SYM_CONV THEN
3373   MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
3374                ITERATE_IMAGE_NONZERO) THEN
3375   ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
3376   CONJ_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF_FINITE]; ALL_TAC] THEN
3377   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
3378   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o CONJUNCT1 o CONJUNCT2)) THEN
3379   REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN REWRITE_TAC[PAIR_EQ] THEN
3380   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
3381   ASM_SIMP_TAC[INTER_ACI] THEN
3382   ASM_MESON_TAC[CONTENT_EQ_0_INTERIOR; OPERATIVE_TRIVIAL;
3383                 TAGGED_DIVISION_OF]);;
3384
3385 (* ------------------------------------------------------------------------- *)
3386 (* Additivity of content.                                                    *)
3387 (* ------------------------------------------------------------------------- *)
3388
3389 let ADDITIVE_CONTENT_DIVISION = prove
3390  (`!d a b:real^N.
3391     d division_of interval[a,b]
3392     ==> sum d content = content(interval[a,b])`,
3393   REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP
3394    (MATCH_MP
3395      (REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
3396                   OPERATIVE_DIVISION)
3397      (CONJ MONOIDAL_REAL_ADD OPERATIVE_CONTENT))) THEN
3398   REWRITE_TAC[sum]);;
3399
3400 let ADDITIVE_CONTENT_TAGGED_DIVISION = prove
3401  (`!d a b:real^N.
3402     d tagged_division_of interval[a,b]
3403     ==> sum d (\(x,l). content l) = content(interval[a,b])`,
3404   REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP
3405    (MATCH_MP
3406      (REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
3407                   OPERATIVE_TAGGED_DIVISION)
3408      (CONJ MONOIDAL_REAL_ADD OPERATIVE_CONTENT))) THEN
3409   REWRITE_TAC[sum]);;
3410
3411 let SUBADDITIVE_CONTENT_DIVISION = prove
3412  (`!d s a b:real^M.
3413         d division_of s /\ s SUBSET interval[a,b]
3414         ==> sum d content <= content(interval[a,b])`,
3415   REPEAT STRIP_TAC THEN
3416   MP_TAC(ISPECL [`d:(real^M->bool)->bool`; `a:real^M`; `b:real^M`]
3417         PARTIAL_DIVISION_EXTEND_INTERVAL) THEN
3418   ANTS_TAC THENL
3419    [REWRITE_TAC[UNIONS_SUBSET] THEN
3420     ASM_MESON_TAC[division_of; DIVISION_OF_UNION_SELF; SUBSET_TRANS];
3421     DISCH_THEN(X_CHOOSE_THEN `p:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN
3422     MATCH_MP_TAC REAL_LE_TRANS THEN
3423     EXISTS_TAC `sum (p:(real^M->bool)->bool) content` THEN CONJ_TAC THENL
3424      [MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
3425       ASM_MESON_TAC[division_of; CONTENT_POS_LE; IN_DIFF];
3426       ASM_MESON_TAC[ADDITIVE_CONTENT_DIVISION; REAL_LE_REFL]]]);;
3427
3428 (* ------------------------------------------------------------------------- *)
3429 (* Finally, the integral of a constant!                                      *)
3430 (* ------------------------------------------------------------------------- *)
3431
3432 let HAS_INTEGRAL_CONST = prove
3433  (`!a b:real^M c:real^N.
3434     ((\x. c) has_integral (content(interval[a,b]) % c)) (interval[a,b])`,
3435   REWRITE_TAC[has_integral] THEN REPEAT STRIP_TAC THEN
3436   EXISTS_TAC `\x:real^M. ball(x,&1)` THEN REWRITE_TAC[GAUGE_TRIVIAL] THEN
3437   REPEAT STRIP_TAC THEN
3438   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
3439   FIRST_X_ASSUM(fun th ->
3440   ONCE_REWRITE_TAC[GSYM(MATCH_MP ADDITIVE_CONTENT_TAGGED_DIVISION th)]) THEN
3441   ASM_SIMP_TAC[VSUM_VMUL; GSYM VSUM_SUB] THEN
3442   REWRITE_TAC[LAMBDA_PAIR_THM; VECTOR_SUB_REFL] THEN
3443   ASM_REWRITE_TAC[GSYM LAMBDA_PAIR_THM; VSUM_0; NORM_0]);;
3444
3445 let INTEGRABLE_CONST = prove
3446  (`!a b:real^M c:real^N. (\x. c) integrable_on interval[a,b]`,
3447   REPEAT STRIP_TAC THEN REWRITE_TAC[integrable_on] THEN
3448   EXISTS_TAC `content(interval[a:real^M,b]) % c:real^N` THEN
3449   REWRITE_TAC[HAS_INTEGRAL_CONST]);;
3450
3451 let INTEGRAL_CONST = prove
3452  (`!a b c. integral (interval[a,b]) (\x. c) = content(interval[a,b]) % c`,
3453   REPEAT GEN_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
3454   REWRITE_TAC[HAS_INTEGRAL_CONST]);;
3455
3456 let INTEGRAL_PASTECART_CONST = prove
3457  (`!a b:real^M c d:real^N k:real^P.
3458      integral (interval[pastecart a c,pastecart b d]) (\x. k) =
3459      integral (interval[a,b])
3460               (\x. integral (interval[c,d]) (\y. k))`,
3461   REWRITE_TAC[INTEGRAL_CONST; CONTENT_PASTECART; VECTOR_MUL_ASSOC]);;
3462
3463 (* ------------------------------------------------------------------------- *)
3464 (* Bounds on the norm of Riemann sums and the integral itself.               *)
3465 (* ------------------------------------------------------------------------- *)
3466
3467 let DSUM_BOUND = prove
3468  (`!p a b:real^M c:real^N e.
3469        p division_of interval[a,b] /\ norm(c) <= e
3470        ==> norm(vsum p (\l. content l % c)) <= e * content(interval[a,b])`,
3471   REPEAT STRIP_TAC THEN
3472   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
3473   W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
3474   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
3475    `y <= e ==> x <= y ==> x <= e`) THEN
3476   REWRITE_TAC[LAMBDA_PAIR_THM; NORM_MUL] THEN
3477   MATCH_MP_TAC REAL_LE_TRANS THEN
3478   EXISTS_TAC `sum p (\k:real^M->bool. content k * e)` THEN
3479   CONJ_TAC THENL
3480    [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
3481     X_GEN_TAC `l:real^M->bool` THEN DISCH_TAC THEN
3482     MATCH_MP_TAC REAL_LE_MUL2 THEN SIMP_TAC[REAL_ABS_POS; NORM_POS_LE] THEN
3483     ASM_REWRITE_TAC[] THEN
3484     MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> abs(x) <= x`) THEN
3485     ASM_MESON_TAC[DIVISION_OF; CONTENT_POS_LE];
3486     REWRITE_TAC[SUM_RMUL; ETA_AX] THEN
3487     ASM_MESON_TAC[ADDITIVE_CONTENT_DIVISION; REAL_LE_REFL; REAL_MUL_SYM]]);;
3488
3489 let RSUM_BOUND = prove
3490  (`!p a b f:real^M->real^N e.
3491        p tagged_division_of interval[a,b] /\
3492        (!x. x IN interval[a,b] ==> norm(f x) <= e)
3493        ==> norm(vsum p (\(x,k). content k % f x))
3494             <= e * content(interval[a,b])`,
3495   REPEAT STRIP_TAC THEN
3496   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
3497   W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
3498   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
3499    `y <= e ==> x <= y ==> x <= e`) THEN
3500   REWRITE_TAC[LAMBDA_PAIR_THM; NORM_MUL] THEN
3501   MATCH_MP_TAC REAL_LE_TRANS THEN
3502   EXISTS_TAC `sum p (\(x:real^M,k:real^M->bool). content k * e)` THEN
3503   CONJ_TAC THENL
3504    [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
3505     MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN DISCH_TAC THEN
3506     MATCH_MP_TAC REAL_LE_MUL2 THEN SIMP_TAC[REAL_ABS_POS; NORM_POS_LE] THEN
3507     CONJ_TAC THENL
3508      [ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE; REAL_ABS_REFL;
3509                     REAL_LE_REFL];
3510       ASM_MESON_TAC[TAG_IN_INTERVAL]];
3511     FIRST_ASSUM(fun th -> REWRITE_TAC
3512      [GSYM(MATCH_MP ADDITIVE_CONTENT_TAGGED_DIVISION th)]) THEN
3513     REWRITE_TAC[GSYM SUM_LMUL; LAMBDA_PAIR_THM] THEN
3514     REWRITE_TAC[REAL_MUL_AC; REAL_LE_REFL]]);;
3515
3516 let RSUM_DIFF_BOUND = prove
3517  (`!p a b f g:real^M->real^N.
3518        p tagged_division_of interval[a,b] /\
3519        (!x. x IN interval[a,b] ==> norm(f x - g x) <= e)
3520        ==> norm(vsum p (\(x,k). content k % f x) -
3521                 vsum p (\(x,k). content k % g x))
3522            <= e * content(interval[a,b])`,
3523   REPEAT STRIP_TAC THEN
3524   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
3525   MATCH_MP_TAC REAL_LE_TRANS THEN
3526   EXISTS_TAC
3527    `norm(vsum p (\(x,k).
3528       content(k:real^M->bool) % ((f:real^M->real^N) x - g x)))` THEN
3529   CONJ_TAC THENL
3530    [ASM_SIMP_TAC[GSYM VSUM_SUB; VECTOR_SUB_LDISTRIB] THEN
3531     REWRITE_TAC[LAMBDA_PAIR_THM; REAL_LE_REFL];
3532     ASM_SIMP_TAC[RSUM_BOUND]]);;
3533
3534 let HAS_INTEGRAL_BOUND = prove
3535  (`!f:real^M->real^N a b i B.
3536         &0 <= B /\
3537         (f has_integral i) (interval[a,b]) /\
3538         (!x. x IN interval[a,b] ==> norm(f x) <= B)
3539         ==> norm i <= B * content(interval[a,b])`,
3540   let lemma = prove
3541    (`norm(s) <= B ==> ~(norm(s - i) < norm(i) - B)`,
3542     MATCH_MP_TAC(REAL_ARITH `n1 <= n + n2 ==> n <= B ==> ~(n2 < n1 - B)`) THEN
3543     ONCE_REWRITE_TAC[NORM_SUB] THEN REWRITE_TAC[NORM_TRIANGLE_SUB]) in
3544   REPEAT STRIP_TAC THEN
3545   ASM_CASES_TAC `&0 < content(interval[a:real^M,b])` THENL
3546    [ALL_TAC;
3547     SUBGOAL_THEN `i:real^N = vec 0` SUBST1_TAC THEN
3548     ASM_SIMP_TAC[REAL_LE_MUL; NORM_0; CONTENT_POS_LE] THEN
3549     ASM_MESON_TAC[HAS_INTEGRAL_NULL_EQ; CONTENT_LT_NZ]] THEN
3550   ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
3551   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [has_integral]) THEN
3552   DISCH_THEN(MP_TAC o SPEC
3553     `norm(i:real^N) - B * content(interval[a:real^M,b])`) THEN
3554   ASM_REWRITE_TAC[REAL_SUB_LT] THEN
3555   DISCH_THEN(X_CHOOSE_THEN `d:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
3556   MP_TAC(SPECL [`d:real^M->real^M->bool`; `a:real^M`; `b:real^M`]
3557         FINE_DIVISION_EXISTS) THEN
3558   ASM_REWRITE_TAC[] THEN DISCH_THEN
3559    (X_CHOOSE_THEN `p:(real^M#(real^M->bool)->bool)` STRIP_ASSUME_TAC) THEN
3560   FIRST_X_ASSUM(MP_TAC o SPEC `p:(real^M#(real^M->bool)->bool)`) THEN
3561   ASM_MESON_TAC[lemma; RSUM_BOUND]);;
3562
3563 (* ------------------------------------------------------------------------- *)
3564 (* Similar theorems about relationship among components.                     *)
3565 (* ------------------------------------------------------------------------- *)
3566
3567 let RSUM_COMPONENT_LE = prove
3568  (`!p a b f:real^M->real^N g:real^M->real^N.
3569        p tagged_division_of interval[a,b] /\ 1 <= i /\ i <= dimindex(:N) /\
3570        (!x. x IN interval[a,b] ==> (f x)$i <= (g x)$i)
3571        ==> vsum p (\(x,k). content k % f x)$i <=
3572            vsum p (\(x,k). content k % g x)$i`,
3573   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[VSUM_COMPONENT] THEN
3574   MATCH_MP_TAC SUM_LE THEN
3575   ASM_SIMP_TAC[FORALL_PAIR_THM; VECTOR_MUL_COMPONENT] THEN
3576   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
3577   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
3578   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
3579   ASM_MESON_TAC[SUBSET; REAL_LE_LMUL; CONTENT_POS_LE]);;
3580
3581 let HAS_INTEGRAL_COMPONENT_LE = prove
3582  (`!f:real^M->real^N g:real^M->real^N s i j k.
3583         1 <= k /\ k <= dimindex(:N) /\
3584         (f has_integral i) s /\ (g has_integral j) s /\
3585         (!x. x IN s ==> (f x)$k <= (g x)$k)
3586         ==> i$k <= j$k`,
3587   SUBGOAL_THEN
3588    `!f:real^M->real^N g:real^M->real^N a b i j k.
3589         1 <= k /\ k <= dimindex(:N) /\
3590         (f has_integral i) (interval[a,b]) /\
3591         (g has_integral j) (interval[a,b]) /\
3592         (!x. x IN interval[a,b] ==> (f x)$k <= (g x)$k)
3593         ==> i$k <= j$k`
3594   ASSUME_TAC THENL
3595    [REPEAT STRIP_TAC THEN
3596     MATCH_MP_TAC(REAL_ARITH `~(&0 < i - j) ==> i <= j`) THEN DISCH_TAC THEN
3597     REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `((i:real^N)$k - (j:real^N)$k) / &3` o
3598        GEN_REWRITE_RULE I [has_integral])) THEN
3599     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
3600     DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
3601     DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
3602     SUBGOAL_THEN `?p. p tagged_division_of interval[a:real^M,b] /\
3603                       d1 fine p /\ d2 fine p`
3604     STRIP_ASSUME_TAC THENL
3605      [REWRITE_TAC[GSYM FINE_INTER] THEN MATCH_MP_TAC FINE_DIVISION_EXISTS THEN
3606       ASM_SIMP_TAC[GAUGE_INTER];
3607       ALL_TAC] THEN
3608     REPEAT
3609      (FIRST_X_ASSUM(MP_TAC o SPEC `p:real^M#(real^M->bool)->bool`) THEN
3610       ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o MATCH_MP REAL_LT_IMP_LE) THEN
3611       DISCH_THEN(MP_TAC o SPEC `k:num` o MATCH_MP NORM_BOUND_COMPONENT_LE) THEN
3612       ASM_SIMP_TAC[VECTOR_SUB_COMPONENT]) THEN
3613     SUBGOAL_THEN
3614      `vsum p (\(x,l:real^M->bool). content l % (f:real^M->real^N) x)$k <=
3615       vsum p (\(x,l). content l % (g:real^M->real^N) x)$k`
3616     MP_TAC THENL
3617      [MATCH_MP_TAC RSUM_COMPONENT_LE THEN ASM_MESON_TAC[];
3618       UNDISCH_TAC `&0 < (i:real^N)$k - (j:real^N)$k` THEN
3619       SPEC_TAC(`vsum p (\(x:real^M,l:real^M->bool).
3620                                 content l % (f x):real^N)$k`,
3621                `fs:real`) THEN
3622       SPEC_TAC(`vsum p (\(x:real^M,l:real^M->bool).
3623                                 content l % (g x):real^N)$k`,
3624                `gs:real`) THEN
3625       REAL_ARITH_TAC];
3626     ALL_TAC] THEN
3627   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[has_integral_alt] THEN
3628   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
3629   STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
3630   REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC
3631    `((i:real^N)$k - (j:real^N)$k) / &2`)) THEN
3632   ASM_REWRITE_TAC[REAL_HALF; REAL_SUB_LT] THEN
3633   DISCH_THEN(X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) THEN
3634   DISCH_THEN(X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC) THEN
3635   MP_TAC(ISPEC
3636    `ball(vec 0,B1) UNION ball(vec 0:real^M,B2)`
3637    BOUNDED_SUBSET_CLOSED_INTERVAL) THEN
3638   REWRITE_TAC[BOUNDED_UNION; BOUNDED_BALL; UNION_SUBSET; NOT_EXISTS_THM] THEN
3639   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
3640   DISCH_THEN(CONJUNCTS_THEN(ANTE_RES_THEN MP_TAC)) THEN
3641   DISCH_THEN(X_CHOOSE_THEN `w:real^N` STRIP_ASSUME_TAC) THEN
3642   DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
3643   SUBGOAL_THEN `(z:real^N)$k <= (w:real^N)$k` MP_TAC THENL
3644    [FIRST_X_ASSUM MATCH_MP_TAC THEN
3645     MAP_EVERY EXISTS_TAC
3646      [`(\x. if x IN s then f x else vec 0):real^M->real^N`;
3647       `(\x. if x IN s then g x else vec 0):real^M->real^N`;
3648       `a:real^M`; `b:real^M`] THEN
3649     ASM_MESON_TAC[REAL_LE_REFL];
3650     MP_TAC(ISPECL [`w - j:real^N`; `k:num`] COMPONENT_LE_NORM) THEN
3651     MP_TAC(ISPECL [`z - i:real^N`; `k:num`] COMPONENT_LE_NORM) THEN
3652     ASM_REWRITE_TAC[] THEN
3653     SIMP_TAC[VECTOR_SUB_COMPONENT; ASSUME `1 <= k`;
3654               ASSUME `k <= dimindex(:N)`] THEN
3655     REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_NOT_LE])) THEN
3656     NORM_ARITH_TAC]);;
3657
3658 let INTEGRAL_COMPONENT_LE = prove
3659  (`!f:real^M->real^N g:real^M->real^N s k.
3660         1 <= k /\ k <= dimindex(:N) /\
3661         f integrable_on s /\ g integrable_on s /\
3662         (!x. x IN s ==> (f x)$k <= (g x)$k)
3663         ==> (integral s f)$k <= (integral s g)$k`,
3664   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LE THEN
3665   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
3666
3667 let HAS_INTEGRAL_DROP_LE = prove
3668  (`!f:real^M->real^1 g:real^M->real^1 s i j.
3669         (f has_integral i) s /\ (g has_integral j) s /\
3670         (!x. x IN s ==> drop(f x) <= drop(g x))
3671         ==> drop i <= drop j`,
3672   REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN
3673   MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LE THEN
3674   REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN ASM_MESON_TAC[]);;
3675
3676 let INTEGRAL_DROP_LE = prove
3677  (`!f:real^M->real^1 g:real^M->real^1 s.
3678         f integrable_on s /\ g integrable_on s /\
3679         (!x. x IN s ==> drop(f x) <= drop(g x))
3680         ==> drop(integral s f) <= drop(integral s g)`,
3681   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_DROP_LE THEN
3682   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
3683
3684 let HAS_INTEGRAL_COMPONENT_POS = prove
3685  (`!f:real^M->real^N s i k.
3686         1 <= k /\ k <= dimindex(:N) /\
3687         (f has_integral i) s /\
3688         (!x. x IN s ==> &0 <= (f x)$k)
3689         ==> &0 <= i$k`,
3690   REPEAT STRIP_TAC THEN
3691   MP_TAC(ISPECL [`(\x. vec 0):real^M->real^N`; `f:real^M->real^N`;
3692                  `s:real^M->bool`; `vec 0:real^N`;
3693                  `i:real^N`; `k:num`] HAS_INTEGRAL_COMPONENT_LE) THEN
3694   ASM_SIMP_TAC[VEC_COMPONENT; HAS_INTEGRAL_0]);;
3695
3696 let INTEGRAL_COMPONENT_POS = prove
3697  (`!f:real^M->real^N s k.
3698         1 <= k /\ k <= dimindex(:N) /\
3699         f integrable_on s /\
3700         (!x. x IN s ==> &0 <= (f x)$k)
3701         ==> &0 <= (integral s f)$k`,
3702   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_POS THEN
3703   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
3704
3705 let HAS_INTEGRAL_DROP_POS = prove
3706  (`!f:real^M->real^1 s i.
3707         (f has_integral i) s /\
3708         (!x. x IN s ==> &0 <= drop(f x))
3709         ==> &0 <= drop i`,
3710   REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN
3711   MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_POS THEN
3712   REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN ASM_MESON_TAC[]);;
3713
3714 let INTEGRAL_DROP_POS = prove
3715  (`!f:real^M->real^1 s.
3716         f integrable_on s /\
3717         (!x. x IN s ==> &0 <= drop(f x))
3718         ==> &0 <= drop(integral s f)`,
3719   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_DROP_POS THEN
3720   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
3721
3722 let HAS_INTEGRAL_COMPONENT_NEG = prove
3723  (`!f:real^M->real^N s i k.
3724         1 <= k /\ k <= dimindex(:N) /\
3725         (f has_integral i) s /\
3726         (!x. x IN s ==> (f x)$k <= &0)
3727         ==> i$k <= &0`,
3728   REPEAT STRIP_TAC THEN
3729   MP_TAC(ISPECL [`f:real^M->real^N`; `(\x. vec 0):real^M->real^N`;
3730                  `s:real^M->bool`; `i:real^N`; `vec 0:real^N`;
3731                  `k:num`] HAS_INTEGRAL_COMPONENT_LE) THEN
3732   ASM_SIMP_TAC[VEC_COMPONENT; HAS_INTEGRAL_0]);;
3733
3734 let HAS_INTEGRAL_DROP_NEG = prove
3735  (`!f:real^M->real^1 s i.
3736         (f has_integral i) s /\
3737         (!x. x IN s ==> drop(f x) <= &0)
3738         ==> drop i <= &0`,
3739   REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN
3740   MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_NEG THEN
3741   REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN ASM_MESON_TAC[]);;
3742
3743 let HAS_INTEGRAL_COMPONENT_LBOUND = prove
3744  (`!f:real^M->real^N a b i k.
3745         (f has_integral i) (interval[a,b]) /\ 1 <= k /\ k <= dimindex(:N) /\
3746         (!x. x IN interval[a,b] ==> B <= f(x)$k)
3747         ==> B * content(interval[a,b]) <= i$k`,
3748   REPEAT STRIP_TAC THEN
3749   MP_TAC(ISPECL [`(\x. lambda i. B):real^M->real^N`; `f:real^M->real^N`;
3750                  `interval[a:real^M,b]`;
3751                  `content(interval[a:real^M,b]) % (lambda i. B):real^N`;
3752                  `i:real^N`; `k:num`]
3753                 HAS_INTEGRAL_COMPONENT_LE) THEN
3754   ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; LAMBDA_BETA; HAS_INTEGRAL_CONST] THEN
3755   REWRITE_TAC[REAL_MUL_AC]);;
3756
3757 let HAS_INTEGRAL_COMPONENT_UBOUND = prove
3758  (`!f:real^M->real^N a b i k.
3759         (f has_integral i) (interval[a,b]) /\ 1 <= k /\ k <= dimindex(:N) /\
3760         (!x. x IN interval[a,b] ==> f(x)$k <= B)
3761         ==> i$k <= B * content(interval[a,b])`,
3762   REPEAT STRIP_TAC THEN
3763   MP_TAC(ISPECL [`f:real^M->real^N`; `(\x. lambda i. B):real^M->real^N`;
3764                  `interval[a:real^M,b]`; `i:real^N`;
3765                  `content(interval[a:real^M,b]) % (lambda i. B):real^N`;
3766                  `k:num`]
3767                 HAS_INTEGRAL_COMPONENT_LE) THEN
3768   ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; LAMBDA_BETA; HAS_INTEGRAL_CONST] THEN
3769   REWRITE_TAC[REAL_MUL_AC]);;
3770
3771 let INTEGRAL_COMPONENT_LBOUND = prove
3772  (`!f:real^M->real^N a b k.
3773         f integrable_on interval[a,b] /\ 1 <= k /\ k <= dimindex(:N) /\
3774         (!x. x IN interval[a,b] ==> B <= f(x)$k)
3775         ==> B * content(interval[a,b]) <= (integral(interval[a,b]) f)$k`,
3776   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LBOUND THEN
3777   EXISTS_TAC `f:real^M->real^N` THEN
3778   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);;
3779
3780 let INTEGRAL_COMPONENT_UBOUND = prove
3781  (`!f:real^M->real^N a b k.
3782         f integrable_on interval[a,b] /\ 1 <= k /\ k <= dimindex(:N) /\
3783         (!x. x IN interval[a,b] ==> f(x)$k <= B)
3784         ==> (integral(interval[a,b]) f)$k <= B * content(interval[a,b])`,
3785   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_UBOUND THEN
3786   EXISTS_TAC `f:real^M->real^N` THEN
3787   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);;
3788
3789 (* ------------------------------------------------------------------------- *)
3790 (* Uniform limit of integrable functions is integrable.                      *)
3791 (* ------------------------------------------------------------------------- *)
3792
3793 let INTEGRABLE_UNIFORM_LIMIT = prove
3794  (`!f a b. (!e. &0 < e
3795                 ==> ?g. (!x. x IN interval[a,b] ==> norm(f x - g x) <= e) /\
3796                         g integrable_on interval[a,b] )
3797            ==> (f:real^M->real^N) integrable_on interval[a,b]`,
3798   let lemma = prove
3799    (`x <= norm(a + b) + c ==> x <= norm(a) + norm(b) + c`,
3800     MESON_TAC[REAL_ADD_AC; NORM_TRIANGLE; REAL_LE_TRANS; REAL_LE_RADD]) in
3801   let (lemma1,lemma2) = (CONJ_PAIR o prove)
3802    (`(norm(s2 - s1) <= e / &2 /\
3803       norm(s1 - i1) < e / &4 /\ norm(s2 - i2) < e / &4
3804       ==> norm(i1 - i2) < e) /\
3805      (norm(sf - sg) <= e / &3
3806       ==> norm(i - s) < e / &3 ==> norm(sg - i) < e / &3 ==> norm(sf - s) < e)`,
3807     CONJ_TAC THENL
3808      [REWRITE_TAC[CONJ_ASSOC] THEN
3809       GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o ONCE_DEPTH_CONV) [NORM_SUB] THEN
3810       MATCH_MP_TAC(REAL_ARITH
3811        `w <= x + y + z + &0
3812         ==> (x <= e / &2 /\ y < e / &4) /\ z < e / &4 ==> w < e`);
3813       MATCH_MP_TAC(REAL_ARITH
3814       `w <= x + y + z + &0
3815       ==> x <= e / &3 ==> y < e / &3 ==> z < e / &3 ==> w < e`)] THEN
3816     REPEAT(MATCH_MP_TAC lemma) THEN REWRITE_TAC[REAL_ADD_RID] THEN
3817     MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN VECTOR_ARITH_TAC) in
3818   REPEAT STRIP_TAC THEN
3819   ASM_CASES_TAC `&0 < content(interval[a:real^M,b])` THENL
3820    [ALL_TAC;
3821     ASM_MESON_TAC[HAS_INTEGRAL_NULL; CONTENT_LT_NZ; integrable_on]] THEN
3822   FIRST_X_ASSUM(MP_TAC o GEN `n:num` o SPEC `inv(&n + &1)`) THEN
3823   REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
3824   REWRITE_TAC[FORALL_AND_THM; SKOLEM_THM; integrable_on] THEN
3825   DISCH_THEN(X_CHOOSE_THEN `g:num->real^M->real^N` (CONJUNCTS_THEN2
3826    ASSUME_TAC (X_CHOOSE_TAC `i:num->real^N`))) THEN
3827   SUBGOAL_THEN `cauchy(i:num->real^N)` MP_TAC THENL
3828    [REWRITE_TAC[cauchy] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3829     MP_TAC(SPEC `e / &4 / content(interval[a:real^M,b])`
3830         REAL_ARCH_INV) THEN
3831     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
3832     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
3833     MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN REWRITE_TAC[GE] THEN
3834     STRIP_TAC THEN
3835     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV [has_integral]) THEN
3836     ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
3837     DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
3838     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
3839     DISCH_THEN(fun th -> MP_TAC(SPEC `m:num` th) THEN
3840       MP_TAC(SPEC `n:num` th)) THEN
3841     DISCH_THEN(X_CHOOSE_THEN `gn:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
3842     DISCH_THEN(X_CHOOSE_THEN `gm:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
3843     MP_TAC(ISPECL [`(\x. gm(x) INTER gn(x)):real^M->real^M->bool`;
3844                    `a:real^M`; `b:real^M`] FINE_DIVISION_EXISTS) THEN
3845     ASM_SIMP_TAC[GAUGE_INTER; LEFT_IMP_EXISTS_THM] THEN
3846     X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
3847     REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`)) THEN
3848     FIRST_ASSUM(fun th -> REWRITE_TAC[CONV_RULE(REWR_CONV FINE_INTER) th]) THEN
3849     SUBGOAL_THEN `norm(vsum p (\(x,k:real^M->bool). content k % g (n:num) x) -
3850                        vsum p (\(x:real^M,k). content k % g m x :real^N))
3851                   <= e / &2`
3852     MP_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[dist] THEN MESON_TAC[lemma1]] THEN
3853     MATCH_MP_TAC REAL_LE_TRANS THEN
3854     EXISTS_TAC `&2 / &N * content(interval[a:real^M,b])` THEN CONJ_TAC THENL
3855      [MATCH_MP_TAC RSUM_DIFF_BOUND;
3856       ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN
3857       ASM_REAL_ARITH_TAC] THEN
3858     ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
3859     FIRST_X_ASSUM(fun th -> MP_TAC(SPECL [`n:num`; `x:real^M`] th) THEN
3860       MP_TAC(SPECL [`m:num`; `x:real^M`] th)) THEN
3861     ASM_REWRITE_TAC[IMP_IMP] THEN
3862     GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o LAND_CONV) [NORM_SUB] THEN
3863     DISCH_THEN(MP_TAC o MATCH_MP REAL_LE_ADD2) THEN
3864     DISCH_THEN(MP_TAC o MATCH_MP NORM_TRIANGLE_LE) THEN
3865     MATCH_MP_TAC(REAL_ARITH `u = v /\ a <= inv(x) /\ b <= inv(x) ==>
3866                                 u <= a + b ==> v <= &2 / x`) THEN
3867     CONJ_TAC THENL [AP_TERM_TAC THEN VECTOR_ARITH_TAC; ALL_TAC] THEN
3868     CONJ_TAC THEN MATCH_MP_TAC REAL_LE_INV2 THEN
3869     REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
3870     ASM_ARITH_TAC;
3871     ALL_TAC] THEN
3872   REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN
3873   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `s:real^N` THEN DISCH_TAC THEN
3874   REWRITE_TAC[has_integral] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3875   FIRST_X_ASSUM(MP_TAC o SPEC `e / &3` o GEN_REWRITE_RULE I
3876    [LIM_SEQUENTIALLY]) THEN
3877   ASM_SIMP_TAC[dist; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
3878   DISCH_THEN(X_CHOOSE_TAC `N1:num`) THEN
3879   MP_TAC(SPEC `e / &3 / content(interval[a:real^M,b])` REAL_ARCH_INV) THEN
3880   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
3881   DISCH_THEN(X_CHOOSE_THEN `N2:num` STRIP_ASSUME_TAC) THEN
3882   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV [has_integral]) THEN
3883   DISCH_THEN(MP_TAC o SPECL [`N1 + N2:num`; `e / &3`]) THEN
3884   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
3885   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^M->real^M->bool` THEN
3886   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
3887   X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN
3888   FIRST_X_ASSUM(MP_TAC o SPEC `p:real^M#(real^M->bool)->bool`) THEN
3889   ASM_REWRITE_TAC[] THEN
3890   FIRST_X_ASSUM(MP_TAC o C MATCH_MP (ARITH_RULE `N1:num <= N1 + N2`)) THEN
3891   MATCH_MP_TAC lemma2 THEN MATCH_MP_TAC REAL_LE_TRANS THEN
3892   EXISTS_TAC `inv(&(N1 + N2) + &1) * content(interval[a:real^M,b])` THEN
3893   CONJ_TAC THENL
3894    [MATCH_MP_TAC RSUM_DIFF_BOUND THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN
3895   ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN
3896   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
3897    `x < a ==> y <= x ==> y <= a`)) THEN
3898   MATCH_MP_TAC REAL_LE_INV2 THEN
3899   REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
3900   ASM_ARITH_TAC);;
3901
3902 (* ------------------------------------------------------------------------- *)
3903 (* Negligible sets.                                                          *)
3904 (* ------------------------------------------------------------------------- *)
3905
3906 let indicator = new_definition
3907   `indicator s :real^M->real^1 = \x. if x IN s then vec 1 else vec 0`;;
3908
3909 let DROP_INDICATOR = prove
3910  (`!s x. drop(indicator s x) = if x IN s then &1 else &0`,
3911   REPEAT GEN_TAC THEN REWRITE_TAC[indicator] THEN
3912   COND_CASES_TAC THEN ASM_REWRITE_TAC[DROP_VEC]);;
3913
3914 let DROP_INDICATOR_POS_LE = prove
3915  (`!s x. &0 <= drop(indicator s x)`,
3916   REWRITE_TAC[DROP_INDICATOR] THEN REAL_ARITH_TAC);;
3917
3918 let DROP_INDICATOR_LE_1 = prove
3919  (`!s x. drop(indicator s x) <= &1`,
3920   REWRITE_TAC[DROP_INDICATOR] THEN REAL_ARITH_TAC);;
3921
3922 let DROP_INDICATOR_ABS_LE_1 = prove
3923  (`!s x. abs(drop(indicator s x)) <= &1`,
3924   REWRITE_TAC[DROP_INDICATOR] THEN REAL_ARITH_TAC);;
3925
3926 let negligible = new_definition
3927  `negligible s <=> !a b. (indicator s has_integral (vec 0)) (interval[a,b])`;;
3928
3929 (* ------------------------------------------------------------------------- *)
3930 (* Negligibility of hyperplane.                                              *)
3931 (* ------------------------------------------------------------------------- *)
3932
3933 let VSUM_NONZERO_IMAGE_LEMMA = prove
3934  (`!s f:A->B g:B->real^N a.
3935         FINITE s /\ g(a) = vec 0 /\
3936         (!x y. x IN s /\ y IN s /\ f x = f y /\ ~(x = y) ==> g(f x) = vec 0)
3937        ==> vsum {f x |x| x IN s /\ ~(f x = a)} g =
3938            vsum s (g o f)`,
3939   REPEAT STRIP_TAC THEN
3940   SUBGOAL_THEN `FINITE {(f:A->B) x |x| x IN s /\ ~(f x = a)}`
3941   ASSUME_TAC THENL
3942    [MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `IMAGE (f:A->B) s` THEN
3943     ASM_SIMP_TAC[FINITE_IMAGE; SUBSET; IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[];
3944     ASM_SIMP_TAC[VSUM] THEN MATCH_MP_TAC ITERATE_NONZERO_IMAGE_LEMMA THEN
3945     ASM_REWRITE_TAC[NEUTRAL_VECTOR_ADD; MONOIDAL_VECTOR_ADD]]);;
3946
3947 let INTERVAL_DOUBLESPLIT = prove
3948  (`1 <= k /\ k <= dimindex(:N)
3949       ==> interval[a,b] INTER {x:real^N | abs(x$k - c) <= e} =
3950           interval[(lambda i. if i = k then max (a$k) (c - e) else a$i),
3951                    (lambda i. if i = k then min (b$k) (c + e) else b$i)]`,
3952    REWRITE_TAC[REAL_ARITH `abs(x - c) <= e <=> x >= c - e /\ x <= c + e`] THEN
3953    REWRITE_TAC[SET_RULE `s INTER {x | P x /\ Q x} =
3954                         (s INTER {x | Q x}) INTER {x | P x}`] THEN
3955    SIMP_TAC[INTERVAL_SPLIT]);;
3956
3957 let DIVISION_DOUBLESPLIT = prove
3958  (`!p a b:real^N k c e.
3959         p division_of interval[a,b] /\ 1 <= k /\ k <= dimindex(:N)
3960         ==> {l INTER {x | abs(x$k - c) <= e} |l|
3961                 l IN p /\ ~(l INTER {x | abs(x$k - c) <= e} = {})}
3962             division_of (interval[a,b] INTER {x | abs(x$k - c) <= e})`,
3963   REPEAT GEN_TAC THEN DISCH_TAC THEN
3964   FIRST_ASSUM(MP_TAC o SPEC `c + e:real` o MATCH_MP DIVISION_SPLIT) THEN
3965   DISCH_THEN(MP_TAC o CONJUNCT1) THEN
3966   ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
3967   FIRST_ASSUM MP_TAC THEN REWRITE_TAC[IMP_IMP] THEN
3968   DISCH_THEN(MP_TAC o MATCH_MP (TAUT
3969    `(a /\ b /\ c) /\ d ==> d /\ b /\ c`)) THEN
3970   DISCH_THEN(MP_TAC o CONJUNCT2 o SPEC `c - e:real` o
3971     MATCH_MP DIVISION_SPLIT) THEN
3972   ASM_SIMP_TAC[INTERVAL_DOUBLESPLIT; INTERVAL_SPLIT] THEN
3973   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
3974   REWRITE_TAC[REAL_ARITH `abs(x - c) <= e <=> x >= c - e /\ x <= c + e`] THEN
3975   GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN
3976   GEN_TAC THEN REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN
3977   ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[GSYM CONJ_ASSOC] THEN
3978   ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> c /\ a /\ b /\ d`] THEN
3979   REWRITE_TAC[UNWIND_THM2] THEN AP_TERM_TAC THEN ABS_TAC THEN SET_TAC[]);;
3980
3981 let CONTENT_DOUBLESPLIT = prove
3982  (`!a b:real^N k c e.
3983         &0 < e /\ 1 <= k /\ k <= dimindex(:N)
3984         ==> ?d. &0 < d /\
3985                 content(interval[a,b] INTER {x | abs(x$k - c) <= d}) < e`,
3986   REPEAT STRIP_TAC THEN
3987   ASM_CASES_TAC `content(interval[a:real^N,b]) = &0` THENL
3988    [EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
3989     MATCH_MP_TAC REAL_LET_TRANS THEN
3990     EXISTS_TAC `content(interval[a:real^N,b])` THEN
3991     CONJ_TAC THENL [FIRST_X_ASSUM(K ALL_TAC o SYM); ASM_REWRITE_TAC[]] THEN
3992     ASM_SIMP_TAC[INTERVAL_DOUBLESPLIT] THEN MATCH_MP_TAC CONTENT_SUBSET THEN
3993     ASM_SIMP_TAC[GSYM INTERVAL_DOUBLESPLIT] THEN SET_TAC[];
3994     ALL_TAC] THEN
3995   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CONTENT_EQ_0]) THEN
3996   REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN
3997   REWRITE_TAC[REAL_NOT_LE] THEN DISCH_TAC THEN
3998   SUBGOAL_THEN `&0 < product ((1..dimindex (:N)) DELETE k)
3999                               (\i. (b:real^N)$i - (a:real^N)$i)`
4000   ASSUME_TAC THENL
4001    [MATCH_MP_TAC PRODUCT_POS_LT THEN
4002     ASM_SIMP_TAC[FINITE_DELETE; FINITE_NUMSEG; IN_DELETE; IN_NUMSEG;
4003                  REAL_SUB_LT];
4004     ALL_TAC] THEN
4005   ABBREV_TAC `d = e / &3 / product ((1..dimindex (:N)) DELETE k)
4006                                    (\i. (b:real^N)$i - (a:real^N)$i)` THEN
4007   EXISTS_TAC `d:real` THEN SUBGOAL_THEN `&0 < d` ASSUME_TAC THENL
4008    [EXPAND_TAC "d" THEN MATCH_MP_TAC REAL_LT_DIV THEN
4009     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH];
4010     ALL_TAC] THEN
4011   ASM_SIMP_TAC[content; INTERVAL_DOUBLESPLIT] THEN
4012   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
4013   FIRST_X_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I [INTERVAL_NE_EMPTY]) THEN
4014   SUBGOAL_THEN `1..dimindex(:N) = k INSERT ((1..dimindex(:N)) DELETE k)`
4015   SUBST1_TAC THENL
4016    [REWRITE_TAC[EXTENSION; IN_INSERT; IN_DELETE; IN_NUMSEG] THEN
4017     ASM_MESON_TAC[];
4018     ALL_TAC] THEN
4019   SIMP_TAC[PRODUCT_CLAUSES; FINITE_NUMSEG; FINITE_DELETE; IN_DELETE] THEN
4020   ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND; REAL_LT_IMP_LE;
4021                 LAMBDA_BETA; IN_DELETE; IN_NUMSEG] THEN
4022   SUBGOAL_THEN
4023    `product ((1..dimindex (:N)) DELETE k)
4024      (\j. ((lambda i. if i = k then min (b$k) (c + d) else b$i):real^N)$j -
4025           ((lambda i. if i = k then max (a$k) (c - d) else a$i):real^N)$j) =
4026     product ((1..dimindex (:N)) DELETE k)
4027             (\i. (b:real^N)$i - (a:real^N)$i)`
4028   SUBST1_TAC THENL
4029    [MATCH_MP_TAC PRODUCT_EQ THEN
4030     SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA];
4031     ALL_TAC] THEN
4032   ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THEN
4033   MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `&2 * d` THEN
4034   CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN
4035   MATCH_MP_TAC(REAL_ARITH `&0 < d /\ &3 * d <= x ==> &2 * d < x`) THEN
4036   ASM_REWRITE_TAC[] THEN EXPAND_TAC "d" THEN REAL_ARITH_TAC);;
4037
4038 let NEGLIGIBLE_STANDARD_HYPERPLANE = prove
4039  (`!c k. 1 <= k /\ k <= dimindex(:N) ==> negligible {x:real^N | x$k = c}`,
4040   REPEAT STRIP_TAC THEN REWRITE_TAC[negligible; has_integral] THEN
4041   REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_SUB_RZERO] THEN
4042   MP_TAC(ISPECL [`a:real^N`; `b:real^N`; `k:num`; `c:real`; `e:real`]
4043         CONTENT_DOUBLESPLIT) THEN
4044   ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
4045   EXISTS_TAC `\x:real^N. ball(x,d)` THEN ASM_SIMP_TAC[GAUGE_BALL] THEN
4046   ABBREV_TAC `i = indicator {x:real^N | x$k = c}` THEN REPEAT STRIP_TAC THEN
4047   SUBGOAL_THEN
4048    `vsum p (\(x,l). content l % i x) =
4049     vsum p (\(x,l). content(l INTER {x:real^N | abs(x$k - c) <= d}) %
4050                     (i:real^N->real^1) x)`
4051   SUBST1_TAC THENL
4052    [MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
4053     MAP_EVERY X_GEN_TAC [`x:real^N`; `l:real^N->bool`] THEN
4054     DISCH_TAC THEN EXPAND_TAC "i" THEN REWRITE_TAC[indicator] THEN
4055     REWRITE_TAC[IN_ELIM_THM] THEN
4056     COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN
4057     AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
4058     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
4059     DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `l:real^N->bool`]) THEN
4060     ASM_REWRITE_TAC[] THEN
4061     MATCH_MP_TAC(SET_RULE `s SUBSET t ==> l SUBSET s ==> l = l INTER t`) THEN
4062     REWRITE_TAC[SUBSET; IN_BALL; IN_ELIM_THM; dist] THEN
4063     UNDISCH_THEN `(x:real^N)$k = c` (SUBST1_TAC o SYM) THEN
4064     ASM_SIMP_TAC[GSYM VECTOR_SUB_COMPONENT] THEN
4065     ONCE_REWRITE_TAC[NORM_SUB] THEN
4066     ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS; REAL_LT_IMP_LE];
4067     ALL_TAC] THEN
4068   MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC
4069    `norm(vsum p (\(x:real^N,l).
4070           content(l INTER {x:real^N | abs(x$k - c) <= d}) %
4071          vec 1:real^1))` THEN
4072   CONJ_TAC THENL
4073    [FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
4074     ASM_SIMP_TAC[VSUM_REAL; NORM_LIFT] THEN
4075     MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= y ==> abs(x) <= abs(y)`) THEN
4076     REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM; DROP_CMUL] THEN CONJ_TAC THENL
4077      [MATCH_MP_TAC SUM_POS_LE; MATCH_MP_TAC SUM_LE] THEN
4078     ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
4079     MAP_EVERY X_GEN_TAC [`x:real^N`; `l:real^N->bool`] THEN STRIP_TAC THENL
4080      [MATCH_MP_TAC REAL_LE_MUL; MATCH_MP_TAC REAL_LE_LMUL] THEN
4081     EXPAND_TAC "i" THEN REWRITE_TAC[DROP_VEC] THEN
4082     REWRITE_TAC[DROP_INDICATOR_POS_LE; DROP_INDICATOR_LE_1] THEN
4083     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
4084     DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `l:real^N->bool`] o
4085         el 1 o CONJUNCTS) THEN
4086     ASM_REWRITE_TAC[] THEN
4087     STRIP_TAC THEN ASM_SIMP_TAC[INTERVAL_DOUBLESPLIT; CONTENT_POS_LE];
4088     ALL_TAC] THEN
4089   MP_TAC(ISPECL [`(\l. content (l INTER {x | abs (x$k - c) <= d}) % vec 1):
4090                   (real^N->bool)->real^1`;
4091                  `p:real^N#(real^N->bool)->bool`;
4092                  `interval[a:real^N,b]`]
4093         VSUM_OVER_TAGGED_DIVISION_LEMMA) THEN
4094   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
4095    [MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN STRIP_TAC THEN
4096     REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN
4097     MATCH_MP_TAC(REAL_ARITH `!x. x = &0 /\ &0 <= y /\ y <= x ==> y = &0`) THEN
4098     EXISTS_TAC `content(interval[u:real^N,v])` THEN
4099     CONJ_TAC THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[] THEN
4100     DISCH_THEN(K ALL_TAC) THEN
4101     ASM_SIMP_TAC[CONTENT_POS_LE; INTERVAL_DOUBLESPLIT] THEN
4102     MATCH_MP_TAC CONTENT_SUBSET THEN
4103     ASM_SIMP_TAC[GSYM INTERVAL_DOUBLESPLIT] THEN SET_TAC[];
4104     ALL_TAC] THEN
4105   DISCH_THEN SUBST1_TAC THEN
4106   MP_TAC(ISPECL
4107      [`IMAGE SND (p:real^N#(real^N->bool)->bool)`;
4108       `\l. l INTER {x:real^N | abs (x$k - c) <= d}`;
4109       `\l:real^N->bool. content l % vec 1 :real^1`;
4110       `{}:real^N->bool`] VSUM_NONZERO_IMAGE_LEMMA) THEN
4111     REWRITE_TAC[o_DEF] THEN
4112   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_TAGGED_DIVISION) THEN
4113   ANTS_TAC THENL
4114    [CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_FINITE]; ALL_TAC] THEN
4115     REWRITE_TAC[CONTENT_EMPTY; VECTOR_MUL_LZERO] THEN
4116     ONCE_REWRITE_TAC[IMP_CONJ] THEN
4117     REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
4118     FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
4119     MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN DISCH_TAC THEN
4120     X_GEN_TAC `m:real^N->bool` THEN STRIP_TAC THEN
4121     REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN
4122     SIMP_TAC[INTERVAL_DOUBLESPLIT; ASSUME `1 <= k`;
4123              ASSUME `k <= dimindex(:N)`] THEN
4124     REWRITE_TAC[CONTENT_EQ_0_INTERIOR] THEN
4125     ASM_SIMP_TAC[GSYM INTERVAL_DOUBLESPLIT] THEN
4126     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
4127     DISCH_THEN(MP_TAC o SPECL [`interval[u:real^N,v]`; `m:real^N->bool`] o
4128       el 2 o CONJUNCTS) THEN ASM_REWRITE_TAC[] THEN
4129     MATCH_MP_TAC(SET_RULE
4130       `u SUBSET s /\ u SUBSET t ==> s INTER t = {} ==> u = {}`) THEN
4131     CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN ASM SET_TAC[];
4132     ALL_TAC] THEN
4133   REWRITE_TAC[o_DEF] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
4134   MATCH_MP_TAC REAL_LET_TRANS THEN
4135   EXISTS_TAC
4136    `&1 * content(interval[a,b] INTER {x:real^N | abs (x$k - c) <= d})` THEN
4137   CONJ_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[REAL_MUL_LID]] THEN
4138   FIRST_ASSUM(MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ]
4139     DIVISION_DOUBLESPLIT)) THEN
4140   DISCH_THEN(MP_TAC o SPECL [`k:num`; `c:real`; `d:real`]) THEN
4141   ASM_SIMP_TAC[INTERVAL_DOUBLESPLIT] THEN DISCH_TAC THEN
4142   MATCH_MP_TAC DSUM_BOUND THEN
4143   ASM_SIMP_TAC[NORM_REAL; VEC_COMPONENT; DIMINDEX_1; LE_REFL] THEN
4144   REAL_ARITH_TAC);;
4145
4146 (* ------------------------------------------------------------------------- *)
4147 (* A technical lemma about "refinement" of division.                         *)
4148 (* ------------------------------------------------------------------------- *)
4149
4150 let TAGGED_DIVISION_FINER = prove
4151  (`!p a b:real^N d. p tagged_division_of interval[a,b] /\ gauge d
4152              ==> ?q. q tagged_division_of interval[a,b] /\ d fine q /\
4153                      !x k. (x,k) IN p /\ k SUBSET d(x) ==> (x,k) IN q`,
4154   let lemma1 = prove
4155    (`{k | ?x. (x,k) IN p} = IMAGE SND p`,
4156     REWRITE_TAC[EXTENSION; EXISTS_PAIR_THM; IN_IMAGE; IN_ELIM_THM] THEN
4157     MESON_TAC[]) in
4158   SUBGOAL_THEN
4159    `!a b:real^N d p.
4160        FINITE p
4161        ==> p tagged_partial_division_of interval[a,b] /\ gauge d
4162            ==> ?q. q tagged_division_of (UNIONS {k | ?x. x,k IN p}) /\
4163                    d fine q /\
4164                    !x k. (x,k) IN p /\ k SUBSET d(x) ==> (x,k) IN q`
4165   ASSUME_TAC THENL
4166    [ALL_TAC;
4167     REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
4168     GEN_REWRITE_TAC LAND_CONV [tagged_division_of] THEN
4169     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (SUBST1_TAC o SYM)) THEN
4170     FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[IMP_IMP]) THEN
4171     ASM_MESON_TAC[tagged_partial_division_of]] THEN
4172   GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN
4173   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN CONJ_TAC THENL
4174    [DISCH_THEN(K ALL_TAC) THEN
4175     REWRITE_TAC[SET_RULE `UNIONS {k | ?x. x,k IN {}} = {}`] THEN
4176     EXISTS_TAC `{}:real^N#(real^N->bool)->bool` THEN
4177     REWRITE_TAC[fine; NOT_IN_EMPTY; TAGGED_DIVISION_OF_EMPTY];
4178     ALL_TAC] THEN
4179   GEN_REWRITE_TAC I [FORALL_PAIR_THM] THEN MAP_EVERY X_GEN_TAC
4180    [`x:real^N`; `k:real^N->bool`; `p:real^N#(real^N->bool)->bool`] THEN
4181   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
4182   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ANTS_TAC THENL
4183    [ASM_REWRITE_TAC[] THEN MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_SUBSET THEN
4184     EXISTS_TAC `(x:real^N,k:real^N->bool) INSERT p` THEN ASM SET_TAC[];
4185     ALL_TAC] THEN
4186   DISCH_THEN(X_CHOOSE_THEN `q1:real^N#(real^N->bool)->bool`
4187     STRIP_ASSUME_TAC) THEN
4188   SUBGOAL_THEN
4189    `UNIONS {l:real^N->bool | ?y:real^N. (y,l) IN (x,k) INSERT p} =
4190     k UNION UNIONS {l | ?y. (y,l) IN p}`
4191   SUBST1_TAC THENL
4192    [GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_UNION; IN_UNIONS] THEN
4193     REWRITE_TAC[IN_ELIM_THM; IN_INSERT; PAIR_EQ] THEN MESON_TAC[];
4194     ALL_TAC] THEN
4195   SUBGOAL_THEN `?u v:real^N. k = interval[u,v]` MP_TAC THENL
4196    [ASM_MESON_TAC[IN_INSERT; tagged_partial_division_of]; ALL_TAC] THEN
4197   DISCH_THEN(REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) THEN
4198   ASM_CASES_TAC `interval[u,v] SUBSET ((d:real^N->real^N->bool) x)` THENL
4199    [EXISTS_TAC `{(x:real^N,interval[u:real^N,v])} UNION q1` THEN CONJ_TAC THENL
4200      [MATCH_MP_TAC TAGGED_DIVISION_UNION THEN ASM_REWRITE_TAC[] THEN
4201       CONJ_TAC THENL
4202        [MATCH_MP_TAC TAGGED_DIVISION_OF_SELF THEN
4203         FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I
4204          [tagged_partial_division_of]) THEN
4205         REWRITE_TAC[IN_INSERT; PAIR_EQ] THEN MESON_TAC[];
4206         ALL_TAC];
4207       CONJ_TAC THENL
4208        [MATCH_MP_TAC FINE_UNION THEN ASM_REWRITE_TAC[] THEN
4209         REWRITE_TAC[fine; IN_SING; PAIR_EQ] THEN ASM_MESON_TAC[];
4210         ALL_TAC] THEN
4211       ASM_REWRITE_TAC[IN_INSERT; PAIR_EQ; IN_UNION; IN_SING] THEN
4212       ASM_MESON_TAC[]];
4213     FIRST_ASSUM(MP_TAC o SPECL [`u:real^N`; `v:real^N`] o MATCH_MP
4214       FINE_DIVISION_EXISTS) THEN
4215     DISCH_THEN(X_CHOOSE_THEN `q2:real^N#(real^N->bool)->bool`
4216       STRIP_ASSUME_TAC) THEN
4217     EXISTS_TAC `q2 UNION q1:real^N#(real^N->bool)->bool` THEN CONJ_TAC THENL
4218      [MATCH_MP_TAC TAGGED_DIVISION_UNION THEN ASM_REWRITE_TAC[];
4219       ASM_SIMP_TAC[FINE_UNION] THEN
4220       ASM_REWRITE_TAC[IN_INSERT; PAIR_EQ; IN_UNION; IN_SING] THEN
4221       ASM_MESON_TAC[]]] THEN
4222   (MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
4223    REWRITE_TAC[lemma1; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
4224    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I
4225       [tagged_partial_division_of]) THEN
4226    REWRITE_TAC[IN_INSERT; FINITE_INSERT; PAIR_EQ] THEN
4227    STRIP_TAC THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN CONJ_TAC THENL
4228     [REWRITE_TAC[INTERIOR_CLOSED_INTERVAL; OPEN_INTERVAL]; ALL_TAC] THEN
4229    CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
4230    REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
4231    ASM_MESON_TAC[]));;
4232
4233 (* ------------------------------------------------------------------------- *)
4234 (* Hence the main theorem about negligible sets.                             *)
4235 (* ------------------------------------------------------------------------- *)
4236
4237 let HAS_INTEGRAL_NEGLIGIBLE = prove
4238  (`!f:real^M->real^N s t.
4239         negligible s /\ (!x. x IN (t DIFF s) ==> f x = vec 0)
4240         ==> (f has_integral (vec 0)) t`,
4241   let lemma = prove
4242    (`!f:B->real g:A#B->real s t.
4243           FINITE s /\ FINITE t /\
4244           (!x y. (x,y) IN t ==> &0 <= g(x,y)) /\
4245           (!y. y IN s ==> ?x. (x,y) IN t /\ f(y) <= g(x,y))
4246           ==> sum s f <= sum t g`,
4247     REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_LE_INCLUDED THEN
4248     EXISTS_TAC `SND:A#B->B` THEN
4249     REWRITE_TAC[EXISTS_PAIR_THM; FORALL_PAIR_THM] THEN
4250     ASM_MESON_TAC[]) in
4251   SUBGOAL_THEN
4252    `!f:real^M->real^N s a b.
4253         negligible s /\ (!x. ~(x IN s) ==> f x = vec 0)
4254         ==> (f has_integral (vec 0)) (interval[a,b])`
4255   ASSUME_TAC THENL
4256    [ALL_TAC;
4257     REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC THEN
4258     ONCE_REWRITE_TAC[has_integral_alt] THEN COND_CASES_TAC THENL
4259      [MATCH_MP_TAC HAS_INTEGRAL_EQ THEN
4260       EXISTS_TAC `\x. if x IN t then (f:real^M->real^N) x else vec 0` THEN
4261       SIMP_TAC[] THEN
4262       FIRST_X_ASSUM(CHOOSE_THEN(CHOOSE_THEN SUBST_ALL_TAC)) THEN
4263       FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[];
4264       ALL_TAC] THEN
4265     GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN
4266     REWRITE_TAC[REAL_LT_01] THEN
4267     REPEAT STRIP_TAC THEN EXISTS_TAC `vec 0:real^N` THEN
4268     ASM_REWRITE_TAC[NORM_0; VECTOR_SUB_REFL] THEN
4269     FIRST_X_ASSUM MATCH_MP_TAC THEN
4270     EXISTS_TAC `s:real^M->bool` THEN ASM_MESON_TAC[]] THEN
4271   REWRITE_TAC[negligible; has_integral; RIGHT_FORALL_IMP_THM] THEN
4272   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
4273   MAP_EVERY(fun t -> MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC t)
4274    [`a:real^M`; `b:real^M`] THEN
4275   REWRITE_TAC[VECTOR_SUB_RZERO] THEN DISCH_TAC THEN
4276   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
4277   FIRST_X_ASSUM(MP_TAC o GEN `n:num` o
4278       SPEC `e / &2 / ((&n + &1) * &2 pow n)`) THEN
4279   REWRITE_TAC[real_div; REAL_MUL_POS_LT] THEN REWRITE_TAC[GSYM real_div] THEN
4280   ASM_SIMP_TAC[REAL_LT_INV_EQ; REAL_LT_MUL; REAL_POW_LT; REAL_OF_NUM_LT;
4281            FORALL_AND_THM; ARITH; REAL_ARITH `&0 < &n + &1`; SKOLEM_THM] THEN
4282   DISCH_THEN(X_CHOOSE_THEN `d:num->real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
4283   EXISTS_TAC `\x. (d:num->real^M->real^M->bool)
4284                   (num_of_int(int_of_real(floor(norm(f x:real^N))))) x` THEN
4285   CONJ_TAC THENL [REWRITE_TAC[gauge] THEN ASM_MESON_TAC[gauge]; ALL_TAC] THEN
4286   X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN
4287   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
4288   ASM_CASES_TAC `p:real^M#(real^M->bool)->bool = {}` THEN
4289   ASM_REWRITE_TAC[VSUM_CLAUSES; NORM_0] THEN
4290   MP_TAC(SPEC `sup(IMAGE (\(x,k:real^M->bool). norm((f:real^M->real^N) x)) p)`
4291     REAL_ARCH_SIMPLE) THEN
4292   ASM_SIMP_TAC[REAL_SUP_LE_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
4293   REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN
4294   DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
4295   MP_TAC(GEN `i:num`
4296    (ISPECL [`p:real^M#(real^M->bool)->bool`; `a:real^M`; `b:real^M`;
4297                 `(d:num->real^M->real^M->bool) i`]
4298                 TAGGED_DIVISION_FINER)) THEN
4299   ASM_REWRITE_TAC[SKOLEM_THM; RIGHT_IMP_EXISTS_THM; FORALL_AND_THM] THEN
4300   DISCH_THEN(X_CHOOSE_THEN `q:num->real^M#(real^M->bool)->bool`
4301         STRIP_ASSUME_TAC) THEN
4302   MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC
4303    `sum(0..N+1) (\i. (&i + &1) *
4304                      norm(vsum (q i) (\(x:real^M,k:real^M->bool).
4305                                             content k % indicator s x)))` THEN
4306   CONJ_TAC THENL
4307    [ALL_TAC;
4308     MATCH_MP_TAC REAL_LET_TRANS THEN
4309     EXISTS_TAC `sum (0..N+1) (\i. e / &2 / &2 pow i)` THEN CONJ_TAC THENL
4310      [ALL_TAC;
4311       REWRITE_TAC[real_div; SUM_LMUL; GSYM REAL_POW_INV] THEN
4312       REWRITE_TAC[SUM_GP; LT] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
4313       REWRITE_TAC[REAL_ARITH `(e * &1 / &2) * (&1 - x) / (&1 / &2) < e <=>
4314                                 &0 < e * x`] THEN
4315       ASM_SIMP_TAC[REAL_LT_MUL; REAL_POW_LT; REAL_ARITH `&0 < &1 / &2`]] THEN
4316     MATCH_MP_TAC SUM_LE_NUMSEG THEN REPEAT STRIP_TAC THEN
4317     REWRITE_TAC[] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
4318     ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
4319     REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN
4320     REWRITE_TAC[GSYM REAL_INV_MUL] THEN REWRITE_TAC[GSYM real_div] THEN
4321     ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN MATCH_MP_TAC REAL_LT_IMP_LE THEN
4322     FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]] THEN
4323   FIRST_ASSUM(ASSUME_TAC o GEN `i:num` o
4324     MATCH_MP TAGGED_DIVISION_OF_FINITE o SPEC `i:num`) THEN
4325   ASM_SIMP_TAC[VSUM_REAL; NORM_LIFT] THEN
4326   REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM; DROP_CMUL] THEN
4327   REWRITE_TAC[real_abs] THEN
4328   SUBGOAL_THEN
4329    `!i:num. &0 <= sum (q i) (\(x:real^M,y:real^M->bool).
4330               content y * drop (indicator s x))`
4331   ASSUME_TAC THENL
4332    [REPEAT GEN_TAC THEN MATCH_MP_TAC SUM_POS_LE THEN
4333     ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
4334     REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_MUL THEN
4335     REWRITE_TAC[DROP_INDICATOR_POS_LE] THEN
4336     ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE];
4337     ALL_TAC] THEN
4338   ASM_REWRITE_TAC[GSYM SUM_LMUL] THEN
4339   REWRITE_TAC[LAMBDA_PAIR_THM] THEN
4340   W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
4341   ASM_REWRITE_TAC[] THEN
4342   MATCH_MP_TAC(REAL_ARITH `x <= y ==> n <= x ==> n <= y`) THEN
4343   ASM_SIMP_TAC[SUM_SUM_PRODUCT; FINITE_NUMSEG] THEN
4344   MATCH_MP_TAC lemma THEN
4345   ASM_SIMP_TAC[FINITE_PRODUCT_DEPENDENT; FORALL_PAIR_THM; FINITE_NUMSEG] THEN
4346   REWRITE_TAC[IN_ELIM_PAIR_THM] THEN CONJ_TAC THENL
4347    [REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN
4348     CONJ_TAC THENL [REAL_ARITH_TAC; MATCH_MP_TAC REAL_LE_MUL] THEN
4349     REWRITE_TAC[DROP_INDICATOR_POS_LE] THEN
4350     ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE];
4351     ALL_TAC] THEN
4352   MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
4353   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
4354   DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `k:real^M->bool`]) THEN
4355   ASM_REWRITE_TAC[] THEN ABBREV_TAC
4356    `n = num_of_int(int_of_real(floor(norm((f:real^M->real^N) x))))` THEN
4357   SUBGOAL_THEN `&n <= norm((f:real^M->real^N) x) /\
4358                 norm(f x) < &n + &1`
4359   STRIP_ASSUME_TAC THENL
4360    [SUBGOAL_THEN `&n = floor(norm((f:real^M->real^N) x))`
4361      (fun th -> MESON_TAC[th; FLOOR]) THEN
4362     EXPAND_TAC "n" THEN
4363     MP_TAC(ISPEC `norm((f:real^M->real^N) x)` FLOOR_POS) THEN
4364     REWRITE_TAC[NORM_POS_LE; LEFT_IMP_EXISTS_THM] THEN
4365     X_GEN_TAC `m:num` THEN DISCH_THEN SUBST1_TAC THEN
4366     REWRITE_TAC[GSYM int_of_num; NUM_OF_INT_OF_NUM];
4367     ALL_TAC] THEN
4368   DISCH_TAC THEN EXISTS_TAC `n:num` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
4369    [ASM_SIMP_TAC[IN_NUMSEG; LE_0] THEN
4370     REWRITE_TAC[GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_ADD] THEN
4371     MATCH_MP_TAC REAL_LE_TRANS THEN
4372     EXISTS_TAC `norm((f:real^M->real^N) x)` THEN ASM_REWRITE_TAC[] THEN
4373     MATCH_MP_TAC(REAL_ARITH `x <= n ==> x <= n + &1`) THEN
4374     ASM_MESON_TAC[];
4375     ALL_TAC] THEN
4376   ASM_CASES_TAC `(x:real^M) IN s` THEN ASM_SIMP_TAC[indicator] THEN
4377   REWRITE_TAC[DROP_VEC; REAL_MUL_RZERO; NORM_0;
4378               VECTOR_MUL_RZERO; REAL_LE_REFL] THEN
4379   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
4380   REWRITE_TAC[DROP_VEC; REAL_MUL_RID; NORM_MUL] THEN
4381   SUBGOAL_THEN `&0 <= content(k:real^M->bool)` ASSUME_TAC THENL
4382    [ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE]; ALL_TAC] THEN
4383   ASM_REWRITE_TAC[real_abs] THEN MATCH_MP_TAC REAL_LE_LMUL THEN
4384   ASM_SIMP_TAC[REAL_LT_IMP_LE]);;
4385
4386 let HAS_INTEGRAL_SPIKE = prove
4387  (`!f:real^M->real^N g s t.
4388         negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x) /\
4389         (f has_integral y) t
4390         ==> (g has_integral y) t`,
4391   SUBGOAL_THEN
4392    `!f:real^M->real^N g s a b y.
4393         negligible s /\ (!x. x IN (interval[a,b] DIFF s) ==> g x = f x)
4394         ==> (f has_integral y) (interval[a,b])
4395             ==> (g has_integral y) (interval[a,b])`
4396   ASSUME_TAC THENL
4397    [REPEAT STRIP_TAC THEN
4398     SUBGOAL_THEN
4399      `((\x. (f:real^M->real^N)(x) + (g(x) - f(x))) has_integral (y + vec 0))
4400       (interval[a,b])`
4401     MP_TAC THENL
4402      [ALL_TAC;
4403       REWRITE_TAC[VECTOR_ARITH `f + g - f = g /\ f + vec 0 = f`; ETA_AX]] THEN
4404     MATCH_MP_TAC HAS_INTEGRAL_ADD THEN ASM_REWRITE_TAC[] THEN
4405     MATCH_MP_TAC HAS_INTEGRAL_NEGLIGIBLE THEN
4406     EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[VECTOR_SUB_EQ] THEN
4407     ASM_MESON_TAC[];
4408     ALL_TAC] THEN
4409   REPEAT GEN_TAC THEN
4410   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
4411   ONCE_REWRITE_TAC[has_integral_alt] THEN COND_CASES_TAC THEN
4412   ASM_REWRITE_TAC[] THENL
4413    [FIRST_X_ASSUM(CHOOSE_THEN(CHOOSE_THEN SUBST_ALL_TAC)) THEN ASM_MESON_TAC[];
4414     ALL_TAC] THEN
4415   MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
4416   REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
4417   MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
4418   REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
4419   MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
4420   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
4421   MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
4422   FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `s:real^M->bool` THEN
4423   ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);;
4424
4425 let HAS_INTEGRAL_SPIKE_EQ = prove
4426  (`!f:real^M->real^N g s t y.
4427         negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x)
4428         ==> ((f has_integral y) t <=> (g has_integral y) t)`,
4429   REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
4430   MATCH_MP_TAC HAS_INTEGRAL_SPIKE THENL
4431    [EXISTS_TAC `f:real^M->real^N`; EXISTS_TAC `g:real^M->real^N`] THEN
4432   EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN
4433   ASM_MESON_TAC[NORM_SUB]);;
4434
4435 let INTEGRABLE_SPIKE = prove
4436  (`!f:real^M->real^N g s t.
4437         negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x)
4438         ==> f integrable_on t ==> g integrable_on  t`,
4439   REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[integrable_on] THEN
4440   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
4441   MP_TAC(SPEC_ALL HAS_INTEGRAL_SPIKE) THEN ASM_REWRITE_TAC[]);;
4442
4443 let INTEGRABLE_SPIKE_EQ = prove
4444  (`!f:real^M->real^N g s t.
4445         negligible s /\ (!x. x IN t DIFF s ==> g x = f x)
4446         ==> (f integrable_on t <=> g integrable_on t)`,
4447   MESON_TAC[INTEGRABLE_SPIKE]);;
4448
4449 let INTEGRAL_SPIKE = prove
4450  (`!f:real^M->real^N g s t y.
4451         negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x)
4452         ==> integral t f = integral t g`,
4453   REPEAT STRIP_TAC THEN REWRITE_TAC[integral] THEN
4454   AP_TERM_TAC THEN ABS_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_EQ THEN
4455   ASM_MESON_TAC[]);;
4456
4457 (* ------------------------------------------------------------------------- *)
4458 (* Some other trivialities about negligible sets.                            *)
4459 (* ------------------------------------------------------------------------- *)
4460
4461 let NEGLIGIBLE_SUBSET = prove
4462  (`!s:real^N->bool t:real^N->bool.
4463         negligible s /\ t SUBSET s ==> negligible t`,
4464   REPEAT STRIP_TAC THEN REWRITE_TAC[negligible] THEN
4465   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
4466   MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN
4467   MAP_EVERY EXISTS_TAC [`(\x. vec 0):real^N->real^1`; `s:real^N->bool`] THEN
4468   ASM_REWRITE_TAC[HAS_INTEGRAL_0] THEN
4469   REWRITE_TAC[indicator] THEN ASM SET_TAC[]);;
4470
4471 let NEGLIGIBLE_DIFF = prove
4472  (`!s t:real^N->bool. negligible s ==> negligible(s DIFF t)`,
4473   REPEAT STRIP_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN
4474   EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[SUBSET_DIFF]);;
4475
4476 let NEGLIGIBLE_INTER = prove
4477  (`!s t. negligible s \/ negligible t ==> negligible(s INTER t)`,
4478   MESON_TAC[NEGLIGIBLE_SUBSET; INTER_SUBSET]);;
4479
4480 let NEGLIGIBLE_UNION = prove
4481  (`!s t:real^N->bool.
4482         negligible s /\ negligible t ==> negligible (s UNION t)`,
4483   REPEAT GEN_TAC THEN DISCH_TAC THEN FIRST_ASSUM MP_TAC THEN
4484   REWRITE_TAC[negligible; AND_FORALL_THM] THEN
4485   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `a:real^N` THEN
4486   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `b:real^N` THEN
4487   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_ADD) THEN
4488   REWRITE_TAC[VECTOR_ADD_LID] THEN MATCH_MP_TAC EQ_IMP THEN
4489   MATCH_MP_TAC HAS_INTEGRAL_SPIKE_EQ THEN
4490   EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN
4491   SIMP_TAC[indicator; IN_UNION; IN_DIFF; VECTOR_ADD_LID]);;
4492
4493 let NEGLIGIBLE_UNION_EQ = prove
4494  (`!s t:real^N->bool.
4495         negligible (s UNION t) <=> negligible s /\ negligible t`,
4496   MESON_TAC[NEGLIGIBLE_UNION; SUBSET_UNION; NEGLIGIBLE_SUBSET]);;
4497
4498 let NEGLIGIBLE_SING = prove
4499  (`!a:real^N. negligible {a}`,
4500   GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN
4501   EXISTS_TAC `{x | (x:real^N)$1 = (a:real^N)$1}` THEN
4502   SIMP_TAC[NEGLIGIBLE_STANDARD_HYPERPLANE; LE_REFL; DIMINDEX_GE_1] THEN
4503   SET_TAC[]);;
4504
4505 let NEGLIGIBLE_INSERT = prove
4506  (`!a:real^N s. negligible(a INSERT s) <=> negligible s`,
4507   ONCE_REWRITE_TAC[SET_RULE `a INSERT s = {a} UNION s`] THEN
4508   REWRITE_TAC[NEGLIGIBLE_UNION_EQ; NEGLIGIBLE_SING]);;
4509
4510 let NEGLIGIBLE_EMPTY = prove
4511  (`negligible {}`,
4512   MESON_TAC[EMPTY_SUBSET; NEGLIGIBLE_SUBSET; NEGLIGIBLE_SING]);;
4513
4514 let NEGLIGIBLE_FINITE = prove
4515  (`!s. FINITE s ==> negligible s`,
4516   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
4517   SIMP_TAC[NEGLIGIBLE_EMPTY; NEGLIGIBLE_INSERT]);;
4518
4519 let NEGLIGIBLE_UNIONS = prove
4520  (`!s. FINITE s /\ (!t. t IN s ==> negligible t)
4521        ==> negligible(UNIONS s)`,
4522   REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
4523   REWRITE_TAC[UNIONS_0; UNIONS_INSERT; NEGLIGIBLE_EMPTY; IN_INSERT] THEN
4524   SIMP_TAC[NEGLIGIBLE_UNION]);;
4525
4526 let NEGLIGIBLE = prove
4527  (`!s:real^N->bool. negligible s <=> !t. (indicator s has_integral vec 0) t`,
4528   GEN_TAC THEN EQ_TAC THENL
4529    [ALL_TAC; REWRITE_TAC[negligible] THEN SIMP_TAC[]] THEN
4530   DISCH_TAC THEN GEN_TAC THEN ONCE_REWRITE_TAC[has_integral_alt] THEN
4531   COND_CASES_TAC THENL [ASM_MESON_TAC[negligible]; ALL_TAC] THEN
4532   GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
4533   REPEAT STRIP_TAC THEN EXISTS_TAC `vec 0:real^1` THEN
4534   MP_TAC(ISPECL [`s:real^N->bool`; `s INTER t:real^N->bool`]
4535         NEGLIGIBLE_SUBSET) THEN
4536   ASM_REWRITE_TAC[INTER_SUBSET; negligible; VECTOR_SUB_REFL; NORM_0] THEN
4537   REWRITE_TAC[indicator; IN_INTER] THEN
4538   SIMP_TAC[TAUT `(if p /\ q then r else s) =
4539                  (if q then if p then r else s else s)`]);;
4540
4541 (* ------------------------------------------------------------------------- *)
4542 (* Finite or empty cases of the spike theorem are quite commonly needed.     *)
4543 (* ------------------------------------------------------------------------- *)
4544
4545 let HAS_INTEGRAL_SPIKE_FINITE = prove
4546  (`!f:real^M->real^N g s t y.
4547         FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x) /\
4548         (f has_integral y) t
4549         ==> (g has_integral y) t`,
4550   MESON_TAC[HAS_INTEGRAL_SPIKE; NEGLIGIBLE_FINITE]);;
4551
4552 let HAS_INTEGRAL_SPIKE_FINITE_EQ = prove
4553  (`!f:real^M->real^N g s y.
4554         FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x)
4555         ==> ((f has_integral y) t <=> (g has_integral y) t)`,
4556   MESON_TAC[HAS_INTEGRAL_SPIKE_FINITE]);;
4557
4558 let INTEGRABLE_SPIKE_FINITE = prove
4559  (`!f:real^M->real^N g s.
4560         FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x)
4561         ==> f integrable_on t
4562             ==> g integrable_on  t`,
4563   REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[integrable_on] THEN
4564   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
4565   MP_TAC(SPEC_ALL HAS_INTEGRAL_SPIKE_FINITE) THEN ASM_REWRITE_TAC[]);;
4566
4567 let INTEGRAL_EQ = prove
4568  (`!f:real^M->real^N g s.
4569         (!x. x IN s ==> f x = g x) ==> integral s f = integral s g`,
4570   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_SPIKE THEN
4571   EXISTS_TAC `{}:real^M->bool` THEN ASM_SIMP_TAC[NEGLIGIBLE_EMPTY; IN_DIFF]);;
4572
4573 let INTEGRAL_EQ_0 = prove
4574  (`!f:real^M->real^N s. (!x. x IN s ==> f x = vec 0) ==> integral s f = vec 0`,
4575   REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
4576   EXISTS_TAC `integral s ((\x. vec 0):real^M->real^N)` THEN
4577   CONJ_TAC THENL
4578    [MATCH_MP_TAC INTEGRAL_EQ THEN ASM_REWRITE_TAC[];
4579     REWRITE_TAC[INTEGRAL_0]]);;
4580
4581 (* ------------------------------------------------------------------------- *)
4582 (* In particular, the boundary of an interval is negligible.                 *)
4583 (* ------------------------------------------------------------------------- *)
4584
4585 let NEGLIGIBLE_FRONTIER_INTERVAL = prove
4586  (`!a b:real^N. negligible(interval[a,b] DIFF interval(a,b))`,
4587   REPEAT GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN
4588   EXISTS_TAC `UNIONS (IMAGE (\k. {x:real^N | x$k = (a:real^N)$k} UNION
4589                                  {x:real^N | x$k = (b:real^N)$k})
4590                             (1..dimindex(:N)))` THEN
4591   CONJ_TAC THENL
4592    [MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN
4593     SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; FORALL_IN_IMAGE] THEN
4594     SIMP_TAC[IN_NUMSEG; NEGLIGIBLE_UNION_EQ; NEGLIGIBLE_STANDARD_HYPERPLANE];
4595     REWRITE_TAC[SUBSET; IN_DIFF; IN_INTERVAL; IN_UNIONS; EXISTS_IN_IMAGE] THEN
4596     REWRITE_TAC[IN_NUMSEG; IN_UNION; IN_ELIM_THM; REAL_LT_LE] THEN
4597     MESON_TAC[]]);;
4598
4599 let HAS_INTEGRAL_SPIKE_INTERIOR = prove
4600  (`!f:real^M->real^N g a b y.
4601         (!x. x IN interval(a,b) ==> g x = f x) /\
4602         (f has_integral y) (interval[a,b])
4603         ==> (g has_integral y) (interval[a,b])`,
4604   REPEAT GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN DISCH_TAC THEN
4605   MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
4606                            HAS_INTEGRAL_SPIKE) THEN
4607   EXISTS_TAC `interval[a:real^M,b] DIFF interval(a,b)` THEN
4608   REWRITE_TAC[NEGLIGIBLE_FRONTIER_INTERVAL] THEN ASM SET_TAC[]);;
4609
4610 let HAS_INTEGRAL_SPIKE_INTERIOR_EQ = prove
4611  (`!f:real^M->real^N g a b y.
4612         (!x. x IN interval(a,b) ==> g x = f x)
4613         ==> ((f has_integral y) (interval[a,b]) <=>
4614              (g has_integral y) (interval[a,b]))`,
4615   MESON_TAC[HAS_INTEGRAL_SPIKE_INTERIOR]);;
4616
4617 let INTEGRABLE_SPIKE_INTERIOR = prove
4618  (`!f:real^M->real^N g a b.
4619         (!x. x IN interval(a,b) ==> g x = f x)
4620         ==> f integrable_on (interval[a,b])
4621             ==> g integrable_on  (interval[a,b])`,
4622   REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[integrable_on] THEN
4623   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
4624   MP_TAC(SPEC_ALL HAS_INTEGRAL_SPIKE_INTERIOR) THEN ASM_REWRITE_TAC[]);;
4625
4626 (* ------------------------------------------------------------------------- *)
4627 (* Integrability of continuous functions.                                    *)
4628 (* ------------------------------------------------------------------------- *)
4629
4630 let NEUTRAL_AND = prove
4631  (`neutral(/\) = T`,
4632   REWRITE_TAC[neutral; FORALL_BOOL_THM] THEN MESON_TAC[]);;
4633
4634 let MONOIDAL_AND = prove
4635  (`monoidal(/\)`,
4636   REWRITE_TAC[monoidal; NEUTRAL_AND; CONJ_ACI]);;
4637
4638 let ITERATE_AND = prove
4639  (`!p s. FINITE s ==> (iterate(/\) s p <=> !x. x IN s ==> p x)`,
4640   GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
4641   ASM_SIMP_TAC[MONOIDAL_AND; NEUTRAL_AND; ITERATE_CLAUSES] THEN SET_TAC[]);;
4642
4643 let OPERATIVE_DIVISION_AND = prove
4644  (`!P d a b. operative(/\) P /\ d division_of interval[a,b]
4645              ==> ((!i. i IN d ==> P i) <=> P(interval[a,b]))`,
4646   REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o CONJ MONOIDAL_AND) THEN
4647   FIRST_ASSUM(MP_TAC o MATCH_MP OPERATIVE_DIVISION) THEN
4648   ASM_MESON_TAC[ITERATE_AND; DIVISION_OF_FINITE]);;
4649
4650 let OPERATIVE_APPROXIMABLE = prove
4651  (`!f:real^M->real^N e.
4652         &0 <= e
4653         ==> operative(/\)
4654                (\i. ?g. (!x. x IN i ==> norm (f x - g x) <= e) /\
4655                         g integrable_on i)`,
4656   REPEAT STRIP_TAC THEN REWRITE_TAC[operative; NEUTRAL_AND] THEN CONJ_TAC THENL
4657    [REPEAT STRIP_TAC THEN EXISTS_TAC `f:real^M->real^N` THEN
4658     ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0; integrable_on] THEN
4659     ASM_MESON_TAC[HAS_INTEGRAL_NULL];
4660     ALL_TAC] THEN
4661   MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`; `c:real`; `k:num`] THEN
4662   STRIP_TAC THEN EQ_TAC THENL
4663    [ASM_MESON_TAC[INTEGRABLE_SPLIT; IN_INTER]; ALL_TAC] THEN
4664   DISCH_THEN(CONJUNCTS_THEN2
4665    (X_CHOOSE_THEN `g1:real^M->real^N` STRIP_ASSUME_TAC)
4666    (X_CHOOSE_THEN `g2:real^M->real^N` STRIP_ASSUME_TAC)) THEN
4667   EXISTS_TAC `\x. if x$k = c then (f:real^M->real^N)(x) else
4668                   if x$k <= c then g1(x) else g2(x)` THEN
4669   CONJ_TAC THENL
4670    [GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[] THEN
4671     COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN
4672     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTER; IN_ELIM_THM]) THEN
4673     ASM_MESON_TAC[REAL_ARITH `x <= c \/ x >= c`];
4674     ALL_TAC] THEN
4675   SUBGOAL_THEN
4676    `(\x:real^M. if x$k = c then f x else if x$k <= c then g1 x else g2 x)
4677     integrable_on (interval[u,v] INTER {x | x$k <= c}) /\
4678     (\x. if x$k = c then f x :real^N else if x$k <= c then g1 x else g2 x)
4679     integrable_on (interval[u,v] INTER {x | x$k >= c})`
4680   MP_TAC THENL
4681    [ALL_TAC;
4682     REWRITE_TAC[integrable_on] THEN ASM_MESON_TAC[HAS_INTEGRAL_SPLIT]] THEN
4683   CONJ_TAC THENL
4684    [UNDISCH_TAC
4685      `(g1:real^M->real^N) integrable_on (interval[u,v] INTER {x | x$k <= c})`;
4686     UNDISCH_TAC
4687     `(g2:real^M->real^N) integrable_on (interval[u,v] INTER {x | x$k >= c})`
4688    ] THEN
4689   ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MATCH_MP_TAC INTEGRABLE_SPIKE THEN
4690   ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THEN
4691   EXISTS_TAC `{x:real^M | x$k = c}` THEN
4692   ASM_SIMP_TAC[NEGLIGIBLE_STANDARD_HYPERPLANE; IN_DIFF; IN_INTER; IN_ELIM_THM;
4693                REAL_ARITH `x >= c /\ ~(x = c) ==> ~(x <= c)`] THEN
4694   EXISTS_TAC `e:real` THEN REPEAT STRIP_TAC THEN
4695   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM]);;
4696
4697 let APPROXIMABLE_ON_DIVISION = prove
4698  (`!f:real^M->real^N d a b.
4699         &0 <= e /\
4700         (d division_of interval[a,b]) /\
4701         (!i. i IN d
4702              ==> ?g. (!x. x IN i ==> norm (f x - g x) <= e) /\
4703                      g integrable_on i)
4704         ==> ?g. (!x. x IN interval[a,b] ==> norm (f x - g x) <= e) /\
4705                 g integrable_on interval[a,b]`,
4706   REPEAT STRIP_TAC THEN
4707   MP_TAC(ISPECL [`(/\)`; `d:(real^M->bool)->bool`;
4708                  `a:real^M`; `b:real^M`;
4709                  `\i. ?g:real^M->real^N.
4710                        (!x. x IN i ==> norm (f x - g x) <= e) /\
4711                        g integrable_on i`]
4712                 OPERATIVE_DIVISION) THEN
4713   ASM_SIMP_TAC[OPERATIVE_APPROXIMABLE; MONOIDAL_AND] THEN
4714   DISCH_THEN(SUBST1_TAC o SYM) THEN
4715   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
4716   ASM_SIMP_TAC[ITERATE_AND]);;
4717
4718 let INTEGRABLE_CONTINUOUS = prove
4719  (`!f:real^M->real^N a b.
4720         f continuous_on interval[a,b] ==> f integrable_on interval[a,b]`,
4721   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_UNIFORM_LIMIT THEN
4722   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
4723   MATCH_MP_TAC APPROXIMABLE_ON_DIVISION THEN
4724   ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN
4725   FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
4726     COMPACT_UNIFORMLY_CONTINUOUS)) THEN
4727   REWRITE_TAC[COMPACT_INTERVAL; uniformly_continuous_on] THEN
4728   DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[dist] THEN
4729   DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
4730   SUBGOAL_THEN
4731    `?p. p tagged_division_of interval[a:real^M,b] /\ (\x. ball(x,d)) fine p`
4732   STRIP_ASSUME_TAC THENL
4733    [ASM_MESON_TAC[FINE_DIVISION_EXISTS; GAUGE_BALL]; ALL_TAC] THEN
4734   EXISTS_TAC `IMAGE SND (p:real^M#(real^M->bool)->bool)` THEN
4735   ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION] THEN
4736   REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN
4737   MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
4738   DISCH_TAC THEN EXISTS_TAC `\y:real^M. (f:real^M->real^N) x` THEN
4739   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
4740   DISCH_THEN(MP_TAC o
4741     SPECL [`x:real^M`; `l:real^M->bool`] o el 1 o CONJUNCTS) THEN
4742   ASM_REWRITE_TAC[SUBSET] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4743   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
4744   REWRITE_TAC[SUBSET; IN_BALL; dist] THEN
4745    FIRST_X_ASSUM SUBST_ALL_TAC THEN REPEAT STRIP_TAC THENL
4746    [ASM_MESON_TAC[REAL_LT_IMP_LE; NORM_SUB];
4747     REWRITE_TAC[integrable_on] THEN
4748     EXISTS_TAC `content(interval[a':real^M,b']) % (f:real^M->real^N) x` THEN
4749     REWRITE_TAC[HAS_INTEGRAL_CONST]]);;
4750
4751 (* ------------------------------------------------------------------------- *)
4752 (* Specialization of additivity to one dimension.                            *)
4753 (* ------------------------------------------------------------------------- *)
4754
4755 let OPERATIVE_1_LT = prove
4756  (`!op. monoidal op
4757         ==> !f. operative op f <=>
4758                 (!a b. drop b <= drop a ==> f(interval[a,b]) = neutral op) /\
4759                 (!a b c. drop a < drop c /\ drop c < drop b
4760                          ==> op (f(interval[a,c])) (f(interval[c,b])) =
4761                              f(interval[a,b]))`,
4762   REPEAT STRIP_TAC THEN REWRITE_TAC[operative; CONTENT_EQ_0_1] THEN
4763   MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> (a /\ b <=> a /\ c)`) THEN
4764   DISCH_TAC THEN REWRITE_TAC[FORALL_1; DIMINDEX_1] THEN
4765   AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `a:real^1` THEN
4766   AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `b:real^1` THEN
4767   EQ_TAC THEN DISCH_TAC THENL
4768    [X_GEN_TAC `c:real^1` THEN FIRST_ASSUM(SUBST1_TAC o SPEC `drop c`) THEN
4769     DISCH_TAC THEN FIRST_ASSUM(ASSUME_TAC o MATCH_MP REAL_LT_TRANS) THEN
4770     ASM_SIMP_TAC[INTERVAL_SPLIT; DIMINDEX_1; LE_REFL; REAL_LT_IMP_LE] THEN
4771     BINOP_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
4772     REWRITE_TAC[CONS_11; PAIR_EQ] THEN
4773     SIMP_TAC[FORALL_1; CART_EQ; DIMINDEX_1; LAMBDA_BETA; LE_REFL] THEN
4774     REWRITE_TAC[GSYM drop] THEN ASM_REAL_ARITH_TAC;
4775     ALL_TAC] THEN
4776   X_GEN_TAC `d:real` THEN ABBREV_TAC `c = lift d` THEN
4777   SUBGOAL_THEN `d = drop c` SUBST1_TAC THENL
4778    [ASM_MESON_TAC[LIFT_DROP]; ALL_TAC] THEN
4779   SIMP_TAC[INTERVAL_SPLIT; LE_REFL; drop; DIMINDEX_1] THEN
4780   REWRITE_TAC[GSYM drop] THEN
4781   DISJ_CASES_TAC(REAL_ARITH `drop c <= drop a \/ drop a < drop c`) THENL
4782    [SUBGOAL_THEN
4783      `content(interval[a:real^1,
4784         (lambda i. if i = 1 then min (drop b) (drop c) else b$i)]) = &0 /\
4785       interval[(lambda i. if i = 1 then max (drop a) (drop c) else a$i),b] =
4786       interval[a,b]`
4787     (CONJUNCTS_THEN2 MP_TAC SUBST1_TAC) THENL
4788      [CONJ_TAC THENL
4789        [SIMP_TAC[CONTENT_EQ_0_1];
4790         AP_TERM_TAC THEN REWRITE_TAC[CONS_11; PAIR_EQ]] THEN
4791       SIMP_TAC[drop; CART_EQ; FORALL_1; LAMBDA_BETA; DIMINDEX_1; LE_REFL] THEN
4792       UNDISCH_TAC `drop c <= drop a` THEN REWRITE_TAC[drop] THEN
4793       REAL_ARITH_TAC;
4794       REWRITE_TAC[CONTENT_EQ_0_1] THEN
4795       DISCH_THEN(ANTE_RES_THEN SUBST1_TAC) THEN ASM_MESON_TAC[monoidal]];
4796     ALL_TAC] THEN
4797   DISJ_CASES_TAC(REAL_ARITH `drop b <= drop c \/ drop c < drop b`) THENL
4798    [SUBGOAL_THEN
4799      `interval[a,(lambda i. if i = 1 then min (drop b) (drop c) else b$i)] =
4800       interval[a,b] /\
4801       content(interval
4802         [(lambda i. if i = 1 then max (drop a) (drop c) else a$i),b]) = &0`
4803       (CONJUNCTS_THEN2 SUBST1_TAC MP_TAC) THENL
4804      [CONJ_TAC THENL
4805        [AP_TERM_TAC THEN REWRITE_TAC[CONS_11; PAIR_EQ];
4806         SIMP_TAC[CONTENT_EQ_0_1]] THEN
4807       SIMP_TAC[drop; CART_EQ; FORALL_1; LAMBDA_BETA; DIMINDEX_1; LE_REFL] THEN
4808       UNDISCH_TAC `drop b <= drop c` THEN REWRITE_TAC[drop] THEN
4809       REAL_ARITH_TAC;
4810       REWRITE_TAC[CONTENT_EQ_0_1] THEN
4811       DISCH_THEN(ANTE_RES_THEN SUBST1_TAC) THEN ASM_MESON_TAC[monoidal]];
4812     ALL_TAC] THEN
4813   SUBGOAL_THEN
4814    `(lambda i. if i = 1 then min (drop b) (drop c) else b$i) = c /\
4815     (lambda i. if i = 1 then max (drop a) (drop c) else a$i) = c`
4816    (fun th -> REWRITE_TAC[th] THEN ASM_MESON_TAC[]) THEN
4817   SIMP_TAC[CART_EQ; FORALL_1; DIMINDEX_1; LE_REFL; LAMBDA_BETA] THEN
4818   REWRITE_TAC[GSYM drop] THEN ASM_REAL_ARITH_TAC);;
4819
4820 let OPERATIVE_1_LE = prove
4821  (`!op. monoidal op
4822         ==> !f. operative op f <=>
4823                 (!a b. drop b <= drop a ==> f(interval[a,b]) = neutral op) /\
4824                 (!a b c. drop a <= drop c /\ drop c <= drop b
4825                          ==> op (f(interval[a,c])) (f(interval[c,b])) =
4826                              f(interval[a,b]))`,
4827   GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN EQ_TAC THENL
4828    [ALL_TAC; ASM_SIMP_TAC[OPERATIVE_1_LT] THEN MESON_TAC[REAL_LT_IMP_LE]] THEN
4829   REWRITE_TAC[operative; CONTENT_EQ_0_1] THEN
4830   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
4831   REWRITE_TAC[FORALL_1; DIMINDEX_1] THEN
4832   MAP_EVERY (fun t -> MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC t)
4833    [`a:real^1`; `b:real^1`] THEN DISCH_TAC THEN
4834   X_GEN_TAC `c:real^1` THEN FIRST_ASSUM(SUBST1_TAC o SPEC `drop c`) THEN
4835   DISCH_TAC THEN FIRST_ASSUM(ASSUME_TAC o MATCH_MP REAL_LE_TRANS) THEN
4836   ASM_SIMP_TAC[INTERVAL_SPLIT; DIMINDEX_1; LE_REFL] THEN
4837   BINOP_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
4838   REWRITE_TAC[CONS_11; PAIR_EQ] THEN
4839   SIMP_TAC[FORALL_1; CART_EQ; DIMINDEX_1; LAMBDA_BETA; LE_REFL] THEN
4840   REWRITE_TAC[GSYM drop] THEN ASM_REAL_ARITH_TAC);;
4841
4842 (* ------------------------------------------------------------------------- *)
4843 (* Special case of additivity we need for the FCT.                           *)
4844 (* ------------------------------------------------------------------------- *)
4845
4846 let ADDITIVE_TAGGED_DIVISION_1 = prove
4847  (`!f:real^1->real^N p a b.
4848         drop a <= drop b /\
4849         p tagged_division_of interval[a,b]
4850         ==> vsum p
4851              (\(x,k). f(interval_upperbound k) - f(interval_lowerbound k)) =
4852             f b - f a`,
4853   REPEAT STRIP_TAC THEN
4854   MP_TAC(ISPECL
4855    [`(+):real^N->real^N->real^N`;
4856     `p:(real^1#(real^1->bool)->bool)`;
4857     `a:real^1`; `b:real^1`;
4858     `(\k. if k = {} then vec 0
4859           else f(interval_upperbound k) - f(interval_lowerbound k)):
4860      ((real^1->bool)->real^N)`] OPERATIVE_TAGGED_DIVISION) THEN
4861   ASM_SIMP_TAC[MONOIDAL_VECTOR_ADD; OPERATIVE_1_LT; NEUTRAL_VECTOR_ADD;
4862                INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
4863   ANTS_TAC THENL
4864    [ASM_SIMP_TAC[INTERVAL_EQ_EMPTY_1; REAL_ARITH `a <= b ==> ~(b < a)`;
4865                  REAL_LT_IMP_LE; CONTENT_EQ_0_1;
4866                  INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
4867     SIMP_TAC[REAL_ARITH `b <= a ==> (b < a <=> ~(b = a))`] THEN
4868     SIMP_TAC[DROP_EQ; TAUT
4869       `(if ~p then x else y) = (if p then y else x)`] THEN
4870     SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1; REAL_LE_REFL] THEN
4871     REWRITE_TAC[VECTOR_SUB_REFL; COND_ID; EQ_SYM_EQ] THEN
4872     REPEAT GEN_TAC THEN DISCH_TAC THEN
4873     FIRST_ASSUM(ASSUME_TAC o MATCH_MP REAL_LT_TRANS) THEN
4874     ASM_SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1;
4875                  REAL_ARITH `b < a ==> ~(a < b)`; REAL_LT_IMP_LE] THEN
4876     MESON_TAC[VECTOR_ARITH `(c - a) + (b - c):real^N = b - a`];
4877     ALL_TAC] THEN
4878   ASM_SIMP_TAC[INTERVAL_EQ_EMPTY_1; GSYM REAL_NOT_LE] THEN
4879   DISCH_THEN(SUBST1_TAC o SYM) THEN
4880   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
4881   ASM_SIMP_TAC[GSYM VSUM] THEN MATCH_MP_TAC VSUM_EQ THEN
4882   REWRITE_TAC[FORALL_PAIR_THM] THEN
4883   ASM_MESON_TAC[TAGGED_DIVISION_OF; MEMBER_NOT_EMPTY]);;
4884
4885 (* ------------------------------------------------------------------------- *)
4886 (* A useful lemma allowing us to factor out the content size.                *)
4887 (* ------------------------------------------------------------------------- *)
4888
4889 let HAS_INTEGRAL_FACTOR_CONTENT = prove
4890  (`!f:real^M->real^N i a b.
4891       (f has_integral i) (interval[a,b]) <=>
4892       (!e. &0 < e
4893            ==> ?d. gauge d /\
4894                    (!p. p tagged_division_of interval[a,b] /\ d fine p
4895                         ==> norm (vsum p (\(x,k). content k % f x) - i)
4896                             <= e * content(interval[a,b])))`,
4897   REPEAT GEN_TAC THEN
4898   ASM_CASES_TAC `content(interval[a:real^M,b]) = &0` THENL
4899    [MP_TAC(SPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`]
4900      VSUM_CONTENT_NULL) THEN
4901     ASM_SIMP_TAC[HAS_INTEGRAL_NULL_EQ; VECTOR_SUB_LZERO; NORM_NEG] THEN
4902     DISCH_TAC THEN REWRITE_TAC[REAL_MUL_RZERO; NORM_LE_0] THEN
4903     ASM_MESON_TAC[FINE_DIVISION_EXISTS; GAUGE_TRIVIAL; REAL_LT_01];
4904     ALL_TAC] THEN
4905   REWRITE_TAC[has_integral] THEN EQ_TAC THEN DISCH_TAC THEN
4906   X_GEN_TAC `e:real` THEN DISCH_TAC THENL
4907    [FIRST_X_ASSUM(MP_TAC o SPEC `e * content(interval[a:real^M,b])`) THEN
4908     ASM_SIMP_TAC[REAL_LT_MUL; CONTENT_LT_NZ] THEN MESON_TAC[REAL_LT_IMP_LE];
4909     ALL_TAC] THEN
4910   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2 / content(interval[a:real^M,b])`) THEN
4911   ASM_SIMP_TAC[REAL_LT_DIV; CONTENT_LT_NZ; REAL_OF_NUM_LT; ARITH] THEN
4912   ASM_SIMP_TAC[REAL_DIV_RMUL] THEN
4913   ASM_MESON_TAC[REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`]);;
4914
4915 (* ------------------------------------------------------------------------- *)
4916 (* Attempt a systematic general set of "offset" results for components.      *)
4917 (* ------------------------------------------------------------------------- *)
4918
4919 let GAUGE_MODIFY = prove
4920  (`!f:real^M->real^N.
4921       (!s. open s ==> open {x | f(x) IN s})
4922       ==> !d. gauge d ==> gauge (\x y. d (f x) (f y))`,
4923   GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
4924   SIMP_TAC[gauge; IN] THEN DISCH_TAC THEN
4925   X_GEN_TAC `x:real^M` THEN
4926   FIRST_X_ASSUM(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN
4927   DISCH_THEN(ANTE_RES_THEN MP_TAC o CONJUNCT2) THEN
4928   MATCH_MP_TAC EQ_IMP THEN
4929   AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
4930   REWRITE_TAC[IN]);;
4931
4932 (* ------------------------------------------------------------------------- *)
4933 (* Integrabibility on subintervals.                                          *)
4934 (* ------------------------------------------------------------------------- *)
4935
4936 let OPERATIVE_INTEGRABLE = prove
4937  (`!f. operative (/\) (\i. f integrable_on i)`,
4938   GEN_TAC THEN REWRITE_TAC[operative; NEUTRAL_AND] THEN CONJ_TAC THENL
4939    [REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_NULL_EQ];
4940     REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[INTEGRABLE_SPLIT] THEN
4941     REWRITE_TAC[integrable_on] THEN ASM_MESON_TAC[HAS_INTEGRAL_SPLIT]]);;
4942
4943 let INTEGRABLE_SUBINTERVAL = prove
4944  (`!f:real^M->real^N a b c d.
4945         f integrable_on interval[a,b] /\
4946         interval[c,d] SUBSET interval[a,b]
4947         ==> f integrable_on interval[c,d]`,
4948   REPEAT STRIP_TAC THEN
4949   ASM_CASES_TAC `interval[c:real^M,d] = {}` THENL
4950    [ASM_REWRITE_TAC[integrable_on] THEN
4951     MESON_TAC[HAS_INTEGRAL_NULL; CONTENT_EMPTY; EMPTY_AS_INTERVAL];
4952     ASM_MESON_TAC[OPERATIVE_INTEGRABLE; OPERATIVE_DIVISION_AND;
4953                   PARTIAL_DIVISION_EXTEND_1]]);;
4954
4955 (* ------------------------------------------------------------------------- *)
4956 (* Combining adjacent intervals in 1 dimension.                              *)
4957 (* ------------------------------------------------------------------------- *)
4958
4959 let HAS_INTEGRAL_COMBINE = prove
4960  (`!f i:real^N j a b c.
4961         drop a <= drop c /\ drop c <= drop b /\
4962         (f has_integral i) (interval[a,c]) /\
4963         (f has_integral j) (interval[c,b])
4964         ==> (f has_integral (i + j)) (interval[a,b])`,
4965   REPEAT STRIP_TAC THEN MP_TAC
4966    ((CONJUNCT2 o GEN_REWRITE_RULE I
4967      [MATCH_MP OPERATIVE_1_LE(MATCH_MP MONOIDAL_LIFTED MONOIDAL_VECTOR_ADD)])
4968     (ISPEC `f:real^1->real^N` OPERATIVE_INTEGRAL)) THEN
4969   DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`; `c:real^1`]) THEN
4970   ASM_REWRITE_TAC[] THEN
4971   REPEAT(COND_CASES_TAC THEN
4972    ASM_REWRITE_TAC[lifted; distinctness "option"; injectivity "option"]) THEN
4973   ASM_MESON_TAC[INTEGRABLE_INTEGRAL; HAS_INTEGRAL_UNIQUE; integrable_on;
4974                 INTEGRAL_UNIQUE]);;
4975
4976 let INTEGRAL_COMBINE = prove
4977  (`!f:real^1->real^N a b c.
4978         drop a <= drop c /\ drop c <= drop b /\ f integrable_on (interval[a,b])
4979         ==> integral(interval[a,c]) f + integral(interval[c,b]) f =
4980             integral(interval[a,b]) f`,
4981   REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
4982   MATCH_MP_TAC INTEGRAL_UNIQUE THEN MATCH_MP_TAC HAS_INTEGRAL_COMBINE THEN
4983   EXISTS_TAC `c:real^1` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THEN
4984   MATCH_MP_TAC INTEGRABLE_INTEGRAL THEN
4985   MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN
4986   MAP_EVERY EXISTS_TAC [`a:real^1`; `b:real^1`] THEN
4987   ASM_REWRITE_TAC[SUBSET_INTERVAL_1; REAL_LE_REFL]);;
4988
4989 let INTEGRABLE_COMBINE = prove
4990  (`!f a b c.
4991         drop a <= drop c /\ drop c <= drop b /\
4992         f integrable_on interval[a,c] /\
4993         f integrable_on interval[c,b]
4994         ==> f integrable_on interval[a,b]`,
4995   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_COMBINE]);;
4996
4997 (* ------------------------------------------------------------------------- *)
4998 (* Reduce integrability to "local" integrability.                            *)
4999 (* ------------------------------------------------------------------------- *)
5000
5001 let INTEGRABLE_ON_LITTLE_SUBINTERVALS = prove
5002  (`!f:real^M->real^N a b.
5003         (!x. x IN interval[a,b]
5004              ==> ?d. &0 < d /\
5005                      !u v. x IN interval[u,v] /\
5006                            interval[u,v] SUBSET ball(x,d) /\
5007                            interval[u,v] SUBSET interval[a,b]
5008                            ==> f integrable_on interval[u,v])
5009         ==> f integrable_on interval[a,b]`,
5010   REPEAT GEN_TAC THEN
5011   REWRITE_TAC[RIGHT_IMP_EXISTS_THM; GAUGE_EXISTENCE_LEMMA] THEN
5012   REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM] THEN
5013   DISCH_THEN(X_CHOOSE_THEN `d:real^M->real` STRIP_ASSUME_TAC) THEN
5014   MP_TAC(ISPECL [`\x:real^M. ball(x,d x)`; `a:real^M`; `b:real^M`]
5015                 FINE_DIVISION_EXISTS) THEN
5016   ASM_SIMP_TAC[GAUGE_BALL_DEPENDENT; LEFT_IMP_EXISTS_THM] THEN
5017   X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN
5018   MP_TAC(MATCH_MP (REWRITE_RULE[IMP_CONJ] OPERATIVE_DIVISION_AND)
5019          (ISPEC `f:real^M->real^N` OPERATIVE_INTEGRABLE)) THEN
5020   DISCH_THEN(MP_TAC o SPECL
5021    [`IMAGE SND (p:real^M#(real^M->bool)->bool)`; `a:real^M`; `b:real^M`]) THEN
5022   ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION] THEN
5023   DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[FORALL_IN_IMAGE] THEN
5024   REWRITE_TAC[FORALL_PAIR_THM] THEN
5025   MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
5026   FIRST_ASSUM(MP_TAC o el 1 o CONJUNCTS o
5027    GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
5028   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
5029   REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN
5030   DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `k:real^M->bool`]) THEN
5031   ASM_REWRITE_TAC[] THEN  ASM_MESON_TAC[SUBSET]);;
5032
5033 (* ------------------------------------------------------------------------- *)
5034 (* Second FCT or existence of antiderivative.                                *)
5035 (* ------------------------------------------------------------------------- *)
5036
5037 let INTEGRAL_HAS_VECTOR_DERIVATIVE_POINTWISE = prove
5038  (`!f:real^1->real^N a b x.
5039         f integrable_on interval[a,b] /\ x IN interval[a,b] /\
5040         f continuous (at x within interval[a,b])
5041         ==> ((\u. integral (interval [a,u]) f) has_vector_derivative f x)
5042             (at x within interval [a,b])`,
5043   REWRITE_TAC[IN_INTERVAL_1] THEN REPEAT STRIP_TAC THEN
5044   REWRITE_TAC[has_vector_derivative; HAS_DERIVATIVE_WITHIN_ALT] THEN
5045   CONJ_TAC THENL
5046    [REWRITE_TAC[linear; DROP_ADD; DROP_CMUL] THEN
5047     CONJ_TAC THEN VECTOR_ARITH_TAC;
5048     ALL_TAC] THEN
5049   X_GEN_TAC `e:real` THEN DISCH_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
5050   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [continuous_within]) THEN
5051   DISCH_THEN(MP_TAC o SPEC `e:real`) THEN
5052   ASM_REWRITE_TAC[IN_INTERVAL_1; dist] THEN
5053   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN
5054   ASM_REWRITE_TAC[] THEN X_GEN_TAC `y:real^1` THEN STRIP_TAC THEN
5055   REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB] THEN
5056   DISJ_CASES_TAC(REAL_ARITH `drop x <= drop y \/ drop y <= drop x`) THENL
5057    [ASM_SIMP_TAC[REAL_ARITH `x <= y ==> abs(y - x) = y - x`];
5058     ONCE_REWRITE_TAC[VECTOR_ARITH
5059      `fy - fx - (x - y) % c:real^N = --(fx - fy - (y - x) % c)`] THEN
5060     ASM_SIMP_TAC[NORM_NEG; REAL_ARITH `x <= y ==> abs(x - y) = y - x`]] THEN
5061   ASM_SIMP_TAC[GSYM CONTENT_1] THEN MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN
5062   EXISTS_TAC `(\u. f(u) - f(x)):real^1->real^N` THEN
5063   (ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN CONJ_TAC THENL
5064    [ALL_TAC;
5065     REPEAT STRIP_TAC THEN
5066     MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
5067     REPEAT(POP_ASSUM MP_TAC) THEN
5068     REWRITE_TAC[IN_INTERVAL_1; NORM_REAL; DROP_SUB; GSYM drop] THEN
5069     REAL_ARITH_TAC] THEN
5070    MATCH_MP_TAC HAS_INTEGRAL_SUB THEN REWRITE_TAC[HAS_INTEGRAL_CONST]) THENL
5071     [SUBGOAL_THEN
5072       `integral(interval[a,x]) f + integral(interval[x,y]) f =
5073        integral(interval[a,y]) f /\
5074        ((f:real^1->real^N) has_integral integral(interval[x,y]) f)
5075         (interval[x,y])`
5076       (fun th -> MESON_TAC[th;
5077           VECTOR_ARITH `a + b = c:real^N ==> c - a = b`]);
5078      SUBGOAL_THEN
5079       `integral(interval[a,y]) f + integral(interval[y,x]) f =
5080        integral(interval[a,x]) f /\
5081        ((f:real^1->real^N) has_integral integral(interval[y,x]) f)
5082         (interval[y,x])`
5083        (fun th -> MESON_TAC[th;
5084          VECTOR_ARITH `a + b = c:real^N ==> c - a = b`])] THEN
5085    (CONJ_TAC THENL
5086      [MATCH_MP_TAC INTEGRAL_COMBINE;
5087       MATCH_MP_TAC INTEGRABLE_INTEGRAL] THEN
5088     ASM_REWRITE_TAC[] THEN
5089     MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN
5090     MAP_EVERY EXISTS_TAC [`a:real^1`; `b:real^1`] THEN
5091     ASM_SIMP_TAC[INTEGRABLE_CONTINUOUS; SUBSET_INTERVAL_1] THEN
5092     ASM_REAL_ARITH_TAC));;
5093
5094 let INTEGRAL_HAS_VECTOR_DERIVATIVE = prove
5095  (`!f:real^1->real^N a b.
5096      f continuous_on interval[a,b]
5097      ==> !x. x IN interval[a,b]
5098              ==> ((\u. integral (interval[a,u]) f) has_vector_derivative f(x))
5099                  (at x within interval[a,b])`,
5100   REPEAT STRIP_TAC THEN
5101   MATCH_MP_TAC INTEGRAL_HAS_VECTOR_DERIVATIVE_POINTWISE THEN
5102   ASM_MESON_TAC[INTEGRABLE_CONTINUOUS; CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN]);;
5103
5104 let ANTIDERIVATIVE_CONTINUOUS = prove
5105  (`!f:real^1->real^N a b.
5106      f continuous_on interval[a,b]
5107      ==> ?g. !x. x IN interval[a,b]
5108                  ==> (g has_vector_derivative f(x))
5109                           (at x within interval[a,b])`,
5110   MESON_TAC[INTEGRAL_HAS_VECTOR_DERIVATIVE]);;
5111
5112 (* ------------------------------------------------------------------------- *)
5113 (* General "twiddling" for interval-to-interval function image.              *)
5114 (* ------------------------------------------------------------------------- *)
5115
5116 let HAS_INTEGRAL_TWIDDLE = prove
5117  (`!f:real^N->real^P (g:real^M->real^N) h r i a b.
5118       &0 < r /\
5119       (!x. h(g x) = x) /\ (!x. g(h x) = x) /\ (!x. g continuous at x) /\
5120       (!u v. ?w z. IMAGE g (interval[u,v]) = interval[w,z]) /\
5121       (!u v. ?w z. IMAGE h (interval[u,v]) = interval[w,z]) /\
5122       (!u v. content(IMAGE g (interval[u,v])) = r * content(interval[u,v])) /\
5123       (f has_integral i) (interval[a,b])
5124       ==> ((\x. f(g x)) has_integral (inv r) % i) (IMAGE h (interval[a,b]))`,
5125   let lemma0 = prove
5126    (`(!x k. (x,k) IN IMAGE (\(x,k). f x,g k) p ==> P x k) <=>
5127      (!x k. (x,k) IN p ==> P (f x) (g k))`,
5128     REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM; PAIR_EQ] THEN MESON_TAC[])
5129   and lemma1 = prove
5130    (`{k | ?x. (x,k) IN p} = IMAGE SND p`,
5131     REWRITE_TAC[EXTENSION; EXISTS_PAIR_THM; IN_IMAGE; IN_ELIM_THM] THEN
5132     MESON_TAC[])
5133   and lemma2 = prove
5134    (`SND o (\(x,k). f x,g k) = g o SND`,
5135     REWRITE_TAC[FUN_EQ_THM; FORALL_PAIR_THM; o_DEF]) in
5136   REPEAT GEN_TAC THEN ASM_CASES_TAC `interval[a:real^N,b] = {}` THEN
5137   ASM_SIMP_TAC[IMAGE_CLAUSES; HAS_INTEGRAL_EMPTY_EQ; VECTOR_MUL_RZERO] THEN
5138   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5139   REWRITE_TAC[has_integral] THEN
5140   ASM_REWRITE_TAC[has_integral_def; has_integral_compact_interval] THEN
5141   DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5142   FIRST_X_ASSUM(MP_TAC o SPEC `e * r:real`) THEN
5143   ASM_SIMP_TAC[REAL_LT_MUL] THEN
5144   DISCH_THEN(X_CHOOSE_THEN `d:real^N->real^N->bool` STRIP_ASSUME_TAC) THEN
5145   EXISTS_TAC `\x y:real^M. (d:real^N->real^N->bool) (g x) (g y)` THEN
5146   CONJ_TAC THENL
5147    [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [gauge]) THEN
5148     SIMP_TAC[gauge; IN; FORALL_AND_THM] THEN
5149     STRIP_TAC THEN X_GEN_TAC `x:real^M` THEN
5150     SUBGOAL_THEN `(\y:real^M. (d:real^N->real^N->bool) (g x) (g y)) =
5151                   {y | g y IN (d (g x))}` SUBST1_TAC
5152     THENL [SET_TAC[]; ASM_SIMP_TAC[CONTINUOUS_OPEN_PREIMAGE_UNIV]];
5153     ALL_TAC] THEN
5154   X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN
5155   FIRST_X_ASSUM(MP_TAC o SPEC
5156    `IMAGE (\(x,k). (g:real^M->real^N) x, IMAGE g k) p`) THEN
5157   ANTS_TAC THENL
5158    [CONJ_TAC THENL
5159      [ALL_TAC;
5160       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
5161       REWRITE_TAC[fine; lemma0] THEN
5162       STRIP_TAC THEN REPEAT GEN_TAC THEN DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN
5163       ASM SET_TAC[]] THEN
5164     SUBGOAL_THEN
5165      `interval[a,b] = IMAGE ((g:real^M->real^N) o h) (interval[a,b])`
5166     SUBST1_TAC THENL [SIMP_TAC[o_DEF] THEN ASM SET_TAC[]; ALL_TAC] THEN
5167     SUBGOAL_THEN `?u v. IMAGE (h:real^N->real^M) (interval[a,b]) =
5168                         interval[u,v]`
5169     (REPEAT_TCL CHOOSE_THEN
5170       (fun th -> SUBST_ALL_TAC th THEN ASSUME_TAC th)) THENL
5171       [ASM_MESON_TAC[]; ALL_TAC] THEN
5172     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
5173     REWRITE_TAC[TAGGED_DIVISION_OF; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
5174     REWRITE_TAC[lemma0] THEN REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
5175     REPEAT GEN_TAC THEN STRIP_TAC THEN CONJ_TAC THENL
5176      [ASM_SIMP_TAC[FINITE_IMAGE]; ALL_TAC] THEN
5177     CONJ_TAC THENL
5178      [MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
5179       DISCH_TAC THEN
5180       UNDISCH_TAC
5181        `!x:real^M k.
5182              x,k IN p
5183              ==> x IN k /\
5184                  k SUBSET interval[u,v] /\
5185                  ?w z. k = interval[w,z]` THEN
5186       DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `k:real^M->bool`]) THEN
5187       ASM_REWRITE_TAC[] THEN
5188       REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THENL
5189        [SET_TAC[];
5190         REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[];
5191         STRIP_TAC THEN ASM_REWRITE_TAC[]];
5192       ALL_TAC] THEN
5193     CONJ_TAC THENL
5194      [ALL_TAC;
5195       ASM_REWRITE_TAC[IMAGE_o] THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
5196       REWRITE_TAC[lemma1; GSYM IMAGE_o; lemma2] THEN
5197       REWRITE_TAC[IMAGE_o; GSYM IMAGE_UNIONS; ETA_AX]] THEN
5198     MAP_EVERY X_GEN_TAC [`x1:real^M`; `k1:real^M->bool`] THEN DISCH_TAC THEN
5199     MAP_EVERY X_GEN_TAC [`x2:real^M`; `k2:real^M->bool`] THEN STRIP_TAC THEN
5200     UNDISCH_TAC
5201      `!x1:real^M k1:real^M->bool.
5202              x1,k1 IN p
5203              ==> (!x2 k2.
5204                       x2,k2 IN p /\ ~(x1,k1 = x2,k2)
5205                       ==> interior k1 INTER interior k2 = {})` THEN
5206     DISCH_THEN(MP_TAC o SPECL [`x1:real^M`; `k1:real^M->bool`]) THEN
5207     ASM_REWRITE_TAC[] THEN
5208     DISCH_THEN(MP_TAC o SPECL [`x2:real^M`; `k2:real^M->bool`]) THEN
5209     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
5210      [ASM_MESON_TAC[PAIR_EQ]; ALL_TAC] THEN
5211     MATCH_MP_TAC(SET_RULE
5212      `interior(IMAGE f s) SUBSET IMAGE f (interior s) /\
5213       interior(IMAGE f t) SUBSET IMAGE f (interior t) /\
5214       (!x y. f x = f y ==> x = y)
5215       ==> interior s INTER interior t = {}
5216           ==> interior(IMAGE f s) INTER interior(IMAGE f t) = {}`) THEN
5217     REPEAT CONJ_TAC THEN TRY(MATCH_MP_TAC INTERIOR_IMAGE_SUBSET) THEN
5218     ASM_MESON_TAC[];
5219     ALL_TAC] THEN
5220   W(fun (asl,w) -> MP_TAC(PART_MATCH (lhand o rand) VSUM_IMAGE
5221                 (lhand(rand(lhand(lhand w)))))) THEN
5222   ANTS_TAC THENL
5223    [FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
5224     ASM_REWRITE_TAC[FORALL_PAIR_THM; PAIR_EQ] THEN
5225     REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5226     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5227     MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN ASM SET_TAC[];
5228     ALL_TAC] THEN
5229   DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM] THEN
5230   DISCH_TAC THEN MATCH_MP_TAC REAL_LT_LCANCEL_IMP THEN
5231   EXISTS_TAC `abs r` THEN ASM_SIMP_TAC[REAL_ARITH `&0 < x ==> &0 < abs x`] THEN
5232   REWRITE_TAC[GSYM NORM_MUL] THEN ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE] THEN
5233   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
5234    `x < a * b ==> x = y ==> y < b * a`)) THEN
5235   AP_TERM_TAC THEN REWRITE_TAC[VECTOR_SUB_LDISTRIB] THEN
5236   ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; REAL_LT_IMP_NZ] THEN
5237   REWRITE_TAC[VECTOR_MUL_LID; GSYM VSUM_LMUL] THEN
5238   AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
5239   REWRITE_TAC[FORALL_PAIR_THM; VECTOR_MUL_ASSOC] THEN
5240   REPEAT STRIP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
5241   ASM_MESON_TAC[TAGGED_DIVISION_OF]);;
5242
5243 (* ------------------------------------------------------------------------- *)
5244 (* Special case of permuting the coordinates.                                *)
5245 (* ------------------------------------------------------------------------- *)
5246
5247 let HAS_INTEGRAL_TWIZZLE_INTERVAL = prove
5248  (`!f:real^N->real^P p a b:real^M.
5249       (f has_integral y) (interval[(lambda i. a$(p i)),(lambda i. b$(p i))]) /\
5250       dimindex(:M) = dimindex(:N) /\ p permutes 1..dimindex(:N)
5251       ==> ((\x. f(lambda i. x$p i)) has_integral y) (interval[a,b])`,
5252   REPEAT STRIP_TAC THEN MP_TAC(ISPECL
5253    [`f:real^N->real^P`; `(\x. lambda i. x$(p i)):real^M->real^N`;
5254     `(\x. lambda i. x$(inverse p i)):real^N->real^M`;
5255     `&1`; `y:real^P`;
5256     `((\x. lambda i. x$(p i)):real^M->real^N) a`;
5257     `((\x. lambda i. x$(p i)):real^M->real^N) b`]
5258     HAS_INTEGRAL_TWIDDLE) THEN
5259   REWRITE_TAC[REAL_LT_01] THEN
5260   FIRST_ASSUM(ASSUME_TAC o MATCH_MP PERMUTES_INVERSE) THEN
5261   MP_TAC(SPEC `inverse p:num->num`
5262    (INST_TYPE [`:N`,`:M`; `:M`,`:N`] IMAGE_TWIZZLE_INTERVAL)) THEN
5263   MP_TAC(SPEC `p:num->num` IMAGE_TWIZZLE_INTERVAL) THEN
5264   ONCE_ASM_REWRITE_TAC[] THEN ASM_REWRITE_TAC[] THEN
5265   REPLICATE_TAC 2 (DISCH_THEN(fun th -> REWRITE_TAC[th])) THEN
5266   SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN ANTS_TAC THENL
5267    [REPEAT CONJ_TAC THENL
5268      [IMP_REWRITE_TAC[LAMBDA_BETA] THEN REWRITE_TAC[GSYM IN_NUMSEG] THEN
5269       ASM_MESON_TAC[PERMUTES_INVERSES; PERMUTES_IN_IMAGE];
5270       IMP_REWRITE_TAC[LAMBDA_BETA] THEN REWRITE_TAC[GSYM IN_NUMSEG] THEN
5271       ASM_MESON_TAC[PERMUTES_INVERSES; PERMUTES_IN_IMAGE];
5272       GEN_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
5273       SIMP_TAC[linear; CART_EQ; LAMBDA_BETA; VECTOR_MUL_COMPONENT;
5274                VECTOR_ADD_COMPONENT];
5275       MESON_TAC[];
5276       MESON_TAC[];
5277       MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN
5278       SIMP_TAC[REAL_MUL_LID; CONTENT_CLOSED_INTERVAL_CASES] THEN
5279       AP_THM_TAC THEN BINOP_TAC THENL
5280        [IMP_REWRITE_TAC[LAMBDA_BETA] THEN
5281         REWRITE_TAC[GSYM IN_NUMSEG] THEN
5282         ASM_MESON_TAC[PERMUTES_INVERSES; PERMUTES_IN_IMAGE];
5283         MP_TAC(MATCH_MP PRODUCT_PERMUTE
5284           (ASSUME `p permutes 1..dimindex(:N)`)) THEN
5285         ASM_REWRITE_TAC[] THEN ONCE_ASM_REWRITE_TAC[] THEN
5286         DISCH_THEN(fun th -> GEN_REWRITE_TAC RAND_CONV [th]) THEN
5287         MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN REWRITE_TAC[o_DEF] THEN
5288         IMP_REWRITE_TAC[LAMBDA_BETA] THEN REWRITE_TAC[] THEN
5289         IMP_REWRITE_TAC[LAMBDA_BETA]]];
5290     REWRITE_TAC[o_DEF; REAL_INV_1; VECTOR_MUL_LID] THEN
5291     MATCH_MP_TAC EQ_IMP THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
5292     AP_THM_TAC THEN AP_TERM_TAC THEN
5293     SIMP_TAC[PAIR_EQ; LAMBDA_BETA; CART_EQ] THEN
5294     IMP_REWRITE_TAC[LAMBDA_BETA] THEN
5295     REWRITE_TAC[GSYM IN_NUMSEG] THEN
5296     ASM_MESON_TAC[PERMUTES_INVERSES; PERMUTES_IN_IMAGE]]);;
5297
5298 (* ------------------------------------------------------------------------- *)
5299 (* Special case of a basic affine transformation.                            *)
5300 (* ------------------------------------------------------------------------- *)
5301
5302 let INTERVAL_IMAGE_AFFINITY_INTERVAL = prove
5303  (`!a b m c. ?u v. IMAGE (\x. m % x + c) (interval[a,b]) = interval[u,v]`,
5304   REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN
5305   MESON_TAC[EMPTY_AS_INTERVAL]);;
5306
5307 let CONTENT_IMAGE_AFFINITY_INTERVAL = prove
5308  (`!a b:real^N m c.
5309         content(IMAGE (\x. m % x + c) (interval[a,b])) =
5310         (abs m) pow (dimindex(:N)) * content(interval[a,b])`,
5311   REPEAT STRIP_TAC THEN REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN
5312   COND_CASES_TAC THEN ASM_REWRITE_TAC[CONTENT_EMPTY; REAL_MUL_RZERO] THEN
5313   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN COND_CASES_TAC THEN
5314   W(fun (asl,w) -> MP_TAC(PART_MATCH (lhand o rand) CONTENT_CLOSED_INTERVAL
5315                 (lhs w))) THEN
5316   (ANTS_TAC THENL
5317     [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
5318      FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
5319      ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
5320                   REAL_LE_RADD; REAL_LE_LMUL] THEN
5321      ONCE_REWRITE_TAC[REAL_ARITH `m * b <= m * a <=> --m * a <= --m * b`] THEN
5322      ASM_SIMP_TAC[REAL_ARITH `~(&0 <= x) ==> &0 <= --x`; REAL_LE_LMUL];
5323      ALL_TAC]) THEN
5324   DISCH_THEN SUBST1_TAC THEN
5325   ONCE_REWRITE_TAC[GSYM PRODUCT_CONST_NUMSEG_1] THEN
5326   ASM_SIMP_TAC[CONTENT_CLOSED_INTERVAL; GSYM PRODUCT_MUL_NUMSEG] THEN
5327   MATCH_MP_TAC PRODUCT_EQ THEN
5328   SIMP_TAC[IN_NUMSEG; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
5329   ASM_REAL_ARITH_TAC);;
5330
5331 let HAS_INTEGRAL_AFFINITY = prove
5332  (`!f:real^M->real^N i a b m c.
5333         (f has_integral i) (interval[a,b]) /\ ~(m = &0)
5334         ==> ((\x. f(m % x + c)) has_integral
5335              (inv(abs(m) pow dimindex(:M)) % i))
5336             (IMAGE (\x. inv m % x + --(inv(m) % c)) (interval[a,b]))`,
5337   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_TWIDDLE THEN
5338   ASM_SIMP_TAC[INTERVAL_IMAGE_AFFINITY_INTERVAL; GSYM REAL_ABS_NZ;
5339         REAL_POW_LT; PRODUCT_EQ_0_NUMSEG; CONTENT_IMAGE_AFFINITY_INTERVAL] THEN
5340   ASM_SIMP_TAC[CONTINUOUS_CMUL; CONTINUOUS_AT_ID; CONTINUOUS_CONST;
5341                CONTINUOUS_ADD] THEN
5342   REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC; VECTOR_MUL_RNEG] THEN
5343   ASM_SIMP_TAC[REAL_MUL_LINV; REAL_MUL_RINV] THEN
5344   CONJ_TAC THEN VECTOR_ARITH_TAC);;
5345
5346 let INTEGRABLE_AFFINITY = prove
5347  (`!f:real^M->real^N a b m c.
5348         f integrable_on interval[a,b] /\ ~(m = &0)
5349         ==> (\x. f(m % x + c)) integrable_on
5350             (IMAGE (\x. inv m % x + --(inv(m) % c)) (interval[a,b]))`,
5351   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_AFFINITY]);;
5352
5353 (* ------------------------------------------------------------------------- *)
5354 (* Special case of stretching coordinate axes separately.                    *)
5355 (* ------------------------------------------------------------------------- *)
5356
5357 let CONTENT_IMAGE_STRETCH_INTERVAL = prove
5358  (`!a b:real^N m.
5359         content(IMAGE (\x. lambda k. m k * x$k) (interval[a,b]):real^N->bool) =
5360         abs(product(1..dimindex(:N)) m) * content(interval[a,b])`,
5361   REPEAT GEN_TAC THEN REWRITE_TAC[content; IMAGE_EQ_EMPTY] THEN
5362   COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_MUL_RZERO] THEN
5363   ASM_REWRITE_TAC[IMAGE_STRETCH_INTERVAL] THEN
5364   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN
5365   ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; LAMBDA_BETA;
5366                REAL_ARITH `min a b <= max a b`] THEN
5367   ASM_REWRITE_TAC[REAL_ARITH `max a b - min a b = abs(b - a)`;
5368                   GSYM REAL_SUB_LDISTRIB; REAL_ABS_MUL] THEN
5369   ASM_SIMP_TAC[PRODUCT_MUL; FINITE_NUMSEG;
5370                REAL_ARITH `a <= b ==> abs(b - a) = b - a`] THEN
5371   ASM_SIMP_TAC[PRODUCT_ABS; FINITE_NUMSEG]);;
5372
5373 let HAS_INTEGRAL_STRETCH = prove
5374  (`!f:real^M->real^N i m a b.
5375         (f has_integral i) (interval[a,b]) /\
5376         (!k. 1 <= k /\ k <= dimindex(:M) ==>  ~(m k = &0))
5377         ==> ((\x:real^M. f(lambda k. m k * x$k)) has_integral
5378              (inv(abs(product(1..dimindex(:M)) m)) % i))
5379             (IMAGE (\x. lambda k. inv(m k) * x$k) (interval[a,b]))`,
5380   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_TWIDDLE THEN
5381   SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN
5382   ASM_SIMP_TAC[REAL_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_RINV; REAL_MUL_LID] THEN
5383   ASM_REWRITE_TAC[GSYM REAL_ABS_NZ; PRODUCT_EQ_0_NUMSEG] THEN
5384   CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN CONJ_TAC THENL
5385    [GEN_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
5386     SIMP_TAC[linear; LAMBDA_BETA; CART_EQ; VECTOR_ADD_COMPONENT;
5387              VECTOR_MUL_COMPONENT] THEN REAL_ARITH_TAC;
5388     REWRITE_TAC[CONTENT_IMAGE_STRETCH_INTERVAL] THEN
5389     REWRITE_TAC[IMAGE_STRETCH_INTERVAL] THEN MESON_TAC[EMPTY_AS_INTERVAL]]);;
5390
5391 let INTEGRABLE_STRETCH = prove
5392  (`!f:real^M->real^N m a b.
5393         f integrable_on interval[a,b] /\
5394         (!k. 1 <= k /\ k <= dimindex(:M) ==>  ~(m k = &0))
5395         ==> (\x:real^M. f(lambda k. m k * x$k)) integrable_on
5396             (IMAGE (\x. lambda k. inv(m k) * x$k) (interval[a,b]))`,
5397   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_STRETCH]);;
5398
5399 (* ------------------------------------------------------------------------- *)
5400 (* Even more special cases.                                                  *)
5401 (* ------------------------------------------------------------------------- *)
5402
5403 let HAS_INTEGRAL_REFLECT_LEMMA = prove
5404  (`!f:real^M->real^N i a b.
5405      (f has_integral i) (interval[a,b])
5406      ==> ((\x. f(--x)) has_integral i) (interval[--b,--a])`,
5407   REPEAT STRIP_TAC THEN
5408   FIRST_ASSUM(MP_TAC o C CONJ (REAL_ARITH `~(-- &1 = &0)`)) THEN
5409   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_AFFINITY) THEN
5410   DISCH_THEN(MP_TAC o SPEC `vec 0:real^M`) THEN
5411   REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN
5412   CONV_TAC REAL_RAT_REDUCE_CONV THEN
5413   REWRITE_TAC[REAL_ABS_NEG; REAL_ABS_NUM; REAL_POW_ONE] THEN
5414   REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_NEG_0] THEN
5415   REWRITE_TAC[REAL_INV_NEG; REAL_INV_1] THEN
5416   REWRITE_TAC[VECTOR_ARITH `-- &1 % x + vec 0 = --x`] THEN
5417   REWRITE_TAC[VECTOR_MUL_LID] THEN MATCH_MP_TAC EQ_IMP THEN
5418   AP_TERM_TAC THEN POP_ASSUM(K ALL_TAC) THEN
5419   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN CONV_TAC SYM_CONV THEN
5420   POP_ASSUM MP_TAC THEN REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN
5421   REWRITE_TAC[TAUT `a /\ b /\ c <=> ~(a /\ b ==> ~c)`] THEN
5422   SIMP_TAC[VECTOR_NEG_COMPONENT; REAL_LT_NEG2]);;
5423
5424 let HAS_INTEGRAL_REFLECT = prove
5425  (`!f:real^M->real^N i a b.
5426      ((\x. f(--x)) has_integral i) (interval[--b,--a]) <=>
5427      (f has_integral i) (interval[a,b])`,
5428   REPEAT GEN_TAC THEN EQ_TAC THEN
5429   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_REFLECT_LEMMA) THEN
5430   REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);;
5431
5432 let INTEGRABLE_REFLECT = prove
5433  (`!f:real^M->real^N a b.
5434      (\x. f(--x)) integrable_on (interval[--b,--a]) <=>
5435      f integrable_on (interval[a,b])`,
5436   REWRITE_TAC[integrable_on; HAS_INTEGRAL_REFLECT]);;
5437
5438 let INTEGRAL_REFLECT = prove
5439  (`!f:real^M->real^N a b.
5440      integral (interval[--b,--a]) (\x. f(--x)) =
5441      integral (interval[a,b]) f`,
5442   REWRITE_TAC[integral; HAS_INTEGRAL_REFLECT]);;
5443
5444 (* ------------------------------------------------------------------------- *)
5445 (* Technical lemmas about how many non-trivial intervals of a division a     *)
5446 (* point can be in (we sometimes need this for bounding sums).               *)
5447 (* ------------------------------------------------------------------------- *)
5448
5449 let DIVISION_COMMON_POINT_BOUND = prove
5450  (`!d s:real^N->bool x.
5451         d division_of s
5452         ==> CARD {k | k IN d /\ ~(content k = &0) /\ x IN k}
5453             <= 2 EXP (dimindex(:N))`,
5454   let lemma = prove
5455    (`!f s. (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\
5456            FINITE s /\ CARD(IMAGE f s) <= n
5457            ==> CARD(s) <= n`,
5458     MESON_TAC[CARD_IMAGE_INJ]) in
5459   REPEAT STRIP_TAC THEN
5460   SUBGOAL_THEN `!k. k IN d ==> ?a b:real^N. interval[a,b] = k` MP_TAC THENL
5461    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
5462   REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
5463   MAP_EVERY X_GEN_TAC
5464    [`A:(real^N->bool)->real^N`; `B:(real^N->bool)->real^N`] THEN
5465   STRIP_TAC THEN MATCH_MP_TAC(ISPEC
5466    `\d. (lambda i. (x:real^N)$i = (A:(real^N->bool)->real^N)(d)$i):bool^N`
5467    lemma) THEN
5468   REPEAT CONJ_TAC THENL
5469    [ALL_TAC;
5470     MATCH_MP_TAC FINITE_RESTRICT THEN ASM_MESON_TAC[division_of];
5471     MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `CARD(:bool^N)` THEN CONJ_TAC THENL
5472      [MATCH_MP_TAC CARD_SUBSET THEN REWRITE_TAC[SUBSET_UNIV] THEN
5473       SIMP_TAC[FINITE_CART_UNIV; FINITE_BOOL];
5474       SIMP_TAC[FINITE_BOOL; CARD_CART_UNIV; CARD_BOOL; LE_REFL]]] THEN
5475   MAP_EVERY X_GEN_TAC [`k:real^N->bool`; `l:real^N->bool`] THEN
5476   SIMP_TAC[IN_ELIM_THM; CART_EQ; LAMBDA_BETA] THEN STRIP_TAC THEN
5477   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
5478   DISCH_THEN(MP_TAC o SPECL [`k:real^N->bool`; `l:real^N->bool`] o
5479         el 2 o CONJUNCTS) THEN
5480   ASM_REWRITE_TAC[GSYM INTERIOR_INTER] THEN
5481   MATCH_MP_TAC(TAUT `~q ==> (~p ==> q) ==> p`) THEN
5482   MAP_EVERY UNDISCH_TAC
5483    [`(x:real^N) IN k`; `(x:real^N) IN l`;
5484     `~(content(k:real^N->bool) = &0)`;
5485     `~(content(l:real^N->bool) = &0)`] THEN
5486   SUBGOAL_THEN
5487    `k = interval[A k:real^N,B k] /\ l = interval[A l,B l]`
5488    (CONJUNCTS_THEN SUBST1_TAC)
5489   THENL [ASM_MESON_TAC[]; REWRITE_TAC[INTER_INTERVAL]] THEN
5490   REWRITE_TAC[CONTENT_EQ_0_INTERIOR; INTERIOR_CLOSED_INTERVAL] THEN
5491   SIMP_TAC[IN_INTERVAL; INTERVAL_NE_EMPTY; LAMBDA_BETA] THEN
5492   REPEAT DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
5493   REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN ASM_REWRITE_TAC[] THEN
5494   REAL_ARITH_TAC);;
5495
5496 let TAGGED_PARTIAL_DIVISION_COMMON_POINT_BOUND = prove
5497  (`!p s:real^N->bool y.
5498         p tagged_partial_division_of s
5499         ==> CARD {(x,k) | (x,k) IN p /\ y IN k /\ ~(content k = &0)}
5500             <= 2 EXP (dimindex(:N))`,
5501   let lemma = prove
5502    (`!f s. (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\
5503            FINITE s /\ CARD(IMAGE f s) <= n
5504            ==> CARD(s) <= n`,
5505     MESON_TAC[CARD_IMAGE_INJ]) in
5506   REPEAT STRIP_TAC THEN MATCH_MP_TAC(ISPEC `SND` lemma) THEN
5507   REPEAT CONJ_TAC THENL
5508    [REWRITE_TAC[IMP_CONJ; FORALL_IN_GSPEC; RIGHT_FORALL_IMP_THM; PAIR_EQ] THEN
5509     MAP_EVERY X_GEN_TAC [`x1:real^N`; `k1:real^N->bool`] THEN
5510     REPEAT DISCH_TAC THEN
5511     MAP_EVERY X_GEN_TAC [`x2:real^N`; `k2:real^N->bool`] THEN
5512     REPEAT DISCH_TAC THEN
5513     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [tagged_partial_division_of]) THEN
5514     DISCH_THEN(MP_TAC o SPECL
5515      [`x1:real^N`; `k1:real^N->bool`; `x2:real^N`; `k2:real^N->bool`] o
5516      CONJUNCT2 o CONJUNCT2) THEN
5517     ASM_REWRITE_TAC[PAIR_EQ] THEN
5518     MATCH_MP_TAC(TAUT `~q ==> (~p ==> q) ==> p`) THEN
5519     REWRITE_TAC[INTER_ACI] THEN
5520     ASM_MESON_TAC[CONTENT_EQ_0_INTERIOR; tagged_partial_division_of];
5521     MATCH_MP_TAC FINITE_SUBSET THEN
5522     EXISTS_TAC `p:real^N#(real^N->bool)->bool` THEN CONJ_TAC THENL
5523      [ASM_MESON_TAC[tagged_partial_division_of]; SET_TAC[]];
5524     FIRST_ASSUM(MP_TAC o MATCH_MP PARTIAL_DIVISION_OF_TAGGED_DIVISION) THEN
5525     DISCH_THEN(MP_TAC o SPEC `y:real^N` o
5526       MATCH_MP DIVISION_COMMON_POINT_BOUND) THEN
5527     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LE_TRANS) THEN
5528     MATCH_MP_TAC CARD_SUBSET THEN CONJ_TAC THENL
5529      [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN
5530       REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; EXISTS_PAIR_THM] THEN MESON_TAC[];
5531       MATCH_MP_TAC FINITE_RESTRICT THEN MATCH_MP_TAC FINITE_IMAGE THEN
5532       ASM_MESON_TAC[tagged_partial_division_of]]]);;
5533
5534 let TAGGED_PARTIAL_DIVISION_COMMON_TAGS = prove
5535  (`!p s:real^N->bool x.
5536         p tagged_partial_division_of s
5537         ==> CARD {(x,k) | k | (x,k) IN p /\ ~(content k = &0)}
5538             <= 2 EXP (dimindex(:N))`,
5539   REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC `x:real^N` o
5540    MATCH_MP TAGGED_PARTIAL_DIVISION_COMMON_POINT_BOUND) THEN
5541   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LE_TRANS) THEN
5542   MATCH_MP_TAC CARD_SUBSET THEN CONJ_TAC THENL
5543    [REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_PAIR_THM] THEN
5544     ASM_MESON_TAC[tagged_partial_division_of];
5545     MATCH_MP_TAC FINITE_SUBSET THEN
5546     EXISTS_TAC `p:real^N#(real^N->bool)->bool` THEN CONJ_TAC THENL
5547      [ASM_MESON_TAC[tagged_partial_division_of]; SET_TAC[]]]);;
5548
5549 (* ------------------------------------------------------------------------- *)
5550 (* Integrating characteristic function of an interval.                       *)
5551 (* ------------------------------------------------------------------------- *)
5552
5553 let HAS_INTEGRAL_RESTRICT_OPEN_SUBINTERVAL = prove
5554  (`!f:real^M->real^N a b c d i.
5555         (f has_integral i) (interval[c,d]) /\
5556         interval[c,d] SUBSET interval[a,b]
5557         ==> ((\x. if x IN interval(c,d) then f x else vec 0) has_integral i)
5558              (interval[a,b])`,
5559   REPEAT GEN_TAC THEN ASM_CASES_TAC `interval[c:real^M,d] = {}` THENL
5560    [FIRST_ASSUM(MP_TAC o AP_TERM
5561      `interior:(real^M->bool)->(real^M->bool)`) THEN
5562     SIMP_TAC[INTERIOR_CLOSED_INTERVAL; INTERIOR_EMPTY] THEN
5563     ASM_SIMP_TAC[NOT_IN_EMPTY; HAS_INTEGRAL_0_EQ; HAS_INTEGRAL_EMPTY_EQ];
5564     ALL_TAC] THEN
5565   ABBREV_TAC `g:real^M->real^N =
5566                  \x. if x IN interval(c,d) then f x else vec 0` THEN
5567   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5568   FIRST_X_ASSUM(MP_TAC o check(is_neg o concl)) THEN
5569   REWRITE_TAC[TAUT `a ==> b ==> c <=> b /\ a ==> c`] THEN
5570   DISCH_THEN(MP_TAC o MATCH_MP PARTIAL_DIVISION_EXTEND_1) THEN
5571   DISCH_THEN(X_CHOOSE_THEN `p:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN
5572   MP_TAC(ISPECL
5573    [`lifted((+):real^N->real^N->real^N)`;
5574     `p:(real^M->bool)->bool`;
5575     `a:real^M`; `b:real^M`;
5576     `\i. if (g:real^M->real^N) integrable_on i
5577          then SOME (integral i g) else NONE`]
5578    OPERATIVE_DIVISION) THEN
5579   ASM_SIMP_TAC[OPERATIVE_INTEGRAL; MONOIDAL_LIFTED; MONOIDAL_VECTOR_ADD] THEN
5580   SUBGOAL_THEN
5581    `iterate (lifted (+)) p
5582      (\i. if (g:real^M->real^N) integrable_on i
5583           then SOME (integral i g) else NONE) =
5584     SOME i`
5585   SUBST1_TAC THENL
5586    [ALL_TAC;
5587     COND_CASES_TAC THEN
5588     REWRITE_TAC[distinctness "option"; injectivity "option"] THEN
5589     ASM_MESON_TAC[INTEGRABLE_INTEGRAL]] THEN
5590   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
5591   FIRST_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE
5592    `x IN s ==> s = x INSERT (s DELETE x)`)) THEN
5593   ASM_SIMP_TAC[ITERATE_CLAUSES; MONOIDAL_LIFTED; MONOIDAL_VECTOR_ADD;
5594                FINITE_DELETE; IN_DELETE] THEN
5595   SUBGOAL_THEN `(g:real^M->real^N) integrable_on interval[c,d]`
5596   ASSUME_TAC THENL
5597    [FIRST_ASSUM(MP_TAC o MATCH_MP HAS_INTEGRAL_INTEGRABLE) THEN
5598     MATCH_MP_TAC INTEGRABLE_SPIKE_INTERIOR THEN
5599     EXPAND_TAC "g" THEN SIMP_TAC[];
5600     ALL_TAC] THEN
5601   ASM_REWRITE_TAC[] THEN
5602   SUBGOAL_THEN
5603    `iterate (lifted (+)) (p DELETE interval[c,d])
5604       (\i. if (g:real^M->real^N) integrable_on i
5605            then SOME (integral i g) else NONE) = SOME(vec 0)`
5606   SUBST1_TAC THENL
5607    [ALL_TAC;
5608     REWRITE_TAC[lifted; VECTOR_ADD_RID] THEN AP_TERM_TAC THEN
5609     MATCH_MP_TAC INTEGRAL_UNIQUE THEN
5610     MATCH_MP_TAC HAS_INTEGRAL_SPIKE_INTERIOR THEN
5611     EXISTS_TAC `f:real^M->real^N` THEN
5612     EXPAND_TAC "g" THEN ASM_SIMP_TAC[]] THEN
5613   SIMP_TAC[GSYM NEUTRAL_VECTOR_ADD; GSYM NEUTRAL_LIFTED;
5614            MONOIDAL_VECTOR_ADD] THEN
5615   MATCH_MP_TAC(MATCH_MP ITERATE_EQ_NEUTRAL
5616         (MATCH_MP MONOIDAL_LIFTED(SPEC_ALL MONOIDAL_VECTOR_ADD))) THEN
5617   SIMP_TAC[NEUTRAL_LIFTED; NEUTRAL_VECTOR_ADD; MONOIDAL_VECTOR_ADD] THEN
5618   X_GEN_TAC `k:real^M->bool` THEN REWRITE_TAC[IN_DELETE] THEN STRIP_TAC THEN
5619   SUBGOAL_THEN `((g:real^M->real^N) has_integral (vec 0)) k`
5620    (fun th -> MESON_TAC[th; integrable_on; INTEGRAL_UNIQUE]) THEN
5621   SUBGOAL_THEN `?u v:real^M. k = interval[u,v]` MP_TAC THENL
5622    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
5623   DISCH_THEN(REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) THEN
5624   MATCH_MP_TAC HAS_INTEGRAL_SPIKE_INTERIOR THEN
5625   EXISTS_TAC `(\x. vec 0):real^M->real^N` THEN
5626   REWRITE_TAC[HAS_INTEGRAL_0] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
5627   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
5628   DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
5629   DISCH_THEN(MP_TAC o SPECL
5630    [`interval[c:real^M,d]`; `interval[u:real^M,v]`]) THEN
5631   ASM_REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN
5632   EXPAND_TAC "g" THEN REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM SET_TAC[]);;
5633
5634 let HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL = prove
5635  (`!f:real^M->real^N a b c d i.
5636         (f has_integral i) (interval[c,d]) /\
5637         interval[c,d] SUBSET interval[a,b]
5638         ==> ((\x. if x IN interval[c,d] then f x else vec 0) has_integral i)
5639              (interval[a,b])`,
5640   REPEAT GEN_TAC THEN
5641   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_RESTRICT_OPEN_SUBINTERVAL) THEN
5642   MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
5643     HAS_INTEGRAL_SPIKE) THEN
5644   EXISTS_TAC `interval[c:real^M,d] DIFF interval(c,d)` THEN
5645   REWRITE_TAC[NEGLIGIBLE_FRONTIER_INTERVAL] THEN REWRITE_TAC[IN_DIFF] THEN
5646   MP_TAC(ISPECL [`c:real^M`; `d:real^M`] INTERVAL_OPEN_SUBSET_CLOSED) THEN
5647   SET_TAC[]);;
5648
5649 let HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVALS_EQ = prove
5650  (`!f:real^M->real^N a b c d i.
5651         interval[c,d] SUBSET interval[a,b]
5652         ==> (((\x. if x IN interval[c,d] then f x else vec 0) has_integral i)
5653               (interval[a,b]) <=>
5654              (f has_integral i) (interval[c,d]))`,
5655   REPEAT STRIP_TAC THEN ASM_CASES_TAC `interval[c:real^M,d] = {}` THENL
5656    [ASM_REWRITE_TAC[NOT_IN_EMPTY; HAS_INTEGRAL_0_EQ; HAS_INTEGRAL_EMPTY_EQ];
5657     ALL_TAC] THEN
5658   EQ_TAC THEN DISCH_TAC THEN
5659   ASM_SIMP_TAC[HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL] THEN
5660   SUBGOAL_THEN `(f:real^M->real^N) integrable_on interval[c,d]` MP_TAC THENL
5661    [MATCH_MP_TAC INTEGRABLE_EQ THEN
5662     EXISTS_TAC `\x. if x IN interval[c:real^M,d]
5663                     then f x:real^N else vec 0` THEN
5664     SIMP_TAC[] THEN MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN
5665     ASM_MESON_TAC[integrable_on];
5666     ALL_TAC] THEN
5667   DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
5668   DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
5669   MP_TAC(ASSUME `interval[c:real^M,d] SUBSET interval[a,b]`) THEN
5670   REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
5671   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL) THEN
5672   ASM_MESON_TAC[HAS_INTEGRAL_UNIQUE; INTEGRABLE_INTEGRAL]);;
5673
5674 (* ------------------------------------------------------------------------- *)
5675 (* Hence we can apply the limit process uniformly to all integrals.          *)
5676 (* ------------------------------------------------------------------------- *)
5677
5678 let HAS_INTEGRAL = prove
5679  (`!f:real^M->real^N i s.
5680      (f has_integral i) s <=>
5681         !e. &0 < e
5682             ==> ?B. &0 < B /\
5683                     !a b. ball(vec 0,B) SUBSET interval[a,b]
5684                           ==> ?z. ((\x. if x IN s then f(x) else vec 0)
5685                                    has_integral z) (interval[a,b]) /\
5686                                   norm(z - i) < e`,
5687   REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [has_integral_alt] THEN
5688   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
5689   POP_ASSUM(X_CHOOSE_THEN `a:real^M` (X_CHOOSE_THEN `b:real^M`
5690    SUBST_ALL_TAC)) THEN
5691   MP_TAC(ISPECL [`a:real^M`; `b:real^M`] (CONJUNCT1 BOUNDED_INTERVAL)) THEN
5692   REWRITE_TAC[BOUNDED_POS] THEN
5693   DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN EQ_TAC THENL
5694    [DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5695     EXISTS_TAC `B + &1` THEN ASM_SIMP_TAC[REAL_LT_ADD; REAL_LT_01] THEN
5696     MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN
5697     REWRITE_TAC[SUBSET; IN_BALL; NORM_ARITH `dist(vec 0,x) = norm x`] THEN
5698     DISCH_TAC THEN EXISTS_TAC `i:real^N` THEN
5699     ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN
5700     MATCH_MP_TAC HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL THEN
5701     ASM_MESON_TAC[SUBSET; REAL_ARITH `n <= B ==> n < B + &1`];
5702     ALL_TAC] THEN
5703   DISCH_TAC THEN
5704   SUBGOAL_THEN `?y. ((f:real^M->real^N) has_integral y) (interval[a,b])`
5705   MP_TAC THENL
5706    [SUBGOAL_THEN
5707      `?c d. interval[a,b] SUBSET interval[c,d] /\
5708             (\x. if x IN interval[a,b] then (f:real^M->real^N) x
5709                  else vec 0) integrable_on interval[c,d]`
5710     STRIP_ASSUME_TAC THENL
5711      [FIRST_X_ASSUM(MP_TAC o C MATCH_MP REAL_LT_01) THEN
5712       DISCH_THEN(X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC) THEN
5713       ABBREV_TAC `c:real^M = lambda i. --(max B C)` THEN
5714       ABBREV_TAC `d:real^M = lambda i. max B C` THEN
5715       MAP_EVERY EXISTS_TAC [`c:real^M`; `d:real^M`] THEN CONJ_TAC THENL
5716        [REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^M` THEN
5717         DISCH_TAC THEN REWRITE_TAC[IN_INTERVAL] THEN
5718         X_GEN_TAC `k:num` THEN MAP_EVERY EXPAND_TAC ["c"; "d"] THEN
5719         SIMP_TAC[LAMBDA_BETA; REAL_BOUNDS_LE] THEN STRIP_TAC THEN
5720         MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN
5721         ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
5722         MATCH_MP_TAC(REAL_ARITH `x <= B ==> x <= max B C`) THEN
5723         ASM_SIMP_TAC[];
5724         ALL_TAC] THEN
5725       FIRST_X_ASSUM(MP_TAC o SPECL [`c:real^M`; `d:real^M`]) THEN ANTS_TAC THENL
5726        [REWRITE_TAC[SUBSET; IN_BALL; NORM_ARITH `dist(vec 0,x) = norm x`] THEN
5727         X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[IN_INTERVAL] THEN
5728         X_GEN_TAC `k:num` THEN MAP_EVERY EXPAND_TAC ["c"; "d"] THEN
5729         SIMP_TAC[LAMBDA_BETA; REAL_BOUNDS_LE] THEN STRIP_TAC THEN
5730         MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN
5731         ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
5732         MATCH_MP_TAC(REAL_ARITH `x < C ==> x <= max B C`) THEN
5733         ASM_SIMP_TAC[];
5734         ALL_TAC] THEN
5735       MESON_TAC[integrable_on];
5736       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [integrable_on]) THEN
5737       ASM_SIMP_TAC[HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVALS_EQ]];
5738     ALL_TAC] THEN
5739   DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN
5740   SUBGOAL_THEN `i:real^N = y` ASSUME_TAC THEN ASM_REWRITE_TAC[] THEN
5741   MATCH_MP_TAC(NORM_ARITH `~(&0 < norm(y - i)) ==> i = y`) THEN
5742   DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `norm(y - i:real^N)`) THEN
5743   ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN X_GEN_TAC `C:real` THEN
5744   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5745   REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
5746   ABBREV_TAC `c:real^M = lambda i. --(max B C)` THEN
5747   ABBREV_TAC `d:real^M = lambda i. max B C` THEN
5748   MAP_EVERY EXISTS_TAC [`c:real^M`; `d:real^M`] THEN CONJ_TAC THENL
5749    [REWRITE_TAC[SUBSET; IN_BALL; NORM_ARITH `dist(vec 0,x) = norm x`] THEN
5750     X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[IN_INTERVAL] THEN
5751     X_GEN_TAC `k:num` THEN MAP_EVERY EXPAND_TAC ["c"; "d"] THEN
5752     SIMP_TAC[LAMBDA_BETA; REAL_BOUNDS_LE] THEN STRIP_TAC THEN
5753     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN
5754     ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
5755     MATCH_MP_TAC(REAL_ARITH `x < C ==> x <= max B C`) THEN
5756     ASM_SIMP_TAC[];
5757     ALL_TAC] THEN
5758   SUBGOAL_THEN `interval[a:real^M,b] SUBSET interval[c,d]` ASSUME_TAC THENL
5759    [REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^M` THEN
5760     DISCH_TAC THEN REWRITE_TAC[IN_INTERVAL] THEN
5761     X_GEN_TAC `k:num` THEN MAP_EVERY EXPAND_TAC ["c"; "d"] THEN
5762     SIMP_TAC[LAMBDA_BETA; REAL_BOUNDS_LE] THEN STRIP_TAC THEN
5763     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN
5764     ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
5765     MATCH_MP_TAC(REAL_ARITH `x <= B ==> x <= max B C`) THEN
5766     ASM_SIMP_TAC[];
5767     ALL_TAC] THEN
5768   ASM_SIMP_TAC[HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVALS_EQ] THEN
5769   ASM_MESON_TAC[REAL_LT_REFL; HAS_INTEGRAL_UNIQUE]);;
5770
5771 let HAS_INTEGRAL_TWIZZLE = prove
5772  (`!f:real^N->real^P s:real^M->bool y p.
5773         dimindex(:M) = dimindex(:N) /\ p permutes 1..dimindex(:N) /\
5774         (f has_integral y) (IMAGE (\x. lambda i. x$p i) s)
5775         ==> ((\x. f(lambda i. x$p i)) has_integral y) s`,
5776   REPEAT GEN_TAC THEN
5777   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5778   ONCE_REWRITE_TAC[HAS_INTEGRAL] THEN DISCH_TAC THEN
5779   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5780   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
5781   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN STRIP_TAC THEN
5782   ASM_REWRITE_TAC[] THEN
5783   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN
5784   FIRST_X_ASSUM(MP_TAC o SPECL
5785    [`(lambda i. (a:real^M)$p i):real^N`;
5786     `(lambda i. (b:real^M)$p i):real^N`]) THEN
5787   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
5788   SIMP_TAC[SUBSET; IN_BALL_0; IN_INTERVAL; LAMBDA_BETA] THEN
5789   ASM_REWRITE_TAC[NORM_LT_SQUARE; dot] THEN DISCH_TAC THEN ANTS_TAC THENL
5790    [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
5791     FIRST_X_ASSUM(MP_TAC o SPEC
5792       `(lambda i. (x:real^N)$(inverse p i)):real^M`) THEN
5793     SIMP_TAC[LAMBDA_BETA] THEN ANTS_TAC THENL
5794      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
5795        `x < a ==> x = y ==> y < a`)) THEN
5796       FIRST_ASSUM(MP_TAC o GSYM o
5797         MATCH_MP SUM_PERMUTE o MATCH_MP PERMUTES_INVERSE) THEN
5798       ONCE_ASM_REWRITE_TAC[] THEN SIMP_TAC[o_DEF];
5799       REWRITE_TAC[GSYM IN_NUMSEG] THEN
5800       ASM_MESON_TAC[PERMUTES_INVERSES; PERMUTES_IN_IMAGE]];
5801     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `z:real^P` THEN
5802     MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[]] THEN
5803   DISCH_THEN(MP_TAC o MATCH_MP (ONCE_REWRITE_RULE[IMP_CONJ]
5804       HAS_INTEGRAL_TWIZZLE_INTERVAL)) THEN
5805   ANTS_TAC THENL [ASM_MESON_TAC[]; REWRITE_TAC[]] THEN
5806   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
5807   REWRITE_TAC[FUN_EQ_THM] THEN  GEN_TAC THEN AP_THM_TAC THEN
5808   AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE
5809    `(!x y. f x = f y ==> x = y)
5810     ==> (f x IN IMAGE f s <=> x IN s)`) THEN
5811   SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN
5812   ONCE_ASM_REWRITE_TAC[] THEN REWRITE_TAC[GSYM IN_NUMSEG] THEN
5813   ASM_MESON_TAC[PERMUTES_INVERSES; PERMUTES_IN_IMAGE]);;
5814
5815 let HAS_INTEGRAL_TWIZZLE_EQ = prove
5816  (`!f:real^N->real^P s:real^M->bool y p.
5817         dimindex(:M) = dimindex(:N) /\ p permutes 1..dimindex(:N)
5818         ==> ((f has_integral y) (IMAGE (\x. lambda i. x$p i) s) <=>
5819              ((\x. f(lambda i. x$p i)) has_integral y) s)`,
5820   REPEAT STRIP_TAC THEN EQ_TAC THENL
5821    [ASM_MESON_TAC[HAS_INTEGRAL_TWIZZLE]; ALL_TAC] THEN
5822   MP_TAC(ISPECL
5823    [`(f:real^N->real^P) o ((\x. lambda i. x$p i):real^M->real^N)`;
5824     `IMAGE ((\x. lambda i. x$p i):real^M->real^N) s`;
5825     `y:real^P`; `inverse p:num->num`] HAS_INTEGRAL_TWIZZLE) THEN
5826   REWRITE_TAC[] THEN ONCE_ASM_REWRITE_TAC[] THEN
5827   ASM_SIMP_TAC[PERMUTES_INVERSE; o_DEF; GSYM IMAGE_o] THEN
5828   MATCH_MP_TAC MONO_IMP THEN CONJ_TAC THEN MATCH_MP_TAC EQ_IMP THENL
5829    [AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE
5830      `(!x. f x = x) ==> s = IMAGE f s`) THEN
5831     SIMP_TAC[CART_EQ; LAMBDA_BETA];
5832     AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
5833     REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN AP_TERM_TAC THEN
5834     SIMP_TAC[CART_EQ; FUN_EQ_THM; LAMBDA_BETA]] THEN
5835   IMP_REWRITE_TAC[LAMBDA_BETA] THEN
5836   REWRITE_TAC[GSYM IN_NUMSEG] THEN
5837   ASM_MESON_TAC[PERMUTES_INVERSES; PERMUTES_IN_IMAGE]);;
5838
5839 let HAS_INTEGRAL_PASTECART_SYM_ALT = prove
5840  (`!f:real^(M,N)finite_sum->real^P s y.
5841         ((\z. f(pastecart (sndcart z) (fstcart z))) has_integral y) s <=>
5842         (f has_integral y) (IMAGE (\z. pastecart (sndcart z) (fstcart z)) s)`,
5843   REPEAT STRIP_TAC THEN
5844   SUBGOAL_THEN
5845    `?p. p permutes 1..dimindex(:(M,N)finite_sum) /\
5846         !z. pastecart (sndcart z:real^M) (fstcart z:real^N) =
5847             lambda i. z$(p i)`
5848   STRIP_ASSUME_TAC THENL
5849    [REPEAT STRIP_TAC THEN
5850     EXISTS_TAC `\i. if 1 <= i /\ i <= dimindex(:M) then i + dimindex(:N)
5851                 else if i <= dimindex(:M) + dimindex(:N) then i - dimindex(:M)
5852                  else i` THEN
5853     CONJ_TAC THENL
5854      [MATCH_MP_TAC PERMUTES_BIJECTIONS THEN
5855       EXISTS_TAC `\i. if 1 <= i /\ i <= dimindex(:N) then i + dimindex(:M)
5856                 else if i <= dimindex(:M) + dimindex(:N) then i - dimindex(:N)
5857                 else i` THEN
5858       SIMP_TAC[IN_NUMSEG; DIMINDEX_FINITE_SUM] THEN ARITH_TAC;
5859       SIMP_TAC[FUN_EQ_THM; CART_EQ; pastecart; LAMBDA_BETA] THEN
5860       SIMP_TAC[fstcart; sndcart; LAMBDA_BETA; DIMINDEX_FINITE_SUM;
5861                ARITH_RULE `i:num <= n ==> i + m <= n + m`] THEN
5862       REPEAT STRIP_TAC THEN
5863       REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN
5864       TRY(MATCH_MP_TAC LAMBDA_BETA) THEN ASM_ARITH_TAC];
5865     ASM_REWRITE_TAC[] THEN CONV_TAC SYM_CONV THEN
5866     MATCH_MP_TAC HAS_INTEGRAL_TWIZZLE_EQ THEN ASM_REWRITE_TAC[] THEN
5867     REWRITE_TAC[DIMINDEX_FINITE_SUM; ADD_SYM]]);;
5868
5869 let HAS_INTEGRAL_PASTECART_SYM = prove
5870  (`!f:real^(M,N)finite_sum->real^P s y.
5871         ((\z. f(pastecart (sndcart z) (fstcart z))) has_integral y)
5872         (IMAGE (\z. pastecart (sndcart z) (fstcart z)) s) <=>
5873         (f has_integral y) s`,
5874   REPEAT STRIP_TAC THEN
5875   MP_TAC(ISPECL
5876    [`f:real^(M,N)finite_sum->real^P`;
5877     `IMAGE (\z. pastecart (sndcart z) (fstcart z))
5878            (s:real^(M,N)finite_sum->bool)`; `y:real^P`]
5879    HAS_INTEGRAL_PASTECART_SYM_ALT) THEN
5880   REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN AP_TERM_TAC THEN
5881   REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN
5882   REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN
5883   REWRITE_TAC[PASTECART_FST_SND; IMAGE_ID]);;
5884
5885 let INTEGRAL_PASTECART_SYM = prove
5886  (`!f:real^(M,N)finite_sum->real^P s y.
5887         integral
5888            (IMAGE (\z. pastecart (sndcart z) (fstcart z)) s)
5889            (\z. f(pastecart (sndcart z) (fstcart z))) =
5890         integral s f`,
5891   REWRITE_TAC[integral; HAS_INTEGRAL_PASTECART_SYM]);;
5892
5893 let INTEGRABLE_PASTECART_SYM = prove
5894  (`!f:real^(M,N)finite_sum->real^P s y.
5895         (\z. f(pastecart (sndcart z) (fstcart z))) integrable_on
5896         (IMAGE (\z. pastecart (sndcart z) (fstcart z)) s) <=>
5897         f integrable_on s`,
5898   REWRITE_TAC[integrable_on; HAS_INTEGRAL_PASTECART_SYM]);;
5899
5900 (* ------------------------------------------------------------------------- *)
5901 (* Hence a general restriction property.                                     *)
5902 (* ------------------------------------------------------------------------- *)
5903
5904 let HAS_INTEGRAL_RESTRICT = prove
5905  (`!f:real^M->real^N s t i.
5906         s SUBSET t
5907         ==> (((\x. if x IN s then f x else vec 0) has_integral i) t <=>
5908              (f has_integral i) s)`,
5909   REWRITE_TAC[SUBSET] THEN REPEAT STRIP_TAC THEN
5910   ONCE_REWRITE_TAC[HAS_INTEGRAL] THEN REWRITE_TAC[] THEN
5911   ONCE_REWRITE_TAC[MESON[] `(if p then if q then x else y else y) =
5912                             (if q then if p then x else y else y)`] THEN
5913   ASM_SIMP_TAC[]);;
5914
5915 let INTEGRAL_RESTRICT = prove
5916  (`!f:real^M->real^N s t.
5917         s SUBSET t
5918         ==> integral t (\x. if x IN s then f x else vec 0) =
5919             integral s f`,
5920   SIMP_TAC[integral; HAS_INTEGRAL_RESTRICT]);;
5921
5922 let INTEGRABLE_RESTRICT = prove
5923  (`!f:real^M->real^N s t.
5924         s SUBSET t
5925         ==> ((\x. if x IN s then f x else vec 0) integrable_on t <=>
5926              f integrable_on s)`,
5927   SIMP_TAC[integrable_on; HAS_INTEGRAL_RESTRICT]);;
5928
5929 let HAS_INTEGRAL_RESTRICT_UNIV = prove
5930  (`!f:real^M->real^N s i.
5931         ((\x. if x IN s then f x else vec 0) has_integral i) (:real^M) <=>
5932          (f has_integral i) s`,
5933   SIMP_TAC[HAS_INTEGRAL_RESTRICT; SUBSET_UNIV]);;
5934
5935 let INTEGRAL_RESTRICT_UNIV = prove
5936  (`!f:real^M->real^N s.
5937         integral (:real^M) (\x. if x IN s then f x else vec 0) =
5938         integral s f`,
5939   REWRITE_TAC[integral; HAS_INTEGRAL_RESTRICT_UNIV]);;
5940
5941 let INTEGRABLE_RESTRICT_UNIV = prove
5942  (`!f s. (\x. if x IN s then f x else vec 0) integrable_on (:real^M) <=>
5943          f integrable_on s`,
5944   REWRITE_TAC[integrable_on; HAS_INTEGRAL_RESTRICT_UNIV]);;
5945
5946 let HAS_INTEGRAL_RESTRICT_INTER = prove
5947  (`!f:real^M->real^N s t.
5948         ((\x. if x IN s then f x else vec 0) has_integral i) t <=>
5949         (f has_integral i) (s INTER t)`,
5950   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
5951   REWRITE_TAC[IN_INTER] THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
5952   REWRITE_TAC[FUN_EQ_THM] THEN MESON_TAC[]);;
5953
5954 let INTEGRAL_RESTRICT_INTER = prove
5955  (`!f:real^M->real^N s t.
5956         integral t (\x. if x IN s then f x else vec 0) =
5957         integral (s INTER t) f`,
5958   REWRITE_TAC[integral; HAS_INTEGRAL_RESTRICT_INTER]);;
5959
5960 let INTEGRABLE_RESTRICT_INTER = prove
5961  (`!f:real^M->real^N s t.
5962         (\x. if x IN s then f x else vec 0) integrable_on t <=>
5963         f integrable_on (s INTER t)`,
5964   REWRITE_TAC[integrable_on; HAS_INTEGRAL_RESTRICT_INTER]);;
5965
5966 let HAS_INTEGRAL_ON_SUPERSET = prove
5967  (`!f s t.
5968         (!x. ~(x IN s) ==> f x = vec 0) /\ s SUBSET t /\ (f has_integral i) s
5969         ==> (f has_integral i) t`,
5970   REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET] THEN
5971   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5972   ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
5973   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN
5974   AP_TERM_TAC THEN ABS_TAC THEN ASM_MESON_TAC[]);;
5975
5976 let INTEGRABLE_ON_SUPERSET = prove
5977  (`!f s t.
5978         (!x. ~(x IN s) ==> f x = vec 0) /\ s SUBSET t /\ f integrable_on s
5979         ==> f integrable_on t`,
5980   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_ON_SUPERSET]);;
5981
5982 let NEGLIGIBLE_ON_INTERVALS = prove
5983  (`!s. negligible s <=> !a b:real^N. negligible(s INTER interval[a,b])`,
5984   GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
5985    [MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `s:real^N->bool` THEN
5986     ASM_REWRITE_TAC[] THEN SET_TAC[];
5987     ALL_TAC] THEN
5988   REWRITE_TAC[negligible] THEN
5989   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
5990   FIRST_ASSUM(ASSUME_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN
5991   MATCH_MP_TAC HAS_INTEGRAL_NEGLIGIBLE THEN
5992   EXISTS_TAC `s INTER interval[a:real^N,b]` THEN
5993   ASM_REWRITE_TAC[] THEN SIMP_TAC[indicator; IN_DIFF; IN_INTER] THEN
5994   MESON_TAC[]);;
5995
5996 let NEGLIGIBLE_BOUNDED_SUBSETS = prove
5997  (`!s:real^N->bool.
5998     negligible s <=> !t. bounded t /\ t SUBSET s ==> negligible t`,
5999   MESON_TAC[NEGLIGIBLE_ON_INTERVALS; INTER_SUBSET; BOUNDED_SUBSET;
6000             BOUNDED_INTERVAL; NEGLIGIBLE_SUBSET]);;
6001
6002 let NEGLIGIBLE_ON_COUNTABLE_INTERVALS = prove
6003  (`!s:real^N->bool.
6004         negligible s <=>
6005         !n. negligible (s INTER interval[--vec n,vec n])`,
6006   GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [NEGLIGIBLE_ON_INTERVALS] THEN
6007   EQ_TAC THEN SIMP_TAC[] THEN REPEAT STRIP_TAC THEN
6008   SUBGOAL_THEN
6009    `!a b:real^N. ?n. s INTER interval[a,b] =
6010                      ((s INTER interval[--vec n,vec n]) INTER interval[a,b])`
6011    (fun th -> ASM_MESON_TAC[th; NEGLIGIBLE_ON_INTERVALS]) THEN
6012   REPEAT GEN_TAC THEN
6013   MP_TAC(ISPECL [`interval[a:real^N,b]`; `vec 0:real^N`]
6014         BOUNDED_SUBSET_CBALL) THEN
6015   REWRITE_TAC[BOUNDED_INTERVAL] THEN
6016   DISCH_THEN(X_CHOOSE_THEN `r:real` STRIP_ASSUME_TAC) THEN
6017   MP_TAC(SPEC `r:real` REAL_ARCH_SIMPLE) THEN
6018   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
6019   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
6020    `i SUBSET b ==> b SUBSET n ==> s INTER i = (s INTER n) INTER i`)) THEN
6021   REWRITE_TAC[SUBSET; IN_CBALL_0; IN_INTERVAL; VEC_COMPONENT;
6022               VECTOR_NEG_COMPONENT; GSYM REAL_ABS_BOUNDS]  THEN
6023   ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS]);;
6024
6025 let HAS_INTEGRAL_SPIKE_SET_EQ = prove
6026  (`!f:real^M->real^N s t y.
6027         negligible(s DIFF t UNION t DIFF s)
6028         ==> ((f has_integral y) s <=> (f has_integral y) t)`,
6029   REPEAT STRIP_TAC THEN  ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
6030   MATCH_MP_TAC HAS_INTEGRAL_SPIKE_EQ THEN
6031   EXISTS_TAC `s DIFF t UNION t DIFF s:real^M->bool` THEN
6032   ASM_REWRITE_TAC[] THEN SET_TAC[]);;
6033
6034 let HAS_INTEGRAL_SPIKE_SET = prove
6035  (`!f:real^M->real^N s t y.
6036         negligible(s DIFF t UNION t DIFF s) /\
6037         (f has_integral y) s
6038         ==> (f has_integral y) t`,
6039   MESON_TAC[HAS_INTEGRAL_SPIKE_SET_EQ]);;
6040
6041 let INTEGRABLE_SPIKE_SET = prove
6042  (`!f:real^M->real^N s t.
6043         negligible(s DIFF t UNION t DIFF s)
6044         ==> f integrable_on s ==> f integrable_on t`,
6045   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_SPIKE_SET_EQ]);;
6046
6047 let INTEGRABLE_SPIKE_SET_EQ = prove
6048  (`!f:real^M->real^N s t.
6049         negligible(s DIFF t UNION t DIFF s)
6050         ==> (f integrable_on s <=> f integrable_on t)`,
6051   MESON_TAC[INTEGRABLE_SPIKE_SET; UNION_COMM]);;
6052
6053 let INTEGRAL_SPIKE_SET = prove
6054  (`!f:real^M->real^N g s t.
6055         negligible(s DIFF t UNION t DIFF s)
6056         ==> integral s f = integral t f`,
6057   REPEAT STRIP_TAC THEN REWRITE_TAC[integral] THEN
6058   AP_TERM_TAC THEN ABS_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_SET_EQ THEN
6059   ASM_MESON_TAC[]);;
6060
6061 let HAS_INTEGRAL_INTERIOR = prove
6062  (`!f:real^M->real^N y s.
6063         negligible(frontier s)
6064         ==> ((f has_integral y) (interior s) <=> (f has_integral y) s)`,
6065   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_SET_EQ THEN
6066   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
6067     NEGLIGIBLE_SUBSET)) THEN
6068   REWRITE_TAC[frontier] THEN
6069   MP_TAC(ISPEC `s:real^M->bool` INTERIOR_SUBSET) THEN
6070   MP_TAC(ISPEC `s:real^M->bool` CLOSURE_SUBSET) THEN
6071   SET_TAC[]);;
6072
6073 let HAS_INTEGRAL_CLOSURE = prove
6074  (`!f:real^M->real^N y s.
6075         negligible(frontier s)
6076         ==> ((f has_integral y) (closure s) <=> (f has_integral y) s)`,
6077   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_SET_EQ THEN
6078   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
6079     NEGLIGIBLE_SUBSET)) THEN
6080   REWRITE_TAC[frontier] THEN
6081   MP_TAC(ISPEC `s:real^M->bool` INTERIOR_SUBSET) THEN
6082   MP_TAC(ISPEC `s:real^M->bool` CLOSURE_SUBSET) THEN
6083   SET_TAC[]);;
6084
6085 let INTEGRABLE_CASES = prove
6086  (`!f g:real^M->real^N s.
6087         f integrable_on {x | x IN s /\ P x} /\
6088         g integrable_on {x | x IN s /\ ~P x}
6089         ==> (\x. if P x then f x else g x) integrable_on s`,
6090   REPEAT GEN_TAC THEN
6091   ONCE_REWRITE_TAC[GSYM INTEGRABLE_RESTRICT_UNIV] THEN
6092   DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_ADD) THEN
6093   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] INTEGRABLE_EQ) THEN
6094   REWRITE_TAC[IN_UNIV; IN_ELIM_THM] THEN
6095   MESON_TAC[VECTOR_ADD_LID; VECTOR_ADD_RID]);;
6096
6097 (* ------------------------------------------------------------------------- *)
6098 (* More lemmas that are useful later.                                        *)
6099 (* ------------------------------------------------------------------------- *)
6100
6101 let HAS_INTEGRAL_DROP_POS_AE = prove
6102  (`!f:real^M->real^1 s t i.
6103         (f has_integral i) s /\
6104         negligible t /\ (!x. x IN s DIFF t ==> &0 <= drop(f x))
6105         ==> &0 <= drop i`,
6106   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_DROP_POS THEN
6107   EXISTS_TAC `f:real^M->real^1` THEN EXISTS_TAC `s DIFF t:real^M->bool` THEN
6108   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_SET THEN
6109   EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN
6110   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
6111         NEGLIGIBLE_SUBSET)) THEN
6112   SET_TAC[]);;
6113
6114 let INTEGRAL_DROP_POS_AE = prove
6115  (`!f:real^M->real^1 s t.
6116         f integrable_on s /\
6117         negligible t /\ (!x. x IN s DIFF t ==> &0 <= drop(f x))
6118         ==> &0 <= drop(integral s f)`,
6119   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_DROP_POS_AE THEN
6120   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
6121
6122 let HAS_INTEGRAL_SUBSET_COMPONENT_LE = prove
6123  (`!f:real^M->real^N s t i j k.
6124         s SUBSET t /\ (f has_integral i) s /\ (f has_integral j) t /\
6125         1 <= k /\ k <= dimindex(:N) /\
6126         (!x. x IN t ==> &0 <= f(x)$k)
6127         ==> i$k <= j$k`,
6128   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
6129   STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LE THEN
6130   MAP_EVERY EXISTS_TAC
6131    [`(\x. if x IN s then f x else vec 0):real^M->real^N`;
6132     `(\x. if x IN t then f x else vec 0):real^M->real^N`;
6133     `(:real^M)`] THEN
6134   ASM_REWRITE_TAC[] THEN
6135   REPEAT STRIP_TAC THEN
6136   REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL]) THEN
6137   ASM_SIMP_TAC[VEC_COMPONENT] THEN ASM SET_TAC[]);;
6138
6139 let INTEGRAL_SUBSET_COMPONENT_LE = prove
6140  (`!f:real^M->real^N s t k.
6141         s SUBSET t /\ f integrable_on s /\ f integrable_on t /\
6142         1 <= k /\ k <= dimindex(:N) /\
6143         (!x. x IN t ==> &0 <= f(x)$k)
6144         ==> (integral s f)$k <= (integral t f)$k`,
6145   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SUBSET_COMPONENT_LE THEN
6146   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
6147
6148 let HAS_INTEGRAL_SUBSET_DROP_LE = prove
6149  (`!f:real^M->real^1 s t i j.
6150         s SUBSET t /\ (f has_integral i) s /\ (f has_integral j) t /\
6151         (!x. x IN t ==> &0 <= drop(f x))
6152         ==> drop i <= drop j`,
6153   REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN
6154   MATCH_MP_TAC HAS_INTEGRAL_SUBSET_COMPONENT_LE THEN
6155   REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN ASM_MESON_TAC[]);;
6156
6157 let INTEGRAL_SUBSET_DROP_LE = prove
6158  (`!f:real^M->real^1 s t.
6159         s SUBSET t /\ f integrable_on s /\ f integrable_on t /\
6160         (!x. x IN t ==> &0 <= drop(f(x)))
6161         ==> drop(integral s f) <= drop(integral t f)`,
6162   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SUBSET_DROP_LE THEN
6163   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
6164
6165 let HAS_INTEGRAL_ALT = prove
6166  (`!f:real^M->real^N s i.
6167         (f has_integral i) s <=>
6168             (!a b. (\x. if x IN s then f x else vec 0)
6169                    integrable_on interval[a,b]) /\
6170             (!e. &0 < e
6171                  ==> ?B. &0 < B /\
6172                          !a b. ball (vec 0,B) SUBSET interval[a,b]
6173                                ==> norm(integral(interval[a,b])
6174                                           (\x. if x IN s then f x else vec 0) -
6175                                         i) < e)`,
6176   REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [HAS_INTEGRAL] THEN
6177   SPEC_TAC(`\x. if x IN s then (f:real^M->real^N) x else vec 0`,
6178            `f:real^M->real^N`) THEN
6179   GEN_TAC THEN EQ_TAC THENL
6180    [ALL_TAC; MESON_TAC[INTEGRAL_UNIQUE; integrable_on]] THEN
6181   DISCH_TAC THEN CONJ_TAC THENL
6182    [ALL_TAC; ASM_MESON_TAC[INTEGRAL_UNIQUE]] THEN
6183   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
6184   POP_ASSUM(MP_TAC o C MATCH_MP REAL_LT_01) THEN
6185   DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
6186   MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN
6187   EXISTS_TAC `(lambda i. min ((a:real^M)$i) (--B)):real^M` THEN
6188   EXISTS_TAC `(lambda i. max ((b:real^M)$i) B):real^M` THEN CONJ_TAC THENL
6189    [FIRST_X_ASSUM(MP_TAC o SPECL
6190      [`(lambda i. min ((a:real^M)$i) (--B)):real^M`;
6191       `(lambda i. max ((b:real^M)$i) B):real^M`]) THEN
6192     ANTS_TAC THENL [ALL_TAC; MESON_TAC[integrable_on]];
6193     SIMP_TAC[SUBSET; IN_INTERVAL; IN_BALL; LAMBDA_BETA;
6194              REAL_MIN_LE; REAL_LE_MAX]] THEN
6195   SIMP_TAC[SUBSET; IN_BALL; IN_INTERVAL; LAMBDA_BETA] THEN
6196   GEN_TAC THEN REWRITE_TAC[NORM_ARITH `dist(vec 0,x) = norm x`] THEN
6197   DISCH_TAC THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
6198   MATCH_MP_TAC(REAL_ARITH
6199     `abs(x) <= B ==> min a (--B) <= x /\ x <= max b B`) THEN
6200   MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN
6201   ASM_SIMP_TAC[REAL_LT_IMP_LE; COMPONENT_LE_NORM]);;
6202
6203 let INTEGRABLE_ALT = prove
6204  (`!f:real^M->real^N s.
6205         f integrable_on s <=>
6206           (!a b. (\x. if x IN s then f x else vec 0) integrable_on
6207                  interval[a,b]) /\
6208           (!e. &0 < e
6209                ==> ?B. &0 < B /\
6210                        !a b c d.
6211                           ball(vec 0,B) SUBSET interval[a,b] /\
6212                           ball(vec 0,B) SUBSET interval[c,d]
6213                           ==> norm(integral (interval[a,b])
6214                                     (\x. if x IN s then f x else vec 0) -
6215                                    integral (interval[c,d])
6216                                     (\x. if x IN s then f x else vec 0)) < e)`,
6217   REPEAT GEN_TAC THEN
6218   GEN_REWRITE_TAC LAND_CONV [integrable_on] THEN
6219   ONCE_REWRITE_TAC[HAS_INTEGRAL_ALT] THEN
6220   REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN
6221   MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> (a /\ b <=> a /\ c)`) THEN
6222   DISCH_TAC THEN EQ_TAC THENL
6223    [DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN
6224     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6225     FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
6226     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
6227     MESON_TAC[NORM_ARITH `norm(a - y) < e / &2 /\ norm(b - y) < e / &2
6228                           ==> norm(a - b) < e`];
6229     ALL_TAC] THEN
6230   DISCH_TAC THEN
6231   SUBGOAL_THEN
6232    `cauchy (\n. integral (interval[(lambda i. --(&n)),(lambda i. &n)])
6233                          (\x. if x IN s then (f:real^M->real^N) x else vec 0))`
6234   MP_TAC THENL
6235    [REWRITE_TAC[cauchy] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6236     FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
6237     DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
6238     MP_TAC(SPEC `B:real` REAL_ARCH_SIMPLE) THEN
6239     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN
6240     REPEAT STRIP_TAC THEN REWRITE_TAC[dist] THEN
6241     FIRST_X_ASSUM MATCH_MP_TAC THEN
6242     REWRITE_TAC[SUBSET; IN_BALL; NORM_ARITH `dist(vec 0,x) = norm x`] THEN
6243     CONJ_TAC;
6244     REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN
6245     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `i:real^N` THEN
6246     REWRITE_TAC[LIM_SEQUENTIALLY] THEN DISCH_THEN(LABEL_TAC "C") THEN
6247     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6248     REMOVE_THEN "C" (MP_TAC o SPEC `e / &2`) THEN
6249     FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
6250     DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
6251     DISCH_THEN(X_CHOOSE_THEN `N:num` ASSUME_TAC) THEN
6252     MP_TAC(SPEC `max (&N) B` REAL_ARCH_SIMPLE) THEN
6253     REWRITE_TAC[REAL_MAX_LE; REAL_OF_NUM_LE] THEN
6254     DISCH_THEN(X_CHOOSE_THEN `n:num` STRIP_ASSUME_TAC) THEN
6255     EXISTS_TAC `&n` THEN CONJ_TAC THENL
6256      [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
6257     MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN STRIP_TAC THEN
6258     FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN ASM_REWRITE_TAC[] THEN
6259     MATCH_MP_TAC(NORM_ARITH
6260      `norm(i1 - i2) < e / &2 ==> dist(i1,i) < e / &2 ==> norm(i2 - i) < e`) THEN
6261     FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THEN
6262     MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `ball(vec 0:real^M,&n)` THEN
6263     ASM_SIMP_TAC[SUBSET_BALL] THEN
6264     REWRITE_TAC[SUBSET; IN_BALL; NORM_ARITH `dist(vec 0,x) = norm x`]] THEN
6265   X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
6266   SIMP_TAC[IN_INTERVAL; LAMBDA_BETA] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
6267   REWRITE_TAC[REAL_BOUNDS_LE] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
6268   EXISTS_TAC `norm(x:real^M)` THEN ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
6269   REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[GSYM REAL_OF_NUM_GE] THEN
6270   REAL_ARITH_TAC);;
6271
6272 let INTEGRABLE_ALT_SUBSET = prove
6273  (`!f:real^M->real^N s.
6274         f integrable_on s <=>
6275           (!a b. (\x. if x IN s then f x else vec 0) integrable_on
6276                  interval[a,b]) /\
6277           (!e. &0 < e
6278                ==> ?B. &0 < B /\
6279                        !a b c d.
6280                           ball(vec 0,B) SUBSET interval[a,b] /\
6281                           interval[a,b] SUBSET interval[c,d]
6282                           ==> norm(integral (interval[a,b])
6283                                     (\x. if x IN s then f x else vec 0) -
6284                                    integral (interval[c,d])
6285                                     (\x. if x IN s then f x else vec 0)) < e)`,
6286   REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [INTEGRABLE_ALT] THEN
6287   ABBREV_TAC `g:real^M->real^N = \x. if x IN s then f x else vec 0` THEN
6288   POP_ASSUM(K ALL_TAC) THEN
6289   MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> (a /\ b <=> a /\ c)`) THEN
6290   DISCH_TAC THEN EQ_TAC THENL [MESON_TAC[SUBSET_TRANS]; ALL_TAC] THEN
6291   DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6292   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
6293   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
6294   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
6295   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real^M`; `d:real^M`] THEN
6296   STRIP_TAC THEN
6297   FIRST_X_ASSUM(MP_TAC o SPECL
6298    [`(lambda i. max ((a:real^M)$i) ((c:real^M)$i)):real^M`;
6299     `(lambda i. min ((b:real^M)$i) ((d:real^M)$i)):real^M`]) THEN
6300   ASM_REWRITE_TAC[GSYM INTER_INTERVAL; SUBSET_INTER] THEN
6301   DISCH_THEN(fun th ->
6302     MP_TAC(ISPECL [`a:real^M`; `b:real^M`] th) THEN
6303     MP_TAC(ISPECL [`c:real^M`; `d:real^M`] th)) THEN
6304   ASM_REWRITE_TAC[INTER_SUBSET] THEN NORM_ARITH_TAC);;
6305
6306 let INTEGRABLE_ON_SUBINTERVAL = prove
6307  (`!f:real^M->real^N s a b.
6308         f integrable_on s /\ interval[a,b] SUBSET s
6309         ==> f integrable_on interval[a,b]`,
6310   REPEAT GEN_TAC THEN
6311   GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [INTEGRABLE_ALT] THEN
6312   DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o CONJUNCT1) ASSUME_TAC) THEN
6313   DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN
6314   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] INTEGRABLE_EQ) THEN
6315   ASM SET_TAC[]);;
6316
6317 let INTEGRAL_SPLIT = prove
6318  (`!f:real^M->real^N a b t k.
6319         f integrable_on interval[a,b] /\ 1 <= k /\ k <= dimindex(:M)
6320         ==> integral (interval[a,b]) f =
6321                 integral(interval
6322                  [a,(lambda i. if i = k then min (b$k) t else b$i)]) f +
6323                 integral(interval
6324                  [(lambda i. if i = k then max (a$k) t else a$i),b]) f`,
6325   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
6326   MATCH_MP_TAC HAS_INTEGRAL_SPLIT THEN
6327   MAP_EVERY EXISTS_TAC [`k:num`; `t:real`] THEN
6328   ASM_SIMP_TAC[INTERVAL_SPLIT; GSYM HAS_INTEGRAL_INTEGRAL] THEN
6329   CONJ_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
6330   EXISTS_TAC `interval[a:real^M,b]` THEN
6331   ASM_SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN
6332   REPEAT STRIP_TAC THEN TRY COND_CASES_TAC THEN
6333   ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC);;
6334
6335 let INTEGRAL_SPLIT_SIGNED = prove
6336  (`!f:real^M->real^N a b t k.
6337         1 <= k /\ k <= dimindex(:M) /\ a$k <= t /\ a$k <= b$k /\
6338         f integrable_on
6339         interval[a,(lambda i. if i = k then max (b$k) t else b$i)]
6340         ==> integral (interval[a,b]) f =
6341                 integral(interval
6342                  [a,(lambda i. if i = k then t else b$i)]) f +
6343                 (if b$k < t then -- &1 else &1) %
6344                 integral(interval
6345                  [(lambda i. if i = k then min (b$k) t else a$i),
6346                   (lambda i. if i = k then max (b$k) t else b$i)]) f`,
6347   REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
6348    [MP_TAC(ISPECL
6349     [`f:real^M->real^N`;
6350      `a:real^M`;
6351      `(lambda i. if i = k then t else (b:real^M)$i):real^M`;
6352      `(b:real^M)$k`; `k:num`]
6353         INTEGRAL_SPLIT) THEN
6354     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
6355      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
6356        (REWRITE_RULE[IMP_CONJ] INTEGRABLE_ON_SUBINTERVAL)) THEN
6357       ASM_SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN
6358       REPEAT STRIP_TAC THEN TRY COND_CASES_TAC THEN
6359       ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC;
6360       DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC(VECTOR_ARITH
6361        `x = y /\ w = z
6362         ==> x:real^N = (y + z) + --(&1) % w`) THEN
6363       CONJ_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
6364       REWRITE_TAC[CONS_11; PAIR_EQ; CART_EQ] THEN TRY CONJ_TAC THEN
6365       ASM_SIMP_TAC[LAMBDA_BETA] THEN
6366       GEN_TAC THEN STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN
6367       ASM_REAL_ARITH_TAC];
6368     MP_TAC(ISPECL
6369     [`f:real^M->real^N`;
6370      `a:real^M`;
6371      `b:real^M`;
6372      `t:real`; `k:num`]
6373         INTEGRAL_SPLIT) THEN
6374     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
6375      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
6376        (REWRITE_RULE[IMP_CONJ] INTEGRABLE_ON_SUBINTERVAL)) THEN
6377       ASM_SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN
6378       REPEAT STRIP_TAC THEN TRY COND_CASES_TAC THEN
6379       ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC;
6380       DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[VECTOR_MUL_LID] THEN
6381       BINOP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
6382       REWRITE_TAC[CONS_11; PAIR_EQ; CART_EQ] THEN TRY CONJ_TAC THEN
6383       ASM_SIMP_TAC[LAMBDA_BETA] THEN
6384       GEN_TAC THEN STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN
6385       ASM_REAL_ARITH_TAC]]);;
6386
6387 let INTEGRAL_INTERVALS_INCLUSION_EXCLUSION = prove
6388  (`!f:real^M->real^N a b c d.
6389         f integrable_on interval[a,b] /\
6390         c IN interval[a,b] /\ d IN interval[a,b]
6391         ==> integral(interval[a,d]) f =
6392                 vsum {s | s SUBSET 1..dimindex(:M)}
6393                     (\s. --(&1) pow CARD {i | i IN s /\ d$i < c$i} %
6394                          integral
6395                           (interval[(lambda i. if i IN s
6396                                                then min (c$i) (d$i)
6397                                                else (a:real^M)$i),
6398                                     (lambda i. if i IN s
6399                                                then max (c$i) (d$i)
6400                                                else c$i)]) f)`,
6401   let lemma1 = prove
6402    (`!f:(num->bool)->real^N n.
6403           vsum {s | s SUBSET 1..SUC n} f =
6404           vsum {s | s SUBSET 1..n} f +
6405           vsum {s | s SUBSET 1..n} (\s. f(SUC n INSERT s))`,
6406     REPEAT STRIP_TAC THEN
6407     REWRITE_TAC[NUMSEG_CLAUSES; ARITH_RULE `1 <= SUC n`; POWERSET_CLAUSES] THEN
6408     W(MP_TAC o PART_MATCH (lhs o rand) VSUM_UNION o lhs o snd) THEN
6409     ANTS_TAC THENL
6410      [ASM_SIMP_TAC[FINITE_IMAGE; FINITE_POWERSET; FINITE_NUMSEG] THEN
6411       REWRITE_TAC[SET_RULE
6412        `DISJOINT s (IMAGE f t) <=> !x. x IN t ==> ~(f x IN s)`] THEN
6413       GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM; SUBSET] THEN
6414       DISCH_THEN(MP_TAC o SPEC `SUC n`) THEN
6415       REWRITE_TAC[IN_INSERT; IN_NUMSEG] THEN ARITH_TAC;
6416       DISCH_THEN SUBST1_TAC THEN AP_TERM_TAC THEN
6417       MATCH_MP_TAC(REWRITE_RULE[o_DEF] VSUM_IMAGE) THEN
6418       SIMP_TAC[FINITE_POWERSET; FINITE_NUMSEG] THEN
6419       MAP_EVERY X_GEN_TAC [`s:num->bool`; `t:num->bool`] THEN
6420       REWRITE_TAC[IN_ELIM_THM] THEN MATCH_MP_TAC(SET_RULE
6421        `~(a IN i)
6422         ==> s SUBSET i /\ t SUBSET i /\ a INSERT s = a INSERT t
6423             ==> s = t`) THEN
6424       REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC]) in
6425   let lemma2 = prove
6426    (`!f:real^M->real^N m a:real^M c:real^M d:real^M.
6427           f integrable_on (:real^M) /\ m <= dimindex(:M) /\
6428           (!i. m < i /\ i <= dimindex(:M) ==> a$i = c$i \/ d$i = c$i) /\
6429           (!i. m < i /\ i <= dimindex(:M) ==> a$i = c$i ==> a$i = d$i) /\
6430           (!i. 1 <= i /\ i <= dimindex(:M) ==> a$i <= c$i /\ a$i <= d$i)
6431           ==> integral(interval[a,d]) f =
6432                   vsum {s | s SUBSET 1..m}
6433                       (\s. --(&1) pow CARD {i | i IN s /\ d$i < c$i} %
6434                            integral
6435                             (interval[(lambda i. if i IN s
6436                                                  then min (c$i) (d$i)
6437                                                  else (a:real^M)$i),
6438                                       (lambda i. if i IN s
6439                                                  then max (c$i) (d$i)
6440                                                  else c$i)]) f)`,
6441     GEN_TAC THEN INDUCT_TAC THENL
6442      [REWRITE_TAC[NUMSEG_CLAUSES; ARITH; SUBSET_EMPTY; SING_GSPEC] THEN
6443       REWRITE_TAC[VSUM_SING; NOT_IN_EMPTY; EMPTY_GSPEC; CARD_CLAUSES] THEN
6444       REWRITE_TAC[real_pow; LAMBDA_ETA; VECTOR_MUL_LID] THEN
6445       REWRITE_TAC[ARITH_RULE `0 < i <=> 1 <= i`] THEN REPEAT STRIP_TAC THEN
6446       ASM_CASES_TAC
6447        `?k. 1 <= k /\ k <= dimindex(:M) /\ (a:real^M)$k = (c:real^M)$k`
6448       THENL
6449        [MATCH_MP_TAC(MESON[] `i = vec 0 /\ j = vec 0 ==> i:real^N = j`) THEN
6450         CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_NULL THEN
6451         REWRITE_TAC[CONTENT_EQ_0] THEN ASM_MESON_TAC[];
6452         SUBGOAL_THEN `d:real^M = c:real^M` (fun th -> REWRITE_TAC[th]) THEN
6453         REWRITE_TAC[CART_EQ] THEN ASM_MESON_TAC[]];
6454       ALL_TAC] THEN
6455     REPEAT STRIP_TAC THEN REWRITE_TAC[lemma1] THEN
6456     SUBGOAL_THEN
6457      `!s. s SUBSET 1..m
6458           ==> --(&1) pow CARD {i | i IN SUC m INSERT s /\ d$i < c$i} =
6459               (if (d:real^M)$(SUC m) < (c:real^M)$(SUC m) then -- &1 else &1) *
6460               --(&1) pow CARD {i | i IN s /\ d$i < c$i}`
6461      (fun th -> SIMP_TAC[th; IN_ELIM_THM]) THENL
6462      [X_GEN_TAC `s:num->bool` THEN DISCH_TAC THEN
6463       SUBGOAL_THEN `FINITE(s:num->bool)` ASSUME_TAC THENL
6464        [ASM_MESON_TAC[FINITE_NUMSEG; FINITE_SUBSET]; ALL_TAC] THEN
6465       COND_CASES_TAC THENL
6466        [ASM_SIMP_TAC[CARD_CLAUSES; FINITE_RESTRICT; SET_RULE
6467          `P a ==> {x | x IN a INSERT s /\ P x} =
6468                   a INSERT {x | x IN s /\ P x}`] THEN
6469         REWRITE_TAC[IN_ELIM_THM] THEN COND_CASES_TAC THEN
6470         ASM_REWRITE_TAC[real_pow] THEN
6471         SUBGOAL_THEN `~(SUC m IN 1..m)` (fun th -> ASM SET_TAC[th]) THEN
6472         REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC;
6473         ASM_SIMP_TAC[REAL_MUL_LID; SET_RULE
6474          `~(P a) ==> {x | x IN a INSERT s /\ P x} = {x | x IN s /\ P x}`]];
6475       ALL_TAC] THEN
6476     MP_TAC(ISPECL
6477      [`f:real^M->real^N`; `a:real^M`; `d:real^M`; `(c:real^M)$SUC m`; `SUC m`]
6478          INTEGRAL_SPLIT_SIGNED) THEN
6479     ANTS_TAC THENL
6480      [ASM_MESON_TAC[ARITH_RULE `1 <= SUC n`; INTEGRABLE_ON_SUBINTERVAL;
6481                     SUBSET_UNIV];
6482       DISCH_THEN SUBST1_TAC] THEN
6483     REWRITE_TAC[VSUM_LMUL; GSYM VECTOR_MUL_ASSOC] THEN
6484     BINOP_TAC THENL [ALL_TAC; AP_TERM_TAC] THENL
6485      [FIRST_X_ASSUM(MP_TAC o SPECL
6486        [`a:real^M`;
6487         `c:real^M`;
6488         `(lambda i. if i = SUC m then (c:real^M)$SUC m
6489                     else (d:real^M)$i):real^M`]);
6490       FIRST_X_ASSUM(MP_TAC o SPECL
6491        [`(lambda i. if i = SUC m
6492                     then min ((d:real^M)$SUC m) ((c:real^M)$SUC m)
6493                     else (a:real^M)$i):real^M`;
6494         `(lambda i. if i = SUC m
6495                     then max ((d:real^M)$SUC m) ((c:real^M)$SUC m)
6496                     else (c:real^M)$i):real^M`;
6497         `(lambda i. if i = SUC m
6498                     then max ((d:real^M)$SUC m) ((c:real^M)$SUC m)
6499                     else d$i):real^M`])] THEN
6500     (ANTS_TAC THENL
6501       [ASM_REWRITE_TAC[] THEN
6502        CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
6503        CONJ_TAC THENL
6504         [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
6505          SUBGOAL_THEN `1 <= i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
6506          ASM_SIMP_TAC[LAMBDA_BETA] THEN
6507          COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
6508          FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC;
6509          ALL_TAC] THEN
6510        CONJ_TAC THENL
6511         [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
6512          SUBGOAL_THEN `1 <= i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
6513          ASM_SIMP_TAC[LAMBDA_BETA] THEN
6514          COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
6515          ASM_MESON_TAC[ARITH_RULE `m < i <=> i = SUC m \/ SUC m < i`];
6516          X_GEN_TAC `i:num` THEN STRIP_TAC THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN
6517          COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN TRY REAL_ARITH_TAC THEN
6518          FIRST_X_ASSUM SUBST_ALL_TAC THEN ASM_REWRITE_TAC[] THEN
6519          ASM_MESON_TAC[]];
6520        DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
6521        X_GEN_TAC `s:num->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN
6522        DISCH_TAC THEN BINOP_TAC THENL
6523         [AP_TERM_TAC THEN AP_TERM_TAC THEN
6524          REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
6525          X_GEN_TAC `i:num` THEN
6526          ASM_CASES_TAC `(i:num) IN s` THEN ASM_REWRITE_TAC[] THEN
6527          SUBGOAL_THEN `i IN 1..m` MP_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
6528          REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN
6529          SUBGOAL_THEN `i <= dimindex(:M)` ASSUME_TAC THENL
6530           [ASM_ARITH_TAC; ALL_TAC] THEN
6531          ASM_SIMP_TAC[LAMBDA_BETA] THEN
6532          COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC;
6533          AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
6534          REWRITE_TAC[CONS_11; PAIR_EQ] THEN
6535          SIMP_TAC[CART_EQ; LAMBDA_BETA; AND_FORALL_THM] THEN
6536          X_GEN_TAC `i:num` THEN
6537          ASM_CASES_TAC `1 <= i /\ i <= dimindex(:M)` THEN
6538          ASM_REWRITE_TAC[] THEN
6539          ASM_CASES_TAC `(i:num) IN s` THEN ASM_REWRITE_TAC[IN_INSERT] THEN
6540          COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN TRY REAL_ARITH_TAC THEN
6541          SUBGOAL_THEN `~(SUC m IN 1..m)` (fun th -> ASM SET_TAC[th]) THEN
6542          REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC]])) in
6543   REWRITE_TAC[IN_INTERVAL] THEN REPEAT STRIP_TAC THEN
6544   MP_TAC(ISPECL
6545    [`\x. if x IN interval[a,b] then (f:real^M->real^N) x else vec 0`;
6546     `dimindex(:M)`; `a:real^M`; `c:real^M`; `d:real^M`]
6547    lemma2) THEN
6548   ASM_SIMP_TAC[LTE_ANTISYM; INTEGRABLE_RESTRICT_UNIV; LE_REFL] THEN
6549   MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THENL
6550    [ALL_TAC;
6551     MATCH_MP_TAC VSUM_EQ THEN X_GEN_TAC `s:num->bool` THEN
6552     REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN AP_TERM_TAC] THEN
6553   MATCH_MP_TAC INTEGRAL_EQ THEN ASM_REWRITE_TAC[] THEN
6554   MATCH_MP_TAC(SET_RULE
6555    `i SUBSET j ==> !x. x IN i ==> (if x IN j then f x else b) = f x`) THEN
6556   ASM_SIMP_TAC[SUBSET_INTERVAL; REAL_LE_REFL; LAMBDA_BETA] THEN
6557   DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
6558   REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN
6559   ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;
6560
6561 let INTEGRAL_INTERVALS_DIFF_INCLUSION_EXCLUSION = prove
6562  (`!f:real^M->real^N a b c d.
6563         f integrable_on interval[a,b] /\
6564         c IN interval[a,b] /\ d IN interval[a,b]
6565         ==> integral(interval[a,d]) f - integral(interval[a,c]) f =
6566                 vsum {s | ~(s = {}) /\ s SUBSET 1..dimindex(:M)}
6567                     (\s. --(&1) pow CARD {i | i IN s /\ d$i < c$i} %
6568                          integral
6569                           (interval[(lambda i. if i IN s
6570                                                then min (c$i) (d$i)
6571                                                else (a:real^M)$i),
6572                                     (lambda i. if i IN s
6573                                                then max (c$i) (d$i)
6574                                                else c$i)]) f)`,
6575   REPEAT GEN_TAC THEN DISCH_TAC THEN
6576   FIRST_ASSUM(SUBST1_TAC o
6577    MATCH_MP INTEGRAL_INTERVALS_INCLUSION_EXCLUSION) THEN
6578   REWRITE_TAC[SET_RULE `{s | ~(s = a) /\ P s} = {s | P s} DELETE a`] THEN
6579   SIMP_TAC[VSUM_DELETE; FINITE_POWERSET; FINITE_NUMSEG; EMPTY_SUBSET;
6580            IN_ELIM_THM] THEN
6581   REWRITE_TAC[NOT_IN_EMPTY; EMPTY_GSPEC; CARD_CLAUSES; LAMBDA_ETA] THEN
6582   REWRITE_TAC[real_pow; VECTOR_MUL_LID]);;
6583
6584 let INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_RIGHT = prove
6585  (`!f:real^M->real^N a b c.
6586         f integrable_on interval[a,b] /\ c IN interval[a,b]
6587         ==> integral(interval[a,c]) f =
6588                 vsum {s | s SUBSET 1..dimindex (:M)}
6589                      (\s. --(&1) pow CARD s %
6590                           integral
6591                            (interval[(lambda i. if i IN s then c$i else a$i),
6592                                      b])
6593                            f)`,
6594   REPEAT STRIP_TAC THEN MP_TAC(ISPECL
6595    [`f:real^M->real^N`; `a:real^M`; `b:real^M`; `b:real^M`; `c:real^M`]
6596         INTEGRAL_INTERVALS_INCLUSION_EXCLUSION) THEN
6597   ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN ANTS_TAC THENL
6598    [ASM_MESON_TAC[ENDS_IN_INTERVAL; MEMBER_NOT_EMPTY]; ALL_TAC] THEN
6599   DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
6600   X_GEN_TAC `s:num->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN
6601   ASM_CASES_TAC `?k. k IN s /\ (c:real^M)$k = (b:real^M)$k` THENL
6602    [FIRST_X_ASSUM(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN
6603     SUBGOAL_THEN `1 <= k /\ k <= dimindex(:M)` STRIP_ASSUME_TAC THENL
6604      [ASM_MESON_TAC[IN_NUMSEG; SUBSET]; ALL_TAC] THEN
6605     MATCH_MP_TAC(MESON[] `a:real^N = vec 0 /\ b = vec 0 ==> a = b`) THEN
6606     CONJ_TAC THEN REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ2_TAC THEN
6607     MATCH_MP_TAC INTEGRAL_NULL THEN REWRITE_TAC[CONTENT_EQ_0] THEN
6608     EXISTS_TAC `k:num` THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC;
6609     ALL_TAC] THEN
6610   RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN BINOP_TAC THENL
6611    [AP_TERM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
6612     ASM_MESON_TAC[REAL_LT_LE; SUBSET; IN_NUMSEG];
6613     AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
6614     AP_THM_TAC THEN AP_TERM_TAC THEN
6615     ASM_SIMP_TAC[CART_EQ; PAIR_EQ; LAMBDA_BETA] THEN
6616     CONJ_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
6617     FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
6618     REAL_ARITH_TAC]);;
6619
6620 let INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_LEFT = prove
6621  (`!f:real^M->real^N a b c.
6622         f integrable_on interval[a,b] /\ c IN interval[a,b]
6623         ==> integral(interval[c,b]) f =
6624                 vsum {s | s SUBSET 1..dimindex (:M)}
6625                      (\s. --(&1) pow CARD s %
6626                           integral
6627                            (interval[a,(lambda i. if i IN s then c$i else b$i)])
6628                            f)`,
6629   REPEAT STRIP_TAC THEN MP_TAC(ISPECL
6630    [`\x. (f:real^M->real^N) (--x)`;
6631     `--b:real^M`;
6632     `--a:real^M`;
6633     `--c:real^M`]
6634         INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_RIGHT) THEN
6635   REWRITE_TAC[REAL_ARITH `min (--a) (--b) = --(max a b)`;
6636               REAL_ARITH `max (--a) (--b) = --(min a b)`;
6637               VECTOR_NEG_COMPONENT] THEN
6638   SUBGOAL_THEN
6639    `!P x y. (lambda i. if P i then --(x i) else --(y i)):real^M =
6640             --(lambda i. if P i then x i else y i)`
6641    (fun th -> REWRITE_TAC[th])
6642   THENL
6643    [SIMP_TAC[CART_EQ; VECTOR_NEG_COMPONENT; LAMBDA_BETA] THEN MESON_TAC[];
6644     ALL_TAC] THEN
6645   ASM_REWRITE_TAC[INTEGRAL_REFLECT; INTEGRABLE_REFLECT;
6646                   IN_INTERVAL_REFLECT]);;
6647
6648 let HAS_INTEGRAL_REFLECT_GEN = prove
6649  (`!f:real^M->real^N i s.
6650      ((\x. f(--x)) has_integral i) s <=> (f has_integral i) (IMAGE (--) s)`,
6651   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[HAS_INTEGRAL_ALT] THEN
6652   REWRITE_TAC[] THEN
6653   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
6654    [GSYM INTEGRABLE_REFLECT; GSYM INTEGRAL_REFLECT] THEN
6655   REWRITE_TAC[IN_IMAGE; VECTOR_NEG_NEG] THEN
6656   REWRITE_TAC[UNWIND_THM1; VECTOR_ARITH `x:real^N = --y <=> --x = y`] THEN
6657   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [MESON[VECTOR_NEG_NEG]
6658    `(!x:real^N y:real^N. P x y) <=> (!x y. P (--y) (--x))`] THEN
6659   REWRITE_TAC[VECTOR_NEG_NEG] THEN
6660   REWRITE_TAC[SUBSET; IN_BALL_0; GSYM REFLECT_INTERVAL; IN_IMAGE] THEN
6661   REWRITE_TAC[UNWIND_THM1; VECTOR_ARITH `x:real^N = --y <=> --x = y`] THEN
6662   ONCE_REWRITE_TAC[GSYM NORM_NEG] THEN
6663   REWRITE_TAC[MESON[VECTOR_NEG_NEG] `(!x:real^N. P (--x)) <=> (!x. P x)`] THEN
6664   REWRITE_TAC[NORM_NEG]);;
6665
6666 let INTEGRABLE_REFLECT_GEN = prove
6667  (`!f:real^M->real^N s.
6668         (\x. f(--x)) integrable_on s <=> f integrable_on (IMAGE (--) s)`,
6669   REWRITE_TAC[integrable_on; HAS_INTEGRAL_REFLECT_GEN]);;
6670
6671 let INTEGRAL_REFLECT_GEN = prove
6672  (`!f:real^M->real^N s.
6673         integral s (\x. f(--x)) = integral (IMAGE (--) s) f`,
6674    REWRITE_TAC[integral; HAS_INTEGRAL_REFLECT_GEN]);;
6675
6676 (* ------------------------------------------------------------------------- *)
6677 (* A straddling criterion for integrability.                                 *)
6678 (* ------------------------------------------------------------------------- *)
6679
6680 let INTEGRABLE_STRADDLE_INTERVAL = prove
6681  (`!f:real^N->real^1 a b.
6682         (!e. &0 < e
6683              ==> ?g h i j. (g has_integral i) (interval[a,b]) /\
6684                            (h has_integral j) (interval[a,b]) /\
6685                            norm(i - j) < e /\
6686                            !x. x IN interval[a,b]
6687                                ==> drop(g x) <= drop(f x) /\
6688                                    drop(f x) <= drop(h x))
6689         ==> f integrable_on interval[a,b]`,
6690   REPEAT STRIP_TAC THEN REWRITE_TAC[INTEGRABLE_CAUCHY] THEN
6691   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6692   FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN
6693   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH; LEFT_IMP_EXISTS_THM] THEN
6694   MAP_EVERY X_GEN_TAC
6695    [`g:real^N->real^1`; `h:real^N->real^1`; `i:real^1`; `j:real^1`] THEN
6696   REWRITE_TAC[has_integral] THEN REWRITE_TAC[IMP_CONJ] THEN
6697   DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
6698   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
6699   DISCH_THEN(X_CHOOSE_THEN `d1:real^N->real^N->bool` STRIP_ASSUME_TAC) THEN
6700   DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
6701   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
6702   DISCH_THEN(X_CHOOSE_THEN `d2:real^N->real^N->bool` STRIP_ASSUME_TAC) THEN
6703   DISCH_TAC THEN DISCH_TAC THEN
6704   EXISTS_TAC `(\x. d1 x INTER d2 x):real^N->real^N->bool` THEN
6705   ASM_SIMP_TAC[GAUGE_INTER; FINE_INTER] THEN
6706   MAP_EVERY X_GEN_TAC
6707    [`p1:(real^N#(real^N->bool))->bool`;
6708     `p2:(real^N#(real^N->bool))->bool`] THEN
6709   REPEAT STRIP_TAC THEN
6710   REPEAT(FIRST_X_ASSUM(fun th ->
6711    MP_TAC(SPEC `p1:(real^N#(real^N->bool))->bool` th) THEN
6712    MP_TAC(SPEC `p2:(real^N#(real^N->bool))->bool` th))) THEN
6713   EVERY_ASSUM(fun th -> try ASSUME_TAC(MATCH_MP TAGGED_DIVISION_OF_FINITE th)
6714                         with Failure _ -> ALL_TAC) THEN
6715   ASM_SIMP_TAC[VSUM_REAL] THEN REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM] THEN
6716   SUBST1_TAC(SYM(ISPEC `i:real^1` (CONJUNCT1 LIFT_DROP))) THEN
6717   SUBST1_TAC(SYM(ISPEC `j:real^1` (CONJUNCT1 LIFT_DROP))) THEN
6718   REWRITE_TAC[GSYM LIFT_SUB; DROP_CMUL; NORM_LIFT] THEN
6719   MATCH_MP_TAC(REAL_ARITH
6720    `g1 - h2 <= f1 - f2 /\ f1 - f2 <= h1 - g2 /\
6721     abs(i - j) < e / &3
6722     ==> abs(g2 - i) < e / &3
6723         ==> abs(g1 - i) < e / &3
6724             ==> abs(h2 - j) < e / &3
6725                 ==> abs(h1 - j) < e / &3
6726                     ==> abs(f1 - f2) < e`) THEN
6727   ASM_REWRITE_TAC[GSYM DROP_SUB; GSYM NORM_LIFT; LIFT_DROP] THEN CONJ_TAC THEN
6728   MATCH_MP_TAC(REAL_ARITH `x <= x' /\ y' <= y ==> x - y <= x' - y'`) THEN
6729   CONJ_TAC THEN MATCH_MP_TAC SUM_LE THEN
6730   REWRITE_TAC[FORALL_PAIR_THM] THEN REPEAT STRIP_TAC THEN
6731   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_LMUL THEN
6732   ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE; SUBSET]);;
6733
6734 let INTEGRABLE_STRADDLE = prove
6735  (`!f:real^N->real^1 s.
6736         (!e. &0 < e
6737              ==> ?g h i j. (g has_integral i) s /\
6738                            (h has_integral j) s /\
6739                            norm(i - j) < e /\
6740                            !x. x IN s
6741                                ==> drop(g x) <= drop(f x) /\
6742                                    drop(f x) <= drop(h x))
6743         ==> f integrable_on s`,
6744   let lemma = prove
6745    (`&0 <= drop x /\ drop x <= drop y ==> norm x <= norm y`,
6746     REWRITE_TAC[NORM_REAL; GSYM drop] THEN REAL_ARITH_TAC) in
6747   REPEAT STRIP_TAC THEN
6748   SUBGOAL_THEN
6749    `!a b. (\x. if x IN s then (f:real^N->real^1) x else vec 0)
6750           integrable_on interval[a,b]`
6751   ASSUME_TAC THENL
6752    [RULE_ASSUM_TAC(REWRITE_RULE[HAS_INTEGRAL_ALT]) THEN
6753     MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
6754     MATCH_MP_TAC INTEGRABLE_STRADDLE_INTERVAL THEN
6755     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6756     FIRST_X_ASSUM(MP_TAC o SPEC `e / &4`) THEN
6757     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
6758     REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
6759     MAP_EVERY X_GEN_TAC
6760      [`g:real^N->real^1`; `h:real^N->real^1`; `i:real^1`; `j:real^1`] THEN
6761     REWRITE_TAC[GSYM CONJ_ASSOC] THEN
6762     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6763     DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `e / &4`) MP_TAC) THEN
6764     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6765     DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `e / &4`) STRIP_ASSUME_TAC) THEN
6766     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
6767     DISCH_THEN(X_CHOOSE_THEN `B2:real`
6768      (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "H"))) THEN
6769     DISCH_THEN(X_CHOOSE_THEN `B1:real`
6770      (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "G"))) THEN
6771     MAP_EVERY EXISTS_TAC
6772      [`\x. if x IN s then (g:real^N->real^1) x else vec 0`;
6773       `\x. if x IN s then (h:real^N->real^1) x else vec 0`;
6774       `integral(interval[a:real^N,b])
6775          (\x. if x IN s then (g:real^N->real^1) x else vec 0:real^1)`;
6776       `integral(interval[a:real^N,b])
6777          (\x. if x IN s then (h:real^N->real^1) x else vec 0:real^1)`] THEN
6778     ASM_SIMP_TAC[INTEGRABLE_INTEGRAL] THEN
6779     CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LE_REFL]] THEN
6780     ABBREV_TAC `c:real^N = lambda i. min ((a:real^N)$i) (--(max B1 B2))` THEN
6781     ABBREV_TAC `d:real^N = lambda i. max ((b:real^N)$i) (max B1 B2)` THEN
6782     REMOVE_THEN "H" (MP_TAC o SPECL [`c:real^N`; `d:real^N`]) THEN
6783     REMOVE_THEN "G" (MP_TAC o SPECL [`c:real^N`; `d:real^N`]) THEN
6784     MATCH_MP_TAC(TAUT
6785         `(a /\ c) /\ (b /\ d ==> e) ==> (a ==> b) ==> (c ==> d) ==> e`) THEN
6786     CONJ_TAC THENL
6787      [CONJ_TAC THEN MAP_EVERY EXPAND_TAC ["c"; "d"] THEN
6788       SIMP_TAC[SUBSET; IN_BALL; IN_INTERVAL; LAMBDA_BETA] THEN
6789       GEN_TAC THEN REWRITE_TAC[NORM_ARITH `dist(vec 0,x) = norm x`] THEN
6790       DISCH_TAC THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
6791       MATCH_MP_TAC(REAL_ARITH
6792         `abs(x) <= B ==> min a (--B) <= x /\ x <= max b B`) THEN
6793       MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^N)` THEN
6794       ASM_SIMP_TAC[REAL_LT_IMP_LE; COMPONENT_LE_NORM; REAL_LE_MAX];
6795       ALL_TAC] THEN
6796     MATCH_MP_TAC(NORM_ARITH
6797        `norm(i - j) < e / &4 /\
6798         norm(ah - ag) <= norm(ch - cg)
6799         ==> norm(cg - i) < e / &4 /\
6800             norm(ch - j) < e / &4
6801             ==> norm(ag - ah) < e`) THEN
6802     ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[GSYM INTEGRAL_SUB] THEN
6803     MATCH_MP_TAC lemma THEN CONJ_TAC THENL
6804      [MATCH_MP_TAC(INST_TYPE [`:N`,`:M`] HAS_INTEGRAL_DROP_POS) THEN
6805       MAP_EVERY EXISTS_TAC
6806        [`(\x. (if x IN s then h x else vec 0) - (if x IN s then g x else vec 0))
6807          :real^N->real^1`;
6808         `interval[a:real^N,b]`] THEN
6809       ASM_SIMP_TAC[INTEGRABLE_INTEGRAL; HAS_INTEGRAL_SUB] THEN
6810       ASM_SIMP_TAC[INTEGRABLE_SUB; INTEGRABLE_INTEGRAL] THEN
6811       REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
6812       ASM_SIMP_TAC[DROP_SUB; DROP_VEC; REAL_SUB_LE; REAL_POS] THEN
6813       ASM_MESON_TAC[REAL_LE_TRANS];
6814       ALL_TAC] THEN
6815     MATCH_MP_TAC(INST_TYPE [`:N`,`:M`] HAS_INTEGRAL_SUBSET_DROP_LE) THEN
6816     MAP_EVERY EXISTS_TAC
6817      [`(\x. (if x IN s then h x else vec 0) - (if x IN s then g x else vec 0))
6818        :real^N->real^1`;
6819       `interval[a:real^N,b]`; `interval[c:real^N,d]`] THEN
6820     ASM_SIMP_TAC[INTEGRABLE_SUB; INTEGRABLE_INTEGRAL] THEN CONJ_TAC THENL
6821      [REWRITE_TAC[SUBSET_INTERVAL] THEN DISCH_TAC THEN
6822       MAP_EVERY EXPAND_TAC ["c"; "d"] THEN
6823       SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC;
6824       ALL_TAC] THEN
6825     REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
6826     ASM_SIMP_TAC[DROP_SUB; DROP_VEC; REAL_SUB_LE; REAL_POS] THEN
6827     ASM_MESON_TAC[REAL_LE_TRANS];
6828     ALL_TAC] THEN
6829   ONCE_REWRITE_TAC[INTEGRABLE_ALT] THEN ASM_REWRITE_TAC[] THEN
6830   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6831   FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN
6832   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
6833   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; HAS_INTEGRAL_ALT] THEN
6834   MAP_EVERY X_GEN_TAC
6835    [`g:real^N->real^1`; `h:real^N->real^1`; `i:real^1`; `j:real^1`] THEN
6836   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6837   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
6838   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `e / &3`)) THEN
6839   FIRST_X_ASSUM(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `e / &3`)) THEN
6840   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
6841   DISCH_THEN(X_CHOOSE_THEN `B1:real`
6842     (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "G"))) THEN
6843   DISCH_THEN(X_CHOOSE_THEN `B2:real`
6844     (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "H"))) THEN
6845   EXISTS_TAC `max B1 B2` THEN
6846   ASM_REWRITE_TAC[REAL_LT_MAX; BALL_MAX_UNION; UNION_SUBSET] THEN
6847   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `c:real^N`; `d:real^N`] THEN
6848   STRIP_TAC THEN REWRITE_TAC[ABS_DROP; DROP_SUB] THEN
6849   MATCH_MP_TAC(REAL_ARITH
6850    `!ga gc ha hc i j.
6851         ga <= fa /\ fa <= ha /\
6852         gc <= fc /\ fc <= hc /\
6853         abs(ga - i) < e / &3 /\
6854         abs(gc - i) < e / &3 /\
6855         abs(ha - j) < e / &3 /\
6856         abs(hc - j) < e / &3 /\
6857         abs(i - j) < e / &3
6858         ==> abs(fa - fc) < e`) THEN
6859   MAP_EVERY EXISTS_TAC
6860    [`drop(integral(interval[a:real^N,b]) (\x. if x IN s then g x else vec 0))`;
6861     `drop(integral(interval[c:real^N,d]) (\x. if x IN s then g x else vec 0))`;
6862     `drop(integral(interval[a:real^N,b]) (\x. if x IN s then h x else vec 0))`;
6863     `drop(integral(interval[c:real^N,d]) (\x. if x IN s then h x else vec 0))`;
6864     `drop i`; `drop j`] THEN
6865   REWRITE_TAC[GSYM DROP_SUB; GSYM ABS_DROP] THEN ASM_SIMP_TAC[] THEN
6866   REPEAT CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN
6867   ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
6868   COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_LE_REFL]);;
6869
6870 let HAS_INTEGRAL_STRADDLE_NULL = prove
6871  (`!f g:real^N->real^1 s.
6872         (!x. x IN s ==> &0 <= drop(f x) /\ drop(f x) <= drop(g x)) /\
6873         (g has_integral (vec 0)) s
6874         ==> (f has_integral (vec 0)) s`,
6875   REPEAT STRIP_TAC THEN REWRITE_TAC[HAS_INTEGRAL_INTEGRABLE_INTEGRAL] THEN
6876   MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6877    [MATCH_MP_TAC INTEGRABLE_STRADDLE THEN
6878     GEN_TAC THEN DISCH_TAC THEN
6879     MAP_EVERY EXISTS_TAC
6880      [`(\x. vec 0):real^N->real^1`; `g:real^N->real^1`;
6881       `vec 0:real^1`; `vec 0:real^1`] THEN
6882     ASM_REWRITE_TAC[DROP_VEC; HAS_INTEGRAL_0; VECTOR_SUB_REFL; NORM_0];
6883     DISCH_TAC THEN ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN
6884     REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
6885      [MATCH_MP_TAC(ISPECL [`f:real^N->real^1`; `g:real^N->real^1`]
6886         HAS_INTEGRAL_DROP_LE);
6887       MATCH_MP_TAC(ISPECL [`(\x. vec 0):real^N->real^1`; `f:real^N->real^1`]
6888         HAS_INTEGRAL_DROP_LE)] THEN
6889     EXISTS_TAC `s:real^N->bool` THEN
6890     ASM_SIMP_TAC[GSYM HAS_INTEGRAL_INTEGRAL; DROP_VEC; HAS_INTEGRAL_0]]);;
6891
6892 (* ------------------------------------------------------------------------- *)
6893 (* Adding integrals over several sets.                                       *)
6894 (* ------------------------------------------------------------------------- *)
6895
6896 let HAS_INTEGRAL_UNION = prove
6897  (`!f:real^M->real^N i j s t.
6898         (f has_integral i) s /\ (f has_integral j) t /\ negligible(s INTER t)
6899         ==> (f has_integral (i + j)) (s UNION t)`,
6900   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
6901   REWRITE_TAC[CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
6902   MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN
6903   EXISTS_TAC `(\x. if x IN (s INTER t) then &2 % f(x)
6904                    else if x IN (s UNION t) then f(x)
6905                    else vec 0):real^M->real^N` THEN
6906   EXISTS_TAC `s INTER t:real^M->bool` THEN
6907   ASM_REWRITE_TAC[IN_DIFF; IN_UNION; IN_INTER; IN_UNIV] THEN
6908   CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
6909   FIRST_X_ASSUM(MP_TAC o MATCH_MP HAS_INTEGRAL_ADD) THEN
6910   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
6911   REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN
6912   MAP_EVERY ASM_CASES_TAC [`(x:real^M) IN s`; `(x:real^M) IN t`] THEN
6913   ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);;
6914
6915 let INTEGRAL_UNION = prove
6916  (`!f:real^M->real^N s t.
6917         f integrable_on s /\ f integrable_on t /\ negligible(s INTER t)
6918         ==> integral (s UNION t) f = integral s f + integral t f`,
6919   REPEAT STRIP_TAC THEN
6920   MATCH_MP_TAC INTEGRAL_UNIQUE THEN
6921   MATCH_MP_TAC HAS_INTEGRAL_UNION THEN
6922   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);;
6923
6924 let HAS_INTEGRAL_UNIONS = prove
6925  (`!f:real^M->real^N i t.
6926         FINITE t /\
6927         (!s. s IN t ==> (f has_integral (i s)) s) /\
6928         (!s s'. s IN t /\ s' IN t /\ ~(s = s') ==> negligible(s INTER s'))
6929         ==> (f has_integral (vsum t i)) (UNIONS t)`,
6930   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
6931   REWRITE_TAC[CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
6932   FIRST_ASSUM(MP_TAC o MATCH_MP HAS_INTEGRAL_VSUM) THEN REWRITE_TAC[] THEN
6933   MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
6934                 HAS_INTEGRAL_SPIKE) THEN
6935   EXISTS_TAC
6936    `UNIONS (IMAGE (\(a,b). a INTER b :real^M->bool)
6937                   {a,b | a IN t /\ b IN {y | y IN t /\ ~(a = y)}})` THEN
6938   CONJ_TAC THENL
6939    [MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN CONJ_TAC THENL
6940      [MATCH_MP_TAC FINITE_IMAGE THEN MATCH_MP_TAC FINITE_PRODUCT_DEPENDENT THEN
6941       ASM_SIMP_TAC[FINITE_RESTRICT];
6942       REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN
6943       ASM_SIMP_TAC[IN_ELIM_THM]];
6944     X_GEN_TAC `x:real^M` THEN REWRITE_TAC[IN_UNIV; IN_DIFF] THEN
6945     ASM_CASES_TAC `(x:real^M) IN UNIONS t` THEN ASM_REWRITE_TAC[] THENL
6946      [ALL_TAC;
6947       RULE_ASSUM_TAC(REWRITE_RULE[SET_RULE
6948        `~(x IN UNIONS t) <=> !s. s IN t ==> ~(x IN s)`]) THEN
6949       ASM_SIMP_TAC[VSUM_0]] THEN
6950     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_UNIONS]) THEN
6951     DISCH_THEN(X_CHOOSE_THEN `a:real^M->bool` STRIP_ASSUME_TAC) THEN
6952     REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE; EXISTS_PAIR_THM] THEN
6953     REWRITE_TAC[IN_ELIM_PAIR_THM; NOT_EXISTS_THM] THEN
6954     DISCH_THEN(MP_TAC o SPEC `a:real^M->bool`) THEN
6955     ASM_REWRITE_TAC[IN_ELIM_THM; IN_INTER] THEN
6956     ASM_SIMP_TAC[MESON[]
6957      `x IN a /\ a IN t
6958       ==> ((!b. ~((b IN t /\ ~(a = b)) /\ x IN b)) <=>
6959            (!b. b IN t ==> (x IN b <=> b = a)))`] THEN
6960     ASM_REWRITE_TAC[VSUM_DELTA]]);;
6961
6962 let HAS_INTEGRAL_DIFF = prove
6963  (`!f:real^M->real^N i j s t.
6964     (f has_integral i) s /\
6965     (f has_integral j) t /\
6966     negligible (t DIFF s)
6967     ==> (f has_integral (i - j)) (s DIFF t)`,
6968   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
6969   REWRITE_TAC[CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
6970   MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN
6971   EXISTS_TAC `(\x. if x IN (t DIFF s) then --(f x)
6972                    else if x IN (s DIFF t) then f x
6973                    else vec 0):real^M->real^N` THEN
6974   EXISTS_TAC `t DIFF s:real^M->bool` THEN
6975   ASM_REWRITE_TAC[IN_DIFF; IN_UNION; IN_INTER; IN_UNIV] THEN
6976   CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
6977   FIRST_X_ASSUM(MP_TAC o MATCH_MP HAS_INTEGRAL_SUB) THEN
6978   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
6979   REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN
6980   MAP_EVERY ASM_CASES_TAC [`(x:real^M) IN s`; `(x:real^M) IN t`] THEN
6981   ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);;
6982
6983 let INTEGRAL_DIFF = prove
6984  (`!f:real^M->real^N s t.
6985         f integrable_on s /\ f integrable_on t /\ negligible(t DIFF s)
6986         ==> integral (s DIFF t) f = integral s f - integral t f`,
6987   REPEAT STRIP_TAC THEN
6988   MATCH_MP_TAC INTEGRAL_UNIQUE THEN
6989   MATCH_MP_TAC HAS_INTEGRAL_DIFF THEN
6990   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);;
6991
6992 (* ------------------------------------------------------------------------- *)
6993 (* In particular adding integrals over a division, maybe not of an interval. *)
6994 (* ------------------------------------------------------------------------- *)
6995
6996 let HAS_INTEGRAL_COMBINE_DIVISION = prove
6997  (`!f:real^M->real^N s d i.
6998         d division_of s /\
6999         (!k. k IN d ==> (f has_integral (i k)) k)
7000         ==> (f has_integral (vsum d i)) s`,
7001   REPEAT STRIP_TAC THEN
7002   FIRST_ASSUM(SUBST1_TAC o SYM o last o CONJUNCTS o
7003               GEN_REWRITE_RULE I [division_of]) THEN
7004   MATCH_MP_TAC HAS_INTEGRAL_UNIONS THEN ASM_REWRITE_TAC[] THEN
7005   CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_FINITE]; ALL_TAC] THEN
7006   MAP_EVERY X_GEN_TAC [`k1:real^M->bool`; `k2:real^M->bool`] THEN
7007   STRIP_TAC THEN
7008   SUBGOAL_THEN `?u v:real^M x y:real^M.
7009                 k1 = interval[u,v] /\ k2 = interval[x,y]`
7010    (REPEAT_TCL CHOOSE_THEN (CONJUNCTS_THEN SUBST_ALL_TAC))
7011   THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
7012   FIRST_ASSUM(MP_TAC o el 2 o CONJUNCTS o
7013               GEN_REWRITE_RULE I [division_of]) THEN
7014   DISCH_THEN(MP_TAC o SPECL
7015    [`interval[u:real^M,v]`; `interval[x:real^M,y]`]) THEN
7016   ASM_REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN DISCH_TAC THEN
7017   MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN
7018   EXISTS_TAC `(interval[u,v:real^M] DIFF interval(u,v)) UNION
7019               (interval[x,y] DIFF interval(x,y))` THEN
7020   SIMP_TAC[NEGLIGIBLE_FRONTIER_INTERVAL; NEGLIGIBLE_UNION] THEN
7021   ASM SET_TAC[]);;
7022
7023 let INTEGRAL_COMBINE_DIVISION_BOTTOMUP = prove
7024  (`!f:real^M->real^N d s.
7025         d division_of s /\ (!k. k IN d ==> f integrable_on k)
7026         ==> integral s f = vsum d (\i. integral i f)`,
7027   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
7028   MATCH_MP_TAC HAS_INTEGRAL_COMBINE_DIVISION THEN
7029   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);;
7030
7031 let HAS_INTEGRAL_COMBINE_DIVISION_TOPDOWN = prove
7032  (`!f:real^M->real^N s d k.
7033         f integrable_on s /\ d division_of k /\ k SUBSET s
7034         ==> (f has_integral (vsum d (\i. integral i f))) k`,
7035   REPEAT STRIP_TAC THEN
7036   MATCH_MP_TAC HAS_INTEGRAL_COMBINE_DIVISION THEN
7037   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL] THEN
7038   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
7039   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
7040   EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN
7041   ASM_MESON_TAC[division_of; SUBSET_TRANS]);;
7042
7043 let INTEGRAL_COMBINE_DIVISION_TOPDOWN = prove
7044  (`!f:real^M->real^N d s.
7045         f integrable_on s /\ d division_of s
7046         ==> integral s f = vsum d (\i. integral i f)`,
7047   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
7048   MATCH_MP_TAC HAS_INTEGRAL_COMBINE_DIVISION_TOPDOWN THEN
7049   EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL]);;
7050
7051 let INTEGRABLE_COMBINE_DIVISION = prove
7052  (`!f d s.
7053         d division_of s /\ (!i. i IN d ==> f integrable_on i)
7054         ==> f integrable_on s`,
7055   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_COMBINE_DIVISION]);;
7056
7057 let INTEGRABLE_ON_SUBDIVISION = prove
7058  (`!f:real^M->real^N s d i.
7059         d division_of i /\
7060         f integrable_on s /\ i SUBSET s
7061         ==> f integrable_on i`,
7062   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_COMBINE_DIVISION THEN
7063   EXISTS_TAC `d:(real^M->bool)->bool` THEN ASM_REWRITE_TAC[] THEN
7064   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
7065   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
7066   ASM_MESON_TAC[division_of; UNIONS_SUBSET]);;
7067
7068 (* ------------------------------------------------------------------------- *)
7069 (* Also tagged divisions.                                                    *)
7070 (* ------------------------------------------------------------------------- *)
7071
7072 let HAS_INTEGRAL_COMBINE_TAGGED_DIVISION = prove
7073  (`!f:real^M->real^N s p i.
7074         p tagged_division_of s /\
7075         (!x k. (x,k) IN p ==> (f has_integral (i k)) k)
7076         ==> (f has_integral (vsum p (\(x,k). i k))) s`,
7077   REPEAT STRIP_TAC THEN
7078   SUBGOAL_THEN
7079    `!x:real^M k:real^M->bool.
7080       (x,k) IN p ==> ((f:real^M->real^N) has_integral integral k f) k`
7081   ASSUME_TAC THENL
7082    [ASM_MESON_TAC[HAS_INTEGRAL_INTEGRAL; integrable_on]; ALL_TAC] THEN
7083   SUBGOAL_THEN
7084    `((f:real^M->real^N) has_integral
7085      (vsum (IMAGE SND (p:real^M#(real^M->bool)->bool))
7086            (\k. integral k f))) s`
7087   MP_TAC THENL
7088    [MATCH_MP_TAC HAS_INTEGRAL_COMBINE_DIVISION THEN
7089     ASM_REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN
7090     ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION];
7091     ALL_TAC] THEN
7092   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN
7093   AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN
7094   MATCH_MP_TAC EQ_TRANS THEN
7095   EXISTS_TAC `vsum p (\(x:real^M,k:real^M->bool). integral k f:real^N)` THEN
7096   CONJ_TAC THENL
7097    [MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
7098     ASM_MESON_TAC[HAS_INTEGRAL_UNIQUE];
7099     MATCH_MP_TAC VSUM_OVER_TAGGED_DIVISION_LEMMA THEN
7100     EXISTS_TAC `s:real^M->bool` THEN ASM_SIMP_TAC[INTEGRAL_NULL]]);;
7101
7102 let INTEGRAL_COMBINE_TAGGED_DIVISION_BOTTOMUP = prove
7103  (`!f:real^M->real^N p a b.
7104         p tagged_division_of interval[a,b] /\
7105         (!x k. (x,k) IN p ==> f integrable_on k)
7106         ==> integral (interval[a,b]) f = vsum p (\(x,k). integral k f)`,
7107   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
7108   MATCH_MP_TAC HAS_INTEGRAL_COMBINE_TAGGED_DIVISION THEN
7109   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);;
7110
7111 let HAS_INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN = prove
7112  (`!f:real^M->real^N a b p.
7113         f integrable_on interval[a,b] /\ p tagged_division_of interval[a,b]
7114         ==> (f has_integral (vsum p (\(x,k). integral k f))) (interval[a,b])`,
7115   REPEAT STRIP_TAC THEN
7116   MATCH_MP_TAC HAS_INTEGRAL_COMBINE_TAGGED_DIVISION THEN
7117   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL] THEN
7118   ASM_MESON_TAC[INTEGRABLE_SUBINTERVAL; TAGGED_DIVISION_OF]);;
7119
7120 let INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN = prove
7121  (`!f:real^M->real^N a b p.
7122         f integrable_on interval[a,b] /\ p tagged_division_of interval[a,b]
7123         ==> integral (interval[a,b]) f = vsum p (\(x,k). integral k f)`,
7124   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
7125   MATCH_MP_TAC HAS_INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN THEN
7126   ASM_REWRITE_TAC[]);;
7127
7128 (* ------------------------------------------------------------------------- *)
7129 (* Henstock's lemma.                                                         *)
7130 (* ------------------------------------------------------------------------- *)
7131
7132 let HENSTOCK_LEMMA_PART1 = prove
7133  (`!f:real^M->real^N a b d e.
7134         f integrable_on interval[a,b] /\
7135         &0 < e /\ gauge d /\
7136         (!p. p tagged_division_of interval[a,b] /\ d fine p
7137              ==> norm (vsum p (\(x,k). content k % f x) -
7138                        integral(interval[a,b]) f) < e)
7139         ==> !p. p tagged_partial_division_of interval[a,b] /\ d fine p
7140                             ==> norm(vsum p (\(x,k). content k % f x -
7141                                                      integral k f)) <= e`,
7142   let lemma = prove
7143    (`(!k. &0 < k ==> x <= e + k) ==> x <= e`,
7144     DISCH_THEN(MP_TAC o SPEC `(x - e) / &2`) THEN REAL_ARITH_TAC) in
7145   REPEAT GEN_TAC THEN STRIP_TAC THEN GEN_TAC THEN STRIP_TAC THEN
7146   MATCH_MP_TAC lemma THEN X_GEN_TAC `k:real` THEN DISCH_TAC THEN
7147   MP_TAC(ISPECL
7148     [`IMAGE SND (p:(real^M#(real^M->bool))->bool)`; `a:real^M`; `b:real^M`]
7149     PARTIAL_DIVISION_EXTEND_INTERVAL) THEN
7150   ANTS_TAC THENL
7151    [CONJ_TAC THENL
7152      [ASM_MESON_TAC[PARTIAL_DIVISION_OF_TAGGED_DIVISION]; ALL_TAC] THEN
7153     REWRITE_TAC[SUBSET; FORALL_IN_UNIONS] THEN
7154     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
7155     REWRITE_TAC[FORALL_PAIR_THM] THEN
7156     ASM_MESON_TAC[tagged_partial_division_of; SUBSET];
7157     ALL_TAC] THEN
7158   SUBGOAL_THEN `FINITE(p:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
7159    [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
7160   DISCH_THEN(X_CHOOSE_THEN `q:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN
7161   FIRST_X_ASSUM(MP_TAC o MATCH_MP(SET_RULE
7162    `s SUBSET t ==> t = s UNION (t DIFF s)`)) THEN
7163   ABBREV_TAC `r = q DIFF IMAGE SND (p:(real^M#(real^M->bool))->bool)` THEN
7164   SUBGOAL_THEN `IMAGE SND (p:(real^M#(real^M->bool))->bool) INTER r = {}`
7165   ASSUME_TAC THENL [EXPAND_TAC "r" THEN SET_TAC[]; ALL_TAC] THEN
7166   DISCH_THEN SUBST_ALL_TAC THEN
7167   SUBGOAL_THEN `FINITE(r:(real^M->bool)->bool)` ASSUME_TAC THENL
7168    [ASM_MESON_TAC[division_of; FINITE_UNION]; ALL_TAC] THEN
7169   SUBGOAL_THEN
7170    `!i. i IN r
7171         ==> ?p. p tagged_division_of i /\ d fine p /\
7172                 norm(vsum p (\(x,j). content j % f x) -
7173                      integral i (f:real^M->real^N))
7174                 < k / (&(CARD(r:(real^M->bool)->bool)) + &1)`
7175   MP_TAC THENL
7176    [X_GEN_TAC `i:real^M->bool` THEN DISCH_TAC THEN
7177     SUBGOAL_THEN `(i:real^M->bool) SUBSET interval[a,b]` ASSUME_TAC THENL
7178      [ASM_MESON_TAC[division_of; IN_UNION]; ALL_TAC] THEN
7179     SUBGOAL_THEN `?u v:real^M. i = interval[u,v]`
7180      (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
7181     THENL [ASM_MESON_TAC[division_of; IN_UNION]; ALL_TAC] THEN
7182     SUBGOAL_THEN `(f:real^M->real^N) integrable_on interval[u,v]` MP_TAC THENL
7183      [ASM_MESON_TAC[INTEGRABLE_SUBINTERVAL]; ALL_TAC] THEN
7184     DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
7185     REWRITE_TAC[has_integral] THEN
7186     DISCH_THEN(MP_TAC o SPEC `k / (&(CARD(r:(real^M->bool)->bool)) + &1)`) THEN
7187     ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &n + &1`] THEN
7188     DISCH_THEN(X_CHOOSE_THEN `dd:real^M->real^M->bool` MP_TAC) THEN
7189     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
7190     MP_TAC(ISPECL [`d:real^M->real^M->bool`; `dd:real^M->real^M->bool`]
7191       GAUGE_INTER) THEN
7192     ASM_REWRITE_TAC[] THEN
7193     DISCH_THEN(MP_TAC o MATCH_MP FINE_DIVISION_EXISTS) THEN
7194     DISCH_THEN(MP_TAC o SPECL [`u:real^M`; `v:real^M`]) THEN
7195     REWRITE_TAC[FINE_INTER] THEN MESON_TAC[];
7196     ALL_TAC] THEN
7197   REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
7198   REWRITE_TAC[TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN
7199   REWRITE_TAC[FORALL_AND_THM] THEN
7200   DISCH_THEN(X_CHOOSE_THEN `q:(real^M->bool)->(real^M#(real^M->bool))->bool`
7201     STRIP_ASSUME_TAC) THEN
7202   FIRST_X_ASSUM(MP_TAC o SPEC
7203     `p UNION UNIONS {q (i:real^M->bool) | i IN r}
7204      :(real^M#(real^M->bool))->bool`) THEN
7205   ANTS_TAC THENL
7206    [CONJ_TAC THENL
7207      [ALL_TAC;
7208       MATCH_MP_TAC FINE_UNION THEN ASM_REWRITE_TAC[] THEN
7209       MATCH_MP_TAC FINE_UNIONS THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
7210       ASM_REWRITE_TAC[FORALL_IN_IMAGE]] THEN
7211     FIRST_ASSUM(SUBST1_TAC o SYM o last o CONJUNCTS o
7212                 GEN_REWRITE_RULE I [division_of]) THEN
7213     REWRITE_TAC[UNIONS_UNION] THEN
7214     MATCH_MP_TAC TAGGED_DIVISION_UNION THEN CONJ_TAC THENL
7215      [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF]; ALL_TAC] THEN
7216     CONJ_TAC THENL
7217      [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
7218       MATCH_MP_TAC TAGGED_DIVISION_UNIONS THEN
7219       FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
7220       SIMP_TAC[FINITE_UNION; IN_UNION] THEN ASM_MESON_TAC[];
7221       ALL_TAC] THEN
7222     MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
7223     REWRITE_TAC[OPEN_INTERIOR] THEN
7224     REPEAT(CONJ_TAC THENL
7225             [ASM_MESON_TAC[division_of; FINITE_UNION; IN_UNION]; ALL_TAC]) THEN
7226     X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
7227     ONCE_REWRITE_TAC[INTER_COMM] THEN
7228     MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
7229     REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM; OPEN_INTERIOR] THEN
7230     REPEAT(CONJ_TAC THENL
7231      [ASM_MESON_TAC[tagged_partial_division_of; FINITE_IMAGE]; ALL_TAC]) THEN
7232     REPEAT STRIP_TAC THEN
7233     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
7234     DISCH_THEN(MATCH_MP_TAC o el 2 o CONJUNCTS) THEN
7235     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
7236     REWRITE_TAC[NOT_IN_EMPTY; GSYM NOT_EXISTS_THM] THEN
7237     ASM_REWRITE_TAC[EXISTS_PAIR_THM; IN_IMAGE; IN_INTER; IN_UNION] THEN
7238     ASM_MESON_TAC[];
7239     ALL_TAC] THEN
7240   SUBGOAL_THEN
7241    `vsum (p UNION UNIONS {q i | i IN r}) (\(x,k). content k % f x) =
7242     vsum p (\(x:real^M,k:real^M->bool). content k % f x:real^N) +
7243     vsum (UNIONS {q i | (i:real^M->bool) IN r}) (\(x,k). content k % f x)`
7244   SUBST1_TAC THENL
7245    [MATCH_MP_TAC VSUM_UNION_NONZERO THEN ASM_REWRITE_TAC[] THEN
7246     ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
7247     ASM_SIMP_TAC[FINITE_UNIONS; FINITE_IMAGE; FORALL_IN_IMAGE] THEN
7248     CONJ_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF_FINITE]; ALL_TAC] THEN
7249     REWRITE_TAC[IN_INTER] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
7250     REWRITE_TAC[IMP_CONJ; FORALL_IN_UNIONS; FORALL_IN_IMAGE] THEN
7251     REWRITE_TAC[FORALL_PAIR_THM; FORALL_IN_IMAGE; RIGHT_FORALL_IMP_THM] THEN
7252     X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
7253     MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
7254     DISCH_TAC THEN
7255     SUBGOAL_THEN `(l:real^M->bool) SUBSET k` ASSUME_TAC THENL
7256      [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN DISCH_TAC THEN
7257     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
7258     DISCH_THEN(MP_TAC o SPECL [`k:real^M->bool`; `l:real^M->bool`] o
7259                el 2 o CONJUNCTS) THEN
7260     ANTS_TAC THENL
7261      [ASM_REWRITE_TAC[IN_UNION; IN_IMAGE; EXISTS_PAIR_THM] THEN
7262       CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
7263       DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
7264       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
7265       REWRITE_TAC[NOT_IN_EMPTY; GSYM NOT_EXISTS_THM] THEN
7266       ASM_REWRITE_TAC[EXISTS_PAIR_THM; IN_IMAGE; IN_INTER; IN_UNION] THEN
7267       ASM_MESON_TAC[];
7268       ALL_TAC] THEN
7269     ASM_SIMP_TAC[SUBSET_INTERIOR; SET_RULE `s SUBSET t ==> t INTER s = s`] THEN
7270     SUBGOAL_THEN `?u v:real^M. l = interval[u,v]`
7271      (fun th -> REPEAT_TCL CHOOSE_THEN SUBST1_TAC th THEN
7272                 SIMP_TAC[VECTOR_MUL_LZERO; GSYM CONTENT_EQ_0_INTERIOR]) THEN
7273     ASM_MESON_TAC[tagged_partial_division_of];
7274     ALL_TAC] THEN
7275   W(MP_TAC o PART_MATCH (lhand o rand) VSUM_UNIONS_NONZERO o
7276     rand o lhand o rand o lhand o lhand o snd) THEN
7277   ANTS_TAC THENL
7278    [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN
7279     REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; RIGHT_FORALL_IMP_THM] THEN
7280     CONJ_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF; IN_UNION]; ALL_TAC] THEN
7281     X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
7282     X_GEN_TAC `l:real^M->bool` THEN DISCH_TAC THEN
7283     DISCH_TAC THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
7284     MAP_EVERY X_GEN_TAC [`x:real^M`; `m:real^M->bool`] THEN
7285     DISCH_TAC THEN DISCH_TAC THEN
7286     REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN
7287     SUBGOAL_THEN `?u v:real^M. m = interval[u,v]`
7288      (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
7289     THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF; IN_UNION]; ALL_TAC] THEN
7290     REWRITE_TAC[CONTENT_EQ_0_INTERIOR] THEN
7291     MATCH_MP_TAC(SET_RULE `!t. s SUBSET t /\ t = {} ==> s = {}`) THEN
7292     EXISTS_TAC `interior(k INTER l:real^M->bool)` THEN CONJ_TAC THENL
7293      [MATCH_MP_TAC SUBSET_INTERIOR THEN REWRITE_TAC[SUBSET_INTER] THEN
7294       ASM_MESON_TAC[TAGGED_DIVISION_OF];
7295       ALL_TAC] THEN
7296     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
7297     REWRITE_TAC[INTERIOR_INTER] THEN
7298     DISCH_THEN(MATCH_MP_TAC o SPECL [`k:real^M->bool`; `l:real^M->bool`] o
7299                el 2 o CONJUNCTS) THEN
7300     REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM; IN_UNION] THEN ASM_MESON_TAC[];
7301     ALL_TAC] THEN
7302   DISCH_THEN SUBST1_TAC THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
7303   W(MP_TAC o PART_MATCH (lhand o rand) VSUM_IMAGE_NONZERO o
7304     rand o lhand o rand o lhand o lhand o snd) THEN
7305   ASM_REWRITE_TAC[o_DEF] THEN ANTS_TAC THENL
7306    [MAP_EVERY X_GEN_TAC [`k:real^M->bool`; `l:real^M->bool`] THEN
7307     STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ_0 THEN
7308     REWRITE_TAC[FORALL_PAIR_THM] THEN
7309     MAP_EVERY X_GEN_TAC [`x:real^M`; `m:real^M->bool`] THEN DISCH_TAC THEN
7310     MP_TAC(ASSUME `!i:real^M->bool. i IN r ==> q i tagged_division_of i`) THEN
7311     DISCH_THEN(fun th -> MP_TAC(SPEC `l:real^M->bool` th) THEN
7312                          ANTS_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN
7313                          MP_TAC(SPEC `k:real^M->bool` th) THEN
7314                          ANTS_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC]) THEN
7315     ASM_REWRITE_TAC[tagged_division_of] THEN ASM_MESON_TAC[];
7316     ALL_TAC] THEN
7317   DISCH_THEN SUBST1_TAC THEN
7318   SUBGOAL_THEN
7319    `vsum p (\(x,k). content k % (f:real^M->real^N) x - integral k f) =
7320     vsum p (\(x,k). content k % f x) - vsum p (\(x,k). integral k f)`
7321   SUBST1_TAC THENL [ASM_SIMP_TAC[GSYM VSUM_SUB; LAMBDA_PAIR_THM]; ALL_TAC] THEN
7322   MATCH_MP_TAC(NORM_ARITH
7323    `!ir. ip + ir = i /\
7324          norm(cr - ir) < k
7325          ==> norm((cp + cr) - i) < e ==> norm(cp - ip) <= e + k`) THEN
7326   EXISTS_TAC `vsum r (\k. integral k (f:real^M->real^N))` THEN CONJ_TAC THENL
7327    [MATCH_MP_TAC EQ_TRANS THEN
7328     EXISTS_TAC `vsum (IMAGE SND (p:(real^M#(real^M->bool))->bool) UNION r)
7329                      (\k. integral k (f:real^M->real^N))` THEN
7330     CONJ_TAC THENL
7331      [ALL_TAC; ASM_MESON_TAC[INTEGRAL_COMBINE_DIVISION_TOPDOWN]] THEN
7332     MATCH_MP_TAC EQ_TRANS THEN
7333     EXISTS_TAC `vsum (IMAGE SND (p:(real^M#(real^M->bool))->bool))
7334                      (\k. integral k (f:real^M->real^N)) +
7335                 vsum r (\k. integral k f)` THEN
7336     CONJ_TAC THENL
7337      [ALL_TAC;
7338       CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_UNION_NONZERO THEN
7339       ASM_SIMP_TAC[FINITE_IMAGE; NOT_IN_EMPTY]] THEN
7340     AP_THM_TAC THEN AP_TERM_TAC THEN
7341     SUBGOAL_THEN `(\(x:real^M,k). integral k (f:real^M->real^N)) =
7342                   (\k. integral k f) o SND`
7343     SUBST1_TAC THENL
7344      [SIMP_TAC[o_THM; FUN_EQ_THM; FORALL_PAIR_THM]; ALL_TAC] THEN
7345     CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_IMAGE_NONZERO THEN
7346     ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
7347     MAP_EVERY X_GEN_TAC
7348      [`x:real^M`; `l:real^M->bool`; `y:real^M`; `m:real^M->bool`] THEN
7349     REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
7350     DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
7351     FIRST_X_ASSUM(MP_TAC o
7352       GEN_REWRITE_RULE I [tagged_partial_division_of]) THEN
7353     DISCH_THEN(CONJUNCTS_THEN MP_TAC o CONJUNCT2) THEN
7354     DISCH_THEN(MP_TAC o SPECL
7355      [`x:real^M`; `l:real^M->bool`; `y:real^M`; `l:real^M->bool`]) THEN
7356     ASM_REWRITE_TAC[INTER_IDEMPOT] THEN DISCH_TAC THEN
7357     DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `l:real^M->bool`]) THEN
7358     ASM_REWRITE_TAC[] THEN
7359     DISCH_THEN(REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC o last o CONJUNCTS) THEN
7360     MATCH_MP_TAC INTEGRAL_UNIQUE THEN MATCH_MP_TAC HAS_INTEGRAL_NULL THEN
7361     ASM_REWRITE_TAC[CONTENT_EQ_0_INTERIOR];
7362     ALL_TAC] THEN
7363   ASM_SIMP_TAC[GSYM VSUM_SUB] THEN MATCH_MP_TAC REAL_LET_TRANS THEN
7364   EXISTS_TAC `sum (r:(real^M->bool)->bool) (\x. k / (&(CARD r) + &1))` THEN
7365   CONJ_TAC THENL
7366    [MATCH_MP_TAC VSUM_NORM_LE THEN ASM_SIMP_TAC[REAL_LT_IMP_LE];
7367     ASM_SIMP_TAC[SUM_CONST] THEN
7368     REWRITE_TAC[real_div; REAL_MUL_ASSOC] THEN
7369     SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &x + &1`] THEN
7370     REWRITE_TAC[REAL_ARITH `a * k < k * b <=> &0 < k * (b - a)`] THEN
7371     MATCH_MP_TAC REAL_LT_MUL THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC]);;
7372
7373 let HENSTOCK_LEMMA_PART2 = prove
7374  (`!f:real^M->real^N a b d e.
7375         f integrable_on interval[a,b] /\
7376         &0 < e /\ gauge d /\
7377         (!p. p tagged_division_of interval[a,b] /\ d fine p
7378              ==> norm (vsum p (\(x,k). content k % f x) -
7379                        integral(interval[a,b]) f) < e)
7380         ==> !p. p tagged_partial_division_of interval[a,b] /\ d fine p
7381                             ==> sum p (\(x,k). norm(content k % f x -
7382                                                     integral k f))
7383                                 <= &2 * &(dimindex(:N)) * e`,
7384   REPEAT STRIP_TAC THEN REWRITE_TAC[LAMBDA_PAIR] THEN
7385   MATCH_MP_TAC VSUM_NORM_ALLSUBSETS_BOUND THEN
7386   REWRITE_TAC[LAMBDA_PAIR_THM] THEN
7387   CONJ_TAC THENL [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
7388   X_GEN_TAC `q:(real^M#(real^M->bool))->bool` THEN DISCH_TAC THEN
7389   MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
7390     HENSTOCK_LEMMA_PART1) THEN
7391   MAP_EVERY EXISTS_TAC
7392    [`a:real^M`; `b:real^M`; `d:real^M->real^M->bool`] THEN
7393   ASM_REWRITE_TAC[] THEN
7394   ASM_MESON_TAC[FINE_SUBSET; TAGGED_PARTIAL_DIVISION_SUBSET]);;
7395
7396 let HENSTOCK_LEMMA = prove
7397  (`!f:real^M->real^N a b.
7398         f integrable_on interval[a,b]
7399         ==> !e. &0 < e
7400                 ==> ?d. gauge d /\
7401                         !p. p tagged_partial_division_of interval[a,b] /\
7402                             d fine p
7403                             ==> sum p (\(x,k). norm(content k % f x -
7404                                                     integral k f)) < e`,
7405   MP_TAC HENSTOCK_LEMMA_PART2 THEN
7406   REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
7407   DISCH_THEN(fun th -> STRIP_TAC THEN X_GEN_TAC `e:real` THEN
7408                        STRIP_TAC THEN MP_TAC th) THEN
7409   FIRST_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
7410   GEN_REWRITE_TAC LAND_CONV [has_integral] THEN
7411   DISCH_THEN(MP_TAC o SPEC `e / (&2 * (&(dimindex(:N)) + &1))`) THEN
7412   ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &2 * (&n + &1)`] THEN
7413   DISCH_THEN(X_CHOOSE_THEN `d:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
7414   DISCH_THEN(MP_TAC o SPECL
7415    [`d:real^M->real^M->bool`; `e / (&2 * (&(dimindex(:N)) + &1))`]) THEN
7416   ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &2 * (&n + &1)`] THEN
7417   DISCH_THEN(fun th -> EXISTS_TAC `d:real^M->real^M->bool` THEN MP_TAC th) THEN
7418   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
7419   MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
7420   MATCH_MP_TAC(REAL_ARITH `d < e ==> x <= d ==> x < e`) THEN
7421   REWRITE_TAC[real_div; REAL_INV_MUL; REAL_INV_INV; REAL_MUL_ASSOC] THEN
7422   SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
7423   UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC);;
7424
7425 (* ------------------------------------------------------------------------- *)
7426 (* Monotone convergence (bounded interval first).                            *)
7427 (* ------------------------------------------------------------------------- *)
7428
7429 let MONOTONE_CONVERGENCE_INTERVAL = prove
7430  (`!f:num->real^N->real^1 g a b.
7431         (!k. (f k) integrable_on interval[a,b]) /\
7432         (!k x. x IN interval[a,b] ==> drop(f k x) <= drop(f (SUC k) x)) /\
7433         (!x. x IN interval[a,b] ==> ((\k. f k x) --> g x) sequentially) /\
7434         bounded {integral (interval[a,b]) (f k) | k IN (:num)}
7435         ==> g integrable_on interval[a,b] /\
7436             ((\k. integral (interval[a,b]) (f k))
7437              --> integral (interval[a,b]) g) sequentially`,
7438   let lemma = prove
7439    (`{(x,y) | P x y} = {p | P (FST p) (SND p)}`,
7440     REWRITE_TAC[EXTENSION; FORALL_PAIR_THM; IN_ELIM_PAIR_THM; IN_ELIM_THM]) in
7441   REPEAT GEN_TAC THEN STRIP_TAC THEN
7442   ASM_CASES_TAC `content(interval[a:real^N,b]) = &0` THENL
7443    [ASM_SIMP_TAC[INTEGRAL_NULL; INTEGRABLE_ON_NULL; LIM_CONST];
7444     RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONTENT_LT_NZ])] THEN
7445   SUBGOAL_THEN
7446    `!x:real^N k:num. x IN interval[a,b] ==> drop(f k x) <= drop(g x)`
7447   ASSUME_TAC THENL
7448    [REPEAT STRIP_TAC THEN
7449     MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LBOUND) THEN
7450     EXISTS_TAC `\k. (f:num->real^N->real^1) k x` THEN
7451     ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
7452     EXISTS_TAC `k:num` THEN SPEC_TAC(`k:num`,`k:num`) THEN
7453     MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN REWRITE_TAC[REAL_LE_TRANS] THEN
7454     ASM_SIMP_TAC[REAL_LE_REFL];
7455     ALL_TAC] THEN
7456   SUBGOAL_THEN
7457    `?i. ((\k. integral (interval[a,b]) (f k:real^N->real^1)) --> i)
7458         sequentially`
7459   CHOOSE_TAC THENL
7460    [MATCH_MP_TAC BOUNDED_INCREASING_CONVERGENT THEN ASM_REWRITE_TAC[] THEN
7461     GEN_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_REWRITE_TAC[];
7462     ALL_TAC] THEN
7463   SUBGOAL_THEN
7464    `!k. drop(integral(interval[a,b]) ((f:num->real^N->real^1) k)) <= drop i`
7465   ASSUME_TAC THENL
7466     [GEN_TAC THEN MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LBOUND) THEN
7467      EXISTS_TAC `\k. integral(interval[a,b]) ((f:num->real^N->real^1) k)` THEN
7468      ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
7469      EXISTS_TAC `k:num` THEN SPEC_TAC(`k:num`,`k:num`) THEN
7470      MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
7471      ASM_REWRITE_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN
7472      GEN_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_REWRITE_TAC[];
7473      ALL_TAC] THEN
7474   SUBGOAL_THEN
7475    `((g:real^N->real^1) has_integral i) (interval[a,b])`
7476   ASSUME_TAC THENL
7477    [REWRITE_TAC[has_integral] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
7478     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV
7479      [HAS_INTEGRAL_INTEGRAL]) THEN
7480     REWRITE_TAC[has_integral] THEN
7481     DISCH_THEN(MP_TAC o GEN `k:num` o
7482       SPECL [`k:num`; `e / &2 pow (k + 2)`]) THEN
7483     ASM_SIMP_TAC[REAL_LT_DIV; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN
7484     GEN_REWRITE_TAC LAND_CONV [SKOLEM_THM] THEN
7485     REWRITE_TAC[LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN
7486     X_GEN_TAC `b:num->real^N->real^N->bool` THEN STRIP_TAC THEN
7487     SUBGOAL_THEN
7488      `?r. !k. r:num <= k
7489                ==> &0 <= drop i - drop(integral(interval[a:real^N,b]) (f k)) /\
7490                    drop i - drop(integral(interval[a,b]) (f k)) < e / &4`
7491     STRIP_ASSUME_TAC THENL
7492      [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
7493       DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
7494       ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
7495       MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
7496       MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
7497       MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[ABS_DROP; dist; DROP_SUB] THEN
7498       MATCH_MP_TAC(REAL_ARITH
7499        `x <= y ==> abs(x - y) < e ==> &0 <= y - x /\ y - x < e`) THEN
7500       ASM_REWRITE_TAC[];
7501       ALL_TAC] THEN
7502     SUBGOAL_THEN
7503      `!x. x IN interval[a:real^N,b]
7504           ==> ?n. r:num <= n /\
7505                   !k. n <= k ==> &0 <= drop(g x) - drop(f k x) /\
7506                                  drop(g x) - drop(f k x) <
7507                                    e / (&4 * content(interval[a,b]))`
7508     MP_TAC THENL
7509      [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7510       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (BINDER_CONV o RAND_CONV)
7511         [LIM_SEQUENTIALLY]) THEN
7512       DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_SIMP_TAC[REAL_SUB_LE] THEN
7513       DISCH_THEN(MP_TAC o SPEC `e / (&4 * content(interval[a:real^N,b]))`) THEN
7514       ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN
7515       REWRITE_TAC[dist; ABS_DROP; DROP_SUB] THEN
7516       ASM_SIMP_TAC[REAL_ARITH `f <= g ==> abs(f - g) = g - f`] THEN
7517       DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
7518       EXISTS_TAC `N + r:num` THEN CONJ_TAC THENL [ARITH_TAC; ALL_TAC] THEN
7519       ASM_MESON_TAC[ARITH_RULE `N + r:num <= k ==> N <= k`];
7520       ALL_TAC] THEN
7521     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
7522     REWRITE_TAC[SKOLEM_THM] THEN
7523     REWRITE_TAC[FORALL_AND_THM; TAUT
7524      `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN
7525     REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN
7526     DISCH_THEN(X_CHOOSE_THEN `m:real^N->num` STRIP_ASSUME_TAC) THEN
7527     ABBREV_TAC `d:real^N->real^N->bool = \x. b(m x:num) x` THEN
7528     EXISTS_TAC `d:real^N->real^N->bool` THEN CONJ_TAC THENL
7529      [EXPAND_TAC "d" THEN REWRITE_TAC[gauge] THEN
7530       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV [gauge]) THEN
7531       SIMP_TAC[];
7532       ALL_TAC] THEN
7533     X_GEN_TAC `p:(real^N#(real^N->bool))->bool` THEN STRIP_TAC THEN
7534     MATCH_MP_TAC(NORM_ARITH
7535      `!b c. norm(a - b) <= e / &4 /\
7536             norm(b - c) < e / &2 /\
7537             norm(c - d) < e / &4
7538             ==> norm(a - d) < e`) THEN
7539     EXISTS_TAC `vsum p (\(x:real^N,k:real^N->bool).
7540                   content k % (f:num->real^N->real^1) (m x) x)` THEN
7541     EXISTS_TAC `vsum p (\(x:real^N,k:real^N->bool).
7542                   integral k ((f:num->real^N->real^1) (m x)))` THEN
7543     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
7544     SUBGOAL_THEN `?s:num. !t:real^N#(real^N->bool). t IN p ==> m(FST t) <= s`
7545     MP_TAC THENL [ASM_SIMP_TAC[UPPER_BOUND_FINITE_SET]; ALL_TAC] THEN
7546     REWRITE_TAC[FORALL_PAIR_THM] THEN DISCH_THEN(X_CHOOSE_TAC `s:num`) THEN
7547     REPEAT CONJ_TAC THENL
7548      [ASM_SIMP_TAC[GSYM VSUM_SUB] THEN REWRITE_TAC[LAMBDA_PAIR_THM] THEN
7549       REWRITE_TAC[GSYM VECTOR_SUB_LDISTRIB] THEN
7550       W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
7551       ASM_REWRITE_TAC[] THEN
7552       MATCH_MP_TAC(REAL_ARITH `y <= e ==> x <= y ==> x <= e`) THEN
7553       REWRITE_TAC[LAMBDA_PAIR_THM] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
7554       EXISTS_TAC
7555        `sum p (\(x:real^N,k:real^N->bool).
7556                  content k * e / (&4 * content (interval[a:real^N,b])))` THEN
7557       CONJ_TAC THENL
7558        [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
7559         MAP_EVERY X_GEN_TAC [`x:real^N`; `k:real^N->bool`] THEN
7560         DISCH_TAC THEN REWRITE_TAC[NORM_MUL; GSYM VECTOR_SUB_LDISTRIB] THEN
7561         MATCH_MP_TAC REAL_LE_MUL2 THEN
7562         REWRITE_TAC[REAL_ABS_POS; NORM_POS_LE] THEN
7563         REWRITE_TAC[ABS_DROP; DROP_SUB] THEN
7564         REWRITE_TAC[REAL_ARITH `abs(x) <= x <=> &0 <= x`] THEN CONJ_TAC THENL
7565          [ASM_MESON_TAC[CONTENT_POS_LE; TAGGED_DIVISION_OF]; ALL_TAC] THEN
7566         MATCH_MP_TAC(REAL_ARITH
7567          `&0 <= g - f /\ g - f < e ==> abs(g - f) <= e`) THEN
7568         CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
7569         REWRITE_TAC[LE_REFL] THEN ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET];
7570         ALL_TAC] THEN
7571       REWRITE_TAC[LAMBDA_PAIR; SUM_RMUL] THEN REWRITE_TAC[LAMBDA_PAIR_THM] THEN
7572       FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP
7573        ADDITIVE_CONTENT_TAGGED_DIVISION th]) THEN
7574       MATCH_MP_TAC REAL_EQ_IMP_LE THEN
7575       UNDISCH_TAC `&0 < content(interval[a:real^N,b])` THEN
7576       CONV_TAC REAL_FIELD;
7577       ASM_SIMP_TAC[GSYM VSUM_SUB] THEN REWRITE_TAC[LAMBDA_PAIR_THM] THEN
7578       MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC
7579         `norm(vsum (0..s)
7580                (\j. vsum {(x:real^N,k:real^N->bool) | (x,k) IN p /\ m(x) = j}
7581                          (\(x,k). content k % f (m x) x :real^1 -
7582                                   integral k (f (m x)))))` THEN
7583       CONJ_TAC THENL
7584        [MATCH_MP_TAC REAL_EQ_IMP_LE THEN REWRITE_TAC[lemma] THEN
7585         AP_TERM_TAC THEN MATCH_MP_TAC(GSYM VSUM_GROUP) THEN
7586         ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG; LE_0] THEN
7587         ASM_REWRITE_TAC[FORALL_PAIR_THM];
7588         ALL_TAC] THEN
7589       MATCH_MP_TAC REAL_LET_TRANS THEN
7590       EXISTS_TAC `sum (0..s) (\i. e / &2 pow (i + 2))` THEN CONJ_TAC THENL
7591        [ALL_TAC;
7592         REWRITE_TAC[real_div; GSYM REAL_POW_INV; SUM_LMUL] THEN
7593         REWRITE_TAC[REAL_POW_ADD; SUM_RMUL] THEN REWRITE_TAC[SUM_GP] THEN
7594         CONV_TAC REAL_RAT_REDUCE_CONV THEN
7595         ASM_SIMP_TAC[REAL_LT_LMUL_EQ; CONJUNCT1 LT] THEN
7596         REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC] THEN
7597         CONV_TAC REAL_RAT_REDUCE_CONV THEN
7598         MATCH_MP_TAC(REAL_ARITH `&0 < x * y ==> (&1 - x) * y < y`) THEN
7599         MATCH_MP_TAC REAL_LT_MUL THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
7600         MATCH_MP_TAC REAL_POW_LT THEN CONV_TAC REAL_RAT_REDUCE_CONV] THEN
7601       MATCH_MP_TAC VSUM_NORM_LE THEN REWRITE_TAC[FINITE_NUMSEG] THEN
7602       X_GEN_TAC `t:num` THEN REWRITE_TAC[IN_NUMSEG; LE_0] THEN DISCH_TAC THEN
7603       MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
7604        `norm(vsum {x:real^N,k:real^N->bool | x,k IN p /\ m x:num = t}
7605                   (\(x,k). content k % f t x - integral k (f t)):real^1)` THEN
7606       CONJ_TAC THENL
7607        [MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
7608         MATCH_MP_TAC VSUM_EQ THEN SIMP_TAC[FORALL_PAIR_THM; IN_ELIM_PAIR_THM];
7609         ALL_TAC] THEN
7610       MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
7611         HENSTOCK_LEMMA_PART1) THEN
7612       MAP_EVERY EXISTS_TAC
7613        [`a:real^N`; `b:real^N`; `(b(t:num)):real^N->real^N->bool`] THEN
7614       ASM_REWRITE_TAC[] THEN
7615       ASM_SIMP_TAC[REAL_LT_DIV; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN
7616       CONJ_TAC THENL
7617        [MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_SUBSET THEN
7618         EXISTS_TAC `p:(real^N#(real^N->bool))->bool` THEN
7619         SIMP_TAC[SUBSET; FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN
7620         ASM_MESON_TAC[tagged_division_of];
7621         ALL_TAC] THEN
7622       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
7623       EXPAND_TAC "d" THEN REWRITE_TAC[fine; IN_ELIM_PAIR_THM] THEN MESON_TAC[];
7624
7625       MP_TAC(ISPECL [`(f:num->real^N->real^1) s`; `a:real^N`; `b:real^N`;
7626                      `p:(real^N#(real^N->bool))->bool`]
7627                     INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN) THEN
7628       MP_TAC(ISPECL [`(f:num->real^N->real^1) r`; `a:real^N`; `b:real^N`;
7629                      `p:(real^N#(real^N->bool))->bool`]
7630                     INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN) THEN
7631       ASM_SIMP_TAC[ABS_DROP; DROP_SUB; DROP_VSUM; GSYM DROP_EQ] THEN
7632       REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM] THEN MATCH_MP_TAC(REAL_ARITH
7633        `sr <= sx /\ sx <= ss /\ ks <= i /\ &0 <= i - kr /\ i - kr < e
7634         ==> kr = sr ==> ks = ss ==> abs(sx - i) < e`) THEN
7635       ASM_SIMP_TAC[LE_REFL] THEN CONJ_TAC THEN MATCH_MP_TAC SUM_LE THEN
7636       ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
7637       MAP_EVERY X_GEN_TAC [`x:real^N`; `i:real^N->bool`] THEN DISCH_TAC THEN
7638       (SUBGOAL_THEN `i SUBSET interval[a:real^N,b]` ASSUME_TAC THENL
7639         [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
7640        SUBGOAL_THEN `?u v:real^N. i = interval[u,v]`
7641         (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
7642        THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC]) THEN
7643       MATCH_MP_TAC INTEGRAL_DROP_LE THEN
7644       REPEAT(CONJ_TAC THENL
7645        [ASM_MESON_TAC[INTEGRABLE_SUBINTERVAL]; ALL_TAC]) THEN
7646       X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
7647       MP_TAC(ISPEC
7648         `\m n:num. drop (f m (y:real^N)) <= drop (f n y)`
7649         TRANSITIVE_STEPWISE_LE) THEN
7650       REWRITE_TAC[REAL_LE_TRANS; REAL_LE_REFL] THEN
7651       (ANTS_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC]) THEN
7652       DISCH_THEN MATCH_MP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
7653       ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET]];
7654     ALL_TAC] THEN
7655   CONJ_TAC THENL [ASM_MESON_TAC[integrable_on]; ALL_TAC] THEN
7656   FIRST_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN
7657   ASM_REWRITE_TAC[]);;
7658
7659 let MONOTONE_CONVERGENCE_INCREASING = prove
7660  (`!f:num->real^N->real^1 g s.
7661         (!k. (f k) integrable_on s) /\
7662         (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\
7663         (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) /\
7664         bounded {integral s (f k) | k IN (:num)}
7665         ==> g integrable_on s /\
7666             ((\k. integral s (f k)) --> integral s g) sequentially`,
7667   SUBGOAL_THEN
7668    `!f:num->real^N->real^1 g s.
7669         (!k x. x IN s ==> &0 <= drop(f k x)) /\
7670         (!k. (f k) integrable_on s) /\
7671         (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\
7672         (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) /\
7673         bounded {integral s (f k) | k IN (:num)}
7674         ==> g integrable_on s /\
7675             ((\k. integral s (f k)) --> integral s g) sequentially`
7676   ASSUME_TAC THENL
7677    [ALL_TAC;
7678     REPEAT GEN_TAC THEN STRIP_TAC THEN
7679     FIRST_X_ASSUM(MP_TAC o ISPECL
7680      [`\n x:real^N. f(SUC n) x - f 0 x:real^1`;
7681       `\x. (g:real^N->real^1) x - f 0 x`; `s:real^N->bool`]) THEN
7682     REWRITE_TAC[] THEN ANTS_TAC THEN REPEAT CONJ_TAC THENL
7683      [REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_SUB; REAL_SUB_LE] THEN
7684       MP_TAC(ISPEC
7685         `\m n:num. drop (f m (x:real^N)) <= drop (f n x)`
7686         TRANSITIVE_STEPWISE_LE) THEN
7687       REWRITE_TAC[REAL_LE_TRANS; REAL_LE_REFL] THEN ASM_MESON_TAC[LE_0];
7688       GEN_TAC THEN MATCH_MP_TAC INTEGRABLE_SUB THEN ASM_REWRITE_TAC[ETA_AX];
7689       REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_SUB; REAL_SUB_LE] THEN
7690       ASM_SIMP_TAC[REAL_ARITH `x - a <= y - a <=> x <= y`];
7691       REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_SUB THEN SIMP_TAC[LIM_CONST] THEN
7692       REWRITE_TAC[ADD1] THEN
7693       MATCH_MP_TAC(ISPECL[`f:num->real^1`; `l:real^1`; `1`] SEQ_OFFSET) THEN
7694       ASM_SIMP_TAC[];
7695       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
7696       ASM_SIMP_TAC[INTEGRAL_SUB; ETA_AX; bounded] THEN
7697       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
7698       REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN
7699       DISCH_THEN(X_CHOOSE_THEN `B:real`
7700         (fun th -> EXISTS_TAC `B + norm(integral s (f 0:real^N->real^1))` THEN
7701                    X_GEN_TAC `k:num` THEN MP_TAC(SPEC `SUC k` th))) THEN
7702       NORM_ARITH_TAC;
7703       ASM_SIMP_TAC[INTEGRAL_SUB; ETA_AX; IMP_CONJ] THEN
7704       SUBGOAL_THEN `(f 0:real^N->real^1) integrable_on s` MP_TAC THENL
7705        [ASM_REWRITE_TAC[]; ONCE_REWRITE_TAC[IMP_IMP]] THEN
7706       DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_ADD) THEN
7707       REWRITE_TAC[ETA_AX; VECTOR_ARITH `f + (g - f):real^N = g`] THEN
7708       DISCH_TAC THEN ASM_SIMP_TAC[INTEGRAL_SUB; ETA_AX] THEN
7709       MP_TAC(ISPECL [`sequentially`; `integral s (f 0:real^N->real^1)`]
7710                     LIM_CONST) THEN
7711       REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN
7712       REWRITE_TAC[ETA_AX; VECTOR_ARITH `f + (g - f):real^N = g`] THEN
7713       REWRITE_TAC[ADD1] THEN
7714       SIMP_TAC[ISPECL[`f:num->real^1`; `l:real^1`; `1`] SEQ_OFFSET_REV]]] THEN
7715   REPEAT GEN_TAC THEN STRIP_TAC THEN
7716   SUBGOAL_THEN
7717    `!x:real^N k:num. x IN s ==> drop(f k x) <= drop(g x)`
7718   ASSUME_TAC THENL
7719    [REPEAT STRIP_TAC THEN
7720     MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LBOUND) THEN
7721     EXISTS_TAC `\k. (f:num->real^N->real^1) k x` THEN
7722     ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
7723     EXISTS_TAC `k:num` THEN SPEC_TAC(`k:num`,`k:num`) THEN
7724     MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN REWRITE_TAC[REAL_LE_TRANS] THEN
7725     ASM_SIMP_TAC[REAL_LE_REFL];
7726     ALL_TAC] THEN
7727   SUBGOAL_THEN
7728    `?i. ((\k. integral s (f k:real^N->real^1)) --> i)
7729         sequentially`
7730   CHOOSE_TAC THENL
7731    [MATCH_MP_TAC BOUNDED_INCREASING_CONVERGENT THEN ASM_REWRITE_TAC[] THEN
7732     GEN_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_REWRITE_TAC[];
7733     ALL_TAC] THEN
7734   SUBGOAL_THEN
7735    `!k. drop(integral s ((f:num->real^N->real^1) k)) <= drop i`
7736   ASSUME_TAC THENL
7737     [GEN_TAC THEN MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LBOUND) THEN
7738      EXISTS_TAC `\k. integral(s) ((f:num->real^N->real^1) k)` THEN
7739      ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
7740      EXISTS_TAC `k:num` THEN SPEC_TAC(`k:num`,`k:num`) THEN
7741      MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
7742      ASM_REWRITE_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN
7743      GEN_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_REWRITE_TAC[];
7744      ALL_TAC] THEN
7745   SUBGOAL_THEN `((g:real^N->real^1) has_integral i) s` ASSUME_TAC THENL
7746    [ALL_TAC;
7747     CONJ_TAC THENL [ASM_MESON_TAC[integrable_on]; ALL_TAC] THEN
7748     FIRST_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN
7749     ASM_REWRITE_TAC[]] THEN
7750   REWRITE_TAC[HAS_INTEGRAL_ALT] THEN
7751   MP_TAC(ISPECL
7752    [`\k x. if x IN s then (f:num->real^N->real^1) k x else vec 0`;
7753     `\x. if x IN s then (g:real^N->real^1) x else vec 0`]
7754    (MATCH_MP(MESON[] `(!a b c d. P a b c d ==> Q a b c d)
7755                       ==> !a b. (!c d. P a b c d) ==> (!c d. Q a b c d)`)
7756             MONOTONE_CONVERGENCE_INTERVAL)) THEN
7757   ANTS_TAC THENL
7758    [REPEAT GEN_TAC THEN REWRITE_TAC[] THEN
7759     MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
7760      [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV [INTEGRABLE_ALT]) THEN
7761       SIMP_TAC[];
7762       DISCH_TAC] THEN
7763     CONJ_TAC THENL
7764      [REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_LE_REFL];
7765       ALL_TAC] THEN
7766     CONJ_TAC THENL
7767      [REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[LIM_CONST];
7768       ALL_TAC] THEN
7769     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
7770     ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
7771     REWRITE_TAC[bounded; FORALL_IN_IMAGE; IN_UNIV] THEN
7772     MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
7773     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:num` THEN
7774     REWRITE_TAC[ABS_DROP] THEN MATCH_MP_TAC(REAL_ARITH
7775      `&0 <= y /\ y <= x ==> abs(x) <= a ==> abs(y) <= a`) THEN
7776     CONJ_TAC THENL
7777      [MATCH_MP_TAC INTEGRAL_DROP_POS THEN ASM_REWRITE_TAC[] THEN
7778       REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
7779       ASM_SIMP_TAC[REAL_LE_REFL; DROP_VEC];
7780       ALL_TAC] THEN
7781     GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM INTEGRAL_RESTRICT_UNIV] THEN
7782     MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN
7783     ASM_REWRITE_TAC[SUBSET_UNIV; IN_UNIV] THEN
7784     ASM_REWRITE_TAC[INTEGRABLE_RESTRICT_UNIV; ETA_AX] THEN
7785     GEN_TAC THEN COND_CASES_TAC THEN
7786     ASM_SIMP_TAC[REAL_LE_REFL; DROP_VEC; REAL_LE_REFL];
7787     ALL_TAC] THEN
7788   REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
7789   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
7790   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
7791   DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
7792   ASM_SIMP_TAC[dist; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
7793   DISCH_THEN(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC) THEN
7794   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV
7795    [HAS_INTEGRAL_INTEGRAL]) THEN
7796   GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [HAS_INTEGRAL_ALT] THEN
7797   REWRITE_TAC[FORALL_AND_THM] THEN
7798   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
7799   DISCH_THEN(MP_TAC o SPECL [`N:num`; `e / &4`]) THEN
7800   ASM_SIMP_TAC[dist; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
7801   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
7802   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
7803   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN
7804   FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN
7805   ASM_REWRITE_TAC[] THEN
7806   FIRST_ASSUM(MP_TAC o C MATCH_MP (ARITH_RULE `N:num <= N`)) THEN
7807   REWRITE_TAC[IMP_IMP] THEN
7808   DISCH_THEN(MP_TAC o MATCH_MP (NORM_ARITH
7809    `norm(x - y) < e / &4 /\ norm(z - x) < e / &4
7810     ==> norm(z - y) < e / &2`)) THEN
7811   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (BINDER_CONV o BINDER_CONV)
7812         [LIM_SEQUENTIALLY]) THEN
7813   DISCH_THEN(MP_TAC o SPECL [`a:real^N`; `b:real^N`; `e / &2`]) THEN
7814   ASM_REWRITE_TAC[dist; REAL_HALF] THEN
7815   DISCH_THEN(X_CHOOSE_THEN `M:num` (MP_TAC o SPEC `M + N:num`)) THEN
7816   REWRITE_TAC[LE_ADD; ABS_DROP; DROP_SUB] THEN
7817   MATCH_MP_TAC(REAL_ARITH
7818    `f1 <= f2 /\ f2 <= i
7819     ==> abs(f2 - g) < e / &2 ==> abs(f1 - i) < e / &2 ==> abs(g - i) < e`) THEN
7820   CONJ_TAC THENL
7821    [MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_REWRITE_TAC[] THEN
7822     X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7823     COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN
7824     MP_TAC(ISPEC
7825         `\m n:num. drop (f m (x:real^N)) <= drop (f n x)`
7826         TRANSITIVE_STEPWISE_LE) THEN
7827     REWRITE_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN
7828     ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
7829     DISCH_THEN MATCH_MP_TAC THEN ARITH_TAC;
7830     ALL_TAC] THEN
7831   MATCH_MP_TAC REAL_LE_TRANS THEN
7832   EXISTS_TAC `drop(integral s ((f:num->real^N->real^1) (M + N)))` THEN
7833   ASM_REWRITE_TAC[] THEN
7834   GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM INTEGRAL_RESTRICT_UNIV] THEN
7835   MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN
7836   ASM_REWRITE_TAC[SUBSET_UNIV; IN_UNIV] THEN
7837   ASM_REWRITE_TAC[INTEGRABLE_RESTRICT_UNIV; ETA_AX] THEN
7838   GEN_TAC THEN COND_CASES_TAC THEN
7839   ASM_SIMP_TAC[REAL_LE_REFL; DROP_VEC; REAL_LE_REFL]);;
7840
7841 let MONOTONE_CONVERGENCE_DECREASING = prove
7842  (`!f:num->real^N->real^1 g s.
7843         (!k. (f k) integrable_on s) /\
7844         (!k x. x IN s ==> drop(f (SUC k) x) <= drop(f k x)) /\
7845         (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) /\
7846         bounded {integral s (f k) | k IN (:num)}
7847         ==> g integrable_on s /\
7848             ((\k. integral s (f k)) --> integral s g) sequentially`,
7849   REPEAT GEN_TAC THEN DISCH_TAC THEN
7850   MP_TAC(ISPECL
7851    [`(\k x. --(f k x)):num->real^N->real^1`;
7852     `(\x. --(g x)):real^N->real^1`; `s:real^N->bool`]
7853         MONOTONE_CONVERGENCE_INCREASING) THEN
7854   FIRST_ASSUM MP_TAC THEN
7855   MATCH_MP_TAC(TAUT `(a ==> b) /\ (c ==> d) ==> a ==> (b ==> c) ==> d`) THEN
7856   REWRITE_TAC[] THEN CONJ_TAC THENL
7857    [REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THENL
7858      [MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
7859       DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_NEG) THEN REWRITE_TAC[];
7860       SIMP_TAC[DROP_NEG; REAL_LE_NEG2];
7861       REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_NEG THEN ASM_SIMP_TAC[];
7862       ALL_TAC] THEN
7863     DISCH_TAC THEN MATCH_MP_TAC BOUNDED_SUBSET THEN
7864     EXISTS_TAC `IMAGE (\x. --x)
7865                       {integral s (f k:real^N->real^1) | k IN (:num)}` THEN
7866     CONJ_TAC THENL
7867      [MATCH_MP_TAC BOUNDED_LINEAR_IMAGE THEN
7868       ASM_SIMP_TAC[LINEAR_COMPOSE_NEG; LINEAR_ID];
7869       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[GSYM IMAGE_o] THEN
7870       REWRITE_TAC[SUBSET; IN_IMAGE] THEN
7871       GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN
7872       REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[o_THM] THEN
7873       MATCH_MP_TAC INTEGRAL_NEG THEN ASM_REWRITE_TAC[]];
7874     ALL_TAC] THEN
7875   DISCH_THEN(CONJUNCTS_THEN2
7876    (MP_TAC o MATCH_MP INTEGRABLE_NEG) (MP_TAC o MATCH_MP LIM_NEG)) THEN
7877   REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX] THEN
7878   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
7879   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN
7880   BINOP_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN TRY GEN_TAC THEN
7881   MATCH_MP_TAC(VECTOR_ARITH `x:real^N = --y ==> --x = y`) THEN
7882   MATCH_MP_TAC INTEGRAL_NEG THEN ASM_REWRITE_TAC[]);;
7883
7884 let MONOTONE_CONVERGENCE_INCREASING_AE = prove
7885  (`!f:num->real^N->real^1 g s t.
7886         (!k. (f k) integrable_on s) /\
7887         negligible t /\
7888         (!k x. x IN s DIFF t ==> drop(f k x) <= drop(f (SUC k) x)) /\
7889         (!x. x IN s DIFF t ==> ((\k. f k x) --> g x) sequentially) /\
7890         bounded {integral s (f k) | k IN (:num)}
7891         ==> g integrable_on s /\
7892             ((\k. integral s (f k)) --> integral s g) sequentially`,
7893   REPEAT GEN_TAC THEN STRIP_TAC THEN
7894   MP_TAC(ISPECL
7895    [`\n x. if x IN t then vec 0
7896            else (f:num->real^N->real^1) n x`;
7897     `\x. if x IN t then vec 0
7898            else (g:real^N->real^1) x`; `s:real^N->bool`]
7899         MONOTONE_CONVERGENCE_INCREASING) THEN
7900   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
7901    [REPEAT CONJ_TAC THENL
7902      [X_GEN_TAC `k:num` THEN
7903       MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE) THEN
7904       EXISTS_TAC `(f:num->real^N->real^1) k` THEN
7905       EXISTS_TAC `t:real^N->bool` THEN
7906       ASM_SIMP_TAC[IN_DIFF];
7907       REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
7908       ASM_REWRITE_TAC[REAL_LE_REFL] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
7909       ASM SET_TAC[];
7910       X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7911       ASM_CASES_TAC `(x:real^N) IN t` THEN ASM_REWRITE_TAC[LIM_CONST] THEN
7912       FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_DIFF];
7913       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
7914         BOUNDED_SUBSET)) THEN
7915       MATCH_MP_TAC(SET_RULE
7916        `(!x. x IN s ==> f x = g x)
7917         ==> {f x | x IN s} SUBSET {g x | x IN s}`) THEN
7918       REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_SPIKE THEN
7919       EXISTS_TAC `t:real^N->bool` THEN
7920       ASM_SIMP_TAC[IN_DIFF]];
7921     MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
7922      [MATCH_MP_TAC INTEGRABLE_SPIKE THEN EXISTS_TAC `t:real^N->bool` THEN
7923       ASM_SIMP_TAC[IN_DIFF];
7924       MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THEN
7925       REWRITE_TAC[FUN_EQ_THM] THEN REPEAT GEN_TAC THEN
7926       MATCH_MP_TAC INTEGRAL_SPIKE THEN EXISTS_TAC `t:real^N->bool` THEN
7927       ASM_SIMP_TAC[IN_DIFF]]]);;
7928
7929 let MONOTONE_CONVERGENCE_DECREASING_AE = prove
7930  (`!f:num->real^N->real^1 g s t.
7931         (!k. (f k) integrable_on s) /\
7932         negligible t /\
7933         (!k x. x IN s DIFF t ==> drop(f (SUC k) x) <= drop(f k x)) /\
7934         (!x. x IN s DIFF t ==> ((\k. f k x) --> g x) sequentially) /\
7935         bounded {integral s (f k) | k IN (:num)}
7936         ==> g integrable_on s /\
7937             ((\k. integral s (f k)) --> integral s g) sequentially`,
7938   REPEAT GEN_TAC THEN STRIP_TAC THEN
7939   MP_TAC(ISPECL
7940    [`\n x. if x IN t then vec 0
7941            else (f:num->real^N->real^1) n x`;
7942     `\x. if x IN t then vec 0
7943            else (g:real^N->real^1) x`; `s:real^N->bool`]
7944         MONOTONE_CONVERGENCE_DECREASING) THEN
7945   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
7946    [REPEAT CONJ_TAC THENL
7947      [X_GEN_TAC `k:num` THEN
7948       MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE) THEN
7949       EXISTS_TAC `(f:num->real^N->real^1) k` THEN
7950       EXISTS_TAC `t:real^N->bool` THEN
7951       ASM_SIMP_TAC[IN_DIFF];
7952       REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
7953       ASM_REWRITE_TAC[REAL_LE_REFL] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
7954       ASM SET_TAC[];
7955       X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7956       ASM_CASES_TAC `(x:real^N) IN t` THEN ASM_REWRITE_TAC[LIM_CONST] THEN
7957       FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_DIFF];
7958       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
7959         BOUNDED_SUBSET)) THEN
7960       MATCH_MP_TAC(SET_RULE
7961        `(!x. x IN s ==> f x = g x)
7962         ==> {f x | x IN s} SUBSET {g x | x IN s}`) THEN
7963       REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_SPIKE THEN
7964       EXISTS_TAC `t:real^N->bool` THEN
7965       ASM_SIMP_TAC[IN_DIFF]];
7966     MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
7967      [MATCH_MP_TAC INTEGRABLE_SPIKE THEN EXISTS_TAC `t:real^N->bool` THEN
7968       ASM_SIMP_TAC[IN_DIFF];
7969       MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THEN
7970       REWRITE_TAC[FUN_EQ_THM] THEN REPEAT GEN_TAC THEN
7971       MATCH_MP_TAC INTEGRAL_SPIKE THEN EXISTS_TAC `t:real^N->bool` THEN
7972       ASM_SIMP_TAC[IN_DIFF]]]);;
7973
7974 (* ------------------------------------------------------------------------- *)
7975 (* More lemmas about existence and bounds between integrals.                 *)
7976 (* ------------------------------------------------------------------------- *)
7977
7978 let INTEGRAL_NORM_BOUND_INTEGRAL = prove
7979  (`!f:real^M->real^N g s.
7980         f integrable_on s /\ g integrable_on s /\
7981         (!x. x IN s ==> norm(f x) <= drop(g x))
7982         ==> norm(integral s f) <= drop(integral s g)`,
7983   let lemma = prove
7984    (`(!e. &0 < e ==> x < y + e) ==> x <= y`,
7985     DISCH_THEN(MP_TAC o SPEC `x - y:real`) THEN REAL_ARITH_TAC) in
7986   SUBGOAL_THEN
7987    `!f:real^M->real^N g a b.
7988         f integrable_on interval[a,b] /\ g integrable_on interval[a,b] /\
7989         (!x. x IN interval[a,b] ==> norm(f x) <= drop(g x))
7990         ==> norm(integral(interval[a,b]) f) <= drop(integral(interval[a,b]) g)`
7991   ASSUME_TAC THENL
7992    [REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma THEN
7993     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
7994     UNDISCH_TAC `(f:real^M->real^N) integrable_on interval[a,b]` THEN
7995     DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
7996     FIRST_X_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
7997     REWRITE_TAC[has_integral] THEN DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
7998     ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN
7999     X_GEN_TAC `d1:real^M->real^M->bool` THEN STRIP_TAC THEN
8000     DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
8001     ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN
8002     X_GEN_TAC `d2:real^M->real^M->bool` THEN
8003     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
8004     MP_TAC(ISPECL [`d1:real^M->real^M->bool`; `d2:real^M->real^M->bool`]
8005                   GAUGE_INTER) THEN
8006     ASM_REWRITE_TAC[] THEN
8007     DISCH_THEN(MP_TAC o MATCH_MP FINE_DIVISION_EXISTS) THEN
8008     DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN
8009     REWRITE_TAC[FINE_INTER; LEFT_IMP_EXISTS_THM] THEN
8010     X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
8011     DISCH_THEN(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN
8012     FIRST_X_ASSUM(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN
8013     ASM_REWRITE_TAC[ABS_DROP; DROP_SUB] THEN MATCH_MP_TAC(NORM_ARITH
8014      `norm(sg) <= dsa
8015       ==> abs(dsa - dia) < e / &2 ==> norm(sg - ig) < e / &2
8016           ==> norm(ig) < dia + e`) THEN
8017     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
8018     ASM_SIMP_TAC[DROP_VSUM] THEN MATCH_MP_TAC VSUM_NORM_LE THEN
8019     ASM_REWRITE_TAC[o_DEF; FORALL_PAIR_THM] THEN
8020     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
8021     REWRITE_TAC[NORM_MUL; DROP_CMUL] THEN
8022     MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[REAL_ABS_POS; NORM_POS_LE] THEN
8023     REWRITE_TAC[REAL_ARITH `abs x <= x <=> &0 <= x`] THEN
8024     ASM_MESON_TAC[CONTENT_POS_LE; TAGGED_DIVISION_OF; SUBSET];
8025     ALL_TAC] THEN
8026   REPEAT GEN_TAC THEN REWRITE_TAC[CONJ_ASSOC] THEN
8027   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
8028   DISCH_THEN(CONJUNCTS_THEN (fun th ->
8029      ASSUME_TAC(CONJUNCT1(GEN_REWRITE_RULE I [INTEGRABLE_ALT] th)) THEN
8030      MP_TAC(MATCH_MP INTEGRABLE_INTEGRAL th))) THEN
8031   ONCE_REWRITE_TAC[HAS_INTEGRAL] THEN
8032   DISCH_THEN(LABEL_TAC "A") THEN DISCH_TAC THEN MATCH_MP_TAC lemma THEN
8033   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8034   REMOVE_THEN "A" (MP_TAC o SPEC `e / &2`) THEN
8035   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
8036   DISCH_THEN(X_CHOOSE_THEN `B1:real`
8037    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "F"))) THEN
8038   DISCH_THEN(X_CHOOSE_THEN `B2:real`
8039    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "A"))) THEN
8040   MP_TAC(ISPEC `ball(vec 0,max B1 B2):real^M->bool`
8041     BOUNDED_SUBSET_CLOSED_INTERVAL) THEN
8042   REWRITE_TAC[BOUNDED_BALL; LEFT_IMP_EXISTS_THM] THEN
8043   REWRITE_TAC[BALL_MAX_UNION; UNION_SUBSET] THEN
8044   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
8045   DISCH_THEN(CONJUNCTS_THEN(ANTE_RES_THEN MP_TAC)) THEN
8046   DISCH_THEN(X_CHOOSE_THEN `z:real^1` (CONJUNCTS_THEN2 ASSUME_TAC
8047      (fun th -> DISCH_THEN(X_CHOOSE_THEN `w:real^N`
8048                 (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN MP_TAC th))) THEN
8049   ASM_REWRITE_TAC[ABS_DROP; DROP_SUB] THEN MATCH_MP_TAC(NORM_ARITH
8050      `norm(sg) <= dsa
8051       ==> abs(dsa - dia) < e / &2 ==> norm(sg - ig) < e / &2
8052           ==> norm(ig) < dia + e`) THEN
8053   REPEAT(FIRST_X_ASSUM(SUBST1_TAC o SYM o MATCH_MP INTEGRAL_UNIQUE)) THEN
8054   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
8055   REPEAT STRIP_TAC THEN
8056   COND_CASES_TAC THEN ASM_SIMP_TAC[NORM_0; DROP_VEC; REAL_LE_REFL]);;
8057
8058 let INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT = prove
8059  (`!f:real^M->real^N g:real^M->real^P s k.
8060         1 <= k /\ k <= dimindex(:P) /\
8061         f integrable_on s /\ g integrable_on s /\
8062         (!x. x IN s ==> norm(f x) <= (g x)$k)
8063         ==> norm(integral s f) <= (integral s g)$k`,
8064   REPEAT STRIP_TAC THEN
8065   MATCH_MP_TAC REAL_LE_TRANS THEN
8066   EXISTS_TAC `drop(integral s ((\y. lift(y$k)) o (g:real^M->real^P)))` THEN
8067   SUBGOAL_THEN `linear(\y:real^P. lift(y$k))` ASSUME_TAC THENL
8068    [ASM_SIMP_TAC[linear; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
8069                  LIFT_ADD; LIFT_CMUL];
8070     ALL_TAC] THEN
8071   CONJ_TAC THENL
8072    [MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
8073     ASM_SIMP_TAC[o_THM; LIFT_DROP] THEN MATCH_MP_TAC INTEGRABLE_LINEAR THEN
8074     ASM_SIMP_TAC[];
8075     ALL_TAC] THEN
8076   SUBGOAL_THEN
8077    `integral s ((\y. lift (y$k)) o (g:real^M->real^P)) =
8078         (\y. lift (y$k)) (integral s g)`
8079   SUBST1_TAC THENL
8080    [MATCH_MP_TAC INTEGRAL_LINEAR THEN ASM_REWRITE_TAC[];
8081     REWRITE_TAC[LIFT_DROP; REAL_LE_REFL]]);;
8082
8083 let HAS_INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT = prove
8084  (`!f:real^M->real^N g:real^M->real^P s i j k.
8085         1 <= k /\ k <= dimindex(:P) /\
8086         (f has_integral i) s /\ (g has_integral j) s /\
8087         (!x. x IN s ==> norm(f x) <= (g x)$k)
8088         ==> norm(i) <= j$k`,
8089   REPEAT STRIP_TAC THEN
8090   REPEAT(FIRST_X_ASSUM(fun th ->
8091    SUBST1_TAC(SYM(MATCH_MP INTEGRAL_UNIQUE th)) THEN
8092    ASSUME_TAC(MATCH_MP HAS_INTEGRAL_INTEGRABLE th))) THEN
8093   MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT THEN
8094   ASM_REWRITE_TAC[]);;
8095
8096 let INTEGRABLE_ON_ALL_INTERVALS_INTEGRABLE_BOUND = prove
8097  (`!f:real^M->real^N g s.
8098         (!a b. (\x. if x IN s then f x else vec 0)
8099                integrable_on interval[a,b]) /\
8100         (!x. x IN s ==> norm(f x) <= drop(g x)) /\
8101         g integrable_on s
8102         ==> f integrable_on s`,
8103   let lemma = prove
8104    (`!f:real^M->real^N g.
8105           (!a b. f integrable_on interval[a,b]) /\
8106           (!x. norm(f x) <= drop(g x)) /\
8107           g integrable_on (:real^M)
8108           ==> f integrable_on (:real^M)`,
8109     REPEAT GEN_TAC THEN
8110     REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
8111     ONCE_REWRITE_TAC[INTEGRABLE_ALT_SUBSET] THEN
8112     ASM_REWRITE_TAC[IN_UNIV; ETA_AX] THEN
8113     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
8114     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
8115     ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
8116     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
8117     MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
8118     REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
8119     DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
8120     MATCH_MP_TAC(REAL_ARITH `a <= b ==> b < c ==> a < c`) THEN
8121     ONCE_REWRITE_TAC[NORM_SUB] THEN
8122     ASM_SIMP_TAC[GSYM INTEGRAL_DIFF; NEGLIGIBLE_EMPTY;
8123                  SET_RULE `s SUBSET t ==> s DIFF t = {}`] THEN
8124     REWRITE_TAC[ABS_DROP] THEN
8125     MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= abs y`) THEN
8126     MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
8127     ASM_MESON_TAC[integrable_on; HAS_INTEGRAL_DIFF; NEGLIGIBLE_EMPTY;
8128                  SET_RULE `s SUBSET t ==> s DIFF t = {}`]) in
8129   REPEAT GEN_TAC THEN
8130   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
8131   ONCE_REWRITE_TAC[GSYM INTEGRABLE_RESTRICT_UNIV] THEN
8132   DISCH_TAC THEN MATCH_MP_TAC lemma THEN
8133   EXISTS_TAC `(\x. if x IN s then g x else vec 0):real^M->real^1` THEN
8134   ASM_REWRITE_TAC[] THEN
8135   GEN_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[NORM_0; DROP_VEC; REAL_POS]);;
8136
8137 (* ------------------------------------------------------------------------- *)
8138 (* Explicit limit statement for integrals over [0,inf].                      *)
8139 (* ------------------------------------------------------------------------- *)
8140
8141 let HAS_INTEGRAL_LIM_AT_POSINFINITY = prove
8142  (`!f l:real^N.
8143         (f has_integral l) {t | &0 <= drop t} <=>
8144         (!a. f integrable_on interval[vec 0,a]) /\
8145         ((\a. integral (interval[vec 0,lift a]) f) --> l) at_posinfinity`,
8146   REPEAT GEN_TAC THEN
8147   GEN_REWRITE_TAC LAND_CONV [HAS_INTEGRAL_ALT] THEN
8148   REWRITE_TAC[INTEGRAL_RESTRICT_INTER; INTEGRABLE_RESTRICT_INTER] THEN
8149   SUBGOAL_THEN
8150    `!a b. {t | &0 <= drop t} INTER interval[a,b] =
8151           interval[lift(max (&0) (drop a)),b]`
8152    (fun th -> REWRITE_TAC[th])
8153   THENL
8154    [REWRITE_TAC[EXTENSION; FORALL_LIFT; IN_INTER; IN_INTERVAL_1;
8155                 LIFT_DROP; IN_ELIM_THM] THEN
8156     REAL_ARITH_TAC;
8157     ALL_TAC] THEN
8158   REWRITE_TAC[LIM_AT_POSINFINITY; dist; real_ge] THEN
8159   EQ_TAC THEN STRIP_TAC THEN CONJ_TAC THENL
8160    [X_GEN_TAC `a:real^1` THEN
8161     FIRST_X_ASSUM(MP_TAC o SPECL [`vec 0:real^1`; `a:real^1`]) THEN
8162     REWRITE_TAC[DROP_VEC; LIFT_NUM; REAL_ARITH `max x x = x`];
8163     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8164     FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
8165     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
8166     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*")) THEN
8167     X_GEN_TAC `b:real` THEN DISCH_TAC THEN
8168     REMOVE_THEN "*" (MP_TAC o SPECL [`lift(--b)`; `lift b`]) THEN
8169     REWRITE_TAC[DROP_VEC; LIFT_NUM; LIFT_DROP] THEN
8170     SUBGOAL_THEN `max (&0) (--b) = &0` SUBST1_TAC THENL
8171      [ASM_REAL_ARITH_TAC; REWRITE_TAC[LIFT_NUM]] THEN
8172     DISCH_THEN MATCH_MP_TAC THEN
8173     REWRITE_TAC[BALL_1; SUBSET_INTERVAL_1] THEN
8174     REWRITE_TAC[DROP_ADD; DROP_SUB; DROP_VEC; LIFT_DROP] THEN
8175     ASM_REAL_ARITH_TAC;
8176     MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`] THEN
8177     FIRST_X_ASSUM(MP_TAC o SPEC `b:real^1`) THEN
8178     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] INTEGRABLE_SUBINTERVAL) THEN
8179     SIMP_TAC[SUBSET_INTERVAL_1; DROP_ADD; DROP_SUB; DROP_VEC; LIFT_DROP] THEN
8180     REAL_ARITH_TAC;
8181     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8182     FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
8183     DISCH_THEN(X_CHOOSE_THEN `B:real` (LABEL_TAC "*")) THEN
8184     EXISTS_TAC `abs B + &1` THEN
8185     CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN
8186     MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`] THEN
8187     REWRITE_TAC[BALL_1; SUBSET_INTERVAL_1] THEN
8188     REWRITE_TAC[DROP_ADD; DROP_SUB; DROP_VEC; LIFT_DROP] THEN
8189     STRIP_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
8190     SUBGOAL_THEN `max (&0) (drop a) = &0` SUBST1_TAC THENL
8191      [ASM_REAL_ARITH_TAC; REWRITE_TAC[LIFT_NUM]] THEN
8192     FIRST_X_ASSUM(MP_TAC o SPEC `drop b`) THEN
8193     REWRITE_TAC[LIFT_DROP] THEN DISCH_THEN MATCH_MP_TAC THEN
8194     ASM_REAL_ARITH_TAC]);;
8195
8196 let HAS_INTEGRAL_LIM_SEQUENTIALLY = prove
8197  (`!f:real^1->real^N l.
8198            (f o lift --> vec 0) at_posinfinity /\
8199            (!n. f integrable_on interval[vec 0,vec n]) /\
8200            ((\n. integral (interval[vec 0,vec n]) f) --> l) sequentially
8201            ==> (f has_integral l) {t | &0 <= drop t}`,
8202   REPEAT STRIP_TAC THEN
8203   ONCE_REWRITE_TAC[HAS_INTEGRAL_LIM_AT_POSINFINITY] THEN
8204   MATCH_MP_TAC(TAUT `p /\ (p ==> q) ==> p /\ q`) THEN CONJ_TAC THENL
8205    [X_GEN_TAC `a:real^1` THEN MP_TAC(SPEC `drop a` REAL_ARCH_SIMPLE) THEN
8206     DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN
8207     FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN
8208     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] INTEGRABLE_SUBINTERVAL) THEN
8209     REWRITE_TAC[SUBSET_INTERVAL_1; DROP_VEC] THEN ASM_REAL_ARITH_TAC;
8210     DISCH_TAC] THEN
8211   REWRITE_TAC[LIM_AT_POSINFINITY; real_ge] THEN
8212   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8213   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_AT_POSINFINITY]) THEN
8214   DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
8215   ASM_REWRITE_TAC[REAL_HALF; o_THM; real_ge; FORALL_DROP; LIFT_DROP] THEN
8216   REWRITE_TAC[DIST_0; LEFT_IMP_EXISTS_THM] THEN
8217   X_GEN_TAC `B:real` THEN DISCH_TAC THEN
8218   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
8219   DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
8220   DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN EXISTS_TAC `max (&N) B + &1` THEN
8221   X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN MP_TAC(SPEC `drop x` FLOOR_POS) THEN
8222   ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
8223   DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN
8224   SUBGOAL_THEN
8225    `integral(interval[vec 0,x]) (f:real^1->real^N) =
8226     integral(interval[vec 0,vec n]) f + integral(interval[vec n,x]) f`
8227   SUBST1_TAC THENL
8228    [CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_COMBINE THEN
8229     ASM_REWRITE_TAC[DROP_VEC] THEN
8230     MP_TAC(SPEC `drop x` FLOOR) THEN ASM_REAL_ARITH_TAC;
8231     ALL_TAC] THEN
8232   MATCH_MP_TAC(NORM_ARITH
8233    `dist(a:real^N,l) < e / &2 /\ norm b <= e / &2 ==> dist(a + b,l) < e`) THEN
8234   CONJ_TAC THENL
8235    [FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[GSYM REAL_OF_NUM_LE] THEN
8236     MP_TAC(SPEC `drop x` FLOOR) THEN ASM_REAL_ARITH_TAC;
8237     ALL_TAC] THEN
8238   TRANS_TAC REAL_LE_TRANS
8239     `drop(integral(interval[vec n:real^1,x]) (\x. lift(e / &2)))` THEN
8240   CONJ_TAC THENL
8241    [MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
8242     ASM_REWRITE_TAC[INTEGRABLE_CONST; IN_INTERVAL_1; LIFT_DROP] THEN
8243     CONJ_TAC THENL
8244      [MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
8245       EXISTS_TAC `interval[vec 0:real^1,x]` THEN
8246       ASM_REWRITE_TAC[SUBSET_INTERVAL_1; DROP_VEC] THEN ASM_REAL_ARITH_TAC;
8247       REWRITE_TAC[DROP_VEC] THEN REPEAT STRIP_TAC THEN
8248       MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
8249       MP_TAC(SPEC `drop x` FLOOR) THEN ASM_REAL_ARITH_TAC];
8250     REWRITE_TAC[INTEGRAL_CONST] THEN IMP_REWRITE_TAC[CONTENT_1] THEN
8251     CONJ_TAC THENL
8252      [REWRITE_TAC[GSYM LIFT_CMUL; LIFT_DROP; DROP_VEC] THEN
8253       GEN_REWRITE_TAC RAND_CONV [GSYM REAL_MUL_LID] THEN
8254       MATCH_MP_TAC REAL_LE_RMUL THEN
8255       MP_TAC(SPEC `drop x` FLOOR) THEN ASM_REAL_ARITH_TAC;
8256       REWRITE_TAC[DROP_VEC] THEN MP_TAC(SPEC `drop x` FLOOR) THEN
8257       ASM_REAL_ARITH_TAC]]);;
8258
8259 (* ------------------------------------------------------------------------- *)
8260 (* Interval functions of bounded variation on a set.                         *)
8261 (* ------------------------------------------------------------------------- *)
8262
8263 parse_as_infix("has_bounded_setvariation_on",(12,"right"));;
8264
8265 let set_variation = new_definition
8266  `set_variation s (f:(real^M->bool)->real^N) =
8267         sup { sum d (\k. norm(f k)) | ?t. d division_of t /\ t SUBSET s}`;;
8268
8269 let has_bounded_setvariation_on = new_definition
8270   `(f:(real^M->bool)->real^N) has_bounded_setvariation_on s <=>
8271         ?B. !d t. d division_of t /\ t SUBSET s
8272                   ==> sum d (\k. norm(f k)) <= B`;;
8273
8274 let HAS_BOUNDED_SETVARIATION_ON = prove
8275  (`!f:(real^M->bool)->real^N s.
8276         f  has_bounded_setvariation_on s <=>
8277         ?B. &0 < B /\ !d t. d division_of t /\ t SUBSET s
8278                             ==> sum d (\k. norm(f k)) <= B`,
8279   REWRITE_TAC[has_bounded_setvariation_on] THEN
8280   MESON_TAC[REAL_ARITH `&0 < abs B + &1 /\ (x <= B ==> x <= abs B + &1)`]);;
8281
8282 let HAS_BOUNDED_SETVARIATION_ON_EQ = prove
8283  (`!f g:(real^M->bool)->real^N s.
8284         (!a b. ~(interval[a,b] = {}) /\ interval[a,b] SUBSET s
8285                ==> f(interval[a,b]) = g(interval[a,b])) /\
8286         f has_bounded_setvariation_on s
8287         ==> g has_bounded_setvariation_on s`,
8288   REPEAT GEN_TAC THEN
8289   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
8290   REWRITE_TAC[has_bounded_setvariation_on] THEN
8291   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
8292   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `d:(real^M->bool)->bool` THEN
8293   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `t:real^M->bool` THEN
8294   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
8295   MATCH_MP_TAC(REAL_ARITH `x = y ==> x <= B ==> y <= B`) THEN
8296   MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th ->
8297   GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION_NONEMPTY th]) THEN
8298   REPEAT STRIP_TAC THEN REWRITE_TAC[] THEN AP_TERM_TAC THEN
8299   FIRST_X_ASSUM MATCH_MP_TAC THEN
8300   ASM_MESON_TAC[division_of; SUBSET_TRANS]);;
8301
8302 let SET_VARIATION_EQ = prove
8303  (`!f g:(real^M->bool)->real^N s.
8304         (!a b. ~(interval[a,b] = {}) /\ interval[a,b] SUBSET s
8305                ==> f(interval[a,b]) = g(interval[a,b]))
8306         ==> set_variation s f = set_variation s g`,
8307   REPEAT STRIP_TAC THEN REWRITE_TAC[set_variation] THEN AP_TERM_TAC THEN
8308   MATCH_MP_TAC(SET_RULE
8309    `(!x. P x ==> f x = g x) ==> {f x | P x} = {g x | P x}`) THEN
8310   X_GEN_TAC `d:(real^M->bool)->bool` THEN
8311   DISCH_THEN(X_CHOOSE_THEN `t:real^M->bool` STRIP_ASSUME_TAC) THEN
8312   MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th ->
8313   GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION_NONEMPTY th]) THEN
8314   REPEAT STRIP_TAC THEN REWRITE_TAC[] THEN AP_TERM_TAC THEN
8315   FIRST_X_ASSUM MATCH_MP_TAC THEN
8316   ASM_MESON_TAC[division_of; SUBSET_TRANS]);;
8317
8318 let HAS_BOUNDED_SETVARIATION_ON_COMPONENTWISE = prove
8319  (`!f:(real^M->bool)->real^N s.
8320         f has_bounded_setvariation_on s <=>
8321         !i. 1 <= i /\ i <= dimindex(:N)
8322             ==> (\k. lift(f k$i)) has_bounded_setvariation_on s`,
8323   REPEAT GEN_TAC THEN
8324   REWRITE_TAC[has_bounded_setvariation_on; NORM_LIFT] THEN EQ_TAC THENL
8325    [DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
8326     X_GEN_TAC `i:num` THEN STRIP_TAC THEN EXISTS_TAC `B:real` THEN
8327     MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN
8328     STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL
8329       [`d:(real^M->bool)->bool`; `t:real^M->bool`]) THEN
8330     ASM_REWRITE_TAC[] THEN
8331     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN
8332     MATCH_MP_TAC SUM_LE THEN ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
8333     ASM_MESON_TAC[DIVISION_OF_FINITE];
8334     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
8335     REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
8336     X_GEN_TAC `B:num->real` THEN DISCH_TAC THEN
8337     EXISTS_TAC `sum (1..dimindex(:N)) B` THEN
8338     MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN
8339     STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
8340     EXISTS_TAC `sum d (\k. sum (1..dimindex(:N))
8341                            (\i. abs(((f:(real^M->bool)->real^N) k)$i)))` THEN
8342     FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
8343     ASM_SIMP_TAC[SUM_LE; NORM_LE_L1] THEN
8344     W(MP_TAC o PART_MATCH (lhs o rand) SUM_SWAP o lhand o snd) THEN
8345     ASM_SIMP_TAC[FINITE_NUMSEG] THEN DISCH_THEN SUBST1_TAC THEN
8346     MATCH_MP_TAC SUM_LE_NUMSEG THEN ASM_MESON_TAC[]]);;
8347
8348 let SETVARIATION_EQUAL_LEMMA = prove
8349  (`!mf:((real^M->bool)->real^N)->((real^M->bool)->real^N) ms ms'.
8350         (!s. ms'(ms s) = s /\ ms(ms' s) = s) /\
8351         (!f a b. ~(interval[a,b] = {})
8352                  ==> mf f (ms (interval[a,b])) = f (interval[a,b]) /\
8353                      ?a' b'. ~(interval[a',b'] = {}) /\
8354                              ms' (interval[a,b]) = interval[a',b']) /\
8355         (!t u. t SUBSET u ==> ms t SUBSET ms u /\ ms' t SUBSET ms' u) /\
8356         (!d t. d division_of t
8357                ==> (IMAGE ms d) division_of ms t /\
8358                    (IMAGE ms' d) division_of ms' t)
8359    ==> (!f s. (mf f) has_bounded_setvariation_on (ms s) <=>
8360               f has_bounded_setvariation_on s) /\
8361        (!f s. set_variation (ms s) (mf f) = set_variation s f)`,
8362   REPEAT GEN_TAC THEN STRIP_TAC THEN
8363   REWRITE_TAC[has_bounded_setvariation_on; set_variation] THEN
8364   MATCH_MP_TAC(MESON[]
8365    `((!f s. s1 f s = s2 f s) ==> P) /\
8366     (!f s. s1 f s = s2 f s)
8367     ==> P /\ (!f s. sup (s1 f s) = sup (s2 f s))`) THEN
8368   CONJ_TAC THENL
8369    [REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
8370     REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN MESON_TAC[];
8371     ALL_TAC] THEN
8372   REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN REPEAT GEN_TAC THEN EQ_TAC THEN
8373   STRIP_TAC THEN ASM_REWRITE_TAC[] THENL
8374    [EXISTS_TAC `IMAGE (ms':(real^M->bool)->real^M->bool) d`;
8375     EXISTS_TAC `IMAGE (ms:(real^M->bool)->real^M->bool) d`] THEN
8376   (CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
8377    W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE o rand o snd) THEN
8378    ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_THEN SUBST1_TAC]) THEN
8379   MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[o_THM] THEN FIRST_ASSUM
8380    (fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION_NONEMPTY th]) THEN
8381   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN STRIP_TAC THEN
8382   AP_TERM_TAC THEN ASM_SIMP_TAC[] THEN
8383   SUBGOAL_THEN `?a' b':real^M. ~(interval[a',b'] = {}) /\
8384                         ms' (interval[a:real^M,b]) = interval[a',b']`
8385   STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
8386   ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;
8387
8388 let HAS_BOUNDED_SETVARIATION_ON_ELEMENTARY = prove
8389  (`!f:(real^M->bool)->real^N s.
8390         (?d. d division_of s)
8391         ==> (f has_bounded_setvariation_on s <=>
8392              ?B. !d. d division_of s ==> sum d (\k. norm(f k)) <= B)`,
8393   REPEAT GEN_TAC THEN DISCH_TAC THEN
8394   REWRITE_TAC[has_bounded_setvariation_on] THEN EQ_TAC THEN
8395   MATCH_MP_TAC MONO_EXISTS THENL [MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN
8396   GEN_TAC THEN DISCH_TAC THEN
8397   MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN
8398   STRIP_TAC THEN FIRST_X_ASSUM(X_CHOOSE_TAC `d':(real^M->bool)->bool`) THEN
8399   MP_TAC(ISPECL [`d:(real^M->bool)->bool`; `d':(real^M->bool)->bool`;
8400              `t:real^M->bool`; `s:real^M->bool`] PARTIAL_DIVISION_EXTEND) THEN
8401   ASM_REWRITE_TAC[] THEN
8402   DISCH_THEN(X_CHOOSE_TAC `d'':(real^M->bool)->bool`) THEN
8403   MATCH_MP_TAC REAL_LE_TRANS THEN
8404   EXISTS_TAC `sum d'' (\k:real^M->bool. norm(f k:real^N))` THEN
8405   ASM_SIMP_TAC[] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
8406   ASM_REWRITE_TAC[NORM_POS_LE] THEN ASM_MESON_TAC[DIVISION_OF_FINITE]);;
8407
8408 let HAS_BOUNDED_SETVARIATION_ON_INTERVAL = prove
8409  (`!f:(real^M->bool)->real^N a b.
8410         f has_bounded_setvariation_on interval[a,b] <=>
8411         ?B. !d. d division_of interval[a,b] ==> sum d (\k. norm(f k)) <= B`,
8412   REPEAT GEN_TAC THEN MATCH_MP_TAC HAS_BOUNDED_SETVARIATION_ON_ELEMENTARY THEN
8413   REWRITE_TAC[ELEMENTARY_INTERVAL]);;
8414
8415 let HAS_BOUNDED_SETVARIATION_ON_UNIV = prove
8416  (`!f:(real^M->bool)->real^N.
8417         f has_bounded_setvariation_on (:real^M) <=>
8418         ?B. !d. d division_of UNIONS d ==> sum d (\k. norm(f k)) <= B`,
8419   REPEAT GEN_TAC THEN
8420   REWRITE_TAC[has_bounded_setvariation_on; SUBSET_UNIV] THEN
8421   MESON_TAC[DIVISION_OF_UNION_SELF]);;
8422
8423 let HAS_BOUNDED_SETVARIATION_ON_SUBSET = prove
8424  (`!f:(real^M->bool)->real^N s t.
8425         f has_bounded_setvariation_on s /\ t SUBSET s
8426         ==> f has_bounded_setvariation_on t`,
8427   REPEAT GEN_TAC THEN
8428   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
8429   REWRITE_TAC[has_bounded_setvariation_on] THEN
8430   MATCH_MP_TAC MONO_EXISTS THEN ASM_MESON_TAC[SUBSET_TRANS]);;
8431
8432 let HAS_BOUNDED_SETVARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS = prove
8433  (`!f:(real^M->bool)->real^N s.
8434         f has_bounded_setvariation_on s
8435         ==> bounded { f(interval[c,d]) | interval[c,d] SUBSET s}`,
8436   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_setvariation_on; bounded] THEN
8437   DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN
8438   EXISTS_TAC `max (abs B) (norm((f:(real^M->bool)->real^N) {}))` THEN
8439   REWRITE_TAC[FORALL_IN_GSPEC] THEN
8440   MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN DISCH_TAC THEN
8441   ASM_CASES_TAC `interval[c:real^M,d] = {}` THEN
8442   ASM_REWRITE_TAC[REAL_ARITH `a <= max b a`] THEN
8443   FIRST_X_ASSUM(MP_TAC o SPECL
8444    [`{interval[c:real^M,d]}`; `interval[c:real^M,d]`]) THEN
8445   ASM_SIMP_TAC[DIVISION_OF_SELF; SUM_SING] THEN REAL_ARITH_TAC);;
8446
8447 let HAS_BOUNDED_SETVARIATION_ON_NORM = prove
8448  (`!f:(real^M->bool)->real^N s.
8449         (\x. lift(norm(f x))) has_bounded_setvariation_on s <=>
8450         f has_bounded_setvariation_on s`,
8451   REWRITE_TAC[has_bounded_setvariation_on; NORM_REAL; GSYM drop] THEN
8452   REWRITE_TAC[REAL_ABS_NORM; LIFT_DROP]);;
8453
8454 let HAS_BOUNDED_SETVARIATION_ON_COMPOSE_LINEAR = prove
8455  (`!f:(real^M->bool)->real^N g:real^N->real^P s.
8456         f has_bounded_setvariation_on s /\ linear g
8457         ==> (g o f) has_bounded_setvariation_on s`,
8458   REPEAT GEN_TAC THEN
8459   REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON] THEN
8460   DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `B:real`) ASSUME_TAC) THEN
8461   FIRST_X_ASSUM(X_CHOOSE_TAC `C:real` o MATCH_MP LINEAR_BOUNDED_POS) THEN
8462   EXISTS_TAC `B * C:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN
8463   MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN
8464   STRIP_TAC THEN REWRITE_TAC[o_THM] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
8465   EXISTS_TAC `sum d (\k. C * norm((f:(real^M->bool)->real^N) k))` THEN
8466   CONJ_TAC THENL
8467    [MATCH_MP_TAC SUM_LE THEN ASM_MESON_TAC[DIVISION_OF_FINITE];
8468     GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN
8469     REWRITE_TAC[SUM_LMUL] THEN ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN
8470     ASM_MESON_TAC[]]);;
8471
8472 let HAS_BOUNDED_SETVARIATION_ON_0 = prove
8473  (`!s:real^N->bool. (\x. vec 0) has_bounded_setvariation_on s`,
8474   REWRITE_TAC[has_bounded_setvariation_on; NORM_0; SUM_0] THEN
8475   MESON_TAC[REAL_LE_REFL]);;
8476
8477 let SET_VARIATION_0 = prove
8478  (`!s:real^N->bool. set_variation s (\x. vec 0) = &0`,
8479   GEN_TAC THEN REWRITE_TAC[set_variation; NORM_0; SUM_0] THEN
8480   GEN_REWRITE_TAC RAND_CONV [GSYM SUP_SING] THEN
8481   AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_SING] THEN
8482   MESON_TAC[ELEMENTARY_EMPTY; EMPTY_SUBSET]);;
8483
8484 let HAS_BOUNDED_SETVARIATION_ON_CMUL = prove
8485  (`!f:(real^M->bool)->real^N c s.
8486         f has_bounded_setvariation_on s
8487         ==> (\x. c % f x) has_bounded_setvariation_on s`,
8488   REPEAT GEN_TAC THEN
8489   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT; o_DEF]
8490      HAS_BOUNDED_SETVARIATION_ON_COMPOSE_LINEAR) THEN
8491   REWRITE_TAC[linear] THEN VECTOR_ARITH_TAC);;
8492
8493 let HAS_BOUNDED_SETVARIATION_ON_NEG = prove
8494  (`!f:(real^M->bool)->real^N s.
8495         (\x. --(f x)) has_bounded_setvariation_on s <=>
8496         f has_bounded_setvariation_on s`,
8497   REWRITE_TAC[has_bounded_setvariation_on; NORM_NEG]);;
8498
8499 let HAS_BOUNDED_SETVARIATION_ON_ADD = prove
8500  (`!f:(real^M->bool)->real^N g s.
8501         f has_bounded_setvariation_on s /\
8502         g has_bounded_setvariation_on s
8503         ==> (\x. f x + g x) has_bounded_setvariation_on s`,
8504   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_setvariation_on] THEN
8505   DISCH_THEN(CONJUNCTS_THEN2
8506    (X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC)
8507    (X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC)) THEN
8508   EXISTS_TAC `B + C:real` THEN
8509   MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN
8510   STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
8511   EXISTS_TAC `sum d (\k. norm((f:(real^M->bool)->real^N) k)) +
8512               sum d (\k. norm((g:(real^M->bool)->real^N) k))` THEN
8513   CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LE_ADD2]] THEN
8514   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
8515   ASM_SIMP_TAC[GSYM SUM_ADD] THEN
8516   MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[NORM_TRIANGLE]);;
8517
8518 let HAS_BOUNDED_SETVARIATION_ON_SUB = prove
8519  (`!f:(real^M->bool)->real^N g s.
8520         f has_bounded_setvariation_on s /\
8521         g has_bounded_setvariation_on s
8522         ==> (\x. f x - g x) has_bounded_setvariation_on s`,
8523   REWRITE_TAC[VECTOR_ARITH `x - y:real^N = x + --y`] THEN
8524   SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_ADD; HAS_BOUNDED_SETVARIATION_ON_NEG]);;
8525
8526 let HAS_BOUNDED_SETVARIATION_ON_NULL = prove
8527  (`!f:(real^M->bool)->real^N s.
8528         (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = vec 0) /\
8529         content s = &0 /\ bounded s
8530         ==> f has_bounded_setvariation_on s`,
8531   REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_setvariation_on] THEN
8532   EXISTS_TAC `&0` THEN REPEAT STRIP_TAC THEN
8533   MATCH_MP_TAC(REAL_ARITH `x = &0 ==> x <= &0`) THEN
8534   MATCH_MP_TAC SUM_EQ_0 THEN REWRITE_TAC[NORM_EQ_0] THEN
8535   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
8536   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
8537   MATCH_MP_TAC CONTENT_0_SUBSET_GEN THEN
8538   EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN
8539   ASM_MESON_TAC[division_of; SUBSET_TRANS]);;
8540
8541 let SET_VARIATION_ELEMENTARY_LEMMA = prove
8542  (`!f:(real^M->bool)->real^N s.
8543         (?d. d division_of s)
8544         ==> ((!d t. d division_of t /\ t SUBSET s
8545                     ==> sum d (\k. norm(f k)) <= b) <=>
8546              (!d. d division_of s ==> sum d (\k. norm(f k)) <= b))`,
8547   REPEAT GEN_TAC THEN DISCH_THEN(X_CHOOSE_TAC `d1:(real^M->bool)->bool`) THEN
8548   EQ_TAC THENL [MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN
8549   DISCH_TAC THEN X_GEN_TAC `d2:(real^M->bool)->bool` THEN
8550   X_GEN_TAC `t:real^M->bool` THEN STRIP_TAC THEN MP_TAC(ISPECL
8551    [`d2:(real^M->bool)->bool`; `d1:(real^M->bool)->bool`;
8552     `t:real^M->bool`; `s:real^M->bool`] PARTIAL_DIVISION_EXTEND) THEN
8553   ASM_REWRITE_TAC[] THEN
8554   DISCH_THEN(X_CHOOSE_TAC `d3:(real^M->bool)->bool`) THEN
8555   MATCH_MP_TAC REAL_LE_TRANS THEN
8556   EXISTS_TAC `sum d3 (\k:real^M->bool. norm(f k:real^N))` THEN
8557   ASM_SIMP_TAC[] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
8558   ASM_REWRITE_TAC[NORM_POS_LE] THEN ASM_MESON_TAC[DIVISION_OF_FINITE]);;
8559
8560 let SET_VARIATION_ON_ELEMENTARY = prove
8561  (`!f:(real^M->bool)->real^N s.
8562         (?d. d division_of s)
8563         ==> set_variation s f =
8564              sup { sum d (\k. norm(f k)) | d division_of s}`,
8565   REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[set_variation; sup] THEN
8566   REWRITE_TAC[FORALL_IN_GSPEC; LEFT_IMP_EXISTS_THM] THEN
8567   ASM_SIMP_TAC[SET_VARIATION_ELEMENTARY_LEMMA]);;
8568
8569 let SET_VARIATION_ON_INTERVAL = prove
8570  (`!f:(real^M->bool)->real^N a b.
8571         set_variation (interval[a,b]) f =
8572         sup { sum d (\k. norm(f k)) | d division_of interval[a,b]}`,
8573   REPEAT GEN_TAC THEN MATCH_MP_TAC SET_VARIATION_ON_ELEMENTARY THEN
8574   REWRITE_TAC[ELEMENTARY_INTERVAL]);;
8575
8576 let HAS_BOUNDED_SETVARIATION_WORKS = prove
8577  (`!f:(real^M->bool)->real^N s.
8578         f has_bounded_setvariation_on s
8579         ==> (!d t. d division_of t /\ t SUBSET s
8580                    ==> sum d (\k. norm(f k)) <= set_variation s f) /\
8581             (!B. (!d t. d division_of t /\ t SUBSET s
8582                         ==> sum d (\k. norm (f k)) <= B)
8583                  ==> set_variation s f <= B)`,
8584   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_setvariation_on] THEN
8585   DISCH_TAC THEN
8586   MP_TAC(ISPEC `{ sum d (\k. norm((f:(real^M->bool)->real^N) k)) |
8587                   ?t. d division_of t /\ t SUBSET s}`
8588          SUP) THEN
8589   REWRITE_TAC[FORALL_IN_GSPEC; LEFT_IMP_EXISTS_THM] THEN
8590   REWRITE_TAC[set_variation] THEN DISCH_THEN MATCH_MP_TAC THEN
8591   ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
8592   MAP_EVERY EXISTS_TAC [`&0`; `{}:(real^M->bool)->bool`] THEN
8593   REWRITE_TAC[SUM_CLAUSES] THEN EXISTS_TAC `{}:real^M->bool` THEN
8594   SIMP_TAC[division_of; EMPTY_SUBSET; NOT_IN_EMPTY; FINITE_EMPTY; UNIONS_0]);;
8595
8596 let HAS_BOUNDED_SETVARIATION_WORKS_ON_ELEMENTARY = prove
8597  (`!f:(real^M->bool)->real^N s.
8598         f has_bounded_setvariation_on s /\ (?d. d division_of s)
8599         ==> (!d. d division_of s
8600                  ==> sum d (\k. norm(f k)) <= set_variation s f) /\
8601             (!B. (!d. d division_of s ==> sum d (\k. norm(f k)) <= B)
8602                  ==> set_variation s f <= B)`,
8603   SIMP_TAC[GSYM SET_VARIATION_ELEMENTARY_LEMMA] THEN
8604   MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS]);;
8605
8606 let HAS_BOUNDED_SETVARIATION_WORKS_ON_INTERVAL = prove
8607  (`!f:(real^M->bool)->real^N a b.
8608       f has_bounded_setvariation_on interval[a,b]
8609       ==> (!d. d division_of interval[a,b]
8610                ==> sum d (\k. norm(f k)) <= set_variation (interval[a,b]) f) /\
8611           (!B. (!d. d division_of interval[a,b]
8612                     ==> sum d (\k. norm(f k)) <= B)
8613                ==> set_variation (interval[a,b]) f <= B)`,
8614   SIMP_TAC[HAS_BOUNDED_SETVARIATION_WORKS_ON_ELEMENTARY; ELEMENTARY_INTERVAL]);;
8615
8616 let SET_VARIATION_UBOUND = prove
8617  (`!f:(real^M->bool)->real^N s B.
8618         f has_bounded_setvariation_on s /\
8619         (!d t. d division_of t /\ t SUBSET s ==> sum d (\k. norm(f k)) <= B)
8620         ==> set_variation s f <= B`,
8621   MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS]);;
8622
8623 let SET_VARIATION_UBOUND_ON_INTERVAL = prove
8624  (`!f:(real^M->bool)->real^N a b B.
8625         f has_bounded_setvariation_on interval[a,b] /\
8626         (!d. d division_of interval[a,b] ==> sum d (\k. norm(f k)) <= B)
8627         ==> set_variation (interval[a,b]) f <= B`,
8628   SIMP_TAC[GSYM SET_VARIATION_ELEMENTARY_LEMMA; ELEMENTARY_INTERVAL] THEN
8629   MESON_TAC[SET_VARIATION_UBOUND]);;
8630
8631 let SET_VARIATION_LBOUND = prove
8632  (`!f:(real^M->bool)->real^N s B.
8633         f has_bounded_setvariation_on s /\
8634         (?d t. d division_of t /\ t SUBSET s /\ B <= sum d (\k. norm(f k)))
8635         ==> B <= set_variation s f`,
8636   MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS; REAL_LE_TRANS]);;
8637
8638 let SET_VARIATION_LBOUND_ON_INTERVAL = prove
8639  (`!f:(real^M->bool)->real^N a b B.
8640         f has_bounded_setvariation_on interval[a,b] /\
8641         (?d. d division_of interval[a,b] /\ B <= sum d (\k. norm(f k)))
8642         ==> B <= set_variation (interval[a,b]) f`,
8643   MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS_ON_INTERVAL; REAL_LE_TRANS]);;
8644
8645 let SET_VARIATION = prove
8646  (`!f:(real^M->bool)->real^N s d t.
8647         f has_bounded_setvariation_on s /\ d division_of t /\ t SUBSET s
8648         ==> sum d (\k. norm(f k)) <= set_variation s f`,
8649   MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS]);;
8650
8651 let SET_VARIATION_WORKS_ON_INTERVAL = prove
8652  (`!f:(real^M->bool)->real^N a b d.
8653         f has_bounded_setvariation_on interval[a,b] /\
8654         d division_of interval[a,b]
8655         ==> sum d (\k. norm(f k)) <= set_variation (interval[a,b]) f`,
8656   MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS_ON_INTERVAL]);;
8657
8658 let SET_VARIATION_POS_LE = prove
8659  (`!f:(real^M->bool)->real^N s.
8660         f has_bounded_setvariation_on s ==> &0 <= set_variation s f`,
8661   REPEAT STRIP_TAC THEN
8662   FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] SET_VARIATION)) THEN
8663   DISCH_THEN(MP_TAC o SPECL[`{}:(real^M->bool)->bool`; `{}:real^M->bool`]) THEN
8664   REWRITE_TAC[EMPTY_SUBSET; SUM_CLAUSES; DIVISION_OF_TRIVIAL]);;
8665
8666 let SET_VARIATION_GE_FUNCTION = prove
8667  (`!f:(real^M->bool)->real^N s a b.
8668         f has_bounded_setvariation_on s /\
8669         interval[a,b] SUBSET s /\ ~(interval[a,b] = {})
8670         ==> norm(f(interval[a,b])) <= set_variation s f`,
8671   REPEAT STRIP_TAC THEN MATCH_MP_TAC SET_VARIATION_LBOUND THEN
8672   ASM_REWRITE_TAC[] THEN EXISTS_TAC `{interval[a:real^M,b]}` THEN
8673   EXISTS_TAC `interval[a:real^M,b]` THEN
8674   ASM_REWRITE_TAC[SUM_SING; REAL_LE_REFL] THEN
8675   ASM_SIMP_TAC[DIVISION_OF_SELF]);;
8676
8677 let SET_VARIATION_ON_NULL = prove
8678  (`!f:(real^M->bool)->real^N s.
8679         (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = vec 0) /\
8680         content s = &0 /\ bounded s
8681         ==> set_variation s f = &0`,
8682   REPEAT STRIP_TAC THEN
8683   ONCE_REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
8684    [MATCH_MP_TAC SET_VARIATION_UBOUND THEN
8685     ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_NULL] THEN
8686     REPEAT STRIP_TAC THEN
8687     MATCH_MP_TAC(REAL_ARITH `x = &0 ==> x <= &0`) THEN
8688     MATCH_MP_TAC SUM_EQ_0 THEN REWRITE_TAC[NORM_EQ_0] THEN
8689     FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
8690     REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
8691     MATCH_MP_TAC CONTENT_0_SUBSET_GEN THEN
8692     EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN
8693     ASM_MESON_TAC[division_of; SUBSET_TRANS];
8694     MATCH_MP_TAC SET_VARIATION_POS_LE THEN
8695     ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_NULL]]);;
8696
8697 let SET_VARIATION_TRIANGLE = prove
8698  (`!f:(real^M->bool)->real^N g s.
8699         f has_bounded_setvariation_on s /\
8700         g has_bounded_setvariation_on s
8701         ==> set_variation s (\x. f x + g x)
8702              <= set_variation s f + set_variation s g`,
8703   REPEAT STRIP_TAC THEN MATCH_MP_TAC SET_VARIATION_UBOUND THEN
8704   ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_ADD] THEN
8705   MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN
8706   STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
8707   EXISTS_TAC `sum d (\k. norm((f:(real^M->bool)->real^N) k)) +
8708               sum d (\k. norm((g:(real^M->bool)->real^N) k))` THEN
8709   CONJ_TAC THENL
8710    [FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
8711     ASM_SIMP_TAC[GSYM SUM_ADD] THEN
8712     MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[NORM_TRIANGLE];
8713     MATCH_MP_TAC REAL_LE_ADD2 THEN
8714     CONJ_TAC THEN MATCH_MP_TAC SET_VARIATION THEN ASM_MESON_TAC[]]);;
8715
8716 let OPERATIVE_LIFTED_SETVARIATION = prove
8717  (`!f:(real^M->bool)->real^N.
8718         operative(+) f
8719         ==> operative (lifted(+))
8720                       (\i. if f has_bounded_setvariation_on i
8721                            then SOME(set_variation i f) else NONE)`,
8722   let lemma1 = prove
8723    (`!f:(real^M->bool)->real B1 B2 k a b.
8724       1 <= k /\ k <= dimindex(:M) /\
8725       (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = &0) /\
8726       (!a b c. f(interval[a,b]) <=
8727                f(interval[a,b] INTER {x | x$k <= c}) +
8728                f(interval[a,b] INTER {x | x$k >= c})) /\
8729       (!d. d division_of (interval[a,b] INTER {x | x$k <= c})
8730            ==> sum d f <= B1) /\
8731       (!d. d division_of (interval[a,b] INTER {x | x$k >= c})
8732            ==> sum d f <= B2)
8733       ==> !d. d division_of interval[a,b] ==> sum d f <= B1 + B2`,
8734     REPEAT GEN_TAC THEN
8735     REPLICATE_TAC 4 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
8736     DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "L") (LABEL_TAC "R")) THEN
8737     GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
8738     EXISTS_TAC
8739      `sum {l INTER {x:real^M | x$k <= c} | l | l IN d /\
8740                                         ~(l INTER {x | x$k <= c} = {})} f +
8741       sum {l INTER {x | x$k >= c} | l | l IN d /\
8742                                         ~(l INTER {x | x$k >= c} = {})} f` THEN
8743     CONJ_TAC THENL
8744      [ALL_TAC;
8745       MATCH_MP_TAC REAL_LE_ADD2 THEN CONJ_TAC THEN
8746       FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[DIVISION_SPLIT]] THEN
8747     ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
8748     FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
8749     W(fun (asl,w) ->
8750          MP_TAC(PART_MATCH (lhs o rand) SUM_IMAGE_NONZERO (lhand(rand w))) THEN
8751          MP_TAC(PART_MATCH (lhs o rand) SUM_IMAGE_NONZERO (rand(rand w)))) THEN
8752     MATCH_MP_TAC(TAUT
8753      `(a1 /\ a2) /\ (b1 /\ b2 ==> c)
8754       ==> (a1 ==> b1) ==> (a2 ==> b2) ==> c`) THEN
8755     CONJ_TAC THENL
8756      [ASM_SIMP_TAC[FINITE_RESTRICT; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
8757       REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ] THEN
8758       FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
8759       REPEAT STRIP_TAC THEN ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
8760       FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THENL
8761        [MATCH_MP_TAC DIVISION_SPLIT_RIGHT_INJ;
8762         MATCH_MP_TAC DIVISION_SPLIT_LEFT_INJ] THEN
8763       ASM_MESON_TAC[];
8764       DISCH_THEN(CONJUNCTS_THEN SUBST1_TAC)] THEN
8765     MATCH_MP_TAC REAL_LE_TRANS THEN
8766     EXISTS_TAC
8767      `sum d (f o (\l. l INTER {x | x$k <= c})) +
8768       sum d (f o (\l. l INTER {x:real^M | x$k >= c}))` THEN
8769     CONJ_TAC THENL
8770      [ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN
8771       ASM_REWRITE_TAC[o_THM] THEN
8772       FIRST_ASSUM(fun th -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]);
8773       MATCH_MP_TAC(REAL_ARITH `x = y /\ w = z ==> x + w <= y + z`) THEN
8774       CONJ_TAC THEN MATCH_MP_TAC SUM_SUPERSET THEN
8775       REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} SUBSET s`] THEN
8776       REWRITE_TAC[SET_RULE `(x IN s /\ ~(x IN {x | x IN s /\ ~P x}) ==> Q x) <=>
8777                             (x IN s ==> P x ==> Q x)`] THEN
8778       SIMP_TAC[o_THM] THEN ASM_MESON_TAC[EMPTY_AS_INTERVAL; CONTENT_EMPTY]])
8779   and lemma2 = prove
8780    (`!f:(real^M->bool)->real B k.
8781       1 <= k /\ k <= dimindex(:M) /\
8782       (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = &0) /\
8783       (!d. d division_of interval[a,b] ==> sum d f <= B)
8784       ==> !d1 d2. d1 division_of (interval[a,b] INTER {x | x$k <= c}) /\
8785                   d2 division_of (interval[a,b] INTER {x | x$k >= c})
8786                   ==> sum d1 f + sum d2 f <= B`,
8787     REPEAT STRIP_TAC THEN
8788     FIRST_X_ASSUM(MP_TAC o SPEC `d1 UNION d2:(real^M->bool)->bool`) THEN
8789     ANTS_TAC THENL
8790      [SUBGOAL_THEN
8791        `interval[a,b] = (interval[a,b] INTER {x:real^M | x$k <= c}) UNION
8792                         (interval[a,b] INTER {x:real^M | x$k >= c})`
8793       SUBST1_TAC THENL
8794        [MATCH_MP_TAC(SET_RULE
8795          `(!x. x IN t \/ x IN u) ==> (s = s INTER t UNION s INTER u)`) THEN
8796         REWRITE_TAC[IN_ELIM_THM] THEN REAL_ARITH_TAC;
8797         MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN ASM_REWRITE_TAC[] THEN
8798         REWRITE_TAC[GSYM INTERIOR_INTER] THEN
8799         MATCH_MP_TAC(SET_RULE
8800          `!t. interior s SUBSET interior t /\ interior t = {}
8801               ==> interior s = {}`) THEN
8802         EXISTS_TAC `{x:real^M | x$k = c}` THEN CONJ_TAC THENL
8803          [ALL_TAC; REWRITE_TAC[INTERIOR_STANDARD_HYPERPLANE]] THEN
8804         MATCH_MP_TAC SUBSET_INTERIOR THEN
8805         REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN REAL_ARITH_TAC];
8806       MATCH_MP_TAC(REAL_ARITH `x = y ==> x <= b ==> y <= b`) THEN
8807       MATCH_MP_TAC SUM_UNION_NONZERO THEN
8808       REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_FINITE]; ALL_TAC]) THEN
8809       X_GEN_TAC `k:real^M->bool` THEN REWRITE_TAC[IN_INTER] THEN STRIP_TAC THEN
8810       SUBGOAL_THEN `?u v:real^M. k = interval[u,v]`
8811         (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
8812       THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
8813       FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC CONTENT_0_SUBSET_GEN THEN
8814       EXISTS_TAC `interval[a,b] INTER {x:real^M | x$k = c}` THEN CONJ_TAC THENL
8815        [MATCH_MP_TAC SUBSET_TRANS THEN
8816         EXISTS_TAC `(interval[a,b] INTER {x:real^M | x$k <= c}) INTER
8817                     (interval[a,b] INTER {x:real^M | x$k >= c})` THEN
8818         CONJ_TAC THENL
8819          [ONCE_REWRITE_TAC[SUBSET_INTER] THEN ASM_MESON_TAC[division_of];
8820           REWRITE_TAC[SET_RULE
8821             `(s INTER t) INTER (s INTER u) = s INTER t INTER u`] THEN
8822           SIMP_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN REAL_ARITH_TAC];
8823         SIMP_TAC[BOUNDED_INTER; BOUNDED_INTERVAL] THEN
8824         GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
8825          [REAL_ARITH `x = y <=> x <= y /\ x >= y`] THEN
8826         REWRITE_TAC[SET_RULE
8827          `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN
8828         ASM_SIMP_TAC[GSYM INTER_ASSOC; INTERVAL_SPLIT] THEN
8829         REWRITE_TAC[CONTENT_EQ_0] THEN EXISTS_TAC `k:num` THEN
8830         ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC]]) in
8831   REWRITE_TAC[operative; NEUTRAL_VECTOR_ADD] THEN REPEAT GEN_TAC THEN
8832   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (ASSUME_TAC o GSYM)) THEN
8833   ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_NULL; BOUNDED_INTERVAL;
8834    MONOIDAL_REAL_ADD; SET_VARIATION_ON_NULL; NEUTRAL_LIFTED;
8835    NEUTRAL_REAL_ADD] THEN
8836   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real`; `k:num`] THEN
8837   STRIP_TAC THEN ASM_CASES_TAC
8838    `(f:(real^M->bool)->real^N) has_bounded_setvariation_on interval[a,b]` THEN
8839   ASM_REWRITE_TAC[] THENL
8840    [SUBGOAL_THEN
8841      `(f:(real^M->bool)->real^N) has_bounded_setvariation_on
8842       interval[a,b] INTER {x | x$k <= c} /\
8843       (f:(real^M->bool)->real^N) has_bounded_setvariation_on
8844       interval[a,b] INTER {x | x$k >= c}`
8845     ASSUME_TAC THENL
8846      [CONJ_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
8847        (REWRITE_RULE[IMP_CONJ] HAS_BOUNDED_SETVARIATION_ON_SUBSET)) THEN
8848       REWRITE_TAC[INTER_SUBSET];
8849       ALL_TAC] THEN
8850     ASM_REWRITE_TAC[lifted] THEN AP_TERM_TAC THEN
8851     REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
8852      [MATCH_MP_TAC SET_VARIATION_UBOUND_ON_INTERVAL THEN ASM_REWRITE_TAC[] THEN
8853       REPEAT STRIP_TAC THEN MATCH_MP_TAC
8854        (REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM] lemma1) THEN
8855       MAP_EVERY EXISTS_TAC [`k:num`; `a:real^M`; `b:real^M`] THEN
8856       ASM_SIMP_TAC[NORM_0] THEN CONJ_TAC THENL
8857        [REPEAT GEN_TAC THEN
8858         MATCH_MP_TAC(NORM_ARITH
8859           `x:real^N = y + z ==> norm(x) <= norm y + norm z`) THEN
8860         ASM_SIMP_TAC[];
8861         FIRST_X_ASSUM(fun th -> MP_TAC th THEN MATCH_MP_TAC MONO_AND) THEN
8862         ASM_SIMP_TAC[INTERVAL_SPLIT; SET_VARIATION_WORKS_ON_INTERVAL]];
8863       ONCE_REWRITE_TAC[REAL_ARITH `x + y <= z <=> x <= z - y`] THEN
8864       ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
8865       MATCH_MP_TAC SET_VARIATION_UBOUND_ON_INTERVAL THEN
8866       ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THEN
8867       X_GEN_TAC `d1:(real^M->bool)->bool` THEN STRIP_TAC THEN
8868       ONCE_REWRITE_TAC[REAL_ARITH `x <= y - z <=> z <= y - x`] THEN
8869       ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
8870       MATCH_MP_TAC SET_VARIATION_UBOUND_ON_INTERVAL THEN
8871       ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THEN
8872       X_GEN_TAC `d2:(real^M->bool)->bool` THEN STRIP_TAC THEN
8873       REWRITE_TAC[REAL_ARITH `x <= y - z <=> z + x <= y`] THEN
8874       REPEAT STRIP_TAC THEN MATCH_MP_TAC
8875        (REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM] lemma2) THEN
8876       EXISTS_TAC `k:num` THEN
8877       ASM_SIMP_TAC[NORM_0; SET_VARIATION_WORKS_ON_INTERVAL]];
8878     REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[lifted]) THEN
8879     FIRST_X_ASSUM(MP_TAC o check (is_neg o concl)) THEN
8880     MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN
8881     REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_INTERVAL] THEN
8882     EXISTS_TAC `set_variation (interval[a,b] INTER {x | x$k <= c})
8883                               (f:(real^M->bool)->real^N) +
8884                 set_variation (interval[a,b] INTER {x | x$k >= c}) f` THEN
8885     REPEAT STRIP_TAC THEN MATCH_MP_TAC
8886        (REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM] lemma1) THEN
8887       MAP_EVERY EXISTS_TAC [`k:num`; `a:real^M`; `b:real^M`] THEN
8888       ASM_SIMP_TAC[NORM_0] THEN REPEAT CONJ_TAC THENL
8889        [REPEAT GEN_TAC THEN
8890         MATCH_MP_TAC(NORM_ARITH
8891           `x:real^N = y + z ==> norm(x) <= norm y + norm z`) THEN
8892         ASM_SIMP_TAC[];
8893         UNDISCH_TAC
8894          `(f:(real^M->bool)->real^N) has_bounded_setvariation_on
8895           (interval[a,b] INTER {x | x$k <= c})` THEN
8896         ASM_SIMP_TAC[INTERVAL_SPLIT; SET_VARIATION_WORKS_ON_INTERVAL];
8897         UNDISCH_TAC
8898          `(f:(real^M->bool)->real^N) has_bounded_setvariation_on
8899           (interval[a,b] INTER {x | x$k >= c})` THEN
8900         ASM_SIMP_TAC[INTERVAL_SPLIT; SET_VARIATION_WORKS_ON_INTERVAL]]]);;
8901
8902 let HAS_BOUNDED_SETVARIATION_ON_DIVISION = prove
8903  (`!f:(real^M->bool)->real^N a b d.
8904         operative (+) f /\ d division_of interval[a,b]
8905         ==> ((!k. k IN d ==> f has_bounded_setvariation_on k) <=>
8906              f has_bounded_setvariation_on interval[a,b])`,
8907   REPEAT STRIP_TAC THEN MATCH_MP_TAC OPERATIVE_DIVISION_AND THEN
8908   ASM_REWRITE_TAC[operative; NEUTRAL_AND] THEN CONJ_TAC THENL
8909    [RULE_ASSUM_TAC(REWRITE_RULE[operative; NEUTRAL_VECTOR_ADD]) THEN
8910     ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_NULL; BOUNDED_INTERVAL];
8911     FIRST_ASSUM(MP_TAC o MATCH_MP OPERATIVE_LIFTED_SETVARIATION) THEN
8912     REWRITE_TAC[operative] THEN DISCH_THEN(MP_TAC o CONJUNCT2) THEN
8913     REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
8914     REPEAT(COND_CASES_TAC THEN
8915            ASM_REWRITE_TAC[lifted; distinctness "option"])]);;
8916
8917 let SET_VARIATION_ON_DIVISION = prove
8918  (`!f:(real^M->bool)->real^N a b d.
8919         operative (+) f /\ d division_of interval[a,b] /\
8920         f has_bounded_setvariation_on interval[a,b]
8921         ==> sum d (\k. set_variation k f) = set_variation (interval[a,b]) f`,
8922   let lemma0 = prove
8923    (`!op x y. lifted op (SOME x) y = SOME z <=> ?w. y = SOME w /\ op x w = z`,
8924     GEN_TAC THEN GEN_TAC THEN MATCH_MP_TAC option_INDUCT THEN
8925     REWRITE_TAC[lifted; distinctness "option"; injectivity "option"] THEN
8926     MESON_TAC[]) in
8927   let lemma = prove
8928    (`!P op f s z.
8929           monoidal op /\ FINITE s /\
8930           iterate(lifted op) s (\i. if P i then SOME(f i) else NONE) = SOME z
8931           ==> iterate op s f = z`,
8932     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
8933     REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
8934     MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
8935     ASM_SIMP_TAC[ITERATE_CLAUSES; MONOIDAL_LIFTED; NEUTRAL_LIFTED] THEN
8936     REWRITE_TAC[injectivity "option"] THEN REPEAT GEN_TAC THEN
8937     STRIP_TAC THEN GEN_TAC THEN COND_CASES_TAC THEN
8938     REWRITE_TAC[lifted; distinctness "option"] THEN ASM_MESON_TAC[lemma0]) in
8939   REPEAT STRIP_TAC THEN
8940   FIRST_ASSUM(MP_TAC o MATCH_MP OPERATIVE_LIFTED_SETVARIATION) THEN
8941   DISCH_THEN(MP_TAC o SPECL[`d:(real^M->bool)->bool`; `a:real^M`; `b:real^M`] o
8942     MATCH_MP (REWRITE_RULE [TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`]
8943         OPERATIVE_DIVISION)) THEN
8944   ASM_SIMP_TAC[MONOIDAL_LIFTED; MONOIDAL_REAL_ADD] THEN
8945   MP_TAC(ISPECL
8946    [`\k. (f:(real^M->bool)->real^N) has_bounded_setvariation_on k`;
8947     `(+):real->real->real`;
8948     `\k. set_variation k (f:(real^M->bool)->real^N)`;
8949     `d:(real^M->bool)->bool`;
8950     `set_variation (interval[a,b]) (f:(real^M->bool)->real^N)`]
8951    lemma) THEN
8952   FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
8953   ASM_REWRITE_TAC[sum; MONOIDAL_REAL_ADD]);;
8954
8955 let SET_VARIATION_MONOTONE = prove
8956  (`!f:(real^M->bool)->real^N s t.
8957         f has_bounded_setvariation_on s /\ t SUBSET s
8958         ==> set_variation t f <= set_variation s f`,
8959   REPEAT STRIP_TAC THEN REWRITE_TAC[set_variation] THEN
8960   MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN REPEAT CONJ_TAC THENL
8961    [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
8962     MAP_EVERY EXISTS_TAC [`&0`; `{}:(real^M->bool)->bool`] THEN
8963     REWRITE_TAC[SUM_CLAUSES] THEN EXISTS_TAC `{}:real^M->bool` THEN
8964     REWRITE_TAC[EMPTY_SUBSET; DIVISION_OF_TRIVIAL];
8965     MATCH_MP_TAC(SET_RULE
8966      `(!d. P d ==> Q d) ==> {f d | P d} SUBSET {f d | Q d}`) THEN
8967     ASM_MESON_TAC[SUBSET_TRANS];
8968     REWRITE_TAC[FORALL_IN_GSPEC; LEFT_IMP_EXISTS_THM] THEN
8969     ASM_REWRITE_TAC[GSYM has_bounded_setvariation_on]]);;
8970
8971 let HAS_BOUNDED_SETVARIATION_REFLECT2_EQ,SET_VARIATION_REFLECT2 =
8972  (CONJ_PAIR o prove)
8973  (`(!f:(real^M->bool)->real^N s.
8974         (\k. f(IMAGE (--) k)) has_bounded_setvariation_on (IMAGE (--) s) <=>
8975         f has_bounded_setvariation_on s) /\
8976    (!f:(real^M->bool)->real^N s.
8977         set_variation (IMAGE (--) s) (\k. f(IMAGE (--) k)) =
8978         set_variation s f)`,
8979   MATCH_MP_TAC SETVARIATION_EQUAL_LEMMA THEN
8980   EXISTS_TAC `IMAGE ((--):real^M->real^M)` THEN
8981   SIMP_TAC[IMAGE_SUBSET; GSYM IMAGE_o; o_DEF] THEN
8982   REWRITE_TAC[VECTOR_NEG_NEG; IMAGE_ID; REFLECT_INTERVAL] THEN
8983   SIMP_TAC[ETA_AX; DIVISION_OF_REFLECT] THEN
8984   SIMP_TAC[EQ_INTERVAL; TAUT `~q /\ (p /\ q \/ r) <=> ~q /\ r`] THEN
8985   REWRITE_TAC[TAUT `p /\ q /\ r <=> r /\ q /\ p`] THEN
8986   REWRITE_TAC[UNWIND_THM1; CONTRAPOS_THM] THEN
8987   REWRITE_TAC[INTERVAL_EQ_EMPTY; VECTOR_NEG_COMPONENT; REAL_LT_NEG2]);;
8988
8989 let HAS_BOUNDED_SETVARIATION_TRANSLATION2_EQ, SET_VARIATION_TRANSLATION2 =
8990  (CONJ_PAIR o prove)
8991  (`(!a f:(real^M->bool)->real^N s.
8992           (\k. f(IMAGE (\x. a + x) k))
8993           has_bounded_setvariation_on (IMAGE (\x. --a + x) s) <=>
8994           f has_bounded_setvariation_on s) /\
8995    (!a f:(real^M->bool)->real^N s.
8996           set_variation (IMAGE (\x. --a + x) s) (\k. f(IMAGE (\x. a + x) k)) =
8997           set_variation s f)`,
8998   GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `a:real^M` THEN
8999   MATCH_MP_TAC SETVARIATION_EQUAL_LEMMA THEN
9000   EXISTS_TAC `\s. IMAGE (\x:real^M. a + x) s` THEN
9001   SIMP_TAC[IMAGE_SUBSET; GSYM IMAGE_o; o_DEF] THEN
9002   REWRITE_TAC[VECTOR_ARITH `a + --a + x:real^N = x`; IMAGE_ID;
9003               VECTOR_ARITH `--a + a + x:real^N = x`] THEN
9004   REWRITE_TAC[GSYM INTERVAL_TRANSLATION] THEN
9005   SIMP_TAC[EQ_INTERVAL; TAUT `~q /\ (p /\ q \/ r) <=> ~q /\ r`] THEN
9006   REWRITE_TAC[TAUT `p /\ q /\ r <=> r /\ q /\ p`] THEN
9007   REWRITE_TAC[UNWIND_THM1; CONTRAPOS_THM] THEN
9008   REWRITE_TAC[INTERVAL_EQ_EMPTY; VECTOR_ADD_COMPONENT; REAL_LT_LADD] THEN
9009   REPEAT STRIP_TAC THEN
9010   GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [ETA_AX] THEN
9011   ASM_SIMP_TAC[DIVISION_OF_TRANSLATION]);;
9012
9013 let HAS_BOUNDED_SETVARIATION_TRANSLATION = prove
9014  (`!f:(real^M->bool)->real^N s a.
9015         f has_bounded_setvariation_on s
9016         ==> (\k. f(IMAGE (\x. a + x) k))
9017             has_bounded_setvariation_on (IMAGE (\x. --a + x) s)`,
9018   REWRITE_TAC[HAS_BOUNDED_SETVARIATION_TRANSLATION2_EQ]);;
9019
9020 (* ------------------------------------------------------------------------- *)
9021 (* Absolute integrability (this is the same as Lebesgue integrability).      *)
9022 (* ------------------------------------------------------------------------- *)
9023
9024 parse_as_infix("absolutely_integrable_on",(12,"right"));;
9025
9026 let absolutely_integrable_on = new_definition
9027  `f absolutely_integrable_on s <=>
9028         f integrable_on s /\ (\x. lift(norm(f x))) integrable_on s`;;
9029
9030 let ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE = prove
9031  (`!f s. f absolutely_integrable_on s ==> f integrable_on s`,
9032   SIMP_TAC[absolutely_integrable_on]);;
9033
9034 let ABSOLUTELY_INTEGRABLE_LE = prove
9035  (`!f:real^M->real^N s.
9036         f absolutely_integrable_on s
9037         ==> norm(integral s f) <= drop(integral s (\x. lift(norm(f x))))`,
9038   REWRITE_TAC[absolutely_integrable_on] THEN
9039   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
9040   ASM_REWRITE_TAC[LIFT_DROP; REAL_LE_REFL]);;
9041
9042 let ABSOLUTELY_INTEGRABLE_ON_NULL = prove
9043  (`!f a b. content(interval[a,b]) = &0
9044            ==> f absolutely_integrable_on interval[a,b]`,
9045   SIMP_TAC[absolutely_integrable_on; INTEGRABLE_ON_NULL]);;
9046
9047 let ABSOLUTELY_INTEGRABLE_0 = prove
9048  (`!s. (\x. vec 0) absolutely_integrable_on s`,
9049   REWRITE_TAC[absolutely_integrable_on; NORM_0; LIFT_NUM; INTEGRABLE_0]);;
9050
9051 let ABSOLUTELY_INTEGRABLE_CMUL = prove
9052  (`!f s c. f absolutely_integrable_on s
9053            ==> (\x. c % f(x)) absolutely_integrable_on s`,
9054   SIMP_TAC[absolutely_integrable_on; INTEGRABLE_CMUL; NORM_MUL; LIFT_CMUL]);;
9055
9056 let ABSOLUTELY_INTEGRABLE_NEG = prove
9057  (`!f s. f absolutely_integrable_on s
9058          ==> (\x. --f(x)) absolutely_integrable_on s`,
9059   SIMP_TAC[absolutely_integrable_on; INTEGRABLE_NEG; NORM_NEG]);;
9060
9061 let ABSOLUTELY_INTEGRABLE_NORM = prove
9062  (`!f s. f absolutely_integrable_on s
9063          ==> (\x. lift(norm(f x))) absolutely_integrable_on s`,
9064   SIMP_TAC[absolutely_integrable_on; NORM_LIFT; REAL_ABS_NORM]);;
9065
9066 let ABSOLUTELY_INTEGRABLE_ABS_1 = prove
9067  (`!f s. f absolutely_integrable_on s
9068          ==> (\x. lift(abs(drop(f x)))) absolutely_integrable_on s`,
9069   REWRITE_TAC[GSYM NORM_LIFT; LIFT_DROP; ABSOLUTELY_INTEGRABLE_NORM]);;
9070
9071 let ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL = prove
9072  (`!f:real^M->real^N s a b.
9073         f absolutely_integrable_on s /\ interval[a,b] SUBSET s
9074         ==> f absolutely_integrable_on interval[a,b]`,
9075   REWRITE_TAC[absolutely_integrable_on] THEN
9076   MESON_TAC[INTEGRABLE_ON_SUBINTERVAL]);;
9077
9078 let ABSOLUTELY_INTEGRABLE_SPIKE = prove
9079  (`!f:real^M->real^N g s t.
9080         negligible s /\ (!x. x IN t DIFF s ==> g x = f x)
9081         ==> f absolutely_integrable_on t ==> g absolutely_integrable_on t`,
9082   REPEAT GEN_TAC THEN STRIP_TAC THEN
9083   REWRITE_TAC[absolutely_integrable_on] THEN MATCH_MP_TAC MONO_AND THEN
9084   CONJ_TAC THEN MATCH_MP_TAC INTEGRABLE_SPIKE THEN
9085   EXISTS_TAC `s:real^M->bool` THEN ASM_SIMP_TAC[]);;
9086
9087 let ABSOLUTELY_INTEGRABLE_RESTRICT_INTER = prove
9088  (`!f:real^M->real^N s t.
9089         (\x. if x IN s then f x else vec 0) absolutely_integrable_on t <=>
9090         f absolutely_integrable_on (s INTER t)`,
9091   REWRITE_TAC[absolutely_integrable_on; GSYM INTEGRABLE_RESTRICT_INTER] THEN
9092   REWRITE_TAC[COND_RAND; NORM_0; LIFT_NUM]);;
9093
9094 let ABSOLUTELY_INTEGRABLE_EQ = prove
9095  (`!f:real^M->real^N g s.
9096         (!x. x IN s ==> f x = g x) /\ f absolutely_integrable_on s
9097         ==> g absolutely_integrable_on s`,
9098   REWRITE_TAC[absolutely_integrable_on] THEN REPEAT STRIP_TAC THEN
9099   MATCH_MP_TAC INTEGRABLE_EQ THENL
9100    [EXISTS_TAC `f:real^M->real^N`;
9101     EXISTS_TAC `\x. lift(norm((f:real^M->real^N) x))`] THEN
9102   ASM_SIMP_TAC[]);;
9103
9104 let ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION = prove
9105  (`!f:real^M->real^N s.
9106         f absolutely_integrable_on s
9107         ==> (\k. integral k f) has_bounded_setvariation_on s`,
9108   REWRITE_TAC[has_bounded_setvariation_on] THEN REPEAT STRIP_TAC THEN
9109   EXISTS_TAC
9110    `drop(integral (s:real^M->bool) (\x. lift(norm(f x:real^N))))` THEN
9111   X_GEN_TAC `d:(real^M->bool)->bool` THEN
9112   X_GEN_TAC `t:real^M->bool` THEN STRIP_TAC THEN
9113   SUBGOAL_THEN `(UNIONS d:real^M->bool) SUBSET s` ASSUME_TAC THENL
9114    [ASM_MESON_TAC[SUBSET_TRANS; division_of]; ALL_TAC] THEN
9115   MATCH_MP_TAC REAL_LE_TRANS THEN
9116   EXISTS_TAC
9117    `drop(integral (UNIONS d) (\x. lift(norm((f:real^M->real^N) x))))` THEN
9118   CONJ_TAC THENL
9119    [ALL_TAC;
9120     MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN
9121     ASM_REWRITE_TAC[LIFT_DROP; NORM_POS_LE] THEN CONJ_TAC THENL
9122      [MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
9123       EXISTS_TAC `s:real^M->bool` THEN
9124       EXISTS_TAC `d:(real^M->bool)->bool` THEN CONJ_TAC THENL
9125        [ASM_MESON_TAC[DIVISION_OF_SUBSET; division_of]; ALL_TAC] THEN
9126       ASM_REWRITE_TAC[];
9127       ALL_TAC] THEN
9128     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
9129     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN ASM_REWRITE_TAC[]] THEN
9130   MATCH_MP_TAC REAL_LE_TRANS THEN
9131   EXISTS_TAC
9132    `drop(vsum d (\i. integral i (\x:real^M. lift(norm(f x:real^N)))))` THEN
9133   CONJ_TAC THENL
9134    [FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
9135     ASM_SIMP_TAC[DROP_VSUM] THEN MATCH_MP_TAC SUM_LE THEN
9136     ASM_REWRITE_TAC[o_THM] THEN
9137     FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
9138     MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN
9139     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_LE THEN
9140     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL THEN
9141     EXISTS_TAC `s:real^M->bool` THEN ASM_MESON_TAC[division_of; SUBSET_TRANS];
9142     MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
9143     CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_TOPDOWN THEN
9144     CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[DIVISION_OF_UNION_SELF]] THEN
9145     MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
9146     MAP_EVERY EXISTS_TAC [`s:real^M->bool`; `d:(real^M->bool)->bool`] THEN
9147     CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_UNION_SELF]; ALL_TAC] THEN
9148     ASM_REWRITE_TAC[] THEN
9149     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
9150     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN ASM_REWRITE_TAC[]]);;
9151
9152 let lemma = prove
9153  (`!f:A->real^N g s e.
9154         sum s (\x. norm(f x - g x)) < e
9155         ==> FINITE s
9156             ==> abs(sum s (\x. norm(f x)) - sum s (\x. norm(g x))) < e`,
9157   REPEAT GEN_TAC THEN SIMP_TAC[GSYM SUM_SUB] THEN
9158   DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
9159   MATCH_MP_TAC(REAL_ARITH `x <= y ==> y < e ==> x < e`) THEN
9160   W(MP_TAC o PART_MATCH (lhand o rand) SUM_ABS o lhand o snd) THEN
9161   ASM_REWRITE_TAC[] THEN
9162   MATCH_MP_TAC(REAL_ARITH `y <= z ==> x <= y ==> x <= z`) THEN
9163   MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[] THEN
9164   REPEAT STRIP_TAC THEN NORM_ARITH_TAC);;
9165
9166 let BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE_INTERVAL = prove
9167  (`!f:real^M->real^N a b.
9168         f integrable_on interval[a,b] /\
9169         (\k. integral k f) has_bounded_setvariation_on interval[a,b]
9170         ==> f absolutely_integrable_on interval[a,b]`,
9171   REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_INTERVAL] THEN
9172   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[absolutely_integrable_on] THEN
9173   MP_TAC(ISPEC `IMAGE (\d. sum d (\k. norm(integral k (f:real^M->real^N))))
9174                       {d | d division_of interval[a,b] }`
9175          SUP) THEN
9176   REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
9177   REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
9178   ABBREV_TAC
9179    `i = sup (IMAGE (\d. sum d (\k. norm(integral k (f:real^M->real^N))))
9180                       {d | d division_of interval[a,b] })` THEN
9181   ANTS_TAC THENL
9182    [REWRITE_TAC[ELEMENTARY_INTERVAL] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
9183   STRIP_TAC THEN REWRITE_TAC[integrable_on] THEN EXISTS_TAC `lift i` THEN
9184   REWRITE_TAC[has_integral] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
9185   FIRST_X_ASSUM(MP_TAC o SPEC `i - e / &2`) THEN
9186   ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(i <= i - e / &2)`] THEN
9187   REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LE; LEFT_IMP_EXISTS_THM] THEN
9188   X_GEN_TAC `d:(real^M->bool)->bool` THEN STRIP_TAC THEN
9189   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
9190   SUBGOAL_THEN
9191    `!x. ?e. &0 < e /\
9192             !i. i IN d /\ ~(x IN i) ==> ball(x:real^M,e) INTER i = {}`
9193   MP_TAC THENL
9194    [X_GEN_TAC `x:real^M` THEN MP_TAC(ISPECL
9195      [`UNIONS {i:real^M->bool | i IN d /\ ~(x IN i)}`; `x:real^M`]
9196      SEPARATE_POINT_CLOSED) THEN
9197     ANTS_TAC THENL
9198      [CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN
9199       MATCH_MP_TAC CLOSED_UNIONS THEN
9200       ASM_SIMP_TAC[FINITE_RESTRICT; IN_ELIM_THM; IMP_CONJ] THEN
9201       FIRST_ASSUM(fun t -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN
9202       REWRITE_TAC[CLOSED_INTERVAL];
9203       ALL_TAC] THEN
9204     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real` THEN
9205     SIMP_TAC[FORALL_IN_UNIONS; EXTENSION; IN_INTER; NOT_IN_EMPTY; IN_BALL] THEN
9206     REWRITE_TAC[IN_ELIM_THM; DE_MORGAN_THM; REAL_NOT_LT] THEN MESON_TAC[];
9207     ALL_TAC] THEN
9208   REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN
9209   X_GEN_TAC `k:real^M->real` THEN STRIP_TAC THEN
9210   FIRST_ASSUM(MP_TAC o SPEC `e / &2` o MATCH_MP HENSTOCK_LEMMA) THEN
9211   ASM_REWRITE_TAC[REAL_HALF] THEN
9212   DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
9213   EXISTS_TAC `\x:real^M. g(x) INTER ball(x,k x)` THEN CONJ_TAC THENL
9214    [MATCH_MP_TAC GAUGE_INTER THEN ASM_REWRITE_TAC[] THEN
9215     ASM_REWRITE_TAC[gauge; CENTRE_IN_BALL; OPEN_BALL];
9216     ALL_TAC] THEN
9217   REWRITE_TAC[FINE_INTER] THEN X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN
9218   STRIP_TAC THEN
9219   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
9220   ABBREV_TAC
9221    `p' = {(x:real^M,k:real^M->bool) |
9222                 ?i l. x IN i /\ i IN d /\ (x,l) IN p /\ k = i INTER l}` THEN
9223   SUBGOAL_THEN `g fine (p':(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
9224    [EXPAND_TAC "p'" THEN
9225     MP_TAC(ASSUME `g fine (p:(real^M#(real^M->bool))->bool)`) THEN
9226     REWRITE_TAC[fine; IN_ELIM_PAIR_THM] THEN
9227     MESON_TAC[SET_RULE `k SUBSET l ==> (i INTER k) SUBSET l`];
9228     ALL_TAC] THEN
9229   SUBGOAL_THEN `p' tagged_division_of interval[a:real^M,b]` ASSUME_TAC THENL
9230    [REWRITE_TAC[TAGGED_DIVISION_OF] THEN EXPAND_TAC "p'" THEN
9231     REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
9232     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
9233     MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
9234      [DISCH_TAC THEN MATCH_MP_TAC FINITE_SUBSET THEN
9235       EXISTS_TAC
9236        `IMAGE (\(k,(x,l)). x,k INTER l)
9237               {k,xl | k IN (d:(real^M->bool)->bool) /\
9238                       xl IN (p:(real^M#(real^M->bool))->bool)}` THEN
9239       ASM_SIMP_TAC[FINITE_IMAGE; FINITE_PRODUCT] THEN
9240       EXPAND_TAC "p'" THEN REWRITE_TAC[SUBSET; FORALL_PAIR_THM] THEN
9241       REWRITE_TAC[IN_ELIM_PAIR_THM; IN_IMAGE; EXISTS_PAIR_THM; PAIR_EQ] THEN
9242       MESON_TAC[];
9243       ALL_TAC] THEN
9244     MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
9245      [DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
9246       REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
9247       MAP_EVERY X_GEN_TAC [`i:real^M->bool`; `l:real^M->bool`] THEN
9248       STRIP_TAC THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN
9249       ASM_SIMP_TAC[IN_INTER] THEN CONJ_TAC THENL
9250        [MATCH_MP_TAC(SET_RULE `l SUBSET s ==> (k INTER l) SUBSET s`) THEN
9251         ASM_MESON_TAC[];
9252         ALL_TAC] THEN
9253       FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `l:real^M->bool`]) THEN
9254       ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9255       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
9256       DISCH_THEN(MP_TAC o SPEC `i:real^M->bool` o el 1 o CONJUNCTS) THEN
9257       ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
9258       ASM_REWRITE_TAC[INTER_INTERVAL] THEN MESON_TAC[];
9259       ALL_TAC] THEN
9260     MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
9261      [DISCH_TAC THEN MAP_EVERY X_GEN_TAC
9262        [`x1:real^M`; `k1:real^M->bool`; `x2:real^M`; `k2:real^M->bool`] THEN
9263       DISCH_THEN(CONJUNCTS_THEN2
9264        (X_CHOOSE_THEN `i1:real^M->bool` (X_CHOOSE_THEN `l1:real^M->bool`
9265           STRIP_ASSUME_TAC)) MP_TAC) THEN
9266       FIRST_X_ASSUM SUBST_ALL_TAC THEN
9267       DISCH_THEN(CONJUNCTS_THEN2
9268        (X_CHOOSE_THEN `i2:real^M->bool` (X_CHOOSE_THEN `l2:real^M->bool`
9269           STRIP_ASSUME_TAC)) ASSUME_TAC) THEN
9270       FIRST_X_ASSUM SUBST_ALL_TAC THEN
9271       MATCH_MP_TAC(SET_RULE
9272        `(interior(i1) INTER interior(i2) = {} \/
9273          interior(l1) INTER interior(l2) = {}) /\
9274         interior(i1 INTER l1) SUBSET interior(i1) /\
9275         interior(i2 INTER l2) SUBSET interior(i2) /\
9276         interior(i1 INTER l1) SUBSET interior(l1) /\
9277         interior(i2 INTER l2) SUBSET interior(l2)
9278         ==> interior(i1 INTER l1) INTER interior(i2 INTER l2) = {}`) THEN
9279       SIMP_TAC[SUBSET_INTERIOR; INTER_SUBSET] THEN
9280       FIRST_X_ASSUM(MP_TAC o SPECL
9281        [`x1:real^M`; `l1:real^M->bool`; `x2:real^M`; `l2:real^M->bool`]) THEN
9282       ASM_REWRITE_TAC[] THEN
9283       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
9284       DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
9285       DISCH_THEN(MP_TAC o SPECL [`i1:real^M->bool`; `i2:real^M->bool`]) THEN
9286       ASM_REWRITE_TAC[] THEN
9287       FIRST_X_ASSUM(MP_TAC o check(is_neg o concl)) THEN
9288       ASM_REWRITE_TAC[PAIR_EQ] THEN MESON_TAC[];
9289       ALL_TAC] THEN
9290     DISCH_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
9291      [REWRITE_TAC[UNIONS_SUBSET; IN_ELIM_THM] THEN
9292       REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9293       MATCH_MP_TAC(SET_RULE `i SUBSET s ==> (i INTER k) SUBSET s`) THEN
9294       ASM_MESON_TAC[division_of];
9295       ALL_TAC] THEN
9296     REWRITE_TAC[SUBSET] THEN X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN
9297     REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN
9298     REWRITE_TAC[LEFT_AND_EXISTS_THM; GSYM CONJ_ASSOC] THEN
9299     REWRITE_TAC[MESON[]
9300      `p /\ q /\ r /\ x = t /\ P x <=> x = t /\ p /\ q /\ r /\ P t`] THEN
9301     ONCE_REWRITE_TAC[MESON[]
9302      `(?a b c d. P a b c d) <=> (?d b c a. P a b c d)`] THEN
9303     REWRITE_TAC[IN_INTER; UNWIND_THM2] THEN
9304     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
9305     DISCH_THEN(MP_TAC o SPEC `y:real^M`) THEN ASM_REWRITE_TAC[] THEN
9306     REWRITE_TAC[IN_UNIONS; IN_ELIM_THM; LEFT_AND_EXISTS_THM] THEN
9307     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real^M->bool` THEN
9308     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^M` THEN
9309     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9310     FIRST_X_ASSUM(MP_TAC o last o CONJUNCTS o
9311         GEN_REWRITE_RULE I [division_of]) THEN
9312     REWRITE_TAC[EXTENSION] THEN DISCH_THEN(MP_TAC o SPEC `y:real^M`) THEN
9313     ASM_REWRITE_TAC[IN_UNIONS] THEN
9314     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^M->bool` THEN
9315     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9316     FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `k:real^M->bool`]) THEN
9317     GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN
9318     ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN
9319     REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
9320     EXISTS_TAC `y:real^M` THEN ASM_REWRITE_TAC[INTER; IN_ELIM_THM] THEN
9321     UNDISCH_TAC `(\x:real^M. ball (x,k x)) fine p` THEN
9322     REWRITE_TAC[fine; SUBSET] THEN ASM_MESON_TAC[];
9323     ALL_TAC] THEN
9324   FIRST_X_ASSUM(MP_TAC o SPEC `p':(real^M#(real^M->bool))->bool`) THEN
9325   ASM_REWRITE_TAC[] THEN
9326   ANTS_TAC THENL [ASM_MESON_TAC[tagged_division_of]; ALL_TAC] THEN
9327   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
9328   REWRITE_TAC[LAMBDA_PAIR] THEN DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN
9329   ASM_SIMP_TAC[DROP_VSUM; o_DEF; SUM_SUB; DROP_SUB; ABS_DROP] THEN
9330   REWRITE_TAC[LAMBDA_PAIR_THM; DROP_CMUL; NORM_MUL; LIFT_DROP] THEN
9331   MATCH_MP_TAC(REAL_ARITH
9332     `!sni. i - e / &2 < sni /\
9333            sni' <= i /\ sni <= sni' /\ sf' = sf
9334               ==> abs(sf' - sni') < e / &2
9335                   ==> abs(sf - i) < e`) THEN
9336   EXISTS_TAC `sum d (\k. norm (integral k (f:real^M->real^N)))` THEN
9337   ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
9338    [MP_TAC(ISPECL [`\k. norm(integral k (f:real^M->real^N))`;
9339                    `p':(real^M#(real^M->bool))->bool`;
9340                    `interval[a:real^M,b]`] SUM_OVER_TAGGED_DIVISION_LEMMA) THEN
9341     ASM_SIMP_TAC[INTEGRAL_NULL; NORM_0] THEN DISCH_THEN SUBST1_TAC THEN
9342     FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[DIVISION_OF_TAGGED_DIVISION];
9343     ALL_TAC] THEN
9344   SUBGOAL_THEN
9345    `p' = {x:real^M,(i INTER l:real^M->bool) |
9346             (x,l) IN p /\ i IN d /\ ~(i INTER l = {})}`
9347   (LABEL_TAC "p'") THENL
9348    [EXPAND_TAC "p'" THEN GEN_REWRITE_TAC I [EXTENSION] THEN
9349     REWRITE_TAC[FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN
9350     REWRITE_TAC[IN_ELIM_THM] THEN
9351     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
9352     REWRITE_TAC[PAIR_EQ; GSYM CONJ_ASSOC] THEN
9353     GEN_REWRITE_TAC RAND_CONV [SWAP_EXISTS_THM] THEN
9354     AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
9355     X_GEN_TAC `i:real^M->bool` THEN REWRITE_TAC[] THEN
9356     CONV_TAC(RAND_CONV UNWIND_CONV) THEN
9357     AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
9358     X_GEN_TAC `l:real^M->bool` THEN REWRITE_TAC[] THEN
9359     ASM_CASES_TAC `k:real^M->bool = i INTER l` THEN ASM_REWRITE_TAC[] THEN
9360     ASM_REWRITE_TAC[IN_INTER; GSYM MEMBER_NOT_EMPTY] THEN
9361     EQ_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
9362     REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
9363     DISCH_THEN(X_CHOOSE_THEN `y:real^M` STRIP_ASSUME_TAC) THEN
9364     ASM_REWRITE_TAC[] THEN
9365     FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `i:real^M->bool`]) THEN
9366     GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN
9367     ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN
9368     REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
9369     EXISTS_TAC `y:real^M` THEN ASM_REWRITE_TAC[INTER; IN_ELIM_THM] THEN
9370     UNDISCH_TAC `(\x:real^M. ball (x,k x)) fine p` THEN
9371     REWRITE_TAC[fine; SUBSET] THEN ASM_MESON_TAC[];
9372     ALL_TAC] THEN
9373   CONJ_TAC THENL
9374    [MP_TAC(ISPECL
9375      [`\y. norm(integral y (f:real^M->real^N))`;
9376       `p':(real^M#(real^M->bool))->bool`;
9377       `interval[a:real^M,b]`]
9378      SUM_OVER_TAGGED_DIVISION_LEMMA) THEN
9379     ASM_SIMP_TAC[INTEGRAL_NULL; NORM_0] THEN DISCH_THEN SUBST1_TAC THEN
9380     MATCH_MP_TAC REAL_LE_TRANS THEN
9381     EXISTS_TAC `sum {i INTER l | i IN d /\
9382                  (l IN IMAGE SND (p:(real^M#(real^M->bool))->bool))}
9383                     (\k. norm(integral k (f:real^M->real^N)))` THEN
9384     CONJ_TAC THENL
9385      [ALL_TAC;
9386       MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC SUM_SUPERSET THEN
9387       CONJ_TAC THENL
9388        [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
9389         REWRITE_TAC[FORALL_PAIR_THM] THEN
9390         REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; PAIR_EQ; EXISTS_PAIR_THM] THEN
9391         MESON_TAC[];
9392         ALL_TAC] THEN
9393       REWRITE_TAC[IN_ELIM_THM; LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN
9394       MAP_EVERY X_GEN_TAC
9395        [`kk:real^M->bool`; `i:real^M->bool`; `l:real^M->bool`] THEN
9396       ASM_CASES_TAC `kk:real^M->bool = i INTER l` THEN ASM_REWRITE_TAC[] THEN
9397       REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM; UNWIND_THM1] THEN
9398       DISCH_THEN(CONJUNCTS_THEN2
9399        (CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_TAC `x:real^M`)) MP_TAC) THEN
9400       REWRITE_TAC[IN_ELIM_THM; PAIR_EQ; NOT_EXISTS_THM] THEN
9401       DISCH_THEN(MP_TAC o SPECL
9402        [`x:real^M`; `x:real^M`; `i:real^M->bool`; `l:real^M->bool`]) THEN
9403       ASM_SIMP_TAC[INTEGRAL_EMPTY; NORM_0]] THEN
9404     SUBGOAL_THEN
9405      `{k INTER l | k IN d /\ l IN IMAGE SND (p:(real^M#(real^M->bool))->bool)} =
9406       IMAGE (\(k,l). k INTER l) {k,l | k IN d /\ l IN IMAGE SND p}`
9407     SUBST1_TAC THENL
9408      [GEN_REWRITE_TAC I [EXTENSION] THEN
9409       REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; EXISTS_PAIR_THM; FORALL_PAIR_THM] THEN
9410       REWRITE_TAC[PAIR_EQ] THEN
9411       CONV_TAC(REDEPTH_CONV UNWIND_CONV) THEN MESON_TAC[];
9412       ALL_TAC] THEN
9413     W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE_NONZERO o rand o snd) THEN
9414     ANTS_TAC THENL
9415      [ASSUME_TAC(MATCH_MP DIVISION_OF_TAGGED_DIVISION
9416         (ASSUME `p tagged_division_of interval[a:real^M,b]`)) THEN
9417       ASM_SIMP_TAC[FINITE_PRODUCT; FINITE_IMAGE] THEN
9418       REWRITE_TAC[FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN
9419       MAP_EVERY X_GEN_TAC
9420        [`l1:real^M->bool`; `k1:real^M->bool`;
9421         `l2:real^M->bool`; `k2:real^M->bool`] THEN
9422       REWRITE_TAC[PAIR_EQ] THEN STRIP_TAC THEN
9423       SUBGOAL_THEN `interior(l2 INTER k2:real^M->bool) = {}` MP_TAC THENL
9424        [ALL_TAC;
9425         MP_TAC(ASSUME `d division_of interval[a:real^M,b]`) THEN
9426         REWRITE_TAC[division_of] THEN
9427         DISCH_THEN(MP_TAC o SPEC `l2:real^M->bool` o el 1 o CONJUNCTS) THEN
9428         ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9429         MP_TAC(ASSUME
9430          `(IMAGE SND (p:(real^M#(real^M->bool))->bool))
9431                 division_of interval[a:real^M,b]`) THEN
9432         REWRITE_TAC[division_of] THEN
9433         DISCH_THEN(MP_TAC o SPEC `k2:real^M->bool` o el 1 o CONJUNCTS) THEN
9434         ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
9435         ASM_REWRITE_TAC[INTER_INTERVAL] THEN DISCH_TAC THEN
9436         REWRITE_TAC[NORM_EQ_0] THEN
9437         MATCH_MP_TAC INTEGRAL_NULL THEN
9438         ASM_REWRITE_TAC[CONTENT_EQ_0_INTERIOR]] THEN
9439       MATCH_MP_TAC(SET_RULE
9440        `(interior(k1) INTER interior(k2) = {} \/
9441          interior(l1) INTER interior(l2) = {}) /\
9442         interior(l1 INTER k1) SUBSET interior(k1) /\
9443         interior(l2 INTER k2) SUBSET interior(k2) /\
9444         interior(l1 INTER k1) SUBSET interior(l1) /\
9445         interior(l2 INTER k2) SUBSET interior(l2) /\
9446         interior(l1 INTER k1) = interior(l2 INTER k2)
9447         ==> interior(l2 INTER k2) = {}`) THEN
9448       SIMP_TAC[SUBSET_INTERIOR; INTER_SUBSET] THEN ASM_REWRITE_TAC[] THEN
9449       MP_TAC(ASSUME `d division_of interval[a:real^M,b]`) THEN
9450       REWRITE_TAC[division_of] THEN DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
9451       DISCH_THEN(MP_TAC o SPECL [`l1:real^M->bool`; `l2:real^M->bool`]) THEN
9452       ASM_REWRITE_TAC[] THEN
9453       MP_TAC(ASSUME
9454        `(IMAGE SND (p:(real^M#(real^M->bool))->bool))
9455               division_of interval[a:real^M,b]`) THEN
9456       REWRITE_TAC[division_of] THEN DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
9457       DISCH_THEN(MP_TAC o SPECL [`k1:real^M->bool`; `k2:real^M->bool`]) THEN
9458       ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[];
9459       ALL_TAC] THEN
9460     DISCH_THEN SUBST1_TAC THEN
9461     GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM ETA_AX] THEN
9462     GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [LAMBDA_PAIR_THM] THEN
9463     ASM_SIMP_TAC[GSYM SUM_SUM_PRODUCT; FINITE_IMAGE] THEN
9464     MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[] THEN
9465     X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN REWRITE_TAC[o_DEF] THEN
9466     MATCH_MP_TAC REAL_LE_TRANS THEN
9467     EXISTS_TAC
9468      `sum { k INTER l |
9469              l IN IMAGE SND (p:(real^M#(real^M->bool))->bool)}
9470           (\k. norm(integral k (f:real^M->real^N)))` THEN
9471     CONJ_TAC THENL
9472      [ALL_TAC;
9473       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
9474       W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE_NONZERO o lhand o snd) THEN
9475       ANTS_TAC THENL [ALL_TAC; SIMP_TAC[o_DEF; REAL_LE_REFL]] THEN
9476       ASM_SIMP_TAC[FINITE_IMAGE] THEN
9477       MAP_EVERY X_GEN_TAC [`k1:real^M->bool`; `k2:real^M->bool`] THEN
9478       STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9479       SUBGOAL_THEN `interior(k INTER k2:real^M->bool) = {}` MP_TAC THENL
9480        [ALL_TAC;
9481         MP_TAC(MATCH_MP DIVISION_OF_TAGGED_DIVISION
9482          (ASSUME `p tagged_division_of interval[a:real^M,b]`)) THEN
9483         MP_TAC(ASSUME `d division_of interval[a:real^M,b]`) THEN
9484         REWRITE_TAC[division_of] THEN
9485         DISCH_THEN(MP_TAC o SPEC `k:real^M->bool` o el 1 o CONJUNCTS) THEN
9486         ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9487         DISCH_THEN(MP_TAC o SPEC `k2:real^M->bool` o el 1 o CONJUNCTS) THEN
9488         ASM_REWRITE_TAC[INTER_INTERVAL; GSYM CONTENT_EQ_0_INTERIOR] THEN
9489         STRIP_TAC THEN ASM_REWRITE_TAC[INTER_INTERVAL] THEN
9490         SIMP_TAC[GSYM CONTENT_EQ_0_INTERIOR; INTEGRAL_NULL; NORM_0]] THEN
9491       MATCH_MP_TAC(SET_RULE
9492        `interior(k INTER k2) SUBSET interior(k1 INTER k2) /\
9493         interior(k1 INTER k2) = {}
9494         ==> interior(k INTER k2) = {}`) THEN
9495       CONJ_TAC THENL
9496        [MATCH_MP_TAC SUBSET_INTERIOR THEN ASM SET_TAC[]; ALL_TAC] THEN
9497       MP_TAC(MATCH_MP DIVISION_OF_TAGGED_DIVISION
9498          (ASSUME `p tagged_division_of interval[a:real^M,b]`)) THEN
9499       REWRITE_TAC[division_of] THEN
9500       DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
9501       REWRITE_TAC[INTERIOR_INTER] THEN DISCH_THEN MATCH_MP_TAC THEN
9502       ASM_REWRITE_TAC[]] THEN
9503     SUBGOAL_THEN `?u v:real^M. k = interval[u,v]`
9504      (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
9505     THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
9506     SUBGOAL_THEN `interval[u:real^M,v] SUBSET interval[a,b]` ASSUME_TAC THENL
9507      [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
9508     ABBREV_TAC `d' =
9509         {interval[u,v] INTER l |l|
9510                 l IN IMAGE SND (p:(real^M#(real^M->bool))->bool) /\
9511                 ~(interval[u,v] INTER l = {})}` THEN
9512     MATCH_MP_TAC REAL_LE_TRANS THEN
9513     EXISTS_TAC
9514      `sum d' (\k. norm (integral k (f:real^M->real^N)))` THEN
9515     CONJ_TAC THENL
9516      [ALL_TAC;
9517       MATCH_MP_TAC REAL_EQ_IMP_LE THEN CONV_TAC SYM_CONV THEN
9518       MATCH_MP_TAC SUM_SUPERSET THEN
9519       EXPAND_TAC "d'" THEN REWRITE_TAC[SUBSET; SET_RULE
9520        `a IN {f x |x| x IN s /\ ~(f x = b)} <=>
9521         a IN {f x | x IN s} /\ ~(a = b)`] THEN
9522       SIMP_TAC[IMP_CONJ; INTEGRAL_EMPTY; NORM_0]] THEN
9523     SUBGOAL_THEN `d' division_of interval[u:real^M,v]` ASSUME_TAC THENL
9524      [EXPAND_TAC "d'" THEN MATCH_MP_TAC DIVISION_INTER_1 THEN
9525       EXISTS_TAC `interval[a:real^M,b]` THEN
9526       ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION];
9527       ALL_TAC] THEN
9528     MATCH_MP_TAC REAL_LE_TRANS THEN
9529     EXISTS_TAC `norm(vsum d' (\i. integral i (f:real^M->real^N)))` THEN
9530     CONJ_TAC THENL
9531      [MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
9532       MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_TOPDOWN THEN
9533       ASM_MESON_TAC[INTEGRABLE_ON_SUBINTERVAL];
9534       ALL_TAC] THEN
9535     MATCH_MP_TAC VSUM_NORM_LE THEN
9536     REWRITE_TAC[REAL_LE_REFL] THEN ASM_MESON_TAC[division_of];
9537     ALL_TAC] THEN
9538   REMOVE_THEN "p'" SUBST_ALL_TAC THEN
9539   MATCH_MP_TAC EQ_TRANS THEN
9540   EXISTS_TAC `sum {x,i INTER l | (x,l) IN p /\ i IN d}
9541                   (\(x,k:real^M->bool).
9542                       abs(content k) * norm((f:real^M->real^N) x))` THEN
9543   CONJ_TAC THENL
9544    [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_SUPERSET THEN
9545     CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
9546     REWRITE_TAC[FORALL_PAIR_THM] THEN
9547     MAP_EVERY X_GEN_TAC [`x:real^M`; `i:real^M->bool`] THEN
9548     ASM_CASES_TAC `i:real^M->bool = {}` THEN
9549     ASM_SIMP_TAC[CONTENT_EMPTY; REAL_ABS_NUM; REAL_MUL_LZERO] THEN
9550     MATCH_MP_TAC(TAUT `(a <=> b) ==> a /\ ~b ==> c`) THEN
9551     REWRITE_TAC[IN_ELIM_THM] THEN
9552     REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
9553     REWRITE_TAC[PAIR_EQ] THEN ASM_MESON_TAC[];
9554     ALL_TAC] THEN
9555   SUBGOAL_THEN
9556    `{x,i INTER l | x,l IN (p:(real^M#(real^M->bool))->bool) /\ i IN d} =
9557     IMAGE (\((x,l),k). x,k INTER l) {m,k | m IN p /\ k IN d}`
9558   SUBST1_TAC THENL
9559    [GEN_REWRITE_TAC I [EXTENSION] THEN
9560     REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; EXISTS_PAIR_THM; FORALL_PAIR_THM] THEN
9561     REWRITE_TAC[PAIR_EQ] THEN
9562     CONV_TAC(REDEPTH_CONV UNWIND_CONV) THEN MESON_TAC[];
9563     ALL_TAC] THEN
9564   W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE_NONZERO o lhand o snd) THEN
9565   ANTS_TAC THENL
9566    [ASM_SIMP_TAC[FINITE_PRODUCT] THEN
9567     REWRITE_TAC[FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN
9568     MAP_EVERY X_GEN_TAC
9569      [`x1:real^M`; `l1:real^M->bool`; `k1:real^M->bool`;
9570       `x2:real^M`; `l2:real^M->bool`; `k2:real^M->bool`] THEN
9571     REWRITE_TAC[PAIR_EQ] THEN
9572     ASM_CASES_TAC `x1:real^M = x2` THEN ASM_REWRITE_TAC[] THEN
9573     STRIP_TAC THEN
9574     REWRITE_TAC[REAL_ENTIRE] THEN DISJ1_TAC THEN
9575     REWRITE_TAC[REAL_ABS_ZERO] THEN
9576     SUBGOAL_THEN `interior(k2 INTER l2:real^M->bool) = {}` MP_TAC THENL
9577      [ALL_TAC;
9578       FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
9579       DISCH_THEN(MP_TAC o SPEC `k2:real^M->bool` o el 1 o CONJUNCTS) THEN
9580       ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9581       MP_TAC(ASSUME `p tagged_division_of interval[a:real^M,b]`) THEN
9582       REWRITE_TAC[TAGGED_DIVISION_OF] THEN
9583       DISCH_THEN(MP_TAC o el 1 o CONJUNCTS) THEN
9584       DISCH_THEN(MP_TAC o SPECL [`x2:real^M`; `l2:real^M->bool`]) THEN
9585       ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
9586       ASM_REWRITE_TAC[INTER_INTERVAL; CONTENT_EQ_0_INTERIOR]] THEN
9587     MATCH_MP_TAC(SET_RULE
9588      `(interior(k1) INTER interior(k2) = {} \/
9589        interior(l1) INTER interior(l2) = {}) /\
9590       interior(k1 INTER l1) SUBSET interior(k1) /\
9591       interior(k2 INTER l2) SUBSET interior(k2) /\
9592       interior(k1 INTER l1) SUBSET interior(l1) /\
9593       interior(k2 INTER l2) SUBSET interior(l2) /\
9594       interior(k1 INTER l1) = interior(k2 INTER l2)
9595       ==> interior(k2 INTER l2) = {}`) THEN
9596     SIMP_TAC[SUBSET_INTERIOR; INTER_SUBSET] THEN ASM_REWRITE_TAC[] THEN
9597     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
9598     DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
9599     DISCH_THEN(MP_TAC o SPECL [`k1:real^M->bool`; `k2:real^M->bool`]) THEN
9600     MP_TAC(ASSUME `p tagged_division_of interval[a:real^M,b]`) THEN
9601     REWRITE_TAC[TAGGED_DIVISION_OF] THEN
9602     DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
9603     DISCH_THEN(MP_TAC o SPECL
9604      [`x2:real^M`; `l1:real^M->bool`; `x2:real^M`; `l2:real^M->bool`]) THEN
9605     ASM_REWRITE_TAC[PAIR_EQ] THEN ASM_MESON_TAC[];
9606     ALL_TAC] THEN
9607   DISCH_THEN SUBST1_TAC THEN
9608   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM ETA_AX] THEN
9609   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [LAMBDA_PAIR_THM] THEN
9610   ASM_SIMP_TAC[GSYM SUM_SUM_PRODUCT] THEN
9611   MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
9612   MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
9613   DISCH_TAC THEN REWRITE_TAC[o_THM; SUM_RMUL] THEN
9614   AP_THM_TAC THEN AP_TERM_TAC THEN
9615   SUBGOAL_THEN `?u v:real^M. l = interval[u,v]`
9616    (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
9617   THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
9618   MATCH_MP_TAC EQ_TRANS THEN
9619   EXISTS_TAC `sum d (\k. content(k INTER interval[u:real^M,v]))` THEN
9620   CONJ_TAC THENL
9621    [MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[real_abs] THEN
9622     X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
9623     SUBGOAL_THEN `?w z:real^M. k = interval[w,z]`
9624       (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
9625     THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
9626     REWRITE_TAC[INTER_INTERVAL; CONTENT_POS_LE];
9627     ALL_TAC] THEN
9628   MATCH_MP_TAC EQ_TRANS THEN
9629   EXISTS_TAC `sum {k INTER interval[u:real^M,v] | k IN d} content` THEN
9630   CONJ_TAC THENL
9631    [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN
9632     CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_IMAGE_NONZERO THEN
9633     ASM_REWRITE_TAC[] THEN
9634     MAP_EVERY X_GEN_TAC [`k1:real^M->bool`; `k2:real^M->bool`] THEN
9635     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9636     SUBGOAL_THEN `interior(k2 INTER interval[u:real^M,v]) = {}` MP_TAC THENL
9637      [ALL_TAC;
9638       FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
9639       DISCH_THEN(MP_TAC o SPEC `k2:real^M->bool` o el 1 o CONJUNCTS) THEN
9640       ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9641       ASM_REWRITE_TAC[INTER_INTERVAL; CONTENT_EQ_0_INTERIOR]] THEN
9642     MATCH_MP_TAC(SET_RULE
9643      `interior(k2 INTER i) SUBSET interior(k1 INTER k2) /\
9644       interior(k1 INTER k2) = {}
9645       ==> interior(k2 INTER i) = {}`) THEN
9646     CONJ_TAC THENL
9647      [MATCH_MP_TAC SUBSET_INTERIOR THEN ASM SET_TAC[]; ALL_TAC] THEN
9648     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
9649     DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
9650     REWRITE_TAC[INTERIOR_INTER] THEN DISCH_THEN MATCH_MP_TAC THEN
9651     ASM_REWRITE_TAC[];
9652     ALL_TAC] THEN
9653   SUBGOAL_THEN `interval[u:real^M,v] SUBSET interval[a,b]` ASSUME_TAC THENL
9654    [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
9655   MATCH_MP_TAC EQ_TRANS THEN
9656   EXISTS_TAC `sum {k INTER interval[u:real^M,v] |k|
9657                       k IN d /\ ~(k INTER interval[u,v] = {})} content` THEN
9658   CONJ_TAC THENL
9659    [MATCH_MP_TAC SUM_SUPERSET THEN
9660     REWRITE_TAC[SUBSET; SET_RULE
9661      `a IN {f x |x| x IN s /\ ~(f x = b)} <=>
9662       a IN {f x | x IN s} /\ ~(a = b)`] THEN
9663     SIMP_TAC[IMP_CONJ; CONTENT_EMPTY];
9664     ALL_TAC] THEN
9665   MATCH_MP_TAC ADDITIVE_CONTENT_DIVISION THEN
9666   ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC DIVISION_INTER_1 THEN
9667   EXISTS_TAC `interval[a:real^M,b]` THEN ASM_REWRITE_TAC[]);;
9668
9669 let BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE = prove
9670  (`!f:real^M->real^N.
9671         f integrable_on UNIV /\
9672         (\k. integral k f) has_bounded_setvariation_on (:real^M)
9673         ==> f absolutely_integrable_on UNIV`,
9674   REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN
9675   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[absolutely_integrable_on] THEN
9676   MP_TAC(ISPEC `IMAGE (\d. sum d (\k. norm(integral k (f:real^M->real^N))))
9677                       {d | d division_of (UNIONS d) }`
9678          SUP) THEN
9679   REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
9680   REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
9681   ABBREV_TAC
9682    `i = sup (IMAGE (\d. sum d (\k. norm(integral k (f:real^M->real^N))))
9683                       {d | d division_of (UNIONS d) })` THEN
9684   ANTS_TAC THENL
9685    [CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
9686     EXISTS_TAC `{}:(real^M->bool)->bool` THEN
9687     REWRITE_TAC[UNIONS_0; DIVISION_OF_TRIVIAL];
9688     ALL_TAC] THEN
9689   STRIP_TAC THEN REWRITE_TAC[integrable_on] THEN EXISTS_TAC `lift i` THEN
9690   REWRITE_TAC[HAS_INTEGRAL_ALT; IN_UNIV] THEN
9691   MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
9692    [MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
9693     MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`]
9694       (REWRITE_RULE[HAS_BOUNDED_SETVARIATION_ON_INTERVAL]
9695        BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE_INTERVAL)) THEN
9696     ANTS_TAC THENL [ALL_TAC; SIMP_TAC[absolutely_integrable_on]] THEN
9697     CONJ_TAC THENL
9698      [MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN EXISTS_TAC `(:real^M)` THEN
9699       ASM_REWRITE_TAC[SUBSET_UNIV];
9700       ALL_TAC] THEN
9701     EXISTS_TAC `B:real` THEN REPEAT STRIP_TAC THEN
9702     FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[DIVISION_OF_UNION_SELF];
9703     ALL_TAC] THEN
9704   DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
9705   FIRST_X_ASSUM(MP_TAC o SPEC `i - e`) THEN
9706   ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(i <= i - e)`] THEN
9707   REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LE; LEFT_IMP_EXISTS_THM] THEN
9708   X_GEN_TAC `d:(real^M->bool)->bool` THEN STRIP_TAC THEN
9709   SUBGOAL_THEN `bounded(UNIONS d:real^M->bool)` MP_TAC THENL
9710    [ASM_MESON_TAC[ELEMENTARY_BOUNDED]; ALL_TAC] THEN
9711   REWRITE_TAC[BOUNDED_POS] THEN
9712   DISCH_THEN(X_CHOOSE_THEN `K:real` STRIP_ASSUME_TAC) THEN
9713   EXISTS_TAC `K + &1` THEN ASM_SIMP_TAC[REAL_LT_ADD; REAL_LT_01] THEN
9714   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN
9715   REWRITE_TAC[ABS_DROP; DROP_SUB; LIFT_DROP] THEN
9716   MATCH_MP_TAC(REAL_ARITH
9717    `!s1. i - e < s1 /\ s1 <= s /\ s < i + e ==> abs(s - i) < e`) THEN
9718   EXISTS_TAC `sum (d:(real^M->bool)->bool) (\k. norm (integral k
9719                     (f:real^M->real^N)))` THEN
9720   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
9721   ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
9722    [MATCH_MP_TAC REAL_LE_TRANS THEN
9723     EXISTS_TAC `sum d
9724       (\k. drop(integral k (\x. lift(norm((f:real^M->real^N) x)))))` THEN
9725     CONJ_TAC THENL
9726      [MATCH_MP_TAC SUM_LE THEN
9727       FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN
9728       REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_LE THEN
9729       ASM_REWRITE_TAC[absolutely_integrable_on] THEN
9730       MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
9731       EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV];
9732       ALL_TAC] THEN
9733     MATCH_MP_TAC REAL_LE_TRANS THEN
9734     EXISTS_TAC `drop(integral (UNIONS d)
9735                       (\x. lift(norm((f:real^M->real^N) x))))` THEN
9736     CONJ_TAC THENL
9737      [MATCH_MP_TAC(MESON[REAL_LE_REFL; LIFT_DROP]
9738        `lift x = y ==> x <= drop y`) THEN
9739       ASM_SIMP_TAC[LIFT_SUM; o_DEF; LIFT_DROP] THEN CONV_TAC SYM_CONV THEN
9740       MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_BOTTOMUP THEN
9741       FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]);
9742       ALL_TAC] THEN
9743     MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN
9744     ASM_REWRITE_TAC[LIFT_DROP; NORM_POS_LE] THEN
9745     MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
9746      [MATCH_MP_TAC SUBSET_TRANS THEN
9747       EXISTS_TAC `ball(vec 0:real^M,K + &1)` THEN
9748       ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET; IN_BALL] THEN
9749       ASM_SIMP_TAC[NORM_ARITH `norm(x) <= K ==> dist(vec 0,x) < K + &1`];
9750       ALL_TAC] THEN
9751     DISCH_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
9752     EXISTS_TAC `interval[a:real^M,b]` THEN
9753     EXISTS_TAC `d:(real^M->bool)->bool` THEN ASM_REWRITE_TAC[];
9754     ALL_TAC] THEN
9755   FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN
9756   REWRITE_TAC[HAS_INTEGRAL_INTEGRAL; has_integral] THEN
9757   DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
9758   DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool` MP_TAC) THEN
9759   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*")) THEN
9760   MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`]
9761                 HENSTOCK_LEMMA) THEN
9762   ANTS_TAC THENL
9763    [MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
9764     EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV];
9765     ALL_TAC] THEN
9766   DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
9767   DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool` MP_TAC) THEN
9768   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "+")) THEN
9769   SUBGOAL_THEN `?p. p tagged_division_of interval[a:real^M,b] /\
9770                     d1 fine p /\ d2 fine p`
9771   STRIP_ASSUME_TAC THENL
9772    [REWRITE_TAC[GSYM FINE_INTER] THEN MATCH_MP_TAC FINE_DIVISION_EXISTS THEN
9773     ASM_SIMP_TAC[GAUGE_INTER];
9774     ALL_TAC] THEN
9775   REMOVE_THEN "*" (MP_TAC o SPEC `p:(real^M#(real^M->bool)->bool)`) THEN
9776   REMOVE_THEN "+" (MP_TAC o SPEC `p:(real^M#(real^M->bool)->bool)`) THEN
9777   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
9778    [ASM_MESON_TAC[tagged_division_of]; ALL_TAC] THEN
9779   REWRITE_TAC[ABS_DROP; DROP_SUB] THEN
9780   REWRITE_TAC[LAMBDA_PAIR] THEN DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN
9781   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
9782   ASM_SIMP_TAC[DROP_VSUM; o_DEF; SUM_SUB] THEN
9783   REWRITE_TAC[LAMBDA_PAIR_THM; DROP_CMUL; NORM_MUL; LIFT_DROP] THEN
9784   MATCH_MP_TAC(REAL_ARITH
9785    `sf' = sf /\ si <= i
9786     ==> abs(sf - si) < e / &2
9787         ==> abs(sf' - di) < e / &2
9788             ==> di < i + e`) THEN
9789   CONJ_TAC THENL
9790    [MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM; real_abs] THEN
9791     ASM_MESON_TAC[CONTENT_POS_LE; TAGGED_DIVISION_OF];
9792     ALL_TAC] THEN
9793   SUBGOAL_THEN
9794    `sum p (\(x:real^M,k). norm(integral k f)) =
9795     sum (IMAGE SND p) (\k. norm(integral k (f:real^M->real^N)))`
9796   SUBST1_TAC THENL
9797    [MATCH_MP_TAC SUM_OVER_TAGGED_DIVISION_LEMMA THEN
9798     EXISTS_TAC `interval[a:real^M,b]` THEN ASM_REWRITE_TAC[] THEN
9799     SIMP_TAC[INTEGRAL_NULL; NORM_0];
9800     ALL_TAC] THEN
9801   FIRST_X_ASSUM MATCH_MP_TAC THEN
9802   MATCH_MP_TAC PARTIAL_DIVISION_OF_TAGGED_DIVISION THEN
9803   EXISTS_TAC `interval[a:real^M,b]` THEN ASM_MESON_TAC[tagged_division_of]);;
9804
9805 let ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_UNIV_EQ = prove
9806  (`!f:real^M->real^N.
9807         f absolutely_integrable_on (:real^M) <=>
9808         f integrable_on (:real^M) /\
9809         (\k. integral k f) has_bounded_setvariation_on (:real^M)`,
9810   GEN_TAC THEN EQ_TAC THEN
9811   SIMP_TAC[ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION;
9812            BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE;
9813            ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE]);;
9814
9815 let ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_EQ = prove
9816  (`!f:real^M->real^N a b.
9817         f absolutely_integrable_on interval[a,b] <=>
9818         f integrable_on interval[a,b] /\
9819         (\k. integral k f) has_bounded_setvariation_on interval[a,b]`,
9820   REPEAT GEN_TAC THEN EQ_TAC THEN
9821   SIMP_TAC[ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION;
9822            BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE_INTERVAL;
9823            ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE]);;
9824
9825 let ABSOLUTELY_INTEGRABLE_SET_VARIATION = prove
9826  (`!f:real^M->real^N a b.
9827         f absolutely_integrable_on interval[a,b]
9828         ==> set_variation (interval[a,b]) (\k. integral k f) =
9829                  drop(integral (interval[a,b]) (\x. lift(norm(f x))))`,
9830   REPEAT STRIP_TAC THEN REWRITE_TAC[set_variation] THEN
9831   MATCH_MP_TAC REAL_SUP_UNIQUE THEN
9832   REWRITE_TAC[FORALL_IN_GSPEC; EXISTS_IN_GSPEC] THEN CONJ_TAC THENL
9833    [X_GEN_TAC `d:(real^M->bool)->bool` THEN
9834     DISCH_THEN(X_CHOOSE_THEN `s:real^M->bool` STRIP_ASSUME_TAC) THEN
9835     MATCH_MP_TAC REAL_LE_TRANS THEN
9836     EXISTS_TAC `drop(integral s (\x. lift(norm((f:real^M->real^N) x))))` THEN
9837     CONJ_TAC THENL
9838      [MP_TAC(ISPECL [`\x. lift(norm((f:real^M->real^N) x))`;
9839                      `d:(real^M->bool)->bool`; `s:real^M->bool`]
9840         INTEGRAL_COMBINE_DIVISION_TOPDOWN) THEN
9841       ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
9842        [RULE_ASSUM_TAC(REWRITE_RULE[absolutely_integrable_on]) THEN
9843         ASM_REWRITE_TAC[] THEN
9844         MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
9845         EXISTS_TAC `interval[a:real^M,b]` THEN ASM_MESON_TAC[];
9846         DISCH_THEN SUBST1_TAC] THEN
9847       FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
9848       ASM_SIMP_TAC[DROP_VSUM] THEN MATCH_MP_TAC SUM_LE THEN
9849       ASM_REWRITE_TAC[o_THM] THEN
9850       REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
9851       REWRITE_TAC[LIFT_DROP; REAL_LE_REFL; GSYM absolutely_integrable_on] THEN
9852       RULE_ASSUM_TAC(REWRITE_RULE[division_of]) THEN
9853       ASM_MESON_TAC[ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL; SUBSET_TRANS];
9854       MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN
9855       ASM_REWRITE_TAC[LIFT_DROP; NORM_POS_LE] THEN
9856       RULE_ASSUM_TAC(REWRITE_RULE[absolutely_integrable_on]) THEN
9857       ASM_REWRITE_TAC[] THEN
9858       MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
9859       EXISTS_TAC `interval[a:real^M,b]` THEN ASM_MESON_TAC[]];
9860     X_GEN_TAC `B:real` THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN
9861     ABBREV_TAC `e = drop(integral (interval [a,b])
9862                                   (\x. lift(norm((f:real^M->real^N) x)))) -
9863                     B` THEN
9864     DISCH_TAC THEN
9865     FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE) THEN
9866     DISCH_THEN(MP_TAC o SPEC `e / &2` o MATCH_MP HENSTOCK_LEMMA) THEN
9867     ASM_REWRITE_TAC[REAL_HALF] THEN
9868     DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool`
9869      (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "F"))) THEN
9870     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [absolutely_integrable_on]) THEN
9871     DISCH_THEN(MP_TAC o CONJUNCT2) THEN
9872     REWRITE_TAC[HAS_INTEGRAL_INTEGRAL; has_integral] THEN
9873     DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
9874     DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool`
9875      (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "A"))) THEN
9876     MP_TAC(ISPECL
9877      [`\x. (d1:real^M->real^M->bool) x INTER d2 x`;
9878       `a:real^M`; `b:real^M`]
9879      FINE_DIVISION_EXISTS) THEN
9880     ASM_SIMP_TAC[GAUGE_INTER; FINE_INTER] THEN
9881     DISCH_THEN(X_CHOOSE_THEN `p:real^M#(real^M->bool)->bool`
9882         STRIP_ASSUME_TAC) THEN
9883     REMOVE_THEN "A" (MP_TAC o SPEC  `p:real^M#(real^M->bool)->bool`) THEN
9884     REMOVE_THEN "F" (MP_TAC o SPEC  `p:real^M#(real^M->bool)->bool`) THEN
9885     ASM_REWRITE_TAC[] THEN
9886     ANTS_TAC THENL [ASM_MESON_TAC[tagged_division_of]; ALL_TAC] THEN
9887     MP_TAC(ISPECL
9888      [`\x. lift(norm((f:real^M->real^N) x))`;
9889       `a:real^M`; `b:real^M`; `p:real^M#(real^M->bool)->bool`]
9890       INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN) THEN
9891     ANTS_TAC THENL
9892      [RULE_ASSUM_TAC(REWRITE_RULE[absolutely_integrable_on]) THEN
9893       ASM_REWRITE_TAC[];
9894       DISCH_THEN SUBST_ALL_TAC] THEN
9895     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
9896     DISCH_TAC THEN
9897     SUBGOAL_THEN
9898      `abs(sum p (\(x,k). content k * norm((f:real^M->real^N) x)) -
9899           sum p (\(x,k:real^M->bool). norm(integral k f))) < e / &2`
9900     MP_TAC THENL
9901      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
9902         REAL_LET_TRANS)) THEN
9903       ASM_SIMP_TAC[GSYM SUM_SUB] THEN MATCH_MP_TAC SUM_ABS_LE THEN
9904       ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN REPEAT STRIP_TAC THEN
9905       MATCH_MP_TAC(NORM_ARITH
9906        `x = norm u ==> abs(x - norm v) <= norm(u - v:real^N)`) THEN
9907       REWRITE_TAC[NORM_MUL; real_abs] THEN
9908       ASM_MESON_TAC[CONTENT_POS_LE; TAGGED_DIVISION_OF];
9909       ALL_TAC] THEN
9910     ONCE_REWRITE_TAC[GSYM NORM_LIFT] THEN
9911     ASM_SIMP_TAC[LIFT_SUB; LIFT_SUM] THEN
9912     REWRITE_TAC[LAMBDA_PAIR_THM; o_DEF; LIFT_CMUL; IMP_IMP] THEN
9913     DISCH_THEN(MP_TAC o MATCH_MP (NORM_ARITH
9914      `norm(x - y:real^N) < e / &2 /\ norm(x - z) < e / &2
9915       ==> norm(y - z) < e`)) THEN
9916     REWRITE_TAC[NORM_1; DROP_SUB] THEN
9917     DISCH_THEN(MP_TAC o SPEC `B:real` o MATCH_MP
9918      (REAL_ARITH `!B. abs(x - y) < e ==> y - B = e ==> &0 < x - B`)) THEN
9919     ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[DROP_VSUM; REAL_SUB_LT] THEN
9920     REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM; LIFT_DROP] THEN DISCH_TAC THEN
9921     EXISTS_TAC `IMAGE SND (p:real^M#(real^M->bool)->bool)` THEN CONJ_TAC THENL
9922      [EXISTS_TAC `interval[a:real^M,b]` THEN
9923       ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION; SUBSET_REFL];
9924       FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
9925         SUM_OVER_TAGGED_DIVISION_LEMMA)) THEN
9926       DISCH_THEN(fun th ->
9927        W(MP_TAC o PART_MATCH (rand o rand) th o rand o snd)) THEN
9928       SIMP_TAC[INTEGRAL_NULL; NORM_0] THEN
9929       DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[]]]);;
9930
9931 let ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV = prove
9932  (`!f s. (\x. if x IN s then f x else vec 0)
9933               absolutely_integrable_on (:real^M) <=>
9934          f absolutely_integrable_on s`,
9935   REWRITE_TAC[absolutely_integrable_on; INTEGRABLE_RESTRICT_UNIV;
9936               COND_RAND; NORM_0; LIFT_NUM]);;
9937
9938 let ABSOLUTELY_INTEGRABLE_CONST = prove
9939  (`!a b c. (\x. c) absolutely_integrable_on interval[a,b]`,
9940   REWRITE_TAC[absolutely_integrable_on; INTEGRABLE_CONST]);;
9941
9942 let ABSOLUTELY_INTEGRABLE_ADD = prove
9943  (`!f:real^M->real^N g s.
9944         f absolutely_integrable_on s /\
9945         g absolutely_integrable_on s
9946         ==> (\x. f(x) + g(x)) absolutely_integrable_on s`,
9947   SUBGOAL_THEN
9948    `!f:real^M->real^N g.
9949         f absolutely_integrable_on (:real^M) /\
9950         g absolutely_integrable_on (:real^M)
9951         ==> (\x. f(x) + g(x)) absolutely_integrable_on (:real^M)`
9952   ASSUME_TAC THENL
9953    [ALL_TAC;
9954     ONCE_REWRITE_TAC[GSYM ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV] THEN
9955     REPEAT GEN_TAC THEN DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN
9956     REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN
9957     AP_THM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN
9958     GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_ADD_LID]] THEN
9959   REPEAT STRIP_TAC THEN
9960   EVERY_ASSUM(STRIP_ASSUME_TAC o
9961    GEN_REWRITE_RULE I [absolutely_integrable_on]) THEN
9962   MATCH_MP_TAC BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE THEN
9963   ASM_SIMP_TAC[INTEGRABLE_ADD] THEN
9964   MP_TAC(ISPECL [`g:real^M->real^N`; `(:real^M)`]
9965      ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION) THEN
9966   MP_TAC(ISPECL [`f:real^M->real^N`; `(:real^M)`]
9967      ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION) THEN
9968   ASM_REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN
9969   DISCH_THEN(X_CHOOSE_TAC `B1:real`) THEN
9970   DISCH_THEN(X_CHOOSE_TAC `B2:real`) THEN EXISTS_TAC `B1 + B2:real` THEN
9971   X_GEN_TAC `d:(real^M->bool)->bool` THEN DISCH_TAC THEN
9972   REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `d:(real^M->bool)->bool`)) THEN
9973   ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
9974   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
9975    `a <= B1 ==> x <= a + B2 ==> x <= B1 + B2`)) THEN
9976   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
9977    `b <= B2 ==> x <= a + b ==> x <= a + B2`)) THEN
9978   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
9979   ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN
9980   FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN
9981   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN STRIP_TAC THEN
9982   MATCH_MP_TAC(NORM_ARITH `x = y + z ==> norm(x) <= norm(y) + norm(z)`) THEN
9983   MATCH_MP_TAC INTEGRAL_ADD THEN CONJ_TAC THEN
9984   MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
9985   EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]);;
9986
9987 let ABSOLUTELY_INTEGRABLE_SUB = prove
9988  (`!f:real^M->real^N g s.
9989         f absolutely_integrable_on s /\
9990         g absolutely_integrable_on s
9991         ==> (\x. f(x) - g(x)) absolutely_integrable_on s`,
9992   REWRITE_TAC[VECTOR_SUB] THEN
9993   SIMP_TAC[ABSOLUTELY_INTEGRABLE_ADD; ABSOLUTELY_INTEGRABLE_NEG]);;
9994
9995 let ABSOLUTELY_INTEGRABLE_LINEAR = prove
9996  (`!f:real^M->real^N h:real^N->real^P s.
9997         f absolutely_integrable_on s /\ linear h
9998         ==> (h o f) absolutely_integrable_on s`,
9999   SUBGOAL_THEN
10000    `!f:real^M->real^N h:real^N->real^P.
10001         f absolutely_integrable_on (:real^M) /\ linear h
10002         ==> (h o f) absolutely_integrable_on (:real^M)`
10003   ASSUME_TAC THENL
10004    [ALL_TAC;
10005     ONCE_REWRITE_TAC[GSYM ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV] THEN
10006     REPEAT GEN_TAC THEN DISCH_THEN(fun th ->
10007      ANTE_RES_THEN MP_TAC th THEN
10008      ASSUME_TAC(MATCH_MP LINEAR_0 (CONJUNCT2 th))) THEN
10009     ASM_REWRITE_TAC[o_DEF; COND_RAND]] THEN
10010   REPEAT STRIP_TAC THEN
10011   MATCH_MP_TAC BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE THEN
10012   FIRST_ASSUM(MP_TAC o
10013     MATCH_MP ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION) THEN
10014   RULE_ASSUM_TAC(REWRITE_RULE[absolutely_integrable_on]) THEN
10015   ASM_SIMP_TAC[INTEGRABLE_LINEAR; HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN
10016   FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o MATCH_MP
10017               LINEAR_BOUNDED_POS) THEN
10018   DISCH_THEN(X_CHOOSE_TAC `b:real`) THEN EXISTS_TAC `B * b:real` THEN
10019   X_GEN_TAC `d:(real^M->bool)->bool` THEN DISCH_TAC THEN
10020   MATCH_MP_TAC REAL_LE_TRANS THEN
10021   EXISTS_TAC `B * sum d (\k. norm(integral k (f:real^M->real^N)))` THEN
10022   ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN REWRITE_TAC[GSYM SUM_LMUL] THEN
10023   MATCH_MP_TAC SUM_LE THEN
10024   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
10025   FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN
10026   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN
10027   MATCH_MP_TAC REAL_LE_TRANS THEN
10028   EXISTS_TAC `norm(h(integral (interval[a,b]) (f:real^M->real^N)):real^P)` THEN
10029   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
10030   MATCH_MP_TAC INTEGRAL_UNIQUE THEN MATCH_MP_TAC HAS_INTEGRAL_LINEAR THEN
10031   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL] THEN
10032   MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
10033   EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]);;
10034
10035 let ABSOLUTELY_INTEGRABLE_VSUM = prove
10036  (`!f:A->real^M->real^N s t.
10037         FINITE t /\
10038         (!a. a IN t ==> (f a) absolutely_integrable_on s)
10039         ==>  (\x. vsum t (\a. f a x)) absolutely_integrable_on s`,
10040   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
10041   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
10042   SIMP_TAC[VSUM_CLAUSES; ABSOLUTELY_INTEGRABLE_0; IN_INSERT;
10043            ABSOLUTELY_INTEGRABLE_ADD; ETA_AX]);;
10044
10045 let ABSOLUTELY_INTEGRABLE_ABS = prove
10046  (`!f:real^M->real^N s.
10047         f absolutely_integrable_on s
10048         ==> (\x. (lambda i. abs(f(x)$i)):real^N) absolutely_integrable_on s`,
10049   REPEAT STRIP_TAC THEN
10050   SUBGOAL_THEN
10051    `(\x. (lambda i. abs(f(x)$i))):real^M->real^N =
10052     (\x. vsum (1..dimindex(:N))
10053         (\i. (((\y. (lambda j. if j = i then drop y else &0)) o
10054                (\x. lift(norm((lambda j. if j = i then x$i else &0):real^N))) o
10055                (f:real^M->real^N)) x)))`
10056   SUBST1_TAC THENL
10057    [REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `x:real^M` THEN
10058     GEN_REWRITE_TAC I [CART_EQ] THEN
10059     X_GEN_TAC `i:num` THEN STRIP_TAC THEN
10060     ASM_SIMP_TAC[LAMBDA_BETA; VSUM_COMPONENT; o_THM] THEN
10061     GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN
10062     ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG; LIFT_DROP] THEN
10063     GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN
10064     REWRITE_TAC[vector_norm; dot] THEN MATCH_MP_TAC EQ_TRANS THEN
10065     EXISTS_TAC `sqrt(sum (1..dimindex(:N))
10066                          (\k. if k = i then ((f:real^M->real^N) x)$i pow 2
10067                               else &0))` THEN
10068     CONJ_TAC THENL
10069      [ASM_REWRITE_TAC[SUM_DELTA; IN_NUMSEG; POW_2_SQRT_ABS]; ALL_TAC] THEN
10070     AP_TERM_TAC THEN MATCH_MP_TAC SUM_EQ THEN
10071     SIMP_TAC[IN_NUMSEG; LAMBDA_BETA] THEN
10072     REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
10073     ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_POW_2];
10074     ALL_TAC] THEN
10075   MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_VSUM THEN
10076   REWRITE_TAC[IN_NUMSEG; FINITE_NUMSEG] THEN
10077   REPEAT STRIP_TAC THEN REWRITE_TAC[ETA_AX] THEN
10078   MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_LINEAR THEN CONJ_TAC THENL
10079    [ALL_TAC;
10080     SIMP_TAC[linear; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
10081              LAMBDA_BETA] THEN
10082     REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
10083     ASM_REWRITE_TAC[DROP_ADD; REAL_ADD_LID; DROP_CMUL; REAL_MUL_RZERO]] THEN
10084   REWRITE_TAC[o_DEF] THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN
10085   SUBGOAL_THEN
10086     `(\x. lambda j. if j = i then (f x:real^N)$i else &0):real^M->real^N =
10087      (\x. lambda j. if j = i then x$i else &0) o f`
10088   SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
10089   MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_LINEAR THEN ASM_REWRITE_TAC[] THEN
10090   SIMP_TAC[linear; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
10091              LAMBDA_BETA] THEN
10092   REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
10093   ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_ADD_LID] THEN
10094   FIRST_X_ASSUM SUBST_ALL_TAC THEN
10095   ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT]);;
10096
10097 let ABSOLUTELY_INTEGRABLE_MAX = prove
10098  (`!f:real^M->real^N g:real^M->real^N s.
10099         f absolutely_integrable_on s /\ g absolutely_integrable_on s
10100         ==> (\x. (lambda i. max (f(x)$i) (g(x)$i)):real^N)
10101             absolutely_integrable_on s`,
10102   REPEAT GEN_TAC THEN DISCH_TAC THEN
10103   FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_SUB) THEN
10104   DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ABS) THEN
10105   FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ADD) THEN
10106   REWRITE_TAC[IMP_IMP] THEN
10107   DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ADD) THEN
10108   DISCH_THEN(MP_TAC o SPEC `inv(&2)` o
10109      MATCH_MP ABSOLUTELY_INTEGRABLE_CMUL) THEN
10110   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
10111   REWRITE_TAC[FUN_EQ_THM; CART_EQ] THEN
10112   SIMP_TAC[LAMBDA_BETA; VECTOR_MUL_COMPONENT; VECTOR_SUB_COMPONENT;
10113            VECTOR_ADD_COMPONENT] THEN
10114   REPEAT STRIP_TAC THEN REAL_ARITH_TAC);;
10115
10116 let ABSOLUTELY_INTEGRABLE_MAX_1 = prove
10117  (`!f:real^M->real g:real^M->real s.
10118         (\x. lift(f x)) absolutely_integrable_on s /\
10119         (\x. lift(g x)) absolutely_integrable_on s
10120         ==> (\x. lift(max (f x) (g x))) absolutely_integrable_on s`,
10121   REPEAT STRIP_TAC THEN
10122   SUBGOAL_THEN `(\x. (lambda i. max (lift(f x)$i) (lift(g x)$i)):real^1)
10123                 absolutely_integrable_on (s:real^M->bool)`
10124   MP_TAC THENL [ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_MAX]; ALL_TAC] THEN
10125   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
10126   REWRITE_TAC[FUN_EQ_THM; CART_EQ] THEN SIMP_TAC[LAMBDA_BETA; lift]);;
10127
10128 let ABSOLUTELY_INTEGRABLE_MIN = prove
10129  (`!f:real^M->real^N g:real^M->real^N s.
10130         f absolutely_integrable_on s /\ g absolutely_integrable_on s
10131         ==> (\x. (lambda i. min (f(x)$i) (g(x)$i)):real^N)
10132             absolutely_integrable_on s`,
10133   REPEAT GEN_TAC THEN DISCH_TAC THEN
10134   FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_SUB) THEN
10135   DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ABS) THEN
10136   FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ADD) THEN
10137   REWRITE_TAC[IMP_IMP] THEN
10138   DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_SUB) THEN
10139   DISCH_THEN(MP_TAC o SPEC `inv(&2)` o
10140      MATCH_MP ABSOLUTELY_INTEGRABLE_CMUL) THEN
10141   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
10142   REWRITE_TAC[FUN_EQ_THM; CART_EQ] THEN
10143   SIMP_TAC[LAMBDA_BETA; VECTOR_MUL_COMPONENT; VECTOR_SUB_COMPONENT;
10144            VECTOR_ADD_COMPONENT] THEN
10145   REPEAT STRIP_TAC THEN REAL_ARITH_TAC);;
10146
10147 let ABSOLUTELY_INTEGRABLE_MIN_1 = prove
10148  (`!f:real^M->real g:real^M->real s.
10149         (\x. lift(f x)) absolutely_integrable_on s /\
10150         (\x. lift(g x)) absolutely_integrable_on s
10151         ==> (\x. lift(min (f x) (g x))) absolutely_integrable_on s`,
10152   REPEAT STRIP_TAC THEN
10153   SUBGOAL_THEN `(\x. (lambda i. min (lift(f x)$i) (lift(g x)$i)):real^1)
10154                 absolutely_integrable_on (s:real^M->bool)`
10155   MP_TAC THENL [ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_MIN]; ALL_TAC] THEN
10156   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
10157   REWRITE_TAC[FUN_EQ_THM; CART_EQ] THEN SIMP_TAC[LAMBDA_BETA; lift]);;
10158
10159 let ABSOLUTELY_INTEGRABLE_ABS_EQ = prove
10160  (`!f:real^M->real^N s.
10161         f absolutely_integrable_on s <=>
10162           f integrable_on s /\
10163           (\x. (lambda i. abs(f(x)$i)):real^N) integrable_on s`,
10164   REPEAT GEN_TAC THEN EQ_TAC THEN
10165   SIMP_TAC[ABSOLUTELY_INTEGRABLE_ABS;
10166            ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE] THEN
10167   SUBGOAL_THEN
10168    `!f:real^M->real^N.
10169         f integrable_on (:real^M) /\
10170         (\x. (lambda i. abs(f(x)$i)):real^N) integrable_on (:real^M)
10171         ==> f absolutely_integrable_on (:real^M)`
10172   ASSUME_TAC THENL
10173    [ALL_TAC;
10174     ONCE_REWRITE_TAC[GSYM ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV;
10175                      GSYM INTEGRABLE_RESTRICT_UNIV] THEN
10176     DISCH_THEN(fun th -> FIRST_X_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN
10177     MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN
10178     AP_THM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN
10179     REWRITE_TAC[CART_EQ] THEN REPEAT STRIP_TAC THEN
10180     ASM_SIMP_TAC[LAMBDA_BETA; COND_COMPONENT; VEC_COMPONENT] THEN
10181     COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_ABS_0]] THEN
10182   REPEAT STRIP_TAC THEN
10183   MATCH_MP_TAC BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE THEN
10184   ASM_REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN
10185   EXISTS_TAC
10186    `sum (1..dimindex(:N))
10187         (\i. integral (:real^M)
10188               (\x. (lambda j. abs ((f:real^M->real^N) x$j)):real^N)$i)` THEN
10189   X_GEN_TAC `d:(real^M->bool)->bool` THEN DISCH_TAC THEN
10190   MATCH_MP_TAC REAL_LE_TRANS THEN
10191   EXISTS_TAC `sum d (\k. sum (1..dimindex(:N))
10192       (\i. integral k
10193               (\x. (lambda j. abs ((f:real^M->real^N) x$j)):real^N)$i))` THEN
10194   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN CONJ_TAC THENL
10195    [MATCH_MP_TAC SUM_LE THEN
10196     FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN
10197     MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN
10198     MATCH_MP_TAC REAL_LE_TRANS THEN
10199     EXISTS_TAC `sum (1..dimindex(:N))
10200              (\i. abs((integral (interval[a,b]) (f:real^M->real^N))$i))` THEN
10201     REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_LE_NUMSEG THEN
10202     X_GEN_TAC `k:num` THEN STRIP_TAC THEN REWRITE_TAC[] THEN
10203     MATCH_MP_TAC(REAL_ARITH `x <= y /\ --x <= y ==> abs(x) <= y`) THEN
10204     ASM_SIMP_TAC[GSYM VECTOR_NEG_COMPONENT] THEN
10205     SUBGOAL_THEN `(f:real^M->real^N) integrable_on interval[a,b] /\
10206         (\x. (lambda i. abs (f x$i)):real^N) integrable_on interval[a,b]`
10207     STRIP_ASSUME_TAC THENL
10208      [CONJ_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
10209       EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV];
10210       ALL_TAC] THEN
10211     ASM_SIMP_TAC[GSYM INTEGRAL_NEG] THEN
10212     CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_COMPONENT_LE THEN
10213     ASM_SIMP_TAC[INTEGRABLE_NEG; LAMBDA_BETA] THEN
10214     ASM_SIMP_TAC[VECTOR_NEG_COMPONENT] THEN
10215     REPEAT STRIP_TAC THEN REAL_ARITH_TAC;
10216     ALL_TAC] THEN
10217   W(MP_TAC o PART_MATCH (lhs o rand) SUM_SWAP o lhand o snd) THEN
10218   ASM_REWRITE_TAC[FINITE_NUMSEG] THEN DISCH_THEN SUBST_ALL_TAC THEN
10219   MATCH_MP_TAC SUM_LE_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
10220   REWRITE_TAC[] THEN
10221   MATCH_MP_TAC REAL_LE_TRANS THEN
10222   EXISTS_TAC
10223    `(integral (UNIONS d)
10224               (\x. (lambda j. abs ((f:real^M->real^N) x$j)):real^N))$k` THEN
10225   CONJ_TAC THENL
10226    [ASM_SIMP_TAC[GSYM VSUM_COMPONENT] THEN
10227     MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_THM_TAC THEN AP_TERM_TAC THEN
10228     CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_TOPDOWN THEN
10229     ASM_REWRITE_TAC[];
10230     MATCH_MP_TAC INTEGRAL_SUBSET_COMPONENT_LE THEN
10231     ASM_SIMP_TAC[LAMBDA_BETA; SUBSET_UNIV; REAL_ABS_POS]] THEN
10232   MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
10233   MAP_EVERY EXISTS_TAC [`(:real^M)`; `d:(real^M->bool)->bool`] THEN
10234   ASM_REWRITE_TAC[SUBSET_UNIV]);;
10235
10236 let NONNEGATIVE_ABSOLUTELY_INTEGRABLE = prove
10237  (`!f:real^M->real^N s.
10238         (!x i. x IN s /\ 1 <= i /\ i <= dimindex(:N)
10239                ==> &0 <= f(x)$i) /\
10240         f integrable_on s
10241         ==> f absolutely_integrable_on s`,
10242   SIMP_TAC[ABSOLUTELY_INTEGRABLE_ABS_EQ] THEN
10243   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_EQ THEN
10244   EXISTS_TAC `f:real^M->real^N` THEN
10245   ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA; real_abs]);;
10246
10247 let ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND = prove
10248  (`!f:real^M->real^N g s.
10249         (!x. x IN s ==> norm(f x) <= drop(g x)) /\
10250         f integrable_on s /\ g integrable_on s
10251         ==> f absolutely_integrable_on s`,
10252   SUBGOAL_THEN
10253    `!f:real^M->real^N g.
10254         (!x. norm(f x) <= drop(g x)) /\
10255         f integrable_on (:real^M) /\ g integrable_on (:real^M)
10256         ==> f absolutely_integrable_on (:real^M)`
10257   ASSUME_TAC THENL
10258    [ALL_TAC;
10259     ONCE_REWRITE_TAC[GSYM INTEGRABLE_RESTRICT_UNIV; GSYM
10260                      ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV] THEN
10261     REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
10262     EXISTS_TAC `(\x. if x IN s then g x else vec 0):real^M->real^1` THEN
10263     ASM_REWRITE_TAC[] THEN GEN_TAC THEN COND_CASES_TAC THEN
10264     ASM_SIMP_TAC[REAL_LE_REFL; NORM_0; DROP_VEC]] THEN
10265   REPEAT STRIP_TAC THEN
10266   MATCH_MP_TAC BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE THEN
10267   ASM_REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN
10268   EXISTS_TAC `drop(integral(:real^M) g)` THEN
10269   X_GEN_TAC `d:(real^M->bool)->bool` THEN DISCH_TAC THEN
10270   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
10271   MATCH_MP_TAC REAL_LE_TRANS THEN
10272   EXISTS_TAC `sum d (\k. drop(integral k (g:real^M->real^1)))` THEN
10273   CONJ_TAC THENL
10274    [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[] THEN
10275     FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
10276     REPEAT STRIP_TAC THEN
10277     MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN ASM_REWRITE_TAC[] THEN
10278     CONJ_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
10279     EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV];
10280     ALL_TAC] THEN
10281   MATCH_MP_TAC REAL_LE_TRANS THEN
10282   EXISTS_TAC `drop(integral (UNIONS d:real^M->bool) g)` THEN CONJ_TAC THENL
10283    [MATCH_MP_TAC(REAL_ARITH `x = y ==> y <= x`) THEN
10284     ASM_SIMP_TAC[GSYM LIFT_EQ; LIFT_DROP; LIFT_SUM; o_DEF] THEN
10285     MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_BOTTOMUP THEN
10286     FIRST_ASSUM(fun th -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
10287     REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
10288     EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV];
10289     MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN
10290     ASM_REWRITE_TAC[SUBSET_UNIV; IN_UNIV] THEN CONJ_TAC THENL
10291      [ALL_TAC; ASM_MESON_TAC[NORM_ARITH `norm(x) <= y ==> &0 <= y`]] THEN
10292     MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
10293     MAP_EVERY EXISTS_TAC [`(:real^M)`; `d:(real^M->bool)->bool`] THEN
10294     ASM_REWRITE_TAC[SUBSET_UNIV]]);;
10295
10296 let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_BOUND = prove
10297  (`!f:real^M->real^N g:real^M->real^P s.
10298         (!x. x IN s ==> norm(f x) <= norm(g x)) /\
10299         f integrable_on s /\ g absolutely_integrable_on s
10300         ==> f absolutely_integrable_on s`,
10301   REPEAT STRIP_TAC THEN
10302   FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I
10303     [absolutely_integrable_on]) THEN
10304   MP_TAC(ISPECL
10305    [`f:real^M->real^N`; `(\x. lift(norm((g:real^M->real^P) x)))`;
10306     `s:real^M->bool`] ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND) THEN
10307   ASM_REWRITE_TAC[LIFT_DROP]);;
10308
10309 let ABSOLUTELY_INTEGRABLE_INF_1 = prove
10310  (`!fs s:real^N->bool k:A->bool.
10311         FINITE k /\ ~(k = {}) /\
10312         (!i. i IN k ==> (\x. lift(fs x i)) absolutely_integrable_on s)
10313         ==> (\x. lift(inf (IMAGE (fs x) k))) absolutely_integrable_on s`,
10314   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
10315   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[IMAGE_CLAUSES] THEN
10316   SIMP_TAC[INF_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
10317   MAP_EVERY X_GEN_TAC [`a:A`; `k:A->bool`] THEN
10318   ASM_CASES_TAC `k:A->bool = {}` THEN ASM_REWRITE_TAC[] THEN
10319   SIMP_TAC[IN_SING; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
10320   REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
10321   REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MIN_1 THEN
10322   CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INSERT] THEN
10323   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
10324   ASM_REWRITE_TAC[IN_INSERT]);;
10325
10326 let ABSOLUTELY_INTEGRABLE_SUP_1 = prove
10327  (`!fs s:real^N->bool k:A->bool.
10328         FINITE k /\ ~(k = {}) /\
10329         (!i. i IN k ==> (\x. lift(fs x i)) absolutely_integrable_on s)
10330         ==> (\x. lift(sup (IMAGE (fs x) k))) absolutely_integrable_on s`,
10331   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
10332   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[IMAGE_CLAUSES] THEN
10333   SIMP_TAC[SUP_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
10334   MAP_EVERY X_GEN_TAC [`a:A`; `k:A->bool`] THEN
10335   ASM_CASES_TAC `k:A->bool = {}` THEN ASM_REWRITE_TAC[] THEN
10336   SIMP_TAC[IN_SING; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
10337   REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
10338   REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MAX_1 THEN
10339   CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INSERT] THEN
10340   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
10341   ASM_REWRITE_TAC[IN_INSERT]);;
10342
10343 let ABSOLUTELY_INTEGRABLE_CONTINUOUS = prove
10344  (`!f:real^M->real^N a b.
10345         f continuous_on interval[a,b]
10346         ==> f absolutely_integrable_on interval[a,b]`,
10347   REPEAT STRIP_TAC THEN
10348   MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
10349   SUBGOAL_THEN `compact(IMAGE (f:real^M->real^N) (interval[a,b]))` MP_TAC THENL
10350    [ASM_SIMP_TAC[COMPACT_CONTINUOUS_IMAGE; COMPACT_INTERVAL]; ALL_TAC] THEN
10351   DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN
10352   REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN
10353   DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
10354   EXISTS_TAC `\x:real^M. lift(B)` THEN
10355   ASM_SIMP_TAC[INTEGRABLE_CONST; LIFT_DROP; INTEGRABLE_CONTINUOUS]);;
10356
10357 let INTEGRABLE_MIN_CONST_1 = prove
10358  (`!f s t.
10359         &0 <= t /\ (!x. x IN s ==> &0 <= f x) /\
10360         (\x:real^N. lift(f x)) integrable_on s
10361         ==> (\x. lift(min (f x) t)) integrable_on s`,
10362   REPEAT STRIP_TAC THEN
10363   MATCH_MP_TAC INTEGRABLE_ON_ALL_INTERVALS_INTEGRABLE_BOUND THEN
10364   EXISTS_TAC `\x:real^N. lift(f x)` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
10365    [REPEAT GEN_TAC THEN
10366     MP_TAC(ISPECL
10367      [`\x:real^N. if x IN s then f x else &0`;
10368       `(\x. t):real^N->real`;
10369       `interval[a:real^N,b]`] ABSOLUTELY_INTEGRABLE_MIN_1) THEN
10370     REWRITE_TAC[] THEN ANTS_TAC THENL
10371      [SIMP_TAC[ABSOLUTELY_INTEGRABLE_CONTINUOUS; CONTINUOUS_ON_CONST] THEN
10372       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL THEN
10373       EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[SUBSET_UNIV] THEN
10374       REWRITE_TAC[COND_RAND; LIFT_DROP; LIFT_NUM] THEN
10375       REWRITE_TAC[ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV] THEN
10376       MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN
10377       ASM_SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
10378       ASM_REWRITE_TAC[IMP_IMP; DIMINDEX_1; FORALL_1; LIFT_DROP; GSYM drop];
10379       DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE) THEN
10380       MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
10381       REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN
10382       COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
10383       CONV_TAC REAL_RAT_REDUCE_CONV THEN
10384       REWRITE_TAC[GSYM DROP_EQ; DROP_VEC; LIFT_DROP] THEN ASM_REAL_ARITH_TAC];
10385     X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
10386     FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
10387     ASM_REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP] THEN
10388     ASM_REAL_ARITH_TAC]);;
10389
10390 let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_UBOUND = prove
10391  (`!f:real^M->real^N g:real^M->real^N s.
10392         (!x i. x IN s /\ 1 <= i /\ i <= dimindex(:N) ==> f(x)$i <= g(x)$i) /\
10393         f integrable_on s /\ g absolutely_integrable_on s
10394         ==> f absolutely_integrable_on s`,
10395   REPEAT STRIP_TAC THEN SUBGOAL_THEN
10396    `(\x. (g:real^M->real^N)(x) - (g(x) - f(x))) absolutely_integrable_on s`
10397   MP_TAC THENL
10398    [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_SUB THEN
10399     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN
10400     ASM_REWRITE_TAC[REAL_SUB_LE; VECTOR_SUB_COMPONENT] THEN
10401     MATCH_MP_TAC INTEGRABLE_SUB THEN
10402     ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE];
10403     REWRITE_TAC[VECTOR_ARITH `x - (x - y):real^N = y`; ETA_AX]]);;
10404
10405 let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_LBOUND = prove
10406  (`!f:real^M->real^N g:real^M->real^N s.
10407         (!x i. x IN s /\ 1 <= i /\ i <= dimindex(:N) ==> f(x)$i <= g(x)$i) /\
10408         f absolutely_integrable_on s /\ g integrable_on s
10409         ==> g absolutely_integrable_on s`,
10410   REPEAT STRIP_TAC THEN SUBGOAL_THEN
10411    `(\x. (f:real^M->real^N)(x) + (g(x) - f(x))) absolutely_integrable_on s`
10412   MP_TAC THENL
10413    [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_ADD THEN
10414     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN
10415     ASM_REWRITE_TAC[REAL_SUB_LE; VECTOR_SUB_COMPONENT] THEN
10416     MATCH_MP_TAC INTEGRABLE_SUB THEN
10417     ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE];
10418     REWRITE_TAC[VECTOR_ARITH `y + (x - y):real^N = x`; ETA_AX]]);;
10419
10420 let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_UBOUND = prove
10421  (`!f:real^M->real^1 g:real^M->real^1 s.
10422         (!x. x IN s ==> drop(f(x)) <= drop(g(x))) /\
10423         f integrable_on s /\ g absolutely_integrable_on s
10424         ==> f absolutely_integrable_on s`,
10425   REPEAT STRIP_TAC THEN MATCH_MP_TAC
10426     ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_UBOUND THEN
10427   EXISTS_TAC `g:real^M->real^1` THEN
10428   ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
10429   ASM_REWRITE_TAC[IMP_IMP; FORALL_1; DIMINDEX_1; GSYM drop]);;
10430
10431 let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_LBOUND = prove
10432  (`!f:real^M->real^1 g:real^M->real^1 s.
10433         (!x. x IN s ==> drop(f(x)) <= drop(g(x))) /\
10434         f absolutely_integrable_on s /\ g integrable_on s
10435         ==> g absolutely_integrable_on s`,
10436   REPEAT STRIP_TAC THEN MATCH_MP_TAC
10437     ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_LBOUND THEN
10438   EXISTS_TAC `f:real^M->real^1` THEN
10439   ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
10440   ASM_REWRITE_TAC[IMP_IMP; FORALL_1; DIMINDEX_1; GSYM drop]);;
10441
10442 let ABSOLUTELY_INTEGRABLE_PASTECART_SYM = prove
10443  (`!f:real^(M,N)finite_sum->real^P s y.
10444         (\z. f(pastecart (sndcart z) (fstcart z))) absolutely_integrable_on
10445         (IMAGE (\z. pastecart (sndcart z) (fstcart z)) s) <=>
10446         f absolutely_integrable_on s`,
10447   REWRITE_TAC[absolutely_integrable_on; INTEGRABLE_PASTECART_SYM]);;
10448
10449 let [HAS_INTEGRAL_PASTECART_SYM_UNIV; INTEGRAL_PASTECART_SYM_UNIV;
10450     INTEGRABLE_PASTECART_SYM_UNIV; ABSOLUTELY_INTEGRABLE_PASTECART_SYM_UNIV] =
10451     (CONJUNCTS o prove)
10452  (`(!f:real^(M,N)finite_sum->real^P s y.
10453         ((\z. f(pastecart (sndcart z) (fstcart z))) has_integral y) UNIV <=>
10454         (f has_integral y) UNIV) /\
10455    (!f:real^(M,N)finite_sum->real^P s y.
10456         integral UNIV (\z. f(pastecart (sndcart z) (fstcart z))) =
10457         integral UNIV f) /\
10458    (!f:real^(M,N)finite_sum->real^P s y.
10459         (\z. f(pastecart (sndcart z) (fstcart z))) integrable_on UNIV <=>
10460         f integrable_on UNIV) /\
10461    (!f:real^(M,N)finite_sum->real^P s y.
10462      (\z. f(pastecart (sndcart z) (fstcart z)))
10463      absolutely_integrable_on UNIV <=>
10464        f absolutely_integrable_on UNIV)`,
10465   REPEAT STRIP_TAC THENL
10466    [GEN_REWRITE_TAC RAND_CONV [GSYM HAS_INTEGRAL_PASTECART_SYM];
10467     GEN_REWRITE_TAC RAND_CONV [GSYM INTEGRAL_PASTECART_SYM];
10468     GEN_REWRITE_TAC RAND_CONV [GSYM INTEGRABLE_PASTECART_SYM];
10469     GEN_REWRITE_TAC RAND_CONV [GSYM ABSOLUTELY_INTEGRABLE_PASTECART_SYM]] THEN
10470   TRY AP_THM_TAC THEN AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN
10471   MATCH_MP_TAC SURJECTIVE_IMAGE_EQ THEN REWRITE_TAC[IN_UNIV] THEN
10472   REWRITE_TAC[EXISTS_PASTECART; FSTCART_PASTECART; SNDCART_PASTECART] THEN
10473   REWRITE_TAC[FORALL_PASTECART] THEN MESON_TAC[]);;
10474
10475 (* ------------------------------------------------------------------------- *)
10476 (* Relating vector integrals to integrals of components.                     *)
10477 (* ------------------------------------------------------------------------- *)
10478
10479 let HAS_INTEGRAL_COMPONENTWISE = prove
10480  (`!f:real^M->real^N s y.
10481         (f has_integral y) s <=>
10482         !i. 1 <= i /\ i <= dimindex(:N)
10483             ==> ((\x. lift((f x)$i)) has_integral (lift(y$i))) s`,
10484   REPEAT GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
10485    [FIRST_X_ASSUM(MP_TAC o ISPEC `\u:real^N. lift(u$i)` o
10486         MATCH_MP (REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_LINEAR)) THEN
10487     REWRITE_TAC[o_DEF] THEN DISCH_THEN MATCH_MP_TAC THEN
10488     REWRITE_TAC[LINEAR_LIFT_COMPONENT];
10489     GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
10490     GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN
10491     GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV o BINDER_CONV)
10492      [GSYM BASIS_EXPANSION] THEN
10493     MATCH_MP_TAC HAS_INTEGRAL_VSUM THEN
10494     REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
10495     X_GEN_TAC `i:num` THEN STRIP_TAC THEN
10496     FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
10497     DISCH_THEN(MP_TAC o ISPEC `\v. drop(v) % (basis i:real^N)` o
10498         MATCH_MP (REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_LINEAR)) THEN
10499     SIMP_TAC[o_DEF; LIFT_DROP; LINEAR_VMUL_DROP; LINEAR_ID]]);;
10500
10501 let INTEGRABLE_COMPONENTWISE = prove
10502  (`!f:real^M->real^N s.
10503         f integrable_on s <=>
10504         !i. 1 <= i /\ i <= dimindex(:N)
10505             ==> (\x. lift((f x)$i)) integrable_on s`,
10506    REPEAT GEN_TAC THEN REWRITE_TAC[integrable_on] THEN
10507    GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
10508     [HAS_INTEGRAL_COMPONENTWISE] THEN
10509    REWRITE_TAC[GSYM LAMBDA_SKOLEM; GSYM EXISTS_LIFT]);;
10510
10511 let LIFT_INTEGRAL_COMPONENT = prove
10512  (`!f:real^M->real^N.
10513         f integrable_on s
10514         ==> lift((integral s f)$k) = integral s (\x. lift((f x)$k))`,
10515   REPEAT STRIP_TAC THEN
10516   SUBGOAL_THEN `?j. 1 <= j /\ j <= dimindex(:N) /\ !z:real^N. z$k = z$j`
10517   CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
10518   ASM_REWRITE_TAC[] THEN CONV_TAC SYM_CONV THEN
10519   MATCH_MP_TAC INTEGRAL_UNIQUE THEN
10520   FIRST_X_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
10521   GEN_REWRITE_TAC LAND_CONV [HAS_INTEGRAL_COMPONENTWISE] THEN
10522   ASM_SIMP_TAC[]);;
10523
10524 let INTEGRAL_COMPONENT = prove
10525  (`!f:real^M->real^N.
10526         f integrable_on s
10527         ==> (integral s f)$k = drop(integral s (\x. lift((f x)$k)))`,
10528   SIMP_TAC[GSYM LIFT_INTEGRAL_COMPONENT; LIFT_DROP]);;
10529
10530 let ABSOLUTELY_INTEGRABLE_COMPONENTWISE = prove
10531  (`!f:real^M->real^N s.
10532      f absolutely_integrable_on s <=>
10533      (!i. 1 <= i /\ i <= dimindex(:N)
10534           ==> (\x. lift(f x$i)) absolutely_integrable_on s)`,
10535   REPEAT GEN_TAC THEN REWRITE_TAC[absolutely_integrable_on] THEN
10536   MATCH_MP_TAC(MESON[]
10537    `(p <=> !i. a i ==> P i) /\
10538     (p /\ (!i. a i ==> P i) ==> (q <=> (!i. a i ==> Q i)))
10539     ==> (p /\ q <=> (!i. a i ==> P i /\ Q i))`) THEN
10540   CONJ_TAC THENL [REWRITE_TAC[GSYM INTEGRABLE_COMPONENTWISE]; ALL_TAC] THEN
10541   REPEAT(STRIP_TAC ORELSE EQ_TAC) THENL
10542    [SUBGOAL_THEN
10543      `(\x. lift((f:real^M->real^N) x$i)) absolutely_integrable_on s`
10544     MP_TAC THENL [ALL_TAC; SIMP_TAC[absolutely_integrable_on]] THEN
10545     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
10546     EXISTS_TAC `\x. lift(norm((f:real^M->real^N) x))` THEN
10547     ASM_SIMP_TAC[ABS_DROP; LIFT_DROP; COMPONENT_LE_NORM];
10548     SUBGOAL_THEN
10549      `(f:real^M->real^N) absolutely_integrable_on s`
10550     MP_TAC THENL [ALL_TAC; SIMP_TAC[absolutely_integrable_on]] THEN
10551     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
10552     EXISTS_TAC
10553      `\x. vsum (1..dimindex(:N))
10554                (\i. lift(norm(lift((f:real^M->real^N)(x)$i))))` THEN
10555     ASM_SIMP_TAC[INTEGRABLE_VSUM; IN_NUMSEG; FINITE_NUMSEG] THEN
10556     SIMP_TAC[DROP_VSUM; FINITE_NUMSEG; o_DEF; LIFT_DROP] THEN
10557     REWRITE_TAC[NORM_LIFT; NORM_LE_L1]]);;
10558
10559 (* ------------------------------------------------------------------------- *)
10560 (* Dominated convergence.                                                    *)
10561 (* ------------------------------------------------------------------------- *)
10562
10563 let DOMINATED_CONVERGENCE = prove
10564  (`!f:num->real^M->real^N g h s.
10565         (!k. (f k) integrable_on s) /\ h integrable_on s /\
10566         (!k x. x IN s ==> norm(f k x) <= drop(h x)) /\
10567         (!x. x IN s ==> ((\k. f k x) --> g x) sequentially)
10568         ==> g integrable_on s /\
10569             ((\k. integral s (f k)) --> integral s g) sequentially`,
10570   SUBGOAL_THEN
10571     `!f:num->real^M->real^1 g h s.
10572         (!k. (f k) integrable_on s) /\ h integrable_on s /\
10573         (!k x. x IN s ==> norm(f k x) <= drop(h x)) /\
10574         (!x. x IN s ==> ((\k. f k x) --> g x) sequentially)
10575         ==> g integrable_on s /\
10576             ((\k. integral s (f k)) --> integral s g) sequentially`
10577   ASSUME_TAC THENL
10578    [ALL_TAC;
10579     REPEAT GEN_TAC THEN STRIP_TAC THEN
10580     SUBGOAL_THEN
10581      `!j. 1 <= j /\ j <= dimindex(:N)
10582           ==> (\x. lift((g x)$j)) integrable_on s /\
10583               ((\k. integral s (\x. lift (((f:num->real^M->real^N) k x)$j)))
10584                --> integral s (\x. lift ((g x:real^N)$j))) sequentially`
10585     STRIP_ASSUME_TAC THENL
10586      [REPEAT GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
10587       EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[] THEN
10588       REPEAT CONJ_TAC THENL
10589        [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV
10590           [INTEGRABLE_COMPONENTWISE]) THEN
10591         ASM_SIMP_TAC[];
10592         MAP_EVERY X_GEN_TAC [`i:num`; `x:real^M`] THEN DISCH_TAC THEN
10593         MATCH_MP_TAC REAL_LE_TRANS THEN
10594         EXISTS_TAC `norm((f:num->real^M->real^N) i x)` THEN
10595         ASM_SIMP_TAC[NORM_LIFT; COMPONENT_LE_NORM];
10596         X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN
10597         FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN
10598         GEN_REWRITE_TAC LAND_CONV [LIM_COMPONENTWISE_LIFT] THEN
10599         ASM_SIMP_TAC[]];
10600       MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
10601        [GEN_REWRITE_TAC I [INTEGRABLE_COMPONENTWISE] THEN ASM_SIMP_TAC[];
10602         DISCH_TAC THEN  ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT] THEN
10603         ASM_SIMP_TAC[LIFT_INTEGRAL_COMPONENT]]]] THEN
10604   REPEAT GEN_TAC THEN STRIP_TAC THEN
10605   MP_TAC(MATCH_MP MONO_FORALL (GEN `m:num`
10606    (ISPECL [`\k:num x:real^M. lift(inf {drop(f j x) | j IN m..(m+k)})`;
10607             `\x:real^M. lift(inf {drop(f j x) | m:num <= j})`;
10608             `s:real^M->bool`]
10609            MONOTONE_CONVERGENCE_DECREASING))) THEN
10610   REWRITE_TAC[LIFT_DROP] THEN ANTS_TAC THENL
10611    [X_GEN_TAC `m:num` THEN REPEAT CONJ_TAC THENL
10612      [GEN_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
10613       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10614       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INF_1 THEN
10615       REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10616       ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN
10617       REPEAT STRIP_TAC THEN
10618       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
10619       EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[];
10620
10621       REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10622       MATCH_MP_TAC REAL_LE_INF_SUBSET THEN
10623       REWRITE_TAC[IMAGE_EQ_EMPTY; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10624       CONJ_TAC THENL
10625        [MATCH_MP_TAC IMAGE_SUBSET THEN
10626         REWRITE_TAC[SUBSET_NUMSEG] THEN ARITH_TAC;
10627         ALL_TAC] THEN
10628       REWRITE_TAC[FORALL_IN_IMAGE] THEN
10629       MATCH_MP_TAC LOWER_BOUND_FINITE_SET_REAL THEN
10630       REWRITE_TAC[FINITE_NUMSEG];
10631
10632       X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10633       REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10634       REWRITE_TAC[dist; ABS_DROP; LIFT_DROP; DROP_SUB] THEN
10635       MP_TAC(SPEC `{drop((f:num->real^M->real^1) j x) | m <= j}` INF) THEN
10636       ABBREV_TAC `i = inf {drop((f:num->real^M->real^1) j x) | m <= j}` THEN
10637       ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
10638       REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
10639       REWRITE_TAC[IN_ELIM_THM; EXTENSION; NOT_IN_EMPTY] THEN ANTS_TAC THENL
10640        [CONJ_TAC THENL [MESON_TAC[LE_REFL]; ALL_TAC] THEN
10641         EXISTS_TAC `--drop(h(x:real^M))` THEN X_GEN_TAC `j:num` THEN
10642         FIRST_X_ASSUM(MP_TAC o SPECL [`j:num`; `x:real^M`]) THEN
10643         ASM_REWRITE_TAC[ABS_DROP] THEN REAL_ARITH_TAC;
10644         ALL_TAC] THEN
10645       DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `i + e:real`)) THEN
10646       ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(i + e <= i)`] THEN
10647       REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LE] THEN
10648       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN STRIP_TAC THEN
10649       X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10650       FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
10651        `y < i + e ==> i <= ix /\ ix <= y ==> abs(ix - i) < e`)) THEN
10652       CONJ_TAC THENL
10653        [EXPAND_TAC "i" THEN MATCH_MP_TAC REAL_LE_INF_SUBSET THEN
10654         REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
10655         REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10656         ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN CONJ_TAC THENL
10657          [MATCH_MP_TAC IMAGE_SUBSET THEN
10658           REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM] THEN ARITH_TAC;
10659           REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN ASM_MESON_TAC[]];
10660         ALL_TAC] THEN
10661       W(MP_TAC o C SPEC INF o rand o lhand o snd) THEN ANTS_TAC THENL
10662        [REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
10663         REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10664         REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10665         EXISTS_TAC `i:real` THEN GEN_TAC THEN REWRITE_TAC[IN_NUMSEG] THEN
10666         DISCH_THEN(fun th -> FIRST_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN
10667         ARITH_TAC;
10668         ALL_TAC] THEN
10669       REWRITE_TAC[FORALL_IN_IMAGE] THEN
10670       DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN
10671       REWRITE_TAC[IN_ELIM_THM; IN_NUMSEG] THEN
10672       ASM_ARITH_TAC;
10673
10674       REWRITE_TAC[bounded] THEN
10675       EXISTS_TAC `drop(integral s (h:real^M->real^1))` THEN
10676       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10677       REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN
10678       X_GEN_TAC `p:num` THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
10679       ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
10680        [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
10681         ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10682         MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INF_1 THEN
10683         REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10684         ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN REPEAT STRIP_TAC THEN
10685         MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
10686         EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[];
10687         ALL_TAC] THEN
10688       X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10689       REWRITE_TAC[ABS_DROP; LIFT_DROP] THEN
10690       MATCH_MP_TAC REAL_ABS_INF_LE THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10691       REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
10692       ASM_SIMP_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD; GSYM ABS_DROP]];
10693     REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN
10694   MP_TAC(MATCH_MP MONO_FORALL (GEN `m:num`
10695    (ISPECL [`\k:num x:real^M. lift(sup {drop(f j x) | j IN m..(m+k)})`;
10696             `\x:real^M. lift(sup {drop(f j x) | m:num <= j})`;
10697             `s:real^M->bool`]
10698            MONOTONE_CONVERGENCE_INCREASING))) THEN
10699   REWRITE_TAC[LIFT_DROP] THEN ANTS_TAC THENL
10700    [X_GEN_TAC `m:num` THEN REPEAT CONJ_TAC THENL
10701      [GEN_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
10702       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10703       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_SUP_1 THEN
10704       REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10705       ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN
10706       REPEAT STRIP_TAC THEN
10707       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
10708       EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[];
10709
10710       REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10711       MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN
10712       REWRITE_TAC[IMAGE_EQ_EMPTY; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10713       CONJ_TAC THENL
10714        [MATCH_MP_TAC IMAGE_SUBSET THEN
10715         REWRITE_TAC[SUBSET_NUMSEG] THEN ARITH_TAC;
10716         ALL_TAC] THEN
10717       REWRITE_TAC[FORALL_IN_IMAGE] THEN
10718       MATCH_MP_TAC UPPER_BOUND_FINITE_SET_REAL THEN
10719       REWRITE_TAC[FINITE_NUMSEG];
10720
10721       X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10722       REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10723       REWRITE_TAC[dist; ABS_DROP; LIFT_DROP; DROP_SUB] THEN
10724       MP_TAC(SPEC `{drop((f:num->real^M->real^1) j x) | m <= j}` SUP) THEN
10725       ABBREV_TAC `i = sup {drop((f:num->real^M->real^1) j x) | m <= j}` THEN
10726       ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
10727       REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
10728       REWRITE_TAC[IN_ELIM_THM; EXTENSION; NOT_IN_EMPTY] THEN ANTS_TAC THENL
10729        [CONJ_TAC THENL [MESON_TAC[LE_REFL]; ALL_TAC] THEN
10730         EXISTS_TAC `drop(h(x:real^M))` THEN X_GEN_TAC `j:num` THEN
10731         FIRST_X_ASSUM(MP_TAC o SPECL [`j:num`; `x:real^M`]) THEN
10732         ASM_REWRITE_TAC[ABS_DROP] THEN REAL_ARITH_TAC;
10733         ALL_TAC] THEN
10734       DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `i - e:real`)) THEN
10735       ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(i <= i - e)`] THEN
10736       REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LE] THEN
10737       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN STRIP_TAC THEN
10738       X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10739       FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
10740        `i - e < y ==> ix <= i /\ y <= ix ==> abs(ix - i) < e`)) THEN
10741       CONJ_TAC THENL
10742        [EXPAND_TAC "i" THEN MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN
10743         REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
10744         REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10745         ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN CONJ_TAC THENL
10746          [MATCH_MP_TAC IMAGE_SUBSET THEN
10747           REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM] THEN ARITH_TAC;
10748           REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN ASM_MESON_TAC[]];
10749         ALL_TAC] THEN
10750       W(MP_TAC o C SPEC SUP o rand o rand o snd) THEN ANTS_TAC THENL
10751        [REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
10752         REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10753         REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10754         EXISTS_TAC `i:real` THEN GEN_TAC THEN REWRITE_TAC[IN_NUMSEG] THEN
10755         DISCH_THEN(fun th -> FIRST_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN
10756         ARITH_TAC;
10757         ALL_TAC] THEN
10758       REWRITE_TAC[FORALL_IN_IMAGE] THEN
10759       DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN
10760       REWRITE_TAC[IN_ELIM_THM; IN_NUMSEG] THEN
10761       ASM_ARITH_TAC;
10762
10763       REWRITE_TAC[bounded] THEN
10764       EXISTS_TAC `drop(integral s (h:real^M->real^1))` THEN
10765       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10766       REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN
10767       X_GEN_TAC `p:num` THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
10768       ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
10769        [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
10770         ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10771         MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_SUP_1 THEN
10772         REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10773         ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN REPEAT STRIP_TAC THEN
10774         MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
10775         EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[];
10776         ALL_TAC] THEN
10777       X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10778       REWRITE_TAC[ABS_DROP; LIFT_DROP] THEN
10779       MATCH_MP_TAC REAL_ABS_SUP_LE THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10780       REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
10781       ASM_SIMP_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD; GSYM ABS_DROP]];
10782     REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN
10783   MP_TAC(ISPECL
10784    [`\k:num x:real^M. lift(inf {drop(f j x) | k <= j})`;
10785     `g:real^M->real^1`;
10786     `s:real^M->bool`]
10787            MONOTONE_CONVERGENCE_INCREASING) THEN
10788   ASM_REWRITE_TAC[LIFT_DROP] THEN ANTS_TAC THENL
10789    [ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN CONJ_TAC THENL
10790      [REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_INF_SUBSET THEN
10791       REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
10792       REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; NOT_LE] THEN
10793       CONJ_TAC THENL [MESON_TAC[LT_REFL]; ALL_TAC] THEN CONJ_TAC THENL
10794        [MATCH_MP_TAC IMAGE_SUBSET THEN
10795         REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM] THEN ARITH_TAC;
10796         ALL_TAC] THEN
10797       REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10798       EXISTS_TAC `--drop(h(x:real^M))` THEN REPEAT STRIP_TAC THEN
10799       MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> --a <= x`) THEN
10800       ASM_SIMP_TAC[GSYM ABS_DROP];
10801       ALL_TAC] THEN
10802     CONJ_TAC THENL
10803      [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10804       FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN
10805       REWRITE_TAC[LIM_SEQUENTIALLY] THEN
10806       DISCH_THEN(fun th -> X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10807                  MP_TAC(SPEC `e / &2` th)) THEN
10808       ASM_REWRITE_TAC[REAL_HALF] THEN
10809       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN
10810       REWRITE_TAC[dist; ABS_DROP; DROP_SUB; LIFT_DROP] THEN
10811       STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10812       MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
10813       ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_INF_ASCLOSE THEN
10814       REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10815       CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LE_TRANS; REAL_LT_IMP_LE]] THEN
10816       REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN
10817       MESON_TAC[LE_REFL];
10818       ALL_TAC] THEN
10819     REWRITE_TAC[bounded; FORALL_IN_IMAGE; IN_ELIM_THM; IN_UNIV] THEN
10820     EXISTS_TAC `drop(integral s (h:real^M->real^1))` THEN
10821     X_GEN_TAC `p:num` THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
10822     ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10823     REWRITE_TAC[ABS_DROP; LIFT_DROP] THEN
10824     MATCH_MP_TAC REAL_ABS_INF_LE THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
10825     REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
10826     ASM_SIMP_TAC[GSYM ABS_DROP; IN_ELIM_THM] THEN
10827     REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN
10828     MESON_TAC[LE_REFL];
10829     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "A"))] THEN
10830   MP_TAC(ISPECL
10831    [`\k:num x:real^M. lift(sup {drop(f j x) | k <= j})`;
10832     `g:real^M->real^1`;
10833     `s:real^M->bool`]
10834            MONOTONE_CONVERGENCE_DECREASING) THEN
10835   ASM_REWRITE_TAC[LIFT_DROP] THEN ANTS_TAC THENL
10836    [ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN CONJ_TAC THENL
10837      [REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN
10838       REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
10839       REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; NOT_LE] THEN
10840       CONJ_TAC THENL [MESON_TAC[LT_REFL]; ALL_TAC] THEN CONJ_TAC THENL
10841        [MATCH_MP_TAC IMAGE_SUBSET THEN
10842         REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM] THEN ARITH_TAC;
10843         ALL_TAC] THEN
10844       REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10845       EXISTS_TAC `drop(h(x:real^M))` THEN REPEAT STRIP_TAC THEN
10846       MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> x <= a`) THEN
10847       ASM_SIMP_TAC[GSYM ABS_DROP];
10848       ALL_TAC] THEN
10849     CONJ_TAC THENL
10850      [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10851       FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN
10852       REWRITE_TAC[LIM_SEQUENTIALLY] THEN
10853       DISCH_THEN(fun th -> X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10854                  MP_TAC(SPEC `e / &2` th)) THEN
10855       ASM_REWRITE_TAC[REAL_HALF] THEN
10856       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN
10857       REWRITE_TAC[dist; ABS_DROP; DROP_SUB; LIFT_DROP] THEN
10858       STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10859       MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
10860       ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_SUP_ASCLOSE THEN
10861       REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10862       CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LE_TRANS; REAL_LT_IMP_LE]] THEN
10863       REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN
10864       MESON_TAC[LE_REFL];
10865       ALL_TAC] THEN
10866     REWRITE_TAC[bounded; FORALL_IN_IMAGE; IN_ELIM_THM; IN_UNIV] THEN
10867     EXISTS_TAC `drop(integral s (h:real^M->real^1))` THEN
10868     X_GEN_TAC `p:num` THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
10869     ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10870     REWRITE_TAC[ABS_DROP; LIFT_DROP] THEN
10871     MATCH_MP_TAC REAL_ABS_SUP_LE THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
10872     REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
10873     ASM_SIMP_TAC[GSYM ABS_DROP; IN_ELIM_THM] THEN
10874     REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN
10875     MESON_TAC[LE_REFL];
10876     DISCH_THEN(LABEL_TAC "B")] THEN
10877   ASM_REWRITE_TAC[LIM_SEQUENTIALLY] THEN
10878   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10879   REMOVE_THEN "A" (MP_TAC o REWRITE_RULE[LIM_SEQUENTIALLY]) THEN
10880   DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
10881   DISCH_THEN(X_CHOOSE_THEN `N1:num` (LABEL_TAC "N1")) THEN
10882   REMOVE_THEN "B" (MP_TAC o REWRITE_RULE[LIM_SEQUENTIALLY]) THEN
10883   DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
10884   DISCH_THEN(X_CHOOSE_THEN `N2:num` (LABEL_TAC "N2")) THEN
10885   EXISTS_TAC `N1 + N2:num` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10886   REMOVE_THEN "N1" (MP_TAC o SPEC `n:num`) THEN
10887   ANTS_TAC THENL
10888    [ASM_MESON_TAC[ARITH_RULE `N1 + N2 <= n ==> N1:num <= n`]; ALL_TAC] THEN
10889   REMOVE_THEN "N2" (MP_TAC o SPEC `n:num`) THEN
10890   ANTS_TAC THENL
10891    [ASM_MESON_TAC[ARITH_RULE `N1 + N2 <= n ==> N2:num <= n`]; ALL_TAC] THEN
10892   REWRITE_TAC[dist; ABS_DROP; DROP_SUB; LIFT_DROP] THEN
10893   MATCH_MP_TAC(REAL_ARITH
10894    `i0 <= i /\ i <= i1
10895     ==> abs(i1 - g) < e ==> abs(i0 - g) < e ==> abs(i - g) < e`) THEN
10896   CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN
10897   ASM_REWRITE_TAC[LIFT_DROP] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THENL
10898    [W(MP_TAC o C SPEC INF o rand o lhand o snd) THEN
10899     REWRITE_TAC[] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
10900     REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10901     ANTS_TAC THENL
10902      [REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN
10903       CONJ_TAC THENL [MESON_TAC[LE_REFL]; ALL_TAC] THEN
10904       EXISTS_TAC `--drop(h(x:real^M))` THEN GEN_TAC THEN DISCH_TAC THEN
10905       MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> --a <= x`) THEN
10906       REWRITE_TAC[GSYM ABS_DROP] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
10907       ASM_REWRITE_TAC[];
10908       DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN REWRITE_TAC[LE_REFL]];
10909     W(MP_TAC o C SPEC SUP o rand o rand o snd) THEN
10910     REWRITE_TAC[] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
10911     REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10912     ANTS_TAC THENL
10913      [REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN
10914       CONJ_TAC THENL [MESON_TAC[LE_REFL]; ALL_TAC] THEN
10915       EXISTS_TAC `drop(h(x:real^M))` THEN GEN_TAC THEN DISCH_TAC THEN
10916       MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> x <= a`) THEN
10917       REWRITE_TAC[GSYM ABS_DROP] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
10918       ASM_REWRITE_TAC[];
10919       DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN REWRITE_TAC[LE_REFL]]]);;
10920
10921 let DOMINATED_CONVERGENCE_INTEGRABLE = prove
10922  (`!f:num->real^M->real^N g h s.
10923          (!k. f k absolutely_integrable_on s) /\
10924          h integrable_on s /\
10925          (!k x. x IN s ==> norm(g x) <= drop(h x)) /\
10926          (!x. x IN s ==> ((\k. f k x) --> g x) sequentially)
10927          ==> g integrable_on s`,
10928   let lemma = prove
10929    (`!f:num->real^N->real^1 g h s.
10930           (!k. f k absolutely_integrable_on s) /\
10931           h integrable_on s /\
10932           (!x. x IN s ==> norm(g x) <= drop(h x)) /\
10933           (!x. x IN s ==> ((\k. f k x) --> g x) sequentially)
10934           ==> g integrable_on s`,
10935     REPEAT STRIP_TAC THEN
10936     SUBGOAL_THEN `(h:real^N->real^1) absolutely_integrable_on s`
10937     ASSUME_TAC THENL
10938      [MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN
10939       ASM_REWRITE_TAC[DIMINDEX_1; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
10940       REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; IMP_IMP] THEN
10941       ASM_MESON_TAC[REAL_LE_TRANS; NORM_POS_LE];
10942       ALL_TAC] THEN
10943     MP_TAC(ISPECL
10944      [`\n:num x:real^N.
10945          lift(min (max (--(drop(h x))) (drop(f n x))) (drop(h x)))`;
10946       `g:real^N->real^1`;
10947       `h:real^N->real^1`;
10948       `s:real^N->bool`] DOMINATED_CONVERGENCE) THEN
10949     ANTS_TAC THENL [ASM_REWRITE_TAC[]; SIMP_TAC[]] THEN REPEAT CONJ_TAC THENL
10950      [X_GEN_TAC `n:num` THEN
10951       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
10952       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MIN_1 THEN
10953       ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN
10954       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MAX_1 THEN
10955       ASM_SIMP_TAC[LIFT_NEG; LIFT_DROP; ETA_AX; ABSOLUTELY_INTEGRABLE_NEG];
10956       MAP_EVERY X_GEN_TAC [`n:num`; `x:real^N`] THEN DISCH_TAC THEN
10957       REWRITE_TAC[LIFT_DROP; ABS_DROP] THEN
10958       SUBGOAL_THEN `&0 <= drop((h:real^N->real^1) x)` MP_TAC THENL
10959        [ASM_MESON_TAC[REAL_LE_TRANS; NORM_POS_LE]; REAL_ARITH_TAC];
10960       X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN
10961       UNDISCH_TAC
10962        `!x. x IN s ==> ((\n. (f:num->real^N->real^1) n x) --> g x)
10963                           sequentially` THEN
10964       DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
10965       REWRITE_TAC[tendsto] THEN MATCH_MP_TAC MONO_FORALL THEN
10966       X_GEN_TAC `e:real` THEN ASM_CASES_TAC `&0 < e` THEN
10967       ASM_REWRITE_TAC[] THEN
10968       MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
10969       X_GEN_TAC `n:num` THEN REWRITE_TAC[] THEN
10970       FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
10971       ASM_REWRITE_TAC[dist; ABS_DROP; DROP_SUB; LIFT_DROP] THEN
10972       REAL_ARITH_TAC]) in
10973   REPEAT GEN_TAC THEN
10974   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
10975   ONCE_REWRITE_TAC[ABSOLUTELY_INTEGRABLE_COMPONENTWISE;
10976                    INTEGRABLE_COMPONENTWISE] THEN
10977   DISCH_TAC THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
10978   MATCH_MP_TAC lemma THEN
10979   EXISTS_TAC `\i x. lift(((f:num->real^M->real^N) i x)$k)` THEN
10980   EXISTS_TAC `h:real^M->real^1` THEN ASM_SIMP_TAC[] THEN CONJ_TAC THENL
10981    [ASM_MESON_TAC[COMPONENT_LE_NORM; NORM_LIFT; REAL_LE_TRANS];
10982     RULE_ASSUM_TAC(ONCE_REWRITE_RULE[LIM_COMPONENTWISE_LIFT]) THEN
10983     RULE_ASSUM_TAC BETA_RULE THEN ASM_SIMP_TAC[]]);;
10984
10985 let DOMINATED_CONVERGENCE_ABSOLUTELY_INTEGRABLE = prove
10986  (`!f:num->real^M->real^N g h s.
10987          (!k. f k absolutely_integrable_on s) /\
10988          h integrable_on s /\
10989          (!k x. x IN s ==> norm(g x) <= drop(h x)) /\
10990          (!x. x IN s ==> ((\k. f k x) --> g x) sequentially)
10991          ==> g absolutely_integrable_on s`,
10992   REPEAT STRIP_TAC THEN
10993   MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
10994   EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[] THEN
10995   MATCH_MP_TAC DOMINATED_CONVERGENCE_INTEGRABLE THEN
10996   EXISTS_TAC `f:num->real^M->real^N` THEN
10997   EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[]);;
10998
10999 let DOMINATED_CONVERGENCE_AE = prove
11000  (`!f:num->real^M->real^N g h s t.
11001         (!k. (f k) integrable_on s) /\ h integrable_on s /\ negligible t /\
11002         (!k x. x IN s DIFF t ==> norm(f k x) <= drop(h x)) /\
11003         (!x. x IN s DIFF t ==> ((\k. f k x) --> g x) sequentially)
11004         ==> g integrable_on s /\
11005             ((\k. integral s (f k)) --> integral s g) sequentially`,
11006   REPEAT GEN_TAC THEN STRIP_TAC THEN
11007   MP_TAC(ISPECL [`f:num->real^M->real^N`; `g:real^M->real^N`;
11008                  `h:real^M->real^1`; `s DIFF t:real^M->bool`]
11009         DOMINATED_CONVERGENCE) THEN
11010   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
11011    [REPEAT STRIP_TAC THEN
11012     MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE_SET) THEN
11013     EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[];
11014     MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
11015      [MATCH_MP_TAC INTEGRABLE_SPIKE_SET;
11016       MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN BINOP_TAC THEN
11017       TRY ABS_TAC THEN MATCH_MP_TAC INTEGRAL_SPIKE_SET]] THEN
11018   FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
11019     NEGLIGIBLE_SUBSET)) THEN
11020   SET_TAC[]);;
11021
11022 (* ------------------------------------------------------------------------- *)
11023 (* A few more properties of negligible sets.                                 *)
11024 (* ------------------------------------------------------------------------- *)
11025
11026 let NEGLIGIBLE_ON_UNIV = prove
11027  (`!s. negligible s <=> (indicator s has_integral vec 0) (:real^N)`,
11028   GEN_TAC THEN EQ_TAC THENL [SIMP_TAC[NEGLIGIBLE]; ALL_TAC] THEN
11029   DISCH_TAC THEN REWRITE_TAC[negligible] THEN
11030   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
11031   SUBGOAL_THEN `indicator s integrable_on interval[a:real^N,b]`
11032   ASSUME_TAC THENL
11033    [MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
11034     EXISTS_TAC `(:real^N)` THEN ASM_MESON_TAC[SUBSET_UNIV; integrable_on];
11035     ASM_SIMP_TAC[GSYM INTEGRAL_EQ_HAS_INTEGRAL] THEN
11036     REWRITE_TAC[GSYM DROP_EQ; GSYM REAL_LE_ANTISYM] THEN
11037     CONJ_TAC THENL
11038      [FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP INTEGRAL_UNIQUE) THEN
11039       MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE;
11040       REWRITE_TAC[DROP_VEC] THEN MATCH_MP_TAC INTEGRAL_DROP_POS] THEN
11041     ASM_REWRITE_TAC[SUBSET_UNIV; DROP_INDICATOR_POS_LE] THEN
11042     ASM_MESON_TAC[integrable_on]]);;
11043
11044 let NEGLIGIBLE_COUNTABLE_UNIONS = prove
11045  (`!s:num->real^N->bool.
11046         (!n. negligible(s n)) ==> negligible(UNIONS {s(n) | n IN (:num)})`,
11047   REPEAT STRIP_TAC THEN
11048   MP_TAC(ISPECL [`\n. indicator(UNIONS {(s:num->real^N->bool)(m) | m <= n})`;
11049              `indicator(UNIONS {(s:num->real^N->bool)(m) | m IN (:num)})`;
11050                  `(:real^N)`] MONOTONE_CONVERGENCE_INCREASING) THEN
11051   SUBGOAL_THEN
11052    `!n. negligible(UNIONS {(s:num->real^N->bool)(m) | m <= n})`
11053   ASSUME_TAC THENL
11054    [GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN
11055     ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
11056     ASM_SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG_LE; FORALL_IN_IMAGE];
11057     ALL_TAC] THEN
11058   SUBGOAL_THEN
11059    `!n:num. (indicator (UNIONS {s m | m <= n})) integrable_on (:real^N)`
11060   ASSUME_TAC THENL
11061    [ASM_MESON_TAC[NEGLIGIBLE_ON_UNIV; integrable_on]; ALL_TAC] THEN
11062   SUBGOAL_THEN
11063    `!n:num. integral (:real^N) (indicator (UNIONS {s m | m <= n})) = vec 0`
11064   ASSUME_TAC THENL
11065    [ASM_MESON_TAC[NEGLIGIBLE_ON_UNIV; INTEGRAL_UNIQUE]; ALL_TAC] THEN
11066   ASM_SIMP_TAC[NEGLIGIBLE_ON_UNIV; LIM_CONST_EQ;
11067                TRIVIAL_LIMIT_SEQUENTIALLY] THEN
11068   ANTS_TAC THENL [ALL_TAC; MESON_TAC[INTEGRAL_EQ_HAS_INTEGRAL]] THEN
11069   REPEAT CONJ_TAC THENL
11070    [MAP_EVERY X_GEN_TAC [`k:num`; `x:real^N`] THEN DISCH_TAC THEN
11071     REWRITE_TAC[indicator] THEN
11072     SUBGOAL_THEN
11073      `x IN UNIONS {(s:num->real^N->bool) m | m <= k}
11074       ==> x IN UNIONS {s m | m <= SUC k}`
11075     MP_TAC THENL
11076      [SPEC_TAC(`x:real^N`,`x:real^N`) THEN
11077       REWRITE_TAC[GSYM SUBSET] THEN MATCH_MP_TAC SUBSET_UNIONS THEN
11078       ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN MATCH_MP_TAC IMAGE_SUBSET THEN
11079       REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ARITH_TAC;
11080       REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN
11081       REWRITE_TAC[DROP_VEC; REAL_LE_REFL; REAL_POS]];
11082     X_GEN_TAC `x:real^N` THEN DISCH_THEN(K ALL_TAC) THEN
11083     MATCH_MP_TAC LIM_EVENTUALLY THEN
11084     REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; indicator] THEN
11085     ASM_CASES_TAC `x IN UNIONS {(s:num->real^N->bool) m | m IN (:num)}` THENL
11086      [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [UNIONS_GSPEC]) THEN
11087       REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN MATCH_MP_TAC MONO_EXISTS THEN
11088       X_GEN_TAC `m:num` THEN DISCH_TAC THEN
11089       X_GEN_TAC `n:num` THEN DISCH_TAC THEN
11090       REWRITE_TAC[UNIONS_GSPEC; IN_ELIM_THM] THEN ASM_MESON_TAC[];
11091       EXISTS_TAC `0` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
11092       ASM_REWRITE_TAC[] THEN
11093       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (RAND_CONV o RAND_CONV)
11094         [UNIONS_GSPEC]) THEN
11095       REWRITE_TAC[UNIONS_GSPEC; IN_ELIM_THM; IN_UNIV] THEN MESON_TAC[]];
11096     REWRITE_TAC[SET_RULE `{c | x | x IN UNIV} = {c}`;
11097                 BOUNDED_INSERT; BOUNDED_EMPTY]]);;
11098
11099 let HAS_INTEGRAL_NEGLIGIBLE_EQ = prove
11100  (`!f:real^M->real^N s.
11101         (!x i. x IN s /\ 1 <= i /\ i <= dimindex(:N) ==> &0 <= f(x)$i)
11102         ==> ((f has_integral vec 0) s <=>
11103              negligible {x | x IN s /\ ~(f x = vec 0)})`,
11104   let lemma = prove
11105    (`!f:real^N->real^1 s.
11106           (!x. x IN s ==> &0 <= drop(f x)) /\ (f has_integral vec 0) s
11107           ==> negligible {x | x IN s /\ ~(f x = vec 0)}`,
11108     REPEAT STRIP_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC
11109      `UNIONS {{x | x IN s /\ norm((f:real^N->real^1) x) >= &1 / (&n + &1)} |
11110               n IN (:num)}` THEN
11111     CONJ_TAC THENL
11112      [MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS THEN
11113       X_GEN_TAC `n:num` THEN REWRITE_TAC[NEGLIGIBLE_ON_UNIV; indicator] THEN
11114       MATCH_MP_TAC HAS_INTEGRAL_STRADDLE_NULL THEN
11115       EXISTS_TAC `(\x. if x IN s then (&n + &1) % f(x) else vec 0):
11116                   real^N->real^1` THEN
11117       CONJ_TAC THENL
11118        [REWRITE_TAC[IN_UNIV; IN_ELIM_THM; real_ge] THEN
11119         X_GEN_TAC `x:real^N` THEN COND_CASES_TAC THEN
11120         ASM_SIMP_TAC[DROP_VEC; DROP_CMUL; REAL_POS] THENL
11121          [ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
11122           ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
11123           MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ a <= abs x ==> a <= x`) THEN
11124           ASM_SIMP_TAC[GSYM ABS_DROP];
11125           COND_CASES_TAC THEN REWRITE_TAC[DROP_VEC; REAL_POS; DROP_CMUL] THEN
11126           ASM_SIMP_TAC[REAL_POS; REAL_LE_MUL; REAL_LE_ADD]];
11127         REWRITE_TAC[HAS_INTEGRAL_RESTRICT_UNIV] THEN
11128         SUBST1_TAC(VECTOR_ARITH `vec 0:real^1 = (&n + &1) % vec 0`) THEN
11129         MATCH_MP_TAC HAS_INTEGRAL_CMUL THEN ASM_REWRITE_TAC[]];
11130       REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN
11131       REWRITE_TAC[GSYM NORM_POS_LT] THEN ONCE_REWRITE_TAC[REAL_ARCH_INV] THEN
11132       DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `n:num`
11133         STRIP_ASSUME_TAC)) THEN
11134       REWRITE_TAC[IN_UNIONS; EXISTS_IN_GSPEC] THEN
11135       EXISTS_TAC `n - 1` THEN ASM_SIMP_TAC[IN_UNIV; IN_ELIM_THM; real_ge] THEN
11136       ASM_SIMP_TAC[REAL_OF_NUM_ADD; SUB_ADD; LE_1] THEN
11137       ASM_SIMP_TAC[real_div; REAL_MUL_LID; REAL_LT_IMP_LE]]) in
11138   REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
11139    [ALL_TAC;
11140     MATCH_MP_TAC HAS_INTEGRAL_NEGLIGIBLE THEN
11141     EXISTS_TAC `{x | x IN s /\ ~((f:real^M->real^N) x = vec 0)}` THEN
11142     ASM_REWRITE_TAC[IN_DIFF; IN_ELIM_THM] THEN MESON_TAC[]] THEN
11143   MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN
11144   EXISTS_TAC `UNIONS {{x | x IN s /\ ~(((f:real^M->real^N) x)$k = &0)} |
11145                       k IN 1..dimindex(:N)}` THEN
11146   CONJ_TAC THENL
11147    [MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN
11148     SIMP_TAC[SIMPLE_IMAGE; FINITE_IMAGE; FINITE_NUMSEG; FORALL_IN_IMAGE] THEN
11149     X_GEN_TAC `k:num` THEN REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN
11150     REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN MATCH_MP_TAC lemma THEN
11151     ASM_SIMP_TAC[LIFT_DROP] THEN
11152     FIRST_X_ASSUM(MP_TAC o ISPEC `\y:real^N. lift(y$k)` o
11153       MATCH_MP(REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_LINEAR)) THEN
11154     REWRITE_TAC[o_DEF; VEC_COMPONENT; LIFT_NUM] THEN
11155     DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[linear] THEN
11156     SIMP_TAC[LIFT_ADD; VECTOR_ADD_COMPONENT; LIFT_CMUL; VECTOR_MUL_COMPONENT];
11157     REWRITE_TAC[SUBSET; IN_UNIONS; EXISTS_IN_GSPEC; CART_EQ; IN_NUMSEG] THEN
11158     REWRITE_TAC[VEC_COMPONENT; IN_ELIM_THM] THEN MESON_TAC[]]);;
11159
11160 let NEGLIGIBLE_COUNTABLE = prove
11161  (`!s:real^N->bool. COUNTABLE s ==> negligible s`,
11162   let lemma = prove
11163    (`IMAGE f s = UNIONS {{f x} | x IN s}`,
11164     REWRITE_TAC[EXTENSION; IN_IMAGE; IN_UNIONS; IN_SING; IN_ELIM_THM] THEN
11165     MESON_TAC[IN_SING]) in
11166   GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN
11167   ASM_REWRITE_TAC[NEGLIGIBLE_EMPTY] THEN
11168   POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN
11169   DISCH_THEN(X_CHOOSE_THEN `f:num->real^N` SUBST1_TAC o
11170     MATCH_MP COUNTABLE_AS_IMAGE) THEN
11171   ONCE_REWRITE_TAC[lemma] THEN MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS THEN
11172   REWRITE_TAC[NEGLIGIBLE_SING]);;
11173
11174 (* ------------------------------------------------------------------------- *)
11175 (* More basic "almost everywhere" variants of other theorems.                *)
11176 (* ------------------------------------------------------------------------- *)
11177
11178 let HAS_INTEGRAL_COMPONENT_LE_AE = prove
11179  (`!f:real^M->real^N g:real^M->real^N s i j k t.
11180         1 <= k /\ k <= dimindex(:N) /\ negligible t /\
11181         (f has_integral i) s /\ (g has_integral j) s /\
11182         (!x. x IN s DIFF t ==> (f x)$k <= (g x)$k)
11183         ==> i$k <= j$k`,
11184   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LE THEN
11185   EXISTS_TAC `\x. if x IN t then vec 0 else (f:real^M->real^N) x` THEN
11186   EXISTS_TAC `\x. if x IN t then vec 0 else (g:real^M->real^N) x` THEN
11187   EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN
11188   REPEAT STRIP_TAC THENL
11189    [MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN EXISTS_TAC `f:real^M->real^N` THEN
11190     EXISTS_TAC `t:real^M->bool` THEN ASM_SIMP_TAC[IN_DIFF];
11191     MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN EXISTS_TAC `g:real^M->real^N` THEN
11192     EXISTS_TAC `t:real^M->bool` THEN ASM_SIMP_TAC[IN_DIFF];
11193     COND_CASES_TAC THEN ASM_SIMP_TAC[IN_DIFF; REAL_LE_REFL]]);;
11194
11195 let INTEGRAL_COMPONENT_LE_AE = prove
11196  (`!f:real^M->real^N g:real^M->real^N s k t.
11197         1 <= k /\ k <= dimindex(:N) /\ negligible t /\
11198         f integrable_on s /\ g integrable_on s /\
11199         (!x. x IN s DIFF t ==> (f x)$k <= (g x)$k)
11200         ==> (integral s f)$k <= (integral s g)$k`,
11201   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LE_AE THEN
11202   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
11203
11204 let HAS_INTEGRAL_DROP_LE_AE = prove
11205  (`!f:real^M->real^1 g:real^M->real^1 s i j t.
11206         (f has_integral i) s /\ (g has_integral j) s /\
11207         negligible t /\ (!x. x IN s DIFF t ==> drop(f x) <= drop(g x))
11208         ==> drop i <= drop j`,
11209   REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN
11210   MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LE_AE THEN
11211   REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN ASM_MESON_TAC[]);;
11212
11213 let INTEGRAL_DROP_LE_AE = prove
11214  (`!f:real^M->real^1 g:real^M->real^1 s t.
11215         f integrable_on s /\ g integrable_on s /\
11216         negligible t /\ (!x. x IN s DIFF t ==> drop(f x) <= drop(g x))
11217         ==> drop(integral s f) <= drop(integral s g)`,
11218   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_DROP_LE_AE THEN
11219   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
11220
11221 let NONNEGATIVE_ABSOLUTELY_INTEGRABLE_AE = prove
11222  (`!f:real^M->real^N s t.
11223         negligible t /\
11224         (!x i. x IN s DIFF t /\ 1 <= i /\ i <= dimindex(:N)
11225                ==> &0 <= f(x)$i) /\
11226         f integrable_on s
11227         ==> f absolutely_integrable_on s`,
11228   REPEAT STRIP_TAC THEN
11229   MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] ABSOLUTELY_INTEGRABLE_SPIKE) THEN
11230   EXISTS_TAC `\x. if x IN s DIFF t then (f:real^M->real^N) x else vec 0` THEN
11231   EXISTS_TAC `t:real^M->bool` THEN ASM_SIMP_TAC[] THEN
11232   MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN
11233   REWRITE_TAC[] THEN CONJ_TAC THENL
11234    [ASM_MESON_TAC[REAL_LE_REFL; VEC_COMPONENT]; ALL_TAC] THEN
11235   MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE) THEN
11236   MAP_EVERY EXISTS_TAC [`f:real^M->real^N`; `t:real^M->bool`] THEN
11237   ASM_SIMP_TAC[]);;
11238
11239 let INTEGRAL_NORM_BOUND_INTEGRAL_AE = prove
11240  (`!f:real^M->real^N g s t.
11241         f integrable_on s /\ g integrable_on s /\
11242         negligible t /\ (!x. x IN s DIFF t ==> norm(f x) <= drop(g x))
11243         ==> norm(integral s f) <= drop(integral s g)`,
11244   REPEAT STRIP_TAC THEN
11245   MP_TAC(ISPECL
11246    [`\x. if x IN s DIFF t then (f:real^M->real^N) x else vec 0`;
11247     `\x. if x IN s DIFF t then (g:real^M->real^1) x else vec 0`;
11248     `s:real^M->bool`]
11249     INTEGRAL_NORM_BOUND_INTEGRAL) THEN
11250   REWRITE_TAC[] THEN ANTS_TAC THENL
11251    [REPEAT CONJ_TAC THENL
11252      [MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE) THEN
11253       EXISTS_TAC `f:real^M->real^N`;
11254       MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE) THEN
11255       EXISTS_TAC `g:real^M->real^1`;
11256       ASM_MESON_TAC[REAL_LE_REFL; NORM_0; DROP_VEC]] THEN
11257     EXISTS_TAC `t:real^M->bool` THEN ASM_SIMP_TAC[];
11258     MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THEN AP_TERM_TAC THEN
11259     MATCH_MP_TAC INTEGRAL_SPIKE THEN EXISTS_TAC `t:real^M->bool` THEN
11260     ASM_SIMP_TAC[]]);;
11261
11262 (* ------------------------------------------------------------------------- *)
11263 (* Beppo Levi theorem.                                                       *)
11264 (* ------------------------------------------------------------------------- *)
11265
11266 let BEPPO_LEVI_INCREASING = prove
11267  (`!f:num->real^N->real^1 s.
11268         (!k. (f k) integrable_on s) /\
11269         (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\
11270         bounded {integral s (f k) | k IN (:num)}
11271         ==> ?g k. negligible k /\
11272                   !x. x IN (s DIFF k) ==> ((\k. f k x) --> g x) sequentially`,
11273   SUBGOAL_THEN
11274    `!f:num->real^N->real^1 s.
11275         (!k x. x IN s ==> &0 <= drop(f k x)) /\
11276         (!k. (f k) integrable_on s) /\
11277         (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\
11278         bounded {integral s (f k) | k IN (:num)}
11279         ==> ?g k. negligible k /\
11280                   !x. x IN (s DIFF k) ==> ((\k. f k x) --> g x) sequentially`
11281   ASSUME_TAC THENL
11282    [ALL_TAC;
11283     REPEAT GEN_TAC THEN STRIP_TAC THEN
11284     FIRST_X_ASSUM(MP_TAC o ISPECL
11285      [`\n x:real^N. f(n:num) x - f 0 x:real^1`; `s:real^N->bool`]) THEN
11286     REWRITE_TAC[] THEN ANTS_TAC THEN REPEAT CONJ_TAC THENL
11287      [REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_SUB; REAL_SUB_LE] THEN
11288       MP_TAC(ISPEC
11289         `\m n:num. drop (f m (x:real^N)) <= drop (f n x)`
11290         TRANSITIVE_STEPWISE_LE) THEN
11291       REWRITE_TAC[REAL_LE_TRANS; REAL_LE_REFL] THEN ASM_MESON_TAC[LE_0];
11292       GEN_TAC THEN MATCH_MP_TAC INTEGRABLE_SUB THEN ASM_REWRITE_TAC[ETA_AX];
11293       REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_SUB; REAL_SUB_LE] THEN
11294       ASM_SIMP_TAC[REAL_ARITH `x - a <= y - a <=> x <= y`];
11295       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
11296       ASM_SIMP_TAC[INTEGRAL_SUB; ETA_AX; bounded] THEN
11297       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
11298       REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN
11299       DISCH_THEN(X_CHOOSE_THEN `B:real`
11300         (fun th -> EXISTS_TAC `B + norm(integral s (f 0:real^N->real^1))` THEN
11301                    X_GEN_TAC `k:num` THEN MP_TAC(SPEC `k:num` th))) THEN
11302       NORM_ARITH_TAC;
11303       ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
11304       GEN_TAC THEN
11305       DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^1` STRIP_ASSUME_TAC) THEN
11306       EXISTS_TAC `(\x. g x + f 0 x):real^N->real^1` THEN
11307       ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^N` THEN
11308       DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
11309       ASM_REWRITE_TAC[LIM_SEQUENTIALLY; dist] THEN
11310       REWRITE_TAC[VECTOR_ARITH `a - b - c:real^1 = a - (c + b)`]]] THEN
11311   REPEAT STRIP_TAC THEN
11312   ABBREV_TAC
11313    `g = \i n:num x:real^N. lift(min (drop(f n x) / (&i + &1)) (&1))` THEN
11314   SUBGOAL_THEN
11315    `!i n. ((g:num->num->real^N->real^1) i n) integrable_on s`
11316   ASSUME_TAC THENL
11317    [REPEAT GEN_TAC THEN EXPAND_TAC "g" THEN
11318     MATCH_MP_TAC INTEGRABLE_MIN_CONST_1 THEN
11319     ASM_SIMP_TAC[REAL_POS; REAL_LE_DIV; REAL_LE_ADD] THEN
11320     REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div] THEN
11321     ASM_SIMP_TAC[LIFT_CMUL; LIFT_DROP; INTEGRABLE_CMUL; ETA_AX];
11322     ALL_TAC] THEN
11323   SUBGOAL_THEN
11324    `!i:num k:num x:real^N. x IN s ==> drop(g i k x) <= drop(g i (SUC k) x)`
11325   ASSUME_TAC THENL
11326    [REPEAT STRIP_TAC THEN EXPAND_TAC "g" THEN REWRITE_TAC[LIFT_DROP] THEN
11327     MATCH_MP_TAC(REAL_ARITH `x <= y ==> min x a <= min y a`) THEN
11328     ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_ARITH `&0 < &n + &1`];
11329     ALL_TAC] THEN
11330   SUBGOAL_THEN `!i:num k:num x:real^N. x IN s ==> norm(g i k x:real^1) <= &1`
11331   ASSUME_TAC THENL
11332    [REPEAT STRIP_TAC THEN EXPAND_TAC "g" THEN
11333     REWRITE_TAC[LIFT_DROP; NORM_REAL; GSYM drop] THEN
11334     MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> abs(min x (&1)) <= &1`) THEN
11335     ASM_SIMP_TAC[REAL_POS; REAL_LE_DIV; REAL_LE_ADD];
11336     ALL_TAC] THEN
11337   SUBGOAL_THEN
11338    `!i:num x:real^N. x IN s ==> ?h:real^1. ((\n. g i n x) --> h) sequentially`
11339   MP_TAC THENL
11340    [REPEAT STRIP_TAC THEN
11341     MP_TAC(ISPECL
11342      [`\n. drop(g (i:num) (n:num) (x:real^N))`; `&1`]
11343      CONVERGENT_BOUNDED_MONOTONE) THEN
11344     REWRITE_TAC[] THEN ANTS_TAC THENL
11345      [ASM_SIMP_TAC[GSYM ABS_DROP] THEN DISJ1_TAC THEN
11346       MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
11347       ASM_SIMP_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN REAL_ARITH_TAC;
11348       DISCH_THEN(X_CHOOSE_THEN `l:real` (fun th ->
11349         EXISTS_TAC `lift l` THEN MP_TAC th)) THEN
11350       REWRITE_TAC[LIM_SEQUENTIALLY; DIST_REAL; GSYM drop; LIFT_DROP]];
11351     GEN_REWRITE_TAC (LAND_CONV o REDEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
11352     REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM]] THEN
11353   X_GEN_TAC `h:num->real^N->real^1` THEN STRIP_TAC THEN
11354   MP_TAC(GEN `i:num `(ISPECL
11355    [`g(i:num):num->real^N->real^1`; `h(i:num):real^N->real^1`;
11356     `s:real^N->bool`] MONOTONE_CONVERGENCE_INCREASING)) THEN
11357   DISCH_THEN(MP_TAC o MATCH_MP MONO_FORALL) THEN
11358   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
11359    [GEN_TAC THEN REWRITE_TAC[bounded] THEN
11360     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
11361     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `K:real` THEN
11362     REWRITE_TAC[FORALL_IN_GSPEC] THEN REWRITE_TAC[IN_UNIV] THEN
11363     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:num` THEN
11364     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN
11365     MATCH_MP_TAC(REAL_ARITH
11366      `norm a = drop a /\ x <= drop a ==> x <= norm a`) THEN
11367     CONJ_TAC THENL
11368      [REWRITE_TAC[NORM_REAL; GSYM drop; REAL_ABS_REFL] THEN
11369       MATCH_MP_TAC INTEGRAL_DROP_POS THEN ASM_SIMP_TAC[];
11370       MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
11371       ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
11372       EXPAND_TAC "g" THEN REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP] THEN
11373       MATCH_MP_TAC(REAL_ARITH
11374        `&0 <= x /\ x <= y ==> abs(min x (&1)) <= y`) THEN
11375       ASM_SIMP_TAC[REAL_LE_ADD; REAL_POS; REAL_LE_DIV] THEN
11376       SIMP_TAC[REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &i + &1`] THEN
11377       REWRITE_TAC[REAL_ARITH `a <= a * (x + &1) <=> &0 <= a * x`] THEN
11378       ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS]];
11379     REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN
11380   ABBREV_TAC
11381    `Z =
11382     {x:real^N | x IN s /\ ~(?l:real^1. ((\k. f k x) --> l) sequentially)}` THEN
11383   ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN EXISTS_TAC `Z:real^N->bool` THEN
11384   REWRITE_TAC[RIGHT_EXISTS_AND_THM; GSYM SKOLEM_THM; RIGHT_EXISTS_IMP_THM] THEN
11385   CONJ_TAC THENL
11386    [ALL_TAC; EXPAND_TAC "Z" THEN REWRITE_TAC[IN_ELIM_THM] THEN SET_TAC[]] THEN
11387   MP_TAC(ISPECL
11388    [`h:num->real^N->real^1`;
11389     `(\x. if x IN Z then vec 1 else vec 0):real^N->real^1`;
11390     `s:real^N->bool`]
11391         MONOTONE_CONVERGENCE_DECREASING) THEN
11392   ASM_REWRITE_TAC[] THEN
11393   SUBGOAL_THEN
11394    `!i x:real^N. x IN s ==> drop(h (SUC i) x) <= drop(h i x)`
11395   ASSUME_TAC THENL
11396    [MAP_EVERY X_GEN_TAC [`i:num`; `x:real^N`] THEN DISCH_TAC THEN
11397     MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LE) THEN
11398     EXISTS_TAC `\n. (g:num->num->real^N->real^1) (SUC i) n x` THEN
11399     EXISTS_TAC `\n. (g:num->num->real^N->real^1) i n x` THEN
11400     ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
11401     MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `n:num` THEN
11402     EXPAND_TAC "g" THEN REWRITE_TAC[LIFT_DROP] THEN
11403     MATCH_MP_TAC(REAL_ARITH `x <= y ==> min x a <= min y a`) THEN
11404     REWRITE_TAC[real_div] THEN MATCH_MP_TAC REAL_LE_LMUL THEN
11405     ASM_SIMP_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
11406     REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN REAL_ARITH_TAC;
11407     ASM_REWRITE_TAC[]] THEN
11408   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
11409   REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV] THEN
11410   DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
11411   SUBGOAL_THEN
11412    `!i. norm(integral s ((h:num->real^N->real^1) i)) <= B / (&i + &1)`
11413   ASSUME_TAC THENL
11414    [X_GEN_TAC `i:num` THEN
11415     MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN
11416     EXISTS_TAC `\k. integral s ((g:num->num->real^N->real^1) i k)` THEN
11417     ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
11418     MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `n:num` THEN
11419     REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
11420     EXISTS_TAC
11421      `drop(integral s (\x. inv(&i + &1) % (f:num->real^N->real^1) n x))` THEN
11422     CONJ_TAC THENL
11423      [MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
11424       ASM_SIMP_TAC[INTEGRABLE_CMUL; ETA_AX] THEN
11425       X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN EXPAND_TAC "g" THEN
11426       REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP; DROP_CMUL] THEN
11427       MATCH_MP_TAC(REAL_ARITH
11428        `&0 <= x /\ x <= y ==> abs(min x (&1)) <= y`) THEN
11429       ASM_SIMP_TAC[REAL_LE_ADD; REAL_POS; REAL_LE_DIV] THEN
11430       REAL_ARITH_TAC;
11431       ASM_SIMP_TAC[INTEGRAL_CMUL; ETA_AX; DROP_CMUL] THEN
11432       ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
11433       ASM_SIMP_TAC[GSYM real_div; REAL_LE_DIV2_EQ;
11434                    REAL_ARITH `&0 < &n + &1`] THEN
11435       MATCH_MP_TAC(REAL_ARITH `abs x <= a ==> x <= a`) THEN
11436       ASM_REWRITE_TAC[GSYM ABS_DROP]];
11437     ALL_TAC] THEN
11438   ANTS_TAC THENL
11439    [REWRITE_TAC[bounded; FORALL_IN_GSPEC] THEN CONJ_TAC THENL
11440      [ALL_TAC;
11441       EXISTS_TAC `B:real` THEN X_GEN_TAC `i:num` THEN
11442       MATCH_MP_TAC REAL_LE_TRANS THEN
11443       EXISTS_TAC `B / (&i + &1)` THEN ASM_REWRITE_TAC[] THEN
11444       ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &i + &1`] THEN
11445       REWRITE_TAC[REAL_ARITH `B <= B * (i + &1) <=> &0 <= i * B`] THEN
11446       ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS; REAL_LT_IMP_LE]] THEN
11447     X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
11448     ASM_CASES_TAC `(x:real^N) IN Z` THEN ASM_REWRITE_TAC[] THENL
11449      [MATCH_MP_TAC LIM_EVENTUALLY THEN
11450       UNDISCH_TAC `(x:real^N) IN Z` THEN EXPAND_TAC "Z" THEN
11451       REWRITE_TAC[IN_ELIM_THM] THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
11452       MP_TAC(GEN `B:real` (ISPECL
11453         [`\n. drop(f (n:num) (x:real^N))`; `B:real`]
11454         CONVERGENT_BOUNDED_MONOTONE)) THEN
11455       REWRITE_TAC[LEFT_FORALL_IMP_THM; LEFT_EXISTS_AND_THM] THEN
11456       MATCH_MP_TAC(TAUT
11457        `q /\ ~r /\ (q ==> ~p ==> s)
11458         ==> (p /\ (q \/ q') ==> r) ==> s`) THEN
11459       CONJ_TAC THENL
11460        [MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
11461         ASM_SIMP_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN REAL_ARITH_TAC;
11462         ALL_TAC] THEN
11463       CONJ_TAC THENL
11464        [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN
11465         ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[] THEN
11466         DISCH_THEN(X_CHOOSE_THEN `l:real` STRIP_ASSUME_TAC) THEN
11467         DISCH_THEN(MP_TAC o SPEC `lift l`) THEN
11468         REWRITE_TAC[LIM_SEQUENTIALLY] THEN
11469         X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11470         FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
11471         REWRITE_TAC[DIST_REAL; GSYM drop; DROP_SUB; LIFT_DROP];
11472         ALL_TAC] THEN
11473       DISCH_TAC THEN REWRITE_TAC[NOT_FORALL_THM; EVENTUALLY_SEQUENTIALLY] THEN
11474       REWRITE_TAC[NOT_EXISTS_THM; NOT_FORALL_THM; REAL_NOT_LE] THEN
11475       DISCH_TAC THEN
11476       EXISTS_TAC `0` THEN  X_GEN_TAC `i:num` THEN DISCH_TAC THEN
11477       MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
11478       EXISTS_TAC `(\n. (g:num->num->real^N->real^1) i n x)` THEN
11479       ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
11480       MATCH_MP_TAC LIM_EVENTUALLY THEN
11481       EXPAND_TAC "g" THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
11482       FIRST_X_ASSUM(MP_TAC o SPEC `&i + &1`) THEN
11483       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
11484       DISCH_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
11485       REWRITE_TAC[GSYM DROP_EQ; DROP_VEC; LIFT_DROP] THEN
11486       REWRITE_TAC[REAL_ARITH `min a b = b <=> b <= a`] THEN
11487       SIMP_TAC[REAL_LE_RDIV_EQ; REAL_ARITH `&0 < &i + &1`; REAL_MUL_LID] THEN
11488       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
11489        `a < abs N ==> &0 <= N /\ N <= n ==> a <= n`)) THEN
11490       ASM_SIMP_TAC[];
11491       UNDISCH_TAC `~((x:real^N) IN Z)` THEN EXPAND_TAC "Z" THEN
11492       REWRITE_TAC[IN_ELIM_THM] THEN ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
11493       X_GEN_TAC `l:real^1` THEN
11494       DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN
11495       REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; IN_UNIV] THEN
11496       DISCH_THEN(X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC) THEN
11497       REWRITE_TAC[LIM_SEQUENTIALLY; DIST_0] THEN
11498       X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11499       MP_TAC(ISPEC `e / C:real` REAL_ARCH_INV) THEN
11500       ASM_SIMP_TAC[REAL_LT_DIV] THEN MATCH_MP_TAC MONO_EXISTS THEN
11501       X_GEN_TAC `N:num` THEN ASM_SIMP_TAC[REAL_LT_RDIV_EQ] THEN STRIP_TAC THEN
11502       X_GEN_TAC `i:num` THEN DISCH_TAC THEN
11503       MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N) * C` THEN
11504       ASM_REWRITE_TAC[] THEN
11505       MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `C / (&i + &1)` THEN
11506       CONJ_TAC THENL
11507        [ALL_TAC;
11508         REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div] THEN
11509         ASM_SIMP_TAC[REAL_LE_RMUL_EQ] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
11510         ASM_REWRITE_TAC[REAL_OF_NUM_LT; REAL_OF_NUM_LE; REAL_OF_NUM_ADD] THEN
11511         ASM_ARITH_TAC] THEN
11512       MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN
11513       EXISTS_TAC `\n. (g:num->num->real^N->real^1) i n x` THEN
11514       ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
11515       MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `n:num` THEN
11516       EXPAND_TAC "g" THEN REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP] THEN
11517       MATCH_MP_TAC(REAL_ARITH
11518        `&0 <= x /\ x <= a ==> abs(min x (&1)) <= a`) THEN
11519       ASM_SIMP_TAC[REAL_LE_DIV; REAL_LE_ADD; REAL_POS] THEN
11520       ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_ARITH `&0 < &i + &1`] THEN
11521       MATCH_MP_TAC(REAL_ARITH `abs x <= a ==> x <= a`) THEN
11522       ASM_REWRITE_TAC[GSYM NORM_LIFT; LIFT_DROP]];
11523     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
11524     MATCH_MP_TAC(MESON[LIM_UNIQUE; TRIVIAL_LIMIT_SEQUENTIALLY]
11525      `(f --> vec 0) sequentially /\ (i = vec 0 ==> p)
11526       ==> (f --> i) sequentially ==> p`) THEN
11527     CONJ_TAC THENL
11528      [MATCH_MP_TAC LIM_NULL_COMPARISON THEN
11529       EXISTS_TAC `\i. B / (&i + &1)` THEN
11530       ASM_SIMP_TAC[ALWAYS_EVENTUALLY] THEN
11531       REWRITE_TAC[real_div; LIFT_CMUL] THEN
11532       SUBST1_TAC(VECTOR_ARITH `vec 0:real^1 = B % vec 0`) THEN
11533       MATCH_MP_TAC LIM_CMUL THEN
11534       REWRITE_TAC[LIM_SEQUENTIALLY; DIST_0] THEN
11535       X_GEN_TAC `e:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_ARCH_INV] THEN
11536       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
11537       X_GEN_TAC `n:num` THEN DISCH_TAC THEN
11538       REWRITE_TAC[NORM_LIFT; GSYM drop; LIFT_DROP; REAL_ABS_INV] THEN
11539       MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN
11540       ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
11541       REWRITE_TAC[REAL_ARITH `abs(&n + &1) = &n + &1`] THEN
11542       REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
11543       ASM_ARITH_TAC;
11544       ASM_SIMP_TAC[INTEGRAL_EQ_HAS_INTEGRAL] THEN
11545       W(MP_TAC o PART_MATCH (lhs o rand) HAS_INTEGRAL_NEGLIGIBLE_EQ o
11546         lhand o snd) THEN
11547       ANTS_TAC THENL
11548        [REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
11549         REWRITE_TAC[IMP_IMP; DIMINDEX_1; FORALL_1; GSYM drop] THEN
11550         REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
11551         REWRITE_TAC[DROP_VEC; REAL_POS];
11552         DISCH_THEN SUBST1_TAC THEN
11553         MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] NEGLIGIBLE_SUBSET) THEN
11554         SIMP_TAC[SUBSET; IN_ELIM_THM; VEC_EQ; ARITH_EQ] THEN
11555         EXPAND_TAC "Z" THEN SIMP_TAC[IN_ELIM_THM]]]]);;
11556
11557 let BEPPO_LEVI_DECREASING = prove
11558  (`!f:num->real^N->real^1 s.
11559         (!k. (f k) integrable_on s) /\
11560         (!k x. x IN s ==> drop(f (SUC k) x) <= drop(f k x)) /\
11561         bounded {integral s (f k) | k IN (:num)}
11562         ==> ?g k. negligible k /\
11563                   !x. x IN (s DIFF k) ==> ((\k. f k x) --> g x) sequentially`,
11564   REPEAT STRIP_TAC THEN
11565   MP_TAC(ISPECL [`\n x. --((f:num->real^N->real^1) n x)`; `s:real^N->bool`]
11566         BEPPO_LEVI_INCREASING) THEN
11567   ASM_SIMP_TAC[INTEGRABLE_NEG; DROP_NEG; ETA_AX; REAL_LE_NEG2] THEN
11568   ANTS_TAC THENL
11569    [REWRITE_TAC[bounded] THEN
11570     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
11571     REWRITE_TAC[FORALL_IN_GSPEC] THEN
11572     ASM_SIMP_TAC[INTEGRAL_NEG; ETA_AX; NORM_NEG];
11573     ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
11574     X_GEN_TAC `k:real^N->bool` THEN
11575     DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^1` STRIP_ASSUME_TAC) THEN
11576     EXISTS_TAC `\x. --((g:real^N->real^1) x)` THEN
11577     ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
11578     GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV o ABS_CONV)
11579       [GSYM VECTOR_NEG_NEG] THEN
11580     ASM_SIMP_TAC[LIM_NEG_EQ]]);;
11581
11582 let BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING = prove
11583  (`!f:num->real^N->real^1 s.
11584         (!k. (f k) integrable_on s) /\
11585         (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\
11586         bounded {integral s (f k) | k IN (:num)}
11587         ==> ?g k. negligible k /\
11588                   (!x. x IN (s DIFF k)
11589                        ==> ((\k. f k x) --> g x) sequentially) /\
11590                   g integrable_on s /\
11591                   ((\k. integral s (f k)) --> integral s g) sequentially`,
11592   REPEAT GEN_TAC THEN DISCH_TAC THEN
11593   FIRST_ASSUM(MP_TAC o MATCH_MP BEPPO_LEVI_INCREASING) THEN
11594   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^1` THEN
11595   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^N->bool` THEN
11596   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
11597   SUBGOAL_THEN
11598    `(g:real^N->real^1) integrable_on (s DIFF k) /\
11599     ((\i. integral (s DIFF k) (f i)) --> integral (s DIFF k) g) sequentially`
11600   MP_TAC THENL
11601    [MATCH_MP_TAC MONOTONE_CONVERGENCE_INCREASING THEN
11602     ASM_REWRITE_TAC[] THEN
11603     FIRST_X_ASSUM(MP_TAC o check (is_conj o concl));
11604     ALL_TAC] THEN
11605   (SUBGOAL_THEN
11606     `!f:real^N->real^1. integral (s DIFF k) f = integral s f /\
11607                         (f integrable_on (s DIFF k) <=> f integrable_on s)`
11608     (fun th -> SIMP_TAC[th; IN_DIFF]) THEN
11609    GEN_TAC THEN CONJ_TAC THEN TRY EQ_TAC THEN
11610    (MATCH_MP_TAC INTEGRABLE_SPIKE_SET ORELSE
11611     MATCH_MP_TAC INTEGRAL_SPIKE_SET) THEN
11612    FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
11613         NEGLIGIBLE_SUBSET)) THEN
11614      SET_TAC[]));;
11615
11616 let BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING = prove
11617  (`!f:num->real^N->real^1 s.
11618         (!k. (f k) integrable_on s) /\
11619         (!k x. x IN s ==> drop(f (SUC k) x) <= drop(f k x)) /\
11620         bounded {integral s (f k) | k IN (:num)}
11621         ==> ?g k. negligible k /\
11622                   (!x. x IN (s DIFF k)
11623                        ==> ((\k. f k x) --> g x) sequentially) /\
11624                   g integrable_on s /\
11625                   ((\k. integral s (f k)) --> integral s g) sequentially`,
11626   REPEAT GEN_TAC THEN DISCH_TAC THEN
11627   FIRST_ASSUM(MP_TAC o MATCH_MP BEPPO_LEVI_DECREASING) THEN
11628   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^1` THEN
11629   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^N->bool` THEN
11630   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
11631   SUBGOAL_THEN
11632    `(g:real^N->real^1) integrable_on (s DIFF k) /\
11633     ((\i. integral (s DIFF k) (f i)) --> integral (s DIFF k) g) sequentially`
11634   MP_TAC THENL
11635    [MATCH_MP_TAC MONOTONE_CONVERGENCE_DECREASING THEN
11636     ASM_REWRITE_TAC[] THEN
11637     FIRST_X_ASSUM(MP_TAC o check (is_conj o concl));
11638     ALL_TAC] THEN
11639   (SUBGOAL_THEN
11640     `!f:real^N->real^1. integral (s DIFF k) f = integral s f /\
11641                         (f integrable_on (s DIFF k) <=> f integrable_on s)`
11642     (fun th -> SIMP_TAC[th; IN_DIFF]) THEN
11643    GEN_TAC THEN CONJ_TAC THEN TRY EQ_TAC THEN
11644    (MATCH_MP_TAC INTEGRABLE_SPIKE_SET ORELSE
11645     MATCH_MP_TAC INTEGRAL_SPIKE_SET) THEN
11646    FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
11647         NEGLIGIBLE_SUBSET)) THEN
11648      SET_TAC[]));;
11649
11650 let BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING_AE = prove
11651  (`!f:num->real^N->real^1 s.
11652         (!k. (f k) integrable_on s) /\
11653         (!k. ?t. negligible t /\
11654                  !x. x IN s DIFF t ==> drop(f k x) <= drop(f (SUC k) x)) /\
11655         bounded {integral s (f k) | k IN (:num)}
11656         ==> ?g k. negligible k /\
11657                   (!x. x IN (s DIFF k)
11658                        ==> ((\k. f k x) --> g x) sequentially) /\
11659                   g integrable_on s /\
11660                   ((\k. integral s (f k)) --> integral s g) sequentially`,
11661   REPEAT GEN_TAC THEN REWRITE_TAC[SKOLEM_THM] THEN
11662   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
11663   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
11664   REWRITE_TAC[FORALL_AND_THM] THEN
11665   DISCH_THEN(X_CHOOSE_THEN `t:num->real^N->bool` STRIP_ASSUME_TAC) THEN
11666   MP_TAC(ISPECL
11667    [`\n x. if x IN UNIONS {t k | k IN (:num)} then vec 0
11668            else (f:num->real^N->real^1) n x`; `s:real^N->bool`]
11669         BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING) THEN
11670   SUBGOAL_THEN
11671    `negligible(UNIONS {t k | k IN (:num)}:real^N->bool)`
11672   ASSUME_TAC THENL [ASM_SIMP_TAC[NEGLIGIBLE_COUNTABLE_UNIONS]; ALL_TAC] THEN
11673   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
11674    [REPEAT CONJ_TAC THENL
11675      [X_GEN_TAC `k:num` THEN
11676       MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE) THEN
11677       EXISTS_TAC `(f:num->real^N->real^1) k` THEN
11678       EXISTS_TAC `UNIONS {t k | k IN (:num)}:real^N->bool` THEN
11679       ASM_SIMP_TAC[IN_DIFF];
11680       REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
11681       ASM_REWRITE_TAC[REAL_LE_REFL] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
11682       ASM SET_TAC[];
11683       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
11684         BOUNDED_SUBSET)) THEN
11685       MATCH_MP_TAC(SET_RULE
11686        `(!x. x IN s ==> f x = g x)
11687         ==> {f x | x IN s} SUBSET {g x | x IN s}`) THEN
11688       REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_SPIKE THEN
11689       EXISTS_TAC `UNIONS {t k | k IN (:num)}:real^N->bool` THEN
11690       ASM_SIMP_TAC[IN_DIFF]];
11691     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^1` THEN
11692     DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
11693     EXISTS_TAC `u UNION UNIONS {t k | k IN (:num)}:real^N->bool` THEN
11694     ASM_REWRITE_TAC[NEGLIGIBLE_UNION_EQ] THEN CONJ_TAC THENL
11695      [X_GEN_TAC `x:real^N` THEN
11696       REWRITE_TAC[IN_DIFF; IN_UNION; DE_MORGAN_THM] THEN STRIP_TAC THEN
11697       FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
11698       ASM_REWRITE_TAC[IN_DIFF];
11699       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[]
11700          `(f --> l) sequentially ==> f = g ==> (g --> l) sequentially`)) THEN
11701       REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN
11702       MATCH_MP_TAC INTEGRAL_SPIKE THEN
11703       EXISTS_TAC `UNIONS {t k | k IN (:num)}:real^N->bool` THEN
11704       ASM_SIMP_TAC[IN_DIFF]]]);;
11705
11706 let BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING_AE = prove
11707  (`!f:num->real^N->real^1 s.
11708         (!k. (f k) integrable_on s) /\
11709         (!k. ?t. negligible t /\
11710                  !x. x IN s DIFF t ==> drop(f (SUC k) x) <= drop(f k x)) /\
11711         bounded {integral s (f k) | k IN (:num)}
11712         ==> ?g k. negligible k /\
11713                   (!x. x IN (s DIFF k)
11714                        ==> ((\k. f k x) --> g x) sequentially) /\
11715                   g integrable_on s /\
11716                   ((\k. integral s (f k)) --> integral s g) sequentially`,
11717   REPEAT GEN_TAC THEN REWRITE_TAC[SKOLEM_THM] THEN
11718   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
11719   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
11720   REWRITE_TAC[FORALL_AND_THM] THEN
11721   DISCH_THEN(X_CHOOSE_THEN `t:num->real^N->bool` STRIP_ASSUME_TAC) THEN
11722   MP_TAC(ISPECL
11723    [`\n x. if x IN UNIONS {t k | k IN (:num)} then vec 0
11724            else (f:num->real^N->real^1) n x`; `s:real^N->bool`]
11725         BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING) THEN
11726   SUBGOAL_THEN
11727    `negligible(UNIONS {t k | k IN (:num)}:real^N->bool)`
11728   ASSUME_TAC THENL [ASM_SIMP_TAC[NEGLIGIBLE_COUNTABLE_UNIONS]; ALL_TAC] THEN
11729   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
11730    [REPEAT CONJ_TAC THENL
11731      [X_GEN_TAC `k:num` THEN
11732       MATCH_MP_TAC(REWRITE_RULE[IMP_IMP] INTEGRABLE_SPIKE) THEN
11733       EXISTS_TAC `(f:num->real^N->real^1) k` THEN
11734       EXISTS_TAC `UNIONS {t k | k IN (:num)}:real^N->bool` THEN
11735       ASM_SIMP_TAC[IN_DIFF];
11736       REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
11737       ASM_REWRITE_TAC[REAL_LE_REFL] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
11738       ASM SET_TAC[];
11739       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
11740         BOUNDED_SUBSET)) THEN
11741       MATCH_MP_TAC(SET_RULE
11742        `(!x. x IN s ==> f x = g x)
11743         ==> {f x | x IN s} SUBSET {g x | x IN s}`) THEN
11744       REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_SPIKE THEN
11745       EXISTS_TAC `UNIONS {t k | k IN (:num)}:real^N->bool` THEN
11746       ASM_SIMP_TAC[IN_DIFF]];
11747     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^1` THEN
11748     DISCH_THEN(X_CHOOSE_THEN `u:real^N->bool` STRIP_ASSUME_TAC) THEN
11749     EXISTS_TAC `u UNION UNIONS {t k | k IN (:num)}:real^N->bool` THEN
11750     ASM_REWRITE_TAC[NEGLIGIBLE_UNION_EQ] THEN CONJ_TAC THENL
11751      [X_GEN_TAC `x:real^N` THEN
11752       REWRITE_TAC[IN_DIFF; IN_UNION; DE_MORGAN_THM] THEN STRIP_TAC THEN
11753       FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
11754       ASM_REWRITE_TAC[IN_DIFF];
11755       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[]
11756          `(f --> l) sequentially ==> f = g ==> (g --> l) sequentially`)) THEN
11757       REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN
11758       MATCH_MP_TAC INTEGRAL_SPIKE THEN
11759       EXISTS_TAC `UNIONS {t k | k IN (:num)}:real^N->bool` THEN
11760       ASM_SIMP_TAC[IN_DIFF]]]);;
11761
11762 (* ------------------------------------------------------------------------- *)
11763 (* Fatou's lemma and Lieb's extension.                                       *)
11764 (* ------------------------------------------------------------------------- *)
11765
11766 let FATOU = prove
11767  (`!f:num->real^N->real^1 g s t B.
11768         negligible t /\
11769         (!n. (f n) integrable_on s) /\
11770         (!n x. x IN s DIFF t ==> &0 <= drop(f n x)) /\
11771         (!x. x IN s DIFF t ==> ((\n. f n x) --> g x) sequentially) /\
11772         (!n. drop(integral s (f n)) <= B)
11773         ==> g integrable_on s /\
11774             &0 <= drop(integral s g) /\ drop(integral s g) <= B`,
11775   REPEAT GEN_TAC THEN STRIP_TAC THEN
11776   ABBREV_TAC
11777    `h = \n x. lift(inf {drop((f:num->real^N->real^1) j x) | n <= j})` THEN
11778   MP_TAC(MATCH_MP MONO_FORALL (GEN `m:num`
11779    (ISPECL [`\k:num x:real^N. lift(inf {drop(f j x) | j IN m..(m+k)})`;
11780             `(h:num->real^N->real^1) m`;
11781             `s:real^N->bool`; `t:real^N->bool`]
11782            MONOTONE_CONVERGENCE_DECREASING_AE))) THEN
11783   ASM_REWRITE_TAC[LIFT_DROP] THEN ANTS_TAC THENL
11784    [X_GEN_TAC `m:num` THEN EXPAND_TAC "h" THEN REWRITE_TAC[] THEN
11785     REPEAT CONJ_TAC THENL
11786      [GEN_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
11787       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
11788       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INF_1 THEN
11789       REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
11790       ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN
11791       REPEAT STRIP_TAC THEN
11792       MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE_AE THEN
11793       EXISTS_TAC `t:real^N->bool` THEN
11794       ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
11795       ASM_REWRITE_TAC[IMP_IMP; DIMINDEX_1; FORALL_1; GSYM drop];
11796       REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
11797       MATCH_MP_TAC REAL_LE_INF_SUBSET THEN
11798       REWRITE_TAC[IMAGE_EQ_EMPTY; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
11799       CONJ_TAC THENL
11800        [MATCH_MP_TAC IMAGE_SUBSET THEN
11801         REWRITE_TAC[SUBSET_NUMSEG] THEN ARITH_TAC;
11802         ALL_TAC] THEN
11803       REWRITE_TAC[FORALL_IN_IMAGE] THEN
11804       MATCH_MP_TAC LOWER_BOUND_FINITE_SET_REAL THEN
11805       REWRITE_TAC[FINITE_NUMSEG];
11806       X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
11807       REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11808       REWRITE_TAC[dist; ABS_DROP; LIFT_DROP; DROP_SUB] THEN
11809       MP_TAC(SPEC `{drop((f:num->real^N->real^1) j x) | m <= j}` INF) THEN
11810       ABBREV_TAC `i = inf {drop((f:num->real^N->real^1) j x) | m <= j}` THEN
11811       ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
11812       REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
11813       REWRITE_TAC[IN_ELIM_THM; EXTENSION; NOT_IN_EMPTY] THEN
11814       ANTS_TAC THENL [ASM_MESON_TAC[LE_REFL]; ALL_TAC] THEN
11815       DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `i + e:real`)) THEN
11816       ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(i + e <= i)`] THEN
11817       REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LE] THEN
11818       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
11819       X_GEN_TAC `n:num` THEN DISCH_TAC THEN
11820       FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
11821        `y < i + e ==> i <= ix /\ ix <= y ==> abs(ix - i) < e`)) THEN
11822       CONJ_TAC THENL
11823        [EXPAND_TAC "i" THEN MATCH_MP_TAC REAL_LE_INF_SUBSET THEN
11824         REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
11825         REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
11826         ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN CONJ_TAC THENL
11827          [MATCH_MP_TAC IMAGE_SUBSET THEN
11828           REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM] THEN ARITH_TAC;
11829           REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN ASM_MESON_TAC[]];
11830         ALL_TAC] THEN
11831       W(MP_TAC o C SPEC INF o rand o lhand o snd) THEN ANTS_TAC THENL
11832        [REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
11833         REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
11834         REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN
11835         EXISTS_TAC `i:real` THEN GEN_TAC THEN REWRITE_TAC[IN_NUMSEG] THEN
11836         DISCH_THEN(fun th -> FIRST_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN
11837         ARITH_TAC;
11838         ALL_TAC] THEN
11839       REWRITE_TAC[FORALL_IN_IMAGE] THEN
11840       DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN
11841       REWRITE_TAC[IN_ELIM_THM; IN_NUMSEG] THEN
11842       ASM_ARITH_TAC;
11843       REWRITE_TAC[bounded] THEN EXISTS_TAC `B:real` THEN
11844       REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV; NORM_REAL; GSYM drop] THEN
11845       X_GEN_TAC `n:num` THEN
11846       MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= b ==> abs(x) <= b`) THEN
11847       CONJ_TAC THENL
11848        [MATCH_MP_TAC INTEGRAL_DROP_POS_AE THEN
11849         EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[LIFT_DROP] THEN
11850         CONJ_TAC THENL
11851          [ALL_TAC;
11852           REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_INF THEN
11853           ASM_SIMP_TAC[SIMPLE_IMAGE; FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
11854           REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD]];
11855         TRANS_TAC REAL_LE_TRANS
11856           `drop (integral s ((f:num->real^N->real^1) m))` THEN
11857         ASM_REWRITE_TAC[] THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN
11858         ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
11859          [ALL_TAC;
11860           SIMP_TAC[REAL_INF_LE_FINITE; LIFT_DROP; SIMPLE_IMAGE;
11861                    FINITE_IMAGE; IMAGE_EQ_EMPTY; FINITE_NUMSEG; IN_NUMSEG;
11862                    NUMSEG_EMPTY; NOT_LT; LE_ADD; EXISTS_IN_IMAGE] THEN
11863           MESON_TAC[REAL_LE_REFL; LE_REFL; LE_ADD]]] THEN
11864       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
11865       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
11866       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INF_1 THEN
11867       REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
11868       ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN
11869       REPEAT STRIP_TAC THEN
11870       MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE_AE THEN
11871       EXISTS_TAC `t:real^N->bool` THEN
11872       ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
11873       ASM_REWRITE_TAC[IMP_IMP; DIMINDEX_1; FORALL_1; GSYM drop]];
11874     REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN
11875   MP_TAC(ISPECL [`h:num->real^N->real^1`; `g:real^N->real^1`;
11876                  `s:real^N->bool`; `t:real^N->bool`]
11877     MONOTONE_CONVERGENCE_INCREASING_AE) THEN
11878   ASM_REWRITE_TAC[] THEN
11879   SUBGOAL_THEN
11880    `!n. &0 <= drop(integral s ((h:num->real^N->real^1) n)) /\
11881         drop(integral s ((h:num->real^N->real^1) n)) <= B`
11882   MP_TAC THENL
11883    [X_GEN_TAC `m:num` THEN CONJ_TAC THENL
11884      [MATCH_MP_TAC INTEGRAL_DROP_POS_AE THEN
11885       EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[LIFT_DROP] THEN
11886       EXPAND_TAC "h" THEN REWRITE_TAC[LIFT_DROP] THEN
11887       REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_INF THEN
11888       ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
11889       ASM_SIMP_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
11890       REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN
11891       MESON_TAC[LE_REFL];
11892       TRANS_TAC REAL_LE_TRANS
11893         `drop (integral s ((f:num->real^N->real^1) m))` THEN
11894       ASM_REWRITE_TAC[] THEN MATCH_MP_TAC INTEGRAL_DROP_LE_AE THEN
11895       EXISTS_TAC `t:real^N->bool` THEN ASM_REWRITE_TAC[] THEN
11896       REPEAT STRIP_TAC THEN EXPAND_TAC "h" THEN REWRITE_TAC[LIFT_DROP] THEN
11897       GEN_REWRITE_TAC RAND_CONV [GSYM INF_SING] THEN
11898       MATCH_MP_TAC  REAL_LE_INF_SUBSET THEN
11899       REWRITE_TAC[NOT_INSERT_EMPTY; SING_SUBSET; FORALL_IN_GSPEC] THEN
11900       CONJ_TAC THENL [REWRITE_TAC[IN_ELIM_THM]; ASM_MESON_TAC[]] THEN
11901       MESON_TAC[LE_REFL; REAL_LE_REFL]];
11902     REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN
11903   ANTS_TAC THENL
11904    [REPEAT CONJ_TAC THENL
11905      [REPEAT STRIP_TAC THEN EXPAND_TAC "h" THEN REWRITE_TAC[LIFT_DROP] THEN
11906       MATCH_MP_TAC REAL_LE_INF_SUBSET THEN
11907       ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
11908       REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY; FORALL_IN_GSPEC] THEN
11909       REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; NOT_LE] THEN
11910       REPEAT CONJ_TAC THENL
11911        [MESON_TAC[LT_REFL];
11912         MATCH_MP_TAC IMAGE_SUBSET THEN
11913         REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ARITH_TAC;
11914         ASM_MESON_TAC[]];
11915       X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
11916       FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
11917       ASM_REWRITE_TAC[LIM_SEQUENTIALLY] THEN DISCH_TAC THEN
11918       X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11919       FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN
11920       ASM_REWRITE_TAC[REAL_HALF] THEN MATCH_MP_TAC MONO_EXISTS THEN
11921       X_GEN_TAC `N:num` THEN REWRITE_TAC[DIST_REAL; GSYM drop] THEN
11922       REPEAT STRIP_TAC THEN
11923       MATCH_MP_TAC(REAL_ARITH
11924        `&0 < e /\ g - e / &2 <= h /\ h <= g + e / &2 ==> abs(h - g) < e`) THEN
11925       ASM_REWRITE_TAC[] THEN EXPAND_TAC "h" THEN REWRITE_TAC[LIFT_DROP] THEN
11926       MATCH_MP_TAC REAL_INF_BOUNDS THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN
11927       REWRITE_TAC[SET_RULE `{f n | P n} = {} <=> !n. ~P n`] THEN
11928       CONJ_TAC THENL [MESON_TAC[LE_REFL]; GEN_TAC THEN DISCH_TAC] THEN
11929       MATCH_MP_TAC(REAL_ARITH
11930        `abs(h - g) < e / &2 ==> g - e / &2 <= h /\ h <= g + e / &2`) THEN
11931       FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[LE_TRANS];
11932       REWRITE_TAC[bounded; FORALL_IN_GSPEC] THEN EXISTS_TAC `B:real` THEN
11933       REPEAT STRIP_TAC THEN REWRITE_TAC[NORM_REAL; GSYM drop] THEN
11934       MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= b ==> abs x <= b`) THEN
11935       ASM_REWRITE_TAC[]];
11936     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
11937      [MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LBOUND);
11938       MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_UBOUND)] THEN
11939     EXISTS_TAC `\n. integral s ((h:num->real^N->real^1) n)` THEN
11940     ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_TRUE]]);;
11941
11942 let LIEB = prove
11943  (`!f:num->real^M->real^N g s t.
11944      (!n. f n absolutely_integrable_on s) /\ g absolutely_integrable_on s /\
11945      negligible t /\ (!x. x IN s DIFF t ==> ((\n. f n x) --> g x) sequentially)
11946      ==> ((\n. integral s (\x. lift(norm(f n x - g x))) -
11947                (integral s (\x. lift(norm(f n x))) -
11948                 integral s (\x. lift(norm(g x)))))
11949           --> vec 0) sequentially`,
11950   (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 4)
11951    [GSYM INTEGRAL_SUB; ABSOLUTELY_INTEGRABLE_SUB; ETA_AX;
11952     ABSOLUTELY_INTEGRABLE_NORM; ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE] THEN
11953   REPEAT STRIP_TAC THEN
11954   MP_TAC(ISPECL
11955    [`\n x. lift(norm((f:num->real^M->real^N) n x - g x) -
11956                 (norm(f n x) - norm(g x)))`;
11957     `(\x. vec 0):real^M->real^1`;
11958     `\x. &2 % lift(norm((g:real^M->real^N) x))`;
11959     `s:real^M->bool`; `t:real^M->bool`]
11960    DOMINATED_CONVERGENCE_AE) THEN
11961   REWRITE_TAC[LIFT_SUB; DROP_CMUL; INTEGRAL_0; INTEGRABLE_0] THEN
11962   DISCH_THEN MATCH_MP_TAC THEN
11963   ASM (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 4)
11964    [GSYM INTEGRAL_SUB; ABSOLUTELY_INTEGRABLE_SUB; ETA_AX; INTEGRABLE_CMUL;
11965     ABSOLUTELY_INTEGRABLE_NORM; ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE] THEN
11966   CONJ_TAC THENL
11967    [REWRITE_TAC[GSYM LIFT_SUB; NORM_LIFT; LIFT_DROP] THEN CONV_TAC NORM_ARITH;
11968     REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_NULL_SUB THEN
11969     ASM_SIMP_TAC[GSYM LIM_NULL_NORM; GSYM LIM_NULL; LIM_NORM]]);;
11970
11971 (* ------------------------------------------------------------------------- *)
11972 (* Fundamental theorem of calculus, starting with strong forms.              *)
11973 (* ------------------------------------------------------------------------- *)
11974
11975 let FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG = prove
11976  (`!f:real^1->real^N f' s a b.
11977         COUNTABLE s /\
11978         drop a <= drop b /\ f continuous_on interval[a,b] /\
11979         (!x. x IN interval[a,b] DIFF s
11980              ==> (f has_vector_derivative f'(x)) (at x within interval[a,b]))
11981         ==> (f' has_integral (f(b) - f(a))) (interval[a,b])`,
11982   REPEAT STRIP_TAC THEN
11983   MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN
11984   EXISTS_TAC `(\x. if x IN s then vec 0 else f' x):real^1->real^N` THEN
11985   EXISTS_TAC `s:real^1->bool` THEN
11986   ASM_SIMP_TAC[NEGLIGIBLE_COUNTABLE; IN_DIFF] THEN
11987   SUBGOAL_THEN
11988    `?f t. s = IMAGE (f:num->real^1) t /\
11989           (!m n. m IN t /\ n IN t /\ f m = f n ==> m = n)`
11990   MP_TAC THENL
11991    [ASM_CASES_TAC `FINITE(s:real^1->bool)` THENL
11992      [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN
11993       ASM_MESON_TAC[];
11994       MP_TAC(ISPEC `s:real^1->bool` COUNTABLE_AS_INJECTIVE_IMAGE) THEN
11995       ASM_REWRITE_TAC[INFINITE] THEN MESON_TAC[IN_UNIV]];
11996     REWRITE_TAC[LEFT_IMP_EXISTS_THM; INJECTIVE_ON_LEFT_INVERSE] THEN
11997     MAP_EVERY X_GEN_TAC [`r:num->real^1`; `t:num->bool`] THEN
11998     DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC) THEN
11999     DISCH_THEN(X_CHOOSE_TAC `n:real^1->num`)] THEN
12000   REWRITE_TAC[HAS_INTEGRAL_FACTOR_CONTENT] THEN
12001   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
12002   SUBGOAL_THEN
12003    `!x. ?d. &0 < d /\
12004             (x IN interval[a,b]
12005              ==> (x IN IMAGE (r:num->real^1) t
12006                   ==> !y. norm(y - x) < d /\ y IN interval[a,b]
12007                           ==> norm(f y - f x)
12008                               <= e / &2 pow (4 + n x) * norm(b - a)) /\
12009                  (~(x IN IMAGE r t)
12010                   ==> !y. norm(y - x) < d /\ y IN interval[a,b]
12011                           ==> norm(f y - f x - drop(y - x) % f' x:real^N)
12012                                 <= e / &2 * norm(y - x)))`
12013   MP_TAC THENL
12014    [X_GEN_TAC `x:real^1` THEN
12015     ASM_CASES_TAC `(x:real^1) IN interval[a,b]` THENL
12016      [ALL_TAC; EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[REAL_LT_01]] THEN
12017     ASM_CASES_TAC `x IN IMAGE (r:num->real^1) t` THEN ASM_REWRITE_TAC[] THENL
12018      [FIRST_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH
12019        `a <= b ==> a = b \/ a < b`)) THEN
12020       REWRITE_TAC[DROP_EQ] THEN STRIP_TAC THENL
12021        [EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
12022         UNDISCH_TAC `(x:real^1) IN interval[a,b]` THEN
12023         ASM_SIMP_TAC[INTERVAL_SING; IN_SING; VECTOR_SUB_REFL; NORM_0] THEN
12024         REAL_ARITH_TAC;
12025         FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [continuous_on]) THEN
12026         DISCH_THEN(MP_TAC o SPEC `x:real^1`) THEN ASM_REWRITE_TAC[dist] THEN
12027         DISCH_THEN(MP_TAC o SPEC
12028          `e / &2 pow (4 + n(x:real^1)) * norm(b - a:real^1)`) THEN
12029         ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; NORM_POS_LT; VECTOR_SUB_EQ;
12030                      REAL_LT_POW2; GSYM DROP_EQ; REAL_LT_IMP_NE] THEN
12031         MESON_TAC[REAL_LT_IMP_LE]];
12032       FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN
12033       ASM_REWRITE_TAC[IN_DIFF; has_vector_derivative;
12034                       HAS_DERIVATIVE_WITHIN_ALT] THEN
12035       DISCH_THEN(MP_TAC o SPEC `e / &2` o CONJUNCT2) THEN
12036       ASM_REWRITE_TAC[REAL_HALF] THEN MESON_TAC[]];
12037     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
12038     REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM; IMP_IMP;
12039                 TAUT `p ==> q /\ r <=> (p ==> q) /\ (p ==> r)`] THEN
12040     X_GEN_TAC `d:real^1->real` THEN
12041     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
12042     DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "E") (LABEL_TAC "U"))] THEN
12043   EXISTS_TAC `\x. ball(x:real^1,d(x))` THEN
12044   ASM_SIMP_TAC[GAUGE_BALL_DEPENDENT] THEN
12045   X_GEN_TAC `p:(real^1#(real^1->bool))->bool` THEN STRIP_TAC THEN
12046   MP_TAC(ISPECL [`f:real^1->real^N`; `p:(real^1#(real^1->bool))->bool`;
12047                  `a:real^1`; `b:real^1`]
12048                 ADDITIVE_TAGGED_DIVISION_1) THEN
12049   ASM_SIMP_TAC[CONTENT_1] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
12050   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
12051   ASM_SIMP_TAC[GSYM VSUM_SUB; LAMBDA_PAIR_THM] THEN
12052   SUBGOAL_THEN
12053    `p:(real^1#(real^1->bool))->bool =
12054     {(x,k) | (x,k) IN p /\ x IN IMAGE r (t:num->bool)} UNION
12055     {(x,k) | (x,k) IN p /\ ~(x IN IMAGE r (t:num->bool))}`
12056   SUBST1_TAC THENL
12057    [REWRITE_TAC[EXTENSION; FORALL_PAIR_THM; IN_ELIM_PAIR_THM; IN_UNION] THEN
12058     MESON_TAC[];
12059     ALL_TAC] THEN
12060   W(MP_TAC o PART_MATCH (lhs o rand) VSUM_UNION o rand o lhand o snd) THEN
12061   ANTS_TAC THENL
12062    [REWRITE_TAC[SET_RULE `DISJOINT s t <=> !x. x IN s ==> ~(x IN t)`] THEN
12063     SIMP_TAC[FORALL_IN_GSPEC; IN_ELIM_PAIR_THM] THEN CONJ_TAC THEN
12064     MATCH_MP_TAC FINITE_SUBSET THEN
12065     EXISTS_TAC `p:(real^1#(real^1->bool))->bool` THEN
12066     ASM_SIMP_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_PAIR_THM];
12067     DISCH_THEN SUBST1_TAC] THEN
12068   SUBGOAL_THEN
12069    `(!P. FINITE {(x:real^1,k:real^1->bool) | (x,k) IN p /\ P x k}) /\
12070     (!P x. FINITE {(x:real^1,k:real^1->bool) |k| (x,k) IN p /\ P x k})`
12071   STRIP_ASSUME_TAC THENL
12072    [REPEAT STRIP_TAC THEN MATCH_MP_TAC FINITE_SUBSET THEN
12073     EXISTS_TAC `p:real^1#(real^1->bool)->bool` THEN
12074     ASM_SIMP_TAC[SUBSET; FORALL_IN_GSPEC];
12075     ALL_TAC] THEN
12076   MATCH_MP_TAC(NORM_ARITH
12077    `norm(x:real^N) <= e / &2 * a /\ norm(y) <= e / &2 * a
12078     ==> norm(x + y) <= e * a`) THEN
12079   CONJ_TAC THENL
12080    [MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
12081      `norm(vsum {(x,k) | (x,k) IN p /\ x IN IMAGE (r:num->real^1) t /\
12082                          ~(content k = &0)}
12083                 (\(x,k). --(f(interval_upperbound k) -
12084                             (f:real^1->real^N)(interval_lowerbound k))))` THEN
12085     CONJ_TAC THENL
12086      [MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
12087       MATCH_MP_TAC VSUM_EQ_SUPERSET THEN
12088       ASM_REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ] THEN
12089       CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
12090       SIMP_TAC[VECTOR_ARITH `a % vec 0 - x:real^N = --x`] THEN
12091       REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
12092       MAP_EVERY X_GEN_TAC [`x:real^1`; `k:real^1->bool`] THEN DISCH_TAC THEN
12093       SUBGOAL_THEN `?u v:real^1. k = interval[u,v] /\ x IN interval[u,v]`
12094       STRIP_ASSUME_TAC THENL
12095        [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
12096       ASM_REWRITE_TAC[CONTENT_EQ_0_1] THEN
12097       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN
12098       DISCH_THEN(MP_TAC o MATCH_MP REAL_LE_TRANS) THEN
12099       SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1;
12100                INTERVAL_EQ_EMPTY; REAL_NOT_LE; REAL_NOT_LT] THEN
12101       REPEAT STRIP_TAC THEN MATCH_MP_TAC(VECTOR_ARITH
12102        `x:real^N = y ==> --(x - y) = vec 0`) THEN
12103       AP_TERM_TAC THEN ASM_REWRITE_TAC[GSYM DROP_EQ; GSYM REAL_LE_ANTISYM];
12104       ALL_TAC] THEN
12105     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
12106      `sum {(x,k:real^1->bool) | (x,k) IN p /\ x IN IMAGE (r:num->real^1) t /\
12107                                 ~(content k = &0)}
12108           ((\(x,k). e / &2 pow (3 + n x) * norm (b - a:real^1)))` THEN
12109     CONJ_TAC THENL
12110      [MATCH_MP_TAC VSUM_NORM_LE THEN
12111       ASM_REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ] THEN
12112       MAP_EVERY X_GEN_TAC [`x:real^1`; `k:real^1->bool`] THEN DISCH_TAC THEN
12113       SUBGOAL_THEN `?u v:real^1. k = interval[u,v] /\ x IN interval[u,v]`
12114       MP_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
12115       DISCH_THEN(REPEAT_TCL CHOOSE_THEN
12116         (CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC)) THEN
12117       SIMP_TAC[CONTENT_EQ_0_1; REAL_NOT_LE; REAL_LT_IMP_LE; IN_INTERVAL_1;
12118                INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
12119       REPEAT STRIP_TAC THEN
12120       REMOVE_THEN "E" (MP_TAC o SPEC `x:real^1`) THEN ANTS_TAC THENL
12121        [ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET]; ALL_TAC] THEN
12122       DISCH_THEN(fun th ->
12123         MP_TAC(ISPEC `u:real^1` th) THEN MP_TAC(ISPEC `v:real^1` th)) THEN
12124       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
12125       DISCH_THEN(MP_TAC o SPECL [`x:real^1`; `interval[u:real^1,v]`]) THEN
12126       ASM_REWRITE_TAC[SUBSET; IN_BALL] THEN
12127       DISCH_THEN(fun th ->
12128         MP_TAC(ISPEC `u:real^1` th) THEN MP_TAC(ISPEC `v:real^1` th)) THEN
12129       ASM_REWRITE_TAC[dist; ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY_1] THEN
12130       ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_SUB] THEN DISCH_TAC THEN DISCH_TAC THEN
12131       SUBGOAL_THEN `interval[u:real^1,v] SUBSET interval[a,b]` ASSUME_TAC THENL
12132        [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
12133       REPEAT(ANTS_TAC THENL
12134        [ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET; INTERVAL_NE_EMPTY_1;
12135                       REAL_LT_IMP_LE];
12136         ONCE_REWRITE_TAC[TAUT `p ==> q ==> r <=> q ==> p ==> r`]]) THEN
12137       REWRITE_TAC[REAL_POW_ADD; real_div; REAL_INV_MUL] THEN NORM_ARITH_TAC;
12138       ALL_TAC] THEN
12139     MP_TAC(ISPECL
12140      [`FST:real^1#(real^1->bool)->real^1`;
12141       `\(x:real^1,k:real^1->bool). e / &2 pow (3 + n x) * norm (b - a:real^1)`;
12142       `{(x,k:real^1->bool) | (x,k) IN p /\ x IN IMAGE (r:num->real^1) t /\
12143                                 ~(content k = &0)}`;
12144       `IMAGE (r:num->real^1) t`
12145      ] SUM_GROUP) THEN
12146     ANTS_TAC THENL
12147      [ASM_REWRITE_TAC[] THEN
12148       SIMP_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC];
12149       DISCH_THEN(SUBST1_TAC o SYM)] THEN
12150     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
12151      `sum (IMAGE (r:num->real^1) t)
12152           (\x. sum {(x,k:real^1->bool) |k|
12153                     (x,k) IN p /\ ~(content k = &0)}
12154                    (\yk. e / &2 pow (3 + n x) * norm(b - a:real^1)))` THEN
12155     CONJ_TAC THENL
12156      [MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC SUM_EQ THEN
12157       X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN REWRITE_TAC[] THEN
12158       MATCH_MP_TAC SUM_EQ_SUPERSET THEN
12159       ASM_REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IMP_CONJ] THEN
12160       REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN ASM_MESON_TAC[];
12161       ALL_TAC] THEN
12162     ASM_SIMP_TAC[SUM_CONST] THEN
12163     REWRITE_TAC[SUM_RMUL; NORM_1; DROP_SUB; REAL_MUL_ASSOC] THEN
12164     ASM_REWRITE_TAC[real_abs; REAL_SUB_LE] THEN MATCH_MP_TAC REAL_LE_RMUL THEN
12165     ASM_REWRITE_TAC[REAL_SUB_LE; REAL_POW_ADD; real_div; REAL_INV_MUL] THEN
12166     ONCE_REWRITE_TAC[REAL_ARITH
12167      `p * e * inv(&2 pow 3) * n = e / &8 * (p * n)`] THEN
12168     ASM_SIMP_TAC[REAL_LE_LMUL_EQ; SUM_LMUL; REAL_ARITH
12169      `e / &8 * x <= e * inv(&2) <=> e * x <= e * &4`] THEN
12170     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
12171      `sum (IMAGE (r:num->real^1) t INTER
12172            IMAGE (FST:real^1#(real^1->bool)->real^1) p)
12173           (\x. &(CARD {(x,k:real^1->bool) | k |
12174                       (x,k) IN p /\ ~(content k = &0)}) *
12175                inv(&2 pow n x))` THEN
12176     CONJ_TAC THENL
12177      [MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC SUM_SUPERSET THEN
12178       REWRITE_TAC[INTER_SUBSET; IMP_CONJ; FORALL_IN_IMAGE] THEN
12179       SIMP_TAC[IN_INTER; FUN_IN_IMAGE] THEN
12180       REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM] THEN
12181       REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_ENTIRE] THEN
12182       DISJ1_TAC THEN AP_TERM_TAC THEN
12183       MATCH_MP_TAC(MESON[CARD_CLAUSES] `s = {} ==> CARD s = 0`) THEN
12184       ASM SET_TAC[];
12185       ALL_TAC] THEN
12186     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
12187      `sum (IMAGE (r:num->real^1) t INTER
12188            IMAGE (FST:real^1#(real^1->bool)->real^1) p)
12189           (\x. &2 / &2 pow (n x))` THEN
12190     CONJ_TAC THENL
12191      [MATCH_MP_TAC SUM_LE THEN
12192       ASM_SIMP_TAC[FINITE_IMAGE; FINITE_INTER] THEN
12193       GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[real_div] THEN
12194       MATCH_MP_TAC REAL_LE_RMUL THEN
12195       SIMP_TAC[REAL_LE_INV_EQ; REAL_POW_LE; REAL_POS; REAL_OF_NUM_LE] THEN
12196       GEN_REWRITE_TAC RAND_CONV [ARITH_RULE `2 = 2 EXP 1`] THEN
12197       GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM DIMINDEX_1] THEN
12198       MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_COMMON_TAGS THEN
12199       ASM_MESON_TAC[tagged_division_of];
12200       ALL_TAC] THEN
12201     REWRITE_TAC[real_div; SUM_LMUL; REAL_ARITH `&2 * x <= &4 <=> x <= &2`;
12202                 REAL_INV_POW] THEN
12203     SUBGOAL_THEN
12204      `(\x:real^1. inv (&2) pow n x) = (\n. inv(&2) pow n) o n`
12205     SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
12206     W(MP_TAC o PART_MATCH (rand o rand) SUM_IMAGE o lhand o snd) THEN
12207     ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN(SUBST1_TAC o SYM)] THEN
12208     SUBGOAL_THEN
12209      `?m. IMAGE (n:real^1->num)
12210                 (IMAGE (r:num->real^1) t INTER
12211                 IMAGE (FST:real^1#(real^1->bool)->real^1) p) SUBSET 0..m`
12212     STRIP_ASSUME_TAC THENL
12213      [REWRITE_TAC[SUBSET; IN_NUMSEG; LE_0] THEN
12214       MATCH_MP_TAC UPPER_BOUND_FINITE_SET THEN
12215       ASM_SIMP_TAC[FINITE_IMAGE; FINITE_INTER];
12216       ALL_TAC] THEN
12217     MATCH_MP_TAC REAL_LE_TRANS THEN
12218     EXISTS_TAC `sum(0..m) (\n. inv(&2) pow n)` THEN CONJ_TAC THENL
12219      [MATCH_MP_TAC SUM_SUBSET THEN
12220       ASM_SIMP_TAC[FINITE_IMAGE; FINITE_INTER; FINITE_NUMSEG] THEN
12221       SIMP_TAC[REAL_LE_INV_EQ; REAL_POW_LE; REAL_POS] THEN ASM SET_TAC[];
12222       REWRITE_TAC[SUM_GP; LT; SUB_0] THEN
12223       CONV_TAC REAL_RAT_REDUCE_CONV THEN
12224       REWRITE_TAC[REAL_ARITH `(&1 - x) / (&1 / &2) <= &2 <=> &0 <= x`] THEN
12225       MATCH_MP_TAC REAL_POW_LE THEN CONV_TAC REAL_RAT_REDUCE_CONV];
12226     MP_TAC(ISPECL [`\x:real^1. x`; `p:(real^1#(real^1->bool))->bool`;
12227                    `a:real^1`; `b:real^1`]
12228                   ADDITIVE_TAGGED_DIVISION_1) THEN
12229     ASM_SIMP_TAC[] THEN DISCH_THEN(MP_TAC o AP_TERM `drop`) THEN
12230     ASM_SIMP_TAC[DROP_VSUM; DROP_SUB] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
12231     REWRITE_TAC[GSYM SUM_LMUL] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
12232     EXISTS_TAC
12233      `sum {(x:real^1,k:real^1->bool) |
12234            (x,k) IN p /\ ~(x IN IMAGE r (t:num->bool))}
12235           (\x. e / &2 * (drop o
12236             (\(x,k). interval_upperbound k - interval_lowerbound k)) x)` THEN
12237     CONJ_TAC THENL
12238      [MATCH_MP_TAC VSUM_NORM_LE THEN ASM_REWRITE_TAC[FORALL_IN_GSPEC] THEN
12239       SIMP_TAC[o_DEF] THEN
12240       REWRITE_TAC[NORM_ARITH `norm(a - (b - c):real^N) = norm(b - c - a)`] THEN
12241       MAP_EVERY X_GEN_TAC [`x:real^1`; `k:real^1->bool`] THEN STRIP_TAC THEN
12242       SUBGOAL_THEN `?u v:real^1. k = interval[u,v] /\ x IN interval[u,v]`
12243       MP_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
12244       DISCH_THEN(REPEAT_TCL CHOOSE_THEN
12245        (CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC)) THEN
12246       REWRITE_TAC[IN_INTERVAL_1] THEN DISCH_THEN(fun th ->
12247         ASSUME_TAC th THEN MP_TAC(MATCH_MP REAL_LE_TRANS th)) THEN
12248       SIMP_TAC[CONTENT_1; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
12249       DISCH_TAC THEN REMOVE_THEN "U" (MP_TAC o SPEC `x:real^1`) THEN
12250       ASM_REWRITE_TAC[] THEN
12251       SUBGOAL_THEN `interval[u:real^1,v] SUBSET interval[a,b]` ASSUME_TAC THENL
12252        [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
12253       ANTS_TAC THENL [ASM_MESON_TAC[SUBSET; IN_INTERVAL_1]; ALL_TAC] THEN
12254       DISCH_THEN(fun th ->
12255         MP_TAC(ISPEC `u:real^1` th) THEN MP_TAC(ISPEC `v:real^1` th)) THEN
12256       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
12257       DISCH_THEN(MP_TAC o SPECL [`x:real^1`; `interval[u:real^1,v]`]) THEN
12258       ASM_REWRITE_TAC[SUBSET; IN_BALL] THEN
12259       DISCH_THEN(fun th ->
12260         MP_TAC(ISPEC `u:real^1` th) THEN MP_TAC(ISPEC `v:real^1` th)) THEN
12261       ASM_REWRITE_TAC[dist; ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY_1] THEN
12262       ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_SUB] THEN DISCH_TAC THEN DISCH_TAC THEN
12263       REPEAT(ANTS_TAC THENL
12264        [ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET; INTERVAL_NE_EMPTY_1;
12265                       REAL_LT_IMP_LE];
12266         ONCE_REWRITE_TAC[TAUT `p ==> q ==> r <=> q ==> p ==> r`]]) THEN
12267       REWRITE_TAC[NORM_1; DROP_SUB] THEN
12268       ASM_SIMP_TAC[REAL_ARITH `a <= b ==> abs(a - b) = b - a`;
12269                    REAL_ARITH `b <= a ==> abs(a - b) = a - b`] THEN
12270       REWRITE_TAC[REAL_SUB_LDISTRIB] THEN MATCH_MP_TAC(NORM_ARITH
12271        `x - y:real^N = z ==> norm(x) <= c - b
12272                    ==> norm(y) <= b - a ==> norm(z) <= c - a`) THEN
12273       VECTOR_ARITH_TAC;
12274       MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN ASM_REWRITE_TAC[] THEN
12275       CONJ_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[FORALL_PAIR_THM]] THEN
12276       REWRITE_TAC[IN_DIFF; IN_ELIM_PAIR_THM] THEN
12277       MAP_EVERY X_GEN_TAC [`x:real^1`; `k:real^1->bool`] THEN STRIP_TAC THEN
12278       SUBGOAL_THEN `?u v:real^1. k = interval[u,v] /\ x IN interval[u,v]`
12279       MP_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
12280       DISCH_THEN(REPEAT_TCL CHOOSE_THEN
12281        (CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC)) THEN
12282       REWRITE_TAC[IN_INTERVAL_1; o_THM] THEN
12283       DISCH_THEN(MP_TAC o MATCH_MP REAL_LE_TRANS) THEN
12284       SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
12285       REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN
12286       ASM_REWRITE_TAC[DROP_SUB] THEN ASM_REAL_ARITH_TAC]]);;
12287
12288 let FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG = prove
12289  (`!f:real^1->real^N f' s a b.
12290         COUNTABLE s /\
12291         drop a <= drop b /\ f continuous_on interval[a,b] /\
12292         (!x. x IN interval(a,b) DIFF s
12293              ==> (f has_vector_derivative f'(x)) (at x))
12294         ==> (f' has_integral (f(b) - f(a))) (interval[a,b])`,
12295   REPEAT STRIP_TAC THEN
12296   MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG THEN
12297   EXISTS_TAC `(a:real^1) INSERT (b:real^1) INSERT s` THEN
12298   ASM_REWRITE_TAC[COUNTABLE_INSERT; IN_INTERVAL_1; IN_DIFF] THEN
12299   REWRITE_TAC[DE_MORGAN_THM; IN_INSERT] THEN
12300   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_AT_WITHIN THEN
12301   FIRST_X_ASSUM MATCH_MP_TAC THEN
12302   ASM_REWRITE_TAC[IN_INTERVAL_1; IN_DIFF; IN_INSERT] THEN
12303   ASM_REWRITE_TAC[REAL_LT_LE; DROP_EQ]);;
12304
12305 let FUNDAMENTAL_THEOREM_OF_CALCULUS = prove
12306  (`!f:real^1->real^N f' a b.
12307         drop a <= drop b /\
12308         (!x. x IN interval[a,b]
12309              ==> (f has_vector_derivative f'(x)) (at x within interval[a,b]))
12310         ==> (f' has_integral (f(b) - f(a))) (interval[a,b])`,
12311   REPEAT STRIP_TAC THEN
12312   MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG THEN
12313   EXISTS_TAC `{}:real^1->bool` THEN
12314   ASM_REWRITE_TAC[COUNTABLE_EMPTY; DIFF_EMPTY] THEN
12315   MATCH_MP_TAC DIFFERENTIABLE_IMP_CONTINUOUS_ON THEN
12316   REWRITE_TAC[differentiable_on] THEN
12317   ASM_MESON_TAC[has_vector_derivative; differentiable]);;
12318
12319 let FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR = prove
12320  (`!f:real^1->real^N f' a b.
12321         drop a <= drop b /\ f continuous_on interval[a,b] /\
12322         (!x. x IN interval(a,b)
12323              ==> (f has_vector_derivative f'(x)) (at x))
12324         ==> (f' has_integral (f(b) - f(a))) (interval[a,b])`,
12325   REPEAT STRIP_TAC THEN
12326   MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG THEN
12327   EXISTS_TAC `{}:real^1->bool` THEN
12328   ASM_REWRITE_TAC[COUNTABLE_EMPTY; DIFF_EMPTY]);;
12329
12330 let ANTIDERIVATIVE_INTEGRAL_CONTINUOUS = prove
12331  (`!f:real^1->real^N a b.
12332      (f continuous_on interval[a,b])
12333      ==> ?g. !u v. u IN interval[a,b] /\ v IN interval[a,b] /\ drop u <= drop v
12334                    ==> (f has_integral (g(v) - g(u))) (interval[u,v])`,
12335   REPEAT STRIP_TAC THEN
12336   FIRST_ASSUM(MP_TAC o MATCH_MP ANTIDERIVATIVE_CONTINUOUS) THEN
12337   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^1->real^N` THEN
12338   REPEAT STRIP_TAC THEN MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS THEN
12339   ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^1` THEN
12340   STRIP_TAC THEN MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_WITHIN_SUBSET THEN
12341   EXISTS_TAC `interval[a:real^1,b]` THEN CONJ_TAC THENL
12342    [FIRST_X_ASSUM MATCH_MP_TAC; ALL_TAC] THEN
12343   REPEAT(POP_ASSUM MP_TAC) THEN
12344   REWRITE_TAC[SUBSET_INTERVAL_1; IN_INTERVAL_1] THEN REAL_ARITH_TAC);;
12345
12346 (* ------------------------------------------------------------------------- *)
12347 (* This doesn't directly involve integration, but that gives an easy proof.  *)
12348 (* ------------------------------------------------------------------------- *)
12349
12350 let HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL = prove
12351  (`!f:real^1->real^N a b k y.
12352         COUNTABLE k /\ f continuous_on interval[a,b] /\ f a = y /\
12353         (!x. x IN (interval[a,b] DIFF k)
12354              ==> (f has_derivative (\h. vec 0)) (at x within interval[a,b]))
12355         ==> !x. x IN interval[a,b] ==> f x = y`,
12356   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
12357   MATCH_MP_TAC(ISPEC `(\x. vec 0):real^1->real^N` HAS_INTEGRAL_UNIQUE) THEN
12358   EXISTS_TAC `interval[a:real^1,x]` THEN
12359   REWRITE_TAC[HAS_INTEGRAL_0] THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
12360   MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG THEN
12361   EXISTS_TAC `k:real^1->bool` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
12362    [REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN
12363     REAL_ARITH_TAC;
12364     MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN
12365     EXISTS_TAC `interval[a:real^1,b]` THEN
12366     ASM_REWRITE_TAC[SUBSET_INTERVAL_1] THEN
12367     REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN
12368     REAL_ARITH_TAC;
12369     X_GEN_TAC `y:real^1` THEN DISCH_TAC THEN
12370     FIRST_X_ASSUM(MP_TAC o SPEC `y:real^1`) THEN ANTS_TAC THENL
12371      [REPEAT(POP_ASSUM MP_TAC) THEN
12372       SIMP_TAC[IN_DIFF; IN_INTERVAL_1] THEN REAL_ARITH_TAC;
12373       ALL_TAC] THEN
12374     DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
12375       HAS_DERIVATIVE_WITHIN_SUBSET)) THEN
12376     DISCH_THEN(MP_TAC o SPEC `interval(a:real^1,b)`) THEN
12377     REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED] THEN
12378     REWRITE_TAC[has_vector_derivative; VECTOR_MUL_RZERO] THEN
12379     MATCH_MP_TAC EQ_IMP THEN MATCH_MP_TAC HAS_DERIVATIVE_WITHIN_OPEN THEN
12380     REPEAT(POP_ASSUM MP_TAC) THEN
12381     SIMP_TAC[OPEN_INTERVAL; IN_INTERVAL_1; IN_DIFF] THEN REAL_ARITH_TAC]);;
12382
12383 (* ------------------------------------------------------------------------- *)
12384 (* Generalize a bit to any convex set.                                       *)
12385 (* ------------------------------------------------------------------------- *)
12386
12387 let HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX = prove
12388  (`!f:real^M->real^N s k c y.
12389       convex s /\ COUNTABLE k /\ f continuous_on s /\ c IN s /\ f c = y /\
12390       (!x. x IN (s DIFF k) ==> (f has_derivative (\h. vec 0)) (at x within s))
12391       ==> !x. x IN s ==> f x = y`,
12392   GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN
12393   MAP_EVERY X_GEN_TAC [`x:real^M`; `z:real^N`] THEN STRIP_TAC THEN
12394   FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
12395   X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN
12396   ASM_CASES_TAC `x:real^M = y` THEN ASM_REWRITE_TAC[] THEN
12397   MP_TAC(ISPECL [`(f:real^M->real^N) o (\t. (&1 - drop t) % x + drop t % y)`;
12398                  `vec 0:real^1`; `vec 1:real^1`;
12399                  `{t | ((&1 - drop t) % (x:real^M) + drop t % y) IN k}`;
12400                  `(f:real^M->real^N) x`]
12401                 HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL) THEN
12402   REWRITE_TAC[o_THM] THEN ANTS_TAC THENL
12403    [ALL_TAC;
12404     DISCH_THEN(MP_TAC o SPEC `vec 1:real^1`) THEN
12405     REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL] THEN
12406     DISCH_THEN(SUBST1_TAC o SYM) THEN AP_TERM_TAC THEN VECTOR_ARITH_TAC] THEN
12407   REPEAT CONJ_TAC THENL
12408    [MATCH_MP_TAC COUNTABLE_IMAGE_INJ THEN ASM_REWRITE_TAC[] THEN
12409     ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ; REAL_SUB_0; DROP_EQ;
12410     VECTOR_ARITH `(&1 - t) % x + t % y = (&1 - u) % x + u % y <=>
12411                   (t - u) % (x - y) = vec 0`];
12412     MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL
12413      [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN CONJ_TAC THEN
12414       MATCH_MP_TAC CONTINUOUS_ON_VMUL THEN
12415       REWRITE_TAC[o_DEF; LIFT_DROP; CONTINUOUS_ON_ID; LIFT_SUB] THEN
12416       SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID];
12417       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
12418           CONTINUOUS_ON_SUBSET)) THEN
12419       REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; GSYM FORALL_DROP] THEN
12420       REWRITE_TAC[DROP_VEC] THEN ASM_MESON_TAC[CONVEX_ALT]];
12421     AP_TERM_TAC THEN REWRITE_TAC[DROP_VEC] THEN VECTOR_ARITH_TAC;
12422     ALL_TAC] THEN
12423   X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN
12424   SUBGOAL_THEN `(\h. vec 0) = ((\h. vec 0):real^M->real^N) o
12425                                (\t. drop t % (y - x))`
12426   SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
12427   MATCH_MP_TAC DIFF_CHAIN_WITHIN THEN CONJ_TAC THENL
12428    [REWRITE_TAC[VECTOR_ARITH `t % (y - x) = ((&0 - t) % x) + t % y`] THEN
12429     MATCH_MP_TAC HAS_DERIVATIVE_ADD THEN
12430     REWRITE_TAC[GSYM DROP_NEG; GSYM DROP_VEC; GSYM DROP_SUB] THEN
12431     SIMP_TAC[HAS_DERIVATIVE_VMUL_DROP; HAS_DERIVATIVE_ID] THEN
12432     REWRITE_TAC[DROP_SUB; VECTOR_SUB_RDISTRIB] THEN
12433     MATCH_MP_TAC HAS_DERIVATIVE_SUB THEN
12434     REWRITE_TAC[VECTOR_MUL_LZERO; DROP_VEC; HAS_DERIVATIVE_CONST] THEN
12435     SIMP_TAC[HAS_DERIVATIVE_VMUL_DROP; HAS_DERIVATIVE_ID];
12436     ALL_TAC] THEN
12437   MATCH_MP_TAC HAS_DERIVATIVE_WITHIN_SUBSET THEN
12438   EXISTS_TAC `s:real^M->bool` THEN REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
12439   REWRITE_TAC[IN_INTERVAL_1; GSYM FORALL_DROP; DROP_VEC] THEN
12440   CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[CONVEX_ALT]] THEN
12441   FIRST_X_ASSUM MATCH_MP_TAC THEN
12442   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_DIFF]) THEN
12443   SIMP_TAC[IN_ELIM_THM; IN_DIFF] THEN REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
12444   REWRITE_TAC[IN_INTERVAL_1; GSYM FORALL_DROP; DROP_VEC] THEN
12445   ASM_MESON_TAC[CONVEX_ALT]);;
12446
12447 (* ------------------------------------------------------------------------- *)
12448 (* Also to any open connected set with finite set of exceptions. Could       *)
12449 (* generalize to locally convex set with limpt-free set of exceptions.       *)
12450 (* ------------------------------------------------------------------------- *)
12451
12452 let HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONNECTED = prove
12453  (`!f:real^M->real^N s k c y.
12454       connected s /\ open s /\ COUNTABLE k /\ f continuous_on s /\
12455       c IN s /\ f c = y /\
12456       (!x. x IN (s DIFF k) ==> (f has_derivative (\h. vec 0)) (at x within s))
12457       ==> !x. x IN s ==> f x = y`,
12458   REPEAT STRIP_TAC THEN
12459   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONNECTED_CLOPEN]) THEN
12460   DISCH_THEN(MP_TAC o SPEC
12461    `{x | x IN s /\ (f:real^M->real^N) x IN {y}}`) THEN
12462   ANTS_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN CONJ_TAC THEN
12463   ASM_SIMP_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE; CLOSED_SING] THEN
12464   MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN ASM_REWRITE_TAC[] THEN
12465   CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN
12466   UNDISCH_TAC `open(s:real^M->bool)` THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN
12467   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `u:real^M` THEN
12468   REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_SING] THEN
12469   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
12470   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN
12471   GEN_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC[] THEN
12472   MATCH_MP_TAC HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX THEN
12473   MAP_EVERY EXISTS_TAC [`k:real^M->bool`; `u:real^M`] THEN
12474   ASM_REWRITE_TAC[CONVEX_BALL; IN_DIFF; CENTRE_IN_BALL] THEN
12475   CONJ_TAC THENL [ASM_MESON_TAC[SUBSET; CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN
12476   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_WITHIN_SUBSET THEN
12477   EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[SUBSET] THEN
12478   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[IN_DIFF]);;
12479
12480 (* ------------------------------------------------------------------------- *)
12481 (* Integration by parts.                                                     *)
12482 (* ------------------------------------------------------------------------- *)
12483
12484 let INTEGRATION_BY_PARTS = prove
12485  (`!(bop:real^M->real^N->real^P) f g f' g' a b c y.
12486         bilinear bop /\ drop a <= drop b /\ COUNTABLE c /\
12487         (\x. bop (f x) (g x)) continuous_on interval[a,b] /\
12488         (!x. x IN interval(a,b) DIFF c
12489              ==> (f has_vector_derivative f'(x)) (at x) /\
12490                  (g has_vector_derivative g'(x)) (at x)) /\
12491         ((\x. bop (f x) (g' x)) has_integral
12492          ((bop (f b) (g b) - bop (f a) (g a)) - y))
12493             (interval[a,b])
12494         ==> ((\x. bop (f' x) (g x)) has_integral y) (interval[a,b])`,
12495   REPEAT STRIP_TAC THEN
12496   MP_TAC(ISPECL [`\x:real^1. (bop:real^M->real^N->real^P) (f x) (g x)`;
12497                  `\x:real^1. (bop:real^M->real^N->real^P) (f x) (g' x) +
12498                              (bop:real^M->real^N->real^P) (f' x) (g x)`;
12499                  `c:real^1->bool`; `a:real^1`; `b:real^1`]
12500     FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG) THEN
12501   ASM_SIMP_TAC[HAS_VECTOR_DERIVATIVE_BILINEAR_AT] THEN
12502   FIRST_ASSUM(fun th -> MP_TAC th THEN REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN
12503         DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_SUB)) THEN
12504   REWRITE_TAC[VECTOR_ARITH `b - a - (b - a - y):real^N = y`; VECTOR_ADD_SUB]);;
12505
12506 let INTEGRATION_BY_PARTS_SIMPLE = prove
12507  (`!(bop:real^M->real^N->real^P) f g f' g' a b y.
12508         bilinear bop /\ drop a <= drop b /\
12509         (!x. x IN interval[a,b]
12510              ==> (f has_vector_derivative f'(x)) (at x within interval[a,b]) /\
12511                  (g has_vector_derivative g'(x)) (at x within interval[a,b])) /\
12512         ((\x. bop (f x) (g' x)) has_integral
12513          ((bop (f b) (g b) - bop (f a) (g a)) - y))
12514             (interval[a,b])
12515         ==> ((\x. bop (f' x) (g x)) has_integral y) (interval[a,b])`,
12516   REPEAT STRIP_TAC THEN
12517   MP_TAC(ISPECL [`\x:real^1. (bop:real^M->real^N->real^P) (f x) (g x)`;
12518                  `\x:real^1. (bop:real^M->real^N->real^P) (f x) (g' x) +
12519                              (bop:real^M->real^N->real^P) (f' x) (g x)`;
12520                  `a:real^1`; `b:real^1`]
12521     FUNDAMENTAL_THEOREM_OF_CALCULUS) THEN
12522   ASM_SIMP_TAC[HAS_VECTOR_DERIVATIVE_BILINEAR_WITHIN] THEN
12523   FIRST_ASSUM(fun th -> MP_TAC th THEN REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN
12524         DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_SUB)) THEN
12525   REWRITE_TAC[VECTOR_ARITH `b - a - (b - a - y):real^N = y`; VECTOR_ADD_SUB]);;
12526
12527 let INTEGRABLE_BY_PARTS = prove
12528  (`!(bop:real^M->real^N->real^P) f g f' g' a b c.
12529         bilinear bop /\ COUNTABLE c /\
12530         (\x. bop (f x) (g x)) continuous_on interval[a,b] /\
12531         (!x. x IN interval(a,b) DIFF c
12532              ==> (f has_vector_derivative f'(x)) (at x) /\
12533                  (g has_vector_derivative g'(x)) (at x)) /\
12534         (\x. bop (f x) (g' x)) integrable_on interval[a,b]
12535         ==> (\x. bop (f' x) (g x)) integrable_on interval[a,b]`,
12536   REPEAT GEN_TAC THEN
12537   DISJ_CASES_TAC(REAL_ARITH `drop b <= drop a \/ drop a <= drop b`) THENL
12538    [DISCH_THEN(K ALL_TAC) THEN MATCH_MP_TAC INTEGRABLE_ON_NULL THEN
12539     ASM_REWRITE_TAC[CONTENT_EQ_0_1];
12540     REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
12541     REWRITE_TAC[integrable_on] THEN
12542     DISCH_THEN(X_CHOOSE_THEN `y:real^P` STRIP_ASSUME_TAC) THEN
12543     EXISTS_TAC `(bop ((f:real^1->real^M) b) ((g:real^1->real^N) b) -
12544                  bop (f a) (g a)) - (y:real^P)` THEN
12545     MATCH_MP_TAC INTEGRATION_BY_PARTS THEN MAP_EVERY EXISTS_TAC
12546      [`f:real^1->real^M`; `g':real^1->real^N`; `c:real^1->bool`] THEN
12547     ASM_REWRITE_TAC[VECTOR_ARITH `b - a - ((b - a) - y):real^N = y`]]);;
12548
12549 let INTEGRABLE_BY_PARTS_EQ = prove
12550  (`!(bop:real^M->real^N->real^P) f g f' g' a b c.
12551         bilinear bop /\ COUNTABLE c /\
12552         (\x. bop (f x) (g x)) continuous_on interval[a,b] /\
12553         (!x. x IN interval(a,b) DIFF c
12554              ==> (f has_vector_derivative f'(x)) (at x) /\
12555                  (g has_vector_derivative g'(x)) (at x))
12556         ==> ((\x. bop (f x) (g' x)) integrable_on interval[a,b] <=>
12557              (\x. bop (f' x) (g x)) integrable_on interval[a,b])`,
12558   REPEAT STRIP_TAC THEN EQ_TAC THENL
12559    [ASM_MESON_TAC[INTEGRABLE_BY_PARTS]; DISCH_TAC] THEN
12560   MP_TAC(ISPEC `\x y. (bop:real^M->real^N->real^P) y x`
12561         INTEGRABLE_BY_PARTS) THEN
12562   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
12563   ANTS_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
12564   UNDISCH_TAC `bilinear(bop:real^M->real^N->real^P)` THEN
12565   REWRITE_TAC[bilinear] THEN MESON_TAC[]);;
12566
12567 (* ------------------------------------------------------------------------- *)
12568 (* Equiintegrability. The definition here only really makes sense for an     *)
12569 (* elementary set. We just use compact intervals in applications below.      *)
12570 (* ------------------------------------------------------------------------- *)
12571
12572 parse_as_infix("equiintegrable_on",(12,"right"));;
12573
12574 let equiintegrable_on = new_definition
12575   `fs equiintegrable_on i <=>
12576         (!f:real^M->real^N. f IN fs ==> f integrable_on i) /\
12577         (!e. &0 < e
12578              ==> ?d. gauge d /\
12579                     !f p. f IN fs /\ p tagged_division_of i /\ d fine p
12580                         ==> norm(vsum p (\(x,k). content(k) % f(x)) -
12581                                  integral i f) < e)`;;
12582
12583 let EQUIINTEGRABLE_ON_SING = prove
12584  (`!f:real^M->real^N a b.
12585         {f} equiintegrable_on interval[a,b] <=>
12586         f integrable_on interval[a,b]`,
12587   REPEAT GEN_TAC THEN REWRITE_TAC[equiintegrable_on] THEN
12588   REWRITE_TAC[IN_SING; FORALL_UNWIND_THM2] THEN
12589   ASM_CASES_TAC `(f:real^M->real^N) integrable_on interval[a,b]` THEN
12590   ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN
12591   FIRST_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
12592   REWRITE_TAC[has_integral; IMP_IMP]);;
12593
12594 (* ------------------------------------------------------------------------- *)
12595 (* Basic combining theorems for the interval of integration.                 *)
12596 (* ------------------------------------------------------------------------- *)
12597
12598 let EQUIINTEGRABLE_ON_NULL = prove
12599  (`!fs:(real^M->real^N)->bool a b.
12600      content(interval[a,b]) = &0 ==> fs equiintegrable_on interval[a,b]`,
12601   REPEAT STRIP_TAC THEN REWRITE_TAC[equiintegrable_on] THEN
12602   ASM_SIMP_TAC[INTEGRABLE_ON_NULL] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
12603   EXISTS_TAC `\x:real^M. ball(x,&1)` THEN REWRITE_TAC[GAUGE_TRIVIAL] THEN
12604   FIRST_ASSUM(fun th -> SIMP_TAC[MATCH_MP (REWRITE_RULE[IMP_CONJ]
12605                                            VSUM_CONTENT_NULL) th]) THEN
12606   ASM_SIMP_TAC[INTEGRAL_NULL; VECTOR_SUB_REFL; NORM_0]);;
12607
12608 let EQUIINTEGRABLE_ON_SPLIT = prove
12609  (`!fs:(real^M->real^N)->bool k a b c.
12610       fs equiintegrable_on (interval[a,b] INTER {x | x$k <= c}) /\
12611       fs equiintegrable_on (interval[a,b] INTER {x | x$k >= c}) /\
12612       1 <= k /\ k <= dimindex(:M)
12613       ==> fs equiintegrable_on (interval[a,b])`,
12614   let lemma1 = prove
12615    (`(!x k. (x,k) IN {x,f k | P x k} ==> Q x k) <=>
12616      (!x k. P x k ==> Q x (f k))`,
12617     REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN
12618     SET_TAC[]) in
12619   let lemma2 = prove
12620    (`!f:B->B s:(A#B)->bool.
12621       FINITE s ==> FINITE {x,f k | (x,k) IN s /\ P x k}`,
12622     REPEAT STRIP_TAC THEN MATCH_MP_TAC FINITE_SUBSET THEN
12623     EXISTS_TAC `IMAGE (\(x:A,k:B). x,(f k:B)) s` THEN
12624     ASM_SIMP_TAC[FINITE_IMAGE] THEN
12625     REWRITE_TAC[SUBSET; FORALL_PAIR_THM; lemma1; IN_IMAGE] THEN
12626     REWRITE_TAC[EXISTS_PAIR_THM; PAIR_EQ] THEN MESON_TAC[]) in
12627   let lemma3 = prove
12628    (`!f:real^M->real^N g:(real^M->bool)->(real^M->bool) p.
12629      FINITE p
12630      ==> vsum {x,g k |x,k| (x,k) IN p /\ ~(g k = {})}
12631               (\(x,k). content k % f x) =
12632          vsum (IMAGE (\(x,k). x,g k) p) (\(x,k). content k % f x)`,
12633     REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN
12634     ASM_SIMP_TAC[FINITE_IMAGE; lemma2] THEN
12635     REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE] THEN
12636     REWRITE_TAC[FORALL_PAIR_THM; SUBSET; IN_IMAGE; EXISTS_PAIR_THM] THEN
12637     REWRITE_TAC[IN_ELIM_THM; PAIR_EQ; VECTOR_MUL_EQ_0] THEN
12638     MESON_TAC[CONTENT_EMPTY]) in
12639   let lemma4 = prove
12640    (`(\(x,l). content (g l) % f x) =
12641      (\(x,l). content l % f x) o (\(x,l). x,g l)`,
12642     REWRITE_TAC[FUN_EQ_THM; o_THM; FORALL_PAIR_THM]) in
12643   REPEAT GEN_TAC THEN
12644   ASM_CASES_TAC `1 <= k /\ k <= dimindex(:M)` THEN ASM_REWRITE_TAC[] THEN
12645   REWRITE_TAC[equiintegrable_on] THEN
12646   MATCH_MP_TAC(TAUT
12647    `(a /\ b ==> c) /\ (a /\ b /\ c ==> a' /\ b' ==> c')
12648     ==> (a /\ a') /\ (b /\ b') ==> c /\ c'`) THEN
12649   CONJ_TAC THENL
12650    [REWRITE_TAC[integrable_on] THEN ASM MESON_TAC[HAS_INTEGRAL_SPLIT];
12651     STRIP_TAC] THEN
12652   SUBGOAL_THEN
12653    `!f:real^M->real^N.
12654         f IN fs
12655         ==> integral (interval[a,b]) f =
12656                 integral (interval [a,b] INTER {x | x$k <= c}) f +
12657                 integral (interval [a,b] INTER {x | x$k >= c}) f`
12658    (fun th -> SIMP_TAC[th])
12659   THENL
12660    [REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
12661     MATCH_MP_TAC HAS_INTEGRAL_SPLIT THEN
12662     MAP_EVERY EXISTS_TAC [`k:num`; `c:real`] THEN
12663     ASM_SIMP_TAC[GSYM HAS_INTEGRAL_INTEGRAL];
12664     ALL_TAC] THEN
12665   DISCH_TAC THEN X_GEN_TAC `e:real` THEN STRIP_TAC THEN
12666   FIRST_X_ASSUM(CONJUNCTS_THEN2 (MP_TAC o SPEC `e / &2`) STRIP_ASSUME_TAC) THEN
12667   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
12668   DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool`
12669    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "I2"))) THEN
12670   DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool`
12671    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "I1"))) THEN
12672   EXISTS_TAC `\x. if x$k = c then (d1(x:real^M) INTER d2(x)):real^M->bool
12673                   else ball(x,abs(x$k - c)) INTER d1(x) INTER d2(x)` THEN
12674   CONJ_TAC THENL
12675    [REWRITE_TAC[gauge] THEN GEN_TAC THEN
12676     RULE_ASSUM_TAC(REWRITE_RULE[gauge]) THEN COND_CASES_TAC THEN
12677     ASM_SIMP_TAC[OPEN_INTER; IN_INTER; OPEN_BALL; IN_BALL] THEN
12678     ASM_REWRITE_TAC[DIST_REFL; GSYM REAL_ABS_NZ; REAL_SUB_0];
12679     ALL_TAC] THEN
12680   X_GEN_TAC `f:real^M->real^N` THEN
12681   X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
12682   SUBGOAL_THEN
12683     `(!x:real^M kk. (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k <= c} = {})
12684                     ==> x$k <= c) /\
12685      (!x:real^M kk. (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k >= c} = {})
12686                     ==> x$k >= c)`
12687   STRIP_ASSUME_TAC THENL
12688    [CONJ_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
12689     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
12690     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `kk:real^M->bool` THEN
12691     DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
12692     COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL; real_ge] THEN DISCH_THEN
12693      (MP_TAC o MATCH_MP (SET_RULE `k SUBSET (a INTER b) ==> k SUBSET a`)) THEN
12694     REWRITE_TAC[SUBSET; IN_BALL; dist] THEN DISCH_TAC THEN
12695     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
12696     DISCH_THEN(X_CHOOSE_THEN `u:real^M` MP_TAC) THEN
12697     REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
12698     FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M`) THEN ASM_REWRITE_TAC[] THEN
12699     ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
12700     REWRITE_TAC[REAL_NOT_LE; REAL_NOT_LT] THEN STRIP_TAC THEN
12701     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((x - u:real^M)$k)` THEN
12702     ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
12703     ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
12704     ASM_REAL_ARITH_TAC;
12705     ALL_TAC] THEN
12706   REMOVE_THEN "I2" (MP_TAC o SPEC
12707    `{(x:real^M,kk INTER {x:real^M | x$k >= c}) |x,kk|
12708      (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k >= c} = {})}` o
12709    SPEC `f:real^M->real^N`) THEN
12710   REMOVE_THEN "I1" (MP_TAC o SPEC
12711    `{(x:real^M,kk INTER {x:real^M | x$k <= c}) |x,kk|
12712      (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k <= c} = {})}` o
12713    SPEC `f:real^M->real^N`) THEN
12714   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT
12715    `(a /\ b) /\ (a' /\ b' ==> c) ==> (a ==> a') ==> (b ==> b') ==> c`) THEN
12716   CONJ_TAC THENL
12717    [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
12718     REWRITE_TAC[TAGGED_DIVISION_OF] THEN
12719     REPEAT(MATCH_MP_TAC(TAUT
12720      `(a ==> (a' /\ a'')) /\ (b ==> (b' /\ d) /\ (b'' /\ e))
12721       ==> a /\ b ==> ((a' /\ b') /\ d) /\ ((a'' /\ b'') /\ e)`) THEN
12722       CONJ_TAC) THEN
12723     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
12724     REWRITE_TAC[lemma1] THEN REWRITE_TAC[IMP_IMP] THENL
12725      [SIMP_TAC[lemma2];
12726       REWRITE_TAC[AND_FORALL_THM] THEN
12727       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
12728       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `kk:real^M->bool` THEN
12729       DISCH_THEN(fun th -> CONJ_TAC THEN STRIP_TAC THEN MP_TAC th) THEN
12730       (ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
12731         [SIMP_TAC[IN_INTER; IN_ELIM_THM] THEN ASM_MESON_TAC[]; ALL_TAC]) THEN
12732       (MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL [SET_TAC[]; ALL_TAC]) THEN
12733       ASM_MESON_TAC[INTERVAL_SPLIT];
12734       DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
12735       (REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
12736        DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
12737        REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
12738        DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
12739        ANTS_TAC THENL [ASM_MESON_TAC[PAIR_EQ]; ALL_TAC] THEN
12740        MATCH_MP_TAC(SET_RULE
12741         `s SUBSET s' /\ t SUBSET t'
12742          ==> s' INTER t' = {} ==> s INTER t = {}`) THEN
12743        CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]);
12744       ALL_TAC] THEN
12745     MATCH_MP_TAC(TAUT `(a ==> b /\ c) /\ d /\ e
12746                        ==> (a ==> (b /\ d) /\ (c /\ e))`) THEN
12747     CONJ_TAC THENL
12748      [DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
12749       DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[INTER_UNIONS] THEN
12750       ONCE_REWRITE_TAC[EXTENSION] THEN REWRITE_TAC[IN_UNIONS] THEN
12751       X_GEN_TAC `x:real^M` THEN AP_TERM_TAC THEN
12752       GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `kk:real^M->bool` THEN
12753       REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN MESON_TAC[NOT_IN_EMPTY];
12754       ALL_TAC] THEN
12755     CONJ_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
12756     REWRITE_TAC[fine; lemma1] THEN
12757     REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
12758     DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
12759     ASM_SIMP_TAC[] THEN SET_TAC[];
12760     ALL_TAC] THEN
12761   DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH
12762    `x < e / &2 /\ y < e / &2 ==> x + y < e`)) THEN
12763   DISCH_THEN(MP_TAC o MATCH_MP NORM_TRIANGLE_LT) THEN
12764   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
12765   REWRITE_TAC[VECTOR_ARITH
12766    `(a - i) + (b - j) = c - (i + j) <=> a + b = c:real^N`] THEN
12767   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
12768  MATCH_MP_TAC EQ_TRANS THEN
12769   EXISTS_TAC
12770    `vsum p (\(x,l). content (l INTER {x:real^M | x$k <= c}) %
12771                      (f:real^M->real^N) x) +
12772     vsum p (\(x,l). content (l INTER {x:real^M | x$k >= c}) %
12773                      (f:real^M->real^N) x)` THEN
12774   CONJ_TAC THENL
12775    [ALL_TAC;
12776     ASM_SIMP_TAC[GSYM VSUM_ADD] THEN MATCH_MP_TAC VSUM_EQ THEN
12777     REWRITE_TAC[FORALL_PAIR_THM; GSYM VECTOR_ADD_RDISTRIB] THEN
12778     MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
12779     DISCH_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
12780     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
12781     DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `l:real^M->bool`] o
12782                el 1 o CONJUNCTS) THEN
12783     ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
12784     ASM_SIMP_TAC[GSYM CONTENT_SPLIT]] THEN
12785   ASM_SIMP_TAC[lemma3] THEN BINOP_TAC THEN
12786   (GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [lemma4] THEN
12787    MATCH_MP_TAC VSUM_IMAGE_NONZERO THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
12788    REWRITE_TAC[PAIR_EQ] THEN
12789    ASM_MESON_TAC[TAGGED_DIVISION_SPLIT_LEFT_INJ; VECTOR_MUL_LZERO;
12790                  TAGGED_DIVISION_SPLIT_RIGHT_INJ]));;
12791
12792 let EQUIINTEGRABLE_DIVISION = prove
12793  (`!fs:(real^M->real^N)->bool d a b.
12794         d division_of interval[a,b]
12795         ==> (fs equiintegrable_on interval[a,b] <=>
12796              !i. i IN d ==> fs equiintegrable_on i)`,
12797   REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
12798   MATCH_MP_TAC OPERATIVE_DIVISION_AND THEN
12799   ASM_REWRITE_TAC[operative; NEUTRAL_AND] THEN
12800   POP_ASSUM_LIST(K ALL_TAC) THEN CONJ_TAC THENL
12801    [MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN
12802     ASM_SIMP_TAC[equiintegrable_on; INTEGRABLE_ON_NULL] THEN
12803     GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `\x:real^M. ball(x,&1)` THEN
12804     ASM_SIMP_TAC[GAUGE_TRIVIAL; INTEGRAL_NULL; VECTOR_SUB_RZERO] THEN
12805     REPEAT STRIP_TAC THEN
12806     FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH
12807      `&0 < e ==> x = vec 0 ==> norm x < e`)) THEN
12808     MATCH_MP_TAC VSUM_EQ_0 THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
12809     REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN
12810     RULE_ASSUM_TAC(REWRITE_RULE[TAGGED_DIVISION_OF]) THEN
12811     ASM_MESON_TAC[CONTENT_EQ_0_INTERIOR; SUBSET_INTERIOR;
12812                   SET_RULE `s = {} <=> s SUBSET {}`];
12813     ALL_TAC] THEN
12814   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real`; `k:num`] THEN
12815   STRIP_TAC THEN EQ_TAC THENL
12816    [ALL_TAC; ASM_MESON_TAC[EQUIINTEGRABLE_ON_SPLIT]] THEN
12817   ASM_SIMP_TAC[INTEGRABLE_SPLIT; equiintegrable_on] THEN
12818   STRIP_TAC THEN CONJ_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
12819   (FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
12820    MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
12821    ASM_CASES_TAC `gauge(d:real^M->real^M->bool)` THEN ASM_REWRITE_TAC[] THEN
12822    MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `f:real^M->real^N` THEN
12823    ASM_CASES_TAC `(f:real^M->real^N) IN fs` THEN ASM_REWRITE_TAC[] THEN
12824    DISCH_TAC THEN
12825    MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`;
12826                   `d:real^M->real^M->bool`; `e / &2`]
12827          HENSTOCK_LEMMA_PART1) THEN ASM_SIMP_TAC[REAL_HALF] THEN
12828    MATCH_MP_TAC MONO_FORALL THEN
12829    X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN
12830    DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ANTS_TAC THENL
12831     [ASM_REWRITE_TAC[] THEN MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_OF_SUBSET THEN
12832      RULE_ASSUM_TAC(REWRITE_RULE[tagged_division_of]) THEN
12833      ASM_MESON_TAC[INTER_SUBSET];
12834      ALL_TAC] THEN
12835    MATCH_MP_TAC(NORM_ARITH
12836     `&0 < e /\ x:real^N = y ==> norm(x) <= e / &2 ==> norm(y) < e`) THEN
12837    ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
12838    W(MP_TAC o PART_MATCH (lhand o rand)
12839      INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN o rand o rand o snd) THEN
12840    ASM_SIMP_TAC[GSYM INTERVAL_SPLIT; INTEGRABLE_SPLIT] THEN
12841    DISCH_THEN SUBST1_TAC THEN
12842    FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
12843    ASM_SIMP_TAC[GSYM VSUM_SUB] THEN MATCH_MP_TAC VSUM_EQ THEN
12844    REWRITE_TAC[FORALL_PAIR_THM]));;
12845
12846 (* ------------------------------------------------------------------------- *)
12847 (* Main limit theorem for an equiintegrable sequence.                        *)
12848 (* ------------------------------------------------------------------------- *)
12849
12850 let EQUIINTEGRABLE_LIMIT = prove
12851  (`!f g:real^M->real^N a b.
12852         {f n | n IN (:num)} equiintegrable_on interval[a,b] /\
12853         (!x. x IN interval[a,b] ==> ((\n. f n x) --> g x) sequentially)
12854         ==> g integrable_on interval[a,b] /\
12855             ((\n. integral(interval[a,b]) (f n)) --> integral(interval[a,b]) g)
12856             sequentially`,
12857   REPEAT GEN_TAC THEN STRIP_TAC THEN
12858   ASM_CASES_TAC `content(interval[a:real^M,b]) = &0` THEN
12859   ASM_SIMP_TAC[INTEGRABLE_ON_NULL; INTEGRAL_NULL; LIM_CONST] THEN
12860   SUBGOAL_THEN `cauchy (\n. integral(interval[a,b]) (f n :real^M->real^N))`
12861   MP_TAC THENL
12862    [REWRITE_TAC[cauchy] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
12863     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [equiintegrable_on]) THEN
12864     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC; IN_UNIV] THEN
12865     DISCH_TAC THEN REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
12866     DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
12867     ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
12868     DISCH_THEN(X_CHOOSE_THEN `d:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
12869     FIRST_ASSUM(MP_TAC o MATCH_MP FINE_DIVISION_EXISTS) THEN
12870     DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN
12871     DISCH_THEN(X_CHOOSE_THEN `p:(real^M#(real^M->bool))->bool`
12872         STRIP_ASSUME_TAC) THEN
12873     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
12874     FIRST_X_ASSUM(MP_TAC o GEN `n:num` o SPECL
12875      [`n:num`; `p:(real^M#(real^M->bool))->bool`]) THEN
12876     ASM_REWRITE_TAC[] THEN DISCH_TAC THEN SUBGOAL_THEN
12877      `cauchy (\n. vsum p (\(x,k:real^M->bool).
12878                content k % (f:num->real^M->real^N) n x))`
12879     MP_TAC THENL
12880      [MATCH_MP_TAC CONVERGENT_IMP_CAUCHY THEN
12881       EXISTS_TAC `vsum p (\(x,k:real^M->bool).
12882           content k % (g:real^M->real^N) x)` THEN
12883       MATCH_MP_TAC
12884        (REWRITE_RULE[LAMBDA_PAIR_THM]
12885         (REWRITE_RULE[FORALL_PAIR_THM]
12886          (ISPECL [`sequentially`; `\(x:real^M,k:real^M->bool) (n:num).
12887                   content k % (f n x:real^N)`] LIM_VSUM))) THEN
12888       ASM_REWRITE_TAC[] THEN
12889       MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
12890       MATCH_MP_TAC LIM_CMUL THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
12891       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
12892       ASM_SIMP_TAC[SUBSET] THEN ASM_MESON_TAC[];
12893       REWRITE_TAC[cauchy] THEN DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
12894       ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
12895       REWRITE_TAC[IMP_IMP; RIGHT_IMP_FORALL_THM; GE] THEN
12896       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
12897       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `m:num` THEN
12898       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:num` THEN
12899       ASM_CASES_TAC `N:num <= m /\ N <= n` THEN ASM_REWRITE_TAC[] THEN
12900       MATCH_MP_TAC(NORM_ARITH
12901        `norm(sm - gm:real^N) < e / &3 /\ norm(sn - gn) < e / &3
12902         ==> dist(sm,sn) < e / &3 ==> dist(gm,gn) < e`) THEN
12903       ASM_REWRITE_TAC[]];
12904     REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN
12905     DISCH_THEN(X_CHOOSE_TAC `l:real^N`) THEN
12906     SUBGOAL_THEN `((g:real^M->real^N) has_integral l) (interval[a,b])`
12907      (fun th -> ASM_MESON_TAC[th; integrable_on; INTEGRAL_UNIQUE]) THEN
12908     REWRITE_TAC[has_integral] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
12909     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [equiintegrable_on]) THEN
12910     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC; IN_UNIV] THEN
12911     DISCH_TAC THEN REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
12912     DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
12913     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
12914     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
12915     X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
12916     MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
12917     ASM_REWRITE_TAC[] THEN
12918     MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN
12919     EXISTS_TAC `\n:num. vsum p (\(x,k:real^M->bool). content k % f n x) -
12920                        integral (interval [a,b]) (f n :real^M->real^N)` THEN
12921     ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; REAL_LT_IMP_LE] THEN
12922     REWRITE_TAC[EVENTUALLY_TRUE] THEN
12923     MATCH_MP_TAC LIM_SUB THEN ASM_REWRITE_TAC[] THEN
12924     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
12925     MATCH_MP_TAC
12926      (REWRITE_RULE[LAMBDA_PAIR_THM]
12927       (REWRITE_RULE[FORALL_PAIR_THM]
12928        (ISPECL [`sequentially`; `\(x:real^M,k:real^M->bool) (n:num).
12929                 content k % (f n x:real^N)`] LIM_VSUM))) THEN
12930     ASM_REWRITE_TAC[] THEN
12931     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
12932     MATCH_MP_TAC LIM_CMUL THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
12933     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
12934     ASM_SIMP_TAC[SUBSET] THEN ASM_MESON_TAC[]]);;
12935
12936 (* ------------------------------------------------------------------------- *)
12937 (* Combining theorems for the set of equiintegrable functions.               *)
12938 (* ------------------------------------------------------------------------- *)
12939
12940 let EQUIINTEGRABLE_SUBSET = prove
12941  (`!fs gs s.
12942    fs equiintegrable_on s /\ gs SUBSET fs ==> gs equiintegrable_on s`,
12943   REWRITE_TAC[equiintegrable_on; SUBSET] THEN MESON_TAC[]);;
12944
12945 let EQUIINTEGRABLE_UNION = prove
12946  (`!fs:(real^M->real^N)->bool gs s.
12947         fs equiintegrable_on s /\ gs equiintegrable_on s
12948         ==> (fs UNION gs) equiintegrable_on s`,
12949   REPEAT GEN_TAC THEN REWRITE_TAC[equiintegrable_on; IN_UNION] THEN
12950   REWRITE_TAC[TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
12951   REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
12952   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
12953   REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `e:real`)) THEN ASM_REWRITE_TAC[] THEN
12954   DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
12955   DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
12956   EXISTS_TAC `\x. (d1:real^M->real^M->bool) x INTER d2 x` THEN
12957   ASM_SIMP_TAC[GAUGE_INTER; FINE_INTER] THEN
12958   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[]);;
12959
12960 let EQUIINTEGRABLE_EQ = prove
12961  (`!fs gs:(real^M->real^N)->bool s.
12962         fs equiintegrable_on s /\
12963         (!g. g IN gs ==> ?f. f IN fs /\ (!x. x IN s ==> f x = g x))
12964         ==> gs equiintegrable_on s`,
12965   REPEAT GEN_TAC THEN REWRITE_TAC[equiintegrable_on] THEN
12966   DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC (LABEL_TAC "*")) THEN
12967   CONJ_TAC THENL
12968    [X_GEN_TAC `g:real^M->real^N` THEN DISCH_TAC THEN
12969     REMOVE_THEN "*" (MP_TAC o SPEC `g:real^M->real^N`) THEN
12970     ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
12971     X_GEN_TAC `f:real^M->real^N` THEN STRIP_TAC THEN
12972     FIRST_X_ASSUM(MP_TAC o SPEC `f:real^M->real^N`) THEN
12973     ASM_MESON_TAC[INTEGRABLE_SPIKE; IN_DIFF; NEGLIGIBLE_EMPTY];
12974     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
12975     FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
12976     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
12977     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
12978     MAP_EVERY X_GEN_TAC
12979      [`g:real^M->real^N`;`p:(real^M#(real^M->bool))->bool`] THEN
12980     STRIP_TAC THEN REMOVE_THEN "*" (MP_TAC o SPEC `g:real^M->real^N`) THEN
12981     ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
12982     X_GEN_TAC `f:real^M->real^N` THEN STRIP_TAC THEN
12983     FIRST_X_ASSUM(MP_TAC o SPECL
12984      [`f:real^M->real^N`;`p:(real^M#(real^M->bool))->bool`]) THEN
12985     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(MESON[]
12986      `x:real^N = y /\ a = b ==> norm(x - a) < e ==> norm(y - b) < e`) THEN
12987     CONJ_TAC THENL
12988      [MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
12989       RULE_ASSUM_TAC(REWRITE_RULE[TAGGED_DIVISION_OF; SUBSET]) THEN
12990       ASM_MESON_TAC[];
12991       ASM_MESON_TAC[INTEGRAL_EQ]]]);;
12992
12993 let EQUIINTEGRABLE_CMUL = prove
12994  (`!fs:(real^M->real^N)->bool s k.
12995         fs equiintegrable_on s
12996         ==> {(\x. c % f x) | abs(c) <= k /\ f IN fs} equiintegrable_on s`,
12997   REPEAT GEN_TAC THEN
12998   SIMP_TAC[equiintegrable_on; INTEGRABLE_CMUL; FORALL_IN_GSPEC] THEN
12999   STRIP_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
13000   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
13001   ASM_SIMP_TAC[RIGHT_IMP_FORALL_THM; INTEGRAL_CMUL; IMP_IMP] THEN
13002   FIRST_X_ASSUM(MP_TAC o SPEC `e / (abs(k) + &1)`) THEN
13003   ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_MUL_LZERO;
13004                REAL_ARITH `&0 < abs(k) + &1`] THEN
13005   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
13006   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
13007   MAP_EVERY X_GEN_TAC [`c:real`; `f:real^M->real^N`;
13008                        `p:(real^M#(real^M->bool))->bool`] THEN
13009   STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o
13010    SPECL [`f:real^M->real^N`; `p:(real^M#(real^M->bool))->bool`]) THEN
13011   ASM_REWRITE_TAC[] THEN
13012   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN
13013   MATCH_MP_TAC(REAL_ARITH `&0 <= y /\ x <= c * y ==> x <= y * (c + &1)`) THEN
13014   REWRITE_TAC[NORM_POS_LE] THEN MATCH_MP_TAC(REAL_ARITH
13015    `!c. x = c * y /\ c *  y <= k * y ==> x <= k * y`) THEN
13016   EXISTS_TAC `abs c:real` THEN CONJ_TAC THENL
13017    [REWRITE_TAC[GSYM NORM_MUL; GSYM VSUM_LMUL; VECTOR_SUB_LDISTRIB] THEN
13018     REWRITE_TAC[LAMBDA_PAIR_THM; VECTOR_MUL_ASSOC; REAL_MUL_SYM];
13019     MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN
13020     ASM_REAL_ARITH_TAC]);;
13021
13022 let EQUIINTEGRABLE_ADD = prove
13023  (`!fs:(real^M->real^N)->bool gs s.
13024         fs equiintegrable_on s /\ gs equiintegrable_on s
13025         ==> {(\x. f x + g x) | f IN fs /\ g IN gs} equiintegrable_on s`,
13026   REPEAT GEN_TAC THEN
13027   SIMP_TAC[equiintegrable_on; INTEGRABLE_ADD; FORALL_IN_GSPEC] THEN
13028   DISCH_THEN(CONJUNCTS_THEN2
13029    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "f"))
13030    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "g"))) THEN
13031   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
13032   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
13033   ASM_SIMP_TAC[RIGHT_IMP_FORALL_THM; INTEGRAL_ADD; IMP_IMP] THEN
13034   REMOVE_THEN "g" (MP_TAC o SPEC `e / &2`) THEN
13035   REMOVE_THEN "f" (MP_TAC o SPEC `e / &2`) THEN
13036   ASM_REWRITE_TAC[REAL_HALF] THEN
13037   DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool`
13038    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "f"))) THEN
13039   DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool`
13040    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "g"))) THEN
13041   EXISTS_TAC `\x. (d1:real^M->real^M->bool) x INTER d2 x` THEN
13042   ASM_SIMP_TAC[GAUGE_INTER; FINE_INTER] THEN
13043   MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^M->real^N`;
13044                        `p:(real^M#(real^M->bool))->bool`] THEN STRIP_TAC THEN
13045   REMOVE_THEN "g" (MP_TAC o SPECL
13046    [`g:real^M->real^N`; `p:(real^M#(real^M->bool))->bool`]) THEN
13047   REMOVE_THEN "f" (MP_TAC o SPECL
13048    [`f:real^M->real^N`; `p:(real^M#(real^M->bool))->bool`]) THEN
13049   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(NORM_ARITH
13050    `s + s' = t
13051     ==> norm(s - i) < e / &2 ==> norm(s' - i') < e / &2
13052         ==> norm(t - (i + i')) < e`) THEN
13053   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
13054   ASM_SIMP_TAC[GSYM VSUM_ADD] THEN
13055   REWRITE_TAC[LAMBDA_PAIR_THM; VECTOR_ADD_LDISTRIB]);;
13056
13057 let EQUIINTEGRABLE_NEG = prove
13058  (`!fs:(real^M->real^N)->bool s.
13059         fs equiintegrable_on s
13060         ==> {(\x. --(f x)) | f IN fs} equiintegrable_on s`,
13061   REPEAT STRIP_TAC THEN
13062   FIRST_ASSUM(MP_TAC o SPEC `&1` o MATCH_MP EQUIINTEGRABLE_CMUL) THEN
13063   MATCH_MP_TAC (REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
13064   REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN REWRITE_TAC[IN_ELIM_THM] THEN
13065   X_GEN_TAC `f:real^M->real^N` THEN DISCH_TAC THEN EXISTS_TAC `-- &1` THEN
13066   EXISTS_TAC `f:real^M->real^N` THEN
13067   ASM_REWRITE_TAC[VECTOR_MUL_LNEG; VECTOR_MUL_LID] THEN REAL_ARITH_TAC);;
13068
13069 let EQUIINTEGRABLE_SUB = prove
13070  (`!fs:(real^M->real^N)->bool gs s.
13071         fs equiintegrable_on s /\ gs equiintegrable_on s
13072         ==> {(\x. f x - g x) | f IN fs /\ g IN gs} equiintegrable_on s`,
13073   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2
13074    MP_TAC (MP_TAC o MATCH_MP EQUIINTEGRABLE_NEG)) THEN
13075   REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN
13076   DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_ADD) THEN
13077   MATCH_MP_TAC (REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
13078   REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN REWRITE_TAC[IN_ELIM_THM] THEN
13079   MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^M->real^N`] THEN
13080   STRIP_TAC THEN EXISTS_TAC `f:real^M->real^N` THEN
13081   EXISTS_TAC `\x. --((g:real^M->real^N) x)` THEN
13082   ASM_REWRITE_TAC[VECTOR_SUB] THEN EXISTS_TAC `g:real^M->real^N` THEN
13083   ASM_REWRITE_TAC[]);;
13084
13085 let EQUIINTEGRABLE_SUM = prove
13086  (`!fs:(real^M->real^N)->bool a b.
13087         fs equiintegrable_on interval[a,b]
13088         ==> {(\x. vsum t (\i. c i % f i x)) |
13089                FINITE t /\
13090                (!i:A. i IN t ==> &0 <= c i /\ (f i) IN fs) /\
13091                sum t c = &1}
13092             equiintegrable_on interval[a,b]`,
13093   REPEAT GEN_TAC THEN REWRITE_TAC[equiintegrable_on] THEN
13094   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
13095   REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; RIGHT_IMP_FORALL_THM] THEN
13096   STRIP_TAC THEN
13097   ASM (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 5)
13098    [INTEGRABLE_CMUL; INTEGRABLE_VSUM; ETA_AX; INTEGRAL_VSUM] THEN
13099   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
13100   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
13101   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
13102   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MAP_EVERY X_GEN_TAC
13103    [`t:A->bool`; `c:A->real`; `f:A->real^M->real^N`;
13104     `p:(real^M#(real^M->bool))->bool`] THEN
13105   STRIP_TAC THEN
13106   SUBGOAL_THEN
13107    `!i:A. i IN t
13108           ==> integral (interval[a,b]) (\x:real^M. c i % f i x:real^N) =
13109               vsum p (\(x:real^M,k).
13110                        integral (k:real^M->bool) (\x:real^M. c i % f i x))`
13111    (fun th -> SIMP_TAC[th])
13112   THENL
13113    [REPEAT STRIP_TAC THEN
13114     MATCH_MP_TAC INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN THEN
13115     ASM_SIMP_TAC[INTEGRABLE_CMUL; ETA_AX];
13116     ALL_TAC] THEN
13117   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
13118   SUBGOAL_THEN
13119    `vsum p (\(x,k:real^M->bool). content k % vsum t (\i. c i % f i x)) =
13120     vsum t (\i. c i %
13121                 vsum p (\(x,k). content k % (f:A->real^M->real^N) i x))`
13122   SUBST1_TAC THENL
13123    [REWRITE_TAC[GSYM VSUM_LMUL] THEN
13124     W(MP_TAC o PART_MATCH (lhs o rand) VSUM_SWAP o
13125       rand o snd) THEN
13126     ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN
13127     MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
13128     REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_SYM];
13129     ALL_TAC] THEN
13130   MATCH_MP_TAC REAL_LET_TRANS THEN
13131   EXISTS_TAC `sum t (\i:A. c i * e / &2)` THEN CONJ_TAC THENL
13132    [ALL_TAC;
13133     ASM_SIMP_TAC[SUM_RMUL; ETA_AX; REAL_MUL_LID] THEN ASM_REAL_ARITH_TAC] THEN
13134   ASM_SIMP_TAC[GSYM VSUM_SUB] THEN MATCH_MP_TAC VSUM_NORM_LE THEN
13135   ASM_REWRITE_TAC[] THEN X_GEN_TAC `i:A` THEN DISCH_TAC THEN
13136   ASM_SIMP_TAC[GSYM VSUM_LMUL; GSYM VSUM_SUB] THEN
13137   REWRITE_TAC[LAMBDA_PAIR_THM] THEN FIRST_X_ASSUM(MP_TAC o SPECL
13138    [`(f:A->real^M->real^N) i`; `p:(real^M#(real^M->bool))->bool`]) THEN
13139   ASM_SIMP_TAC[] THEN DISCH_THEN(MP_TAC o MATCH_MP REAL_LT_IMP_LE) THEN
13140   DISCH_THEN(MP_TAC o SPEC `abs((c:A->real) i)` o
13141     MATCH_MP(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_LMUL)) THEN
13142   ASM_REWRITE_TAC[REAL_ABS_POS; GSYM NORM_MUL] THEN
13143   ASM_SIMP_TAC[GSYM VSUM_LMUL; VECTOR_SUB_LDISTRIB; real_abs] THEN
13144   REWRITE_TAC[LAMBDA_PAIR_THM] THEN
13145   MATCH_MP_TAC(REAL_ARITH `x = y ==> x <= a ==> y <= a`) THEN
13146   AP_TERM_TAC THEN
13147   SUBGOAL_THEN
13148    `integral (interval[a,b]) ((f:A->real^M->real^N) i) =
13149     vsum p (\(x:real^M,k). integral (k:real^M->bool) (f i))`
13150   SUBST1_TAC THENL
13151    [MATCH_MP_TAC INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN THEN ASM_SIMP_TAC[];
13152     ALL_TAC] THEN
13153   ASM_SIMP_TAC[GSYM VSUM_LMUL; GSYM VSUM_SUB] THEN
13154   MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
13155   MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
13156   AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_CMUL THEN
13157   RULE_ASSUM_TAC(REWRITE_RULE[TAGGED_DIVISION_OF]) THEN
13158   ASM_MESON_TAC[INTEGRABLE_SUBINTERVAL]);;
13159
13160 let EQUIINTEGRABLE_UNIFORM_LIMIT = prove
13161  (`!fs:(real^M->real^N)->bool a b.
13162         fs equiintegrable_on interval[a,b]
13163         ==> {g | !e. &0 < e
13164                      ==> ?f. f IN fs /\
13165                              !x. x IN interval[a,b] ==> norm(g x - f x) < e}
13166             equiintegrable_on interval[a,b]`,
13167   REPEAT STRIP_TAC THEN
13168   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [equiintegrable_on]) THEN
13169   REWRITE_TAC[equiintegrable_on; IN_ELIM_THM] THEN REPEAT GEN_TAC THEN
13170   STRIP_TAC THEN CONJ_TAC THENL
13171    [ASM_MESON_TAC[INTEGRABLE_UNIFORM_LIMIT; REAL_LT_IMP_LE]; ALL_TAC] THEN
13172   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
13173   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
13174   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
13175   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MAP_EVERY X_GEN_TAC
13176    [`g:real^M->real^N`;`p:(real^M#(real^M->bool))->bool`] THEN
13177   STRIP_TAC THEN
13178   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
13179   SUBGOAL_THEN `(g:real^M->real^N) integrable_on interval[a,b]`
13180   ASSUME_TAC THENL
13181    [ASM_MESON_TAC[INTEGRABLE_UNIFORM_LIMIT; REAL_LT_IMP_LE]; ALL_TAC] THEN
13182   FIRST_X_ASSUM(MP_TAC o GEN `n:num` o SPEC `inv(&n + &1)`) THEN
13183   REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
13184   REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM; LEFT_IMP_EXISTS_THM] THEN
13185   X_GEN_TAC `f:num->real^M->real^N` THEN STRIP_TAC THEN
13186   SUBGOAL_THEN
13187    `!x. x IN interval[a,b]
13188         ==> ((\n. f n x) --> (g:real^M->real^N) x) sequentially`
13189   ASSUME_TAC THENL
13190    [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
13191     REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `k:real` THEN DISCH_TAC THEN
13192     MP_TAC(SPEC `k:real` REAL_ARCH_INV) THEN ASM_REWRITE_TAC[] THEN
13193     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
13194     STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
13195     REWRITE_TAC[NORM_ARITH `dist(a:real^N,b) = norm(b - a)`] THEN
13196     MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `inv(&n + &1)` THEN
13197     ASM_SIMP_TAC[] THEN
13198     MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN
13199     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
13200     REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
13201     ASM_ARITH_TAC;
13202     ALL_TAC] THEN
13203   MP_TAC(ISPECL [`f:num->real^M->real^N`; `g:real^M->real^N`;
13204                  `a:real^M`; `b:real^M`] EQUIINTEGRABLE_LIMIT) THEN
13205   ANTS_TAC THENL
13206    [ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQUIINTEGRABLE_SUBSET THEN
13207     EXISTS_TAC `fs:(real^M->real^N)->bool` THEN ASM SET_TAC[];
13208     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*"))] THEN
13209   SUBGOAL_THEN
13210    `((\n. vsum p (\(x,k:real^M->bool).
13211                     content k % (f:num->real^M->real^N) n x)) -->
13212      vsum p (\(x,k). content k % g x)) sequentially`
13213    (LABEL_TAC "+")
13214   THENL
13215    [MATCH_MP_TAC
13216        (REWRITE_RULE[LAMBDA_PAIR_THM]
13217         (REWRITE_RULE[FORALL_PAIR_THM]
13218          (ISPECL [`sequentially`; `\(x:real^M,k:real^M->bool) (n:num).
13219                   content k % (f n x:real^N)`] LIM_VSUM))) THEN
13220     ASM_REWRITE_TAC[] THEN
13221     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
13222     MATCH_MP_TAC LIM_CMUL THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
13223     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
13224     ASM_SIMP_TAC[SUBSET] THEN ASM_MESON_TAC[];
13225     ALL_TAC] THEN
13226   REMOVE_THEN "*" (MP_TAC o REWRITE_RULE[LIM_SEQUENTIALLY]) THEN
13227   DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
13228   ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[dist]] THEN
13229   DISCH_THEN(X_CHOOSE_THEN `N1:num` (LABEL_TAC "*")) THEN
13230   REMOVE_THEN "+" (MP_TAC o REWRITE_RULE[LIM_SEQUENTIALLY]) THEN
13231   DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
13232   ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[dist]] THEN
13233   DISCH_THEN(X_CHOOSE_THEN `N2:num` (LABEL_TAC "+")) THEN
13234   SUBGOAL_THEN `?n:num. N1 <= n /\ N2 <= n` STRIP_ASSUME_TAC THENL
13235    [EXISTS_TAC `N1 + N2:num` THEN ARITH_TAC; ALL_TAC] THEN
13236   REMOVE_THEN "*" (MP_TAC o SPEC `n:num`) THEN
13237   REMOVE_THEN "+" (MP_TAC o SPEC `n:num`) THEN
13238   FIRST_X_ASSUM(MP_TAC o SPECL
13239    [`(f:num->real^M->real^N) n`;`p:(real^M#(real^M->bool))->bool`]) THEN
13240   ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);;
13241
13242 let EQUIINTEGRABLE_REFLECT = prove
13243  (`!fs:(real^M->real^N)->bool a b.
13244         fs equiintegrable_on interval[a,b]
13245         ==> {(\x. f(--x)) | f IN fs} equiintegrable_on interval[--b,--a]`,
13246   let lemma = prove
13247    (`(!x k. (x,k) IN IMAGE (\(x,k). f x k,g x k) s ==> Q x k) <=>
13248      (!x k. (x,k) IN s ==> Q (f x k) (g x k))`,
13249     REWRITE_TAC[IN_IMAGE; PAIR_EQ; EXISTS_PAIR_THM] THEN SET_TAC[]) in
13250   REPEAT GEN_TAC THEN REWRITE_TAC[equiintegrable_on] THEN
13251   REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_GSPEC] THEN
13252   DISCH_TAC THEN DISCH_TAC THEN
13253   ASM_REWRITE_TAC[INTEGRABLE_REFLECT; INTEGRAL_REFLECT] THEN
13254   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
13255   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
13256   FIRST_X_ASSUM(K ALL_TAC o check (is_forall o concl)) THEN
13257   DISCH_THEN(X_CHOOSE_THEN `d:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
13258   EXISTS_TAC `\x. IMAGE (--) ((d:real^M->real^M->bool) (--x))` THEN
13259   CONJ_TAC THENL
13260    [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [gauge]) THEN
13261     SIMP_TAC[gauge; OPEN_NEGATIONS] THEN DISCH_TAC THEN
13262     GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_NEG_NEG] THEN
13263     MATCH_MP_TAC FUN_IN_IMAGE THEN ASM_REWRITE_TAC[];
13264     ALL_TAC] THEN
13265   X_GEN_TAC `f:real^M->real^N` THEN DISCH_TAC THEN
13266   X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN REPEAT DISCH_TAC THEN
13267   FIRST_X_ASSUM(MP_TAC o SPEC `f:real^M->real^N`) THEN ASM_REWRITE_TAC[] THEN
13268   DISCH_THEN(MP_TAC o SPEC
13269    `IMAGE (\(x,k). (--x:real^M,IMAGE (--) (k:real^M->bool))) p`) THEN
13270   ANTS_TAC THENL
13271    [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
13272     REWRITE_TAC[TAGGED_DIVISION_OF] THEN
13273     STRIP_TAC THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN
13274     REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; lemma] THEN
13275     REPEAT CONJ_TAC THENL
13276      [MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
13277       ASM_SIMP_TAC[FUN_IN_IMAGE] THEN CONJ_TAC THENL
13278        [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
13279         ONCE_REWRITE_TAC[GSYM IN_INTERVAL_REFLECT] THEN
13280         ASM_SIMP_TAC[VECTOR_NEG_NEG; GSYM SUBSET] THEN ASM_MESON_TAC[];
13281         REWRITE_TAC[EXTENSION; IN_IMAGE] THEN
13282         REWRITE_TAC[VECTOR_ARITH `x:real^N = --y <=> --x = y`] THEN
13283         ONCE_REWRITE_TAC[GSYM IN_INTERVAL_REFLECT] THEN
13284         REWRITE_TAC[UNWIND_THM1] THEN
13285         SUBGOAL_THEN `?u v:real^M. k = interval[u,v]`
13286          (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
13287         THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
13288         ASM_MESON_TAC[VECTOR_NEG_NEG]];
13289       MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
13290       MAP_EVERY X_GEN_TAC [`y:real^M`; `l:real^M->bool`] THEN DISCH_TAC THEN
13291       FIRST_X_ASSUM(MP_TAC o SPECL
13292        [`x:real^M`; `k:real^M->bool`;
13293         `y:real^M`; `l:real^M->bool`]) THEN
13294       ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_IMP THEN
13295       CONJ_TAC THENL [MESON_TAC[PAIR_EQ]; ALL_TAC] THEN
13296       REWRITE_TAC[INTERIOR_NEGATIONS] THEN
13297       MATCH_MP_TAC(SET_RULE
13298        `(!x. f(f x) = x)
13299         ==> s INTER t = {} ==> IMAGE f s INTER IMAGE f t = {}`) THEN
13300       REWRITE_TAC[VECTOR_NEG_NEG];
13301       GEN_REWRITE_TAC I [EXTENSION] THEN
13302       ONCE_REWRITE_TAC[GSYM IN_INTERVAL_REFLECT] THEN
13303       FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN X_GEN_TAC `y:real^M` THEN
13304       REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN
13305       MATCH_MP_TAC(MESON[]
13306        `!f. (!x. f(f x) = x) /\ (!x. P x <=> Q(f x))
13307             ==> ((?x. P x) <=> (?x. Q x))`) THEN
13308       EXISTS_TAC `IMAGE ((--):real^M->real^M)` THEN CONJ_TAC THENL
13309        [REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_NEG_NEG; IMAGE_ID];
13310         ALL_TAC] THEN
13311       X_GEN_TAC `t:real^M->bool` THEN BINOP_TAC THENL
13312        [REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM; PAIR_EQ] THEN
13313         SUBGOAL_THEN `!k:real^M->bool. IMAGE (--) (IMAGE (--) k) = k`
13314         MP_TAC THENL
13315          [REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_NEG_NEG; IMAGE_ID];
13316           MESON_TAC[]];
13317         MATCH_MP_TAC(SET_RULE
13318          `(!x. f(f x) = x) ==> (y IN s <=> f y IN IMAGE f s)`) THEN
13319         REWRITE_TAC[VECTOR_NEG_NEG]]];
13320     ANTS_TAC THENL
13321      [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
13322       REWRITE_TAC[fine; lemma] THEN
13323       REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
13324       MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
13325       MATCH_MP_TAC(SET_RULE
13326        `(!x. f(f x) = x) ==> k SUBSET IMAGE f s ==> IMAGE f k SUBSET s`) THEN
13327       REWRITE_TAC[VECTOR_NEG_NEG];
13328       ALL_TAC] THEN
13329     MATCH_MP_TAC(NORM_ARITH
13330      `x:real^N = y ==> norm(x - i) < e ==> norm(y - i) < e`) THEN
13331     W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhs o snd) THEN
13332     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
13333     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
13334      [MATCH_MP_TAC(MESON[]
13335        `(!x. f(f x) = x)
13336         ==> !x y. x IN p /\ y IN p /\ f x = f y ==> x = y`) THEN
13337       REWRITE_TAC[FORALL_PAIR_THM; GSYM IMAGE_o; o_DEF; VECTOR_NEG_NEG;
13338                   IMAGE_ID];
13339       DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
13340       REWRITE_TAC[FORALL_PAIR_THM; o_THM] THEN
13341       MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
13342       SUBGOAL_THEN `?u v:real^M. k = interval[u,v]`
13343        (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
13344       THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
13345       AP_THM_TAC THEN AP_TERM_TAC THEN
13346       SUBGOAL_THEN `(--):real^M->real^M = (\x. --(&1) % x + vec 0)` SUBST1_TAC
13347       THENL [REWRITE_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC; ALL_TAC] THEN
13348       REWRITE_TAC[CONTENT_IMAGE_AFFINITY_INTERVAL; REAL_ABS_NEG] THEN
13349       REWRITE_TAC[REAL_POW_ONE; REAL_MUL_LID; REAL_ABS_NUM]]]);;
13350
13351 (* ------------------------------------------------------------------------- *)
13352 (* Some technical lemmas about minimizing a "flat" part of a sum over a      *)
13353 (* division, followed by subinterval resictions for equiintegrable family.   *)
13354 (* ------------------------------------------------------------------------- *)
13355
13356 let SUM_CONTENT_AREA_OVER_THIN_DIVISION = prove
13357  (`!d a b:real^M s i c.
13358         d division_of s /\ s SUBSET interval[a,b] /\
13359         1 <= i /\ i <= dimindex(:M) /\ a$i <= c /\ c <= b$i /\
13360         (!k. k IN d ==> ~(k INTER {x | x$i = c} = {}))
13361         ==> (b$i - a$i) *
13362             sum d (\k. content k /
13363                        (interval_upperbound k$i - interval_lowerbound k$i))
13364             <= &2 * content(interval[a,b])`,
13365   let lemma0 = prove
13366    (`!k:real^M->bool i.
13367           1 <= i /\ i <= dimindex(:M)
13368           ==> content k / (interval_upperbound k$i - interval_lowerbound k$i) =
13369               if content k = &0 then &0
13370               else product ((1..dimindex(:M)) DELETE i)
13371                            (\j. interval_upperbound k$j -
13372                                 interval_lowerbound k$j)`,
13373     REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
13374     ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO] THEN
13375     REWRITE_TAC[content] THEN
13376     COND_CASES_TAC THENL [ASM_MESON_TAC[CONTENT_EMPTY]; ALL_TAC] THEN
13377     SUBGOAL_THEN
13378      `1..dimindex(:M) = i INSERT ((1..dimindex(:M)) DELETE i)`
13379     MP_TAC THENL
13380      [REWRITE_TAC[SET_RULE `s = x INSERT (s DELETE x) <=> x IN s`] THEN
13381       ASM_REWRITE_TAC[IN_NUMSEG];
13382       DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
13383        [th])] THEN
13384     ASM_SIMP_TAC[PRODUCT_CLAUSES; IN_NUMSEG; FINITE_DELETE; FINITE_NUMSEG;
13385                  IN_DELETE] THEN
13386     MATCH_MP_TAC(REAL_FIELD `~(y = &0) ==> (y * x) * inv y = x`) THEN
13387     DISCH_TAC THEN
13388     UNDISCH_TAC `~(content(k:real^M->bool) = &0)` THEN
13389     ASM_REWRITE_TAC[content; PRODUCT_EQ_0_NUMSEG] THEN ASM_MESON_TAC[])
13390   and lemma1 = prove
13391    (`!d a b:real^M s i.
13392           d division_of s /\ s SUBSET interval[a,b] /\
13393           1 <= i /\ i <= dimindex(:M) /\
13394           ((!k. k IN d
13395                 ==> ~(content k = &0) /\ ~(k INTER {x | x$i = a$i} = {})) \/
13396            (!k. k IN d
13397                 ==> ~(content k = &0) /\ ~(k INTER {x | x$i = b$i} = {})))
13398           ==> (b$i - a$i) *
13399               sum d (\k. content k /
13400                          (interval_upperbound k$i - interval_lowerbound k$i))
13401               <= content(interval[a,b])`,
13402     REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
13403     FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
13404     ABBREV_TAC
13405      `extend =
13406       \k:real^M->bool. interval
13407            [(lambda j. if j = i then (a:real^M)$i
13408                        else interval_lowerbound k$j):real^M,
13409             (lambda j. if j = i then (b:real^M)$i
13410                        else interval_upperbound k$j)]` THEN
13411     SUBGOAL_THEN `!k. k IN d ==> k SUBSET interval[a:real^M,b]`
13412     ASSUME_TAC THENL
13413      [RULE_ASSUM_TAC(REWRITE_RULE[division_of]) THEN ASM SET_TAC[];
13414       ALL_TAC] THEN
13415     SUBGOAL_THEN `!k:real^M->bool. k IN d ==> ~(k = {})` ASSUME_TAC THENL
13416      [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
13417     SUBGOAL_THEN
13418      `(!k. k IN d ==> ~((extend:(real^M->bool)->(real^M->bool)) k = {})) /\
13419       (!k. k IN d ==> extend k SUBSET interval[a,b])`
13420     STRIP_ASSUME_TAC THENL
13421      [FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
13422       CONJ_TAC THEN MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN
13423       (DISCH_TAC THEN EXPAND_TAC "extend" THEN
13424        SUBGOAL_THEN `interval[u:real^M,v] SUBSET interval[a,b]` MP_TAC THENL
13425         [ASM_SIMP_TAC[]; ALL_TAC] THEN
13426        SUBGOAL_THEN `~(interval[u:real^M,v] = {})` MP_TAC THENL
13427         [ASM_SIMP_TAC[]; ALL_TAC] THEN
13428        SIMP_TAC[SUBSET_INTERVAL; INTERVAL_NE_EMPTY; LAMBDA_BETA;
13429                 INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN
13430        MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL]);
13431       ALL_TAC] THEN
13432     SUBGOAL_THEN
13433      `!k1 k2. k1 IN d /\ k2 IN d /\ ~(k1 = k2)
13434               ==> interior((extend:(real^M->bool)->(real^M->bool)) k1) INTER
13435                   interior(extend k2) = {}`
13436     ASSUME_TAC THENL
13437      [REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
13438       FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
13439       MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN DISCH_TAC THEN
13440       MAP_EVERY X_GEN_TAC [`w:real^M`; `z:real^M`] THEN DISCH_TAC THEN
13441       DISCH_TAC THEN
13442       FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
13443       DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN DISCH_THEN(MP_TAC o SPECL
13444        [`interval[u:real^M,v]`; `interval[w:real^M,z]`]) THEN
13445       ASM_REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN
13446       ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
13447       REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN
13448       EXPAND_TAC "extend" THEN
13449       SIMP_TAC[INTERIOR_CLOSED_INTERVAL; IN_INTERVAL; LAMBDA_BETA] THEN
13450       SUBGOAL_THEN `~(interval[u:real^M,v] = {}) /\
13451                     ~(interval[w:real^M,z] = {})`
13452       MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
13453       SIMP_TAC[SUBSET_INTERVAL; INTERVAL_NE_EMPTY; LAMBDA_BETA;
13454                INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN
13455       STRIP_TAC THEN DISCH_THEN(X_CHOOSE_THEN `x:real^M` MP_TAC) THEN
13456       MP_TAC(MESON[]
13457        `(!P. (!j:num. P j) <=> P i /\ (!j. ~(j = i) ==> P j))`) THEN
13458       DISCH_THEN(fun th -> GEN_REWRITE_TAC
13459        (LAND_CONV o ONCE_DEPTH_CONV) [th]) THEN
13460       ASM_SIMP_TAC[IMP_IMP] THEN STRIP_TAC THEN
13461       FIRST_X_ASSUM(DISJ_CASES_THEN
13462        (fun th -> MP_TAC(SPEC `interval[u:real^M,v]` th) THEN
13463                   MP_TAC(SPEC `interval[w:real^M,z]` th))) THEN
13464       ASM_REWRITE_TAC[CONTENT_EQ_0_INTERIOR; INTERIOR_CLOSED_INTERVAL] THEN
13465       REWRITE_TAC[IMP_CONJ; GSYM MEMBER_NOT_EMPTY; IN_INTER; IN_ELIM_THM] THEN
13466       REWRITE_TAC[IN_INTERVAL; LEFT_IMP_EXISTS_THM] THEN
13467       X_GEN_TAC `q:real^M` THEN STRIP_TAC THEN
13468       X_GEN_TAC `r:real^M` THEN STRIP_TAC THEN
13469       X_GEN_TAC `s:real^M` THEN STRIP_TAC THEN
13470       X_GEN_TAC `t:real^M` THEN STRIP_TAC THENL
13471        [EXISTS_TAC `(lambda j. if j = i then min ((q:real^M)$i) ((s:real^M)$i)
13472                                else (x:real^M)$j):real^M`;
13473         EXISTS_TAC `(lambda j. if j = i then max ((q:real^M)$i) ((s:real^M)$i)
13474                                else (x:real^M)$j):real^M`] THEN
13475       (SIMP_TAC[AND_FORALL_THM; LAMBDA_BETA] THEN X_GEN_TAC `j:num` THEN
13476        ASM_CASES_TAC `j:num = i` THEN ASM_SIMP_TAC[] THEN
13477        UNDISCH_THEN `j:num = i` SUBST_ALL_TAC THEN
13478        SUBGOAL_THEN `interval[u:real^M,v] SUBSET interval[a,b] /\
13479                      interval[w:real^M,z] SUBSET interval[a,b]`
13480        MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
13481        SUBGOAL_THEN `~(interval[u:real^M,v] = {}) /\
13482                      ~(interval[w:real^M,z] = {})`
13483        MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
13484        SIMP_TAC[INTERVAL_NE_EMPTY; SUBSET_INTERVAL] THEN
13485        REPEAT STRIP_TAC THEN
13486        REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN ASM_REWRITE_TAC[] THEN
13487        ASM_REAL_ARITH_TAC);
13488       ALL_TAC] THEN
13489     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
13490      `sum (IMAGE (extend:(real^M->bool)->(real^M->bool)) d) content` THEN
13491     CONJ_TAC THENL
13492      [W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE_NONZERO o rand o snd) THEN
13493       ANTS_TAC THENL
13494        [ASM_REWRITE_TAC[] THEN
13495         MAP_EVERY X_GEN_TAC [`k1:real^M->bool`; `k2:real^M->bool`] THEN
13496         STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL
13497          [`k1:real^M->bool`; `k2:real^M->bool`]) THEN
13498         ASM_REWRITE_TAC[INTER_IDEMPOT] THEN
13499         EXPAND_TAC "extend" THEN REWRITE_TAC[CONTENT_EQ_0_INTERIOR];
13500         DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[GSYM SUM_LMUL] THEN
13501         MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[] THEN
13502         FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
13503         MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN DISCH_TAC THEN
13504         ASM_CASES_TAC `content(interval[u:real^M,v]) = &0` THENL
13505          [ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO; REAL_MUL_RZERO; o_THM] THEN
13506           EXPAND_TAC "extend" THEN REWRITE_TAC[CONTENT_POS_LE];
13507           ALL_TAC] THEN
13508         FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM CONTENT_LT_NZ]) THEN
13509         DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
13510         REWRITE_TAC[CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
13511         ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND;
13512                      REAL_LT_IMP_LE; real_div; REAL_MUL_ASSOC] THEN
13513         ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ; REAL_SUB_LT] THEN
13514         SUBGOAL_THEN
13515          `~((extend:(real^M->bool)->(real^M->bool)) (interval[u,v]) = {})`
13516         MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
13517         EXPAND_TAC "extend" THEN ASM_SIMP_TAC[content; o_THM] THEN
13518         ASM_SIMP_TAC[INTERVAL_NE_EMPTY; INTERVAL_LOWERBOUND;
13519                      INTERVAL_UPPERBOUND; REAL_LT_IMP_LE] THEN
13520         DISCH_THEN(K ALL_TAC) THEN
13521         SUBGOAL_THEN
13522          `1..dimindex(:M) = i INSERT ((1..dimindex(:M)) DELETE i)`
13523         SUBST1_TAC THENL
13524          [MATCH_MP_TAC(SET_RULE `x IN s ==> s = x INSERT (s DELETE x)`) THEN
13525           ASM_REWRITE_TAC[IN_NUMSEG];
13526           ALL_TAC] THEN
13527         SIMP_TAC[PRODUCT_CLAUSES; FINITE_NUMSEG; FINITE_DELETE] THEN
13528         ASM_SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA] THEN
13529         MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC(REAL_RING
13530           `x:real = y ==> ab * uv * x = (ab * y) * uv`) THEN
13531         MATCH_MP_TAC PRODUCT_EQ THEN
13532         SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA]];
13533       MATCH_MP_TAC SUBADDITIVE_CONTENT_DIVISION THEN EXISTS_TAC
13534        `UNIONS (IMAGE (extend:(real^M->bool)->(real^M->bool)) d)` THEN
13535       ASM_SIMP_TAC[UNIONS_SUBSET; division_of; FINITE_IMAGE] THEN
13536       REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
13537       FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
13538       REPEAT CONJ_TAC THEN MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN
13539       DISCH_TAC THENL
13540        [CONJ_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[]] THEN
13541         EXPAND_TAC "extend" THEN REWRITE_TAC[] THEN MESON_TAC[];
13542         ASM_MESON_TAC[];
13543         ASM_SIMP_TAC[]]]) in
13544   REPEAT STRIP_TAC THEN
13545   ASM_CASES_TAC `content(interval[a:real^M,b]) = &0` THENL
13546    [MATCH_MP_TAC(REAL_ARITH `x = &0 /\ &0 <= y ==> x <= &2 * y`) THEN
13547     REWRITE_TAC[CONTENT_POS_LE; REAL_ENTIRE] THEN DISJ2_TAC THEN
13548     MATCH_MP_TAC SUM_EQ_0 THEN X_GEN_TAC `k:real^M->bool` THEN
13549     DISCH_TAC THEN REWRITE_TAC[real_div; REAL_ENTIRE] THEN DISJ1_TAC THEN
13550     MATCH_MP_TAC CONTENT_0_SUBSET THEN
13551     MAP_EVERY EXISTS_TAC [`a:real^M`; `b:real^M`] THEN
13552     ASM_MESON_TAC[division_of; SUBSET_TRANS];
13553     ALL_TAC] THEN
13554   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM CONTENT_LT_NZ]) THEN
13555   DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
13556   REWRITE_TAC[CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
13557   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
13558   MP_TAC(ISPECL
13559    [`{k | k IN {l INTER {x | x$i <= c} | l |
13560                 l IN d /\ ~(l INTER {x:real^M | x$i <= c} = {})} /\
13561           ~(content k = &0)}`;
13562     `a:real^M`;
13563     `(lambda j. if j = i then c else (b:real^M)$j):real^M`;
13564     `UNIONS {k | k IN {l INTER {x | x$i <= c} | l |
13565                        l IN d /\ ~(l INTER {x:real^M | x$i <= c} = {})} /\
13566                  ~(content k = &0)}`;
13567     `i:num`] lemma1) THEN
13568   MP_TAC(ISPECL
13569    [`{k | k IN {l INTER {x | x$i >= c} | l |
13570                 l IN d /\ ~(l INTER {x:real^M | x$i >= c} = {})} /\
13571           ~(content k = &0)}`;
13572     `(lambda j. if j = i then c else (a:real^M)$j):real^M`;
13573     `b:real^M`;
13574     `UNIONS {k | k IN {l INTER {x | x$i >= c} | l |
13575                        l IN d /\ ~(l INTER {x:real^M | x$i >= c} = {})} /\
13576                  ~(content k = &0)}`;
13577     `i:num`] lemma1) THEN
13578   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT
13579    `(p1 /\ p2) /\ (q1 /\ q2 ==> r) ==> (p2 ==> q2) ==> (p1 ==> q1) ==> r`) THEN
13580   CONJ_TAC THENL
13581    [CONJ_TAC THEN
13582     (REPEAT CONJ_TAC THENL
13583      [REWRITE_TAC[division_of] THEN CONJ_TAC THENL
13584        [MATCH_MP_TAC FINITE_RESTRICT THEN
13585         ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
13586         MATCH_MP_TAC FINITE_IMAGE THEN MATCH_MP_TAC FINITE_RESTRICT THEN
13587         ASM_REWRITE_TAC[];
13588         ALL_TAC] THEN
13589       REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
13590       CONJ_TAC THENL
13591        [FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
13592         MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN
13593         REPEAT DISCH_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
13594          [REWRITE_TAC[IN_ELIM_THM; SUBSET; IN_UNIONS] THEN ASM_MESON_TAC[];
13595           ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MESON_TAC[]];
13596         X_GEN_TAC `k:real^M->bool` THEN REPEAT DISCH_TAC THEN
13597         X_GEN_TAC `l:real^M->bool` THEN REPEAT DISCH_TAC THEN
13598         FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
13599         DISCH_THEN(MP_TAC o SPECL [`k:real^M->bool`; `l:real^M->bool`] o
13600           el 2 o CONJUNCTS) THEN
13601         ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
13602         MATCH_MP_TAC(SET_RULE
13603          `s SUBSET s' /\ t SUBSET t'
13604           ==> s' INTER t' = {} ==> s INTER t = {}`) THEN
13605         CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]];
13606       REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC; IMP_CONJ] THEN
13607       X_GEN_TAC `k:real^M->bool` THEN REPEAT DISCH_TAC THEN
13608       SUBGOAL_THEN `k SUBSET interval[a:real^M,b]` MP_TAC THENL
13609        [ASM_MESON_TAC[division_of; SUBSET_TRANS]; ALL_TAC] THEN
13610       MATCH_MP_TAC(SET_RULE
13611        `i INTER h SUBSET j ==> k SUBSET i ==> k INTER h SUBSET j`) THEN
13612       ASM_SIMP_TAC[INTERVAL_SPLIT; SUBSET_INTERVAL; LAMBDA_BETA] THEN
13613       MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
13614       REAL_ARITH_TAC;
13615       ALL_TAC])
13616     THENL [DISJ2_TAC; DISJ1_TAC] THEN
13617     REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ] THEN
13618     ASM_SIMP_TAC[LAMBDA_BETA; real_ge] THEN ASM SET_TAC[REAL_LE_REFL];
13619     ASM_SIMP_TAC[LAMBDA_BETA]] THEN
13620   SUBGOAL_THEN
13621    `sum {k | k IN
13622              { l INTER {x | x$i <= c} | l |
13623                l IN d /\ ~(l INTER {x:real^M | x$i <= c} = {})} /\
13624              ~(content k = &0)}
13625         (\k. content k /
13626              (interval_upperbound k$i - interval_lowerbound k$i)) =
13627     sum d ((\k. content k /
13628              (interval_upperbound k$i - interval_lowerbound k$i)) o
13629            (\k. k INTER {x | x$i <= c})) /\
13630     sum {k | k IN
13631              { l INTER {x | x$i >= c} | l |
13632                l IN d /\ ~(l INTER {x:real^M | x$i >= c} = {})} /\
13633              ~(content k = &0)}
13634         (\k. content k /
13635              (interval_upperbound k$i - interval_lowerbound k$i)) =
13636     sum d ((\k. content k /
13637              (interval_upperbound k$i - interval_lowerbound k$i)) o
13638            (\k. k INTER {x | x$i >= c}))`
13639   (CONJUNCTS_THEN SUBST1_TAC) THENL
13640    [CONJ_TAC THEN
13641     (W(MP_TAC o PART_MATCH (rand o rand) SUM_IMAGE_NONZERO o rand o snd) THEN
13642      ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
13643       [MAP_EVERY X_GEN_TAC [`k:real^M->bool`; `l:real^M->bool`] THEN
13644        STRIP_TAC THEN
13645        REWRITE_TAC[real_div; REAL_ENTIRE] THEN DISJ1_TAC THEN
13646        (MATCH_MP_TAC DIVISION_SPLIT_LEFT_INJ ORELSE
13647         MATCH_MP_TAC DIVISION_SPLIT_RIGHT_INJ) THEN ASM_MESON_TAC[];
13648        DISCH_THEN(SUBST1_TAC o SYM) THEN CONV_TAC SYM_CONV THEN
13649        MATCH_MP_TAC SUM_SUPERSET THEN CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
13650        GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
13651         `x IN IMAGE f d /\
13652          ~(x IN {x | x IN {f y |y| y IN d /\ ~(f y = a)} /\ ~P x})
13653          ==> (!y. f y = a ==> P(f y)) ==> P x`)) THEN
13654        SIMP_TAC[CONTENT_EMPTY; real_div; REAL_MUL_LZERO]]);
13655      ALL_TAC] THEN
13656   MAP_EVERY (fun (t,tac) ->
13657     ASM_CASES_TAC t THENL
13658      [FIRST_X_ASSUM SUBST_ALL_TAC THEN DISCH_THEN(MP_TAC o tac) THEN
13659       MATCH_MP_TAC(REAL_ARITH `x = y /\ a <= b ==> x <= a ==> y <= b`) THEN
13660       CONJ_TAC THENL
13661        [AP_TERM_TAC THEN MATCH_MP_TAC SUM_EQ THEN
13662         X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
13663         PURE_REWRITE_TAC[o_THM] THEN AP_TERM_TAC THEN
13664         REWRITE_TAC[real_ge; SET_RULE
13665          `k INTER {x | P x} = k <=> (!x. x IN k ==> P x)`] THEN
13666         X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
13667         SUBGOAL_THEN `x IN interval[a:real^M,b]` MP_TAC THENL
13668          [ASM_MESON_TAC[SUBSET; division_of]; ALL_TAC] THEN
13669         ASM_SIMP_TAC[IN_INTERVAL];
13670         MATCH_MP_TAC(REAL_ARITH `&0 <= y /\ x <= y ==> x <= &2 * y`) THEN
13671         REWRITE_TAC[CONTENT_POS_LE] THEN MATCH_MP_TAC CONTENT_SUBSET THEN
13672         SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN
13673         MESON_TAC[REAL_LE_REFL]];
13674       ALL_TAC])
13675     [`c = (a:real^M)$i`,CONJUNCT2; `c = (b:real^M)$i`,CONJUNCT1] THEN
13676   SUBGOAL_THEN `(a:real^M)$i < c /\ c < (b:real^M)$i` STRIP_ASSUME_TAC THENL
13677    [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
13678   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
13679   ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN
13680   REWRITE_TAC[REAL_ARITH `(x * &2) / y = &2 * x / y`] THEN
13681   MATCH_MP_TAC(REAL_ARITH
13682    `s <= s1 + s2 /\ c1 = c /\ c2 = c
13683     ==> s1 <= c1 /\ s2 <= c2 ==> s <= &2 * c`) THEN
13684   CONJ_TAC THENL
13685    [ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN
13686     ASM_SIMP_TAC[lemma0] THEN
13687     FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
13688     MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN DISCH_TAC THEN
13689     SUBGOAL_THEN
13690      `~(interval[u:real^M,v] = {}) /\ interval[u,v] SUBSET interval[a,b]`
13691     MP_TAC THENL [ASM_MESON_TAC[division_of; SUBSET_TRANS]; ALL_TAC] THEN
13692     SIMP_TAC[INTERVAL_NE_EMPTY; SUBSET_INTERVAL; IMP_CONJ] THEN
13693     REPEAT STRIP_TAC THEN REWRITE_TAC[o_THM] THEN
13694     MATCH_MP_TAC(REAL_ARITH
13695      `&0 <= x /\ c1 + c2 = c /\
13696       (~(c1 = &0) ==> x1 = x) /\ (~(c2 = &0) ==> x2 = x)
13697       ==> (if c = &0 then &0 else x) <=
13698           (if c1 = &0 then &0 else x1) +
13699           (if c2 = &0 then &0 else x2)`) THEN
13700     ASM_SIMP_TAC[GSYM CONTENT_SPLIT] THEN
13701     ASM_SIMP_TAC[INTERVAL_SPLIT; CONTENT_POS_LE] THEN CONJ_TAC THENL
13702      [MATCH_MP_TAC PRODUCT_POS_LE THEN
13703       ASM_SIMP_TAC[FINITE_DELETE; FINITE_NUMSEG; IN_DELETE; IN_NUMSEG;
13704                    INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_SUB_LE];
13705       REWRITE_TAC[CONTENT_EQ_0; REAL_NOT_LE; MESON[]
13706        `~(?i. P i /\ Q i /\ R i) <=> (!i. P i /\ Q i ==> ~R i)`] THEN
13707       SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_LT_IMP_LE] THEN
13708       REPEAT STRIP_TAC THEN MATCH_MP_TAC PRODUCT_EQ THEN
13709       ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; IN_DELETE;
13710                    IN_NUMSEG; LAMBDA_BETA]];
13711     SUBGOAL_THEN
13712      `~(interval[a,b] = {}) /\
13713       ~(interval[a:real^M,(lambda j. if j = i then c else b$j)] = {}) /\
13714       ~(interval[(lambda j. if j = i then c else a$j):real^M,b] = {})`
13715     MP_TAC THENL
13716      [SIMP_TAC[INTERVAL_NE_EMPTY; LAMBDA_BETA] THEN
13717       ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_LE_REFL];
13718       ALL_TAC] THEN
13719     SIMP_TAC[content] THEN
13720     SIMP_TAC[INTERVAL_NE_EMPTY; INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND] THEN
13721     STRIP_TAC THEN
13722     SUBGOAL_THEN
13723      `1..dimindex(:M) = i INSERT ((1..dimindex(:M)) DELETE i)`
13724     SUBST1_TAC THENL
13725      [MATCH_MP_TAC(SET_RULE `x IN s ==> s = x INSERT (s DELETE x)`) THEN
13726       ASM_REWRITE_TAC[IN_NUMSEG];
13727       ALL_TAC] THEN
13728     SIMP_TAC[PRODUCT_CLAUSES; FINITE_NUMSEG; FINITE_DELETE] THEN
13729     ASM_SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA] THEN
13730     CONJ_TAC THEN MATCH_MP_TAC(REAL_FIELD
13731      `y < x /\ z < w /\ a = b
13732       ==> ((x - y) * a) / (x - y) = ((w - z) * b) / (w - z)`) THEN
13733     ASM_SIMP_TAC[] THEN MATCH_MP_TAC PRODUCT_EQ THEN
13734     SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA]]);;
13735
13736 let BOUNDED_EQUIINTEGRAL_OVER_THIN_TAGGED_PARTIAL_DIVISION = prove
13737  (`!fs f:real^M->real^N a b e.
13738     fs equiintegrable_on interval[a,b] /\ f IN fs /\
13739     (!h x. h IN fs /\ x IN interval[a,b] ==> norm(h x) <= norm(f x)) /\
13740     &0 < e
13741     ==> ?d. gauge d /\
13742             !c i p h. c IN interval[a,b] /\ 1 <= i /\ i <= dimindex(:M) /\
13743                       p tagged_partial_division_of interval[a,b] /\
13744                       d fine p /\
13745                       h IN fs /\
13746                       (!x k. (x,k) IN p ==> ~(k INTER {x | x$i = c$i} = {}))
13747                       ==> sum p(\(x,k). norm(integral k h)) < e`,
13748   REPEAT STRIP_TAC THEN
13749   ASM_CASES_TAC `content(interval[a:real^M,b]) = &0` THENL
13750    [EXISTS_TAC `\x:real^M. ball(x,&1)` THEN REWRITE_TAC[GAUGE_TRIVIAL] THEN
13751     REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
13752      `&0 < e ==> x = &0 ==> x < e`)) THEN
13753     MATCH_MP_TAC SUM_EQ_0 THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
13754     GEN_TAC THEN X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
13755     SUBGOAL_THEN
13756      `?u v:real^M. k = interval[u,v] /\ interval[u,v] SUBSET interval[a,b]`
13757     STRIP_ASSUME_TAC THENL
13758      [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
13759     ASM_REWRITE_TAC[NORM_EQ_0] THEN MATCH_MP_TAC INTEGRAL_NULL THEN
13760     ASM_MESON_TAC[CONTENT_0_SUBSET];
13761     ALL_TAC] THEN
13762   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM CONTENT_LT_NZ]) THEN
13763   DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
13764   REWRITE_TAC[CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
13765   SUBGOAL_THEN
13766    `?d. gauge d /\
13767         !p h. p tagged_partial_division_of interval [a,b] /\
13768               d fine p /\ (h:real^M->real^N) IN fs
13769               ==> sum p (\(x,k). norm(content k % h x - integral k h)) <
13770                   e / &2`
13771    (X_CHOOSE_THEN `g0:real^M->real^M->bool` STRIP_ASSUME_TAC)
13772   THENL
13773    [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [equiintegrable_on]) THEN
13774     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC
13775       `e / &5 / (&(dimindex(:N)) + &1)`)) THEN
13776     ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &5 /\ &0 < &n + &1`] THEN
13777     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^M->real^M->bool` THEN
13778     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MAP_EVERY X_GEN_TAC
13779      [`p:(real^M#(real^M->bool))->bool`; `h:real^M->real^N`] THEN
13780     STRIP_TAC THEN
13781     MP_TAC(ISPECL [`h:real^M->real^N`; `a:real^M`; `b:real^M`;
13782            `g:real^M->real^M->bool`; `e / &5 / (&(dimindex(:N)) + &1)`]
13783         HENSTOCK_LEMMA_PART2) THEN
13784     ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &5 /\ &0 < &n + &1`] THEN
13785     DISCH_THEN(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN
13786     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
13787      `a < b ==> x <= a ==> x < b`) THEN
13788     REWRITE_TAC[REAL_ARITH `&2 * d * e / &5 / (d + &1) =
13789                             (e * &2 / &5 * d) / (d + &1)`] THEN
13790     SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
13791     MATCH_MP_TAC(REAL_ARITH
13792      `&0 < e /\ &0 < e * d ==> e * &2 / &5 * d < e / &2 * (d + &1)`) THEN
13793     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_MUL THEN
13794     ASM_SIMP_TAC[REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1];
13795     ALL_TAC] THEN
13796   ABBREV_TAC
13797    `g:real^M->real^M->bool =
13798        \x. g0(x) INTER
13799            ball(x,(e / &8 / (norm(f x:real^N) + &1)) *
13800                   inf(IMAGE (\m. b$m - a$m) (1..dimindex(:M))) /
13801                   content(interval[a:real^M,b]))` THEN
13802   SUBGOAL_THEN `gauge(g:real^M->real^M->bool)` ASSUME_TAC THENL
13803    [EXPAND_TAC "g" THEN MATCH_MP_TAC GAUGE_INTER THEN ASM_REWRITE_TAC[] THEN
13804     REWRITE_TAC[gauge; OPEN_BALL; CENTRE_IN_BALL] THEN
13805     X_GEN_TAC `x:real^M` THEN MATCH_MP_TAC REAL_LT_MUL THEN
13806     ASM_SIMP_TAC[REAL_LT_DIV; NORM_ARITH
13807      `&0 < &8 /\ &0 < norm(x:real^N) + &1`] THEN
13808     MATCH_MP_TAC REAL_LT_DIV THEN ASM_REWRITE_TAC[] THEN
13809     W(MP_TAC o PART_MATCH (lhand o rand) REAL_LT_INF_FINITE o snd) THEN
13810     ANTS_TAC THENL
13811      [ASM_SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; FINITE_RESTRICT] THEN
13812       SIMP_TAC[IMAGE_EQ_EMPTY; NUMSEG_EMPTY;
13813                GSYM NOT_LE; DIMINDEX_GE_1] THEN
13814       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CART_EQ]) THEN
13815       REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; IN_NUMSEG] THEN
13816       MESON_TAC[];
13817       DISCH_THEN SUBST1_TAC THEN
13818       REWRITE_TAC[FORALL_IN_IMAGE] THEN
13819       ASM_SIMP_TAC[REAL_SUB_LT; IN_NUMSEG; GSYM REAL_ABS_NZ; REAL_SUB_0;
13820                    IN_ELIM_THM]];
13821     ALL_TAC] THEN
13822   EXISTS_TAC `g:real^M->real^M->bool` THEN ASM_REWRITE_TAC[] THEN
13823   MAP_EVERY X_GEN_TAC
13824    [`c:real^M`; `i:num`; `p:(real^M#(real^M->bool))->bool`;
13825     `h:real^M->real^N`] THEN
13826   STRIP_TAC THEN
13827   SUBGOAL_THEN
13828    `interval[c:real^M,b] SUBSET interval[a,b]`
13829   ASSUME_TAC THENL
13830    [UNDISCH_TAC `c IN interval[a:real^M,b]` THEN
13831     SIMP_TAC[IN_INTERVAL; SUBSET_INTERVAL; REAL_LE_REFL];
13832     ALL_TAC] THEN
13833   SUBGOAL_THEN `FINITE(p:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
13834    [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
13835   MP_TAC(ASSUME `(g:real^M->real^M->bool) fine p`) THEN
13836   EXPAND_TAC "g" THEN REWRITE_TAC[FINE_INTER] THEN
13837   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "F")) THEN
13838   FIRST_X_ASSUM(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN
13839   DISCH_THEN(MP_TAC o SPEC `h:real^M->real^N`) THEN
13840   ANTS_TAC THENL
13841    [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_SUBSET]; ALL_TAC] THEN
13842   MATCH_MP_TAC(REAL_ARITH
13843    `x - y <= e / &2 ==> y < e / &2 ==> x < e`) THEN
13844   ASM_SIMP_TAC[GSYM SUM_SUB] THEN
13845   ONCE_REWRITE_TAC[LAMBDA_PAIR_THM] THEN REWRITE_TAC[] THEN
13846   MATCH_MP_TAC REAL_LE_TRANS THEN
13847   EXISTS_TAC
13848    `sum p (\(x:real^M,k:real^M->bool). norm(content k % h x:real^N))` THEN
13849   CONJ_TAC THENL
13850    [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
13851     REWRITE_TAC[NORM_ARITH `norm y - norm(x - y:real^N) <= norm x`];
13852     ALL_TAC] THEN
13853   MATCH_MP_TAC REAL_LE_TRANS THEN
13854   EXISTS_TAC
13855    `sum p (\(x:real^M,k).
13856                    e / &4 * (b$i - a$i) / content(interval[a:real^M,b]) *
13857                    content(k:real^M->bool) /
13858                    (interval_upperbound k$i - interval_lowerbound k$i))` THEN
13859   CONJ_TAC THENL
13860    [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
13861     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
13862     ASM_CASES_TAC `content(k:real^M->bool) = &0` THENL
13863      [ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO; VECTOR_MUL_LZERO; NORM_0;
13864                       REAL_MUL_RZERO; REAL_LE_REFL];
13865       ALL_TAC] THEN
13866     REWRITE_TAC[REAL_ARITH `a * b * content k / d = content k * (a * b) / d`;
13867                 NORM_MUL] THEN
13868     SUBGOAL_THEN `&0 < content(k:real^M->bool)` ASSUME_TAC THENL
13869      [ASM_MESON_TAC[CONTENT_LT_NZ; tagged_partial_division_of]; ALL_TAC] THEN
13870     ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE; REAL_LE_LMUL_EQ] THEN
13871     MATCH_MP_TAC(REAL_ARITH `x + &1 <= y ==> x <= y`) THEN
13872     SUBGOAL_THEN `?u v. k = interval[u:real^M,v]` MP_TAC THENL
13873      [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
13874     DISCH_THEN(REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) THEN
13875     MP_TAC(ISPECL [`u:real^M`; `v:real^M`] CONTENT_POS_LT_EQ) THEN
13876     ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_LT_IMP_LE] THEN
13877     DISCH_TAC THEN
13878     W(MP_TAC o PART_MATCH (lhand o rand) REAL_LE_RDIV_EQ o snd) THEN
13879     ASM_SIMP_TAC[REAL_SUB_LT] THEN DISCH_THEN SUBST1_TAC THEN
13880     GEN_REWRITE_TAC LAND_CONV [REAL_MUL_SYM] THEN
13881     SIMP_TAC[GSYM REAL_LE_RDIV_EQ; NORM_ARITH `&0 < norm(x:real^N) + &1`] THEN
13882     REMOVE_THEN "F" MP_TAC THEN REWRITE_TAC[fine] THEN
13883     DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `interval[u:real^M,v]`]) THEN
13884     ASM_REWRITE_TAC[SUBSET] THEN
13885     DISCH_THEN(fun th -> MP_TAC(SPEC `v:real^M` th) THEN
13886                          MP_TAC(SPEC `u:real^M` th)) THEN
13887     ASM_SIMP_TAC[INTERVAL_NE_EMPTY; REAL_LT_IMP_LE; ENDS_IN_INTERVAL] THEN
13888     REWRITE_TAC[IN_BALL; IMP_IMP] THEN
13889     MATCH_MP_TAC(NORM_ARITH
13890      `abs(vi - ui) <= norm(v - u:real^N) /\ &2 * a <= b
13891       ==> dist(x,u) < a /\ dist(x,v) < a ==> vi - ui <= b`) THEN
13892     ASM_SIMP_TAC[GSYM VECTOR_SUB_COMPONENT; COMPONENT_LE_NORM] THEN
13893     REWRITE_TAC[REAL_ARITH `&2 * e / &8 / x * y = e / &4 * y / x`] THEN
13894     REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC] THEN
13895     MATCH_MP_TAC REAL_LE_LMUL THEN ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN
13896     MATCH_MP_TAC REAL_LE_LMUL THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
13897     ONCE_REWRITE_TAC[REAL_ARITH `a * inv b * inv c:real = (a / c) / b`] THEN
13898     ASM_SIMP_TAC[REAL_LE_DIV2_EQ] THEN
13899     MATCH_MP_TAC(REAL_ARITH `abs x <= e ==> x <= e`) THEN
13900     REWRITE_TAC[real_div; REAL_ABS_MUL] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
13901     REWRITE_TAC[REAL_ABS_POS] THEN CONJ_TAC THENL
13902      [MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= y ==> abs x <= y`) THEN
13903       SIMP_TAC[REAL_INF_LE_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY; FINITE_NUMSEG;
13904                NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1; REAL_LE_INF_FINITE] THEN
13905       REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE; IN_NUMSEG] THEN
13906       ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; REAL_LE_REFL; REAL_SUB_LE;
13907                    REAL_LT_IMP_LE] THEN
13908       ASM_MESON_TAC[REAL_LE_REFL];
13909       REWRITE_TAC[REAL_ABS_INV] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
13910       CONJ_TAC THENL [NORM_ARITH_TAC; ALL_TAC] THEN
13911       MATCH_MP_TAC(REAL_ARITH `x <= y ==> x + &1 <= abs(y + &1)`) THEN
13912       FIRST_X_ASSUM MATCH_MP_TAC THEN
13913       ASM_MESON_TAC[tagged_partial_division_of; SUBSET]];
13914     ALL_TAC] THEN
13915   FIRST_ASSUM(MP_TAC o MATCH_MP TAGGED_PARTIAL_DIVISION_OF_UNION_SELF) THEN
13916   DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
13917     SUM_OVER_TAGGED_DIVISION_LEMMA)) THEN
13918   DISCH_THEN(fun th ->
13919     W(MP_TAC o PART_MATCH (lhs o rand) th o lhand o snd)) THEN
13920   REWRITE_TAC[] THEN ANTS_TAC THENL
13921    [SIMP_TAC[real_div; REAL_MUL_LZERO; REAL_MUL_RZERO];
13922     DISCH_THEN SUBST1_TAC] THEN
13923   REWRITE_TAC[SUM_LMUL; REAL_ARITH
13924    `e / &4 * ba / c * s <= e / &2 <=> e * (ba * s) / c <= e * &2`] THEN
13925   ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN ASM_SIMP_TAC[REAL_LE_LDIV_EQ] THEN
13926   MATCH_MP_TAC SUM_CONTENT_AREA_OVER_THIN_DIVISION THEN
13927   EXISTS_TAC `UNIONS(IMAGE SND (p:(real^M#(real^M->bool))->bool))` THEN
13928   EXISTS_TAC `(c:real^M)$i` THEN
13929   RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN ASM_SIMP_TAC[] THEN
13930   REPEAT CONJ_TAC THENL
13931    [MATCH_MP_TAC DIVISION_OF_TAGGED_DIVISION THEN
13932     ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF];
13933     REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN
13934     ASM_MESON_TAC[tagged_partial_division_of];
13935     ASM_REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM]]);;
13936
13937 let EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE = prove
13938  (`!fs f:real^M->real^N a b.
13939         fs equiintegrable_on interval[a,b] /\ f IN fs /\
13940         (!h x. h IN fs /\ x IN interval[a,b] ==> norm(h x) <= norm(f x))
13941         ==> { (\x. if x$i <= c then h x else vec 0) |
13942               i IN 1..dimindex(:M) /\ c IN (:real) /\ h IN fs }
13943             equiintegrable_on interval[a,b]`,
13944   let lemma = prove
13945    (`(!x k. (x,k) IN IMAGE (\(x,k). f x k,g x k) s ==> Q x k) <=>
13946      (!x k. (x,k) IN s ==> Q (f x k) (g x k))`,
13947     REWRITE_TAC[IN_IMAGE; PAIR_EQ; EXISTS_PAIR_THM] THEN SET_TAC[]) in
13948   REPEAT STRIP_TAC THEN
13949   ASM_CASES_TAC `content(interval[a:real^M,b]) = &0` THEN
13950   ASM_SIMP_TAC[EQUIINTEGRABLE_ON_NULL] THEN
13951   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM CONTENT_LT_NZ]) THEN
13952   DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
13953   REWRITE_TAC[CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
13954   REWRITE_TAC[equiintegrable_on] THEN
13955   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
13956   REWRITE_TAC[IN_UNIV; IMP_IMP; GSYM CONJ_ASSOC; RIGHT_IMP_FORALL_THM;
13957               IN_NUMSEG] THEN
13958   FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o REWRITE_RULE[equiintegrable_on]) THEN
13959   MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
13960    [REPEAT GEN_TAC THEN
13961     ONCE_REWRITE_TAC[SET_RULE `x$i <= c <=> x IN {x:real^N | x$i <= c}`] THEN
13962     REWRITE_TAC[INTEGRABLE_RESTRICT_INTER] THEN
13963     ONCE_REWRITE_TAC[INTER_COMM] THEN SIMP_TAC[INTERVAL_SPLIT] THEN
13964     REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
13965     EXISTS_TAC `interval[a:real^M,b]` THEN ASM_SIMP_TAC[] THEN
13966     SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA; REAL_LE_REFL] THEN
13967     REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
13968     REAL_ARITH_TAC;
13969     DISCH_TAC] THEN
13970   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
13971   MP_TAC(ISPECL [`fs:(real^M->real^N)->bool`; `f:real^M->real^N`;
13972                  `a:real^M`; `b:real^M`; `e / &12`]
13973         BOUNDED_EQUIINTEGRAL_OVER_THIN_TAGGED_PARTIAL_DIVISION) THEN
13974   ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &12`] THEN
13975   DISCH_THEN(X_CHOOSE_THEN `g0:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
13976   SUBGOAL_THEN
13977    `?d. gauge d /\
13978         !p h. p tagged_partial_division_of interval [a,b] /\
13979               d fine p /\ (h:real^M->real^N) IN fs
13980               ==> sum p (\(x,k). norm(content k % h x - integral k h)) <
13981                   e / &3`
13982    (X_CHOOSE_THEN `g1:real^M->real^M->bool` STRIP_ASSUME_TAC)
13983   THENL
13984    [FIRST_ASSUM(MP_TAC o CONJUNCT2 o REWRITE_RULE[equiintegrable_on]) THEN
13985     DISCH_THEN(MP_TAC o SPEC `e / &7 / (&(dimindex(:N)) + &1)`) THEN
13986     ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &7 /\ &0 < &n + &1`] THEN
13987     MATCH_MP_TAC MONO_EXISTS THEN
13988     X_GEN_TAC `d:real^M->real^M->bool` THEN STRIP_TAC THEN
13989     ASM_REWRITE_TAC[] THEN
13990     MAP_EVERY X_GEN_TAC
13991      [`p:(real^M#(real^M->bool))->bool`; `h:real^M->real^N`] THEN
13992     STRIP_TAC THEN
13993     MP_TAC(ISPECL [`h:real^M->real^N`; `a:real^M`; `b:real^M`;
13994            `d:real^M->real^M->bool`; `e / &7 / (&(dimindex(:N)) + &1)`]
13995         HENSTOCK_LEMMA_PART2) THEN
13996     ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &7 /\ &0 < &n + &1`] THEN
13997     DISCH_THEN(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN
13998     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
13999      `a < b ==> x <= a ==> x < b`) THEN
14000     REWRITE_TAC[REAL_ARITH `&2 * d * e / &7 / (d + &1) =
14001                             (e * &2 / &7 * d) / (d + &1)`] THEN
14002     SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
14003     MATCH_MP_TAC(REAL_ARITH
14004      `&0 < e /\ &0 < e * d ==> e * &2 / &7 * d < e / &3 * (d + &1)`) THEN
14005     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_MUL THEN
14006     ASM_SIMP_TAC[REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1];
14007     ALL_TAC] THEN
14008   EXISTS_TAC `\x. (g0:real^M->real^M->bool) x INTER g1 x` THEN
14009   ASM_SIMP_TAC[GAUGE_INTER; FINE_INTER] THEN
14010   X_GEN_TAC `i:num` THEN
14011   ASM_CASES_TAC `1 <= i` THEN ASM_REWRITE_TAC[] THEN
14012   ASM_CASES_TAC `i <= dimindex(:M)` THEN ASM_REWRITE_TAC[] THEN
14013   MP_TAC(MESON[]
14014    `!P. ((!c. (a:real^M)$i <= c /\ c <= (b:real^M)$i ==> P c) ==> (!c. P c)) /\
14015         (!c. (a:real^M)$i <= c /\ c <= (b:real^M)$i ==> P c)
14016         ==> !c. P c`) THEN
14017   DISCH_THEN MATCH_MP_TAC THEN CONJ_TAC THENL
14018    [DISCH_THEN(LABEL_TAC "*") THEN
14019     X_GEN_TAC `c:real` THEN
14020     ASM_CASES_TAC `(a:real^M)$i <= c /\ c <= (b:real^M)$i` THENL
14021      [REMOVE_THEN "*" MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN
14022     REMOVE_THEN "*" (MP_TAC o SPEC `(b:real^M)$i`) THEN
14023     ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL] THEN
14024     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `h:real^M->real^N` THEN
14025     MATCH_MP_TAC MONO_FORALL THEN
14026     X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN
14027     DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
14028     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DE_MORGAN_THM]) THEN
14029     REWRITE_TAC[REAL_NOT_LE] THEN STRIP_TAC THENL
14030      [DISCH_TAC THEN MATCH_MP_TAC(NORM_ARITH
14031        `x:real^N = vec 0 /\ y = vec 0 /\ &0 < e ==> norm(x - y) < e`) THEN
14032       ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
14033        [MATCH_MP_TAC VSUM_EQ_0 THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
14034         MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
14035         COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN
14036         SUBGOAL_THEN `(x:real^M) IN interval[a,b]` MP_TAC THENL
14037          [ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET]; ALL_TAC] THEN
14038         REWRITE_TAC[IN_INTERVAL] THEN
14039         DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
14040         ASM_REAL_ARITH_TAC;
14041         MATCH_MP_TAC EQ_TRANS THEN
14042         EXISTS_TAC `integral(interval[a,b]) ((\x. vec 0):real^M->real^N)` THEN
14043         CONJ_TAC THENL [ALL_TAC; REWRITE_TAC[INTEGRAL_0]] THEN
14044         MATCH_MP_TAC INTEGRAL_EQ THEN REWRITE_TAC[] THEN GEN_TAC THEN
14045         COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL] THEN
14046         DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
14047         ASM_REAL_ARITH_TAC];
14048       MATCH_MP_TAC(NORM_ARITH
14049        `x:real^N = y /\ w = z ==> norm(x - w) < e ==> norm(y - z) < e`) THEN
14050       CONJ_TAC THENL
14051        [MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
14052         MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
14053         SUBGOAL_THEN `(x:real^M) IN interval[a,b]` MP_TAC THENL
14054          [ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET]; ALL_TAC] THEN
14055         REWRITE_TAC[IN_INTERVAL] THEN
14056         DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
14057         STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
14058         COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN
14059         ASM_REAL_ARITH_TAC;
14060         MATCH_MP_TAC INTEGRAL_EQ THEN REWRITE_TAC[] THEN GEN_TAC THEN
14061         COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL] THEN
14062         DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
14063         ASM_REAL_ARITH_TAC]];
14064     ALL_TAC] THEN
14065   X_GEN_TAC `c:real` THEN DISCH_TAC THEN
14066   MAP_EVERY X_GEN_TAC [`h:real^M->real^N`;
14067                   `p:(real^M#(real^M->bool))->bool`] THEN STRIP_TAC THEN
14068   ABBREV_TAC
14069    `q:(real^M#(real^M->bool))->bool =
14070         {(x,k) | (x,k) IN p /\ ~(k INTER {x | x$i <= c} = {})}` THEN
14071   MP_TAC(ISPECL
14072    [`\x. if x$i <= c then (h:real^M->real^N) x else vec 0`;
14073     `a:real^M`; `b:real^M`; `p:(real^M#(real^M->bool))->bool`]
14074         INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN) THEN
14075   ASM_SIMP_TAC[] THEN DISCH_THEN SUBST1_TAC THEN
14076   SUBGOAL_THEN `FINITE(p:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
14077    [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
14078   SUBGOAL_THEN `q SUBSET (p:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
14079    [EXPAND_TAC "q" THEN SIMP_TAC[SUBSET; FORALL_PAIR_THM; IN_ELIM_PAIR_THM];
14080     ALL_TAC] THEN
14081   SUBGOAL_THEN `FINITE(q:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
14082    [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN
14083   ASM_SIMP_TAC[GSYM VSUM_SUB] THEN ONCE_REWRITE_TAC[LAMBDA_PAIR_THM] THEN
14084   REWRITE_TAC[] THEN
14085   SUBGOAL_THEN `q tagged_partial_division_of interval[a:real^M,b] /\
14086                 g0 fine q /\ g1 fine q`
14087   STRIP_ASSUME_TAC THENL
14088    [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_SUBSET; tagged_division_of;
14089                   FINE_SUBSET];
14090     ALL_TAC] THEN
14091   MATCH_MP_TAC(MESON[] `!q. vsum p s = vsum q s /\ norm(vsum q s) < e
14092                             ==> norm(vsum p s:real^N) < e`) THEN
14093   EXISTS_TAC `q:(real^M#(real^M->bool))->bool` THEN CONJ_TAC THENL
14094    [MATCH_MP_TAC VSUM_SUPERSET THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
14095     EXPAND_TAC "q" THEN REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
14096     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
14097     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
14098     SUBGOAL_THEN `(x:real^M) IN k` ASSUME_TAC THENL
14099      [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
14100     DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
14101     REWRITE_TAC[EXTENSION] THEN DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN
14102     REWRITE_TAC[IN_INTER; NOT_IN_EMPTY] THEN ASM_REWRITE_TAC[] THEN
14103     REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN
14104     ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN
14105     REWRITE_TAC[VECTOR_NEG_EQ_0; VECTOR_SUB_LZERO] THEN
14106     MATCH_MP_TAC EQ_TRANS THEN
14107     EXISTS_TAC `integral k ((\x. vec 0):real^M->real^N)` THEN
14108     CONJ_TAC THENL [ALL_TAC; REWRITE_TAC[INTEGRAL_0]] THEN
14109     MATCH_MP_TAC INTEGRAL_EQ THEN ASM SET_TAC[];
14110     ALL_TAC] THEN
14111   SUBGOAL_THEN
14112    `norm(vsum q (\(x,k). content k % h x - integral k (h:real^M->real^N)))
14113         < e / &3`
14114   MP_TAC THENL
14115    [MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `sum q
14116       (\(x,k). norm(content k % h x - integral k (h:real^M->real^N)))` THEN
14117     ASM_SIMP_TAC[] THEN MATCH_MP_TAC VSUM_NORM_LE THEN
14118     ASM_REWRITE_TAC[FORALL_PAIR_THM; REAL_LE_REFL];
14119     ALL_TAC] THEN
14120   MATCH_MP_TAC(NORM_ARITH
14121    `norm(x - y:real^N) <= &2 * e / &3
14122     ==> norm(x) < e / &3 ==> norm(y) < e`) THEN
14123   ASM_SIMP_TAC[GSYM VSUM_SUB] THEN ONCE_REWRITE_TAC[LAMBDA_PAIR_THM] THEN
14124   REWRITE_TAC[] THEN
14125   ABBREV_TAC
14126    `r:(real^M#(real^M->bool))->bool =
14127         {(x,k) | (x,k) IN q /\ ~(k SUBSET {x | x$i <= c})}` THEN
14128   SUBGOAL_THEN `r SUBSET (q:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
14129    [EXPAND_TAC "r" THEN SIMP_TAC[SUBSET; FORALL_PAIR_THM; IN_ELIM_PAIR_THM];
14130     ALL_TAC] THEN
14131   SUBGOAL_THEN `FINITE(r:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
14132    [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN
14133   SUBGOAL_THEN `r tagged_partial_division_of interval[a:real^M,b] /\
14134                 g0 fine r /\ g1 fine r`
14135   STRIP_ASSUME_TAC THENL
14136    [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_SUBSET; FINE_SUBSET];
14137     ALL_TAC] THEN
14138   MATCH_MP_TAC(MESON[] `!r. vsum q s = vsum r s /\ norm(vsum r s) <= e
14139                             ==> norm(vsum q s:real^N) <= e`) THEN
14140   EXISTS_TAC `r:(real^M#(real^M->bool))->bool` THEN CONJ_TAC THENL
14141    [MATCH_MP_TAC VSUM_SUPERSET THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
14142     EXPAND_TAC "r" THEN REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
14143     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
14144     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
14145     SUBGOAL_THEN `(x:real^M) IN k` ASSUME_TAC THENL
14146      [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
14147     DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
14148     REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN
14149     ASM_REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
14150     REWRITE_TAC[VECTOR_ARITH `c - i - (c - j):real^N = j - i`] THEN
14151     REWRITE_TAC[VECTOR_SUB_EQ] THEN MATCH_MP_TAC INTEGRAL_EQ THEN
14152     ASM SET_TAC[];
14153     ALL_TAC] THEN
14154   W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
14155   ASM_REWRITE_TAC[] THEN
14156   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
14157   ONCE_REWRITE_TAC[LAMBDA_PAIR_THM] THEN REWRITE_TAC[] THEN
14158   MAP_EVERY ABBREV_TAC
14159    [`s:(real^M#(real^M->bool))->bool =
14160         {(x,k) | (x,k) IN r /\ x IN {x | x$i <= c}}`;
14161     `t:(real^M#(real^M->bool))->bool =
14162         {(x,k) | (x,k) IN r /\ ~(x IN {x | x$i <= c})}`] THEN
14163   SUBGOAL_THEN
14164    `(s:(real^M#(real^M->bool))->bool) SUBSET r /\
14165     (t:(real^M#(real^M->bool))->bool) SUBSET r`
14166   STRIP_ASSUME_TAC THENL
14167    [MAP_EVERY EXPAND_TAC ["s"; "t"] THEN
14168     SIMP_TAC[SUBSET; FORALL_PAIR_THM; IN_ELIM_PAIR_THM];
14169     ALL_TAC] THEN
14170   SUBGOAL_THEN
14171    `FINITE(s:(real^M#(real^M->bool))->bool) /\
14172     FINITE(t:(real^M#(real^M->bool))->bool)`
14173   STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN
14174   SUBGOAL_THEN `DISJOINT (s:(real^M#(real^M->bool))->bool) t` ASSUME_TAC THENL
14175    [MAP_EVERY EXPAND_TAC ["s"; "t"] THEN
14176     REWRITE_TAC[EXTENSION; DISJOINT; IN_INTER; FORALL_PAIR_THM;
14177                 IN_ELIM_PAIR_THM] THEN SET_TAC[];
14178     ALL_TAC] THEN
14179   SUBGOAL_THEN `r:(real^M#(real^M->bool))->bool = s UNION t` SUBST1_TAC THENL
14180    [MAP_EVERY EXPAND_TAC ["s"; "t"] THEN
14181     REWRITE_TAC[EXTENSION; IN_UNION; FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN
14182     SET_TAC[];
14183     ALL_TAC] THEN
14184   ASM_SIMP_TAC[SUM_UNION] THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
14185    `sum s (\(x:real^M,k). norm
14186           (integral k (h:real^M->real^N) -
14187            integral k (\x. if x$i <= c then h x else vec 0))) +
14188     sum t (\(x:real^M,k). norm
14189           ((content k % (h:real^M->real^N) x - integral k h) +
14190            integral k (\x. if x$i <= c then h x else vec 0)))` THEN
14191   CONJ_TAC THENL
14192    [MATCH_MP_TAC REAL_EQ_IMP_LE THEN BINOP_TAC THEN
14193     MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
14194     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
14195     MAP_EVERY EXPAND_TAC ["s"; "t"] THEN
14196     REWRITE_TAC[IN_ELIM_PAIR_THM] THEN REWRITE_TAC[IN_ELIM_THM] THEN
14197     STRIP_TAC THEN ASM_REWRITE_TAC[] THENL
14198      [MATCH_MP_TAC(NORM_ARITH `a:real^N = --b ==> norm a = norm b`) THEN
14199       VECTOR_ARITH_TAC;
14200       AP_TERM_TAC THEN VECTOR_ARITH_TAC];
14201     ALL_TAC] THEN
14202   SUBGOAL_THEN `s tagged_partial_division_of interval[a:real^M,b] /\
14203                 t tagged_partial_division_of interval[a:real^M,b] /\
14204                 g0 fine s /\ g1 fine s /\ g0 fine t /\ g1 fine t`
14205   STRIP_ASSUME_TAC THENL
14206    [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_SUBSET; FINE_SUBSET];
14207     ALL_TAC] THEN
14208   MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
14209    `(sum s (\(x:real^M,k). norm(integral k (h:real^M->real^N))) +
14210      sum (IMAGE (\(x,k). (x,k INTER {x | x$i <= c})) s)
14211          (\(x:real^M,k). norm(integral k (h:real^M->real^N)))) +
14212     (sum t (\(x:real^M,k). norm(content k % h x - integral k h)) +
14213      sum t (\(x:real^M,k). norm(integral k (h:real^M->real^N))) +
14214      sum (IMAGE (\(x,k). (x,k INTER {x | x$i >= c})) t)
14215          (\(x:real^M,k). norm(integral k (h:real^M->real^N))))` THEN
14216   CONJ_TAC THENL
14217    [MATCH_MP_TAC REAL_LE_ADD2 THEN CONJ_TAC THENL
14218      [W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE_NONZERO o
14219         rand o rand o snd) THEN
14220       ANTS_TAC THENL
14221        [ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
14222         MAP_EVERY X_GEN_TAC
14223          [`x:real^M`; `k:real^M->bool`; `y:real^M`; `l:real^M->bool`] THEN
14224         ASM_CASES_TAC `x:real^M = y` THEN ASM_REWRITE_TAC[PAIR_EQ] THEN
14225         REPEAT STRIP_TAC THEN MP_TAC(ISPECL
14226          [`s:real^M#(real^M->bool)->bool`;
14227           `UNIONS(IMAGE SND (s:real^M#(real^M->bool)->bool))`;
14228           `x:real^M`; `k:real^M->bool`;
14229           `y:real^M`; `l:real^M->bool`; `i:num`; `c:real`]
14230          TAGGED_DIVISION_SPLIT_LEFT_INJ) THEN
14231         ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
14232          [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF]; ALL_TAC] THEN
14233         REWRITE_TAC[NORM_EQ_0] THEN
14234         SUBGOAL_THEN `?u v:real^M. l = interval[u,v]`
14235          (REPEAT_TCL CHOOSE_THEN SUBST1_TAC)
14236         THENL [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
14237         ASM_SIMP_TAC[INTERVAL_SPLIT; INTEGRAL_NULL];
14238         DISCH_THEN SUBST1_TAC THEN
14239         ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN
14240         ASM_REWRITE_TAC[o_THM; FORALL_PAIR_THM] THEN
14241         ONCE_REWRITE_TAC[SET_RULE
14242          `x$i <= c <=> x IN {x:real^M | x$i <= c}`] THEN
14243         REWRITE_TAC[INTEGRAL_RESTRICT_INTER] THEN
14244         REWRITE_TAC[IN_ELIM_THM; INTER_COMM] THEN
14245         REWRITE_TAC[NORM_ARITH `norm(a - b:real^N) <= norm a + norm b`]];
14246       W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE_NONZERO o
14247         rand o rand o rand o snd) THEN
14248       ANTS_TAC THENL
14249        [ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
14250         MAP_EVERY X_GEN_TAC
14251          [`x:real^M`; `k:real^M->bool`; `y:real^M`; `l:real^M->bool`] THEN
14252         ASM_CASES_TAC `x:real^M = y` THEN ASM_REWRITE_TAC[PAIR_EQ] THEN
14253         REPEAT STRIP_TAC THEN MP_TAC(ISPECL
14254          [`t:real^M#(real^M->bool)->bool`;
14255           `UNIONS(IMAGE SND (t:real^M#(real^M->bool)->bool))`;
14256           `x:real^M`; `k:real^M->bool`;
14257           `y:real^M`; `l:real^M->bool`; `i:num`; `c:real`]
14258          TAGGED_DIVISION_SPLIT_RIGHT_INJ) THEN
14259         ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
14260          [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF]; ALL_TAC] THEN
14261         REWRITE_TAC[NORM_EQ_0] THEN
14262         SUBGOAL_THEN `?u v:real^M. l = interval[u,v]`
14263          (REPEAT_TCL CHOOSE_THEN SUBST1_TAC)
14264         THENL [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
14265         ASM_SIMP_TAC[INTERVAL_SPLIT; INTEGRAL_NULL];
14266         DISCH_THEN SUBST1_TAC THEN
14267         ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN
14268         ASM_REWRITE_TAC[o_THM; FORALL_PAIR_THM] THEN
14269         MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
14270         MATCH_MP_TAC(NORM_ARITH
14271          `i = i1 + i2
14272           ==> norm(c + i1:real^N) <= norm(c) + norm(i) + norm(i2)`) THEN
14273         ONCE_REWRITE_TAC[SET_RULE
14274          `x$i <= c <=> x IN {x:real^M | x$i <= c}`] THEN
14275         REWRITE_TAC[INTEGRAL_RESTRICT_INTER] THEN
14276         ONCE_REWRITE_TAC[SET_RULE `{x | P x} INTER s = s INTER {x | P x}`] THEN
14277         SUBGOAL_THEN `?u v:real^M. k = interval[u,v]`
14278          (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
14279         THENL [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
14280         ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MATCH_MP_TAC INTEGRAL_SPLIT THEN
14281         ASM_REWRITE_TAC[] THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
14282         EXISTS_TAC `interval[a:real^M,b]` THEN
14283         ASM_SIMP_TAC[] THEN ASM_MESON_TAC[tagged_partial_division_of]]];
14284     ALL_TAC] THEN
14285   SUBGOAL_THEN
14286    `!x:real^M k. (x,k) IN r ==> ~(k INTER {x:real^M | x$i = c} = {})`
14287   ASSUME_TAC THENL
14288    [REPEAT GEN_TAC THEN MAP_EVERY EXPAND_TAC ["r"; "q"] THEN
14289     REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
14290     REWRITE_TAC[GSYM CONJ_ASSOC; SUBSET; EXTENSION; NOT_FORALL_THM] THEN
14291     REWRITE_TAC[IN_ELIM_THM; NOT_IN_EMPTY; IN_INTER; NOT_IMP] THEN
14292     DISCH_TAC THEN MATCH_MP_TAC CONNECTED_IVT_COMPONENT THEN
14293     REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN
14294     CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LE_TOTAL]] THEN
14295     SUBGOAL_THEN `?u v:real^M. k = interval[u,v]`
14296      (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
14297     THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
14298     MATCH_MP_TAC CONVEX_CONNECTED THEN REWRITE_TAC[CONVEX_INTERVAL];
14299     ALL_TAC] THEN
14300   MATCH_MP_TAC(REAL_ARITH
14301    `x <= e / &6 /\ y <= e / &2 ==> x + y <= &2 * e / &3`) THEN
14302   CONJ_TAC THENL
14303    [MATCH_MP_TAC(REAL_ARITH
14304      `x < e / &12 /\ y < e / &12 ==> x + y <= e / &6`) THEN
14305     CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
14306     EXISTS_TAC `(lambda j. if j = i then c else (a:real^M)$j):real^M` THEN
14307     EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[LAMBDA_BETA; IN_INTERVAL] THENL
14308      [CONJ_TAC THENL
14309        [X_GEN_TAC `j:num` THEN COND_CASES_TAC THEN
14310         ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL];
14311         EXPAND_TAC "s" THEN REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
14312         ASM_MESON_TAC[]];
14313       REPEAT CONJ_TAC THENL
14314        [X_GEN_TAC `j:num` THEN COND_CASES_TAC THEN
14315         ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL];
14316         UNDISCH_TAC `s tagged_partial_division_of interval[a:real^M,b]`;
14317         UNDISCH_TAC `(g0:real^M->real^M->bool) fine s` THEN
14318         REWRITE_TAC[fine; FORALL_IN_IMAGE; lemma] THEN SET_TAC[];
14319         REWRITE_TAC[lemma] THEN
14320         REPEAT GEN_TAC THEN EXPAND_TAC "s" THEN REWRITE_TAC[IN_ELIM_THM] THEN
14321         DISCH_TAC THEN MATCH_MP_TAC(SET_RULE
14322         `~(k INTER t = {}) /\ t SUBSET s ==> ~((k INTER s) INTER t = {})`) THEN
14323         SIMP_TAC[SUBSET; IN_ELIM_THM; REAL_LE_REFL] THEN
14324         FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]]];
14325     MATCH_MP_TAC(REAL_ARITH
14326      `x < e / &3 /\ y < e / &12 /\ z < e / &12 ==> x + y + z <= e / &2`) THEN
14327     REPEAT CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
14328     EXISTS_TAC `(lambda j. if j = i then c else (a:real^M)$j):real^M` THEN
14329     EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[LAMBDA_BETA; IN_INTERVAL] THENL
14330      [CONJ_TAC THENL
14331        [X_GEN_TAC `j:num` THEN COND_CASES_TAC THEN
14332         ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL];
14333         EXPAND_TAC "t" THEN REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
14334         ASM_MESON_TAC[]];
14335       REPEAT CONJ_TAC THENL
14336        [X_GEN_TAC `j:num` THEN COND_CASES_TAC THEN
14337         ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL];
14338         UNDISCH_TAC `t tagged_partial_division_of interval[a:real^M,b]`;
14339         UNDISCH_TAC `(g0:real^M->real^M->bool) fine t` THEN
14340         REWRITE_TAC[fine; FORALL_IN_IMAGE; lemma] THEN SET_TAC[];
14341         REWRITE_TAC[lemma] THEN
14342         REPEAT GEN_TAC THEN EXPAND_TAC "t" THEN REWRITE_TAC[IN_ELIM_THM] THEN
14343         DISCH_TAC THEN MATCH_MP_TAC(SET_RULE
14344         `~(k INTER t = {}) /\ t SUBSET s ==> ~((k INTER s) INTER t = {})`) THEN
14345         SIMP_TAC[SUBSET; IN_ELIM_THM; REAL_LE_REFL; real_ge] THEN
14346         FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]]]] THEN
14347   REWRITE_TAC[tagged_partial_division_of] THEN
14348   (MATCH_MP_TAC MONO_AND THEN SIMP_TAC[FINITE_IMAGE] THEN
14349    MATCH_MP_TAC MONO_AND THEN
14350    REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_GSPEC] THEN
14351    REWRITE_TAC[lemma] THEN CONJ_TAC THEN
14352    MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
14353    MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:real^M->bool` THEN
14354    DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THENL
14355     [MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
14356       [SIMP_TAC[real_ge; IN_INTER; IN_ELIM_THM] THEN ASM SET_TAC[REAL_LE_TOTAL];
14357        MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
14358         [SET_TAC[];
14359          STRIP_TAC THEN ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MESON_TAC[]]];
14360      REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
14361      MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
14362      MATCH_MP_TAC MONO_IMP THEN SIMP_TAC[PAIR_EQ; CONTRAPOS_THM] THEN
14363      MATCH_MP_TAC(SET_RULE
14364       `s SUBSET s' /\ t SUBSET t'
14365        ==> s' INTER t' = {} ==> s INTER t = {}`) THEN CONJ_TAC THEN
14366      MATCH_MP_TAC SUBSET_INTERIOR THEN REWRITE_TAC[INTER_SUBSET]]));;
14367
14368 let EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE = prove
14369  (`!fs f:real^M->real^N a b.
14370         fs equiintegrable_on interval[a,b] /\ f IN fs /\
14371         (!h x. h IN fs /\ x IN interval[a,b] ==> norm(h x) <= norm(f x))
14372         ==> { (\x. if x$i >= c then h x else vec 0) |
14373               i IN 1..dimindex(:M) /\ c IN (:real) /\ h IN fs }
14374             equiintegrable_on interval[a,b]`,
14375   REPEAT STRIP_TAC THEN
14376   MP_TAC(ISPECL
14377    [`{\x. (f:real^M->real^N) (--x) | f IN fs}`;
14378     `\x. (f:real^M->real^N)(--x)`;
14379     `--b:real^M`; `--a:real^M`]
14380         EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE) THEN
14381   ASM_SIMP_TAC[EQUIINTEGRABLE_REFLECT] THEN ANTS_TAC THENL
14382    [ASM_SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
14383     ONCE_REWRITE_TAC[GSYM IN_INTERVAL_REFLECT] THEN
14384     ASM_SIMP_TAC[VECTOR_NEG_NEG] THEN
14385     REWRITE_TAC[SIMPLE_IMAGE; IN_IMAGE] THEN
14386     EXISTS_TAC `f:real^M->real^N` THEN ASM_REWRITE_TAC[];
14387     DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_REFLECT) THEN
14388     REWRITE_TAC[VECTOR_NEG_NEG] THEN MATCH_MP_TAC
14389      (REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
14390     REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN
14391     MAP_EVERY X_GEN_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN
14392     STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC
14393      `(\x. if (--x)$i >= c then (h:real^M->real^N)(--x) else vec 0)` THEN
14394     REWRITE_TAC[VECTOR_NEG_NEG] THEN MAP_EVERY EXISTS_TAC
14395      [`i:num`; `--c:real`; `\x. (h:real^M->real^N)(--x)`] THEN
14396     ASM_REWRITE_TAC[IN_UNIV; VECTOR_NEG_COMPONENT] THEN
14397     REWRITE_TAC[REAL_ARITH `--x >= c <=> x <= --c`] THEN
14398     EXISTS_TAC `h:real^M->real^N` THEN ASM_REWRITE_TAC[]]);;
14399
14400 let EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LT = prove
14401  (`!fs f:real^M->real^N a b.
14402         fs equiintegrable_on interval[a,b] /\ f IN fs /\
14403         (!h x. h IN fs /\ x IN interval[a,b] ==> norm(h x) <= norm(f x))
14404         ==> { (\x. if x$i < c then h x else vec 0) |
14405               i IN 1..dimindex(:M) /\ c IN (:real) /\ h IN fs }
14406             equiintegrable_on interval[a,b]`,
14407   REPEAT STRIP_TAC THEN
14408   MP_TAC(ISPECL [`fs:(real^M->real^N)->bool`; `f:real^M->real^N`;
14409                  `a:real^M`; `b:real^M`]
14410     EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE) THEN
14411   ASM_REWRITE_TAC[] THEN UNDISCH_TAC
14412    `(fs:(real^M->real^N)->bool) equiintegrable_on interval[a,b]` THEN
14413   REWRITE_TAC[IMP_IMP] THEN
14414   DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_SUB) THEN
14415   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
14416   REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN
14417   MAP_EVERY X_GEN_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN
14418   STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
14419   EXISTS_TAC `h:real^M->real^N` THEN
14420   EXISTS_TAC `\x. if x$i >= c then (h:real^M->real^N) x else vec 0` THEN
14421   ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
14422    [MAP_EVERY EXISTS_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN
14423     ASM_REWRITE_TAC[];
14424     REWRITE_TAC[FUN_EQ_THM; real_ge; GSYM REAL_NOT_LT] THEN
14425     GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
14426     VECTOR_ARITH_TAC]);;
14427
14428 let EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GT = prove
14429  (`!fs f:real^M->real^N a b.
14430         fs equiintegrable_on interval[a,b] /\ f IN fs /\
14431         (!h x. h IN fs /\ x IN interval[a,b] ==> norm(h x) <= norm(f x))
14432         ==> { (\x. if x$i > c then h x else vec 0) |
14433               i IN 1..dimindex(:M) /\ c IN (:real) /\ h IN fs }
14434             equiintegrable_on interval[a,b]`,
14435   REPEAT STRIP_TAC THEN
14436   MP_TAC(ISPECL [`fs:(real^M->real^N)->bool`; `f:real^M->real^N`;
14437                  `a:real^M`; `b:real^M`]
14438     EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE) THEN
14439   ASM_REWRITE_TAC[] THEN UNDISCH_TAC
14440    `(fs:(real^M->real^N)->bool) equiintegrable_on interval[a,b]` THEN
14441   REWRITE_TAC[IMP_IMP] THEN
14442   DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_SUB) THEN
14443   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
14444   REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN
14445   MAP_EVERY X_GEN_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN
14446   STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
14447   EXISTS_TAC `h:real^M->real^N` THEN
14448   EXISTS_TAC `\x. if x$i <= c then (h:real^M->real^N) x else vec 0` THEN
14449   ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
14450    [MAP_EVERY EXISTS_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN
14451     ASM_REWRITE_TAC[];
14452     REWRITE_TAC[FUN_EQ_THM; real_gt; GSYM REAL_NOT_LE] THEN
14453     GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
14454     VECTOR_ARITH_TAC]);;
14455
14456 let EQUIINTEGRABLE_OPEN_INTERVAL_RESTRICTIONS = prove
14457  (`!f:real^M->real^N a b.
14458         f integrable_on interval[a,b]
14459         ==> { (\x. if x IN interval(c,d) then f x else vec 0) |
14460               c IN (:real^M) /\ d IN (:real^M) }
14461             equiintegrable_on interval[a,b]`,
14462   REPEAT STRIP_TAC THEN
14463   SUBGOAL_THEN
14464    `!n. n <= dimindex(:M)
14465         ==> f INSERT
14466             { (\x. if !i. 1 <= i /\ i <= n ==> c$i < x$i /\ x$i < d$i
14467                    then (f:real^M->real^N) x else vec 0) |
14468               c IN (:real^M) /\ d IN (:real^M) }
14469             equiintegrable_on interval[a,b]`
14470   MP_TAC THENL
14471    [MATCH_MP_TAC num_INDUCTION THEN
14472     REWRITE_TAC[ARITH_RULE `~(1 <= i /\ i <= 0)`] THEN
14473     ASM_REWRITE_TAC[ETA_AX; EQUIINTEGRABLE_ON_SING; SET_RULE
14474      `f INSERT {f |c,d| c IN UNIV /\ d IN UNIV} = {f}`] THEN
14475     X_GEN_TAC `n:num` THEN ASM_CASES_TAC `SUC n <= dimindex(:M)` THEN
14476     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
14477     DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o
14478         MATCH_MP (REWRITE_RULE[IMP_CONJ]
14479           EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LT)) THEN
14480     REWRITE_TAC[IN_INSERT] THEN ANTS_TAC THENL
14481      [REWRITE_TAC[TAUT
14482        `a \/ b ==> c ==> d <=> (a ==> c ==> d) /\ (b ==> c ==> d)`] THEN
14483       SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN
14484       REWRITE_TAC[FORALL_IN_GSPEC] THEN
14485       REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
14486       ASM_SIMP_TAC[NORM_0; REAL_LE_REFL; NORM_POS_LE];
14487       ALL_TAC] THEN
14488     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN
14489     REWRITE_TAC[IMP_IMP] THEN
14490     DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION) THEN
14491     DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o
14492         MATCH_MP (REWRITE_RULE[IMP_CONJ]
14493           EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GT)) THEN
14494     ASM_REWRITE_TAC[IN_UNION; IN_SING] THEN ANTS_TAC THENL
14495      [REWRITE_TAC[TAUT
14496        `a \/ b ==> c ==> d <=> (a ==> c ==> d) /\ (b ==> c ==> d)`] THEN
14497       SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN
14498       REWRITE_TAC[FORALL_IN_GSPEC; LEFT_OR_DISTRIB] THEN
14499       REWRITE_TAC[TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
14500       SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM]  THEN
14501       REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC;
14502                   FORALL_AND_THM] THEN
14503       SIMP_TAC[IN_UNIV] THEN
14504       REPEAT STRIP_TAC THEN
14505       REPEAT(COND_CASES_TAC THEN
14506              ASM_SIMP_TAC[NORM_0; REAL_LE_REFL; NORM_POS_LE]);
14507       ALL_TAC] THEN
14508     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN
14509     REWRITE_TAC[IMP_IMP] THEN
14510     DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION) THEN
14511     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
14512     MATCH_MP_TAC(SET_RULE
14513       `s SUBSET t ==> (x INSERT s) SUBSET ({x} UNION t)`) THEN
14514     REWRITE_TAC[SUBSET; real_gt; FORALL_IN_GSPEC; IN_UNIV] THEN
14515     MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN
14516     REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `SUC n` THEN
14517     ASM_REWRITE_TAC[IN_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN
14518     EXISTS_TAC `(c:real^M)$(SUC n)` THEN
14519     MATCH_MP_TAC(MESON[]
14520      `(?i c k. P i c k /\ Q (g i c k))
14521       ==> ?h. (h = f \/ ?i c k. P i c k /\ h = g i c k) /\ Q h`) THEN
14522     EXISTS_TAC `SUC n` THEN
14523     ASM_REWRITE_TAC[IN_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN
14524     EXISTS_TAC `(d:real^M)$(SUC n)` THEN
14525     EXISTS_TAC
14526      `\x. if !i. 1 <= i /\ i <= n ==> (c:real^M)$i < x$i /\ x$i < (d:real^M)$i
14527           then (f:real^M->real^N) x else vec 0` THEN
14528     REWRITE_TAC[] THEN CONJ_TAC THENL
14529      [DISJ2_TAC THEN
14530       MAP_EVERY EXISTS_TAC [`c:real^M`; `d:real^M`] THEN REWRITE_TAC[];
14531       REWRITE_TAC[FUN_EQ_THM; LE] THEN
14532       ASM_MESON_TAC[ARITH_RULE `1 <= SUC n`]];
14533     DISCH_THEN(MP_TAC o SPEC `dimindex(:M)`) THEN
14534     REWRITE_TAC[IN_INTERVAL; LE_REFL] THEN
14535     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
14536     SET_TAC[]]);;
14537
14538 let EQUIINTEGRABLE_CLOSED_INTERVAL_RESTRICTIONS = prove
14539  (`!f:real^M->real^N a b.
14540         f integrable_on interval[a,b]
14541         ==> { (\x. if x IN interval[c,d] then f x else vec 0) |
14542               c IN (:real^M) /\ d IN (:real^M) }
14543             equiintegrable_on interval[a,b]`,
14544   REPEAT STRIP_TAC THEN
14545   SUBGOAL_THEN
14546    `!n. n <= dimindex(:M)
14547         ==> f INSERT
14548             { (\x. if !i. 1 <= i /\ i <= n ==> c$i <= x$i /\ x$i <= d$i
14549                    then (f:real^M->real^N) x else vec 0) |
14550               c IN (:real^M) /\ d IN (:real^M) }
14551             equiintegrable_on interval[a,b]`
14552   MP_TAC THENL
14553    [MATCH_MP_TAC num_INDUCTION THEN
14554     REWRITE_TAC[ARITH_RULE `~(1 <= i /\ i <= 0)`] THEN
14555     ASM_REWRITE_TAC[ETA_AX; EQUIINTEGRABLE_ON_SING; SET_RULE
14556      `f INSERT {f |c,d| c IN UNIV /\ d IN UNIV} = {f}`] THEN
14557     X_GEN_TAC `n:num` THEN ASM_CASES_TAC `SUC n <= dimindex(:M)` THEN
14558     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
14559     DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o
14560         MATCH_MP (REWRITE_RULE[IMP_CONJ]
14561           EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE)) THEN
14562     REWRITE_TAC[IN_INSERT] THEN ANTS_TAC THENL
14563      [REWRITE_TAC[TAUT
14564        `a \/ b ==> c ==> d <=> (a ==> c ==> d) /\ (b ==> c ==> d)`] THEN
14565       SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN
14566       REWRITE_TAC[FORALL_IN_GSPEC] THEN
14567       REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
14568       ASM_SIMP_TAC[NORM_0; REAL_LE_REFL; NORM_POS_LE];
14569       ALL_TAC] THEN
14570     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN
14571     REWRITE_TAC[IMP_IMP] THEN
14572     DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION) THEN
14573     DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o
14574         MATCH_MP (REWRITE_RULE[IMP_CONJ]
14575           EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE)) THEN
14576     ASM_REWRITE_TAC[IN_UNION; IN_SING] THEN ANTS_TAC THENL
14577      [REWRITE_TAC[TAUT
14578        `a \/ b ==> c ==> d <=> (a ==> c ==> d) /\ (b ==> c ==> d)`] THEN
14579       SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN
14580       REWRITE_TAC[FORALL_IN_GSPEC; LEFT_OR_DISTRIB] THEN
14581       REWRITE_TAC[TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
14582       SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM]  THEN
14583       REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC;
14584                   FORALL_AND_THM] THEN
14585       SIMP_TAC[IN_UNIV] THEN
14586       REPEAT STRIP_TAC THEN
14587       REPEAT(COND_CASES_TAC THEN
14588              ASM_SIMP_TAC[NORM_0; REAL_LE_REFL; NORM_POS_LE]);
14589       ALL_TAC] THEN
14590     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN
14591     REWRITE_TAC[IMP_IMP] THEN
14592     DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION) THEN
14593     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
14594     MATCH_MP_TAC(SET_RULE
14595       `s SUBSET t ==> (x INSERT s) SUBSET ({x} UNION t)`) THEN
14596     REWRITE_TAC[SUBSET; real_ge; FORALL_IN_GSPEC; IN_UNIV] THEN
14597     MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN
14598     REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `SUC n` THEN
14599     ASM_REWRITE_TAC[IN_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN
14600     EXISTS_TAC `(c:real^M)$(SUC n)` THEN
14601     MATCH_MP_TAC(MESON[]
14602      `(?i c k. P i c k /\ Q (g i c k))
14603       ==> ?h. (h = f \/ ?i c k. P i c k /\ h = g i c k) /\ Q h`) THEN
14604     EXISTS_TAC `SUC n` THEN
14605     ASM_REWRITE_TAC[IN_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN
14606     EXISTS_TAC `(d:real^M)$(SUC n)` THEN
14607     EXISTS_TAC
14608      `\x. if !i. 1 <= i /\ i <= n ==> (c:real^M)$i <= x$i /\ x$i <= (d:real^M)$i
14609           then (f:real^M->real^N) x else vec 0` THEN
14610     REWRITE_TAC[] THEN CONJ_TAC THENL
14611      [DISJ2_TAC THEN
14612       MAP_EVERY EXISTS_TAC [`c:real^M`; `d:real^M`] THEN REWRITE_TAC[];
14613       REWRITE_TAC[FUN_EQ_THM; LE] THEN
14614       ASM_MESON_TAC[ARITH_RULE `1 <= SUC n`]];
14615     DISCH_THEN(MP_TAC o SPEC `dimindex(:M)`) THEN
14616     REWRITE_TAC[IN_INTERVAL; LE_REFL] THEN
14617     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
14618     SET_TAC[]]);;
14619
14620 (* ------------------------------------------------------------------------- *)
14621 (* Continuity of the indefinite integral.                                    *)
14622 (* ------------------------------------------------------------------------- *)
14623
14624 let INDEFINITE_INTEGRAL_CONTINUOUS = prove
14625  (`!f:real^M->real^N a b c d e.
14626         f integrable_on interval[a,b] /\
14627         c IN interval[a,b] /\ d IN interval[a,b] /\ &0 < e
14628         ==> ?k. &0 < k /\
14629                 !c' d'. c' IN interval[a,b] /\
14630                         d' IN interval[a,b] /\
14631                         norm(c' - c) <= k /\ norm(d' - d) <= k
14632                         ==> norm(integral(interval[c',d']) f -
14633                                  integral(interval[c,d]) f) < e`,
14634   REPEAT STRIP_TAC THEN
14635   ONCE_REWRITE_TAC[MESON[] `(?k. P k /\ Q k) <=> ~(!k. P k ==> ~Q k)`] THEN
14636   DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `inv(&n + &1)`) THEN
14637   PURE_REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
14638   REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`; SKOLEM_THM] THEN
14639   REWRITE_TAC[NOT_EXISTS_THM; REAL_NOT_LT; GSYM CONJ_ASSOC] THEN
14640   MAP_EVERY X_GEN_TAC [`u:num->real^M`; `v:num->real^M`] THEN
14641   REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN
14642   ABBREV_TAC
14643    `k:real^M->bool =
14644     UNIONS (IMAGE (\i. {x | x$i = (c:real^M)$i} UNION {x | x$i = (d:real^M)$i})
14645                   (1..dimindex(:M)))` THEN
14646   SUBGOAL_THEN `negligible(k:real^M->bool)` ASSUME_TAC THENL
14647    [EXPAND_TAC "k" THEN MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN
14648     SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; FORALL_IN_IMAGE] THEN
14649     X_GEN_TAC `i:num` THEN REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN
14650     ASM_SIMP_TAC[NEGLIGIBLE_UNION; NEGLIGIBLE_STANDARD_HYPERPLANE];
14651     ALL_TAC] THEN
14652   MP_TAC(ISPECL
14653    [`\n:num x. if x IN interval[u n,v n] then
14654                  if x IN k then vec 0 else (f:real^M->real^N) x
14655                else vec 0`;
14656     `\x. if x IN interval[c,d] then
14657             if x IN k then vec 0 else (f:real^M->real^N) x
14658          else vec 0`;
14659     `a:real^M`; `b:real^M`] EQUIINTEGRABLE_LIMIT) THEN
14660   REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL
14661    [SUBGOAL_THEN
14662      `(\x. if x IN k then vec 0 else (f:real^M->real^N) x)
14663       integrable_on interval[a,b]`
14664     MP_TAC THENL
14665      [UNDISCH_TAC `(f:real^M->real^N) integrable_on interval[a,b]` THEN
14666       MATCH_MP_TAC INTEGRABLE_SPIKE THEN EXISTS_TAC `k:real^M->bool` THEN
14667       ASM_REWRITE_TAC[] THEN SET_TAC[];
14668       ALL_TAC] THEN
14669     DISCH_THEN(MP_TAC o MATCH_MP
14670       EQUIINTEGRABLE_CLOSED_INTERVAL_RESTRICTIONS) THEN
14671     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
14672     REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_UNIV] THEN
14673     REWRITE_TAC[IN_ELIM_THM] THEN
14674     X_GEN_TAC `n:num` THEN MAP_EVERY EXISTS_TAC
14675      [`(u:num->real^M) n`; `(v:num->real^M) n`] THEN
14676     REWRITE_TAC[];
14677     X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
14678     ASM_CASES_TAC `(x:real^M) IN k` THEN
14679     ASM_REWRITE_TAC[COND_ID; LIM_CONST] THEN MATCH_MP_TAC LIM_EVENTUALLY THEN
14680     REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
14681     MP_TAC(SPEC `inf (IMAGE (\i. min (abs((x:real^M)$i - (c:real^M)$i))
14682                                      (abs((x:real^M)$i - (d:real^M)$i)))
14683                             (1..dimindex(:M)))` REAL_ARCH_INV) THEN
14684     SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY;
14685              FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1] THEN
14686     ASM_SIMP_TAC[FORALL_IN_IMAGE; REAL_LT_MIN; IN_NUMSEG] THEN
14687     UNDISCH_TAC `~((x:real^M) IN k)` THEN EXPAND_TAC "k" THEN
14688     REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM; NOT_EXISTS_THM] THEN
14689     REWRITE_TAC[IN_NUMSEG; SET_RULE
14690      `~(p /\ x IN (s UNION t)) <=> p ==> ~(x IN s) /\ ~(x IN t)`] THEN
14691     REWRITE_TAC[IN_ELIM_THM; REAL_ARITH `&0 < abs(x - y) <=> ~(x = y)`] THEN
14692     DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
14693     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
14694     X_GEN_TAC `n:num` THEN DISCH_TAC THEN
14695     SUBGOAL_THEN `x IN interval[(u:num->real^M) n,v n] <=> x IN interval[c,d]`
14696      (fun th -> REWRITE_TAC[th]) THEN
14697     REWRITE_TAC[IN_INTERVAL] THEN AP_TERM_TAC THEN
14698     GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `i:num` THEN
14699     ASM_CASES_TAC `1 <= i /\ i <= dimindex(:M)` THEN ASM_REWRITE_TAC[] THEN
14700     MATCH_MP_TAC(REAL_ARITH
14701      `!N n. abs(u - c) <= n /\ abs(v - d) <= n /\
14702             N < abs(x - c) /\ N < abs(x - d) /\ n <= N
14703       ==> (u <= x /\ x <= v <=> c <= x /\ x <= d)`) THEN
14704     MAP_EVERY EXISTS_TAC [`inv(&N)`; `inv(&n + &1)`] THEN
14705     ASM_SIMP_TAC[] THEN REPEAT (CONJ_TAC THENL
14706      [ASM_MESON_TAC[REAL_LE_TRANS; COMPONENT_LE_NORM; VECTOR_SUB_COMPONENT];
14707       ALL_TAC]) THEN
14708     MATCH_MP_TAC REAL_LE_INV2 THEN
14709     REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
14710     ASM_ARITH_TAC;
14711     DISCH_THEN(MP_TAC o CONJUNCT2) THEN
14712     REWRITE_TAC[INTEGRAL_RESTRICT_INTER] THEN
14713     SUBGOAL_THEN
14714      `interval[c:real^M,d] INTER interval[a,b] = interval[c,d] /\
14715       !n:num. interval[u n,v n] INTER interval[a,b] = interval[u n,v n]`
14716      (fun th -> SIMP_TAC[th])
14717     THENL
14718      [REWRITE_TAC[SET_RULE `s INTER t = s <=> s SUBSET t`] THEN
14719       REWRITE_TAC[SUBSET_INTERVAL] THEN
14720       RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN ASM_MESON_TAC[];
14721       ALL_TAC] THEN
14722     REWRITE_TAC[LIM_SEQUENTIALLY] THEN
14723     DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
14724     DISCH_THEN(X_CHOOSE_THEN `N:num` (MP_TAC o SPEC `N:num`)) THEN
14725     REWRITE_TAC[LE_REFL; REAL_NOT_LT] THEN
14726     FIRST_ASSUM(fun th -> MP_TAC(SPEC `N:num` th) THEN MATCH_MP_TAC
14727     (NORM_ARITH `x = a /\ y = b ==> e <= norm(x - y) ==> e <= dist(a,b)`)) THEN
14728     CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_SPIKE THEN
14729     EXISTS_TAC `k:real^M->bool` THEN ASM_SIMP_TAC[IN_DIFF]]);;
14730
14731 let INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT = prove
14732  (`!f:real^M->real^N a b.
14733         f integrable_on interval[a,b]
14734          ==> (\x. integral (interval[a,x]) f) continuous_on interval[a,b]`,
14735   REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
14736   X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[continuous_within] THEN
14737   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
14738   MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`;
14739                  `a:real^M`; `x:real^M`; `e:real`]
14740         INDEFINITE_INTEGRAL_CONTINUOUS) THEN
14741   ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN
14742   ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[dist]] THEN
14743   MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
14744   FIRST_X_ASSUM MATCH_MP_TAC THEN
14745   ASM_SIMP_TAC[ENDS_IN_INTERVAL; VECTOR_SUB_REFL; NORM_0; REAL_LT_IMP_LE] THEN
14746   ASM SET_TAC[]);;
14747
14748 let INDEFINITE_INTEGRAL_CONTINUOUS_LEFT = prove
14749  (`!f:real^M->real^N a b.
14750         f integrable_on interval[a,b]
14751         ==> (\x. integral(interval[x,b]) f) continuous_on interval[a,b]`,
14752   REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
14753   X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[continuous_within] THEN
14754   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
14755   MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`;
14756                  `x:real^M`; `b:real^M`; `e:real`]
14757         INDEFINITE_INTEGRAL_CONTINUOUS) THEN
14758   ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN
14759   ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[dist]] THEN
14760   MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
14761   FIRST_X_ASSUM MATCH_MP_TAC THEN
14762   ASM_SIMP_TAC[ENDS_IN_INTERVAL; VECTOR_SUB_REFL; NORM_0; REAL_LT_IMP_LE] THEN
14763   ASM SET_TAC[]);;
14764
14765 let INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS = prove
14766  (`!f:real^M->real^N a b.
14767         f integrable_on interval[a,b]
14768         ==> (\y. integral (interval[fstcart y,sndcart y]) f)
14769             uniformly_continuous_on interval[pastecart a a,pastecart b b]`,
14770   REPEAT STRIP_TAC THEN MATCH_MP_TAC COMPACT_UNIFORMLY_CONTINUOUS THEN
14771   REWRITE_TAC[COMPACT_INTERVAL; continuous_on] THEN
14772   REWRITE_TAC[FORALL_PASTECART; GSYM PCROSS_INTERVAL; PCROSS] THEN
14773   REWRITE_TAC[IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN
14774   MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN STRIP_TAC THEN
14775   X_GEN_TAC `e:real` THEN DISCH_TAC THEN MP_TAC(ISPECL
14776    [`f:real^M->real^N`; `a:real^M`; `b:real^M`; `c:real^M`; `d:real^M`;
14777     `e:real`] INDEFINITE_INTEGRAL_CONTINUOUS) THEN
14778   ASM_REWRITE_TAC[dist] THEN MATCH_MP_TAC MONO_EXISTS THEN
14779   X_GEN_TAC `k:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[PASTECART_SUB] THEN
14780   ASM_MESON_TAC[NORM_LE_PASTECART; REAL_LT_IMP_LE; REAL_LE_TRANS]);;
14781
14782 let INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS_EXPLICIT = prove
14783  (`!f:real^M->real^N a b e.
14784         f integrable_on interval[a,b] /\ &0 < e
14785         ==> ?k. &0 < k /\
14786                 !c d c' d'. c IN interval[a,b] /\ d IN interval[a,b] /\
14787                             c' IN interval[a,b] /\ d' IN interval[a,b] /\
14788                             norm (c' - c) <= k /\ norm (d' - d) <= k
14789                             ==> norm(integral(interval[c',d']) f -
14790                                      integral(interval[c,d]) f) < e`,
14791   REPEAT STRIP_TAC THEN MP_TAC(ISPECL
14792    [`f:real^M->real^N`; `a:real^M`; `b:real^M`]
14793     INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS) THEN
14794   ASM_REWRITE_TAC[uniformly_continuous_on] THEN
14795   DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
14796   DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
14797   EXISTS_TAC `k / &3` THEN CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
14798   MAP_EVERY X_GEN_TAC [`c:real^M`; `c':real^M`; `d:real^M`; `d':real^M`] THEN
14799   STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL
14800    [`pastecart (c:real^M) (c':real^M)`;
14801     `pastecart (d:real^M) (d':real^M)`]) THEN
14802   REWRITE_TAC[GSYM PCROSS_INTERVAL; PCROSS] THEN
14803   REWRITE_TAC[IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN
14804   ASM_REWRITE_TAC[dist; PASTECART_SUB] THEN DISCH_THEN MATCH_MP_TAC THEN
14805   ASM_MESON_TAC[NORM_PASTECART_LE; REAL_LET_TRANS;
14806     REAL_ARITH `&0 < k /\ x <= k / &3 /\ y <= k / &3 ==> x + y < k`]);;
14807
14808 let BOUNDED_INTEGRALS_OVER_SUBINTERVALS = prove
14809  (`!f:real^M->real^N a b.
14810         f integrable_on interval[a,b]
14811         ==> bounded { integral (interval[c,d]) f |
14812                       interval[c,d] SUBSET interval[a,b]}`,
14813   REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o MATCH_MP
14814     INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS) THEN
14815   DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
14816     BOUNDED_UNIFORMLY_CONTINUOUS_IMAGE)) THEN
14817   REWRITE_TAC[BOUNDED_INTERVAL] THEN
14818   REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN
14819   REWRITE_TAC[FORALL_PASTECART; GSYM PCROSS_INTERVAL; PASTECART_IN_PCROSS] THEN
14820   REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN
14821   SIMP_TAC[INTERVAL_SUBSET_IS_INTERVAL; IS_INTERVAL_INTERVAL] THEN
14822   MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_SIMP_TAC[] THEN
14823   ASM_SIMP_TAC[INTEGRAL_EMPTY; NORM_0; REAL_LT_IMP_LE]);;
14824
14825 (* ------------------------------------------------------------------------- *)
14826 (* Substitution.                                                             *)
14827 (* ------------------------------------------------------------------------- *)
14828
14829 let HAS_INTEGRAL_SUBSTITUTION_STRONG = prove
14830  (`!f:real^1->real^N g g' a b c d k.
14831         COUNTABLE k /\
14832         f integrable_on interval[c,d] /\
14833         g continuous_on interval[a,b] /\
14834         IMAGE g (interval[a,b]) SUBSET interval[c,d] /\
14835         (!x. x IN interval[a,b] DIFF k
14836                   ==> (g has_vector_derivative g'(x))
14837                        (at x within interval[a,b]) /\
14838                       f continuous
14839                         (at(g x)) within interval[c,d]) /\
14840         drop a <= drop b /\ drop c <= drop d /\ drop(g a) <= drop(g b)
14841         ==> ((\x. drop(g' x) % f(g x)) has_integral
14842              integral (interval[g a,g b]) f) (interval[a,b])`,
14843   REPEAT STRIP_TAC THEN
14844   ABBREV_TAC `ff = \x. integral (interval[c,x]) (f:real^1->real^N)` THEN
14845   MP_TAC(ISPECL
14846    [`(ff:real^1->real^N) o (g:real^1->real^1)`;
14847     `\x:real^1.  drop(g' x) % (f:real^1->real^N)(g x)`;
14848
14849      `k:real^1->bool`; `a:real^1`; `b:real^1`]
14850    FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG) THEN
14851   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
14852    [CONJ_TAC THENL
14853      [MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN ASM_REWRITE_TAC[] THEN
14854       MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN
14855       EXISTS_TAC `interval[c:real^1,d]` THEN ASM_REWRITE_TAC[] THEN
14856       EXPAND_TAC "ff" THEN
14857       MATCH_MP_TAC INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT THEN
14858       ASM_REWRITE_TAC[];
14859       X_GEN_TAC `x:real^1` THEN REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN
14860       FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REWRITE_RULE[SUBSET]
14861         INTERVAL_OPEN_SUBSET_CLOSED)) THEN
14862       SUBGOAL_THEN `(ff o g has_vector_derivative
14863                      drop(g' x) % (f:real^1->real^N)(g x))
14864                     (at x within interval[a,b])`
14865       MP_TAC THENL
14866        [MATCH_MP_TAC VECTOR_DIFF_CHAIN_WITHIN THEN ASM_SIMP_TAC[IN_DIFF] THEN
14867         MP_TAC(ISPECL [`f:real^1->real^N`; `c:real^1`; `d:real^1`;
14868                        `(g:real^1->real^1) x`]
14869           INTEGRAL_HAS_VECTOR_DERIVATIVE_POINTWISE) THEN
14870         ASM_SIMP_TAC[CONTINUOUS_AT_WITHIN; IN_DIFF] THEN
14871         ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
14872         ASM_MESON_TAC[HAS_VECTOR_DERIVATIVE_WITHIN_SUBSET];
14873         REWRITE_TAC[has_vector_derivative; has_derivative] THEN
14874         ASM_SIMP_TAC[LIM_WITHIN_INTERIOR; INTERIOR_INTERVAL;
14875                      NETLIMIT_WITHIN_INTERIOR; NETLIMIT_AT]]];
14876     EXPAND_TAC "ff" THEN
14877     MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
14878     REWRITE_TAC[o_DEF] THEN MATCH_MP_TAC(VECTOR_ARITH
14879      `z + w:real^N = y ==> y - z = w`) THEN
14880     MATCH_MP_TAC INTEGRAL_COMBINE THEN ASM_REWRITE_TAC[] THEN
14881     CONJ_TAC THENL
14882      [ALL_TAC;
14883       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
14884         INTEGRABLE_SUBINTERVAL))] THEN
14885     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
14886     REWRITE_TAC[FORALL_IN_IMAGE; IN_INTERVAL_1; SUBSET] THEN
14887     ASM_MESON_TAC[REAL_LE_REFL; REAL_LE_TRANS]]);;
14888
14889 (* ------------------------------------------------------------------------- *)
14890 (* Second mean value theorem and corollaries.                                *)
14891 (* ------------------------------------------------------------------------- *)
14892
14893 let SECOND_MEAN_VALUE_THEOREM_FULL = prove
14894  (`!f:real^1->real^1 g a b.
14895         ~(interval[a,b] = {}) /\
14896         f integrable_on interval [a,b] /\
14897         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
14898                ==> g x <= g y)
14899         ==> ?c. c IN interval [a,b] /\
14900                 ((\x. g x % f x) has_integral
14901                  (g(a) % integral (interval[a,c]) f +
14902                   g(b) % integral (interval[c,b]) f)) (interval[a,b])`,
14903   let lemma1 = prove
14904    (`!f:real->real s.
14905       (!x. x IN s ==> &0 <= f x /\ f x <= &1)
14906       ==> (!n x. x IN s /\ ~(n = 0)
14907                  ==> abs(f x -
14908                          sum(1..n) (\k. if &k / &n <= f(x)
14909                                         then inv(&n) else &0)) < inv(&n))`,
14910     REPEAT STRIP_TAC THEN
14911     SUBGOAL_THEN `?m. floor(&n * (f:real->real) x) = &m` CHOOSE_TAC THENL
14912      [MATCH_MP_TAC FLOOR_POS THEN ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS];
14913       ALL_TAC] THEN
14914     SUBGOAL_THEN `!k. &k / &n <= (f:real->real) x <=> k <= m` ASSUME_TAC THENL
14915      [REWRITE_TAC[GSYM REAL_OF_NUM_LE] THEN
14916       FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
14917       ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN
14918       SIMP_TAC[REAL_LE_FLOOR; INTEGER_CLOSED; REAL_MUL_SYM];
14919       ALL_TAC] THEN
14920     ASM_REWRITE_TAC[GSYM SUM_RESTRICT_SET] THEN
14921     FIRST_X_ASSUM(MP_TAC o SPEC `n + 1`) THEN
14922     REWRITE_TAC[GSYM REAL_OF_NUM_ADD; real_div; REAL_ADD_RDISTRIB] THEN
14923     ASM_SIMP_TAC[REAL_MUL_RINV; REAL_MUL_LID; REAL_OF_NUM_EQ] THEN
14924     ASM_SIMP_TAC[REAL_ARITH `y <= &1 /\ &0 < i ==> ~(&1 + i <= y)`;
14925                  REAL_LT_INV_EQ; REAL_OF_NUM_LT; LE_1; NOT_LE] THEN
14926     SIMP_TAC[IN_NUMSEG; ARITH_RULE
14927      `m < n + 1 ==> ((1 <= k /\ k <= n) /\ k <= m <=> 1 <= k /\ k <= m)`] THEN
14928     DISCH_TAC THEN REWRITE_TAC[GSYM numseg; SUM_CONST_NUMSEG; ADD_SUB] THEN
14929     MATCH_MP_TAC REAL_LT_LCANCEL_IMP THEN EXISTS_TAC `abs(&n)` THEN
14930     REWRITE_TAC[GSYM REAL_ABS_MUL] THEN
14931     ASM_SIMP_TAC[REAL_ABS_NUM; REAL_MUL_RINV; REAL_OF_NUM_EQ] THEN
14932     ASM_SIMP_TAC[REAL_OF_NUM_LT; LE_1; REAL_SUB_LDISTRIB; GSYM real_div] THEN
14933     ASM_SIMP_TAC[REAL_DIV_LMUL; REAL_OF_NUM_EQ] THEN
14934     MATCH_MP_TAC(REAL_ARITH `f <= x /\ x < f + &1 ==> abs(x - f) < &1`) THEN
14935     FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[FLOOR]) in
14936   let lemma2 = prove
14937    (`!f:real^1->real^N g a b.
14938           f integrable_on interval[a,b] /\
14939           (!x y. drop x <= drop y ==> g(x) <= g(y))
14940           ==> {(\x. if c <= g(x) then f x else vec 0) | c IN (:real)}
14941               equiintegrable_on interval[a,b]`,
14942     REPEAT STRIP_TAC THEN
14943     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN
14944     DISCH_THEN(fun th ->
14945      MP_TAC(SPEC `f:real^1->real^N` (MATCH_MP (REWRITE_RULE[IMP_CONJ]
14946        EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE) th)) THEN
14947      MP_TAC(SPEC `f:real^1->real^N` (MATCH_MP (REWRITE_RULE[IMP_CONJ]
14948        EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GT) th)) THEN
14949       MP_TAC th) THEN
14950     SIMP_TAC[IN_SING; REAL_LE_REFL] THEN
14951     SUBGOAL_THEN `{(\x. vec 0):real^1->real^N} equiintegrable_on interval[a,b]`
14952     MP_TAC THENL
14953      [REWRITE_TAC[EQUIINTEGRABLE_ON_SING; INTEGRABLE_CONST]; ALL_TAC] THEN
14954     REPEAT(ONCE_REWRITE_TAC[IMP_IMP] THEN
14955            DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION)) THEN
14956     REWRITE_TAC[NUMSEG_SING; DIMINDEX_1; IN_SING] THEN
14957     REWRITE_TAC[SET_RULE `{m i c h | i = 1 /\ c IN (:real) /\ h = f} =
14958                           {m 1 c f | c IN (:real)}`] THEN
14959     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
14960     REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_UNIV] THEN
14961     X_GEN_TAC `y:real` THEN
14962     ASM_CASES_TAC `!x. y <= (g:real^1->real) x` THENL
14963      [ASM_REWRITE_TAC[ETA_AX; IN_UNION; IN_SING]; ALL_TAC] THEN
14964     ASM_CASES_TAC `!x. ~(y <= (g:real^1->real) x)` THENL
14965      [ASM_REWRITE_TAC[ETA_AX; IN_UNION; IN_SING]; ALL_TAC] THEN
14966     MP_TAC(ISPEC `IMAGE drop {x | y <= (g:real^1->real) x}` INF) THEN
14967     REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM; IMAGE_EQ_EMPTY] THEN
14968     ANTS_TAC THENL
14969      [ASM_REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN
14970       ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL];
14971       STRIP_TAC THEN REWRITE_TAC[real_gt; real_ge]] THEN
14972     REWRITE_TAC[IN_UNION; GSYM DISJ_ASSOC] THEN
14973     ASM_CASES_TAC `y <= g(lift(inf(IMAGE drop {x | y <= g x})))` THENL
14974      [REPEAT DISJ2_TAC; REPLICATE_TAC 2 DISJ2_TAC THEN DISJ1_TAC] THEN
14975     REWRITE_TAC[IN_ELIM_THM] THEN
14976     EXISTS_TAC `inf(IMAGE drop {x | y <= g x})` THEN
14977     REWRITE_TAC[FUN_EQ_THM] THEN
14978     MATCH_MP_TAC(MESON[]
14979      `(!x. P x <=> Q x)
14980       ==> !x. (if P x then f x else b) = (if Q x then f x else b)`) THEN
14981     X_GEN_TAC `x:real^1` THEN REWRITE_TAC[GSYM REAL_NOT_LE; GSYM drop] THEN
14982     ASM_MESON_TAC[REAL_LE_TOTAL; REAL_LT_ANTISYM; REAL_LE_TRANS; LIFT_DROP]) in
14983   let lemma3 = prove
14984    (`!f:real^1->real^N g a b.
14985           f integrable_on interval[a,b] /\
14986           (!x y. drop x <= drop y ==> g(x) <= g(y))
14987           ==> {(\x. vsum (1..n)
14988                      (\k. if &k / &n <= g x then inv(&n) % f(x) else vec 0)) |
14989                ~(n = 0)}
14990               equiintegrable_on interval[a,b]`,
14991     REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o
14992      MATCH_MP lemma2) THEN
14993     DISCH_THEN(MP_TAC o MATCH_MP
14994      (INST_TYPE [`:num`,`:A`] EQUIINTEGRABLE_SUM)) THEN
14995     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
14996     REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_UNIV] THEN X_GEN_TAC `n:num` THEN
14997     DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
14998     MAP_EVERY EXISTS_TAC [`1..n`; `\k:num. inv(&n)`;
14999      `\k x. if &k / &n <= g x then (f:real^1->real^N) x else vec 0`] THEN
15000     ASM_SIMP_TAC[SUM_CONST_NUMSEG; ADD_SUB; REAL_MUL_RINV; REAL_OF_NUM_EQ] THEN
15001     REWRITE_TAC[FINITE_NUMSEG; COND_RAND; COND_RATOR; VECTOR_MUL_RZERO] THEN
15002     X_GEN_TAC `k:num` THEN
15003     REWRITE_TAC[IN_NUMSEG; REAL_LE_INV_EQ; REAL_POS] THEN STRIP_TAC THEN
15004     EXISTS_TAC `&k / &n` THEN REWRITE_TAC[]) in
15005   let lemma4 = prove
15006    (`!f:real^1->real^1 g a b.
15007           ~(interval[a,b] = {}) /\
15008           f integrable_on interval[a,b] /\
15009           (!x y. drop x <= drop y ==> g(x) <= g(y)) /\
15010           (!x. x IN interval[a,b] ==> &0 <= g x /\ g x <= &1)
15011           ==> (\x. g(x) % f(x)) integrable_on interval[a,b] /\
15012               ?c. c IN interval[a,b] /\
15013                   integral (interval[a,b]) (\x. g(x) % f(x)) =
15014                   integral (interval[c,b]) f`,
15015     REPEAT GEN_TAC THEN STRIP_TAC THEN
15016     SUBGOAL_THEN
15017      `?m M. IMAGE (\x. integral (interval[x,b]) (f:real^1->real^1))
15018                   (interval[a,b]) = interval[m,M]`
15019     STRIP_ASSUME_TAC THENL
15020      [REWRITE_TAC[GSYM CONNECTED_COMPACT_INTERVAL_1] THEN CONJ_TAC THENL
15021        [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE;
15022         MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE] THEN
15023       ASM_SIMP_TAC[INDEFINITE_INTEGRAL_CONTINUOUS_LEFT; CONVEX_CONNECTED;
15024                    CONVEX_INTERVAL; COMPACT_INTERVAL];
15025       ALL_TAC] THEN
15026     MP_TAC(ISPECL[`f:real^1->real^1`; `g:real^1->real`; `a:real^1`; `b:real^1`]
15027           lemma3) THEN
15028     ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
15029     SUBGOAL_THEN
15030      `!n. ?c. c IN interval[a,b] /\
15031               integral (interval[c,b]) (f:real^1->real^1) =
15032               integral (interval[a,b])
15033                 (\x. vsum (1..n)
15034                     (\k. if &k / &n <= g x then inv(&n) % f x else vec 0))`
15035     MP_TAC THENL
15036      [X_GEN_TAC `n:num` THEN ASM_CASES_TAC `n = 0` THENL
15037        [ASM_REWRITE_TAC[VSUM_CLAUSES_NUMSEG; ARITH_EQ; INTEGRAL_0] THEN
15038         EXISTS_TAC `b:real^1` THEN ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN
15039         SIMP_TAC[INTEGRAL_NULL; CONTENT_EQ_0_1; REAL_LE_REFL];
15040         ALL_TAC] THEN
15041       MP_TAC(ISPECL [`f:real^1->real^1`; `g:real^1->real`;
15042                      `a:real^1`; `b:real^1`] lemma2) THEN
15043       ASM_REWRITE_TAC[equiintegrable_on; FORALL_IN_GSPEC; IN_UNIV] THEN
15044       DISCH_THEN(ASSUME_TAC o CONJUNCT1) THEN
15045       REWRITE_TAC[MESON[VECTOR_MUL_RZERO]
15046        `(if p then a % x else vec 0:real^1) =
15047         a % (if p then x else vec 0)`] THEN
15048       ASM_SIMP_TAC[VSUM_LMUL; INTEGRAL_CMUL; INTEGRABLE_VSUM; ETA_AX;
15049                    FINITE_NUMSEG; INTEGRAL_VSUM] THEN
15050       SUBGOAL_THEN
15051        `!y:real. ?d:real^1.
15052           d IN interval[a,b] /\
15053           integral (interval[a,b]) (\x. if y <= g x then f x else vec 0) =
15054           integral (interval[d,b]) (f:real^1->real^1)`
15055       MP_TAC THENL
15056        [X_GEN_TAC `y:real` THEN
15057         SUBGOAL_THEN
15058          `{x | y <= g x} = {} \/
15059           {x | y <= g x} = (:real^1) \/
15060           (?a. {x | y <= g x} = {x | a <= drop x}) \/
15061           (?a. {x | y <= g x} = {x | a < drop x})`
15062         MP_TAC THENL
15063          [MATCH_MP_TAC(TAUT `(~a /\ ~b ==> c \/ d) ==> a \/ b \/ c \/ d`) THEN
15064           DISCH_TAC THEN
15065           MP_TAC(ISPEC `IMAGE drop {x | y <= (g:real^1->real) x}` INF) THEN
15066           ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM; IMAGE_EQ_EMPTY] THEN
15067           ANTS_TAC THENL
15068            [FIRST_ASSUM(MP_TAC o CONJUNCT2) THEN
15069             REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_UNIV] THEN
15070             ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL];
15071             STRIP_TAC] THEN
15072           ASM_CASES_TAC `y <= g(lift(inf(IMAGE drop {x | y <= g x})))` THENL
15073            [DISJ1_TAC; DISJ2_TAC] THEN
15074           REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
15075           EXISTS_TAC `inf(IMAGE drop {x | y <= g x})` THEN
15076           REWRITE_TAC[FUN_EQ_THM] THEN
15077           X_GEN_TAC `x:real^1` THEN
15078           REWRITE_TAC[GSYM REAL_NOT_LE; GSYM drop] THEN
15079           ASM_MESON_TAC[REAL_LE_TOTAL; REAL_LT_ANTISYM;
15080                         REAL_LE_TRANS; LIFT_DROP];
15081           REWRITE_TAC[EXTENSION; IN_UNIV; NOT_IN_EMPTY; IN_ELIM_THM] THEN
15082           DISCH_THEN(DISJ_CASES_THEN2 ASSUME_TAC MP_TAC) THENL
15083            [EXISTS_TAC `b:real^1` THEN ASM_REWRITE_TAC[] THEN
15084             SIMP_TAC[INTEGRAL_NULL; CONTENT_EQ_0_1; REAL_LE_REFL] THEN
15085             ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTEGRAL_0];
15086             ALL_TAC] THEN
15087           DISCH_THEN(DISJ_CASES_THEN2 ASSUME_TAC MP_TAC) THENL
15088            [EXISTS_TAC `a:real^1` THEN
15089             ASM_REWRITE_TAC[ETA_AX; ENDS_IN_INTERVAL];
15090             ALL_TAC] THEN
15091           GEN_REWRITE_TAC LAND_CONV [OR_EXISTS_THM] THEN
15092           REWRITE_TAC[EXISTS_DROP] THEN
15093           DISCH_THEN(X_CHOOSE_THEN `d:real^1` ASSUME_TAC) THEN
15094           ASM_CASES_TAC `drop d < drop a` THENL
15095            [EXISTS_TAC `a:real^1` THEN
15096             ASM_REWRITE_TAC[ETA_AX; ENDS_IN_INTERVAL] THEN
15097             MATCH_MP_TAC INTEGRAL_EQ THEN
15098             REWRITE_TAC[IN_DIFF; IN_INTERVAL_1; NOT_IN_EMPTY] THEN
15099             GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
15100             UNDISCH_TAC `~(y <= (g:real^1->real) x)` THEN
15101             FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
15102             ASM_REAL_ARITH_TAC;
15103             ALL_TAC] THEN
15104           ASM_CASES_TAC `drop b < drop d` THENL
15105            [EXISTS_TAC `b:real^1` THEN
15106             SIMP_TAC[INTEGRAL_NULL; CONTENT_EQ_0_1; REAL_LE_REFL] THEN
15107             ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTEGRAL_0] THEN
15108             MATCH_MP_TAC INTEGRAL_EQ_0 THEN REWRITE_TAC[IN_INTERVAL_1] THEN
15109             REPEAT STRIP_TAC THEN
15110             COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
15111             UNDISCH_TAC `y <= (g:real^1->real) x` THEN
15112             FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
15113             ASM_REAL_ARITH_TAC;
15114             ALL_TAC] THEN
15115           EXISTS_TAC `d:real^1` THEN
15116           ASM_REWRITE_TAC[IN_INTERVAL_1; GSYM REAL_NOT_LT] THEN
15117           ONCE_REWRITE_TAC[SET_RULE
15118             `~((g:real^1->real) x < y) <=> x IN {x | ~(g x < y)}`] THEN
15119           REWRITE_TAC[INTEGRAL_RESTRICT_INTER] THEN
15120           MATCH_MP_TAC INTEGRAL_SPIKE_SET THEN
15121           MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `{d:real^1}` THEN
15122           REWRITE_TAC[NEGLIGIBLE_SING; REAL_NOT_LT; SUBSET] THEN GEN_TAC THEN
15123           REWRITE_TAC[SUBSET; IN_UNION; IN_INTER; IN_DIFF; IN_INTERVAL_1;
15124                       IN_ELIM_THM; IN_SING; GSYM DROP_EQ] THEN
15125           FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
15126           ASM_REAL_ARITH_TAC];
15127         DISCH_THEN(MP_TAC o GEN `k:num` o SPEC `&k / &n`) THEN
15128         REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM; LEFT_IMP_EXISTS_THM] THEN
15129         X_GEN_TAC `d:num->real^1` THEN STRIP_TAC THEN
15130         FIRST_ASSUM(MP_TAC o MATCH_MP (SET_RULE
15131          `IMAGE f s = t ==> !y. y IN t ==> ?x. x IN s /\ f x = y`)) THEN
15132         REWRITE_TAC[GSYM VSUM_LMUL] THEN DISCH_THEN MATCH_MP_TAC THEN
15133         MATCH_MP_TAC(REWRITE_RULE[CONVEX_INDEXED]
15134          (CONJUNCT1(SPEC_ALL CONVEX_INTERVAL))) THEN
15135         REWRITE_TAC[SUM_CONST_NUMSEG; ADD_SUB; REAL_LE_INV_EQ; REAL_POS] THEN
15136         ASM_SIMP_TAC[REAL_MUL_RINV; REAL_OF_NUM_EQ] THEN ASM SET_TAC[]];
15137       REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN
15138       X_GEN_TAC `c:num->real^1` THEN DISCH_THEN(STRIP_ASSUME_TAC o GSYM)] THEN
15139     SUBGOAL_THEN `compact(interval[a:real^1,b])` MP_TAC THENL
15140      [REWRITE_TAC[COMPACT_INTERVAL]; REWRITE_TAC[compact]] THEN
15141     DISCH_THEN(MP_TAC o SPEC `c:num->real^1`) THEN
15142     ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC
15143      [`d:real^1`; `s:num->num`] THEN STRIP_TAC THEN
15144     MP_TAC(ISPECL
15145      [`\n:num x. vsum (1..(s n))
15146                       (\k. if &k / &(s n) <= g x
15147                            then inv(&(s n)) % (f:real^1->real^1) x
15148                            else vec 0)`;
15149       `\x. g x % (f:real^1->real^1) x`; `a:real^1`; `b:real^1`]
15150      EQUIINTEGRABLE_LIMIT) THEN
15151     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
15152      [CONJ_TAC THENL
15153        [MATCH_MP_TAC EQUIINTEGRABLE_SUBSET THEN
15154         EXISTS_TAC
15155          `{\x. vsum(1..0) (\k. if &k / &0 <= g x
15156                                then inv(&0) % (f:real^1->real^1) x else vec 0)}
15157           UNION
15158           {\x. vsum (1..n)
15159                     (\k. if &k / &n <= g x then inv (&n) % f x else vec 0)
15160            | ~(n = 0)}` THEN
15161         CONJ_TAC THENL
15162          [MATCH_MP_TAC EQUIINTEGRABLE_UNION THEN ASM_REWRITE_TAC[] THEN
15163           REWRITE_TAC[EQUIINTEGRABLE_ON_SING; VSUM_CLAUSES_NUMSEG;
15164                       ARITH_EQ] THEN
15165           REWRITE_TAC[INTEGRABLE_0];
15166           REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_UNIV; IN_UNION] THEN
15167           REWRITE_TAC[IN_ELIM_THM; IN_SING] THEN
15168           X_GEN_TAC `n:num` THEN ASM_CASES_TAC `(s:num->num) n = 0` THEN
15169           ASM_REWRITE_TAC[] THEN DISJ2_TAC THEN
15170           EXISTS_TAC `(s:num->num) n` THEN ASM_REWRITE_TAC[]];
15171         X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN REWRITE_TAC[] THEN
15172         ONCE_REWRITE_TAC[MESON[VECTOR_MUL_LZERO]
15173          `(if p then a % x else vec 0) = (if p then a else &0) % x`] THEN
15174         REWRITE_TAC[VSUM_RMUL] THEN MATCH_MP_TAC LIM_VMUL THEN
15175         REWRITE_TAC[LIM_SEQUENTIALLY; o_DEF; DIST_LIFT] THEN
15176         X_GEN_TAC `e:real` THEN DISCH_TAC THEN
15177         MP_TAC(ISPEC `e:real` REAL_ARCH_INV) THEN
15178         ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN
15179         X_GEN_TAC `N:num` THEN STRIP_TAC THEN X_GEN_TAC `n:num` THEN
15180         DISCH_TAC THEN
15181         ONCE_REWRITE_TAC[REAL_ABS_SUB] THEN
15182         MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `inv(&n)` THEN
15183         CONJ_TAC THENL
15184          [MP_TAC(ISPECL
15185            [`(g:real^1->real) o lift`; `IMAGE drop (interval[a,b])`]
15186             lemma1) THEN
15187           ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_DEF; LIFT_DROP; IMP_CONJ;
15188                           RIGHT_FORALL_IMP_THM] THEN
15189           REWRITE_TAC[IMP_IMP] THEN DISCH_TAC THEN
15190           MATCH_MP_TAC REAL_LTE_TRANS THEN
15191           EXISTS_TAC `inv(&((s:num->num) n))` THEN CONJ_TAC THENL
15192            [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[];
15193             MATCH_MP_TAC REAL_LE_INV2 THEN
15194             REWRITE_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_LT]] THEN
15195           FIRST_ASSUM(MP_TAC o SPEC `n:num` o MATCH_MP MONOTONE_BIGGER) THEN
15196           ASM_ARITH_TAC;
15197           MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN
15198           ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
15199           REWRITE_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN ASM_ARITH_TAC]];
15200       STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
15201       EXISTS_TAC `d:real^1` THEN ASM_REWRITE_TAC[] THEN
15202       MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
15203       EXISTS_TAC `\n. integral (interval [c((s:num->num) n),b])
15204                                (f:real^1->real^1)` THEN
15205       ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
15206       MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`]
15207           INDEFINITE_INTEGRAL_CONTINUOUS_LEFT) THEN
15208       ASM_REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
15209       DISCH_THEN(MP_TAC o SPEC `d:real^1`) THEN ASM_REWRITE_TAC[] THEN
15210       REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY] THEN
15211       DISCH_THEN(MP_TAC o SPEC `(c:num->real^1) o (s:num->num)`) THEN
15212       ASM_REWRITE_TAC[] THEN ASM_REWRITE_TAC[o_DEF]]) in
15213   REPEAT GEN_TAC THEN STRIP_TAC THEN
15214   SUBGOAL_THEN `(g:real^1->real) a <= g b` MP_TAC THENL
15215    [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN
15216     ASM_MESON_TAC[INTERVAL_EQ_EMPTY_1; REAL_LET_TOTAL];
15217     ALL_TAC] THEN
15218   REWRITE_TAC[REAL_LE_LT] THEN STRIP_TAC THENL
15219    [ALL_TAC;
15220     SUBGOAL_THEN
15221      `!x. x IN interval[a,b] ==> g(x) % (f:real^1->real^1)(x) = g(a) % f x`
15222     ASSUME_TAC THENL
15223      [X_GEN_TAC `x:real^1` THEN
15224       REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN
15225       AP_THM_TAC THEN AP_TERM_TAC THEN
15226       RULE_ASSUM_TAC(REWRITE_RULE
15227        [IN_INTERVAL_1; INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
15228       ASM_MESON_TAC[REAL_LE_ANTISYM; REAL_LE_TRANS; REAL_LE_TOTAL];
15229       ALL_TAC] THEN
15230     EXISTS_TAC `a:real^1` THEN ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN
15231     MATCH_MP_TAC HAS_INTEGRAL_EQ THEN
15232     EXISTS_TAC `\x. g(a:real^1) % (f:real^1->real^1) x` THEN
15233     ASM_SIMP_TAC[INTEGRAL_NULL; CONTENT_EQ_0_1; REAL_LE_REFL] THEN
15234     ASM_SIMP_TAC[INTEGRAL_CMUL; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN
15235     MATCH_MP_TAC HAS_INTEGRAL_CMUL THEN
15236     ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]] THEN
15237   MP_TAC(ISPECL
15238    [`f:real^1->real^1`;
15239     `\x. if drop x < drop a then &0
15240          else if drop b < drop x then &1
15241          else (g(x) - g(a)) / (g(b) - g(a))`;
15242     `a:real^1`; `b:real^1`]
15243    lemma4) THEN ASM_REWRITE_TAC[] THEN
15244   ANTS_TAC THENL
15245    [CONJ_TAC THEN
15246     REPEAT GEN_TAC THEN
15247     REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_POS; REAL_LE_REFL]) THEN
15248     TRY ASM_REAL_ARITH_TAC THEN
15249     ASM_SIMP_TAC[IN_INTERVAL_1; REAL_LE_DIV2_EQ; REAL_SUB_LT] THEN
15250     ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN
15251     ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; REAL_SUB_LE;
15252                     REAL_ARITH `x - a <= y - a <=> x <= y`] THEN
15253     REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
15254     REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
15255     ALL_TAC] THEN
15256   REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN
15257   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN
15258   ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`] THEN
15259   DISCH_TAC THEN ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRABLE_INTEGRAL] THEN
15260   DISCH_THEN(MP_TAC o SPEC `(g:real^1->real) b - g a` o
15261         MATCH_MP HAS_INTEGRAL_CMUL) THEN
15262   FIRST_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
15263   DISCH_THEN(MP_TAC o SPEC `(g:real^1->real)(a)` o
15264       MATCH_MP HAS_INTEGRAL_CMUL) THEN REWRITE_TAC[IMP_IMP] THEN
15265   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_ADD) THEN
15266   MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`]
15267         INTEGRAL_COMBINE) THEN
15268   ANTS_TAC THENL [ASM_MESON_TAC[IN_INTERVAL_1]; ALL_TAC] THEN
15269   DISCH_THEN(SUBST1_TAC o SYM) THEN
15270   REWRITE_TAC[VECTOR_ARITH
15271    `ga % (i1 + i2) + (gb - ga) % i2:real^N = ga % i1 + gb % i2`] THEN
15272   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_EQ) THEN
15273   X_GEN_TAC `x:real^1` THEN REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN
15274   ASM_SIMP_TAC[GSYM REAL_NOT_LE; VECTOR_MUL_ASSOC] THEN
15275   ASM_SIMP_TAC[REAL_DIV_LMUL; REAL_LT_IMP_NZ; REAL_SUB_LT] THEN
15276   VECTOR_ARITH_TAC);;
15277
15278 let SECOND_MEAN_VALUE_THEOREM = prove
15279  (`!f:real^1->real^1 g a b.
15280         ~(interval[a,b] = {}) /\
15281         f integrable_on interval [a,b] /\
15282         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15283                ==> g x <= g y)
15284         ==> ?c. c IN interval [a,b] /\
15285                 integral (interval[a,b]) (\x. g x % f x) =
15286                  g(a) % integral (interval[a,c]) f +
15287                  g(b) % integral (interval[c,b]) f`,
15288   REPEAT GEN_TAC THEN
15289   DISCH_THEN(MP_TAC o MATCH_MP SECOND_MEAN_VALUE_THEOREM_FULL) THEN
15290   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN
15291   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
15292   FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN REWRITE_TAC[]);;
15293
15294 let SECOND_MEAN_VALUE_THEOREM_GEN_FULL = prove
15295  (`!f:real^1->real^1 g a b u v.
15296         ~(interval[a,b] = {}) /\ f integrable_on interval [a,b] /\
15297         (!x. x IN interval(a,b) ==> u <= g x /\ g x <= v) /\
15298         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15299                ==> g x <= g y)
15300         ==> ?c. c IN interval [a,b] /\
15301                 ((\x. g x % f x) has_integral
15302                  (u % integral (interval[a,c]) f +
15303                   v % integral (interval[c,b]) f)) (interval[a,b])`,
15304   REPEAT STRIP_TAC THEN ASM_CASES_TAC `b:real^1 = a` THENL
15305    [EXISTS_TAC `a:real^1` THEN ASM_REWRITE_TAC[INTERVAL_SING; IN_SING] THEN
15306     ASM_SIMP_TAC[GSYM INTERVAL_SING; INTEGRAL_NULL; CONTENT_EQ_0_1;
15307       VECTOR_ADD_LID; REAL_LE_REFL; VECTOR_MUL_RZERO; HAS_INTEGRAL_NULL];
15308     ALL_TAC] THEN
15309   SUBGOAL_THEN `drop a < drop b` ASSUME_TAC THENL
15310    [ASM_MESON_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LE; DROP_EQ; REAL_LT_LE];
15311     ALL_TAC] THEN
15312   SUBGOAL_THEN `u <= v` ASSUME_TAC THENL
15313    [ASM_MESON_TAC[INTERVAL_EQ_EMPTY_1; MEMBER_NOT_EMPTY; REAL_NOT_LT;
15314                   REAL_LE_TRANS];
15315     ALL_TAC] THEN
15316   MP_TAC(ISPECL
15317    [`f:real^1->real^1`;
15318     `\x:real^1. if x = a then u else if x = b then v else g x:real`;
15319     `a:real^1`; `b:real^1`] SECOND_MEAN_VALUE_THEOREM_FULL) THEN
15320   ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN ANTS_TAC THENL
15321    [MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN
15322     ASM_CASES_TAC `x:real^1 = a` THEN ASM_REWRITE_TAC[] THENL
15323      [ASM_MESON_TAC[REAL_LE_REFL; INTERVAL_CASES_1]; ALL_TAC] THEN
15324     ASM_CASES_TAC `y:real^1 = b` THEN ASM_REWRITE_TAC[] THENL
15325      [ASM_MESON_TAC[REAL_LE_REFL; INTERVAL_CASES_1]; ALL_TAC] THEN
15326     REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[]) THEN
15327     RULE_ASSUM_TAC(REWRITE_RULE[GSYM DROP_EQ]) THEN
15328     REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
15329     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN
15330     MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN MATCH_MP_TAC
15331      (REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
15332         HAS_INTEGRAL_SPIKE) THEN
15333     EXISTS_TAC `{a:real^1,b}` THEN
15334     SIMP_TAC[NEGLIGIBLE_EMPTY; NEGLIGIBLE_INSERT; IN_DIFF; IN_INSERT;
15335              NOT_IN_EMPTY; DE_MORGAN_THM]]);;
15336
15337 let SECOND_MEAN_VALUE_THEOREM_GEN = prove
15338  (`!f:real^1->real^1 g a b u v.
15339         ~(interval[a,b] = {}) /\ f integrable_on interval [a,b] /\
15340         (!x. x IN interval(a,b) ==> u <= g x /\ g x <= v) /\
15341         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15342                ==> g x <= g y)
15343         ==> ?c. c IN interval [a,b] /\
15344                 integral (interval[a,b]) (\x. g x % f x) =
15345                 u % integral (interval[a,c]) f +
15346                 v % integral (interval[c,b]) f`,
15347   REPEAT GEN_TAC THEN
15348   DISCH_THEN(MP_TAC o MATCH_MP SECOND_MEAN_VALUE_THEOREM_GEN_FULL) THEN
15349   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN
15350   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
15351   FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN REWRITE_TAC[]);;
15352
15353 let SECOND_MEAN_VALUE_THEOREM_BONNET_FULL = prove
15354  (`!f:real^1->real^1 g a b.
15355         ~(interval[a,b] = {}) /\ f integrable_on interval [a,b] /\
15356         (!x. x IN interval[a,b] ==> &0 <= g x) /\
15357         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15358                ==> g x <= g y)
15359         ==> ?c. c IN interval [a,b] /\
15360                 ((\x. g x % f x) has_integral
15361                  (g(b) % integral (interval[c,b]) f)) (interval[a,b])`,
15362   REPEAT STRIP_TAC THEN
15363   MP_TAC(ISPECL
15364    [`f:real^1->real^1`; `g:real^1->real`; `a:real^1`; `b:real^1`;
15365     `&0`; `(g:real^1->real) b`] SECOND_MEAN_VALUE_THEOREM_GEN_FULL) THEN
15366   ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN
15367   DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
15368   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
15369   REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC);;
15370
15371 let SECOND_MEAN_VALUE_THEOREM_BONNET = prove
15372  (`!f:real^1->real^1 g a b.
15373         ~(interval[a,b] = {}) /\ f integrable_on interval[a,b] /\
15374         (!x. x IN interval[a,b] ==> &0 <= g x) /\
15375         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15376                ==> g x <= g y)
15377         ==> ?c. c IN interval [a,b] /\
15378                 integral (interval[a,b]) (\x. g x % f x) =
15379                 g(b) % integral (interval[c,b]) f`,
15380   REPEAT GEN_TAC THEN
15381   DISCH_THEN(MP_TAC o MATCH_MP SECOND_MEAN_VALUE_THEOREM_BONNET_FULL) THEN
15382   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN
15383   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
15384   FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN REWRITE_TAC[]);;
15385
15386 let INTEGRABLE_INCREASING_PRODUCT = prove
15387  (`!f:real^1->real^N g a b.
15388         f integrable_on interval[a,b] /\
15389         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15390                ==> g(x) <= g(y))
15391         ==> (\x. g(x) % f(x)) integrable_on interval[a,b]`,
15392   REPEAT STRIP_TAC THEN ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN
15393   ASM_REWRITE_TAC[INTEGRABLE_ON_EMPTY] THEN
15394   ONCE_REWRITE_TAC[INTEGRABLE_COMPONENTWISE] THEN
15395   X_GEN_TAC `i:num` THEN STRIP_TAC THEN
15396   MP_TAC(ISPECL [`\x. lift((f:real^1->real^N) x$i)`;
15397                  `g:real^1->real`; `a:real^1`; `b:real^1`]
15398     SECOND_MEAN_VALUE_THEOREM_FULL) THEN
15399   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
15400    [RULE_ASSUM_TAC(ONCE_REWRITE_RULE[INTEGRABLE_COMPONENTWISE]) THEN
15401     ASM_SIMP_TAC[];
15402     REWRITE_TAC[VECTOR_MUL_COMPONENT; LIFT_CMUL; integrable_on] THEN
15403     MESON_TAC[]]);;
15404
15405 let INTEGRABLE_INCREASING_PRODUCT_UNIV = prove
15406  (`!f:real^1->real^N g B.
15407         f integrable_on (:real^1) /\
15408         (!x y. drop x <= drop y ==> g x <= g y) /\
15409         (!x. abs(g x) <= B)
15410          ==> (\x. g x % f x) integrable_on (:real^1)`,
15411   let lemma = prove
15412    (`!f:real^1->real^1 g B.
15413           f integrable_on (:real^1) /\
15414           (!x y. drop x <= drop y ==> g x <= g y) /\
15415           (!x. abs(g x) <= B)
15416            ==> (\x. g x % f x) integrable_on (:real^1)`,
15417     REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[INTEGRABLE_ALT_SUBSET] THEN
15418     REWRITE_TAC[IN_UNIV; ETA_AX] THEN STRIP_TAC THEN
15419     MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
15420      [REPEAT GEN_TAC THEN MATCH_MP_TAC INTEGRABLE_INCREASING_PRODUCT THEN
15421       ASM_SIMP_TAC[];
15422       DISCH_TAC] THEN
15423     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
15424     FIRST_X_ASSUM(MP_TAC o SPEC `e / (&8 * abs B + &8)`) THEN
15425     ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &8 * abs B + &8`] THEN
15426     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `C:real` THEN STRIP_TAC THEN
15427     ASM_REWRITE_TAC[] THEN
15428     SUBGOAL_THEN `~(ball(vec 0:real^1,C) = {})` ASSUME_TAC THENL
15429      [ASM_REWRITE_TAC[BALL_EQ_EMPTY; REAL_NOT_LE]; ALL_TAC] THEN
15430     MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`; `c:real^1`; `d:real^1`] THEN
15431     STRIP_TAC THEN SUBGOAL_THEN
15432      `~(interval[a:real^1,b] = {}) /\ ~(interval[c:real^1,d] = {})`
15433     MP_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
15434     REWRITE_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN STRIP_TAC THEN
15435     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET_INTERVAL_1]) THEN
15436     ASM_REWRITE_TAC[GSYM REAL_NOT_LE] THEN STRIP_TAC THEN
15437     MP_TAC(ISPECL [`\x. g x % (f:real^1->real^1) x`;
15438                    `c:real^1`; `b:real^1`; `a:real^1`] INTEGRAL_COMBINE) THEN
15439     MP_TAC(ISPECL [`\x. g x % (f:real^1->real^1) x`;
15440                    `c:real^1`; `d:real^1`; `b:real^1`] INTEGRAL_COMBINE) THEN
15441     ASM_REWRITE_TAC[] THEN
15442     ANTS_TAC THENL [ASM_REAL_ARITH_TAC; DISCH_THEN(SUBST1_TAC o SYM)] THEN
15443     DISCH_THEN(SUBST1_TAC o SYM) THEN
15444     REWRITE_TAC[REAL_NOT_LE; NORM_ARITH
15445      `norm(ab - ((ca + ab) + bd):real^1) = norm(ca + bd)`] THEN
15446     MP_TAC(ISPECL[`f:real^1->real^1`; `g:real^1->real`; `c:real^1`; `a:real^1`]
15447           SECOND_MEAN_VALUE_THEOREM) THEN
15448     ASM_SIMP_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN
15449     DISCH_THEN(X_CHOOSE_THEN `u:real^1` STRIP_ASSUME_TAC) THEN
15450     MP_TAC(ISPECL[`f:real^1->real^1`; `g:real^1->real`; `b:real^1`; `d:real^1`]
15451           SECOND_MEAN_VALUE_THEOREM) THEN
15452     ASM_SIMP_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN
15453     DISCH_THEN(X_CHOOSE_THEN `v:real^1` STRIP_ASSUME_TAC) THEN
15454     ASM_REWRITE_TAC[] THEN
15455     SUBGOAL_THEN
15456      `!x y. drop y <= drop a
15457             ==> norm(integral (interval[x,y]) (f:real^1->real^1))
15458                 < e / (&4 * abs B + &4)`
15459      (LABEL_TAC "L")
15460     THENL
15461      [REPEAT STRIP_TAC THEN
15462       ASM_CASES_TAC `drop x <= drop y` THENL
15463        [FIRST_X_ASSUM(fun th ->
15464          MP_TAC(SPECL[`a:real^1`; `b:real^1`; `y:real^1`; `b:real^1`] th) THEN
15465          MP_TAC(SPECL[`a:real^1`; `b:real^1`; `x:real^1`; `b:real^1`] th)) THEN
15466         ASM_REWRITE_TAC[SUBSET_INTERVAL_1; REAL_LE_REFL] THEN
15467         ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
15468         MP_TAC(ISPECL [`f:real^1->real^1`; `x:real^1`; `b:real^1`; `y:real^1`]
15469           INTEGRAL_COMBINE) THEN
15470         ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
15471          [ASM_ARITH_TAC; DISCH_THEN(SUBST1_TAC o SYM)] THEN
15472         MATCH_MP_TAC(NORM_ARITH
15473          `&2 * d = e
15474           ==> norm(ab - (xy + yb)) < d
15475               ==> norm(ab - yb) < d
15476                   ==> norm(xy:real^1) < e`) THEN
15477         CONV_TAC REAL_FIELD;
15478         SUBGOAL_THEN `interval[x:real^1,y] = {}` SUBST1_TAC THENL
15479          [REWRITE_TAC[INTERVAL_EQ_EMPTY_1] THEN ASM_REAL_ARITH_TAC;
15480           REWRITE_TAC[INTEGRAL_EMPTY; NORM_0] THEN
15481           MATCH_MP_TAC REAL_LT_DIV THEN ASM_REAL_ARITH_TAC]];
15482       ALL_TAC] THEN
15483     SUBGOAL_THEN
15484      `!x y. drop b <= drop x
15485             ==> norm(integral (interval[x,y]) (f:real^1->real^1))
15486                 < e / (&4 * abs B + &4)`
15487      (LABEL_TAC "R")
15488     THENL
15489      [REPEAT STRIP_TAC THEN
15490       ASM_CASES_TAC `drop x <= drop y` THENL
15491        [FIRST_X_ASSUM(fun th ->
15492          MP_TAC(SPECL[`a:real^1`; `b:real^1`; `a:real^1`; `x:real^1`] th) THEN
15493          MP_TAC(SPECL[`a:real^1`; `b:real^1`; `a:real^1`; `y:real^1`] th)) THEN
15494         ASM_REWRITE_TAC[SUBSET_INTERVAL_1; REAL_LE_REFL] THEN
15495         ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
15496         MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `y:real^1`; `x:real^1`]
15497           INTEGRAL_COMBINE) THEN
15498         ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
15499          [ASM_ARITH_TAC; DISCH_THEN(SUBST1_TAC o SYM)] THEN
15500         MATCH_MP_TAC(NORM_ARITH
15501          `&2 * d = e
15502           ==> norm(ab - (ax + xy)) < d
15503               ==> norm(ab - ax) < d
15504                   ==> norm(xy:real^1) < e`) THEN
15505         CONV_TAC REAL_FIELD;
15506         SUBGOAL_THEN `interval[x:real^1,y] = {}` SUBST1_TAC THENL
15507          [REWRITE_TAC[INTERVAL_EQ_EMPTY_1] THEN ASM_REAL_ARITH_TAC;
15508           REWRITE_TAC[INTEGRAL_EMPTY; NORM_0] THEN
15509           MATCH_MP_TAC REAL_LT_DIV THEN ASM_REAL_ARITH_TAC]];
15510       ALL_TAC] THEN
15511     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
15512     MATCH_MP_TAC REAL_LET_TRANS THEN
15513     EXISTS_TAC `&4 * B * e / (&4 * abs B + &4)` THEN CONJ_TAC THENL
15514      [MATCH_MP_TAC(NORM_ARITH
15515        `(norm a <= e /\ norm b <= e) /\ (norm c <= e /\ norm d <= e)
15516         ==> norm((a + b) + (c + d):real^1) <= &4 * e`) THEN
15517       REWRITE_TAC[NORM_MUL] THEN CONJ_TAC THENL
15518        [CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
15519         ASM_REWRITE_TAC[NORM_POS_LE; REAL_ABS_POS] THEN
15520         MATCH_MP_TAC REAL_LT_IMP_LE THEN
15521         REMOVE_THEN "L" MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC;
15522         CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
15523         ASM_REWRITE_TAC[NORM_POS_LE; REAL_ABS_POS] THEN
15524         MATCH_MP_TAC REAL_LT_IMP_LE THEN
15525         REMOVE_THEN "R" MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC];
15526       REWRITE_TAC[REAL_ARITH
15527        `&4 * B * e / y < e <=> e * (&4 * B) / y < e * &1`] THEN
15528       ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_LT_LDIV_EQ;
15529                    REAL_ARITH `&0 < &4 * abs B + &4`] THEN
15530       REAL_ARITH_TAC]) in
15531   GEN_TAC THEN ONCE_REWRITE_TAC[INTEGRABLE_COMPONENTWISE] THEN
15532   REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
15533   REWRITE_TAC[VECTOR_MUL_COMPONENT; LIFT_CMUL] THEN
15534   MATCH_MP_TAC lemma THEN EXISTS_TAC `B:real` THEN ASM_SIMP_TAC[]);;
15535
15536 let INTEGRABLE_INCREASING = prove
15537  (`!f:real^1->real^N a b.
15538         (!x y i. x IN interval[a,b] /\ y IN interval[a,b] /\
15539                  drop x <= drop y /\ 1 <= i /\ i <= dimindex(:N)
15540                  ==> f(x)$i <= f(y)$i)
15541         ==> f integrable_on interval[a,b]`,
15542   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[INTEGRABLE_COMPONENTWISE] THEN
15543   X_GEN_TAC `i:num` THEN STRIP_TAC THEN
15544   ONCE_REWRITE_TAC[GSYM REAL_MUL_RID] THEN
15545   REWRITE_TAC[LIFT_CMUL; LIFT_NUM] THEN
15546   MATCH_MP_TAC INTEGRABLE_INCREASING_PRODUCT THEN
15547   ASM_SIMP_TAC[INTEGRABLE_CONST]);;
15548
15549 let INTEGRABLE_INCREASING_1 = prove
15550  (`!f:real^1->real^1 a b.
15551         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15552                ==> drop(f x) <= drop(f y))
15553         ==> f integrable_on interval[a,b]`,
15554   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_INCREASING THEN
15555   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
15556   ASM_SIMP_TAC[IMP_IMP; FORALL_1; DIMINDEX_1; GSYM drop]);;
15557
15558 let INTEGRABLE_DECREASING_PRODUCT = prove
15559  (`!f:real^1->real^N g a b.
15560         f integrable_on interval[a,b] /\
15561         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15562                ==> g(y) <= g(x))
15563         ==> (\x. g(x) % f(x)) integrable_on interval[a,b]`,
15564   REPEAT STRIP_TAC THEN
15565   ONCE_REWRITE_TAC[VECTOR_ARITH `x % y:real^N = --(--x % y)`] THEN
15566   MATCH_MP_TAC INTEGRABLE_NEG THEN
15567   MATCH_MP_TAC INTEGRABLE_INCREASING_PRODUCT THEN
15568   ASM_REWRITE_TAC[REAL_LE_NEG2]);;
15569
15570 let INTEGRABLE_DECREASING_PRODUCT_UNIV = prove
15571  (`!f:real^1->real^N g B.
15572         f integrable_on (:real^1) /\
15573         (!x y. drop x <= drop y ==> g y <= g x) /\
15574         (!x. abs(g x) <= B)
15575          ==> (\x. g x % f x) integrable_on (:real^1)`,
15576   REPEAT STRIP_TAC THEN
15577   ONCE_REWRITE_TAC[VECTOR_ARITH `x % y:real^N = --(--x % y)`] THEN
15578   MATCH_MP_TAC INTEGRABLE_NEG THEN
15579   MATCH_MP_TAC INTEGRABLE_INCREASING_PRODUCT_UNIV THEN
15580   EXISTS_TAC `B:real` THEN ASM_REWRITE_TAC[REAL_LE_NEG2; REAL_ABS_NEG]);;
15581
15582 let INTEGRABLE_DECREASING = prove
15583  (`!f:real^1->real^N a b.
15584         (!x y i. x IN interval[a,b] /\ y IN interval[a,b] /\
15585                  drop x <= drop y /\ 1 <= i /\ i <= dimindex(:N)
15586                  ==> f(y)$i <= f(x)$i)
15587         ==> f integrable_on interval[a,b]`,
15588   REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN
15589   GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [GSYM VECTOR_NEG_NEG] THEN
15590   MATCH_MP_TAC INTEGRABLE_NEG THEN MATCH_MP_TAC INTEGRABLE_INCREASING THEN
15591   ASM_SIMP_TAC[VECTOR_NEG_COMPONENT; REAL_LE_NEG2]);;
15592
15593 let INTEGRABLE_DECREASING_1 = prove
15594  (`!f:real^1->real^1 a b.
15595         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15596                ==> drop(f y) <= drop(f x))
15597         ==> f integrable_on interval[a,b]`,
15598   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_DECREASING THEN
15599   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
15600   ASM_SIMP_TAC[IMP_IMP; FORALL_1; DIMINDEX_1; GSYM drop]);;
15601
15602 (* ------------------------------------------------------------------------- *)
15603 (* Bounded variation and variation function, for real^1->real^N functions.   *)
15604 (* ------------------------------------------------------------------------- *)
15605
15606 parse_as_infix("has_bounded_variation_on",(12,"right"));;
15607
15608 let has_bounded_variation_on = new_definition
15609  `(f:real^1->real^N) has_bounded_variation_on s <=>
15610         (\k. f(interval_upperbound k) - f(interval_lowerbound k))
15611         has_bounded_setvariation_on s`;;
15612
15613 let vector_variation = new_definition
15614  `vector_variation s (f:real^1->real^N) =
15615   set_variation s (\k. f(interval_upperbound k) - f(interval_lowerbound k))`;;
15616
15617 let HAS_BOUNDED_VARIATION_ON_EQ = prove
15618  (`!f g:real^1->real^N s.
15619         (!x. x IN s ==> f x = g x) /\ f has_bounded_variation_on s
15620         ==> g has_bounded_variation_on s`,
15621   REPEAT GEN_TAC THEN
15622   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
15623   REWRITE_TAC[has_bounded_variation_on] THEN
15624   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_BOUNDED_SETVARIATION_ON_EQ) THEN
15625   SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND;
15626            GSYM INTERVAL_NE_EMPTY] THEN
15627   ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET]);;
15628
15629 let VECTOR_VARIATION_EQ = prove
15630  (`!f g:real^1->real^N s.
15631         (!x. x IN s ==> f x = g x)
15632         ==> vector_variation s f = vector_variation s g`,
15633   REPEAT STRIP_TAC THEN REWRITE_TAC[vector_variation] THEN
15634   MATCH_MP_TAC SET_VARIATION_EQ THEN
15635   SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND;
15636            GSYM INTERVAL_NE_EMPTY] THEN
15637   ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET]);;
15638
15639 let HAS_BOUNDED_VARIATION_ON_COMPONENTWISE = prove
15640  (`!f:real^1->real^N s.
15641         f has_bounded_variation_on s <=>
15642         !i. 1 <= i /\ i <= dimindex(:N)
15643             ==> (\x. lift(f x$i)) has_bounded_variation_on s`,
15644   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
15645   GEN_REWRITE_TAC LAND_CONV [HAS_BOUNDED_SETVARIATION_ON_COMPONENTWISE] THEN
15646   REWRITE_TAC[VECTOR_SUB_COMPONENT; LIFT_SUB]);;
15647
15648 let VARIATION_EQUAL_LEMMA = prove
15649  (`!ms ms'.
15650         (!s. ms'(ms s) = s /\ ms(ms' s) = s) /\
15651         (!d t. d division_of t
15652                ==> (IMAGE (IMAGE ms) d) division_of IMAGE ms t /\
15653                    (IMAGE (IMAGE ms') d) division_of IMAGE ms' t) /\
15654         (!a b. ~(interval[a,b] = {})
15655                ==> IMAGE ms' (interval [a,b]) = interval[ms' a,ms' b] \/
15656                    IMAGE ms' (interval [a,b]) = interval[ms' b,ms' a])
15657    ==> (!f:real^1->real^N s.
15658             (\x. f(ms' x)) has_bounded_variation_on (IMAGE ms s) <=>
15659             f has_bounded_variation_on s) /\
15660        (!f:real^1->real^N s.
15661             vector_variation (IMAGE ms s) (\x. f(ms' x)) =
15662             vector_variation s f)`,
15663   REPEAT GEN_TAC THEN STRIP_TAC THEN
15664   REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN
15665   GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `f:real^1->real^N` THEN
15666   MP_TAC(ISPECL
15667    [`\f k. (f:(real^1->bool)->real^N) (IMAGE (ms':real^1->real^1) k)`;
15668     `IMAGE (ms:real^1->real^1)`;
15669     `IMAGE (ms':real^1->real^1)`]
15670   SETVARIATION_EQUAL_LEMMA) THEN
15671   ANTS_TAC THENL
15672    [ASM_SIMP_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; IMAGE_SUBSET] THEN
15673     MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`] THEN STRIP_TAC THEN
15674     FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN
15675     ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
15676     ASM_MESON_TAC[IMAGE_EQ_EMPTY];
15677     ALL_TAC] THEN
15678   REWRITE_TAC[] THEN GEN_REWRITE_TAC LAND_CONV [AND_FORALL_THM] THEN
15679   DISCH_THEN(fun th ->
15680     MP_TAC(SPEC `\k. (f:real^1->real^N) (interval_upperbound k) -
15681                      f (interval_lowerbound k)` th)) THEN
15682   REWRITE_TAC[] THEN DISCH_THEN(fun th -> ONCE_REWRITE_TAC[GSYM th]) THEN
15683   GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `s:real^1->bool` THEN
15684   REWRITE_TAC[has_bounded_setvariation_on; set_variation] THEN
15685   CONJ_TAC THENL
15686    [REPLICATE_TAC 3 (AP_TERM_TAC THEN ABS_TAC) THEN
15687     REWRITE_TAC[TAUT `((p ==> q) <=> (p ==> r)) <=> p ==> (q <=> r)`] THEN
15688     STRIP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC;
15689     AP_TERM_TAC THEN
15690     MATCH_MP_TAC(SET_RULE
15691      `(!x. P x ==> f x = g x) ==> {f x | P x} = {g x | P x}`) THEN
15692     GEN_TAC THEN STRIP_TAC] THEN
15693   MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th ->
15694    GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION_NONEMPTY th]) THEN
15695   MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`] THEN STRIP_TAC THEN
15696   FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN
15697   ASM_REWRITE_TAC[] THEN DISCH_THEN(DISJ_CASES_THEN MP_TAC) THEN
15698   DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
15699    `IMAGE f s = s' ==> ~(s = {}) ==> IMAGE f s = s' /\ ~(s' = {})`)) THEN
15700   ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
15701   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY_1]) THEN
15702   ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1] THEN
15703   NORM_ARITH_TAC);;
15704
15705 let HAS_BOUNDED_VARIATION_ON_SUBSET = prove
15706  (`!f:real^1->real^N s t.
15707         f has_bounded_variation_on s /\ t SUBSET s
15708         ==> f has_bounded_variation_on t`,
15709   REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_SUBSET; has_bounded_variation_on]);;
15710
15711 let HAS_BOUNDED_VARIATION_ON_CONST = prove
15712  (`!s c:real^N. (\x. c) has_bounded_variation_on s`,
15713   REWRITE_TAC[has_bounded_variation_on; VECTOR_SUB_REFL;
15714               HAS_BOUNDED_SETVARIATION_ON_0]);;
15715
15716 let VECTOR_VARIATION_CONST = prove
15717  (`!s c:real^N. vector_variation s (\x. c) = &0`,
15718   REWRITE_TAC[vector_variation; VECTOR_SUB_REFL; SET_VARIATION_0]);;
15719
15720 let HAS_BOUNDED_VARIATION_ON_CMUL = prove
15721  (`!f:real^1->real^N c s.
15722         f has_bounded_variation_on s
15723         ==> (\x. c % f x) has_bounded_variation_on s`,
15724   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
15725   REWRITE_TAC[GSYM VECTOR_SUB_LDISTRIB; HAS_BOUNDED_SETVARIATION_ON_CMUL]);;
15726
15727 let HAS_BOUNDED_VARIATION_ON_NEG = prove
15728  (`!f:real^1->real^N s.
15729         f has_bounded_variation_on s
15730         ==> (\x. --f x) has_bounded_variation_on s`,
15731   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
15732   REWRITE_TAC[VECTOR_ARITH `--a - --b:real^N = --(a - b)`;
15733               HAS_BOUNDED_SETVARIATION_ON_NEG]);;
15734
15735 let HAS_BOUNDED_VARIATION_ON_ADD = prove
15736  (`!f g:real^1->real^N s.
15737         f has_bounded_variation_on s /\ g has_bounded_variation_on s
15738         ==> (\x. f x + g x) has_bounded_variation_on s`,
15739   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
15740   REWRITE_TAC[VECTOR_ARITH `(f + g) - (f' + g'):real^N = (f - f') + (g - g')`;
15741               HAS_BOUNDED_SETVARIATION_ON_ADD]);;
15742
15743 let HAS_BOUNDED_VARIATION_ON_SUB = prove
15744  (`!f g:real^1->real^N s.
15745         f has_bounded_variation_on s /\ g has_bounded_variation_on s
15746         ==> (\x. f x - g x) has_bounded_variation_on s`,
15747   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
15748   REWRITE_TAC[VECTOR_ARITH `(f - g) - (f' - g'):real^N = (f - f') - (g - g')`;
15749               HAS_BOUNDED_SETVARIATION_ON_SUB]);;
15750
15751 let HAS_BOUNDED_VARIATION_ON_COMPOSE_LINEAR = prove
15752  (`!f:real^1->real^M g:real^M->real^N s.
15753         f has_bounded_variation_on s /\ linear g
15754         ==> (g o f) has_bounded_variation_on s`,
15755   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
15756   SIMP_TAC[o_THM; GSYM LINEAR_SUB] THEN
15757   DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_SETVARIATION_ON_COMPOSE_LINEAR) THEN
15758   REWRITE_TAC[o_DEF]);;
15759
15760 let HAS_BOUNDED_VARIATION_ON_NULL = prove
15761  (`!f:real^1->real^N s.
15762         content s = &0 /\ bounded s ==> f has_bounded_variation_on s`,
15763   REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
15764   MATCH_MP_TAC HAS_BOUNDED_SETVARIATION_ON_NULL THEN
15765   ASM_SIMP_TAC[INTERVAL_BOUNDS_NULL_1; VECTOR_SUB_REFL]);;
15766
15767 let HAS_BOUNDED_VARIATION_ON_EMPTY = prove
15768  (`!f:real^1->real^N. f has_bounded_variation_on {}`,
15769   MESON_TAC[CONTENT_EMPTY; BOUNDED_EMPTY; HAS_BOUNDED_VARIATION_ON_NULL]);;
15770
15771 let VECTOR_VARIATION_ON_NULL = prove
15772  (`!f s. content s = &0 /\ bounded s ==> vector_variation s f = &0`,
15773   REPEAT STRIP_TAC THEN REWRITE_TAC[vector_variation] THEN
15774   MATCH_MP_TAC SET_VARIATION_ON_NULL THEN ASM_REWRITE_TAC[] THEN
15775   SIMP_TAC[INTERVAL_BOUNDS_NULL_1; VECTOR_SUB_REFL]);;
15776
15777 let HAS_BOUNDED_VARIATION_ON_NORM = prove
15778  (`!f:real^1->real^N s.
15779         f has_bounded_variation_on s
15780         ==> (\x. lift(norm(f x))) has_bounded_variation_on s`,
15781   REWRITE_TAC[has_bounded_variation_on; has_bounded_setvariation_on] THEN
15782   REPEAT GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
15783   REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
15784   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
15785   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN
15786   MATCH_MP_TAC SUM_LE THEN
15787   REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP; DROP_SUB] THEN
15788   CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_FINITE]; NORM_ARITH_TAC]);;
15789
15790 let HAS_BOUNDED_VARIATION_ON_MAX = prove
15791  (`!f g s. f has_bounded_variation_on s /\ g has_bounded_variation_on s
15792            ==> (\x. lift(max (drop(f x)) (drop(g x))))
15793                has_bounded_variation_on s`,
15794   REPEAT STRIP_TAC THEN
15795   REWRITE_TAC[REAL_ARITH `max a b = inv(&2) * (a + b + abs(a - b))`] THEN
15796   REWRITE_TAC[LIFT_CMUL; LIFT_ADD; LIFT_DROP; GSYM DROP_SUB] THEN
15797   REWRITE_TAC[drop; GSYM NORM_REAL] THEN
15798   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_CMUL THEN
15799   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_ADD THEN ASM_REWRITE_TAC[] THEN
15800   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_ADD THEN ASM_REWRITE_TAC[] THEN
15801   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NORM THEN
15802   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN ASM_REWRITE_TAC[]);;
15803
15804 let HAS_BOUNDED_VARIATION_ON_MIN = prove
15805  (`!f g s. f has_bounded_variation_on s /\ g has_bounded_variation_on s
15806            ==> (\x. lift(min (drop(f x)) (drop(g x))))
15807                has_bounded_variation_on s`,
15808   REPEAT STRIP_TAC THEN
15809   REWRITE_TAC[REAL_ARITH `min a b = inv(&2) * ((a + b) - abs(a - b))`] THEN
15810   REWRITE_TAC[LIFT_CMUL; LIFT_ADD; LIFT_DROP; LIFT_SUB; GSYM DROP_SUB] THEN
15811   REWRITE_TAC[drop; GSYM NORM_REAL] THEN
15812   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_CMUL THEN
15813   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN
15814   ASM_SIMP_TAC[HAS_BOUNDED_VARIATION_ON_ADD] THEN
15815   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NORM THEN
15816   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN ASM_REWRITE_TAC[]);;
15817
15818 let HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS = prove
15819  (`!f:real^1->real^N s.
15820         f has_bounded_variation_on s
15821         ==> bounded { f(d) - f(c) | interval[c,d] SUBSET s /\
15822                                     ~(interval[c,d] = {})}`,
15823   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
15824   DISCH_THEN(MP_TAC o MATCH_MP
15825    HAS_BOUNDED_SETVARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS) THEN
15826   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN
15827   GEN_REWRITE_TAC I [SUBSET] THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN
15828   MAP_EVERY X_GEN_TAC [`d:real^1`; `c:real^1`] THEN
15829   REWRITE_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN STRIP_TAC THEN
15830   REWRITE_TAC[IN_ELIM_THM] THEN
15831   MAP_EVERY EXISTS_TAC [`c:real^1`; `d:real^1`] THEN
15832   ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1]);;
15833
15834 let HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL = prove
15835  (`!f:real^1->real^N a b.
15836         f has_bounded_variation_on interval[a,b]
15837         ==> bounded(IMAGE f (interval[a,b]))`,
15838   REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP
15839    HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS) THEN
15840   REWRITE_TAC[BOUNDED_POS_LT; FORALL_IN_GSPEC; FORALL_IN_IMAGE] THEN
15841   DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
15842   EXISTS_TAC `B + norm((f:real^1->real^N) a)` THEN
15843   ASM_SIMP_TAC[NORM_ARITH `&0 < B ==> &0 < B + norm(x:real^N)`] THEN
15844   X_GEN_TAC `x:real^1` THEN REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN
15845   FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^1`; `a:real^1`]) THEN
15846   REWRITE_TAC[SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1] THEN ANTS_TAC THENL
15847    [ASM_REAL_ARITH_TAC; NORM_ARITH_TAC]);;
15848
15849 let HAS_BOUNDED_VARIATION_ON_MUL = prove
15850  (`!f g:real^1->real^N a b.
15851         f has_bounded_variation_on interval[a,b] /\
15852         g has_bounded_variation_on interval[a,b]
15853         ==> (\x. drop(f x) % g x) has_bounded_variation_on interval[a,b]`,
15854   REPEAT GEN_TAC THEN DISCH_TAC THEN
15855   SUBGOAL_THEN
15856     `bounded(IMAGE (f:real^1->real^1) (interval[a,b])) /\
15857      bounded(IMAGE (g:real^1->real^N) (interval[a,b]))`
15858   MP_TAC THENL
15859    [ASM_SIMP_TAC[HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL];
15860     REWRITE_TAC[BOUNDED_POS_LT; FORALL_IN_IMAGE]] THEN
15861   DISCH_THEN(CONJUNCTS_THEN2
15862    (X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC)
15863    (X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC)) THEN
15864   FIRST_X_ASSUM(CONJUNCTS_THEN MP_TAC) THEN
15865   REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_INTERVAL;
15866               has_bounded_variation_on] THEN
15867   DISCH_THEN(X_CHOOSE_THEN `C2:real` (LABEL_TAC "G")) THEN
15868   DISCH_THEN(X_CHOOSE_THEN `C1:real` (LABEL_TAC "F")) THEN
15869   EXISTS_TAC `B1 * C2 + B2 * C1:real` THEN
15870   X_GEN_TAC `d:(real^1->bool)->bool` THEN DISCH_TAC THEN
15871   MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
15872    `B1 * sum d (\k. norm((g:real^1->real^N)(interval_upperbound k) -
15873                          g(interval_lowerbound k))) +
15874     B2 * sum d (\k. norm((f:real^1->real^1)(interval_upperbound k) -
15875                          f(interval_lowerbound k)))` THEN
15876   CONJ_TAC THENL
15877    [ALL_TAC; MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_SIMP_TAC[REAL_LE_LMUL_EQ]] THEN
15878   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
15879   ASM_SIMP_TAC[GSYM SUM_LMUL; GSYM SUM_ADD] THEN
15880   MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[] THEN
15881   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
15882   MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN
15883   ONCE_REWRITE_TAC[VECTOR_ARITH
15884    `f' % g' - f % g:real^N = f' % (g' - g) + (f' - f) % g`] THEN
15885   MATCH_MP_TAC(NORM_ARITH
15886     `norm x <= a /\ norm y <= b ==> norm(x + y) <= a + b`) THEN
15887   REWRITE_TAC[NORM_MUL; NORM_REAL] THEN
15888   REWRITE_TAC[drop; GSYM NORM_REAL; GSYM VECTOR_SUB_COMPONENT] THEN
15889   SUBGOAL_THEN `~(interval[u:real^1,v] = {})` MP_TAC THENL
15890    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
15891   REWRITE_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN DISCH_TAC THEN
15892   ASM_SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
15893   SUBGOAL_THEN `interval[u:real^1,v] SUBSET interval[a,b]` MP_TAC THENL
15894    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
15895   ASM_REWRITE_TAC[SUBSET_INTERVAL_1; GSYM REAL_NOT_LE] THEN
15896   STRIP_TAC THEN
15897   GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [REAL_MUL_SYM] THEN
15898   CONJ_TAC THEN MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN
15899   MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
15900   REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC);;
15901
15902 let VECTOR_VARIATION_POS_LE = prove
15903  (`!f:real^1->real^N s.
15904         f has_bounded_variation_on s ==> &0 <= vector_variation s f`,
15905   REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN
15906   REWRITE_TAC[SET_VARIATION_POS_LE]);;
15907
15908 let VECTOR_VARIATION_GE_NORM_FUNCTION = prove
15909  (`!f:real^1->real^N s a b.
15910         f has_bounded_variation_on s /\ segment[a,b] SUBSET s
15911         ==> norm(f b - f a) <= vector_variation s f`,
15912   REWRITE_TAC[FORALL_LIFT] THEN GEN_TAC THEN GEN_TAC THEN
15913   MATCH_MP_TAC REAL_WLOG_LE THEN CONJ_TAC THENL
15914    [MESON_TAC[SEGMENT_SYM; NORM_SUB]; ALL_TAC] THEN
15915   REWRITE_TAC[FORALL_DROP; LIFT_DROP; has_bounded_variation_on] THEN
15916   REPEAT STRIP_TAC THEN MP_TAC(ISPECL
15917   [`\k. (f:real^1->real^N)(interval_upperbound k) - f(interval_lowerbound k)`;
15918    `s:real^1->bool`; `a:real^1`; `b:real^1`] SET_VARIATION_GE_FUNCTION) THEN
15919   ASM_REWRITE_TAC[vector_variation; INTERVAL_NE_EMPTY_1] THEN
15920   ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1] THEN
15921   ASM_MESON_TAC[SEGMENT_1]);;
15922
15923 let VECTOR_VARIATION_GE_DROP_FUNCTION = prove
15924  (`!f s a b.
15925         f has_bounded_variation_on s /\ segment[a,b] SUBSET s
15926         ==> drop(f b) - drop(f a) <= vector_variation s f`,
15927   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
15928   EXISTS_TAC `norm((f:real^1->real^1) b - f a)` THEN
15929   ASM_SIMP_TAC[VECTOR_VARIATION_GE_NORM_FUNCTION] THEN
15930   REWRITE_TAC[NORM_REAL; DROP_SUB; GSYM drop] THEN REAL_ARITH_TAC);;
15931
15932 let VECTOR_VARIATION_CONST_EQ = prove
15933  (`!f:real^1->real^N s.
15934         is_interval s /\ f has_bounded_variation_on s
15935         ==> (vector_variation s f = &0 <=> ?c. !x. x IN s ==> f x = c)`,
15936   REPEAT STRIP_TAC THEN EQ_TAC THENL
15937    [DISCH_TAC THEN REWRITE_TAC[MESON[]
15938      `(?c. !x. P x ==> f x = c) <=> !a b. P a /\ P b ==> f a = f b`] THEN
15939     MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`] THEN STRIP_TAC THEN
15940     MP_TAC(ISPECL [`f:real^1->real^N`; `s:real^1->bool`;
15941         `a:real^1`; `b:real^1`] VECTOR_VARIATION_GE_NORM_FUNCTION) THEN
15942     ANTS_TAC THENL
15943      [ASM_MESON_TAC[IS_INTERVAL_CONVEX_1; CONVEX_CONTAINS_SEGMENT];
15944       ASM_REWRITE_TAC[] THEN CONV_TAC NORM_ARITH];
15945     DISCH_THEN(X_CHOOSE_TAC `c:real^N`) THEN
15946     MP_TAC(ISPECL [`f:real^1->real^N`; `(\x. c):real^1->real^N`;
15947                    `s:real^1->bool`] VECTOR_VARIATION_EQ) THEN
15948     ASM_SIMP_TAC[VECTOR_VARIATION_CONST]]);;
15949
15950 let VECTOR_VARIATION_MONOTONE = prove
15951  (`!f s t. f has_bounded_variation_on s /\ t SUBSET s
15952            ==> vector_variation t f <= vector_variation s f`,
15953   REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN
15954   REWRITE_TAC[SET_VARIATION_MONOTONE]);;
15955
15956 let VECTOR_VARIATION_NEG = prove
15957  (`!f:real^1->real^N s.
15958         vector_variation s (\x. --(f x)) = vector_variation s f`,
15959   REPEAT GEN_TAC THEN REWRITE_TAC[vector_variation; set_variation] THEN
15960   REWRITE_TAC[NORM_ARITH `norm(--x - --y:real^N) = norm(x - y)`]);;
15961
15962 let VECTOR_VARIATION_TRIANGLE = prove
15963  (`!f g:real^1->real^N s.
15964         f has_bounded_variation_on s /\ g has_bounded_variation_on s
15965         ==> vector_variation s (\x. f x + g x)
15966               <= vector_variation s f + vector_variation s g`,
15967   REPEAT GEN_TAC THEN
15968   REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN
15969   DISCH_THEN(MP_TAC o MATCH_MP SET_VARIATION_TRIANGLE) THEN
15970   REWRITE_TAC[VECTOR_ARITH `(a + b) - (c + d):real^N = (a - c) + (b - d)`]);;
15971
15972 let OPERATIVE_FUNCTION_ENDPOINT_DIFF = prove
15973  (`!f:real^1->real^N.
15974     operative (+) (\k. f (interval_upperbound k) - f (interval_lowerbound k))`,
15975   GEN_TAC THEN
15976   SIMP_TAC[operative; INTERVAL_BOUNDS_NULL_1; VECTOR_SUB_REFL] THEN
15977   REWRITE_TAC[NEUTRAL_VECTOR_ADD; DIMINDEX_1; FORALL_1; GSYM drop] THEN
15978   REWRITE_TAC[FORALL_DROP] THEN
15979   MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`; `c:real^1`] THEN
15980   ASM_CASES_TAC `interval[a:real^1,b] = {}` THENL
15981    [ASM_REWRITE_TAC[INTER_EMPTY; INTERVAL_BOUNDS_EMPTY_1] THEN
15982     VECTOR_ARITH_TAC;
15983     ALL_TAC] THEN
15984   ASM_CASES_TAC `interval[a,b] INTER {x | drop x <= drop c} = {}` THENL
15985    [ASM_REWRITE_TAC[INTERVAL_BOUNDS_EMPTY_1; VECTOR_SUB_REFL] THEN
15986     SUBGOAL_THEN `interval[a,b] INTER {x | drop x >= drop c} = interval[a,b]`
15987      (fun th -> REWRITE_TAC[th; VECTOR_ADD_LID]) THEN
15988     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
15989      `i INTER s = {} ==> s UNION t = UNIV ==> i INTER t = i`)) THEN
15990     REWRITE_TAC[EXTENSION; IN_UNIV; IN_UNION; IN_ELIM_THM] THEN
15991     REAL_ARITH_TAC;
15992     ALL_TAC] THEN
15993   ASM_CASES_TAC `interval[a,b] INTER {x | drop x >= drop c} = {}` THENL
15994    [ASM_REWRITE_TAC[INTERVAL_BOUNDS_EMPTY_1; VECTOR_SUB_REFL] THEN
15995     SUBGOAL_THEN `interval[a,b] INTER {x | drop x <= drop c} = interval[a,b]`
15996      (fun th -> REWRITE_TAC[th; VECTOR_ADD_RID]) THEN
15997     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
15998      `i INTER s = {} ==> s UNION t = UNIV ==> i INTER t = i`)) THEN
15999     REWRITE_TAC[EXTENSION; IN_UNIV; IN_UNION; IN_ELIM_THM] THEN
16000     REAL_ARITH_TAC;
16001     ALL_TAC] THEN
16002   POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
16003   SIMP_TAC[INTERVAL_SPLIT; drop; DIMINDEX_1; LE_REFL] THEN
16004   REWRITE_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN
16005   SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1] THEN
16006   SIMP_TAC[drop; LAMBDA_BETA; DIMINDEX_1; LE_REFL] THEN STRIP_TAC THEN
16007   MATCH_MP_TAC(VECTOR_ARITH
16008    `fx:real^N = fy ==> fb - fa = fx - fa + fb - fy`) THEN
16009   AP_TERM_TAC THEN REWRITE_TAC[GSYM DROP_EQ; drop] THEN
16010   SIMP_TAC[LAMBDA_BETA; DIMINDEX_1; LE_REFL] THEN ASM_REAL_ARITH_TAC);;
16011
16012 let OPERATIVE_REAL_FUNCTION_ENDPOINT_DIFF = prove
16013  (`!f:real^1->real.
16014     operative (+) (\k. f (interval_upperbound k) - f (interval_lowerbound k))`,
16015   GEN_TAC THEN
16016   MP_TAC(ISPEC `lift o (f:real^1->real)` OPERATIVE_FUNCTION_ENDPOINT_DIFF) THEN
16017   REWRITE_TAC[operative; NEUTRAL_REAL_ADD; NEUTRAL_VECTOR_ADD] THEN
16018   REWRITE_TAC[o_THM; GSYM LIFT_SUB; GSYM LIFT_ADD; GSYM LIFT_NUM] THEN
16019   REWRITE_TAC[LIFT_EQ]);;
16020
16021 let OPERATIVE_LIFTED_VECTOR_VARIATION = prove
16022  (`!f:real^1->real^N.
16023         operative (lifted(+))
16024                   (\i. if f has_bounded_variation_on i
16025                        then SOME(vector_variation i f) else NONE)`,
16026   GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN
16027   MATCH_MP_TAC OPERATIVE_LIFTED_SETVARIATION THEN
16028   REWRITE_TAC[OPERATIVE_FUNCTION_ENDPOINT_DIFF]);;
16029
16030 let HAS_BOUNDED_VARIATION_ON_DIVISION = prove
16031  (`!f:real^1->real^N a b d.
16032         d division_of interval[a,b]
16033         ==> ((!k. k IN d ==> f has_bounded_variation_on k) <=>
16034              f has_bounded_variation_on interval[a,b])`,
16035   REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
16036   MATCH_MP_TAC HAS_BOUNDED_SETVARIATION_ON_DIVISION THEN
16037   ASM_REWRITE_TAC[OPERATIVE_FUNCTION_ENDPOINT_DIFF]);;
16038
16039 let VECTOR_VARIATION_ON_DIVISION = prove
16040  (`!f:real^1->real^N a b d.
16041         d division_of interval[a,b] /\
16042         f has_bounded_variation_on interval[a,b]
16043         ==> sum d (\k. vector_variation k f) =
16044             vector_variation (interval[a,b]) f`,
16045   REPEAT STRIP_TAC THEN REWRITE_TAC[vector_variation] THEN
16046   MATCH_MP_TAC SET_VARIATION_ON_DIVISION THEN
16047   ASM_REWRITE_TAC[OPERATIVE_FUNCTION_ENDPOINT_DIFF; GSYM
16048                   has_bounded_variation_on]);;
16049
16050 let HAS_BOUNDED_VARIATION_ON_COMBINE = prove
16051  (`!f:real^1->real^N a b c.
16052         drop a <= drop c /\ drop c <= drop b
16053         ==> (f has_bounded_variation_on interval[a,b] <=>
16054              f has_bounded_variation_on interval[a,c] /\
16055              f has_bounded_variation_on interval[c,b])`,
16056   REPEAT STRIP_TAC THEN MP_TAC
16057    (ISPEC `f:real^1->real^N` OPERATIVE_LIFTED_VECTOR_VARIATION) THEN
16058   REWRITE_TAC[operative; FORALL_1; FORALL_DROP; DIMINDEX_1] THEN
16059   DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`; `c:real^1`] o
16060    CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN
16061   SUBGOAL_THEN
16062    `interval[a,b] INTER {x:real^1 | x$1 <= drop c} = interval[a,c] /\
16063     interval[a,b] INTER {x:real^1 | x$1 >= drop c} = interval[c,b]`
16064    (fun th -> REWRITE_TAC[th])
16065   THENL
16066    [SIMP_TAC[EXTENSION; IN_INTER; GSYM drop; IN_INTERVAL_1; IN_ELIM_THM] THEN
16067     ASM_REAL_ARITH_TAC;
16068     REPEAT(COND_CASES_TAC THEN
16069            ASM_REWRITE_TAC[distinctness "option"; lifted])]);;
16070
16071 let VECTOR_VARIATION_COMBINE = prove
16072  (`!f:real^1->real^N a b c.
16073         drop a <= drop c /\
16074         drop c <= drop b /\
16075         f has_bounded_variation_on interval[a,b]
16076         ==> vector_variation (interval[a,c]) f +
16077             vector_variation (interval[c,b]) f =
16078             vector_variation (interval[a,b]) f`,
16079   REPEAT STRIP_TAC THEN MP_TAC
16080    (ISPEC `f:real^1->real^N` OPERATIVE_LIFTED_VECTOR_VARIATION) THEN
16081   REWRITE_TAC[operative; FORALL_1; FORALL_DROP; DIMINDEX_1] THEN
16082   DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`; `c:real^1`] o
16083    CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN REPEAT(COND_CASES_TAC THENL
16084     [ALL_TAC;
16085      ASM_MESON_TAC[HAS_BOUNDED_VARIATION_ON_SUBSET; INTER_SUBSET]]) THEN
16086   REWRITE_TAC[lifted; injectivity "option"] THEN DISCH_THEN SUBST1_TAC THEN
16087   SIMP_TAC[INTERVAL_SPLIT; DIMINDEX_1; LE_REFL] THEN
16088   BINOP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
16089   SIMP_TAC[EXTENSION; IN_INTERVAL_1; drop; LAMBDA_BETA;
16090            DIMINDEX_1; LE_REFL] THEN
16091   REWRITE_TAC[GSYM drop] THEN ASM_REAL_ARITH_TAC);;
16092
16093 let VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE = prove
16094  (`!f a b c d.
16095         f has_bounded_variation_on interval[a,b] /\
16096         interval[c,d] SUBSET interval[a,b] /\ ~(interval[c,d] = {})
16097         ==> vector_variation (interval[c,d]) f - drop(f d - f c) <=
16098             vector_variation (interval[a,b]) f - drop(f b - f a)`,
16099   REWRITE_TAC[SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN
16100   REPEAT STRIP_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
16101   SUBGOAL_THEN
16102    `drop(f c) - drop(f a) <= vector_variation(interval[a,c]) f /\
16103     drop(f b) - drop(f d) <= vector_variation(interval[d,b]) f`
16104   MP_TAC THENL
16105    [CONJ_TAC THEN MATCH_MP_TAC VECTOR_VARIATION_GE_DROP_FUNCTION THEN
16106     ASM_REWRITE_TAC[SEGMENT_1; SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1] THEN
16107     (CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC]) THEN
16108     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16109       HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
16110     REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
16111     ALL_TAC] THEN
16112   REWRITE_TAC[DROP_SUB] THEN
16113   MP_TAC(ISPEC `f:real^1->real^1` VECTOR_VARIATION_COMBINE) THEN
16114   DISCH_THEN(fun th ->
16115     MP_TAC(SPECL [`a:real^1`; `b:real^1`; `d:real^1`] th) THEN
16116     MP_TAC(SPECL [`a:real^1`; `d:real^1`; `c:real^1`] th)) THEN
16117   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
16118    [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16119      HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
16120     REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
16121     ASM_REAL_ARITH_TAC]);;
16122
16123 let INCREASING_BOUNDED_VARIATION = prove
16124  (`!f a b.
16125         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
16126                ==> drop(f x) <= drop(f y))
16127         ==> f has_bounded_variation_on interval[a,b]`,
16128   REPEAT STRIP_TAC THEN
16129   ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN
16130   ASM_REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_EMPTY] THEN
16131   REWRITE_TAC[has_bounded_variation_on;
16132               HAS_BOUNDED_SETVARIATION_ON_INTERVAL] THEN
16133   EXISTS_TAC `drop(f b) - drop(f(a:real^1))` THEN
16134   MP_TAC(MATCH_MP (REWRITE_RULE
16135    [TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`]
16136    OPERATIVE_DIVISION) (SPEC `drop o (f:real^1->real^1)`
16137       OPERATIVE_REAL_FUNCTION_ENDPOINT_DIFF)) THEN
16138   MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
16139   DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN
16140   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
16141   ASM_REWRITE_TAC[GSYM sum; MONOIDAL_REAL_ADD] THEN
16142   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
16143   ASM_SIMP_TAC[o_THM; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
16144   DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC REAL_EQ_IMP_LE THEN
16145   MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[NORM_REAL; GSYM drop] THEN
16146   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
16147   MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN
16148   SUBGOAL_THEN `~(interval[u:real^1,v] = {})` ASSUME_TAC THENL
16149    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
16150    RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
16151   ASM_SIMP_TAC[DROP_SUB; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
16152   MATCH_MP_TAC(REAL_ARITH `x <= y ==> abs(y - x) = y - x`) THEN
16153   FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
16154   SUBGOAL_THEN `interval[u:real^1,v] SUBSET interval[a,b]` MP_TAC THENL
16155    [ASM_MESON_TAC[division_of]; REWRITE_TAC[SUBSET_INTERVAL_1]] THEN
16156   ASM_REAL_ARITH_TAC);;
16157
16158 let DECREASING_BOUNDED_VARIATION = prove
16159  (`!f a b.
16160         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
16161                ==> drop(f y) <= drop(f x))
16162          ==> f has_bounded_variation_on interval[a,b]`,
16163   REPEAT GEN_TAC THEN
16164   GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV o BINDER_CONV o RAND_CONV)
16165    [GSYM REAL_LE_NEG2] THEN
16166   REWRITE_TAC[GSYM DROP_NEG] THEN
16167   DISCH_THEN(MP_TAC o MATCH_MP INCREASING_BOUNDED_VARIATION) THEN
16168   DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_ON_NEG) THEN
16169   REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);;
16170
16171 let INCREASING_VECTOR_VARIATION = prove
16172  (`!f a b.
16173         ~(interval[a,b] = {}) /\
16174         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
16175                ==> drop(f x) <= drop(f y))
16176         ==> vector_variation (interval[a,b]) f = drop(f b) - drop(f a)`,
16177   REPEAT STRIP_TAC THEN REWRITE_TAC[vector_variation] THEN
16178   REWRITE_TAC[SET_VARIATION_ON_INTERVAL] THEN
16179   SUBGOAL_THEN
16180    `{sum d (\k. norm (f (interval_upperbound k) - f (interval_lowerbound k))) |
16181      d division_of interval[a:real^1,b]} =
16182     {drop (f b) - drop(f a)}`
16183    (fun th -> SIMP_TAC[SUP_INSERT_FINITE; FINITE_EMPTY; th]) THEN
16184   MATCH_MP_TAC(SET_RULE
16185    `(?x. P x) /\ (!x. P x ==> f x = a) ==> {f x | P x} = {a}`) THEN
16186   CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_SELF]; ALL_TAC] THEN
16187   MP_TAC(MATCH_MP (REWRITE_RULE
16188    [TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`]
16189    OPERATIVE_DIVISION) (SPEC `drop o (f:real^1->real^1)`
16190       OPERATIVE_REAL_FUNCTION_ENDPOINT_DIFF)) THEN
16191    MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
16192   DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN
16193   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
16194   ASM_REWRITE_TAC[GSYM sum; MONOIDAL_REAL_ADD] THEN
16195   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
16196   ASM_SIMP_TAC[o_THM; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
16197   DISCH_THEN(SUBST1_TAC o SYM) THEN
16198   MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[NORM_REAL; GSYM drop] THEN
16199   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
16200   MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN
16201   SUBGOAL_THEN `~(interval[u:real^1,v] = {})` ASSUME_TAC THENL
16202    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
16203    RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
16204   ASM_SIMP_TAC[DROP_SUB; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
16205   MATCH_MP_TAC(REAL_ARITH `x <= y ==> abs(y - x) = y - x`) THEN
16206   FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
16207   SUBGOAL_THEN `interval[u:real^1,v] SUBSET interval[a,b]` MP_TAC THENL
16208    [ASM_MESON_TAC[division_of]; REWRITE_TAC[SUBSET_INTERVAL_1]] THEN
16209   ASM_REAL_ARITH_TAC);;
16210
16211 let DECREASING_VECTOR_VARIATION = prove
16212  (`!f a b.
16213         ~(interval[a,b] = {}) /\
16214         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
16215                ==> drop(f y) <= drop(f x))
16216         ==> vector_variation (interval[a,b]) f = drop(f a) - drop(f b)`,
16217   REPEAT GEN_TAC THEN GEN_REWRITE_TAC
16218    (LAND_CONV o RAND_CONV o BINDER_CONV o BINDER_CONV o RAND_CONV)
16219    [GSYM REAL_LE_NEG2] THEN
16220   REWRITE_TAC[GSYM DROP_NEG] THEN
16221   DISCH_THEN(MP_TAC o MATCH_MP INCREASING_VECTOR_VARIATION) THEN
16222   SIMP_TAC[VECTOR_VARIATION_NEG; DROP_NEG] THEN
16223   DISCH_TAC THEN REAL_ARITH_TAC);;
16224
16225 let HAS_BOUNDED_VARIATION_TRANSLATION2_EQ,VECTOR_VARIATION_TRANSLATION2 =
16226  (CONJ_PAIR o prove)
16227  (`(!a f:real^1->real^N s.
16228         (\x. f(a + x)) has_bounded_variation_on (IMAGE (\x. --a + x) s) <=>
16229         f has_bounded_variation_on s) /\
16230    (!a f:real^1->real^N s.
16231         vector_variation (IMAGE (\x. --a + x) s) (\x. f(a + x)) =
16232         vector_variation s f)`,
16233   GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `a:real^1` THEN
16234   MATCH_MP_TAC VARIATION_EQUAL_LEMMA THEN
16235   REWRITE_TAC[] THEN CONJ_TAC THENL [VECTOR_ARITH_TAC; ALL_TAC] THEN
16236   SIMP_TAC[DIVISION_OF_TRANSLATION; GSYM INTERVAL_TRANSLATION]);;
16237
16238 let HAS_BOUNDED_VARIATION_AFFINITY2_EQ,VECTOR_VARIATION_AFFINITY2 =
16239  (CONJ_PAIR o prove)
16240  (`(!m c f:real^1->real^N s.
16241         (\x. f (m % x + c)) has_bounded_variation_on
16242         IMAGE (\x. inv m % x + --(inv m % c)) s <=>
16243         m = &0 \/ f has_bounded_variation_on s) /\
16244    (!m c f:real^1->real^N s.
16245         vector_variation (IMAGE (\x. inv m % x + --(inv m % c)) s)
16246                          (\x. f (m % x + c)) =
16247         if m = &0 then &0 else vector_variation s f)`,
16248   GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `m:real` THEN
16249   GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `c:real^1` THEN
16250   ASM_CASES_TAC `m = &0` THEN ASM_REWRITE_TAC[] THENL
16251    [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; HAS_BOUNDED_VARIATION_ON_CONST] THEN
16252     REWRITE_TAC[VECTOR_VARIATION_CONST];
16253     MATCH_MP_TAC VARIATION_EQUAL_LEMMA THEN
16254     ASM_SIMP_TAC[REWRITE_RULE[FUN_EQ_THM; o_DEF] AFFINITY_INVERSES; I_THM] THEN
16255     ASM_SIMP_TAC[IMAGE_AFFINITY_INTERVAL] THEN
16256     ASM_REWRITE_TAC[DIVISION_OF_AFFINITY; REAL_INV_EQ_0] THEN
16257     MESON_TAC[]]);;
16258
16259 let HAS_BOUNDED_VARIATION_AFFINITY_EQ,VECTOR_VARIATION_AFFINITY =
16260  (CONJ_PAIR o prove)
16261  (`(!m c f:real^1->real^N s.
16262         (\x. f(m % x + c)) has_bounded_variation_on s <=>
16263         m = &0 \/ f has_bounded_variation_on (IMAGE (\x. m % x + c) s)) /\
16264    (!m c f:real^1->real^N s.
16265         vector_variation s (\x. f(m % x + c)) =
16266         if m = &0 then &0 else vector_variation (IMAGE (\x. m % x + c) s) f)`,
16267   REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN
16268   ASM_CASES_TAC `m = &0` THEN
16269   ASM_REWRITE_TAC[VECTOR_MUL_LZERO; HAS_BOUNDED_VARIATION_ON_CONST;
16270                   VECTOR_VARIATION_CONST] THEN
16271   CONJ_TAC THENL
16272    [MP_TAC(ISPECL[`m:real`; `c:real^1`; `f:real^1->real^N`;
16273                   `IMAGE (\x:real^1. m % x + c) s`]
16274           HAS_BOUNDED_VARIATION_AFFINITY2_EQ);
16275     MP_TAC(ISPECL[`m:real`; `c:real^1`; `f:real^1->real^N`;
16276                   `IMAGE (\x:real^1. m % x + c) s`]
16277           VECTOR_VARIATION_AFFINITY2)] THEN
16278   ASM_SIMP_TAC[AFFINITY_INVERSES; GSYM IMAGE_o; IMAGE_I]);;
16279
16280 let HAS_BOUNDED_VARIATION_TRANSLATION_EQ,VECTOR_VARIATION_TRANSLATION =
16281  (CONJ_PAIR o prove)
16282  (`(!a f:real^1->real^N s.
16283         (\x. f(a + x)) has_bounded_variation_on s <=>
16284         f has_bounded_variation_on (IMAGE (\x. a + x) s)) /\
16285    (!a f:real^1->real^N s.
16286         vector_variation s (\x. f(a + x)) =
16287         vector_variation (IMAGE (\x. a + x) s) f)`,
16288   REPEAT STRIP_TAC THENL
16289    [MP_TAC(ISPECL[`a:real^1`; `f:real^1->real^N`; `IMAGE (\x:real^1. a + x) s`]
16290           HAS_BOUNDED_VARIATION_TRANSLATION2_EQ);
16291     MP_TAC(ISPECL[`a:real^1`; `f:real^1->real^N`; `IMAGE (\x:real^1. a + x) s`]
16292           VECTOR_VARIATION_TRANSLATION2)] THEN
16293   REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN
16294   REWRITE_TAC[IMAGE_ID; VECTOR_ARITH `--a + a + x:real^N = x`;
16295               VECTOR_ARITH `a + --a + x:real^N = x`]);;
16296
16297 let HAS_BOUNDED_VARIATION_TRANSLATION_EQ_INTERVAL,
16298     VECTOR_VARIATION_TRANSLATION_INTERVAL =
16299  (CONJ_PAIR o prove)
16300  (`(!a f:real^1->real^N u v.
16301         (\x. f(a + x)) has_bounded_variation_on interval[u,v] <=>
16302         f has_bounded_variation_on interval[a+u,a+v]) /\
16303    (!a f:real^1->real^N u v.
16304         vector_variation (interval[u,v]) (\x. f(a + x)) =
16305         vector_variation (interval[a+u,a+v]) f)`,
16306   REWRITE_TAC[INTERVAL_TRANSLATION; HAS_BOUNDED_VARIATION_TRANSLATION_EQ;
16307               VECTOR_VARIATION_TRANSLATION]);;
16308
16309 let HAS_BOUNDED_VARIATION_TRANSLATION = prove
16310  (`!f:real^1->real^N s a.
16311         f has_bounded_variation_on s
16312         ==> (\x. f(a + x)) has_bounded_variation_on (IMAGE (\x. --a + x) s)`,
16313   REWRITE_TAC[HAS_BOUNDED_VARIATION_TRANSLATION2_EQ]);;
16314
16315 let HAS_BOUNDED_VARIATION_REFLECT2_EQ,VECTOR_VARIATION_REFLECT2 =
16316  (CONJ_PAIR o prove)
16317  (`(!f:real^1->real^N s.
16318         (\x. f(--x)) has_bounded_variation_on (IMAGE (--) s) <=>
16319         f has_bounded_variation_on s) /\
16320    (!f:real^1->real^N s.
16321         vector_variation (IMAGE (--) s) (\x. f(--x)) =
16322         vector_variation s f)`,
16323   MATCH_MP_TAC VARIATION_EQUAL_LEMMA THEN
16324   REWRITE_TAC[] THEN CONJ_TAC THENL [VECTOR_ARITH_TAC; ALL_TAC] THEN
16325   SIMP_TAC[DIVISION_OF_REFLECT; REFLECT_INTERVAL]);;
16326
16327 let HAS_BOUNDED_VARIATION_REFLECT_EQ,VECTOR_VARIATION_REFLECT =
16328  (CONJ_PAIR o prove)
16329  (`(!f:real^1->real^N s.
16330         (\x. f(--x)) has_bounded_variation_on s <=>
16331         f has_bounded_variation_on (IMAGE (--) s)) /\
16332    (!f:real^1->real^N s.
16333         vector_variation s (\x. f(--x)) =
16334         vector_variation (IMAGE (--) s) f)`,
16335   REPEAT STRIP_TAC THENL
16336    [MP_TAC(ISPECL[`f:real^1->real^N`; `IMAGE (--) (s:real^1->bool)`]
16337           HAS_BOUNDED_VARIATION_REFLECT2_EQ);
16338     MP_TAC(ISPECL[`f:real^1->real^N`; `IMAGE (--) (s:real^1->bool)`]
16339           VECTOR_VARIATION_REFLECT2)] THEN
16340   REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN
16341   REWRITE_TAC[IMAGE_ID; VECTOR_NEG_NEG]);;
16342
16343 let HAS_BOUNDED_VARIATION_REFLECT_EQ_INTERVAL,
16344     VECTOR_VARIATION_REFLECT_INTERVAL =
16345  (CONJ_PAIR o prove)
16346  (`(!f:real^1->real^N u v.
16347         (\x. f(--x)) has_bounded_variation_on interval[u,v] <=>
16348         f has_bounded_variation_on interval[--v,--u]) /\
16349    (!f:real^1->real^N u v.
16350         vector_variation (interval[u,v]) (\x. f(--x)) =
16351         vector_variation (interval[--v,--u]) f)`,
16352   REWRITE_TAC[GSYM REFLECT_INTERVAL; HAS_BOUNDED_VARIATION_REFLECT_EQ;
16353               VECTOR_VARIATION_REFLECT]);;
16354
16355 let HAS_BOUNDED_VARIATION_DARBOUX = prove
16356  (`!f a b.
16357      f has_bounded_variation_on interval[a,b] <=>
16358      ?g h. (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
16359                   ==> drop(g x) <= drop(g y)) /\
16360            (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
16361                   ==> drop(h x) <= drop(h y)) /\
16362            (!x. f x = g x - h x)`,
16363   REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THENL
16364    [MAP_EVERY EXISTS_TAC
16365      [`\x:real^1. lift(vector_variation (interval[a,x]) (f:real^1->real^1))`;
16366       `\x:real^1. lift(vector_variation (interval[a,x]) f) - f x`] THEN
16367     REWRITE_TAC[VECTOR_ARITH `a - (a - x):real^1 = x`] THEN
16368     REWRITE_TAC[LIFT_DROP; DROP_SUB] THEN REPEAT STRIP_TAC THENL
16369      [MATCH_MP_TAC VECTOR_VARIATION_MONOTONE;
16370       MATCH_MP_TAC(REAL_ARITH
16371        `!x. a - (b - x) <= c - (d - x) ==> a - b <= c - d`) THEN
16372       EXISTS_TAC `drop(f(a:real^1))` THEN
16373       REWRITE_TAC[GSYM DROP_SUB] THEN
16374       MATCH_MP_TAC VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE] THEN
16375     (CONJ_TAC THENL
16376        [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16377          HAS_BOUNDED_VARIATION_ON_SUBSET));
16378         ALL_TAC] THEN
16379       RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
16380       REWRITE_TAC[SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1] THEN
16381       ASM_REAL_ARITH_TAC);
16382     GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN ASM_REWRITE_TAC[] THEN
16383     MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN
16384     CONJ_TAC THEN MATCH_MP_TAC INCREASING_BOUNDED_VARIATION THEN
16385     ASM_REWRITE_TAC[]]);;
16386
16387 let HAS_BOUNDED_VARIATION_DARBOUX_STRICT = prove
16388  (`!f a b.
16389      f has_bounded_variation_on interval[a,b] <=>
16390      ?g h. (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x < drop y
16391                   ==> drop(g x) < drop(g y)) /\
16392            (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x < drop y
16393                   ==> drop(h x) < drop(h y)) /\
16394            (!x. f x = g x - h x)`,
16395   REPEAT GEN_TAC THEN REWRITE_TAC[HAS_BOUNDED_VARIATION_DARBOUX] THEN
16396   EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
16397   MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN
16398   STRIP_TAC THENL
16399    [MAP_EVERY EXISTS_TAC [`\x:real^1. g x + x`; `\x:real^1. h x + x`] THEN
16400     ASM_REWRITE_TAC[VECTOR_ARITH `(a + x) - (b + x):real^1 = a - b`] THEN
16401     REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_ADD] THEN
16402     MATCH_MP_TAC REAL_LET_ADD2 THEN ASM_REWRITE_TAC[] THEN
16403     FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[REAL_LT_IMP_LE];
16404     MAP_EVERY EXISTS_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN
16405     ASM_REWRITE_TAC[REAL_LE_LT; DROP_EQ] THEN ASM_MESON_TAC[]]);;
16406
16407 let HAS_BOUNDED_VARIATION_COMPOSE_INCREASING = prove
16408  (`!f g:real^1->real^N a b.
16409         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
16410                ==> drop(f x) <= drop(f y)) /\
16411         g has_bounded_variation_on interval[f a,f b]
16412         ==> (g o f) has_bounded_variation_on interval[a,b]`,
16413   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
16414   ONCE_REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_COMPONENTWISE] THEN
16415   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN
16416   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
16417   ASM_REWRITE_TAC[HAS_BOUNDED_VARIATION_DARBOUX; LEFT_IMP_EXISTS_THM] THEN
16418   MAP_EVERY X_GEN_TAC [`h:real^1->real^1`; `k:real^1->real^1`] THEN
16419   STRIP_TAC THEN
16420   MAP_EVERY EXISTS_TAC [`(h:real^1->real^1) o (f:real^1->real^1)`;
16421                         `(k:real^1->real^1) o (f:real^1->real^1)`] THEN
16422   ASM_REWRITE_TAC[o_THM] THEN
16423   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
16424   REPEAT STRIP_TAC THEN TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN
16425   ASM_REWRITE_TAC[] THEN
16426   REWRITE_TAC[IN_INTERVAL_1] THEN CONJ_TAC THEN
16427   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
16428   RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REWRITE_TAC[] THEN
16429   REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC);;
16430
16431 let HAS_BOUNDED_VARIATION_ON_REFLECT = prove
16432  (`!f:real^1->real^N s.
16433         f has_bounded_variation_on IMAGE (--) s
16434         ==> (\x. f(--x)) has_bounded_variation_on s`,
16435   REPEAT GEN_TAC THEN
16436   REWRITE_TAC[has_bounded_variation_on] THEN
16437   REWRITE_TAC[has_bounded_setvariation_on] THEN
16438   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN DISCH_TAC THEN
16439   MAP_EVERY X_GEN_TAC [`d:(real^1->bool)->bool`; `t:real^1->bool`] THEN
16440   STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL
16441    [`IMAGE (IMAGE (--)) (d:(real^1->bool)->bool)`;
16442     `IMAGE (--) (t:real^1->bool)`]) THEN
16443   ASM_SIMP_TAC[DIVISION_OF_REFLECT] THEN
16444   REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
16445   ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
16446   ASM_REWRITE_TAC[GSYM SUBSET] THEN
16447   W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o lhand o lhand o snd) THEN
16448   ANTS_TAC THENL
16449    [MESON_TAC[VECTOR_ARITH `--x:real^N = --y <=> x = y`; INJECTIVE_IMAGE];
16450     DISCH_THEN SUBST1_TAC THEN
16451     MATCH_MP_TAC(REAL_ARITH `x = y ==> x <= d ==> y <= d`) THEN
16452     MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th ->
16453       GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION th]) THEN
16454     MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN
16455     SUBGOAL_THEN `drop u <= drop v` ASSUME_TAC THENL
16456      [ASM_MESON_TAC[INTERVAL_NE_EMPTY_1; division_of]; ALL_TAC] THEN
16457     ASM_REWRITE_TAC[o_THM; REFLECT_INTERVAL] THEN
16458     ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1;
16459                  DROP_NEG; REAL_LE_NEG2] THEN
16460     NORM_ARITH_TAC]);;
16461
16462 let HAS_BOUNDED_VARIATION_ON_REFLECT_INTERVAL = prove
16463  (`!f:real^1->real^N a b.
16464         f has_bounded_variation_on interval[--b,--a]
16465         ==> (\x. f(--x)) has_bounded_variation_on interval[a,b]`,
16466   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_REFLECT THEN
16467   ASM_REWRITE_TAC[REFLECT_INTERVAL]);;
16468
16469 let VECTOR_VARIATION_REFLECT = prove
16470  (`!f:real^1->real^N s.
16471         vector_variation s (\x. f(--x)) =
16472         vector_variation (IMAGE (--) s) f`,
16473   REPEAT GEN_TAC THEN REWRITE_TAC[vector_variation; set_variation] THEN
16474   AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
16475   X_GEN_TAC `y:real` THEN EQ_TAC THEN
16476   DISCH_THEN(X_CHOOSE_THEN `d:(real^1->bool)->bool`
16477    (CONJUNCTS_THEN2 MP_TAC SUBST1_TAC)) THEN
16478   DISCH_THEN(X_CHOOSE_THEN `t:real^1->bool` STRIP_ASSUME_TAC) THEN
16479   EXISTS_TAC `IMAGE (IMAGE (--)) (d:(real^1->bool)->bool)` THEN
16480   (CONJ_TAC THENL
16481     [EXISTS_TAC `IMAGE (--) (t:real^1->bool)` THEN
16482      ASM_SIMP_TAC[DIVISION_OF_REFLECT] THEN
16483      ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
16484      RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_IMAGE]) THEN
16485      ASM_MESON_TAC[VECTOR_NEG_NEG; IN_IMAGE];
16486      ALL_TAC]) THEN
16487   W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o rand o snd) THEN
16488   (ANTS_TAC THENL
16489    [MESON_TAC[VECTOR_ARITH `--x:real^N = --y <=> x = y`; INJECTIVE_IMAGE];
16490     DISCH_THEN SUBST1_TAC]) THEN
16491   MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th ->
16492     GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION th]) THEN
16493   MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN
16494   (SUBGOAL_THEN `drop u <= drop v` ASSUME_TAC THENL
16495    [ASM_MESON_TAC[INTERVAL_NE_EMPTY_1; division_of]; ALL_TAC]) THEN
16496   ASM_REWRITE_TAC[o_THM; REFLECT_INTERVAL] THEN
16497   ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1;
16498                DROP_NEG; REAL_LE_NEG2; VECTOR_NEG_NEG] THEN
16499   NORM_ARITH_TAC);;
16500
16501 let VECTOR_VARIATION_REFLECT_INTERVAL = prove
16502  (`!f:real^1->real^N a b.
16503         vector_variation (interval[a,b]) (\x. f(--x)) =
16504         vector_variation (interval[--b,--a]) f`,
16505   REWRITE_TAC[VECTOR_VARIATION_REFLECT; REFLECT_INTERVAL]);;
16506
16507 let HAS_BOUNDED_VARIATION_COMPOSE_DECREASING = prove
16508  (`!f g:real^1->real^N a b.
16509         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
16510                ==> drop(f y) <= drop(f x)) /\
16511         g has_bounded_variation_on interval[f b,f a]
16512         ==> (g o f) has_bounded_variation_on interval[a,b]`,
16513   REPEAT GEN_TAC THEN
16514   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
16515   DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[VECTOR_NEG_NEG]
16516     (ISPECL [`f:real^1->real^N`; `--b:real^1`; `--a:real^1`]
16517         HAS_BOUNDED_VARIATION_ON_REFLECT_INTERVAL))) THEN
16518   POP_ASSUM MP_TAC THEN
16519   GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV o BINDER_CONV o RAND_CONV)
16520    [GSYM REAL_LE_NEG2] THEN
16521   REWRITE_TAC[GSYM DROP_NEG; IMP_IMP] THEN
16522   DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_COMPOSE_INCREASING) THEN
16523   REWRITE_TAC[o_DEF; VECTOR_NEG_NEG]);;
16524
16525 let HAS_BOUNDED_VARIATION_ON_ID = prove
16526  (`!a b. (\x. x) has_bounded_variation_on interval[a,b]`,
16527   REPEAT GEN_TAC THEN MATCH_MP_TAC INCREASING_BOUNDED_VARIATION THEN
16528   SIMP_TAC[]);;
16529
16530 let HAS_BOUNDED_VARIATION_ON_LINEAR_IMAGE = prove
16531  (`!f:real^1->real^1 g:real^1->real^N a b.
16532         linear f /\ g has_bounded_variation_on IMAGE f (interval[a,b])
16533         ==> (g o f) has_bounded_variation_on interval[a,b]`,
16534   REPEAT STRIP_TAC THEN
16535   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LINEAR_1]) THEN
16536   DISCH_THEN(X_CHOOSE_THEN `c:real` SUBST_ALL_TAC) THEN
16537   REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC (REAL_ARITH
16538    `c = &0 \/ &0 <= c /\ &0 < c \/ ~(&0 <= c) /\ &0 < --c`)
16539   THENL
16540    [ASM_REWRITE_TAC[o_DEF; VECTOR_MUL_LZERO; HAS_BOUNDED_VARIATION_ON_CONST];
16541     MATCH_MP_TAC HAS_BOUNDED_VARIATION_COMPOSE_INCREASING THEN
16542     REWRITE_TAC[DROP_CMUL];
16543     MATCH_MP_TAC HAS_BOUNDED_VARIATION_COMPOSE_DECREASING THEN
16544     REWRITE_TAC[DROP_CMUL] THEN
16545     ONCE_REWRITE_TAC[REAL_ARITH `c * y <= c * x <=> --c * x <= --c * y`]] THEN
16546   ASM_SIMP_TAC[REAL_LE_LMUL; REAL_LT_IMP_LE] THEN
16547   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(MESON[]
16548    `g has_bounded_variation_on s
16549     ==> s = t ==> g has_bounded_variation_on t`)) THEN
16550   ONCE_REWRITE_TAC[VECTOR_ARITH `c % x:real^N = c % x + vec 0`] THEN
16551   ASM_REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN
16552   COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_ADD_RID] THEN
16553   CONV_TAC SYM_CONV THEN REWRITE_TAC[INTERVAL_EQ_EMPTY_1; DROP_CMUL] THENL
16554    [ALL_TAC;
16555    ONCE_REWRITE_TAC[REAL_ARITH `c * y < c * x <=> --c * x < --c * y`]] THEN
16556   MATCH_MP_TAC REAL_LT_LMUL THEN
16557   ASM_REWRITE_TAC[GSYM INTERVAL_EQ_EMPTY_1]);;
16558
16559 let INCREASING_LEFT_LIMIT_1 = prove
16560  (`!f a b c.
16561         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
16562                ==> drop(f x) <= drop(f y)) /\
16563         c IN interval[a,b]
16564        ==> ?l. (f --> l) (at c within interval[a,c])`,
16565   REPEAT STRIP_TAC THEN EXISTS_TAC
16566    `lift(sup {drop(f x) | x IN interval[a,b] /\ drop x < drop c})` THEN
16567   ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN REWRITE_TAC[LIM_WITHIN] THEN
16568   REWRITE_TAC[DIST_REAL; GSYM drop] THEN
16569   ASM_CASES_TAC `{x | x IN interval[a,b] /\ drop x < drop c} = {}` THENL
16570    [GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN
16571     REWRITE_TAC[REAL_LT_01] THEN
16572     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
16573     MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC(TAUT
16574      `(a ==> ~b) ==> a ==> b ==> c`) THEN
16575     REWRITE_TAC[NOT_IN_EMPTY; IN_ELIM_THM; IN_INTERVAL_1] THEN
16576     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
16577     ALL_TAC] THEN
16578   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
16579   MP_TAC(ISPEC `{drop(f x) | x IN interval[a,b] /\ drop x < drop c}` SUP) THEN
16580   ASM_REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL
16581    [CONJ_TAC THENL
16582      [ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN ASM_SIMP_TAC[IMAGE_EQ_EMPTY];
16583       EXISTS_TAC `drop(f(b:real^1))` THEN REPEAT STRIP_TAC THEN
16584       FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
16585       RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC];
16586     ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN REWRITE_TAC[IMAGE_ID] THEN
16587     ABBREV_TAC `s = sup (IMAGE (\x. drop(f x))
16588                         {x | x IN interval[a,b] /\ drop x < drop c})` THEN
16589     REWRITE_TAC[LIFT_DROP] THEN
16590     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `s - e:real`)) THEN
16591     ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(s <= s - e)`; NOT_FORALL_THM] THEN
16592     REWRITE_TAC[NOT_IMP; REAL_NOT_LE; IN_INTERVAL_1] THEN
16593     DISCH_THEN(X_CHOOSE_THEN `d:real^1` STRIP_ASSUME_TAC) THEN
16594     EXISTS_TAC `drop c - drop d` THEN
16595     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
16596     CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
16597     X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN
16598     FIRST_X_ASSUM(MP_TAC o SPECL [`d:real^1`; `x:real^1`]) THEN
16599     FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN ASM_REAL_ARITH_TAC]);;
16600
16601 let DECREASING_LEFT_LIMIT_1 = prove
16602  (`!f a b c.
16603         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
16604                ==> drop(f y) <= drop(f x)) /\
16605         c IN interval[a,b]
16606         ==> ?l. (f --> l) (at c within interval[a,c])`,
16607   REPEAT STRIP_TAC THEN
16608   MP_TAC(ISPECL
16609    [`\x. --((f:real^1->real^1) x)`; `a:real^1`; `b:real^1`; `c:real^1`]
16610         INCREASING_LEFT_LIMIT_1) THEN
16611   ASM_REWRITE_TAC[REAL_LE_NEG2; DROP_NEG] THEN
16612   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM LIM_NEG_EQ] THEN
16613   REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX] THEN MESON_TAC[]);;
16614
16615 let INCREASING_RIGHT_LIMIT_1 = prove
16616  (`!f a b c.
16617         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
16618                ==> drop(f x) <= drop(f y)) /\
16619         c IN interval[a,b]
16620        ==> ?l. (f --> l) (at c within interval[c,b])`,
16621   REPEAT STRIP_TAC THEN
16622   MP_TAC(ISPECL [`\x. (f:real^1->real^1) (--x)`;
16623                  `--b:real^1`; `--a:real^1`; `--c:real^1`]
16624         DECREASING_LEFT_LIMIT_1) THEN
16625   ASM_REWRITE_TAC[IN_INTERVAL_REFLECT] THEN
16626   ONCE_REWRITE_TAC[MESON[VECTOR_NEG_NEG]
16627    `(!x:real^1 y:real^1. P x y) <=> (!x y. P (--x) (--y))`] THEN
16628   REWRITE_TAC[DROP_NEG; IN_INTERVAL_REFLECT; VECTOR_NEG_NEG] THEN
16629   ASM_SIMP_TAC[REAL_LE_NEG2] THEN MATCH_MP_TAC MONO_EXISTS THEN
16630   X_GEN_TAC `l:real^1` THEN REWRITE_TAC[LIM_WITHIN] THEN
16631   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
16632    [MESON[VECTOR_NEG_NEG] `(!x:real^1. P x) <=> (!x. P (--x))`] THEN
16633   REWRITE_TAC[IN_INTERVAL_REFLECT; VECTOR_NEG_NEG;
16634               NORM_ARITH `dist(--x:real^1,--y) = dist(x,y)`]);;
16635
16636 let DECREASING_RIGHT_LIMIT_1 = prove
16637  (`!f a b c.
16638         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
16639                ==> drop(f y) <= drop(f x)) /\
16640         c IN interval[a,b]
16641        ==> ?l. (f --> l) (at c within interval[c,b])`,
16642   REPEAT STRIP_TAC THEN
16643   MP_TAC(ISPECL
16644    [`\x. --((f:real^1->real^1) x)`; `a:real^1`; `b:real^1`; `c:real^1`]
16645         INCREASING_RIGHT_LIMIT_1) THEN
16646   ASM_REWRITE_TAC[REAL_LE_NEG2; DROP_NEG] THEN
16647   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM LIM_NEG_EQ] THEN
16648   REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX] THEN MESON_TAC[]);;
16649
16650 let HAS_BOUNDED_VECTOR_VARIATION_LEFT_LIMIT = prove
16651  (`!f:real^1->real^N a b c.
16652         f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b]
16653         ==> ?l. (f --> l) (at c within interval[a,c])`,
16654   ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT;
16655                    HAS_BOUNDED_VARIATION_ON_COMPONENTWISE] THEN
16656   REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
16657   X_GEN_TAC `i:num` THEN STRIP_TAC THEN
16658   FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
16659   SPEC_TAC(`\x. lift((f:real^1->real^N)x$i)`,`f:real^1->real^1`) THEN
16660   UNDISCH_TAC `(c:real^1) IN interval[a,b]` THEN POP_ASSUM_LIST(K ALL_TAC) THEN
16661   REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM EXISTS_LIFT] THEN
16662   FIRST_X_ASSUM
16663    (MP_TAC o GEN_REWRITE_RULE I [HAS_BOUNDED_VARIATION_DARBOUX]) THEN
16664   REWRITE_TAC[LEFT_IMP_EXISTS_THM; CONJ_ASSOC] THEN REPEAT GEN_TAC THEN
16665   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
16666   REWRITE_TAC[GSYM CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN
16667    (MP_TAC o SPEC `c:real^1` o MATCH_MP
16668      (ONCE_REWRITE_RULE[IMP_CONJ] INCREASING_LEFT_LIMIT_1))) THEN
16669   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
16670   X_GEN_TAC `l2:real^1` THEN DISCH_TAC THEN
16671   X_GEN_TAC `l1:real^1` THEN DISCH_TAC THEN
16672   EXISTS_TAC `l1 - l2:real^1` THEN
16673   GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
16674   ASM_SIMP_TAC[LIM_SUB]);;
16675
16676 let HAS_BOUNDED_VECTOR_VARIATION_RIGHT_LIMIT = prove
16677  (`!f:real^1->real^N a b c.
16678         f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b]
16679         ==> ?l. (f --> l) (at c within interval[c,b])`,
16680   ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT;
16681                    HAS_BOUNDED_VARIATION_ON_COMPONENTWISE] THEN
16682   REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
16683   X_GEN_TAC `i:num` THEN STRIP_TAC THEN
16684   FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
16685   SPEC_TAC(`\x. lift((f:real^1->real^N)x$i)`,`f:real^1->real^1`) THEN
16686   UNDISCH_TAC `(c:real^1) IN interval[a,b]` THEN POP_ASSUM_LIST(K ALL_TAC) THEN
16687   REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM EXISTS_LIFT] THEN
16688   FIRST_X_ASSUM
16689    (MP_TAC o GEN_REWRITE_RULE I [HAS_BOUNDED_VARIATION_DARBOUX]) THEN
16690   REWRITE_TAC[LEFT_IMP_EXISTS_THM; CONJ_ASSOC] THEN REPEAT GEN_TAC THEN
16691   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
16692   REWRITE_TAC[GSYM CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN
16693    (MP_TAC o SPEC `c:real^1` o MATCH_MP
16694      (ONCE_REWRITE_RULE[IMP_CONJ] INCREASING_RIGHT_LIMIT_1))) THEN
16695   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
16696   X_GEN_TAC `l2:real^1` THEN DISCH_TAC THEN
16697   X_GEN_TAC `l1:real^1` THEN DISCH_TAC THEN
16698   EXISTS_TAC `l1 - l2:real^1` THEN
16699   GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
16700   ASM_SIMP_TAC[LIM_SUB]);;
16701
16702 let VECTOR_VARIATION_CONTINUOUS_LEFT = prove
16703  (`!f:real^1->real^1 a b c.
16704         f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b]
16705         ==> ((\x. lift(vector_variation(interval[a,x]) f))
16706              continuous (at c within interval[a,c]) <=>
16707             f continuous (at c within interval[a,c]))`,
16708   REPEAT STRIP_TAC THEN EQ_TAC THENL
16709    [REWRITE_TAC[continuous_within] THEN
16710     REWRITE_TAC[DIST_LIFT; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN
16711     DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
16712     FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
16713     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN
16714     ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN
16715     FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN ASM_REWRITE_TAC[] THEN
16716     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN
16717     REWRITE_TAC[GSYM DROP_SUB] THEN
16718     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `c:real^1`; `x:real^1`]
16719         VECTOR_VARIATION_COMBINE) THEN
16720     ANTS_TAC THENL
16721      [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
16722       REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
16723       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16724          HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
16725       REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
16726       ALL_TAC] THEN
16727     DISCH_THEN(SUBST1_TAC o SYM) THEN
16728     REWRITE_TAC[REAL_ARITH `abs(a - (a + b)) = abs b`] THEN
16729     REWRITE_TAC[drop; GSYM NORM_REAL] THEN
16730     MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs a`) THEN
16731     ONCE_REWRITE_TAC[NORM_SUB] THEN
16732     MATCH_MP_TAC VECTOR_VARIATION_GE_NORM_FUNCTION THEN CONJ_TAC THENL
16733      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16734         HAS_BOUNDED_VARIATION_ON_SUBSET));
16735       REWRITE_TAC[SEGMENT_1] THEN COND_CASES_TAC] THEN
16736     REWRITE_TAC[SUBSET_INTERVAL_1] THEN
16737     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
16738     ALL_TAC] THEN
16739   DISCH_TAC THEN ASM_CASES_TAC `c limit_point_of interval[a:real^1,c]` THENL
16740    [ALL_TAC;
16741     ASM_REWRITE_TAC[CONTINUOUS_WITHIN; LIM; TRIVIAL_LIMIT_WITHIN]] THEN
16742   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HAS_BOUNDED_VARIATION_DARBOUX]) THEN
16743   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
16744   MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN
16745   STRIP_TAC THEN
16746   MP_TAC(ISPECL [`h:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`]
16747    INCREASING_LEFT_LIMIT_1) THEN
16748   MP_TAC(ISPECL [`g:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`]
16749    INCREASING_LEFT_LIMIT_1) THEN
16750   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
16751   X_GEN_TAC `gc:real^1` THEN DISCH_TAC THEN
16752   X_GEN_TAC `hc:real^1` THEN DISCH_TAC THEN
16753   ABBREV_TAC `k = gc - (g:real^1->real^1) c` THEN
16754   SUBGOAL_THEN `hc - (h:real^1->real^1) c = k` ASSUME_TAC THENL
16755    [EXPAND_TAC "k" THEN
16756     ONCE_REWRITE_TAC[VECTOR_ARITH
16757      `hc' - hc:real^1 = gc' - gc <=> gc' - hc' = gc - hc`] THEN
16758     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_WITHIN]) THEN
16759     ASM_REWRITE_TAC[] THEN
16760     MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
16761       LIM_UNIQUE) THEN
16762     ASM_REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN
16763     GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
16764     ASM_SIMP_TAC[LIM_SUB];
16765     ALL_TAC] THEN
16766   MAP_EVERY ABBREV_TAC
16767    [`g':real^1->real^1 = \x. if drop c <= drop x then g(x) + k else g(x)`;
16768     `h':real^1->real^1 = \x. if drop c <= drop x then h(x) + k else h(x)`] THEN
16769   SUBGOAL_THEN
16770    `(!x y. x IN interval[a,c] /\ y IN interval[a,c] /\ drop x <= drop y
16771            ==> drop(g' x) <= drop(g' y)) /\
16772     (!x y. x IN interval[a,c] /\ y IN interval[a,c] /\ drop x <= drop y
16773            ==> drop(h' x) <= drop(h' y))`
16774   STRIP_ASSUME_TAC THENL
16775    [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN REWRITE_TAC[] THEN CONJ_TAC THEN
16776     MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN
16777     REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN
16778     (ASM_CASES_TAC `drop c <= drop x` THENL
16779       [SUBGOAL_THEN `drop c <= drop y` ASSUME_TAC THENL
16780         [ASM_REAL_ARITH_TAC; ASM_REWRITE_TAC[]] THEN
16781        REWRITE_TAC[DROP_ADD; REAL_LE_RADD] THEN
16782        FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
16783        RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
16784        ALL_TAC] THEN
16785      ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
16786       [ALL_TAC;
16787        FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
16788        RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC] THEN
16789      SUBGOAL_THEN `y:real^1 = c` SUBST_ALL_TAC THENL
16790       [REWRITE_TAC[GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN
16791      FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[]
16792       `gc - g c = k
16793        ==> b <= drop(g c + (gc - g c)) ==> b <= drop(g c + k)`)) THEN
16794      REWRITE_TAC[VECTOR_ARITH `a + b - a:real^1 = b`] THEN
16795      MATCH_MP_TAC(ISPEC `at c within interval[a:real^1,c]`
16796         LIM_DROP_LBOUND))
16797     THENL [EXISTS_TAC `g:real^1->real^1`; EXISTS_TAC `h:real^1->real^1`] THEN
16798     ASM_REWRITE_TAC[TRIVIAL_LIMIT_WITHIN; EVENTUALLY_WITHIN] THEN
16799     EXISTS_TAC `drop c - drop x` THEN
16800     (CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
16801     REWRITE_TAC[DIST_REAL; GSYM drop; IN_INTERVAL_1] THEN
16802     REWRITE_TAC[IN_INTERVAL_1] THEN REPEAT STRIP_TAC THEN
16803     FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
16804     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
16805     ALL_TAC] THEN
16806   SUBGOAL_THEN
16807    `(g':real^1->real^1) continuous (at c within interval[a,c]) /\
16808     (h':real^1->real^1) continuous (at c within interval[a,c])`
16809   MP_TAC THENL
16810    [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN
16811     REWRITE_TAC[CONTINUOUS_WITHIN; REAL_LE_REFL] THEN
16812     RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_ARITH
16813      `g - g':real^1 = k <=> g' + k = g`]) THEN
16814     ASM_REWRITE_TAC[] THEN CONJ_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
16815      (REWRITE_RULE[IMP_CONJ_ALT] LIM_TRANSFORM)) THEN
16816     MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN
16817     REWRITE_TAC[LIM_WITHIN; DIST_REAL; GSYM drop; IN_INTERVAL_1] THEN
16818     SIMP_TAC[REAL_ARITH `x <= c /\ &0 < abs(x - c) ==> ~(c <= x)`] THEN
16819     REWRITE_TAC[VECTOR_SUB_REFL; DROP_VEC; REAL_SUB_REFL; REAL_ABS_NUM] THEN
16820     MESON_TAC[REAL_LT_01];
16821     ALL_TAC] THEN
16822   REWRITE_TAC[continuous_within] THEN
16823   REWRITE_TAC[DIST_LIFT; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN
16824   DISCH_THEN(fun th ->
16825     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
16826     CONJUNCTS_THEN (MP_TAC o SPEC `e / &2`) th) THEN
16827   ASM_REWRITE_TAC[REAL_HALF] THEN
16828   DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN
16829   DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN
16830   EXISTS_TAC `min d1 d2:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
16831   X_GEN_TAC `d:real^1` THEN STRIP_TAC THEN
16832   MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `c:real^1`; `d:real^1`]
16833         VECTOR_VARIATION_COMBINE) THEN
16834   ANTS_TAC THENL
16835    [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
16836     REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
16837     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16838        HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
16839     REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
16840     DISCH_THEN(SUBST1_TAC o SYM)] THEN
16841   REWRITE_TAC[REAL_ARITH `abs(a - (a + b)) = abs b`] THEN
16842   MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x < a ==> abs x < a`) THEN
16843   CONJ_TAC THENL
16844    [MATCH_MP_TAC VECTOR_VARIATION_POS_LE THEN
16845     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16846        HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
16847     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
16848     REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
16849     ALL_TAC] THEN
16850   SUBGOAL_THEN `f:real^1->real^1 = \x. g' x - h' x` SUBST1_TAC THENL
16851    [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN REWRITE_TAC[FUN_EQ_THM] THEN
16852     GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC;
16853     ALL_TAC] THEN
16854   MP_TAC(ISPECL
16855    [`g':real^1->real^1`; `\x. --((h':real^1->real^1) x)`;
16856     `interval[d:real^1,c]`] VECTOR_VARIATION_TRIANGLE) THEN
16857   ANTS_TAC THENL
16858    [CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NEG] THEN
16859     MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUBSET THEN
16860     EXISTS_TAC `interval[a:real^1,c]` THEN
16861     ASM_SIMP_TAC[INCREASING_BOUNDED_VARIATION; SUBSET_INTERVAL_1] THEN
16862     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN  ASM_REAL_ARITH_TAC;
16863     ALL_TAC] THEN
16864   REWRITE_TAC[VECTOR_SUB] THEN MATCH_MP_TAC(REAL_ARITH
16865    `y < a / &2 /\ z < a / &2 ==> x <= y + z ==> x < a`) THEN
16866   REWRITE_TAC[VECTOR_VARIATION_NEG] THEN CONJ_TAC THEN
16867   W(MP_TAC o PART_MATCH (lhs o rand)
16868     INCREASING_VECTOR_VARIATION o lhand o snd) THEN
16869   (ANTS_TAC THENL
16870     [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
16871      ASM_REWRITE_TAC[INTERVAL_EQ_EMPTY_1; IN_INTERVAL_1; REAL_NOT_LT] THEN
16872      REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC;
16873      DISCH_THEN SUBST1_TAC]) THEN
16874   MATCH_MP_TAC(REAL_ARITH `abs(x - y) < e ==> y - x < e`) THEN
16875   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]);;
16876
16877 let VECTOR_VARIATION_CONTINUOUS_RIGHT = prove
16878  (`!f:real^1->real^1 a b c.
16879         f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b]
16880         ==> ((\x. lift(vector_variation(interval[a,x]) f))
16881              continuous (at c within interval[c,b]) <=>
16882             f continuous (at c within interval[c,b]))`,
16883   REPEAT STRIP_TAC THEN EQ_TAC THENL
16884    [REWRITE_TAC[continuous_within] THEN
16885     REWRITE_TAC[DIST_LIFT; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN
16886     DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
16887     FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
16888     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN
16889     ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN
16890     FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN ASM_REWRITE_TAC[] THEN
16891     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN
16892     REWRITE_TAC[GSYM DROP_SUB] THEN
16893     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `x:real^1`; `c:real^1`]
16894         VECTOR_VARIATION_COMBINE) THEN
16895     ANTS_TAC THENL
16896      [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
16897       REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
16898       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16899          HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
16900       REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
16901       ALL_TAC] THEN
16902     DISCH_THEN(SUBST1_TAC o SYM) THEN
16903     REWRITE_TAC[REAL_ARITH `abs((a + b) - a) = abs b`] THEN
16904     REWRITE_TAC[drop; GSYM NORM_REAL] THEN
16905     MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs a`) THEN
16906     MATCH_MP_TAC VECTOR_VARIATION_GE_NORM_FUNCTION THEN CONJ_TAC THENL
16907      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16908         HAS_BOUNDED_VARIATION_ON_SUBSET));
16909       REWRITE_TAC[SEGMENT_1] THEN COND_CASES_TAC] THEN
16910     REWRITE_TAC[SUBSET_INTERVAL_1] THEN
16911     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
16912     ALL_TAC] THEN
16913   DISCH_TAC THEN ASM_CASES_TAC `c limit_point_of interval[c:real^1,b]` THENL
16914    [ALL_TAC;
16915     ASM_REWRITE_TAC[CONTINUOUS_WITHIN; LIM; TRIVIAL_LIMIT_WITHIN]] THEN
16916   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HAS_BOUNDED_VARIATION_DARBOUX]) THEN
16917   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
16918   MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN
16919   STRIP_TAC THEN
16920   MP_TAC(ISPECL [`h:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`]
16921    INCREASING_RIGHT_LIMIT_1) THEN
16922   MP_TAC(ISPECL [`g:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`]
16923    INCREASING_RIGHT_LIMIT_1) THEN
16924   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
16925   X_GEN_TAC `gc:real^1` THEN DISCH_TAC THEN
16926   X_GEN_TAC `hc:real^1` THEN DISCH_TAC THEN
16927   ABBREV_TAC `k = gc - (g:real^1->real^1) c` THEN
16928   SUBGOAL_THEN `hc - (h:real^1->real^1) c = k` ASSUME_TAC THENL
16929    [EXPAND_TAC "k" THEN
16930     ONCE_REWRITE_TAC[VECTOR_ARITH
16931      `hc' - hc:real^1 = gc' - gc <=> gc' - hc' = gc - hc`] THEN
16932     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_WITHIN]) THEN
16933     ASM_REWRITE_TAC[] THEN
16934     MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
16935       LIM_UNIQUE) THEN
16936     ASM_REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN
16937     GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
16938     ASM_SIMP_TAC[LIM_SUB];
16939     ALL_TAC] THEN
16940   MAP_EVERY ABBREV_TAC
16941    [`g':real^1->real^1 = \x. if drop x <= drop c then g(x) + k else g(x)`;
16942     `h':real^1->real^1 = \x. if drop x <= drop c then h(x) + k else h(x)`] THEN
16943   SUBGOAL_THEN
16944    `(!x y. x IN interval[c,b] /\ y IN interval[c,b] /\ drop x <= drop y
16945            ==> drop(g' x) <= drop(g' y)) /\
16946     (!x y. x IN interval[c,b] /\ y IN interval[c,b] /\ drop x <= drop y
16947            ==> drop(h' x) <= drop(h' y))`
16948   STRIP_ASSUME_TAC THENL
16949    [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN REWRITE_TAC[] THEN CONJ_TAC THEN
16950     MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN
16951     REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN
16952     (ASM_CASES_TAC `drop y <= drop c` THENL
16953       [SUBGOAL_THEN `drop x <= drop c` ASSUME_TAC THENL
16954         [ASM_REAL_ARITH_TAC; ASM_REWRITE_TAC[]] THEN
16955        REWRITE_TAC[DROP_ADD; REAL_LE_RADD] THEN
16956        FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
16957        RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
16958        ALL_TAC] THEN
16959      ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
16960       [ALL_TAC;
16961        FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
16962        RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC] THEN
16963      SUBGOAL_THEN `x:real^1 = c` SUBST_ALL_TAC THENL
16964       [REWRITE_TAC[GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN
16965      FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[]
16966       `gc - g c = k
16967        ==> drop(g c + (gc - g c)) <= b ==> drop(g c + k) <= b`)) THEN
16968      REWRITE_TAC[VECTOR_ARITH `a + b - a:real^1 = b`] THEN
16969      MATCH_MP_TAC(ISPEC `at c within interval[c:real^1,b]`
16970         LIM_DROP_UBOUND))
16971     THENL [EXISTS_TAC `g:real^1->real^1`; EXISTS_TAC `h:real^1->real^1`] THEN
16972     ASM_REWRITE_TAC[TRIVIAL_LIMIT_WITHIN; EVENTUALLY_WITHIN] THEN
16973     EXISTS_TAC `drop y - drop c` THEN
16974     (CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
16975     REWRITE_TAC[DIST_REAL; GSYM drop; IN_INTERVAL_1] THEN
16976     REWRITE_TAC[IN_INTERVAL_1] THEN REPEAT STRIP_TAC THEN
16977     FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
16978     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
16979     ALL_TAC] THEN
16980   SUBGOAL_THEN
16981    `(g':real^1->real^1) continuous (at c within interval[c,b]) /\
16982     (h':real^1->real^1) continuous (at c within interval[c,b])`
16983   MP_TAC THENL
16984    [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN
16985     REWRITE_TAC[CONTINUOUS_WITHIN; REAL_LE_REFL] THEN
16986     RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_ARITH
16987      `g - g':real^1 = k <=> g' + k = g`]) THEN
16988     ASM_REWRITE_TAC[] THEN CONJ_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
16989      (REWRITE_RULE[IMP_CONJ_ALT] LIM_TRANSFORM)) THEN
16990     MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN
16991     REWRITE_TAC[LIM_WITHIN; DIST_REAL; GSYM drop; IN_INTERVAL_1] THEN
16992     SIMP_TAC[REAL_ARITH `c <= x /\ &0 < abs(x - c) ==> ~(x <= c)`] THEN
16993     REWRITE_TAC[VECTOR_SUB_REFL; DROP_VEC; REAL_SUB_REFL; REAL_ABS_NUM] THEN
16994     MESON_TAC[REAL_LT_01];
16995     ALL_TAC] THEN
16996   REWRITE_TAC[continuous_within] THEN
16997   REWRITE_TAC[DIST_LIFT; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN
16998   DISCH_THEN(fun th ->
16999     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
17000     CONJUNCTS_THEN (MP_TAC o SPEC `e / &2`) th) THEN
17001   ASM_REWRITE_TAC[REAL_HALF] THEN
17002   DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN
17003   DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN
17004   EXISTS_TAC `min d1 d2:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
17005   X_GEN_TAC `d:real^1` THEN STRIP_TAC THEN
17006   MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `d:real^1`; `c:real^1`]
17007         VECTOR_VARIATION_COMBINE) THEN
17008   ANTS_TAC THENL
17009    [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
17010     REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
17011     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
17012        HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
17013     REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
17014     DISCH_THEN(SUBST1_TAC o SYM)] THEN
17015   REWRITE_TAC[REAL_ARITH `(a + b) - a:real = b`] THEN
17016   MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x < a ==> abs x < a`) THEN
17017   CONJ_TAC THENL
17018    [MATCH_MP_TAC VECTOR_VARIATION_POS_LE THEN
17019     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
17020        HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
17021     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
17022     REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
17023     ALL_TAC] THEN
17024   SUBGOAL_THEN `f:real^1->real^1 = \x. g' x - h' x` SUBST1_TAC THENL
17025    [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN REWRITE_TAC[FUN_EQ_THM] THEN
17026     GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC;
17027     ALL_TAC] THEN
17028   MP_TAC(ISPECL
17029    [`g':real^1->real^1`; `\x. --((h':real^1->real^1) x)`;
17030     `interval[c:real^1,d]`] VECTOR_VARIATION_TRIANGLE) THEN
17031   ANTS_TAC THENL
17032    [CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NEG] THEN
17033     MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUBSET THEN
17034     EXISTS_TAC `interval[c:real^1,b]` THEN
17035     ASM_SIMP_TAC[INCREASING_BOUNDED_VARIATION; SUBSET_INTERVAL_1] THEN
17036     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN  ASM_REAL_ARITH_TAC;
17037     ALL_TAC] THEN
17038   REWRITE_TAC[VECTOR_SUB] THEN MATCH_MP_TAC(REAL_ARITH
17039    `y < a / &2 /\ z < a / &2 ==> x <= y + z ==> x < a`) THEN
17040   REWRITE_TAC[VECTOR_VARIATION_NEG] THEN CONJ_TAC THEN
17041   W(MP_TAC o PART_MATCH (lhs o rand)
17042     INCREASING_VECTOR_VARIATION o lhand o snd) THEN
17043   (ANTS_TAC THENL
17044     [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
17045      ASM_REWRITE_TAC[INTERVAL_EQ_EMPTY_1; IN_INTERVAL_1; REAL_NOT_LT] THEN
17046      REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC;
17047      DISCH_THEN SUBST1_TAC]) THEN
17048   MATCH_MP_TAC(REAL_ARITH `abs x < e ==> x < e`) THEN
17049   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]);;
17050
17051 let VECTOR_VARIATION_CONTINUOUS = prove
17052  (`!f:real^1->real^1 a b c.
17053         f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b]
17054         ==> ((\x. lift(vector_variation(interval[a,x]) f))
17055              continuous (at c within interval[a,b]) <=>
17056             f continuous (at c within interval[a,b]))`,
17057   REPEAT STRIP_TAC THEN
17058   SUBGOAL_THEN
17059    `!f:real^1->real^1.
17060         f continuous (at c within interval[a,b]) <=>
17061         f continuous (at c within interval[a,c]) /\
17062         f continuous (at c within interval[c,b])`
17063    (fun th -> REWRITE_TAC[th] THEN
17064               ASM_MESON_TAC[VECTOR_VARIATION_CONTINUOUS_LEFT;
17065                             VECTOR_VARIATION_CONTINUOUS_RIGHT]) THEN
17066   GEN_TAC THEN REWRITE_TAC[CONTINUOUS_WITHIN] THEN EQ_TAC THENL
17067    [DISCH_THEN(ASSUME_TAC o GEN_ALL o
17068      MATCH_MP (REWRITE_RULE[IMP_CONJ] LIM_WITHIN_SUBSET)) THEN
17069     CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC;
17070     DISCH_THEN(MP_TAC o MATCH_MP LIM_UNION) THEN
17071     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] LIM_WITHIN_SUBSET)] THEN
17072   REWRITE_TAC[SUBSET; IN_UNION; IN_INTERVAL_1] THEN
17073   RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC);;
17074
17075 let HAS_BOUNDED_VARIATION_DARBOUX_STRONG = prove
17076  (`!f a b.
17077      f has_bounded_variation_on interval[a,b]
17078      ==> ?g h. (!x. f x = g x - h x) /\
17079                (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\
17080                       drop x <= drop y
17081                       ==> drop(g x) <= drop(g y)) /\
17082                (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\
17083                       drop x <= drop y
17084                       ==> drop(h x) <= drop(h y)) /\
17085                (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\
17086                       drop x < drop y
17087                       ==> drop(g x) < drop(g y)) /\
17088                (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\
17089                       drop x < drop y
17090                       ==> drop(h x) < drop(h y)) /\
17091                (!x. x IN interval[a,b] /\
17092                     f continuous (at x within interval[a,x])
17093                     ==> g continuous (at x within interval[a,x]) /\
17094                         h continuous (at x within interval[a,x])) /\
17095                (!x. x IN interval[a,b] /\
17096                     f continuous (at x within interval[x,b])
17097                     ==> g continuous (at x within interval[x,b]) /\
17098                         h continuous (at x within interval[x,b])) /\
17099                (!x. x IN interval[a,b] /\
17100                     f continuous (at x within interval[a,b])
17101                     ==> g continuous (at x within interval[a,b]) /\
17102                         h continuous (at x within interval[a,b]))`,
17103   REPEAT STRIP_TAC THEN
17104   MAP_EVERY EXISTS_TAC
17105    [`\x:real^1. x + lift(vector_variation (interval[a,x]) (f:real^1->real^1))`;
17106     `\x:real^1. x + lift(vector_variation (interval[a,x]) f) - f x`] THEN
17107   REWRITE_TAC[VECTOR_ARITH `(x + l) - (x + l - f):real^1 = f`] THEN
17108   REWRITE_TAC[LIFT_DROP; DROP_SUB; DROP_ADD] THEN REPEAT STRIP_TAC THENL
17109    [MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC[] THEN
17110     MATCH_MP_TAC VECTOR_VARIATION_MONOTONE;
17111     MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC[] THEN
17112     MATCH_MP_TAC(REAL_ARITH
17113      `!x. a - (b - x) <= c - (d - x) ==> a - b <= c - d`) THEN
17114     EXISTS_TAC `drop(f(a:real^1))` THEN
17115     REWRITE_TAC[GSYM DROP_SUB] THEN
17116     MATCH_MP_TAC VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE;
17117     MATCH_MP_TAC REAL_LTE_ADD2 THEN ASM_REWRITE_TAC[] THEN
17118     MATCH_MP_TAC VECTOR_VARIATION_MONOTONE;
17119     MATCH_MP_TAC REAL_LTE_ADD2 THEN ASM_REWRITE_TAC[] THEN
17120     MATCH_MP_TAC(REAL_ARITH
17121      `!x. a - (b - x) <= c - (d - x) ==> a - b <= c - d`) THEN
17122     EXISTS_TAC `drop(f(a:real^1))` THEN
17123     REWRITE_TAC[GSYM DROP_SUB] THEN
17124     MATCH_MP_TAC VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE;
17125     MATCH_MP_TAC CONTINUOUS_ADD THEN
17126     REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN
17127     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`]
17128         VECTOR_VARIATION_CONTINUOUS_LEFT) THEN
17129     ASM_REWRITE_TAC[];
17130     MATCH_MP_TAC CONTINUOUS_ADD THEN
17131     REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN
17132     MATCH_MP_TAC CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN
17133     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`]
17134         VECTOR_VARIATION_CONTINUOUS_LEFT) THEN
17135     ASM_REWRITE_TAC[];
17136     MATCH_MP_TAC CONTINUOUS_ADD THEN
17137     REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN
17138     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`]
17139         VECTOR_VARIATION_CONTINUOUS_RIGHT) THEN
17140     ASM_REWRITE_TAC[];
17141     MATCH_MP_TAC CONTINUOUS_ADD THEN
17142     REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN
17143     MATCH_MP_TAC CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN
17144     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`]
17145         VECTOR_VARIATION_CONTINUOUS_RIGHT) THEN
17146     ASM_REWRITE_TAC[];
17147     MATCH_MP_TAC CONTINUOUS_ADD THEN
17148     REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN
17149     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`]
17150         VECTOR_VARIATION_CONTINUOUS) THEN
17151     ASM_REWRITE_TAC[];
17152     MATCH_MP_TAC CONTINUOUS_ADD THEN
17153     REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN
17154     MATCH_MP_TAC CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN
17155     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`]
17156         VECTOR_VARIATION_CONTINUOUS) THEN
17157     ASM_REWRITE_TAC[]] THEN
17158   (CONJ_TAC THENL
17159      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
17160        HAS_BOUNDED_VARIATION_ON_SUBSET));
17161       ALL_TAC] THEN
17162     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
17163     REWRITE_TAC[SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1] THEN
17164     ASM_REAL_ARITH_TAC));;
17165
17166 let HAS_BOUNDED_VARIATION_COUNTABLE_DISCONTINUITIES = prove
17167  (`!f:real^1->real^1 a b.
17168         f has_bounded_variation_on interval[a,b]
17169         ==> COUNTABLE {x | x IN interval[a,b] /\ ~(f continuous at x)}`,
17170   SUBGOAL_THEN
17171    `!f a b.
17172         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
17173                ==> drop(f x) <= drop(f y))
17174         ==> COUNTABLE {x | x IN interval[a,b] /\ ~(f continuous at x)}`
17175   ASSUME_TAC THENL
17176    [ALL_TAC;
17177     REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o
17178      GEN_REWRITE_RULE I [HAS_BOUNDED_VARIATION_DARBOUX]) THEN
17179     REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
17180     MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN
17181     STRIP_TAC THEN FIRST_X_ASSUM(fun th ->
17182       MP_TAC(ISPECL [`g:real^1->real^1`; `a:real^1`; `b:real^1`] th) THEN
17183       MP_TAC(ISPECL [`h:real^1->real^1`; `a:real^1`; `b:real^1`] th)) THEN
17184     ASM_REWRITE_TAC[IMP_IMP; GSYM COUNTABLE_UNION] THEN
17185     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] COUNTABLE_SUBSET) THEN
17186     REWRITE_TAC[SUBSET; IN_UNION; IN_ELIM_THM] THEN GEN_TAC THEN
17187     MATCH_MP_TAC(TAUT
17188      `(p /\ q ==> r) ==> a /\ ~r ==> a /\ ~p \/ a /\ ~q`) THEN
17189     GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [GSYM ETA_AX] THEN
17190     ASM_SIMP_TAC[CONTINUOUS_SUB]] THEN
17191   REPEAT STRIP_TAC THEN ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN
17192   ASM_REWRITE_TAC[NOT_IN_EMPTY; EMPTY_GSPEC; COUNTABLE_EMPTY] THEN
17193   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
17194   ASM_SIMP_TAC[CLOSED_OPEN_INTERVAL_1] THEN
17195   MATCH_MP_TAC COUNTABLE_SUBSET THEN EXISTS_TAC
17196    `a INSERT b INSERT
17197     {x | x IN interval(a,b) /\ ~((f:real^1->real^1) continuous at x)}` THEN
17198   CONJ_TAC THENL [REWRITE_TAC[COUNTABLE_INSERT]; SET_TAC[]] THEN
17199   SUBGOAL_THEN
17200    `(!c:real^1. c IN interval(a,b) ==> c limit_point_of interval[a,c]) /\
17201     (!c:real^1. c IN interval(a,b) ==> c limit_point_of interval[c,b])`
17202   STRIP_ASSUME_TAC THENL
17203    [SIMP_TAC[IN_INTERVAL_1; REAL_LE_REFL; LIMPT_OF_CONVEX;
17204              CONVEX_INTERVAL; REAL_LT_IMP_LE] THEN
17205     REWRITE_TAC[GSYM INTERVAL_SING; GSYM SUBSET_ANTISYM_EQ] THEN
17206     REWRITE_TAC[SUBSET_INTERVAL_1] THEN REAL_ARITH_TAC;
17207     ALL_TAC] THEN
17208   MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`]
17209         INCREASING_LEFT_LIMIT_1) THEN
17210   ASM_REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
17211   DISCH_THEN(X_CHOOSE_THEN `l:real^1->real^1` (LABEL_TAC "l")) THEN
17212   MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`]
17213         INCREASING_RIGHT_LIMIT_1) THEN
17214   ASM_REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
17215   DISCH_THEN(X_CHOOSE_THEN `r:real^1->real^1` (LABEL_TAC "r")) THEN
17216   SUBGOAL_THEN
17217    `!c. c IN interval(a:real^1,b)
17218         ==> drop(l c) <= drop(f c) /\ drop(f c) <= drop(r c)`
17219   ASSUME_TAC THENL
17220    [REPEAT STRIP_TAC THENL
17221      [MATCH_MP_TAC(ISPEC `at c within interval[a:real^1,c]`
17222         LIM_DROP_UBOUND);
17223       MATCH_MP_TAC(ISPEC `at c within interval[c:real^1,b]`
17224         LIM_DROP_LBOUND)] THEN
17225     EXISTS_TAC `f:real^1->real^1` THEN
17226     ASM_SIMP_TAC[REWRITE_RULE[SUBSET] INTERVAL_OPEN_SUBSET_CLOSED;
17227                  TRIVIAL_LIMIT_WITHIN; EVENTUALLY_WITHIN] THEN
17228     EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01; IN_INTERVAL_1] THEN
17229     REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
17230     REWRITE_TAC[IN_INTERVAL_1] THEN
17231     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
17232     ALL_TAC] THEN
17233   SUBGOAL_THEN
17234    `(!c x. c IN interval(a:real^1,b) /\ x IN interval[a,b] /\ drop x < drop c
17235            ==> drop(f x) <= drop(l c)) /\
17236     (!c x. c IN interval(a:real^1,b) /\ x IN interval[a,b] /\ drop c < drop x
17237            ==> drop(r c) <= drop(f x))`
17238   STRIP_ASSUME_TAC THENL
17239    [REPEAT STRIP_TAC THENL
17240      [MATCH_MP_TAC(ISPEC `at c within interval[a:real^1,c]`
17241         LIM_DROP_LBOUND);
17242       MATCH_MP_TAC(ISPEC `at c within interval[c:real^1,b]`
17243         LIM_DROP_UBOUND)] THEN
17244     EXISTS_TAC `f:real^1->real^1` THEN
17245     ASM_SIMP_TAC[REWRITE_RULE[SUBSET] INTERVAL_OPEN_SUBSET_CLOSED;
17246                  TRIVIAL_LIMIT_WITHIN; EVENTUALLY_WITHIN]
17247     THENL
17248      [EXISTS_TAC `drop c - drop x`; EXISTS_TAC `drop x - drop c`] THEN
17249     ASM_REWRITE_TAC[REAL_SUB_LT] THEN
17250     X_GEN_TAC `y:real^1` THEN
17251     REWRITE_TAC[IN_INTERVAL_1; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN
17252     STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
17253     ASM_REWRITE_TAC[IN_INTERVAL_1] THEN
17254     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
17255     ALL_TAC] THEN
17256   REWRITE_TAC[COUNTABLE; ge_c] THEN
17257   TRANS_TAC CARD_LE_TRANS `rational` THEN
17258   GEN_REWRITE_TAC RAND_CONV [GSYM ge_c] THEN
17259   REWRITE_TAC[COUNTABLE_RATIONAL; GSYM COUNTABLE; le_c] THEN
17260   SUBGOAL_THEN
17261    `!c. c IN interval(a,b) /\ ~((f:real^1->real^1) continuous at c)
17262           ==> drop(l(c:real^1)) < drop(r c)`
17263   ASSUME_TAC THENL
17264    [REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_LT_LE] THEN
17265     CONJ_TAC THENL [ASM_MESON_TAC[REAL_LE_TRANS]; ALL_TAC] THEN
17266     REWRITE_TAC[DROP_EQ] THEN DISCH_TAC THEN
17267     SUBGOAL_THEN `l c = (f:real^1->real^1) c /\ r c = f c` ASSUME_TAC THENL
17268      [ASM_MESON_TAC[REAL_LE_ANTISYM; DROP_EQ]; ALL_TAC] THEN
17269     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CONTINUOUS_AT]) THEN
17270     REWRITE_TAC[] THEN
17271     SUBGOAL_THEN
17272      `((f:real^1->real^1) --> f c) (at c within interval(a,b))`
17273     MP_TAC THENL
17274      [ALL_TAC; ASM_SIMP_TAC[OPEN_INTERVAL; LIM_WITHIN_OPEN]] THEN
17275     MATCH_MP_TAC LIM_WITHIN_SUBSET THEN
17276     EXISTS_TAC `interval[a:real^1,c] UNION interval[c,b]` THEN
17277     REWRITE_TAC[LIM_WITHIN_UNION] THEN CONJ_TAC THENL
17278      [ASM_MESON_TAC[REWRITE_RULE[SUBSET] INTERVAL_OPEN_SUBSET_CLOSED];
17279       REWRITE_TAC[SUBSET; IN_UNION; IN_INTERVAL_1] THEN REAL_ARITH_TAC];
17280     ALL_TAC] THEN
17281   SUBGOAL_THEN
17282    `!c. c IN interval(a,b) /\ ~((f:real^1->real^1) continuous at c)
17283         ==> ?q. rational q /\ drop(l c) < q /\ q < drop(r c)`
17284   MP_TAC THENL
17285    [REPEAT STRIP_TAC THEN
17286     SUBGOAL_THEN `drop(l(c:real^1)) < drop(r c)` ASSUME_TAC THENL
17287      [ASM_MESON_TAC[]; ALL_TAC] THEN
17288     MP_TAC(ISPECL [`(drop(l(c:real^1)) + drop(r c)) / &2`;
17289                    `(drop(r c) - drop(l(c:real^1))) / &2`]
17290       RATIONAL_APPROXIMATION) THEN
17291     ASM_REWRITE_TAC[REAL_HALF; REAL_SUB_LT] THEN
17292     MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN REAL_ARITH_TAC;
17293     ALL_TAC] THEN
17294   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
17295   REWRITE_TAC[SKOLEM_THM; IN_ELIM_THM; IN_INTERVAL_1] THEN
17296   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `q:real^1->real` THEN
17297   SIMP_TAC[IN] THEN DISCH_THEN(LABEL_TAC "*") THEN
17298   MATCH_MP_TAC(MESON[REAL_LE_TOTAL]
17299    `(!x y. P x y ==> P y x) /\ (!x y. drop x <= drop y ==> P x y)
17300     ==> !x y. P x y`) THEN
17301   CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
17302   MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN
17303   REWRITE_TAC[REAL_LE_LT; DROP_EQ] THEN
17304   ASM_CASES_TAC `x:real^1 = y` THEN ASM_REWRITE_TAC[] THEN
17305   REPEAT STRIP_TAC THEN
17306   SUBGOAL_THEN `q(x:real^1) < q(y)` MP_TAC THENL
17307    [ALL_TAC; ASM_REWRITE_TAC[REAL_LT_REFL]] THEN
17308   MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `drop(r(x:real^1))` THEN
17309   ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN
17310   MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `drop(l(y:real^1))` THEN
17311   ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN
17312   MATCH_MP_TAC REAL_LE_TRANS THEN
17313   EXISTS_TAC `drop(f(inv(&2) % (x + y):real^1))` THEN
17314   CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
17315   ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_CMUL; DROP_ADD] THEN
17316   ASM_REAL_ARITH_TAC);;
17317
17318 let HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE = prove
17319  (`!f:real^1->real^N s a b.
17320         COUNTABLE s /\ f continuous_on interval[a,b] /\
17321         (!x. x IN interval[a,b] DIFF s ==> f differentiable at x)
17322         ==> (f has_bounded_variation_on interval[a,b] <=>
17323              (\x. vector_derivative f (at x))
17324              absolutely_integrable_on interval[a,b])`,
17325   REPEAT STRIP_TAC THEN
17326   REWRITE_TAC[ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_EQ] THEN
17327   REWRITE_TAC[has_bounded_variation_on] THEN
17328   MATCH_MP_TAC(TAUT `q /\ (p <=> r) ==> (p <=> q /\ r)`) THEN CONJ_TAC THENL
17329    [ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN
17330     ASM_REWRITE_TAC[INTEGRABLE_ON_EMPTY] THEN
17331     RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY_1]) THEN
17332     MP_TAC(ISPECL [`f:real^1->real^N`;
17333                    `\x. vector_derivative (f:real^1->real^N) (at x)`;
17334                    `s:real^1->bool`; `a:real^1`; `b:real^1`]
17335       FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG) THEN
17336     ASM_MESON_TAC[VECTOR_DERIVATIVE_WORKS; integrable_on;
17337                   HAS_VECTOR_DERIVATIVE_AT_WITHIN];
17338     MATCH_MP_TAC(MESON[HAS_BOUNDED_SETVARIATION_ON_EQ]
17339      `(!a b. ~(interval[a,b] = {}) /\ interval[a,b] SUBSET s
17340                ==> f(interval[a,b]) = g(interval[a,b]))
17341       ==> (f has_bounded_setvariation_on s <=>
17342            g has_bounded_setvariation_on s)`) THEN
17343     SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND;
17344              GSYM INTERVAL_NE_EMPTY] THEN
17345     MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN
17346     REWRITE_TAC[INTERVAL_NE_EMPTY_1] THEN STRIP_TAC THEN
17347     MP_TAC(ISPECL [`f:real^1->real^N`;
17348                    `\x. vector_derivative (f:real^1->real^N) (at x)`;
17349                    `s:real^1->bool`; `u:real^1`; `v:real^1`]
17350       FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG) THEN
17351     ASM_REWRITE_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN
17352     ANTS_TAC THENL [ALL_TAC; MESON_TAC[INTEGRAL_UNIQUE]] THEN CONJ_TAC THENL
17353      [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; IN_DIFF; SUBSET];
17354       REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_AT_WITHIN THEN
17355       ASM_SIMP_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN ASM SET_TAC[]]]);;
17356
17357 let HAS_BOUNDED_VARIATION_INTEGRABLE_NORM_DERIVATIVE = prove
17358  (`!f:real^1->real^N s a b.
17359         COUNTABLE s /\ f continuous_on interval[a,b] /\
17360         (!x. x IN interval[a,b] DIFF s ==> f differentiable at x)
17361         ==> (f has_bounded_variation_on interval[a,b] <=>
17362              (\x. lift(norm(vector_derivative f (at x))))
17363              integrable_on interval[a,b])`,
17364   REPEAT GEN_TAC THEN DISCH_THEN(fun th ->
17365     STRIP_ASSUME_TAC th THEN
17366     REWRITE_TAC[MATCH_MP HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE
17367                 th]) THEN
17368   REWRITE_TAC[absolutely_integrable_on] THEN
17369   MATCH_MP_TAC(TAUT `p ==> (p /\ q <=> q)`) THEN
17370   ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN
17371   ASM_REWRITE_TAC[INTEGRABLE_ON_EMPTY] THEN
17372   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY_1]) THEN
17373   MP_TAC(ISPECL [`f:real^1->real^N`;
17374                  `\x. vector_derivative (f:real^1->real^N) (at x)`;
17375                  `s:real^1->bool`; `a:real^1`; `b:real^1`]
17376     FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG) THEN
17377   ASM_MESON_TAC[VECTOR_DERIVATIVE_WORKS; integrable_on;
17378                 HAS_VECTOR_DERIVATIVE_AT_WITHIN]);;
17379
17380 let VECTOR_VARIATION_INTEGRAL_NORM_DERIVATIVE = prove
17381  (`!f:real^1->real^N s a b.
17382         COUNTABLE s /\ f continuous_on interval[a,b] /\
17383         (!x. x IN interval[a,b] DIFF s ==> f differentiable at x) /\
17384         f has_bounded_variation_on interval[a,b]
17385         ==> vector_variation (interval[a,b]) f =
17386                 drop(integral (interval[a,b])
17387                         (\x. lift(norm(vector_derivative f (at x)))))`,
17388   REPEAT STRIP_TAC THEN MP_TAC(ISPECL
17389    [`f:real^1->real^N`; `s:real^1->bool`; `a:real^1`; `b:real^1`]
17390    HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE) THEN
17391   ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
17392   FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_SET_VARIATION) THEN
17393   REWRITE_TAC[vector_variation] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
17394   MATCH_MP_TAC SET_VARIATION_EQ THEN
17395   MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN
17396   SIMP_TAC[INTERVAL_NE_EMPTY_1; INTERVAL_LOWERBOUND_1;
17397            INTERVAL_UPPERBOUND_1] THEN
17398   STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
17399   MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG THEN
17400   EXISTS_TAC `s:real^1->bool` THEN ASM_REWRITE_TAC[] THEN
17401   CONJ_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN
17402   ASM_MESON_TAC[VECTOR_DERIVATIVE_WORKS; HAS_VECTOR_DERIVATIVE_AT_WITHIN;
17403                 IN_DIFF; SUBSET]);;
17404
17405 let INTEGRABLE_BOUNDED_VARIATION_PRODUCT = prove
17406  (`!f:real^1->real^N g a b.
17407         f integrable_on interval[a,b] /\
17408         g has_bounded_variation_on interval[a,b]
17409         ==> (\x. drop(g x) % f x) integrable_on interval[a,b]`,
17410   REPEAT STRIP_TAC THEN FIRST_X_ASSUM
17411    (MP_TAC o GEN_REWRITE_RULE I [HAS_BOUNDED_VARIATION_DARBOUX]) THEN
17412   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
17413   MAP_EVERY X_GEN_TAC [`h:real^1->real^1`; `k:real^1->real^1`] THEN
17414   STRIP_TAC THEN ASM_REWRITE_TAC[DROP_SUB; VECTOR_SUB_RDISTRIB] THEN
17415   MATCH_MP_TAC INTEGRABLE_SUB THEN
17416   CONJ_TAC THEN MATCH_MP_TAC INTEGRABLE_INCREASING_PRODUCT THEN
17417   ASM_REWRITE_TAC[]);;
17418
17419 let INTEGRABLE_BOUNDED_VARIATION_PRODUCT_ALT = prove
17420  (`!f:real^1->real^N g a b.
17421         f integrable_on interval[a,b] /\
17422         (lift o g) has_bounded_variation_on interval[a,b]
17423         ==> (\x. g x % f x) integrable_on interval[a,b]`,
17424   REPEAT GEN_TAC THEN
17425   DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_BOUNDED_VARIATION_PRODUCT) THEN
17426   REWRITE_TAC[o_DEF; LIFT_DROP]);;
17427
17428 let HAS_BOUNDED_VARIATION_ON_INDEFINITE_INTEGRAL_RIGHT = prove
17429  (`!f:real^1->real^N a b.
17430         f absolutely_integrable_on interval[a,b]
17431         ==> (\c. integral (interval[a,c]) f) has_bounded_variation_on
17432             interval[a,b]`,
17433   REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
17434   FIRST_ASSUM(MP_TAC o
17435     MATCH_MP ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION) THEN
17436   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_BOUNDED_SETVARIATION_ON_EQ) THEN
17437   SIMP_TAC[INTERVAL_LOWERBOUND_NONEMPTY; LIFT_EQ;
17438            INTERVAL_UPPERBOUND_NONEMPTY] THEN
17439   SIMP_TAC[INTERVAL_NE_EMPTY_1; SUBSET_INTERVAL_1; GSYM REAL_NOT_LE] THEN
17440   REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_ARITH
17441    `a:real^N = b - c <=> c + a = b`] THEN
17442   MATCH_MP_TAC INTEGRAL_COMBINE THEN ASM_REWRITE_TAC[] THEN
17443   FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE) THEN
17444   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] INTEGRABLE_ON_SUBINTERVAL) THEN
17445   ASM_REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC);;
17446
17447 let HAS_BOUNDED_VARIATION_ON_INDEFINITE_INTEGRAL_LEFT = prove
17448  (`!f:real^1->real^N a b.
17449         f absolutely_integrable_on interval[a,b]
17450         ==> (\c. integral (interval[c,b]) f) has_bounded_variation_on
17451             interval[a,b]`,
17452   REPEAT STRIP_TAC THEN
17453   REWRITE_TAC[has_bounded_variation_on] THEN
17454   ONCE_REWRITE_TAC[GSYM HAS_BOUNDED_SETVARIATION_ON_NEG] THEN
17455   FIRST_ASSUM(MP_TAC o
17456     MATCH_MP ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION) THEN
17457   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_BOUNDED_SETVARIATION_ON_EQ) THEN
17458   SIMP_TAC[INTERVAL_LOWERBOUND_NONEMPTY; LIFT_EQ;
17459            INTERVAL_UPPERBOUND_NONEMPTY] THEN
17460   SIMP_TAC[INTERVAL_NE_EMPTY_1; SUBSET_INTERVAL_1; GSYM REAL_NOT_LE] THEN
17461   REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_ARITH
17462    `a:real^N = --(b - c) <=> a + b = c`] THEN
17463   MATCH_MP_TAC INTEGRAL_COMBINE THEN ASM_REWRITE_TAC[] THEN
17464   FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE) THEN
17465   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] INTEGRABLE_ON_SUBINTERVAL) THEN
17466   ASM_REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC);;
17467
17468 (* ------------------------------------------------------------------------- *)
17469 (* Rectifiable paths and path length defined using variation.                *)
17470 (* ------------------------------------------------------------------------- *)
17471
17472 let rectifiable_path = new_definition
17473  `rectifiable_path (g:real^1->real^N) <=>
17474     path g /\ g has_bounded_variation_on interval[vec 0,vec 1]`;;
17475
17476 let path_length = new_definition
17477  `path_length (g:real^1->real^N) =
17478   vector_variation (interval[vec 0,vec 1]) g`;;
17479
17480 let BOUNDED_RECTIFIABLE_PATH_IMAGE = prove
17481  (`!g:real^1->real^N. rectifiable_path g ==> bounded(path_image g)`,
17482   SIMP_TAC[rectifiable_path; BOUNDED_PATH_IMAGE]);;
17483
17484 let RECTIFIABLE_PATH_IMP_PATH = prove
17485  (`!g:real^1->real^N. rectifiable_path g ==> path g`,
17486   SIMP_TAC[rectifiable_path]);;
17487
17488 let RECTIFIABLE_PATH_LINEPATH = prove
17489  (`!a b:real^N. rectifiable_path(linepath(a,b))`,
17490   REPEAT GEN_TAC THEN REWRITE_TAC[rectifiable_path; PATH_LINEPATH] THEN
17491   REWRITE_TAC[linepath] THEN
17492   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_ADD THEN
17493   REWRITE_TAC[GSYM DROP_VEC; GSYM DROP_SUB] THEN
17494   CONJ_TAC THEN MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_MUL THEN
17495   REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_CONST] THEN
17496   REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_ID] THEN
17497   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN
17498   REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_CONST] THEN
17499   REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_ID]);;
17500
17501 let RECTIFIABLE_PATH_REVERSEPATH = prove
17502  (`!g:real^1->real^N. rectifiable_path(reversepath g) <=> rectifiable_path g`,
17503   SUBGOAL_THEN
17504    `!g:real^1->real^N. rectifiable_path g ==> rectifiable_path(reversepath g)`
17505    (fun th -> MESON_TAC[th; REVERSEPATH_REVERSEPATH]) THEN
17506   GEN_TAC THEN REWRITE_TAC[rectifiable_path] THEN
17507   MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[PATH_REVERSEPATH] THEN
17508   REWRITE_TAC[reversepath] THEN DISCH_TAC THEN
17509   GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
17510   MATCH_MP_TAC HAS_BOUNDED_VARIATION_COMPOSE_DECREASING THEN
17511   ASM_REWRITE_TAC[DROP_SUB; VECTOR_SUB_RZERO; VECTOR_SUB_REFL] THEN
17512   REAL_ARITH_TAC);;
17513
17514 let PATH_LENGTH_REVERSEPATH = prove
17515  (`!g:real^1->real^N. path_length(reversepath g) = path_length g`,
17516   GEN_TAC THEN REWRITE_TAC[path_length; reversepath] THEN
17517   REWRITE_TAC[VECTOR_SUB; VECTOR_VARIATION_REFLECT] THEN
17518   REWRITE_TAC[VECTOR_VARIATION_TRANSLATION] THEN
17519   REWRITE_TAC[REFLECT_INTERVAL; GSYM INTERVAL_TRANSLATION] THEN
17520   REWRITE_TAC[GSYM VECTOR_SUB; VECTOR_SUB_REFL; VECTOR_SUB_RZERO]);;
17521
17522 let RECTIFIABLE_PATH_SUBPATH = prove
17523  (`!u v g:real^1->real^N.
17524         rectifiable_path g /\
17525         u IN interval[vec 0,vec 1] /\
17526         v IN interval[vec 0,vec 1]
17527         ==> rectifiable_path(subpath u v g)`,
17528   REPEAT GEN_TAC THEN SIMP_TAC[PATH_SUBPATH; rectifiable_path] THEN
17529   STRIP_TAC THEN REWRITE_TAC[subpath] THEN
17530   ONCE_REWRITE_TAC[VECTOR_ADD_SYM] THEN
17531   REWRITE_TAC[HAS_BOUNDED_VARIATION_AFFINITY_EQ; IMAGE_AFFINITY_INTERVAL] THEN
17532   REWRITE_TAC[UNIT_INTERVAL_NONEMPTY; DROP_SUB; REAL_SUB_LE; REAL_SUB_0] THEN
17533   DISJ2_TAC THEN COND_CASES_TAC THEN
17534   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
17535         HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
17536   REWRITE_TAC[SUBSET_INTERVAL_1] THEN
17537   REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_VEC] THEN
17538   RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN
17539   ASM_REAL_ARITH_TAC);;
17540
17541 let RECTIFIABLE_PATH_JOIN = prove
17542  (`!g1 g2:real^1->real^N.
17543         pathfinish g1 = pathstart g2
17544         ==> (rectifiable_path(g1 ++ g2) <=>
17545              rectifiable_path g1 /\ rectifiable_path g2)`,
17546   REPEAT GEN_TAC THEN SIMP_TAC[rectifiable_path; PATH_JOIN] THEN
17547   REWRITE_TAC[pathfinish; pathstart] THEN DISCH_TAC THEN
17548   ASM_CASES_TAC `path(g1:real^1->real^N)` THEN ASM_REWRITE_TAC[] THEN
17549   ASM_CASES_TAC `path(g2:real^1->real^N)` THEN ASM_REWRITE_TAC[] THEN
17550   MP_TAC(ISPECL [`g1 ++ g2:real^1->real^N`; `vec 0:real^1`; `vec 1:real^1`;
17551                  `lift(&1 / &2)`]
17552         HAS_BOUNDED_VARIATION_ON_COMBINE) THEN
17553   REWRITE_TAC[DROP_VEC; LIFT_DROP] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
17554   DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[joinpaths] THEN BINOP_TAC THEN
17555   MATCH_MP_TAC EQ_TRANS THENL
17556    [EXISTS_TAC
17557      `(\x. (g1:real^1->real^N)(&2 % x)) has_bounded_variation_on
17558       interval [vec 0,lift(&1 / &2)]` THEN
17559     ONCE_REWRITE_TAC[VECTOR_ARITH `&2 % x:real^N = &2 % x + vec 0`];
17560     EXISTS_TAC
17561      `(\x. (g2:real^1->real^N)(&2 % x - vec 1)) has_bounded_variation_on
17562       interval [lift (&1 / &2),vec 1]` THEN
17563     ONCE_REWRITE_TAC[VECTOR_ARITH `&2 % x - v:real^N = &2 % x + --v`]] THEN
17564   (CONJ_TAC THENL
17565     [ALL_TAC;
17566      REWRITE_TAC[HAS_BOUNDED_VARIATION_AFFINITY_EQ] THEN
17567      REWRITE_TAC[IMAGE_AFFINITY_INTERVAL; INTERVAL_EQ_EMPTY_1] THEN
17568      REWRITE_TAC[DROP_VEC; LIFT_DROP] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
17569      AP_TERM_TAC THEN AP_TERM_TAC THEN
17570      REWRITE_TAC[CONS_11; PAIR_EQ; GSYM DROP_EQ] THEN
17571      REWRITE_TAC[DROP_ADD; DROP_CMUL; LIFT_DROP; DROP_VEC; DROP_NEG] THEN
17572      REAL_ARITH_TAC]) THEN
17573   MATCH_MP_TAC(MESON[HAS_BOUNDED_VARIATION_ON_EQ]
17574    `(!x. x IN s ==> f x = g x)
17575     ==> (f has_bounded_variation_on s <=>
17576          g has_bounded_variation_on s)`) THEN
17577   SIMP_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN X_GEN_TAC `x:real^1` THEN
17578   COND_CASES_TAC THEN REWRITE_TAC[] THEN STRIP_TAC THEN
17579   SUBGOAL_THEN `&2 % x + --vec 1:real^1 = vec 0 /\ &2 % x = vec 1`
17580     (fun th -> ASM_REWRITE_TAC[th]) THEN
17581   REWRITE_TAC[VECTOR_SUB_EQ; GSYM VECTOR_SUB] THEN
17582   REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_VEC] THEN ASM_REAL_ARITH_TAC);;
17583
17584 let RECTIFIABLE_PATH_JOIN_IMP = prove
17585  (`!g1 g2:real^1->real^N.
17586         rectifiable_path g1 /\ rectifiable_path g2 /\
17587         pathfinish g1 = pathstart g2
17588         ==> rectifiable_path(g1 ++ g2)`,
17589   SIMP_TAC[RECTIFIABLE_PATH_JOIN]);;
17590
17591 let RECTIFIABLE_PATH_JOIN_EQ = prove
17592  (`!g1 g2:real^1->real^N.
17593         rectifiable_path g1 /\ rectifiable_path g2
17594         ==> (rectifiable_path (g1 ++ g2) <=> pathfinish g1 = pathstart g2)`,
17595   REPEAT STRIP_TAC THEN EQ_TAC THEN
17596   ASM_SIMP_TAC[RECTIFIABLE_PATH_JOIN_IMP] THEN
17597   DISCH_TAC THEN MATCH_MP_TAC PATH_JOIN_PATH_ENDS THEN
17598   ASM_SIMP_TAC[RECTIFIABLE_PATH_IMP_PATH]);;
17599
17600 let PATH_LENGTH_JOIN = prove
17601  (`!g1 g2:real^1->real^N.
17602         rectifiable_path g1 /\ rectifiable_path g2 /\
17603         pathfinish g1 = pathstart g2
17604         ==> path_length(g1 ++ g2) = path_length g1 + path_length g2`,
17605   REPEAT STRIP_TAC THEN REWRITE_TAC[path_length] THEN
17606   MP_TAC(ISPECL [`g1 ++ g2:real^1->real^N`; `vec 0:real^1`; `vec 1:real^1`;
17607                  `lift(&1 / &2)`]
17608         VECTOR_VARIATION_COMBINE) THEN
17609   REWRITE_TAC[DROP_VEC; LIFT_DROP] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
17610   ANTS_TAC THENL
17611    [ASM_MESON_TAC[rectifiable_path; RECTIFIABLE_PATH_JOIN_IMP];
17612     DISCH_THEN(SUBST1_TAC o SYM)] THEN
17613   MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC
17614    `vector_variation (interval [vec 0,lift (&1 / &2)])
17615                      (\x. (g1:real^1->real^N)(&2 % x)) +
17616     vector_variation (interval [lift (&1 / &2),vec 1])
17617                      (\x.  (g2:real^1->real^N)(&2 % x - vec 1))` THEN
17618   CONJ_TAC THENL
17619    [BINOP_TAC THEN MATCH_MP_TAC VECTOR_VARIATION_EQ THEN
17620     SIMP_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC; joinpaths] THEN
17621     RULE_ASSUM_TAC(REWRITE_RULE[pathfinish; pathstart]) THEN
17622     X_GEN_TAC `x:real^1` THEN
17623     REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN
17624     COND_CASES_TAC THEN REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
17625     SUBGOAL_THEN `&2 % x - vec 1:real^1 = vec 0 /\ &2 % x = vec 1`
17626      (fun th -> ASM_REWRITE_TAC[th]) THEN
17627     REWRITE_TAC[VECTOR_SUB_EQ] THEN
17628     REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_VEC] THEN ASM_REAL_ARITH_TAC;
17629     ONCE_REWRITE_TAC[VECTOR_ARITH `&2 % x:real^N = &2 % x + vec 0`] THEN
17630     ONCE_REWRITE_TAC[VECTOR_ARITH
17631      `(&2 % x + vec 0) - v:real^N = &2 % x + --v`] THEN
17632     REWRITE_TAC[VECTOR_VARIATION_AFFINITY; IMAGE_AFFINITY_INTERVAL] THEN
17633     REWRITE_TAC[INTERVAL_EQ_EMPTY_1; LIFT_DROP; DROP_VEC] THEN
17634     CONV_TAC REAL_RAT_REDUCE_CONV THEN BINOP_TAC THEN
17635     AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
17636     REWRITE_TAC[CONS_11; PAIR_EQ; GSYM DROP_EQ] THEN
17637     REWRITE_TAC[DROP_ADD; DROP_CMUL; LIFT_DROP; DROP_VEC; DROP_NEG] THEN
17638     REAL_ARITH_TAC]);;
17639
17640 (* ------------------------------------------------------------------------- *)
17641 (* Useful equivalent formulations where the path is differentiable.          *)
17642 (* ------------------------------------------------------------------------- *)
17643
17644 let RECTIFIABLE_PATH_DIFFERENTIABLE = prove
17645  (`!g:real^1->real^N s.
17646         COUNTABLE s /\ path g /\
17647         (!t. t IN interval[vec 0,vec 1] DIFF s ==> g differentiable at t)
17648         ==> (rectifiable_path g <=>
17649                 (\t. vector_derivative g (at t))
17650                 absolutely_integrable_on interval[vec 0,vec 1])`,
17651   SIMP_TAC[rectifiable_path] THEN REWRITE_TAC[path] THEN
17652   REPEAT STRIP_TAC THEN MATCH_MP_TAC
17653     HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE THEN
17654   EXISTS_TAC `s:real^1->bool` THEN ASM_REWRITE_TAC[]);;
17655
17656 let PATH_LENGTH_DIFFERENTIABLE = prove
17657  (`!g:real^1->real^N s.
17658         COUNTABLE s /\ rectifiable_path g /\
17659         (!t. t IN interval[vec 0,vec 1] DIFF s ==> g differentiable at t)
17660         ==> path_length g =
17661                 drop(integral (interval[vec 0,vec 1])
17662                               (\t. lift(norm(vector_derivative g (at t)))))`,
17663   REWRITE_TAC[rectifiable_path; path_length; path] THEN REPEAT STRIP_TAC THEN
17664   MATCH_MP_TAC VECTOR_VARIATION_INTEGRAL_NORM_DERIVATIVE THEN
17665   EXISTS_TAC `s:real^1->bool` THEN ASM_REWRITE_TAC[]);;