Update from HH
[Multivariate Analysis/.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 (* ------------------------------------------------------------------------- *)
181 (* Content (length, area, volume...) of an interval.                         *)
182 (* ------------------------------------------------------------------------- *)
183
184 let content = new_definition
185    `content(s:real^M->bool) =
186        if s = {} then &0 else
187        product(1..dimindex(:M))
188               (\i. (interval_upperbound s)$i - (interval_lowerbound s)$i)`;;
189
190 let CONTENT_CLOSED_INTERVAL = prove
191  (`!a b:real^N. (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= b$i)
192                 ==> content(interval[a,b]) =
193                         product(1..dimindex(:N)) (\i. b$i - a$i)`,
194   SIMP_TAC[content; INTERVAL_UPPERBOUND; INTERVAL_EQ_EMPTY;
195            INTERVAL_LOWERBOUND] THEN
196   MESON_TAC[REAL_NOT_LT]);;
197
198 let CONTENT_1 = prove
199  (`!a b. drop a <= drop b ==> content(interval[a,b]) = drop b - drop a`,
200   SIMP_TAC[CONTENT_CLOSED_INTERVAL; FORALL_1; drop; DIMINDEX_1] THEN
201   REWRITE_TAC[PRODUCT_SING_NUMSEG]);;
202
203 let CONTENT_UNIT = prove
204  (`content(interval[vec 0:real^N,vec 1]) = &1`,
205   REWRITE_TAC[content] THEN COND_CASES_TAC THENL
206    [POP_ASSUM MP_TAC THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
207     SIMP_TAC[INTERVAL_NE_EMPTY; VEC_COMPONENT; REAL_POS];
208     MATCH_MP_TAC PRODUCT_EQ_1 THEN
209     SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND;
210              VEC_COMPONENT; REAL_POS; IN_NUMSEG; REAL_SUB_RZERO]]);;
211
212 let CONTENT_UNIT_1 = prove
213  (`content(interval[vec 0:real^1,vec 1]) = &1`,
214   MATCH_ACCEPT_TAC CONTENT_UNIT);;
215
216 let CONTENT_POS_LE = prove
217  (`!a b:real^N. &0 <= content(interval[a,b])`,
218   REPEAT GEN_TAC THEN REWRITE_TAC[content] THEN
219   COND_CASES_TAC THEN REWRITE_TAC[REAL_LE_REFL] THEN
220   MATCH_MP_TAC PRODUCT_POS_LE_NUMSEG THEN
221   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN
222   ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_SUB_LE]);;
223
224 let CONTENT_POS_LT = prove
225  (`!a b:real^N.
226         (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i)
227         ==> &0 < content(interval[a,b])`,
228   REPEAT STRIP_TAC THEN
229   ASM_SIMP_TAC[CONTENT_CLOSED_INTERVAL; REAL_LT_IMP_LE] THEN
230   MATCH_MP_TAC PRODUCT_POS_LT_NUMSEG THEN
231   ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_SUB_LT;
232                REAL_LT_IMP_LE]);;
233
234 let CONTENT_POS_LT_1 = prove
235  (`!a b. drop a < drop b ==> &0 < content(interval[a,b])`,
236   SIMP_TAC[CONTENT_POS_LT; FORALL_1; DIMINDEX_1; GSYM drop]);;
237
238 let CONTENT_EQ_0_GEN = prove
239  (`!s:real^N->bool.
240      bounded s
241      ==> (content s = &0 <=>
242           ?i a. 1 <= i /\ i <= dimindex(:N) /\ !x. x IN s ==> x$i = a)`,
243   REPEAT GEN_TAC THEN REWRITE_TAC[content] THEN
244   COND_CASES_TAC THEN ASM_REWRITE_TAC[NOT_IN_EMPTY] THENL
245    [MESON_TAC[DIMINDEX_GE_1; LE_REFL]; ALL_TAC] THEN
246   REWRITE_TAC[PRODUCT_EQ_0_NUMSEG; REAL_SUB_0] THEN DISCH_TAC THEN
247   AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
248   X_GEN_TAC `k:num` THEN
249   ASM_CASES_TAC `1 <= k` THEN ASM_REWRITE_TAC[] THEN
250   ASM_CASES_TAC `k <= dimindex(:N)` THEN ASM_REWRITE_TAC[] THEN
251   ASM_SIMP_TAC[interval_upperbound; interval_lowerbound; LAMBDA_BETA] THEN
252   W(MP_TAC o PART_MATCH (lhs o rand) REAL_SUP_EQ_INF o lhs o snd) THEN
253   ANTS_TAC THENL
254    [CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
255     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
256     REWRITE_TAC[IN_ELIM_THM] THEN
257     ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS];
258     DISCH_THEN SUBST1_TAC THEN ASM SET_TAC[]]);;
259
260 let CONTENT_EQ_0 = prove
261  (`!a b:real^N.
262         content(interval[a,b]) = &0 <=>
263         ?i. 1 <= i /\ i <= dimindex(:N) /\ b$i <= a$i`,
264   REPEAT GEN_TAC THEN REWRITE_TAC[content; INTERVAL_EQ_EMPTY] THEN
265   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
266    [ASM_MESON_TAC[REAL_LT_IMP_LE]; ALL_TAC] THEN
267   REWRITE_TAC[PRODUCT_EQ_0_NUMSEG; REAL_SUB_0] THEN
268   AP_TERM_TAC THEN ABS_TAC THEN POP_ASSUM MP_TAC THEN
269   REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN
270   SIMP_TAC[REAL_NOT_LT; INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN
271   MESON_TAC[REAL_NOT_LE; REAL_LE_LT]);;
272
273 let CONTENT_0_SUBSET_GEN = prove
274  (`!s t:real^N->bool.
275       s SUBSET t /\ bounded t /\ content t = &0 ==> content s = &0`,
276   REPEAT GEN_TAC THEN
277   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
278   SUBGOAL_THEN `bounded(s:real^N->bool)` ASSUME_TAC THENL
279    [ASM_MESON_TAC[BOUNDED_SUBSET]; ALL_TAC] THEN
280   ASM_SIMP_TAC[CONTENT_EQ_0_GEN] THEN ASM SET_TAC[]);;
281
282 let CONTENT_0_SUBSET = prove
283  (`!s a b:real^N.
284         s SUBSET interval[a,b] /\ content(interval[a,b]) = &0
285         ==> content s = &0`,
286   MESON_TAC[CONTENT_0_SUBSET_GEN; BOUNDED_INTERVAL]);;
287
288 let CONTENT_CLOSED_INTERVAL_CASES = prove
289  (`!a b:real^N.
290         content(interval[a,b]) =
291                 if !i. 1 <= i /\ i <= dimindex(:N) ==> a$i <= b$i
292                 then product(1..dimindex(:N)) (\i. b$i - a$i)
293                 else &0`,
294   REPEAT GEN_TAC THEN COND_CASES_TAC THEN
295   ASM_SIMP_TAC[CONTENT_EQ_0; CONTENT_CLOSED_INTERVAL] THEN
296   ASM_MESON_TAC[REAL_LE_TOTAL]);;
297
298 let CONTENT_EQ_0_INTERIOR = prove
299  (`!a b:real^N.
300         content(interval[a,b]) = &0 <=> interior(interval[a,b]) = {}`,
301   REWRITE_TAC[CONTENT_EQ_0; INTERIOR_CLOSED_INTERVAL; INTERVAL_EQ_EMPTY]);;
302
303 let CONTENT_EQ_0_1 = prove
304  (`!a b:real^1.
305         content(interval[a,b]) = &0 <=> drop b <= drop a`,
306   REWRITE_TAC[CONTENT_EQ_0; drop; DIMINDEX_1; CONJ_ASSOC; LE_ANTISYM] THEN
307   MESON_TAC[]);;
308
309 let CONTENT_POS_LT_EQ = prove
310  (`!a b:real^N.
311         &0 < content(interval[a,b]) <=>
312         !i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i`,
313   REPEAT GEN_TAC THEN EQ_TAC THEN REWRITE_TAC[CONTENT_POS_LT] THEN
314   REWRITE_TAC[REAL_ARITH `&0 < x <=> &0 <= x /\ ~(x = &0)`] THEN
315   REWRITE_TAC[CONTENT_POS_LE; CONTENT_EQ_0] THEN MESON_TAC[REAL_NOT_LE]);;
316
317 let CONTENT_EMPTY = prove
318  (`content {} = &0`,
319   REWRITE_TAC[content]);;
320
321 let CONTENT_SUBSET = prove
322  (`!a b c d:real^N.
323         interval[a,b] SUBSET interval[c,d]
324         ==> content(interval[a,b]) <= content(interval[c,d])`,
325   REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [content] THEN
326   COND_CASES_TAC THEN ASM_REWRITE_TAC[CONTENT_POS_LE] THEN
327   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET]) THEN
328   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN
329   REWRITE_TAC[IN_INTERVAL] THEN DISCH_THEN(fun th ->
330     MP_TAC(SPEC `a:real^N` th) THEN MP_TAC(SPEC `b:real^N` th)) THEN
331   ASM_SIMP_TAC[REAL_LE_REFL; content] THEN REPEAT STRIP_TAC THEN
332   ONCE_REWRITE_TAC[TAUT `(if b then c else d) = (if ~b then d else c)`] THEN
333   REWRITE_TAC[INTERVAL_NE_EMPTY] THEN COND_CASES_TAC THENL
334    [ALL_TAC; ASM_MESON_TAC[REAL_LE_TRANS]] THEN
335   MATCH_MP_TAC PRODUCT_LE_NUMSEG THEN
336   ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN
337   REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN
338   MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
339   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
340   REAL_ARITH_TAC);;
341
342 let CONTENT_LT_NZ = prove
343  (`!a b. &0 < content(interval[a,b]) <=> ~(content(interval[a,b]) = &0)`,
344   REWRITE_TAC[CONTENT_POS_LT_EQ; CONTENT_EQ_0] THEN MESON_TAC[REAL_NOT_LE]);;
345
346 let INTERVAL_BOUNDS_NULL_1 = prove
347  (`!a b:real^1.
348         content(interval[a,b]) = &0
349         ==> interval_upperbound(interval[a,b]) =
350             interval_lowerbound(interval[a,b])`,
351   REPEAT GEN_TAC THEN ASM_CASES_TAC `interval[a:real^1,b] = {}` THENL
352    [ASM_REWRITE_TAC[interval_upperbound; interval_lowerbound] THEN
353     REWRITE_TAC[sup; inf; NOT_IN_EMPTY; EMPTY_GSPEC] THEN DISCH_TAC THEN
354     REPLICATE_TAC 2 (AP_TERM_TAC THEN ABS_TAC) THEN
355     MESON_TAC[REAL_ARITH `~(x <= x - &1) /\ ~(x + &1 <= x)`];
356     RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
357     ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1] THEN
358     REWRITE_TAC[CONTENT_EQ_0_1; GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC]);;
359
360 let INTERVAL_BOUNDS_EMPTY_1 = prove
361  (`interval_upperbound({}:real^1->bool) =
362    interval_lowerbound({}:real^1->bool)`,
363   MESON_TAC[INTERVAL_BOUNDS_NULL_1; CONTENT_EMPTY; EMPTY_AS_INTERVAL]);;
364
365 let CONTENT_PASTECART = prove
366  (`!a b:real^M c d:real^N.
367         content(interval[pastecart a c,pastecart b d]) =
368         content(interval[a,b]) * content(interval[c,d])`,
369   REPEAT GEN_TAC THEN
370   SIMP_TAC[CONTENT_CLOSED_INTERVAL_CASES; LAMBDA_BETA] THEN
371   MATCH_MP_TAC(MESON[REAL_MUL_LZERO; REAL_MUL_RZERO]
372    `(p <=> p1 /\ p2) /\ z = x * y
373     ==> (if p then z else &0) =
374         (if p1 then x else &0) * (if p2 then y else &0)`) THEN
375   CONJ_TAC THENL
376    [EQ_TAC THEN DISCH_TAC THEN TRY CONJ_TAC THEN X_GEN_TAC `i:num` THEN
377     STRIP_TAC THENL
378      [FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
379       ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM] THEN
380       DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC;
381       FIRST_X_ASSUM(MP_TAC o SPEC `i + dimindex(:M)`) THEN
382       ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM] THEN
383       ANTS_TAC THENL [ASM_ARITH_TAC; REWRITE_TAC[ADD_SUB]] THEN
384       COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC;
385       RULE_ASSUM_TAC(REWRITE_RULE[DIMINDEX_FINITE_SUM]) THEN
386       ASM_CASES_TAC `i <= dimindex(:M)` THENL
387        [FIRST_X_ASSUM(MP_TAC o SPEC `i:num` o CONJUNCT1);
388         FIRST_X_ASSUM(MP_TAC o SPEC `i - dimindex(:M)` o CONJUNCT2)] THEN
389       ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM;
390                    ARITH_RULE `i:num <= m ==> i <= m + n`] THEN
391       DISCH_THEN MATCH_MP_TAC THEN ASM_ARITH_TAC];
392     SIMP_TAC[DIMINDEX_FINITE_SUM; ARITH_RULE `1 <= n + 1`;
393              PRODUCT_ADD_SPLIT] THEN
394     BINOP_TAC THENL
395      [ALL_TAC;
396       ONCE_REWRITE_TAC[ADD_SYM] THEN REWRITE_TAC[PRODUCT_OFFSET]] THEN
397     MATCH_MP_TAC PRODUCT_EQ_NUMSEG THEN
398     SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM; ADD_SUB;
399              ARITH_RULE `i:num <= m ==> i <= m + n`;
400              ARITH_RULE `i:num <= n ==> i + m <= m + n`] THEN
401     REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
402     ASM_ARITH_TAC]);;
403
404 (* ------------------------------------------------------------------------- *)
405 (* The notion of a gauge --- simply an open set containing the point.        *)
406 (* ------------------------------------------------------------------------- *)
407
408 let gauge = new_definition
409   `gauge d <=> !x. x IN d(x) /\ open(d(x))`;;
410
411 let GAUGE_BALL_DEPENDENT = prove
412  (`!e. (!x. &0 < e(x)) ==> gauge(\x. ball(x,e(x)))`,
413   SIMP_TAC[gauge; OPEN_BALL; IN_BALL; DIST_REFL]);;
414
415 let GAUGE_BALL = prove
416  (`!e. &0 < e ==> gauge (\x. ball(x,e))`,
417   SIMP_TAC[gauge; OPEN_BALL; IN_BALL; DIST_REFL]);;
418
419 let GAUGE_TRIVIAL = prove
420  (`gauge (\x. ball(x,&1))`,
421   SIMP_TAC[GAUGE_BALL; REAL_LT_01]);;
422
423 let GAUGE_INTER = prove
424  (`!d1 d2. gauge d1 /\ gauge d2 ==> gauge (\x. (d1 x) INTER (d2 x))`,
425   SIMP_TAC[gauge; IN_INTER; OPEN_INTER]);;
426
427 let GAUGE_INTERS = prove
428  (`!s. FINITE s /\ (!d. d IN s ==> gauge (f d))
429        ==> gauge(\x. INTERS {f d x | d IN s})`,
430   REWRITE_TAC[gauge; IN_INTERS] THEN
431   REWRITE_TAC[SET_RULE `{f d x | d IN s} = IMAGE (\d. f d x) s`] THEN
432   SIMP_TAC[FORALL_IN_IMAGE; OPEN_INTERS; FINITE_IMAGE]);;
433
434 let GAUGE_EXISTENCE_LEMMA = prove
435  (`(!x. ?d. p x ==> &0 < d /\ q d x) <=>
436    (!x. ?d. &0 < d /\ (p x ==> q d x))`,
437   MESON_TAC[REAL_LT_01]);;
438
439 (* ------------------------------------------------------------------------- *)
440 (* Divisions.                                                                *)
441 (* ------------------------------------------------------------------------- *)
442
443 parse_as_infix("division_of",(12,"right"));;
444
445 let division_of = new_definition
446  `s division_of i <=>
447         FINITE s /\
448         (!k. k IN s
449              ==> k SUBSET i /\ ~(k = {}) /\ ?a b. k = interval[a,b]) /\
450         (!k1 k2. k1 IN s /\ k2 IN s /\ ~(k1 = k2)
451                  ==> interior(k1) INTER interior(k2) = {}) /\
452         (UNIONS s = i)`;;
453
454 let DIVISION_OF = prove
455  (`s division_of i <=>
456         FINITE s /\
457         (!k. k IN s ==> ~(k = {}) /\ ?a b. k = interval[a,b]) /\
458         (!k1 k2. k1 IN s /\ k2 IN s /\ ~(k1 = k2)
459                  ==> interior(k1) INTER interior(k2) = {}) /\
460         UNIONS s = i`,
461   REWRITE_TAC[division_of] THEN SET_TAC[]);;
462
463 let DIVISION_OF_FINITE = prove
464  (`!s i. s division_of i ==> FINITE s`,
465   MESON_TAC[division_of]);;
466
467 let DIVISION_OF_SELF = prove
468  (`!a b. ~(interval[a,b] = {}) ==> {interval[a,b]} division_of interval[a,b]`,
469   REWRITE_TAC[division_of; FINITE_INSERT; FINITE_RULES; IN_SING; UNIONS_1] THEN
470   MESON_TAC[SUBSET_REFL]);;
471
472 let DIVISION_OF_TRIVIAL = prove
473  (`!s. s division_of {} <=> s = {}`,
474   REWRITE_TAC[division_of; SUBSET_EMPTY; CONJ_ASSOC] THEN
475   REWRITE_TAC[TAUT `~(p /\ ~p)`; GSYM NOT_EXISTS_THM; MEMBER_NOT_EMPTY] THEN
476   REWRITE_TAC[AC CONJ_ACI `((a /\ b) /\ c) /\ d <=> b /\ a /\ c /\ d`] THEN
477   GEN_TAC THEN MATCH_MP_TAC(TAUT `(a ==> b) ==> (a /\ b <=> a)`) THEN
478   DISCH_THEN SUBST1_TAC THEN
479   REWRITE_TAC[FINITE_RULES; UNIONS_0; NOT_IN_EMPTY]);;
480
481 let EMPTY_DIVISION_OF = prove
482  (`!s. {} division_of s <=> s = {}`,
483   REWRITE_TAC[division_of; UNIONS_0; FINITE_EMPTY; NOT_IN_EMPTY] THEN
484   MESON_TAC[]);;
485
486 let DIVISION_OF_SING = prove
487  (`!s a. s division_of interval[a,a] <=> s = {interval[a,a]}`,
488   let lemma = prove
489    (`s SUBSET {{a}} /\ p /\ UNIONS s = {a} <=> s = {{a}} /\ p`,
490     EQ_TAC THEN STRIP_TAC THEN
491     ASM_REWRITE_TAC[SET_RULE `UNIONS {a} = a`] THEN ASM SET_TAC[]) in
492   REWRITE_TAC[division_of; INTERVAL_SING] THEN
493   REWRITE_TAC[SET_RULE `k SUBSET {a} /\ ~(k = {}) /\ p <=> k = {a} /\ p`] THEN
494   REWRITE_TAC[GSYM INTERVAL_SING] THEN
495   REWRITE_TAC[MESON[] `(k = interval[a,b] /\ ?c d. k = interval[c,d]) <=>
496                        (k = interval[a,b])`] THEN
497   REWRITE_TAC[SET_RULE `(!k. k IN s ==> k = a) <=> s SUBSET {a}`] THEN
498   REWRITE_TAC[INTERVAL_SING; lemma] THEN MESON_TAC[FINITE_RULES; IN_SING]);;
499
500 let ELEMENTARY_EMPTY = prove
501  (`?p. p division_of {}`,
502   REWRITE_TAC[DIVISION_OF_TRIVIAL; EXISTS_REFL]);;
503
504 let ELEMENTARY_INTERVAL = prove
505  (`!a b. ?p. p division_of interval[a,b]`,
506   MESON_TAC[DIVISION_OF_TRIVIAL; DIVISION_OF_SELF]);;
507
508 let DIVISION_CONTAINS = prove
509  (`!s i. s division_of i ==> !x. x IN i ==> ?k. x IN k /\ k IN s`,
510   REWRITE_TAC[division_of; EXTENSION; IN_UNIONS] THEN MESON_TAC[]);;
511
512 let FORALL_IN_DIVISION = prove
513  (`!P d i. d division_of i
514            ==> ((!x. x IN d ==> P x) <=>
515                (!a b. interval[a,b] IN d ==> P(interval[a,b])))`,
516   REWRITE_TAC[division_of] THEN MESON_TAC[]);;
517
518 let FORALL_IN_DIVISION_NONEMPTY = prove
519  (`!P d i.
520          d division_of i
521          ==> ((!x. x IN d ==> P x) <=>
522               (!a b. interval [a,b] IN d /\ ~(interval[a,b] = {})
523                      ==> P (interval [a,b])))`,
524   REWRITE_TAC[division_of] THEN MESON_TAC[]);;
525
526 let DIVISION_OF_SUBSET = prove
527  (`!p q:(real^N->bool)->bool.
528         p division_of (UNIONS p) /\ q SUBSET p ==> q division_of (UNIONS q)`,
529   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
530   REWRITE_TAC[division_of] THEN
531   REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THENL
532    [ASM_MESON_TAC[FINITE_SUBSET]; ASM SET_TAC[]; ASM SET_TAC[]]);;
533
534 let DIVISION_OF_UNION_SELF = prove
535  (`!p s. p division_of s ==> p division_of (UNIONS p)`,
536   REWRITE_TAC[division_of] THEN MESON_TAC[]);;
537
538 let DIVISION_OF_CONTENT_0 = prove
539  (`!a b d. content(interval[a,b]) = &0 /\ d division_of interval[a,b]
540            ==> !k. k IN d ==> content k = &0`,
541   REPEAT GEN_TAC THEN STRIP_TAC THEN
542   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
543   REWRITE_TAC[GSYM REAL_LE_ANTISYM; CONTENT_POS_LE] THEN
544   ASM_MESON_TAC[CONTENT_SUBSET; division_of]);;
545
546 let DIVISION_INTER = prove
547  (`!s1 s2:real^N->bool p1 p2.
548         p1 division_of s1 /\
549         p2 division_of s2
550         ==> {k1 INTER k2 | k1 IN p1 /\ k2 IN p2 /\ ~(k1 INTER k2 = {})}
551             division_of (s1 INTER s2)`,
552   let lemma = prove
553    (`{k1 INTER k2 | k1 IN p1 /\ k2 IN p2 /\ ~(k1 INTER k2 = {})} =
554         {s | s IN IMAGE (\(k1,k2). k1 INTER k2) (p1 CROSS p2) /\
555              ~(s = {})}`,
556     REWRITE_TAC[EXTENSION] THEN
557     REWRITE_TAC[IN_IMAGE; IN_ELIM_THM; EXISTS_PAIR_THM; IN_CROSS] THEN
558     MESON_TAC[]) in
559   REPEAT GEN_TAC THEN REWRITE_TAC[DIVISION_OF] THEN STRIP_TAC THEN
560   ASM_SIMP_TAC[lemma; FINITE_RESTRICT; FINITE_CROSS; FINITE_IMAGE] THEN
561   REWRITE_TAC[IN_ELIM_THM] THEN
562   REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; RIGHT_FORALL_IMP_THM] THEN
563   REWRITE_TAC[FORALL_PAIR_THM; IN_CROSS] THEN REPEAT CONJ_TAC THENL
564    [ASM_MESON_TAC[INTER_INTERVAL];
565     REPEAT STRIP_TAC THEN
566     MATCH_MP_TAC(SET_RULE
567      `(interior x1 INTER interior x2 = {} \/
568        interior y1 INTER interior y2 = {}) /\
569       interior(x1 INTER y1) SUBSET interior(x1) /\
570       interior(x1 INTER y1) SUBSET interior(y1) /\
571       interior(x2 INTER y2) SUBSET interior(x2) /\
572       interior(x2 INTER y2) SUBSET interior(y2)
573       ==> interior(x1 INTER y1) INTER interior(x2 INTER y2) = {}`) THEN
574     CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
575     REPEAT CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[];
576     REWRITE_TAC[SET_RULE `UNIONS {x | x IN s /\ ~(x = {})} = UNIONS s`] THEN
577     REPEAT(FIRST_X_ASSUM(SUBST_ALL_TAC o SYM)) THEN
578     GEN_REWRITE_TAC I [EXTENSION] THEN
579     REWRITE_TAC[IN_UNIONS; IN_IMAGE; EXISTS_PAIR_THM; IN_CROSS; IN_INTER] THEN
580     MESON_TAC[IN_INTER]]);;
581
582 let DIVISION_INTER_1 = prove
583  (`!d i a b:real^N.
584         d division_of i /\ interval[a,b] SUBSET i
585         ==> { interval[a,b] INTER k | k |
586                  k IN d /\ ~(interval[a,b] INTER k = {}) }
587             division_of interval[a,b]`,
588   REPEAT STRIP_TAC THEN
589   ASM_CASES_TAC `interval[a:real^N,b] = {}` THEN
590   ASM_REWRITE_TAC[INTER_EMPTY; SET_RULE `{{} | F} = {}`;
591                   DIVISION_OF_TRIVIAL] THEN
592   MP_TAC(ISPECL [`interval[a:real^N,b]`; `i:real^N->bool`;
593                  `{interval[a:real^N,b]}`; `d:(real^N->bool)->bool`]
594                 DIVISION_INTER) THEN
595   ASM_SIMP_TAC[DIVISION_OF_SELF; SET_RULE `s SUBSET t ==> s INTER t = s`] THEN
596   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN SET_TAC[]);;
597
598 let ELEMENTARY_INTER = prove
599  (`!s t. (?p. p division_of s) /\ (?p. p division_of t)
600          ==> ?p. p division_of (s INTER t)`,
601   MESON_TAC[DIVISION_INTER]);;
602
603 let ELEMENTARY_INTERS = prove
604  (`!f:(real^N->bool)->bool.
605         FINITE f /\ ~(f = {}) /\
606         (!s. s IN f ==> ?p. p division_of s)
607         ==> ?p. p division_of (INTERS f)`,
608   REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
609   REWRITE_TAC[INTERS_INSERT] THEN
610   MAP_EVERY X_GEN_TAC [`s:real^N->bool`; `s:(real^N->bool)->bool`] THEN
611   ASM_CASES_TAC `s:(real^N->bool)->bool = {}` THEN ASM_REWRITE_TAC[] THENL
612    [REWRITE_TAC[INTERS_0; INTER_UNIV; IN_SING] THEN MESON_TAC[];
613     REWRITE_TAC[IN_INSERT] THEN REPEAT STRIP_TAC THEN
614     MATCH_MP_TAC ELEMENTARY_INTER THEN ASM_MESON_TAC[]]);;
615
616 let DIVISION_DISJOINT_UNION = prove
617  (`!s1 s2:real^N->bool p1 p2.
618         p1 division_of s1 /\
619         p2 division_of s2 /\
620         interior s1 INTER interior s2 = {}
621         ==> (p1 UNION p2) division_of (s1 UNION s2)`,
622   REPEAT GEN_TAC THEN REWRITE_TAC[division_of] THEN STRIP_TAC THEN
623   ASM_REWRITE_TAC[FINITE_UNION; IN_UNION; EXISTS_OR_THM; SET_RULE
624    `UNIONS {x | P x \/ Q x} = UNIONS {x | P x} UNION UNIONS {x | Q x}`] THEN
625   CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
626   CONJ_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN
627   REPEAT STRIP_TAC THENL
628    [ASM SET_TAC[]; ALL_TAC; ALL_TAC; ASM SET_TAC[]] THEN
629   MATCH_MP_TAC(SET_RULE
630    `!s' t'. s SUBSET s' /\ t SUBSET t' /\ s' INTER t' = {}
631             ==> s INTER t = {}`)
632   THENL
633    [MAP_EVERY EXISTS_TAC
634      [`interior s1:real^N->bool`; `interior s2:real^N->bool`];
635     MAP_EVERY EXISTS_TAC
636      [`interior s2:real^N->bool`; `interior s1:real^N->bool`]] THEN
637   REPEAT CONJ_TAC THEN TRY(MATCH_MP_TAC SUBSET_INTERIOR) THEN
638   ASM SET_TAC[]);;
639
640 let PARTIAL_DIVISION_EXTEND_1 = prove
641  (`!a b c d:real^N.
642         interval[c,d] SUBSET interval[a,b] /\ ~(interval[c,d] = {})
643         ==> ?p. p division_of interval[a,b] /\
644                 interval[c,d] IN p`,
645   REPEAT STRIP_TAC THEN ASM_CASES_TAC `interval[a:real^N,b] = {}` THENL
646    [ASM SET_TAC[]; ALL_TAC] THEN
647   REPEAT(FIRST_X_ASSUM(STRIP_ASSUME_TAC o
648     GEN_REWRITE_RULE I [INTERVAL_NE_EMPTY])) THEN
649   EXISTS_TAC
650    `{interval
651       [(lambda i. if i < l then (c:real^N)$i else (a:real^N)$i):real^N,
652        (lambda i. if i < l then d$i else if i = l then c$l else b$i)] |
653        l IN 1..(dimindex(:N)+1)} UNION
654     {interval
655       [(lambda i. if i < l then c$i else if i = l then d$l else a$i),
656        (lambda i. if i < l then (d:real^N)$i else (b:real^N)$i):real^N] |
657        l IN 1..(dimindex(:N)+1)}` THEN
658   MATCH_MP_TAC(TAUT `b /\ (b ==> a) ==> a /\ b`) THEN CONJ_TAC THENL
659    [REWRITE_TAC[IN_UNION] THEN DISJ1_TAC THEN
660     REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `dimindex(:N)+1` THEN
661     REWRITE_TAC[IN_NUMSEG; LE_REFL; ARITH_RULE `1 <= n + 1`] THEN
662     AP_TERM_TAC THEN SIMP_TAC[CONS_11; PAIR_EQ; CART_EQ; LAMBDA_BETA] THEN
663     SIMP_TAC[ARITH_RULE `i <= n ==> i < n + 1`];
664     DISCH_TAC] THEN
665   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET_INTERVAL]) THEN
666   ASM_REWRITE_TAC[DIVISION_OF] THEN DISCH_TAC THEN REPEAT CONJ_TAC THENL
667    [REWRITE_TAC[SIMPLE_IMAGE] THEN
668     SIMP_TAC[FINITE_UNION; FINITE_IMAGE; FINITE_NUMSEG];
669     REWRITE_TAC[IN_UNION; TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
670     REWRITE_TAC[SIMPLE_IMAGE; FORALL_AND_THM; FORALL_IN_IMAGE] THEN
671     ASM_SIMP_TAC[IN_NUMSEG; INTERVAL_NE_EMPTY; LAMBDA_BETA] THEN
672     CONJ_TAC THEN X_GEN_TAC `l:num` THEN DISCH_TAC THEN
673     (CONJ_TAC THENL [ALL_TAC; MESON_TAC[]]) THEN
674     REPEAT STRIP_TAC THEN
675     REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[]) THEN
676     ASM_MESON_TAC[REAL_LE_TRANS];
677     REWRITE_TAC[IN_UNION; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
678     REWRITE_TAC[SET_RULE
679       `(!y. y IN {f x | x IN s} \/ y IN {g x | x IN s} ==> P y) <=>
680        (!x. x IN s ==> P(f x) /\ P(g x))`] THEN
681     REWRITE_TAC[AND_FORALL_THM; IN_NUMSEG] THEN
682     REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN
683     REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
684     MATCH_MP_TAC WLOG_LE THEN CONJ_TAC THENL
685      [REPEAT GEN_TAC THEN
686       REWRITE_TAC[TAUT `a ==> b ==> c <=> b ==> a ==> c`] THEN
687       REWRITE_TAC[INTER_ACI; CONJ_ACI] THEN MESON_TAC[];
688       ALL_TAC] THEN
689     MAP_EVERY X_GEN_TAC [`l:num`; `m:num`] THEN
690     DISCH_TAC THEN STRIP_TAC THEN STRIP_TAC THEN
691     ONCE_REWRITE_TAC[TAUT `(~p ==> q) <=> (~q ==> p)`] THEN
692      REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN
693     REWRITE_TAC[SET_RULE `s INTER t = {} <=> !x. ~(x IN s /\ x IN t)`] THEN
694     ASM_SIMP_TAC[IN_NUMSEG; INTERVAL_NE_EMPTY; LAMBDA_BETA; IN_INTERVAL;
695                  INTERIOR_CLOSED_INTERVAL] THEN
696     REWRITE_TAC[AND_FORALL_THM] THEN
697     REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN
698     REWRITE_TAC[NOT_FORALL_THM] THEN REPEAT CONJ_TAC THEN
699     DISCH_THEN(X_CHOOSE_THEN `x:real^N` (LABEL_TAC "*")) THEN
700     AP_TERM_TAC THEN SIMP_TAC[CONS_11; PAIR_EQ; CART_EQ; LAMBDA_BETA] THENL
701      (let tac1 =
702         UNDISCH_TAC `l:num <= m` THEN GEN_REWRITE_TAC LAND_CONV [LE_LT] THEN
703         STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
704         REMOVE_THEN "*" (MP_TAC o SPEC `l:num`) THEN
705         ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
706         ASM_REWRITE_TAC[LT_REFL] THEN REAL_ARITH_TAC
707       and tac2 =
708         UNDISCH_TAC `l:num <= m` THEN GEN_REWRITE_TAC LAND_CONV [LE_LT] THEN
709         STRIP_TAC THEN ASM_REWRITE_TAC[] THENL
710          [REMOVE_THEN "*" (MP_TAC o SPEC `l:num`) THEN ANTS_TAC THENL
711            [ASM_ARITH_TAC; ALL_TAC] THEN
712           ASM_REWRITE_TAC[LT_REFL] THEN REAL_ARITH_TAC;
713           ALL_TAC] THEN
714         FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
715         CONJ_TAC THEN X_GEN_TAC `i:num` THEN ASM_CASES_TAC `i:num = l` THEN
716         ASM_REWRITE_TAC[LT_REFL] THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN
717         DISCH_TAC THEN REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `l:num`)) THEN
718         ASM_REWRITE_TAC[LT_REFL] THEN REAL_ARITH_TAC in
719       [tac1; tac2; tac2; tac1]);
720     MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
721      [REWRITE_TAC[IMP_CONJ; SUBSET; FORALL_IN_UNIONS; SIMPLE_IMAGE] THEN
722       REWRITE_TAC[IN_UNIONS; IN_INSERT; IN_UNION; FORALL_IN_IMAGE;
723         RIGHT_FORALL_IMP_THM; FORALL_AND_THM;
724         TAUT `(a \/ b ==> c) <=> (a ==> c) /\ (b ==> c)`] THEN
725       ASM_SIMP_TAC[IN_INTERVAL; IN_NUMSEG; LAMBDA_BETA] THEN
726       REPEAT CONJ_TAC THEN GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
727       MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
728       ASM_MESON_TAC[REAL_LE_TRANS];
729       ALL_TAC] THEN
730     FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
731      `a IN s ==> (c DIFF a) SUBSET UNIONS s ==> c SUBSET UNIONS s`)) THEN
732     REWRITE_TAC[SUBSET; IN_DIFF; IN_INTERVAL] THEN X_GEN_TAC `x:real^N` THEN
733     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
734     REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
735     GEN_REWRITE_TAC LAND_CONV [num_WOP] THEN
736     REWRITE_TAC[TAUT `a ==> ~(b /\ ~c) <=> a /\ b ==> c`] THEN
737     DISCH_THEN(X_CHOOSE_THEN `l:num` STRIP_ASSUME_TAC) THEN
738     REWRITE_TAC[IN_UNIONS; SIMPLE_IMAGE; EXISTS_IN_IMAGE; IN_UNION;
739                 EXISTS_OR_THM; RIGHT_OR_DISTRIB] THEN
740     REWRITE_TAC[OR_EXISTS_THM] THEN EXISTS_TAC `l:num` THEN
741     ASM_SIMP_TAC[IN_NUMSEG; IN_INTERVAL; LAMBDA_BETA;
742                  ARITH_RULE `x <= n ==> x <= n + 1`] THEN
743     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DE_MORGAN_THM]) THEN
744     MATCH_MP_TAC MONO_OR THEN REWRITE_TAC[REAL_NOT_LE] THEN
745     REPEAT STRIP_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[]) THEN
746     ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_LE_TRANS]]);;
747
748 let PARTIAL_DIVISION_EXTEND_INTERVAL = prove
749  (`!p a b:real^N.
750         p division_of (UNIONS p) /\ (UNIONS p) SUBSET interval[a,b]
751         ==> ?q. p SUBSET q /\ q division_of interval[a,b]`,
752   REPEAT GEN_TAC THEN ASM_CASES_TAC `p:(real^N->bool)->bool = {}` THEN
753   ASM_REWRITE_TAC[EMPTY_SUBSET] THENL
754    [MESON_TAC[ELEMENTARY_INTERVAL]; STRIP_TAC] THEN
755   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
756   SUBGOAL_THEN `!k:real^N->bool. k IN p ==> ?q. q division_of interval[a,b] /\
757                                                 k IN q`
758   MP_TAC THENL
759    [X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
760     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
761     DISCH_THEN(MP_TAC o SPEC `k:real^N->bool` o el 1 o CONJUNCTS) THEN
762     ASM_REWRITE_TAC[] THEN STRIP_TAC THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN
763     MATCH_MP_TAC PARTIAL_DIVISION_EXTEND_1 THEN ASM SET_TAC[];
764     ALL_TAC] THEN
765   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
766   REWRITE_TAC[SKOLEM_THM] THEN
767   DISCH_THEN(X_CHOOSE_TAC `q:(real^N->bool)->(real^N->bool)->bool`) THEN
768   SUBGOAL_THEN
769    `?d. d division_of INTERS {UNIONS(q i DELETE i) | (i:real^N->bool) IN p}`
770   MP_TAC THENL
771    [MATCH_MP_TAC ELEMENTARY_INTERS THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
772     ASM_SIMP_TAC[IMAGE_EQ_EMPTY; FINITE_IMAGE] THEN
773     REWRITE_TAC[FORALL_IN_IMAGE] THEN X_GEN_TAC `k:real^N->bool` THEN
774     DISCH_TAC THEN EXISTS_TAC `(q k) DELETE (k:real^N->bool)` THEN
775     MATCH_MP_TAC DIVISION_OF_SUBSET THEN
776     EXISTS_TAC `(q:(real^N->bool)->(real^N->bool)->bool) k` THEN
777     REWRITE_TAC[DELETE_SUBSET] THEN ASM_MESON_TAC[division_of];
778     ALL_TAC] THEN
779   DISCH_THEN(X_CHOOSE_TAC `d:(real^N->bool)->bool`) THEN
780   EXISTS_TAC `(d UNION p):(real^N->bool)->bool` THEN
781   REWRITE_TAC[SUBSET_UNION] THEN
782   SUBGOAL_THEN `interval[a:real^N,b] =
783                 INTERS {UNIONS (q i DELETE i) | i IN p} UNION
784                 UNIONS p`
785   SUBST1_TAC THENL
786    [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN MATCH_MP_TAC(SET_RULE
787      `~(s = {}) /\
788       (!i. i IN s ==> f i UNION i = t)
789      ==> t = INTERS (IMAGE f s) UNION (UNIONS s)`) THEN
790     ASM_REWRITE_TAC[] THEN X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
791     MATCH_MP_TAC(SET_RULE
792      `UNIONS k = s /\ i IN k ==> UNIONS (k DELETE i) UNION i = s`) THEN
793     ASM_MESON_TAC[division_of];
794     ALL_TAC] THEN
795   MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN ASM_REWRITE_TAC[] THEN
796   MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
797   ASM_REWRITE_TAC[OPEN_INTERIOR] THEN
798   CONJ_TAC THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
799   X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
800   MATCH_MP_TAC(SET_RULE
801    `!s. u SUBSET s /\ s INTER t = {} ==> u INTER t = {}`) THEN
802   EXISTS_TAC `interior(UNIONS(q k DELETE (k:real^N->bool)))` THEN
803   CONJ_TAC THENL
804    [MATCH_MP_TAC SUBSET_INTERIOR THEN
805     MATCH_MP_TAC(SET_RULE `x IN s ==> INTERS s SUBSET x`) THEN ASM SET_TAC[];
806     ALL_TAC] THEN
807   ONCE_REWRITE_TAC[INTER_COMM] THEN
808   MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
809   REWRITE_TAC[OPEN_INTERIOR; FINITE_DELETE; IN_DELETE] THEN
810   ASM_MESON_TAC[division_of]);;
811
812 let ELEMENTARY_BOUNDED = prove
813  (`!s. (?p. p division_of s) ==> bounded s`,
814   REWRITE_TAC[division_of] THEN
815   ASM_MESON_TAC[BOUNDED_UNIONS; BOUNDED_INTERVAL]);;
816
817 let ELEMENTARY_SUBSET_INTERVAL = prove
818  (`!s. (?p. p division_of s) ==> ?a b. s SUBSET interval[a,b]`,
819   MESON_TAC[ELEMENTARY_BOUNDED; BOUNDED_SUBSET_CLOSED_INTERVAL]);;
820
821 let DIVISION_UNION_INTERVALS_EXISTS = prove
822  (`!a b c d:real^N.
823         ~(interval[a,b] = {})
824         ==> ?p. (interval[a,b] INSERT p) division_of
825                 (interval[a,b] UNION interval[c,d])`,
826   REPEAT STRIP_TAC THEN
827   ASM_CASES_TAC `interval[c:real^N,d] = {}` THENL
828    [ASM_REWRITE_TAC[UNION_EMPTY] THEN ASM_MESON_TAC[DIVISION_OF_SELF];
829     ALL_TAC] THEN
830   ASM_CASES_TAC `interval[a:real^N,b] INTER interval[c,d] = {}` THENL
831    [EXISTS_TAC `{interval[c:real^N,d]}` THEN
832     ONCE_REWRITE_TAC[SET_RULE `{a,b} = {a} UNION {b}`] THEN
833     MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN
834     ASM_SIMP_TAC[DIVISION_OF_SELF] THEN
835     MATCH_MP_TAC(SET_RULE
836      `interior s SUBSET s /\ interior t SUBSET t /\ s INTER t = {}
837       ==> interior s INTER interior t = {}`) THEN
838     ASM_REWRITE_TAC[INTERIOR_SUBSET];
839     ALL_TAC] THEN
840   SUBGOAL_THEN
841    `?u v:real^N. interval[a,b] INTER interval[c,d] = interval[u,v]`
842   STRIP_ASSUME_TAC THENL [MESON_TAC[INTER_INTERVAL]; ALL_TAC] THEN
843   MP_TAC(ISPECL [`c:real^N`; `d:real^N`; `u:real^N`; `v:real^N`]
844                 PARTIAL_DIVISION_EXTEND_1) THEN
845   ANTS_TAC THENL [ASM_MESON_TAC[INTER_SUBSET]; ALL_TAC] THEN
846   DISCH_THEN(X_CHOOSE_THEN `p:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
847   EXISTS_TAC `p DELETE interval[u:real^N,v]` THEN
848   SUBGOAL_THEN `interval[a:real^N,b] UNION interval[c,d] =
849                 interval[a,b] UNION UNIONS(p DELETE interval[u,v])`
850   SUBST1_TAC THENL
851    [FIRST_ASSUM(SUBST1_TAC o SYM o last o CONJUNCTS o
852                 GEN_REWRITE_RULE I [division_of]) THEN
853     ASM SET_TAC[];
854     ALL_TAC] THEN
855   ONCE_REWRITE_TAC[SET_RULE `x INSERT s = {x} UNION s`] THEN
856   MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN
857   ASM_SIMP_TAC[DIVISION_OF_SELF] THEN CONJ_TAC THENL
858    [MATCH_MP_TAC DIVISION_OF_SUBSET THEN
859     EXISTS_TAC `p:(real^N->bool)->bool` THEN
860     ASM_MESON_TAC[DIVISION_OF_UNION_SELF; DELETE_SUBSET];
861     ALL_TAC] THEN
862   REWRITE_TAC[GSYM INTERIOR_INTER] THEN
863   MATCH_MP_TAC EQ_TRANS THEN
864   EXISTS_TAC `interior(interval[u:real^N,v] INTER
865               UNIONS (p DELETE interval[u,v]))` THEN
866   CONJ_TAC THENL
867    [AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE
868      `!cd. p SUBSET cd /\ uv = ab INTER cd
869            ==> (ab INTER p = uv INTER p)`) THEN
870     EXISTS_TAC `interval[c:real^N,d]` THEN
871     ASM_REWRITE_TAC[UNIONS_SUBSET; IN_DELETE] THEN
872     ASM_MESON_TAC[division_of];
873     REWRITE_TAC[INTERIOR_INTER] THEN
874     MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
875     REWRITE_TAC[IN_DELETE; OPEN_INTERIOR; FINITE_DELETE] THEN
876     ASM_MESON_TAC[division_of]]);;
877
878 let DIVISION_OF_UNIONS = prove
879  (`!f. FINITE f /\
880        (!p. p IN f ==> p division_of (UNIONS p)) /\
881        (!k1 k2. k1 IN UNIONS f /\ k2 IN UNIONS f /\ ~(k1 = k2)
882                 ==> interior k1 INTER interior k2 = {})
883        ==> (UNIONS f) division_of UNIONS(UNIONS f)`,
884   REWRITE_TAC[division_of] THEN
885   SIMP_TAC[FINITE_UNIONS] THEN REWRITE_TAC[FORALL_IN_UNIONS] THEN
886   GEN_TAC THEN DISCH_THEN(MP_TAC o el 1 o CONJUNCTS) THEN
887   MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN SET_TAC[]);;
888
889 let ELEMENTARY_UNION_INTERVAL_STRONG = prove
890  (`!p a b:real^N.
891         p division_of (UNIONS p)
892         ==> ?q. p SUBSET q /\ q division_of (interval[a,b] UNION UNIONS p)`,
893   REPEAT STRIP_TAC THEN ASM_CASES_TAC `p:(real^N->bool)->bool = {}` THENL
894    [ASM_REWRITE_TAC[UNIONS_0; UNION_EMPTY; EMPTY_SUBSET] THEN
895     MESON_TAC[ELEMENTARY_INTERVAL];
896     ALL_TAC] THEN
897   ASM_CASES_TAC `interval[a:real^N,b] = {}` THEN
898   ASM_REWRITE_TAC[UNION_EMPTY] THENL [ASM_MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN
899   ASM_CASES_TAC `interior(interval[a:real^N,b]) = {}` THENL
900    [EXISTS_TAC `interval[a:real^N,b] INSERT p` THEN
901     REWRITE_TAC[division_of] THEN
902     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
903     SIMP_TAC[FINITE_INSERT; UNIONS_INSERT] THEN ASM SET_TAC[];
904     ALL_TAC] THEN
905   ASM_CASES_TAC `interval[a:real^N,b] SUBSET UNIONS p` THENL
906    [ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s UNION t = t`] THEN
907     ASM_MESON_TAC[SUBSET_REFL];
908     ALL_TAC] THEN
909   SUBGOAL_THEN
910    `!k:real^N->bool. k IN p
911                      ==> ?q. ~(k IN q) /\ ~(q = {}) /\
912                              (k INSERT q) division_of (interval[a,b] UNION k)`
913   MP_TAC THENL
914    [X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
915     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
916     DISCH_THEN(MP_TAC o SPEC `k:real^N->bool` o CONJUNCT1 o CONJUNCT2) THEN
917     ASM_REWRITE_TAC[] THEN
918     REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
919     REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
920     MAP_EVERY X_GEN_TAC [`c:real^N`; `d:real^N`] THEN
921     DISCH_THEN SUBST_ALL_TAC THEN
922     ONCE_REWRITE_TAC[UNION_COMM] THEN
923     MP_TAC(ISPECL [`c:real^N`; `d:real^N`; `a:real^N`; `b:real^N`]
924         DIVISION_UNION_INTERVALS_EXISTS) THEN
925     ASM_REWRITE_TAC[] THEN
926     DISCH_THEN(X_CHOOSE_TAC `q:(real^N->bool)->bool`) THEN
927     EXISTS_TAC `q DELETE interval[c:real^N,d]` THEN
928     ASM_REWRITE_TAC[IN_DELETE; SET_RULE
929      `x INSERT (q DELETE x) = x INSERT q`] THEN
930     DISCH_TAC THEN
931     UNDISCH_TAC `(interval[c:real^N,d] INSERT q) division_of
932                  (interval [c,d] UNION interval [a,b])` THEN
933     ASM_SIMP_TAC[SET_RULE `s DELETE x = {} ==> x INSERT s = {x}`] THEN
934     REWRITE_TAC[division_of; UNIONS_1] THEN ASM SET_TAC[];
935     ALL_TAC] THEN
936   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
937   REWRITE_TAC[SKOLEM_THM] THEN
938   DISCH_THEN(X_CHOOSE_TAC `q:(real^N->bool)->(real^N->bool)->bool`) THEN
939   MP_TAC(ISPEC `IMAGE (UNIONS o (q:(real^N->bool)->(real^N->bool)->bool)) p`
940     ELEMENTARY_INTERS) THEN
941   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
942   ASM_SIMP_TAC[FINITE_IMAGE; IMAGE_EQ_EMPTY; FORALL_IN_IMAGE] THEN
943   ANTS_TAC THENL
944    [X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
945     EXISTS_TAC `(q:(real^N->bool)->(real^N->bool)->bool) k` THEN
946     REWRITE_TAC[o_THM] THEN MATCH_MP_TAC DIVISION_OF_SUBSET THEN
947     EXISTS_TAC `(k:real^N->bool) INSERT q k` THEN
948     CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_UNION_SELF]; SET_TAC[]];
949     DISCH_THEN(X_CHOOSE_TAC `r:(real^N->bool)->bool`)] THEN
950   EXISTS_TAC `p UNION r:(real^N->bool)->bool` THEN SIMP_TAC[SUBSET_UNION] THEN
951   SUBGOAL_THEN
952    `interval[a:real^N,b] UNION UNIONS p =
953     UNIONS p UNION INTERS(IMAGE (UNIONS o q) p)`
954   SUBST1_TAC THENL
955    [GEN_REWRITE_TAC I [EXTENSION] THEN X_GEN_TAC `y:real^N` THEN
956     REWRITE_TAC[IN_UNION] THEN
957     ASM_CASES_TAC `(y:real^N) IN UNIONS p` THEN ASM_REWRITE_TAC[IN_INTERS] THEN
958     REWRITE_TAC[FORALL_IN_UNIONS; IMP_CONJ; FORALL_IN_IMAGE;
959                 RIGHT_FORALL_IMP_THM] THEN
960     SUBGOAL_THEN
961      `!k. k IN p ==> UNIONS(k INSERT q k) = interval[a:real^N,b] UNION k`
962     MP_TAC THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
963     REWRITE_TAC[UNIONS_INSERT; o_THM] THEN
964     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [EXTENSION] THEN
965     REWRITE_TAC[RIGHT_IMP_FORALL_THM; IN_UNION] THEN
966     ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
967     DISCH_THEN(MP_TAC o SPEC `y:real^N`) THEN
968     UNDISCH_TAC `~((y:real^N) IN UNIONS p)` THEN
969     SIMP_TAC[IN_UNIONS; NOT_EXISTS_THM; TAUT `~(a /\ b) <=> a ==> ~b`] THEN
970     ASM_CASES_TAC `(y:real^N) IN interval[a,b]` THEN
971     ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
972     ALL_TAC] THEN
973   MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN
974   ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[INTER_COMM] THEN
975   MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
976   ASM_REWRITE_TAC[OPEN_INTERIOR] THEN
977   CONJ_TAC THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
978   X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
979   ASM_SIMP_TAC[INTERIOR_FINITE_INTERS; FINITE_IMAGE] THEN
980   MATCH_MP_TAC(SET_RULE `(?x. x IN p /\ f x INTER s = {})
981                         ==> INTERS (IMAGE f p) INTER s = {}`) THEN
982   REWRITE_TAC[EXISTS_IN_IMAGE; o_THM] THEN EXISTS_TAC `k:real^N->bool` THEN
983   ASM_REWRITE_TAC[] THEN
984   ONCE_REWRITE_TAC[INTER_COMM] THEN
985   MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
986   ASM_REWRITE_TAC[OPEN_INTERIOR] THEN REPEAT CONJ_TAC THENL
987    [ASM_MESON_TAC[division_of; FINITE_INSERT; IN_INSERT];
988     ASM_MESON_TAC[division_of; FINITE_INSERT; IN_INSERT];
989     ALL_TAC] THEN
990   FIRST_X_ASSUM(MP_TAC o SPEC `k:real^N->bool`) THEN
991   ASM_REWRITE_TAC[division_of; IN_INSERT] THEN
992   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]);;
993
994 let ELEMENTARY_UNION_INTERVAL = prove
995  (`!p a b:real^N.
996         p division_of (UNIONS p)
997         ==> ?q. q division_of (interval[a,b] UNION UNIONS p)`,
998   MESON_TAC[ELEMENTARY_UNION_INTERVAL_STRONG]);;
999
1000 let ELEMENTARY_UNIONS_INTERVALS = prove
1001  (`!f. FINITE f /\
1002        (!s. s IN f ==> ?a b:real^N. s = interval[a,b])
1003        ==> (?p. p division_of (UNIONS f))`,
1004   REWRITE_TAC[IMP_CONJ] THEN
1005   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1006   REWRITE_TAC[UNIONS_0; UNIONS_INSERT; ELEMENTARY_EMPTY] THEN
1007   REWRITE_TAC[IN_INSERT; TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
1008   SIMP_TAC[FORALL_AND_THM; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
1009   REPEAT GEN_TAC THEN DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
1010   ASM_REWRITE_TAC[] THEN
1011   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
1012   DISCH_THEN(X_CHOOSE_TAC `p:(real^N->bool)->bool`) THEN
1013   SUBGOAL_THEN `UNIONS f:real^N->bool = UNIONS p` SUBST1_TAC THENL
1014    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
1015   MATCH_MP_TAC ELEMENTARY_UNION_INTERVAL THEN ASM_MESON_TAC[division_of]);;
1016
1017 let ELEMENTARY_UNION = prove
1018  (`!s t:real^N->bool.
1019         (?p. p division_of s) /\ (?p. p division_of t)
1020         ==> (?p. p division_of (s UNION t))`,
1021   REPEAT GEN_TAC THEN DISCH_THEN
1022    (CONJUNCTS_THEN2 (X_CHOOSE_TAC `p1:(real^N->bool)->bool`)
1023                     (X_CHOOSE_TAC `p2:(real^N->bool)->bool`)) THEN
1024   SUBGOAL_THEN `s UNION t :real^N->bool = UNIONS p1 UNION UNIONS p2`
1025   SUBST1_TAC THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
1026   REWRITE_TAC[SET_RULE `UNIONS p1 UNION UNIONS p2 = UNIONS(p1 UNION p2)`] THEN
1027   MATCH_MP_TAC ELEMENTARY_UNIONS_INTERVALS THEN
1028   REWRITE_TAC[IN_UNION; FINITE_UNION] THEN
1029   ASM_MESON_TAC[division_of]);;
1030
1031 let PARTIAL_DIVISION_EXTEND = prove
1032  (`!p q s t:real^N->bool.
1033         p division_of s /\ q division_of t /\ s SUBSET t
1034         ==> ?r. p SUBSET r /\ r division_of t`,
1035   REPEAT STRIP_TAC THEN
1036   SUBGOAL_THEN `?a b:real^N. t SUBSET interval[a,b]` MP_TAC THENL
1037    [ASM_MESON_TAC[ELEMENTARY_SUBSET_INTERVAL]; ALL_TAC] THEN
1038   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
1039   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN
1040   SUBGOAL_THEN `?r1. p SUBSET r1 /\ r1 division_of interval[a:real^N,b]`
1041   STRIP_ASSUME_TAC THENL
1042    [MATCH_MP_TAC PARTIAL_DIVISION_EXTEND_INTERVAL THEN
1043     ASM_MESON_TAC[division_of; SUBSET_TRANS];
1044     ALL_TAC] THEN
1045   SUBGOAL_THEN
1046    `?r2:(real^N->bool)->bool.
1047         r2 division_of (UNIONS(r1 DIFF p)) INTER (UNIONS q)`
1048   STRIP_ASSUME_TAC THENL
1049    [MATCH_MP_TAC ELEMENTARY_INTER THEN
1050     ASM_MESON_TAC[FINITE_DIFF; IN_DIFF; division_of;
1051                   ELEMENTARY_UNIONS_INTERVALS];
1052     ALL_TAC] THEN
1053   EXISTS_TAC `p UNION r2:(real^N->bool)->bool` THEN
1054   CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
1055   SUBGOAL_THEN
1056    `t:real^N->bool = UNIONS p UNION (UNIONS(r1 DIFF p) INTER UNIONS q)`
1057   SUBST1_TAC THENL
1058    [REPEAT(FIRST_X_ASSUM(MP_TAC o last o CONJUNCTS o
1059                 GEN_REWRITE_RULE I [division_of])) THEN
1060     REPEAT(POP_ASSUM MP_TAC) THEN SET_TAC[];
1061     MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN ASM_REWRITE_TAC[] THEN
1062     CONJ_TAC THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
1063     MATCH_MP_TAC(SET_RULE
1064      `!t'. t SUBSET t' /\ s INTER t' = {} ==> s INTER t = {}`) THEN
1065     EXISTS_TAC `interior(UNIONS(r1 DIFF p)):real^N->bool` THEN
1066     CONJ_TAC THENL [MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]; ALL_TAC] THEN
1067     REPEAT(MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
1068            REWRITE_TAC[OPEN_INTERIOR] THEN
1069            REPEAT(CONJ_TAC THENL
1070             [ASM_MESON_TAC[IN_DIFF; FINITE_DIFF; division_of]; ALL_TAC]) THEN
1071            REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC THEN
1072            ONCE_REWRITE_TAC[INTER_COMM]) THEN
1073     ASM_MESON_TAC[division_of; SUBSET]]);;
1074
1075 let INTERVAL_SUBDIVISION = prove
1076  (`!a b c:real^N.
1077         c IN interval[a,b]
1078         ==> IMAGE (\s. interval[(lambda i. if i IN s then c$i else a$i),
1079                                 (lambda i. if i IN s then b$i else c$i)])
1080                   {s | s SUBSET 1..dimindex(:N)}
1081             division_of interval[a,b]`,
1082   REPEAT STRIP_TAC THEN
1083   FIRST_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I [IN_INTERVAL]) THEN
1084   REWRITE_TAC[DIVISION_OF] THEN
1085   SIMP_TAC[FINITE_IMAGE; FINITE_POWERSET; FINITE_NUMSEG] THEN
1086   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
1087   REWRITE_TAC[FORALL_IN_GSPEC; SUBSET_INTERVAL; INTERVAL_NE_EMPTY] THEN
1088   REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN REPEAT CONJ_TAC THENL
1089    [SIMP_TAC[LAMBDA_BETA] THEN ASM_MESON_TAC[REAL_LE_TRANS];
1090     X_GEN_TAC `s:num->bool` THEN DISCH_TAC THEN
1091     X_GEN_TAC `s':num->bool` THEN DISCH_TAC THEN
1092     REWRITE_TAC[SET_RULE
1093      `(~p ==> s INTER t = {}) <=> (!x. x IN s /\ x IN t ==> p)`] THEN
1094     X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_INTERVAL; AND_FORALL_THM] THEN
1095     REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN
1096     SIMP_TAC[LAMBDA_BETA] THEN
1097     ASM_CASES_TAC `s':num->bool = s` THEN ASM_REWRITE_TAC[] THEN
1098     FIRST_X_ASSUM(MP_TAC o MATCH_MP (SET_RULE
1099      `~(s' = s) ==> ?x. x IN s' /\ ~(x IN s) \/ x IN s /\ ~(x IN s')`)) THEN
1100     DISCH_THEN(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN
1101     DISCH_THEN(MP_TAC o SPEC `k:num`) THEN ASM_REWRITE_TAC[] THEN
1102     (ANTS_TAC THENL [ASM_MESON_TAC[SUBSET; IN_NUMSEG]; REAL_ARITH_TAC]);
1103     MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THEN
1104     GEN_REWRITE_TAC I [SUBSET] THENL
1105      [REWRITE_TAC[FORALL_IN_UNIONS] THEN ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
1106       REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN
1107       ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
1108       REWRITE_TAC[RIGHT_FORALL_IMP_THM; GSYM SUBSET] THEN
1109       SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN
1110       ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL];
1111       X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
1112       REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE; EXISTS_IN_GSPEC] THEN EXISTS_TAC
1113        `{i | i IN 1..dimindex(:N) /\ (c:real^N)$i <= (x:real^N)$i}` THEN
1114       CONJ_TAC THENL [SET_TAC[]; REWRITE_TAC[IN_INTERVAL]] THEN
1115       SIMP_TAC[LAMBDA_BETA; IN_ELIM_THM; IN_NUMSEG] THEN
1116       RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN
1117       ASM_MESON_TAC[REAL_LE_TOTAL]]]);;
1118
1119 let DIVISION_OF_NONTRIVIAL = prove
1120  (`!s a b:real^N.
1121         s division_of interval[a,b] /\ ~(content(interval[a,b]) = &0)
1122         ==> {k | k IN s /\ ~(content k = &0)} division_of interval[a,b]`,
1123   REPEAT GEN_TAC THEN WF_INDUCT_TAC `CARD(s:(real^N->bool)->bool)` THEN
1124   REPEAT STRIP_TAC THEN
1125   ASM_CASES_TAC `{k:real^N->bool | k IN s /\ ~(content k = &0)} = s` THEN
1126   ASM_REWRITE_TAC[] THEN
1127   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [EXTENSION]) THEN
1128   REWRITE_TAC[IN_ELIM_THM; NOT_FORALL_THM; LEFT_IMP_EXISTS_THM] THEN
1129   REWRITE_TAC[TAUT `~(a /\ ~b <=> a) <=> a /\ b`] THEN
1130   X_GEN_TAC `k:real^N->bool` THEN STRIP_TAC THEN
1131   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
1132   FIRST_X_ASSUM(MP_TAC o SPEC `s DELETE (k:real^N->bool)`) THEN
1133   ASM_SIMP_TAC[CARD_DELETE; ARITH_RULE `n - 1 < n <=> ~(n = 0)`] THEN
1134   ASM_SIMP_TAC[CARD_EQ_0] THEN ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
1135   ANTS_TAC THENL
1136    [ALL_TAC;
1137     MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
1138     ASM SET_TAC[]] THEN
1139   REWRITE_TAC[DIVISION_OF] THEN
1140   FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [division_of]) THEN
1141   ASM_SIMP_TAC[FINITE_DELETE; IN_DELETE] THEN
1142   FIRST_ASSUM(MP_TAC o C MATCH_MP (ASSUME `(k:real^N->bool) IN s`)) THEN
1143   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
1144   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
1145   MAP_EVERY X_GEN_TAC [`c:real^N`; `d:real^N`] THEN
1146   DISCH_THEN SUBST_ALL_TAC THEN
1147   MATCH_MP_TAC(SET_RULE
1148     `UNIONS s = i /\ k SUBSET UNIONS(s DELETE k)
1149      ==> UNIONS(s DELETE k) = i`) THEN
1150   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(MESON[CLOSED_LIMPT; SUBSET]
1151    `closed s /\ (!x. x IN k ==> x limit_point_of s) ==> k SUBSET s`) THEN
1152   CONJ_TAC THENL
1153    [MATCH_MP_TAC CLOSED_UNIONS THEN
1154     ASM_REWRITE_TAC[FINITE_DELETE; IN_DELETE] THEN
1155     ASM_MESON_TAC[CLOSED_INTERVAL];
1156     ALL_TAC] THEN
1157   X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[LIMPT_APPROACHABLE] THEN
1158   X_GEN_TAC `e:real` THEN DISCH_TAC THEN REWRITE_TAC[dist] THEN
1159   SUBGOAL_THEN `?y:real^N. y IN UNIONS s /\ ~(y IN interval[c,d]) /\
1160                            ~(y = x) /\ norm(y - x) < e`
1161   MP_TAC THENL [ALL_TAC; SET_TAC[]] THEN ASM_REWRITE_TAC[] THEN
1162   MAP_EVERY UNDISCH_TAC
1163    [`~(content(interval[a:real^N,b]) = &0)`;
1164     `content(interval[c:real^N,d]) = &0`] THEN
1165   REWRITE_TAC[CONTENT_EQ_0; NOT_EXISTS_THM] THEN
1166   DISCH_THEN(X_CHOOSE_THEN `i:num` STRIP_ASSUME_TAC) THEN
1167   DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[REAL_NOT_LE] THEN
1168   DISCH_TAC THEN UNDISCH_TAC `~(interval[c:real^N,d] = {})` THEN
1169   REWRITE_TAC[INTERVAL_EQ_EMPTY; NOT_EXISTS_THM] THEN
1170   DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[REAL_NOT_LT] THEN
1171   ASM_SIMP_TAC[REAL_ARITH `a <= b ==> (b <= a <=> a = b)`] THEN
1172   DISCH_THEN(fun th -> SUBST_ALL_TAC th THEN ASSUME_TAC th) THEN
1173   UNDISCH_TAC `interval[c:real^N,d] SUBSET interval[a,b]` THEN
1174   REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
1175   ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
1176   MP_TAC(ASSUME `(x:real^N) IN interval[c,d]`) THEN
1177   GEN_REWRITE_TAC LAND_CONV [IN_INTERVAL] THEN
1178   DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
1179   ASM_SIMP_TAC[REAL_ARITH `d = c ==> (c <= x /\ x <= d <=> x = c)`] THEN
1180   DISCH_TAC THEN
1181   MP_TAC(ASSUME `(x:real^N) IN interval[a,b]`) THEN
1182   GEN_REWRITE_TAC LAND_CONV [IN_INTERVAL] THEN
1183   DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
1184   STRIP_TAC THEN EXISTS_TAC
1185    `(lambda j. if j = i then
1186                  if (c:real^N)$i <= ((a:real^N)$i + (b:real^N)$i) / &2
1187                  then c$i + min e (b$i - c$i) / &2
1188                  else c$i - min e (c$i - a$i) / &2
1189                else (x:real^N)$j):real^N` THEN
1190   SIMP_TAC[IN_INTERVAL; LAMBDA_BETA; CART_EQ] THEN REPEAT CONJ_TAC THENL
1191    [X_GEN_TAC `j:num` THEN STRIP_TAC THEN
1192     UNDISCH_TAC `(x:real^N) IN interval[a,b]` THEN
1193     REWRITE_TAC[IN_INTERVAL] THEN DISCH_THEN(MP_TAC o SPEC `j:num`) THEN
1194     ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN REWRITE_TAC[] THEN
1195     FIRST_X_ASSUM SUBST_ALL_TAC THEN
1196     ASM_REAL_ARITH_TAC;
1197     DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
1198     ASM_REAL_ARITH_TAC;
1199     DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
1200     ASM_REAL_ARITH_TAC;
1201     REWRITE_TAC[vector_norm; dot] THEN
1202     SIMP_TAC[LAMBDA_BETA; VECTOR_SUB_COMPONENT; GSYM REAL_POW_2] THEN
1203     REWRITE_TAC[REAL_ARITH
1204      `((if p then x else y) - y) pow 2 = if p then (x - y) pow 2 else &0`] THEN
1205     ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG; POW_2_SQRT_ABS] THEN
1206     ASM_REAL_ARITH_TAC]);;
1207
1208 let DIVISION_OF_AFFINITY = prove
1209  (`!d s:real^N->bool m c.
1210     IMAGE (IMAGE (\x. m % x + c)) d division_of (IMAGE (\x. m % x + c) s) <=>
1211     if m = &0 then if s = {} then d = {}
1212                    else ~(d = {}) /\ !k. k IN d ==> ~(k = {})
1213     else d division_of s`,
1214   REPEAT GEN_TAC THEN ASM_CASES_TAC `m = &0` THEN ASM_REWRITE_TAC[] THENL
1215    [ASM_CASES_TAC `s:real^N->bool = {}` THEN
1216     ASM_REWRITE_TAC[IMAGE_CLAUSES; DIVISION_OF_TRIVIAL; IMAGE_EQ_EMPTY] THEN
1217     ASM_CASES_TAC `d:(real^N->bool)->bool = {}` THEN
1218     ASM_REWRITE_TAC[IMAGE_CLAUSES; EMPTY_DIVISION_OF; UNIONS_0;
1219                     IMAGE_EQ_EMPTY] THEN
1220     REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN
1221     ASM_SIMP_TAC[SET_RULE `~(s = {}) ==> IMAGE (\x. c) s = {c}`] THEN
1222     ASM_CASES_TAC `!k:real^N->bool. k IN d ==> ~(k = {})` THEN
1223     ASM_REWRITE_TAC[division_of] THENL
1224      [ALL_TAC;
1225       REWRITE_TAC[FORALL_IN_IMAGE] THEN ASM_MESON_TAC[IMAGE_EQ_EMPTY]] THEN
1226     SUBGOAL_THEN
1227      `IMAGE (IMAGE ((\x. c):real^N->real^N)) d = {{c}}`
1228     SUBST1_TAC THENL
1229      [GEN_REWRITE_TAC I [EXTENSION] THEN
1230       REWRITE_TAC[IN_IMAGE; IN_SING] THEN ASM SET_TAC[];
1231       SIMP_TAC[UNIONS_1; FINITE_SING; IN_SING; IMP_CONJ] THEN
1232       REWRITE_TAC[SUBSET_REFL; NOT_INSERT_EMPTY] THEN
1233       MESON_TAC[INTERVAL_SING]];
1234     REWRITE_TAC[division_of] THEN
1235     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
1236     REWRITE_TAC[IMAGE_EQ_EMPTY; GSYM INTERIOR_INTER] THEN
1237     ASM_SIMP_TAC[FINITE_IMAGE_INJ_EQ; GSYM IMAGE_UNIONS;
1238          VECTOR_ARITH `x + a:real^N = y + a <=> x = y`;
1239              VECTOR_MUL_LCANCEL;
1240      SET_RULE `(!x y. f x = f y <=> x = y)
1241                ==> (IMAGE f s SUBSET IMAGE f t <=> s SUBSET t) /\
1242                    (IMAGE f s = IMAGE f t <=> s = t) /\
1243                    (IMAGE f s INTER IMAGE f t = IMAGE f (s INTER t))`] THEN
1244     AP_TERM_TAC THEN BINOP_TAC THENL
1245      [AP_TERM_TAC THEN ABS_TAC THEN REPLICATE_TAC 3 AP_TERM_TAC THEN
1246       EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
1247       MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN
1248       ASM_SIMP_TAC[IMAGE_AFFINITY_INTERVAL] THENL [ALL_TAC; MESON_TAC[]] THEN
1249       FIRST_X_ASSUM(MP_TAC o AP_TERM
1250        `IMAGE (\x:real^N. inv m % x + --(inv m % c))`) THEN
1251       ASM_SIMP_TAC[GSYM IMAGE_o; AFFINITY_INVERSES] THEN
1252       ASM_REWRITE_TAC[IMAGE_I; IMAGE_AFFINITY_INTERVAL] THEN MESON_TAC[];
1253       SUBGOAL_THEN `(\x:real^N. m % x + c) = (\x. c + x) o (\x. m % x)`
1254       SUBST1_TAC THENL
1255        [REWRITE_TAC[FUN_EQ_THM; o_THM] THEN VECTOR_ARITH_TAC;
1256         REWRITE_TAC[IMAGE_o; INTERIOR_TRANSLATION] THEN
1257         ASM_SIMP_TAC[INTERIOR_INJECTIVE_LINEAR_IMAGE; LINEAR_SCALING;
1258                      VECTOR_MUL_LCANCEL; IMAGE_EQ_EMPTY]]]]);;
1259
1260 let DIVISION_OF_TRANSLATION = prove
1261  (`!d s:real^N->bool.
1262         IMAGE (IMAGE (\x. a + x)) d division_of (IMAGE (\x. a + x) s) <=>
1263         d division_of s`,
1264   ONCE_REWRITE_TAC[VECTOR_ARITH `a + x:real^N = &1 % x + a`] THEN
1265   REWRITE_TAC[DIVISION_OF_AFFINITY] THEN CONV_TAC REAL_RAT_REDUCE_CONV);;
1266
1267 let DIVISION_OF_REFLECT = prove
1268  (`!d s:real^N->bool.
1269         IMAGE (IMAGE (--)) d division_of IMAGE (--) s <=>
1270         d division_of s`,
1271   REPEAT GEN_TAC THEN SUBGOAL_THEN `(--) = \x:real^N. --(&1) % x + vec 0`
1272   SUBST1_TAC THENL
1273   [REWRITE_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC;
1274    REWRITE_TAC[DIVISION_OF_AFFINITY] THEN CONV_TAC REAL_RAT_REDUCE_CONV]);;
1275
1276 let ELEMENTARY_COMPACT = prove
1277  (`!s. (?d. d division_of s) ==> compact s`,
1278   REWRITE_TAC[division_of] THEN
1279   MESON_TAC[COMPACT_UNIONS; COMPACT_INTERVAL]);;
1280
1281 (* ------------------------------------------------------------------------- *)
1282 (* Tagged (partial) divisions.                                               *)
1283 (* ------------------------------------------------------------------------- *)
1284
1285 parse_as_infix("tagged_partial_division_of",(12,"right"));;
1286 parse_as_infix("tagged_division_of",(12,"right"));;
1287
1288 let tagged_partial_division_of = new_definition
1289   `s tagged_partial_division_of i <=>
1290         FINITE s /\
1291         (!x k. (x,k) IN s
1292                ==> x IN k /\ k SUBSET i /\ ?a b. k = interval[a,b]) /\
1293         (!x1 k1 x2 k2. (x1,k1) IN s /\ (x2,k2) IN s /\ ~((x1,k1) = (x2,k2))
1294                        ==> (interior(k1) INTER interior(k2) = {}))`;;
1295
1296 let tagged_division_of = new_definition
1297   `s tagged_division_of i <=>
1298         s tagged_partial_division_of i /\ (UNIONS {k | ?x. (x,k) IN s} = i)`;;
1299
1300 let TAGGED_DIVISION_OF_FINITE = prove
1301  (`!s i. s tagged_division_of i ==> FINITE s`,
1302   SIMP_TAC[tagged_division_of; tagged_partial_division_of]);;
1303
1304 let TAGGED_DIVISION_OF = prove
1305  (`s tagged_division_of i <=>
1306         FINITE s /\
1307         (!x k. (x,k) IN s
1308                ==> x IN k /\ k SUBSET i /\ ?a b. k = interval[a,b]) /\
1309         (!x1 k1 x2 k2. (x1,k1) IN s /\ (x2,k2) IN s /\ ~((x1,k1) = (x2,k2))
1310                        ==> (interior(k1) INTER interior(k2) = {})) /\
1311         (UNIONS {k | ?x. (x,k) IN s} = i)`,
1312   REWRITE_TAC[tagged_division_of; tagged_partial_division_of; CONJ_ASSOC]);;
1313
1314 let DIVISION_OF_TAGGED_DIVISION = prove
1315  (`!s i. s tagged_division_of i ==> (IMAGE SND s) division_of i`,
1316   REWRITE_TAC[TAGGED_DIVISION_OF; division_of] THEN
1317   ASM_SIMP_TAC[FINITE_IMAGE; FORALL_IN_IMAGE; FORALL_PAIR_THM; PAIR_EQ] THEN
1318   REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM] THEN
1319   REPEAT GEN_TAC THEN STRIP_TAC THEN REPEAT CONJ_TAC THENL
1320    [ASM_MESON_TAC[MEMBER_NOT_EMPTY];
1321     REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
1322     FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[];
1323     FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
1324     REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_IMAGE; IN_UNIONS] THEN
1325     REWRITE_TAC[FORALL_PAIR_THM; EXISTS_PAIR_THM] THEN MESON_TAC[]]);;
1326
1327 let PARTIAL_DIVISION_OF_TAGGED_DIVISION = prove
1328  (`!s i. s tagged_partial_division_of i
1329          ==> (IMAGE SND s) division_of UNIONS(IMAGE SND s)`,
1330   REWRITE_TAC[tagged_partial_division_of; division_of] THEN
1331   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
1332   REWRITE_TAC[FORALL_PAIR_THM; PAIR_EQ; DE_MORGAN_THM] THEN
1333   GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN REPEAT DISCH_TAC THEN
1334   REPEAT CONJ_TAC THENL
1335    [ASM_MESON_TAC[FINITE_IMAGE];
1336     ALL_TAC;
1337     ASM_MESON_TAC[]] THEN
1338   REPEAT GEN_TAC THEN STRIP_TAC THEN CONJ_TAC THENL
1339    [ALL_TAC; ASM_MESON_TAC[MEMBER_NOT_EMPTY]] THEN
1340   REWRITE_TAC[SUBSET; IN_UNIONS; IN_IMAGE; EXISTS_PAIR_THM] THEN
1341   CONV_TAC(ONCE_DEPTH_CONV UNWIND_CONV) THEN ASM SET_TAC[]);;
1342
1343 let TAGGED_PARTIAL_DIVISION_SUBSET = prove
1344  (`!s t i. s tagged_partial_division_of i /\ t SUBSET s
1345            ==> t tagged_partial_division_of i`,
1346   REWRITE_TAC[tagged_partial_division_of] THEN
1347   MESON_TAC[FINITE_SUBSET; SUBSET]);;
1348
1349 let VSUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA = prove
1350  (`!d:(real^M->bool)->real^N p i.
1351         p tagged_partial_division_of i /\
1352         (!u v. ~(interval[u,v] = {}) /\ content(interval[u,v]) = &0
1353                ==> d(interval[u,v]) = vec 0)
1354         ==> vsum p (\(x,k). d k) = vsum (IMAGE SND p) d`,
1355   REWRITE_TAC[CONTENT_EQ_0_INTERIOR] THEN REPEAT STRIP_TAC THEN
1356   SUBGOAL_THEN `(\(x:real^M,k:real^M->bool). d k:real^N) = d o SND`
1357   SUBST1_TAC THENL [SIMP_TAC[FUN_EQ_THM; FORALL_PAIR_THM; o_THM]; ALL_TAC] THEN
1358   CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_IMAGE_NONZERO THEN
1359   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [tagged_partial_division_of]) THEN
1360   MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
1361   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
1362   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
1363   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:real^M->bool` THEN
1364   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `y:real^M` THEN
1365   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k':real^M->bool` THEN
1366   ASM_CASES_TAC `k':real^M->bool = k` THEN
1367   ASM_REWRITE_TAC[PAIR_EQ; INTER_ACI] THEN
1368   RULE_ASSUM_TAC(REWRITE_RULE[GSYM MEMBER_NOT_EMPTY]) THEN
1369   ASM_MESON_TAC[]);;
1370
1371 let VSUM_OVER_TAGGED_DIVISION_LEMMA = prove
1372  (`!d:(real^M->bool)->real^N p i.
1373         p tagged_division_of i /\
1374         (!u v. ~(interval[u,v] = {}) /\ content(interval[u,v]) = &0
1375                ==> d(interval[u,v]) = vec 0)
1376         ==> vsum p (\(x,k). d k) = vsum (IMAGE SND p) d`,
1377   REWRITE_TAC[tagged_division_of] THEN REPEAT STRIP_TAC THEN
1378   MATCH_MP_TAC VSUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA THEN
1379   EXISTS_TAC `i:real^M->bool` THEN ASM_REWRITE_TAC[]);;
1380
1381 let SUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA = prove
1382  (`!d:(real^N->bool)->real p i.
1383         p tagged_partial_division_of i /\
1384         (!u v. ~(interval[u,v] = {}) /\ content(interval[u,v]) = &0
1385                ==> d(interval[u,v]) = &0)
1386         ==> sum p (\(x,k). d k) = sum (IMAGE SND p) d`,
1387   REPEAT STRIP_TAC THEN
1388   FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o
1389     REWRITE_RULE[tagged_partial_division_of]) THEN
1390   ONCE_REWRITE_TAC[GSYM LIFT_EQ] THEN
1391   ASM_SIMP_TAC[LIFT_SUM; FINITE_IMAGE; o_DEF; LAMBDA_PAIR_THM] THEN
1392   MATCH_MP_TAC VSUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA THEN
1393   ASM_SIMP_TAC[GSYM DROP_EQ; DROP_VEC; LIFT_DROP] THEN ASM_MESON_TAC[]);;
1394
1395 let SUM_OVER_TAGGED_DIVISION_LEMMA = prove
1396  (`!d:(real^N->bool)->real p i.
1397         p tagged_division_of i /\
1398         (!u v. ~(interval[u,v] = {}) /\ content(interval[u,v]) = &0
1399                ==> d(interval[u,v]) = &0)
1400         ==> sum p (\(x,k). d k) = sum (IMAGE SND p) d`,
1401   REWRITE_TAC[tagged_division_of] THEN REPEAT STRIP_TAC THEN
1402   MATCH_MP_TAC SUM_OVER_TAGGED_PARTIAL_DIVISION_LEMMA THEN
1403   EXISTS_TAC `i:real^N->bool` THEN ASM_REWRITE_TAC[]);;
1404
1405 let TAG_IN_INTERVAL = prove
1406  (`!p i k. p tagged_division_of i /\ (x,k) IN p ==> x IN i`,
1407   REWRITE_TAC[TAGGED_DIVISION_OF] THEN SET_TAC[]);;
1408
1409 let TAGGED_DIVISION_OF_EMPTY = prove
1410  (`{} tagged_division_of {}`,
1411   REWRITE_TAC[tagged_division_of; tagged_partial_division_of] THEN
1412   REWRITE_TAC[FINITE_RULES; EXTENSION; NOT_IN_EMPTY; IN_UNIONS; IN_ELIM_THM]);;
1413
1414 let TAGGED_PARTIAL_DIVISION_OF_TRIVIAL = prove
1415  (`!p. p tagged_partial_division_of {} <=> p = {}`,
1416   REWRITE_TAC[tagged_partial_division_of; SUBSET_EMPTY; CONJ_ASSOC] THEN
1417   REWRITE_TAC[SET_RULE `x IN k /\ k = {} <=> F`] THEN
1418   REWRITE_TAC[GSYM FORALL_PAIR_THM; GSYM NOT_EXISTS_THM; MEMBER_NOT_EMPTY] THEN
1419   REWRITE_TAC[AC CONJ_ACI `(a /\ b) /\ c <=> b /\ a /\ c`] THEN
1420   GEN_TAC THEN MATCH_MP_TAC(TAUT `(a ==> b) ==> (a /\ b <=> a)`) THEN
1421   DISCH_THEN SUBST1_TAC THEN
1422   REWRITE_TAC[FINITE_RULES; UNIONS_0; NOT_IN_EMPTY]);;
1423
1424 let TAGGED_DIVISION_OF_TRIVIAL = prove
1425  (`!p. p tagged_division_of {} <=> p = {}`,
1426   REWRITE_TAC[tagged_division_of; TAGGED_PARTIAL_DIVISION_OF_TRIVIAL] THEN
1427   GEN_TAC THEN MATCH_MP_TAC(TAUT `(a ==> b) ==> (a /\ b <=> a)`) THEN
1428   DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[NOT_IN_EMPTY] THEN SET_TAC[]);;
1429
1430 let TAGGED_DIVISION_OF_SELF = prove
1431  (`!x a b. x IN interval[a,b]
1432            ==> {(x,interval[a,b])} tagged_division_of interval[a,b]`,
1433   REWRITE_TAC[TAGGED_DIVISION_OF; FINITE_INSERT; FINITE_RULES; IN_SING] THEN
1434   REWRITE_TAC[FORALL_PAIR_THM; PAIR_EQ] THEN REPEAT STRIP_TAC THEN
1435   ASM_REWRITE_TAC[SUBSET_REFL; UNWIND_THM2; SET_RULE `{k | k = a} = {a}`] THEN
1436   REWRITE_TAC[UNIONS_1] THEN ASM_MESON_TAC[]);;
1437
1438 let TAGGED_DIVISION_UNION = prove
1439  (`!s1 s2:real^N->bool p1 p2.
1440         p1 tagged_division_of s1 /\
1441         p2 tagged_division_of s2 /\
1442         interior s1 INTER interior s2 = {}
1443         ==> (p1 UNION p2) tagged_division_of (s1 UNION s2)`,
1444   REPEAT GEN_TAC THEN REWRITE_TAC[TAGGED_DIVISION_OF] THEN STRIP_TAC THEN
1445   ASM_REWRITE_TAC[FINITE_UNION; IN_UNION; EXISTS_OR_THM; SET_RULE
1446    `UNIONS {x | P x \/ Q x} = UNIONS {x | P x} UNION UNIONS {x | Q x}`] THEN
1447   CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
1448   REPEAT STRIP_TAC THENL
1449    [ASM_MESON_TAC[]; ALL_TAC;
1450     ONCE_REWRITE_TAC[INTER_COMM]; ASM_MESON_TAC[]] THEN
1451   MATCH_MP_TAC(SET_RULE
1452    `!s' t'. s SUBSET s' /\ t SUBSET t' /\ s' INTER t' = {}
1453             ==> s INTER t = {}`) THEN
1454   MAP_EVERY EXISTS_TAC
1455    [`interior s1:real^N->bool`; `interior s2:real^N->bool`] THEN
1456   ASM_SIMP_TAC[] THEN CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN
1457   ASM_MESON_TAC[]);;
1458
1459 let TAGGED_DIVISION_UNIONS = prove
1460  (`!iset pfn. FINITE iset /\
1461               (!i:real^M->bool. i IN iset ==> pfn(i) tagged_division_of i) /\
1462               (!i1 i2. i1 IN iset /\ i2 IN iset /\ ~(i1 = i2)
1463                        ==> (interior(i1) INTER interior(i2) = {}))
1464               ==> UNIONS(IMAGE pfn iset) tagged_division_of (UNIONS iset)`,
1465   let lemma1 = prove
1466     (`(?t. (?x. (t = f x) /\ P x) /\ Q t) <=> ?x. P x /\ Q(f x)`,
1467      MESON_TAC[])
1468   and lemma2 = prove
1469    (`!s1 t1 s2 t2. s1 SUBSET t1 /\ s2 SUBSET t2 /\ (t1 INTER t2 = {})
1470                    ==> (s1 INTER s2 = {})`,
1471     SET_TAC[]) in
1472   REPEAT GEN_TAC THEN
1473   REWRITE_TAC[ONCE_REWRITE_RULE[EXTENSION] tagged_division_of] THEN
1474   REWRITE_TAC[tagged_partial_division_of; IN_UNIONS; IN_ELIM_THM] THEN
1475   REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_UNIONS; IN_IMAGE] THEN
1476   SIMP_TAC[FINITE_UNIONS; FINITE_IMAGE; FORALL_IN_IMAGE] THEN
1477   STRIP_TAC THEN REPEAT CONJ_TAC THENL
1478    [ASM_MESON_TAC[]; ALL_TAC; ASM_MESON_TAC[]] THEN
1479   REPEAT GEN_TAC THEN REWRITE_TAC[lemma1] THEN
1480   REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN
1481   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
1482   MAP_EVERY X_GEN_TAC [`i1:real^M->bool`; `i2:real^M->bool`] THEN
1483   ASM_CASES_TAC `i1 = i2:real^M->bool` THENL
1484    [ASM_MESON_TAC[]; ALL_TAC] THEN
1485   REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma2 THEN
1486   MAP_EVERY EXISTS_TAC
1487    [`interior(i1:real^M->bool)`; `interior(i2:real^M->bool)`] THEN
1488   ASM_MESON_TAC[SUBSET; SUBSET_INTERIOR]);;
1489
1490 let TAGGED_PARTIAL_DIVISION_OF_UNION_SELF = prove
1491  (`!p s. p tagged_partial_division_of s
1492          ==> p tagged_division_of (UNIONS(IMAGE SND p))`,
1493   SIMP_TAC[tagged_partial_division_of; TAGGED_DIVISION_OF] THEN
1494   REPEAT GEN_TAC THEN STRIP_TAC THEN REPEAT CONJ_TAC THENL
1495    [REPEAT STRIP_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
1496     REWRITE_TAC[SUBSET; IN_UNIONS; IN_IMAGE; EXISTS_PAIR_THM] THEN
1497     ASM_MESON_TAC[];
1498     ASM_MESON_TAC[];
1499     AP_TERM_TAC THEN GEN_REWRITE_TAC I [EXTENSION] THEN
1500     REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; EXISTS_PAIR_THM] THEN MESON_TAC[]]);;
1501
1502 let TAGGED_DIVISION_OF_UNION_SELF = prove
1503  (`!p s. p tagged_division_of s
1504          ==> p tagged_division_of (UNIONS(IMAGE SND p))`,
1505   SIMP_TAC[TAGGED_DIVISION_OF] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
1506   MATCH_MP_TAC(TAUT `(c ==> a /\ b) /\ c ==> a /\ b /\ c`) THEN CONJ_TAC THENL
1507    [DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_SIMP_TAC[] THEN ASM_MESON_TAC[];
1508     FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN AP_TERM_TAC THEN
1509     GEN_REWRITE_TAC I [EXTENSION] THEN
1510     REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; EXISTS_PAIR_THM] THEN MESON_TAC[]]);;
1511
1512 let TAGGED_DIVISION_UNION_IMAGE_SND = prove
1513  (`!p s. p tagged_division_of s ==> s = UNIONS(IMAGE SND p)`,
1514   MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF; tagged_division_of]);;
1515
1516 let TAGGED_DIVISION_OF_ALT = prove
1517  (`!p s. p tagged_division_of s <=>
1518          p tagged_partial_division_of s /\
1519          (!x. x IN s ==> ?t k. (t,k) IN p /\ x IN k)`,
1520   REWRITE_TAC[tagged_division_of; GSYM SUBSET_ANTISYM_EQ] THEN
1521   REWRITE_TAC[SUBSET; FORALL_IN_UNIONS; IN_ELIM_THM] THEN
1522   REWRITE_TAC[IN_UNIONS; EXISTS_PAIR_THM; IN_ELIM_THM] THEN
1523   REWRITE_TAC[tagged_partial_division_of; SUBSET] THEN MESON_TAC[]);;
1524
1525 let TAGGED_DIVISION_OF_ANOTHER = prove
1526  (`!p s s'.
1527         p tagged_partial_division_of s' /\
1528         (!t k. (t,k) IN p ==> k SUBSET s) /\
1529         (!x. x IN s ==> ?t k. (t,k) IN p /\ x IN k)
1530         ==> p tagged_division_of s`,
1531   REWRITE_TAC[TAGGED_DIVISION_OF_ALT; tagged_partial_division_of] THEN
1532   SET_TAC[]);;
1533
1534 let TAGGED_PARTIAL_DIVISION_OF_SUBSET = prove
1535  (`!p s t. p tagged_partial_division_of s /\ s SUBSET t
1536            ==> p tagged_partial_division_of t`,
1537   REWRITE_TAC[tagged_partial_division_of] THEN SET_TAC[]);;
1538
1539 let TAGGED_DIVISION_OF_NONTRIVIAL = prove
1540  (`!s a b:real^N.
1541         s tagged_division_of interval[a,b] /\ ~(content(interval[a,b]) = &0)
1542         ==> {(x,k) | (x,k) IN s /\ ~(content k = &0)}
1543             tagged_division_of interval[a,b]`,
1544   REPEAT STRIP_TAC THEN REWRITE_TAC[TAGGED_DIVISION_OF_ALT] THEN
1545   CONJ_TAC THENL
1546    [MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_SUBSET THEN
1547     EXISTS_TAC `s:(real^N#(real^N->bool))->bool` THEN
1548     RULE_ASSUM_TAC(REWRITE_RULE[tagged_division_of]) THEN
1549     ASM_REWRITE_TAC[] THEN SET_TAC[];
1550     FIRST_ASSUM(MP_TAC o MATCH_MP DIVISION_OF_TAGGED_DIVISION) THEN
1551     DISCH_THEN(MP_TAC o
1552      MATCH_MP(REWRITE_RULE[IMP_CONJ] DIVISION_OF_NONTRIVIAL)) THEN
1553     ASM_REWRITE_TAC[] THEN
1554     REWRITE_TAC[division_of] THEN DISCH_THEN(MP_TAC o last o CONJUNCTS) THEN
1555     REWRITE_TAC[GSYM SUBSET_ANTISYM_EQ; SUBSET; IN_ELIM_PAIR_THM] THEN
1556     REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE; EXISTS_PAIR_THM; IN_ELIM_THM;
1557                 GSYM CONJ_ASSOC] THEN
1558     MESON_TAC[]]);;
1559
1560 (* ------------------------------------------------------------------------- *)
1561 (* Fine-ness of a partition w.r.t. a gauge.                                  *)
1562 (* ------------------------------------------------------------------------- *)
1563
1564 parse_as_infix("fine",(12,"right"));;
1565
1566 let fine = new_definition
1567   `d fine s <=> !x k. (x,k) IN s ==> k SUBSET d(x)`;;
1568
1569 let FINE_INTER = prove
1570  (`!p d1 d2. (\x. d1(x) INTER d2(x)) fine p <=> d1 fine p /\ d2 fine p`,
1571   let lemma = prove
1572    (`s SUBSET (t INTER u) <=> s SUBSET t /\ s SUBSET u`,SET_TAC[]) in
1573   REWRITE_TAC[fine; IN_INTER; lemma] THEN MESON_TAC[]);;
1574
1575 let FINE_INTERS = prove
1576  (`!f s p. (\x. INTERS {f d x | d IN s}) fine p <=>
1577            !d. d IN s ==> (f d) fine p`,
1578   REWRITE_TAC[fine; SET_RULE `s SUBSET INTERS u <=> !t. t IN u ==> s SUBSET t`;
1579               IN_ELIM_THM] THEN MESON_TAC[]);;
1580
1581 let FINE_UNION = prove
1582  (`!d p1 p2. d fine p1 /\ d fine p2 ==> d fine (p1 UNION p2)`,
1583   REWRITE_TAC[fine; IN_UNION] THEN MESON_TAC[]);;
1584
1585 let FINE_UNIONS = prove
1586  (`!d ps. (!p. p IN ps ==> d fine p) ==> d fine (UNIONS ps)`,
1587   REWRITE_TAC[fine; IN_UNIONS] THEN MESON_TAC[]);;
1588
1589 let FINE_SUBSET = prove
1590  (`!d p q. p SUBSET q /\ d fine q ==> d fine p`,
1591   REWRITE_TAC[fine; SUBSET] THEN MESON_TAC[]);;
1592
1593 (* ------------------------------------------------------------------------- *)
1594 (* Gauge integral. Define on compact intervals first, then use a limit.      *)
1595 (* ------------------------------------------------------------------------- *)
1596
1597 parse_as_infix("has_integral_compact_interval",(12,"right"));;
1598 parse_as_infix("has_integral",(12,"right"));;
1599 parse_as_infix("integrable_on",(12,"right"));;
1600
1601 let has_integral_compact_interval = new_definition
1602   `(f has_integral_compact_interval y) i <=>
1603         !e. &0 < e
1604             ==> ?d. gauge d /\
1605                     !p. p tagged_division_of i /\ d fine p
1606                         ==> norm(vsum p (\(x,k). content(k) % f(x)) - y) < e`;;
1607
1608 let has_integral_def = new_definition
1609   `(f has_integral y) i <=>
1610         if ?a b. i = interval[a,b] then (f has_integral_compact_interval y) i
1611         else !e. &0 < e
1612                  ==> ?B. &0 < B /\
1613                          !a b. ball(vec 0,B) SUBSET interval[a,b]
1614                                ==> ?z. ((\x. if x IN i then f(x) else vec 0)
1615                                         has_integral_compact_interval z)
1616                                         (interval[a,b]) /\
1617                                        norm(z - y) < e`;;
1618
1619 let has_integral = prove
1620  (`(f has_integral y) (interval[a,b]) <=>
1621         !e. &0 < e
1622             ==> ?d. gauge d /\
1623                     !p. p tagged_division_of interval[a,b] /\ d fine p
1624                         ==> norm(vsum p (\(x,k). content(k) % f(x)) - y) < e`,
1625   REWRITE_TAC[has_integral_def; has_integral_compact_interval] THEN
1626   MESON_TAC[]);;
1627
1628 let has_integral_alt = prove
1629  (`(f has_integral y) i <=>
1630         if ?a b. i = interval[a,b] then (f has_integral y) i
1631         else !e. &0 < e
1632                  ==> ?B. &0 < B /\
1633                          !a b. ball(vec 0,B) SUBSET interval[a,b]
1634                                ==> ?z. ((\x. if x IN i then f(x) else vec 0)
1635                                         has_integral z) (interval[a,b]) /\
1636                                        norm(z - y) < e`,
1637   REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [has_integral_def] THEN
1638   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
1639    [POP_ASSUM(REPEAT_TCL CHOOSE_THEN SUBST1_TAC); ALL_TAC] THEN
1640   REWRITE_TAC[has_integral_compact_interval; has_integral]);;
1641
1642 let integrable_on = new_definition
1643  `f integrable_on i <=> ?y. (f has_integral y) i`;;
1644
1645 let integral = new_definition
1646  `integral i f = @y. (f has_integral y) i`;;
1647
1648 let INTEGRABLE_INTEGRAL = prove
1649  (`!f i. f integrable_on i ==> (f has_integral (integral i f)) i`,
1650   REPEAT GEN_TAC THEN REWRITE_TAC[integrable_on; integral] THEN
1651   CONV_TAC(RAND_CONV SELECT_CONV) THEN REWRITE_TAC[]);;
1652
1653 let HAS_INTEGRAL_INTEGRABLE = prove
1654  (`!f i s. (f has_integral i) s ==> f integrable_on s`,
1655   REWRITE_TAC[integrable_on] THEN MESON_TAC[]);;
1656
1657 let HAS_INTEGRAL_INTEGRAL = prove
1658  (`!f s. f integrable_on s <=> (f has_integral (integral s f)) s`,
1659   MESON_TAC[INTEGRABLE_INTEGRAL; HAS_INTEGRAL_INTEGRABLE]);;
1660
1661 let VSUM_CONTENT_NULL = prove
1662  (`!f:real^M->real^N a b p.
1663         content(interval[a,b]) = &0 /\
1664         p tagged_division_of interval[a,b]
1665         ==> vsum p (\(x,k). content k % f x) = vec 0`,
1666   REPEAT STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ_0 THEN
1667   REWRITE_TAC[FORALL_PAIR_THM] THEN
1668   MAP_EVERY X_GEN_TAC [`p:real^M`; `k:real^M->bool`] THEN
1669   DISCH_TAC THEN REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN
1670   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
1671   DISCH_THEN(MP_TAC o CONJUNCT1 o CONJUNCT2) THEN
1672   DISCH_THEN(MP_TAC o SPECL [`p:real^M`; `k:real^M->bool`]) THEN
1673   ASM_MESON_TAC[CONTENT_SUBSET; CONTENT_POS_LE; REAL_ARITH
1674    `&0 <= x /\ x <= y /\ y = &0 ==> x = &0`]);;
1675
1676 (* ------------------------------------------------------------------------- *)
1677 (* Some basic combining lemmas.                                              *)
1678 (* ------------------------------------------------------------------------- *)
1679
1680 let TAGGED_DIVISION_UNIONS_EXISTS = prove
1681  (`!d iset i:real^M->bool.
1682         FINITE iset /\
1683         (!i. i IN iset ==> ?p. p tagged_division_of i /\ d fine p) /\
1684         (!i1 i2. i1 IN iset /\ i2 IN iset /\ ~(i1 = i2)
1685                  ==> (interior(i1) INTER interior(i2) = {})) /\
1686         (UNIONS iset = i)
1687         ==> ?p. p tagged_division_of i /\ d fine p`,
1688   REPEAT GEN_TAC THEN
1689   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
1690   REWRITE_TAC[SKOLEM_THM; LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN
1691   REPEAT STRIP_TAC THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
1692   EXISTS_TAC `UNIONS (IMAGE(p:(real^M->bool)->((real^M#(real^M->bool))->bool))
1693                       iset)` THEN
1694   ASM_SIMP_TAC[TAGGED_DIVISION_UNIONS] THEN
1695   ASM_MESON_TAC[FINE_UNIONS; IN_IMAGE]);;
1696
1697 (* ------------------------------------------------------------------------- *)
1698 (* The set we're concerned with must be closed.                              *)
1699 (* ------------------------------------------------------------------------- *)
1700
1701 let DIVISION_OF_CLOSED = prove
1702  (`!s i. s division_of i ==> closed i`,
1703   REWRITE_TAC[division_of] THEN MESON_TAC[CLOSED_UNIONS; CLOSED_INTERVAL]);;
1704
1705 (* ------------------------------------------------------------------------- *)
1706 (* General bisection principle for intervals; might be useful elsewhere.     *)
1707 (* ------------------------------------------------------------------------- *)
1708
1709 let INTERVAL_BISECTION_STEP = prove
1710  (`!P. P {} /\
1711        (!s t. P s /\ P t /\ interior(s) INTER interior(t) = {}
1712               ==> P(s UNION t))
1713        ==> !a b:real^N.
1714                 ~(P(interval[a,b]))
1715                 ==> ?c d. ~(P(interval[c,d])) /\
1716                           !i. 1 <= i /\ i <= dimindex(:N)
1717                               ==> a$i <= c$i /\ c$i <= d$i /\ d$i <= b$i /\
1718                                   &2 * (d$i - c$i) <= b$i - a$i`,
1719   REPEAT GEN_TAC THEN STRIP_TAC THEN REPEAT GEN_TAC THEN
1720   ASM_CASES_TAC `!i. 1 <= i /\ i <= dimindex(:N)
1721                      ==> (a:real^N)$i <= (b:real^N)$i` THENL
1722    [ALL_TAC;
1723     RULE_ASSUM_TAC(REWRITE_RULE[GSYM INTERVAL_NE_EMPTY]) THEN
1724     ASM_REWRITE_TAC[]] THEN
1725   SUBGOAL_THEN
1726    `!f. FINITE f /\
1727         (!s:real^N->bool. s IN f ==> P s) /\
1728         (!s:real^N->bool. s IN f ==> ?a b. s = interval[a,b]) /\
1729         (!s t. s IN f /\ t IN f /\ ~(s = t)
1730                ==> interior(s) INTER interior(t) = {})
1731         ==> P(UNIONS f)`
1732   ASSUME_TAC THENL
1733    [ONCE_REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
1734     ASM_SIMP_TAC[UNIONS_0; UNIONS_INSERT; NOT_IN_EMPTY; FORALL_IN_INSERT] THEN
1735     REWRITE_TAC[IMP_IMP] THEN REPEAT GEN_TAC THEN DISCH_THEN(fun th ->
1736       FIRST_X_ASSUM MATCH_MP_TAC THEN STRIP_ASSUME_TAC th) THEN
1737     ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
1738     MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
1739     ASM_REWRITE_TAC[OPEN_INTERIOR] THEN REPEAT STRIP_TAC THEN
1740     FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_INSERT] THEN
1741     ASM_MESON_TAC[];
1742     ALL_TAC] THEN
1743   DISCH_TAC THEN
1744   FIRST_X_ASSUM(MP_TAC o SPEC
1745    `{ interval[c,d] |
1746       !i. 1 <= i /\ i <= dimindex(:N)
1747           ==> ((c:real^N)$i = (a:real^N)$i) /\ (d$i = (a$i + b$i) / &2) \/
1748               (c$i = (a$i + b$i) / &2) /\ ((d:real^N)$i = (b:real^N)$i)}`) THEN
1749   ONCE_REWRITE_TAC[IMP_CONJ] THEN ANTS_TAC THENL
1750    [MATCH_MP_TAC FINITE_SUBSET THEN
1751     EXISTS_TAC
1752      `IMAGE (\s. closed_interval
1753        [(lambda i. if i IN s then (a:real^N)$i else (a$i + b$i) / &2):real^N,
1754         (lambda i. if i IN s then (a$i + b$i) / &2 else (b:real^N)$i)])
1755          {s | s SUBSET (1..dimindex(:N))}` THEN
1756     CONJ_TAC THENL
1757      [SIMP_TAC[FINITE_POWERSET; FINITE_IMAGE; FINITE_NUMSEG]; ALL_TAC] THEN
1758     REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_IMAGE] THEN
1759     X_GEN_TAC `k:real^N->bool` THEN
1760     DISCH_THEN(X_CHOOSE_THEN `c:real^N` (X_CHOOSE_THEN `d:real^N`
1761       (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC))) THEN
1762     EXISTS_TAC `{i | 1 <= i /\ i <= dimindex(:N) /\
1763                      ((c:real^N)$i = (a:real^N)$i)}` THEN
1764     CONJ_TAC THENL [ALL_TAC; SIMP_TAC[IN_ELIM_THM; IN_NUMSEG]] THEN
1765     AP_TERM_TAC THEN REWRITE_TAC[CONS_11; PAIR_EQ] THEN
1766     SIMP_TAC[CART_EQ; LAMBDA_BETA; IN_ELIM_THM] THEN
1767     REPEAT(FIRST_X_ASSUM(MP_TAC o GEN `i:num` o SPEC `i:num`)) THEN
1768     REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN
1769     MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
1770     REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> (a ==> b /\ c)`] THEN
1771     MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
1772     COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
1773     SIMP_TAC[REAL_EQ_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
1774     REAL_ARITH_TAC;
1775     ALL_TAC] THEN
1776   GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN ANTS_TAC THENL
1777    [UNDISCH_TAC `~P(interval[a:real^N,b])` THEN MATCH_MP_TAC EQ_IMP THEN
1778     AP_TERM_TAC THEN AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN
1779     GEN_REWRITE_TAC I [EXTENSION] THEN
1780     REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN
1781     REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN
1782     ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c <=> b /\ a /\ c`] THEN
1783     GEN_REWRITE_TAC LAND_CONV [SWAP_EXISTS_THM] THEN
1784     GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [SWAP_EXISTS_THM] THEN
1785     REWRITE_TAC[UNWIND_THM2; IN_INTERVAL] THEN
1786     REWRITE_TAC[AND_FORALL_THM] THEN
1787     REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> (a ==> b /\ c)`] THEN
1788     REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN AP_TERM_TAC THEN
1789     GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `i:num` THEN
1790     REWRITE_TAC[] THEN
1791     MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> ((a ==> b) <=> (a ==> c))`) THEN
1792     STRIP_TAC THEN
1793     ONCE_REWRITE_TAC[TAUT `(a \/ b) /\ c <=> ~(a ==> ~c) \/ ~(b ==> ~c)`] THEN
1794     SIMP_TAC[] THEN
1795     REWRITE_TAC[TAUT `~(a ==> ~b) <=> a /\ b`; GSYM CONJ_ASSOC] THEN
1796     REWRITE_TAC[EXISTS_OR_THM; RIGHT_EXISTS_AND_THM] THEN
1797     REWRITE_TAC[LEFT_EXISTS_AND_THM; EXISTS_REFL] THEN
1798     SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
1799     REAL_ARITH_TAC;
1800     ALL_TAC] THEN
1801   REWRITE_TAC[FORALL_IN_GSPEC] THEN
1802   MATCH_MP_TAC(TAUT `b /\ (~a ==> e) /\ c ==> ~(a /\ b /\ c) ==> e`) THEN
1803   CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN CONJ_TAC THENL
1804    [REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
1805     REPEAT(MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC) THEN
1806     DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN ASM_REWRITE_TAC[] THEN
1807     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN
1808     DISCH_THEN(fun th -> REPEAT DISCH_TAC THEN MP_TAC th) THEN
1809     FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
1810     REAL_ARITH_TAC;
1811     ALL_TAC] THEN
1812   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
1813   REWRITE_TAC[IMP_IMP; INTERIOR_CLOSED_INTERVAL] THEN
1814   REWRITE_TAC[RIGHT_IMP_FORALL_THM] THEN
1815   MAP_EVERY X_GEN_TAC
1816    [`c1:real^N`; `d1:real^N`; `c2:real^N`; `d2:real^N`] THEN
1817   ASM_CASES_TAC `(c1 = c2:real^N) /\ (d1 = d2:real^N)` THENL
1818    [ASM_REWRITE_TAC[]; ALL_TAC] THEN
1819   DISCH_THEN(fun th ->
1820     DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (K ALL_TAC)) THEN MP_TAC th) THEN
1821   REWRITE_TAC[IMP_IMP] THEN
1822   UNDISCH_TAC `~((c1 = c2:real^N) /\ (d1 = d2:real^N))` THEN
1823   REWRITE_TAC[CART_EQ; INTERIOR_CLOSED_INTERVAL] THEN
1824   REWRITE_TAC[AND_FORALL_THM] THEN
1825   REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> (a ==> b /\ c)`] THEN
1826   REWRITE_TAC[NOT_FORALL_THM] THEN
1827   DISCH_THEN(X_CHOOSE_THEN `j:num` (fun th ->
1828     DISCH_THEN(MP_TAC o SPEC `j:num`) THEN MP_TAC th)) THEN
1829   REWRITE_TAC[NOT_IMP] THEN
1830   DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
1831   ASM_REWRITE_TAC[IMP_IMP] THEN
1832   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
1833   ASM_REWRITE_TAC[EXTENSION; IN_INTERVAL; NOT_IN_EMPTY; IN_INTER] THEN
1834   SIMP_TAC[REAL_EQ_RDIV_EQ; REAL_EQ_LDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
1835   REWRITE_TAC[
1836     REAL_ARITH `~((a * &2 = a + b) /\ (a + b = b * &2)) <=> ~(a = b)`;
1837     REAL_ARITH `~((a + b = a * &2) /\ (b * &2 = a + b)) <=> ~(a = b)`] THEN
1838   DISCH_THEN(fun th -> X_GEN_TAC `x:real^N` THEN MP_TAC th) THEN
1839   REWRITE_TAC[AND_FORALL_THM] THEN
1840   REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> (a ==> b /\ c)`] THEN
1841   ASM_REWRITE_TAC[CONTRAPOS_THM] THEN
1842   DISCH_THEN(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN
1843   REAL_ARITH_TAC);;
1844
1845 let INTERVAL_BISECTION = prove
1846  (`!P. P {} /\
1847        (!s t. P s /\ P t /\ interior(s) INTER interior(t) = {}
1848               ==> P(s UNION t))
1849        ==> !a b:real^N.
1850                 ~(P(interval[a,b]))
1851                 ==> ?x. x IN interval[a,b] /\
1852                         !e. &0 < e
1853                             ==> ?c d. x IN interval[c,d] /\
1854                                       interval[c,d] SUBSET ball(x,e) /\
1855                                       interval[c,d] SUBSET interval[a,b] /\
1856                                       ~P(interval[c,d])`,
1857   REPEAT STRIP_TAC THEN
1858   SUBGOAL_THEN
1859    `?A B. (A(0) = a:real^N) /\ (B(0) = b) /\
1860           !n. ~(P(interval[A(SUC n),B(SUC n)])) /\
1861               !i. 1 <= i /\ i <= dimindex(:N)
1862                        ==> A(n)$i <= A(SUC n)$i /\
1863                            A(SUC n)$i <= B(SUC n)$i /\
1864                            B(SUC n)$i <= B(n)$i /\
1865                            &2 * (B(SUC n)$i - A(SUC n)$i) <= B(n)$i - A(n)$i`
1866   STRIP_ASSUME_TAC THENL
1867    [MP_TAC(ISPEC `P:(real^N->bool)->bool` INTERVAL_BISECTION_STEP) THEN
1868     ASM_REWRITE_TAC[] THEN
1869     GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
1870     REWRITE_TAC[SKOLEM_THM] THEN
1871     DISCH_THEN(X_CHOOSE_THEN `C:real^N->real^N->real^N`
1872      (X_CHOOSE_THEN `D:real^N->real^N->real^N` ASSUME_TAC)) THEN
1873     MP_TAC(prove_recursive_functions_exist num_RECURSION
1874      `(E 0 = a:real^N,b:real^N) /\
1875       (!n. E(SUC n) = C (FST(E n)) (SND(E n)),
1876                       D (FST(E n)) (SND(E n)))`) THEN
1877     DISCH_THEN(X_CHOOSE_THEN `E:num->real^N#real^N` STRIP_ASSUME_TAC) THEN
1878     EXISTS_TAC `\n. FST((E:num->real^N#real^N) n)` THEN
1879     EXISTS_TAC `\n. SND((E:num->real^N#real^N) n)` THEN
1880     ASM_REWRITE_TAC[] THEN INDUCT_TAC THEN ASM_SIMP_TAC[];
1881     ALL_TAC] THEN
1882   SUBGOAL_THEN
1883    `!e. &0 < e
1884         ==> ?n:num. !x y. x IN interval[A(n),B(n)] /\ y IN interval[A(n),B(n)]
1885                           ==> dist(x,y:real^N) < e`
1886   ASSUME_TAC THENL
1887    [X_GEN_TAC `e:real` THEN DISCH_TAC THEN MP_TAC(SPEC
1888      `sum(1..dimindex(:N)) (\i. (b:real^N)$i - (a:real^N)$i) / e`
1889      REAL_ARCH_POW2) THEN
1890     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
1891     MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
1892     MATCH_MP_TAC REAL_LET_TRANS THEN
1893     EXISTS_TAC `sum(1..dimindex(:N))(\i. abs((x - y:real^N)$i))` THEN
1894     REWRITE_TAC[dist; NORM_LE_L1] THEN
1895     MATCH_MP_TAC REAL_LET_TRANS THEN
1896     EXISTS_TAC `sum(1..dimindex(:N))
1897                    (\i. (B:num->real^N)(n)$i - (A:num->real^N)(n)$i)` THEN
1898     CONJ_TAC THENL
1899      [MATCH_MP_TAC SUM_LE_NUMSEG THEN SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
1900       REPEAT STRIP_TAC THEN
1901       MATCH_MP_TAC(REAL_ARITH `a <= x /\ x <= b /\ a <= y /\ y <= b
1902                                ==> abs(x - y) <= b - a`) THEN
1903       UNDISCH_TAC `x IN interval[(A:num->real^N) n,B n]` THEN
1904       UNDISCH_TAC `y IN interval[(A:num->real^N) n,B n]` THEN
1905       REWRITE_TAC[IN_INTERVAL] THEN ASM_SIMP_TAC[];
1906       ALL_TAC] THEN
1907     MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC
1908      `sum(1..dimindex(:N)) (\i. (b:real^N)$i - (a:real^N)$i) /
1909       &2 pow n` THEN
1910     CONJ_TAC THENL
1911      [ALL_TAC;
1912       SIMP_TAC[REAL_LT_LDIV_EQ; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN
1913       ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
1914       ASM_SIMP_TAC[GSYM REAL_LT_LDIV_EQ]] THEN
1915     REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
1916     REWRITE_TAC[GSYM SUM_LMUL] THEN MATCH_MP_TAC SUM_LE_NUMSEG THEN
1917     X_GEN_TAC `j:num` THEN STRIP_TAC THEN REWRITE_TAC[] THEN
1918     ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM real_div] THEN
1919     SPEC_TAC(`n:num`,`m:num`) THEN INDUCT_TAC THEN
1920     ASM_REWRITE_TAC[real_pow; REAL_DIV_1; REAL_LE_REFL] THEN
1921     ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
1922     REWRITE_TAC[real_div; REAL_INV_MUL; REAL_MUL_ASSOC] THEN
1923     SIMP_TAC[GSYM real_div; REAL_LE_RDIV_EQ; REAL_OF_NUM_LT; ARITH] THEN
1924     ASM_MESON_TAC[REAL_LE_TRANS; REAL_MUL_SYM];
1925     ALL_TAC] THEN
1926   SUBGOAL_THEN `?a:real^N. !n:num. a IN interval[A(n),B(n)]` MP_TAC THENL
1927    [MATCH_MP_TAC DECREASING_CLOSED_NEST THEN
1928     ASM_REWRITE_TAC[CLOSED_INTERVAL] THEN CONJ_TAC THENL
1929      [REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN
1930       ASM_MESON_TAC[REAL_NOT_LT; REAL_LE_TRANS];
1931       ALL_TAC] THEN
1932     REWRITE_TAC[LE_EXISTS] THEN SIMP_TAC[LEFT_IMP_EXISTS_THM] THEN
1933     X_GEN_TAC `m:num` THEN ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
1934     REWRITE_TAC[GSYM LEFT_IMP_EXISTS_THM; EXISTS_REFL] THEN
1935     INDUCT_TAC THEN REWRITE_TAC[ADD_CLAUSES; SUBSET_REFL] THEN
1936     MATCH_MP_TAC SUBSET_TRANS THEN
1937     EXISTS_TAC `interval[A(m + d:num):real^N,B(m + d)]` THEN
1938     ASM_REWRITE_TAC[] THEN
1939     REWRITE_TAC[SUBSET; IN_INTERVAL] THEN ASM_MESON_TAC[REAL_LE_TRANS];
1940     ALL_TAC] THEN
1941   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x0:real^N` THEN
1942   DISCH_TAC THEN CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
1943   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
1944   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
1945   DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN
1946   MAP_EVERY EXISTS_TAC [`(A:num->real^N) n`; `(B:num->real^N) n`] THEN
1947   ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
1948    [REWRITE_TAC[SUBSET; IN_BALL] THEN ASM_MESON_TAC[];
1949     ALL_TAC;
1950     SPEC_TAC(`n:num`,`p:num`) THEN INDUCT_TAC THEN ASM_REWRITE_TAC[]] THEN
1951   SUBGOAL_THEN
1952    `!m n. m <= n ==> interval[(A:num->real^N) n,B n] SUBSET interval[A m,B m]`
1953    (fun th -> ASM_MESON_TAC[SUBSET; LE_0; th]) THEN
1954   MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
1955   REPEAT(CONJ_TAC THENL [SET_TAC[]; ALL_TAC]) THEN
1956   REWRITE_TAC[SUBSET_INTERVAL] THEN ASM_MESON_TAC[]);;
1957
1958 (* ------------------------------------------------------------------------- *)
1959 (* Cousin's lemma.                                                           *)
1960 (* ------------------------------------------------------------------------- *)
1961
1962 let FINE_DIVISION_EXISTS = prove
1963  (`!g a b:real^M.
1964         gauge g ==> ?p. p tagged_division_of (interval[a,b]) /\ g fine p`,
1965   REPEAT STRIP_TAC THEN
1966   MP_TAC(ISPEC `\s:real^M->bool. ?p. p tagged_division_of s /\ g fine p`
1967         INTERVAL_BISECTION) THEN
1968   REWRITE_TAC[] THEN ANTS_TAC THENL
1969    [MESON_TAC[TAGGED_DIVISION_UNION; FINE_UNION;
1970               TAGGED_DIVISION_OF_EMPTY; fine; NOT_IN_EMPTY];
1971     DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`])] THEN
1972   GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN
1973   REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN
1974   DISCH_THEN(X_CHOOSE_THEN `x:real^M` (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
1975   FIRST_ASSUM(MP_TAC o SPEC `x:real^M` o REWRITE_RULE[gauge]) THEN
1976   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
1977   REWRITE_TAC[OPEN_CONTAINS_BALL; NOT_FORALL_THM] THEN
1978   DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN
1979   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `e:real` THEN
1980   STRIP_TAC THEN ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN
1981   MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN STRIP_TAC THEN
1982   FIRST_X_ASSUM(MP_TAC o SPEC `{(x:real^M,interval[c:real^M,d])}`) THEN
1983   ASM_SIMP_TAC[TAGGED_DIVISION_OF_SELF] THEN
1984   REWRITE_TAC[fine; IN_SING; PAIR_EQ] THEN ASM_MESON_TAC[SUBSET_TRANS]);;
1985
1986 (* ------------------------------------------------------------------------- *)
1987 (* Basic theorems about integrals.                                           *)
1988 (* ------------------------------------------------------------------------- *)
1989
1990 let HAS_INTEGRAL_UNIQUE = prove
1991  (`!f:real^M->real^N i k1 k2.
1992         (f has_integral k1) i /\ (f has_integral k2) i ==> k1 = k2`,
1993   REPEAT GEN_TAC THEN
1994   SUBGOAL_THEN
1995    `!f:real^M->real^N a b k1 k2.
1996        (f has_integral k1) (interval[a,b]) /\
1997        (f has_integral k2) (interval[a,b])
1998        ==> k1 = k2`
1999   MP_TAC THENL
2000    [REPEAT GEN_TAC THEN REWRITE_TAC[has_integral] THEN
2001     REWRITE_TAC[AND_FORALL_THM] THEN
2002     REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN
2003     ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
2004     ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
2005     REWRITE_TAC[GSYM NORM_POS_LT] THEN DISCH_TAC THEN
2006     DISCH_THEN(MP_TAC o SPEC `norm(k1 - k2 :real^N) / &2`) THEN
2007     ASM_REWRITE_TAC[REAL_HALF] THEN
2008     DISCH_THEN(CONJUNCTS_THEN2
2009      (X_CHOOSE_THEN `d1:real^M->real^M->bool` STRIP_ASSUME_TAC)
2010      (X_CHOOSE_THEN `d2:real^M->real^M->bool` STRIP_ASSUME_TAC)) THEN
2011     MP_TAC(ISPEC `\x. ((d1:real^M->real^M->bool) x) INTER (d2 x)`
2012                  FINE_DIVISION_EXISTS) THEN
2013     ASM_SIMP_TAC[GAUGE_INTER] THEN
2014     DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN
2015     REPEAT(FIRST_X_ASSUM(MP_TAC o check (is_forall o concl))) THEN
2016     REWRITE_TAC[] THEN REWRITE_TAC[IMP_IMP; NOT_EXISTS_THM] THEN
2017     REWRITE_TAC[AND_FORALL_THM] THEN MATCH_MP_TAC MONO_FORALL THEN
2018     GEN_TAC THEN
2019     MATCH_MP_TAC(TAUT
2020      `(f0 ==> f1 /\ f2) /\ ~(n1 /\ n2)
2021       ==> (t /\ f1 ==> n1) /\ (t /\ f2 ==> n2) ==> ~(t /\ f0)`) THEN
2022     CONJ_TAC THENL [SIMP_TAC[fine; SUBSET_INTER]; ALL_TAC] THEN
2023     MATCH_MP_TAC(REAL_ARITH `c <= a + b ==> ~(a < c / &2 /\ b < c / &2)`) THEN
2024     MESON_TAC[NORM_SUB; NORM_TRIANGLE; VECTOR_ARITH
2025      `k1 - k2:real^N = (k1 - x) + (x - k2)`];
2026     ALL_TAC] THEN
2027   DISCH_TAC THEN ONCE_REWRITE_TAC[has_integral_alt] THEN
2028   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
2029    [ASM_MESON_TAC[]; ALL_TAC] THEN
2030   DISCH_TAC THEN MATCH_MP_TAC(NORM_ARITH
2031    `~(&0 < norm(x - y)) ==> x = y`) THEN
2032   DISCH_TAC THEN
2033   FIRST_X_ASSUM(CONJUNCTS_THEN (MP_TAC o SPEC `norm(k1 - k2:real^N) / &2`)) THEN
2034   ASM_REWRITE_TAC[REAL_HALF] THEN
2035   DISCH_THEN(X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) THEN
2036   DISCH_THEN(X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC) THEN
2037   MP_TAC(ISPEC
2038    `ball(vec 0,B1) UNION ball(vec 0:real^M,B2)`
2039    BOUNDED_SUBSET_CLOSED_INTERVAL) THEN
2040   REWRITE_TAC[BOUNDED_UNION; BOUNDED_BALL; UNION_SUBSET; NOT_EXISTS_THM] THEN
2041   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
2042   DISCH_THEN(CONJUNCTS_THEN(ANTE_RES_THEN MP_TAC)) THEN
2043   DISCH_THEN(X_CHOOSE_THEN `w:real^N` STRIP_ASSUME_TAC) THEN
2044   DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
2045   SUBGOAL_THEN `w:real^N = z:real^N` SUBST_ALL_TAC THEN
2046   ASM_MESON_TAC[NORM_ARITH
2047    `~(norm(z - k1) < norm(k1 - k2) / &2 /\
2048       norm(z - k2) < norm(k1 - k2) / &2)`]);;
2049
2050 let INTEGRAL_UNIQUE = prove
2051  (`!f y k.
2052       (f has_integral y) k ==> integral k f = y`,
2053   REPEAT STRIP_TAC THEN REWRITE_TAC[integral] THEN
2054   MATCH_MP_TAC SELECT_UNIQUE THEN ASM_MESON_TAC[HAS_INTEGRAL_UNIQUE]);;
2055
2056 let HAS_INTEGRAL_INTEGRABLE_INTEGRAL = prove
2057  (`!f:real^M->real^N i s.
2058         (f has_integral i) s <=> f integrable_on s /\ integral s f = i`,
2059   MESON_TAC[INTEGRABLE_INTEGRAL; INTEGRAL_UNIQUE; integrable_on]);;
2060
2061 let INTEGRAL_EQ_HAS_INTEGRAL = prove
2062  (`!s f y. f integrable_on s ==> (integral s f = y <=> (f has_integral y) s)`,
2063   MESON_TAC[INTEGRABLE_INTEGRAL; INTEGRAL_UNIQUE]);;
2064
2065 let HAS_INTEGRAL_IS_0 = prove
2066  (`!f:real^M->real^N s.
2067         (!x. x IN s ==> (f(x) = vec 0)) ==> (f has_integral vec 0) s`,
2068   SUBGOAL_THEN
2069    `!f:real^M->real^N a b.
2070         (!x. x IN interval[a,b] ==> (f(x) = vec 0))
2071         ==> (f has_integral vec 0) (interval[a,b])`
2072   ASSUME_TAC THENL
2073    [REPEAT STRIP_TAC THEN REWRITE_TAC[has_integral] THEN
2074     REPEAT STRIP_TAC THEN EXISTS_TAC `\x:real^M. ball(x,&1)` THEN
2075     SIMP_TAC[gauge; OPEN_BALL; CENTRE_IN_BALL; REAL_LT_01] THEN
2076     REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_SUB_RZERO] THEN
2077     UNDISCH_TAC `&0 < e` THEN MATCH_MP_TAC(TAUT `(a <=> b) ==> b ==> a`) THEN
2078     AP_THM_TAC THEN AP_TERM_TAC THEN
2079     REWRITE_TAC[NORM_EQ_0; VECTOR_SUB_EQ; VECTOR_ADD_LID] THEN
2080     MATCH_MP_TAC VSUM_EQ_0 THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
2081     CONV_TAC(ONCE_DEPTH_CONV GEN_BETA_CONV) THEN
2082     X_GEN_TAC `x:real^M` THEN REPEAT STRIP_TAC THEN
2083     SUBGOAL_THEN `(x:real^M) IN interval[a,b]`
2084      (fun th -> ASM_SIMP_TAC[th; VECTOR_MUL_RZERO]) THEN
2085     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [tagged_division_of]) THEN
2086     REWRITE_TAC[tagged_partial_division_of; SUBSET] THEN ASM_MESON_TAC[];
2087     ALL_TAC] THEN
2088   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[has_integral_alt] THEN
2089   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
2090    [ASM_MESON_TAC[]; ALL_TAC] THEN
2091   GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
2092   REPEAT STRIP_TAC THEN EXISTS_TAC `vec 0:real^N` THEN
2093   ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN
2094   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]);;
2095
2096 let HAS_INTEGRAL_0 = prove
2097  (`!s. ((\x. vec 0) has_integral vec 0) s`,
2098   SIMP_TAC[HAS_INTEGRAL_IS_0]);;
2099
2100 let HAS_INTEGRAL_0_EQ = prove
2101  (`!i s. ((\x. vec 0) has_integral i) s <=> i = vec 0`,
2102   MESON_TAC[HAS_INTEGRAL_UNIQUE; HAS_INTEGRAL_0]);;
2103
2104 let HAS_INTEGRAL_LINEAR = prove
2105  (`!f:real^M->real^N y s h:real^N->real^P.
2106         (f has_integral y) s /\ linear h ==> ((h o f) has_integral h(y)) s`,
2107   SUBGOAL_THEN
2108     `!f:real^M->real^N y a b h:real^N->real^P.
2109           (f has_integral y) (interval[a,b]) /\ linear h
2110           ==> ((h o f) has_integral h(y)) (interval[a,b])`
2111   MP_TAC THENL
2112    [REPEAT GEN_TAC THEN REWRITE_TAC[has_integral] THEN STRIP_TAC THEN
2113     FIRST_ASSUM(MP_TAC o MATCH_MP LINEAR_BOUNDED_POS) THEN
2114     DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
2115     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2116     FIRST_X_ASSUM(MP_TAC o SPEC `e:real / B`) THEN
2117     ASM_SIMP_TAC[REAL_LT_DIV] THEN
2118     MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
2119     STRIP_TAC THEN ASM_SIMP_TAC[] THEN
2120     X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN
2121     FIRST_X_ASSUM(MP_TAC o SPEC `p:real^M#(real^M->bool)->bool`) THEN
2122     ASM_SIMP_TAC[REAL_LT_RDIV_EQ] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
2123     MATCH_MP_TAC(REAL_ARITH `x <= y ==> y < e ==> x < e`) THEN
2124     FIRST_ASSUM(fun th -> W(fun (asl,w) ->
2125       MP_TAC(PART_MATCH rand th (rand w)))) THEN
2126     MATCH_MP_TAC(REAL_ARITH `x <= y ==> y <= e ==> x <= e`) THEN
2127     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
2128     ASM_SIMP_TAC[LINEAR_SUB; LINEAR_VSUM; o_DEF; LAMBDA_PAIR_THM;
2129                  LINEAR_CMUL; REAL_LE_REFL];
2130     ALL_TAC] THEN
2131   DISCH_TAC THEN REPEAT GEN_TAC THEN
2132   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
2133   ONCE_REWRITE_TAC[has_integral_alt] THEN
2134   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
2135    [ASM_MESON_TAC[]; ALL_TAC] THEN
2136   DISCH_TAC THEN
2137   FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o MATCH_MP
2138     LINEAR_BOUNDED_POS) THEN
2139   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2140   FIRST_X_ASSUM(MP_TAC o SPEC `e / B:real`) THEN
2141   ASM_SIMP_TAC[REAL_LT_DIV] THEN
2142   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:real` THEN
2143   MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
2144   REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2145   MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
2146   DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
2147   EXISTS_TAC `(h:real^N->real^P) z` THEN
2148   SUBGOAL_THEN
2149    `(\x. if x IN s then ((h:real^N->real^P) o (f:real^M->real^N)) x else vec 0)
2150     = h o (\x. if x IN s then f x else vec 0)`
2151   SUBST1_TAC THENL
2152    [REWRITE_TAC[FUN_EQ_THM; o_THM] THEN ASM_MESON_TAC[LINEAR_0]; ALL_TAC] THEN
2153   ASM_SIMP_TAC[GSYM LINEAR_SUB] THEN
2154   MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `B * norm(z - y:real^N)` THEN
2155   ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
2156   ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ]);;
2157
2158 let HAS_INTEGRAL_CMUL = prove
2159  (`!(f:real^M->real^N) k s c.
2160         (f has_integral k) s
2161         ==> ((\x. c % f(x)) has_integral (c % k)) s`,
2162   REPEAT STRIP_TAC THEN MATCH_MP_TAC
2163    (REWRITE_RULE[o_DEF] HAS_INTEGRAL_LINEAR) THEN
2164   ASM_REWRITE_TAC[linear] THEN CONJ_TAC THEN VECTOR_ARITH_TAC);;
2165
2166 let HAS_INTEGRAL_NEG = prove
2167  (`!f k s. (f has_integral k) s ==> ((\x. --(f x)) has_integral (--k)) s`,
2168   ONCE_REWRITE_TAC[VECTOR_NEG_MINUS1] THEN REWRITE_TAC[HAS_INTEGRAL_CMUL]);;
2169
2170 let HAS_INTEGRAL_ADD = prove
2171  (`!f:real^M->real^N g s.
2172         (f has_integral k) s /\ (g has_integral l) s
2173         ==> ((\x. f(x) + g(x)) has_integral (k + l)) s`,
2174   SUBGOAL_THEN
2175    `!f:real^M->real^N g k l a b.
2176         (f has_integral k) (interval[a,b]) /\
2177         (g has_integral l) (interval[a,b])
2178         ==> ((\x. f(x) + g(x)) has_integral (k + l)) (interval[a,b])`
2179   ASSUME_TAC THENL
2180    [REPEAT GEN_TAC THEN REWRITE_TAC[has_integral; AND_FORALL_THM] THEN
2181     DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2182     FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
2183     DISCH_THEN(CONJUNCTS_THEN2
2184      (X_CHOOSE_THEN `d1:real^M->real^M->bool` STRIP_ASSUME_TAC)
2185      (X_CHOOSE_THEN `d2:real^M->real^M->bool` STRIP_ASSUME_TAC)) THEN
2186     EXISTS_TAC `\x. ((d1:real^M->real^M->bool) x) INTER (d2 x)` THEN
2187     ASM_SIMP_TAC[GAUGE_INTER] THEN
2188     REWRITE_TAC[tagged_division_of; tagged_partial_division_of] THEN
2189     SIMP_TAC[VSUM_ADD; VECTOR_ADD_LDISTRIB; LAMBDA_PAIR] THEN
2190     REWRITE_TAC[GSYM LAMBDA_PAIR] THEN
2191     REWRITE_TAC[GSYM tagged_partial_division_of] THEN
2192     REWRITE_TAC[GSYM tagged_division_of; FINE_INTER] THEN
2193     SIMP_TAC[VECTOR_ARITH `(a + b) - (c + d) = (a - c) + (b - d):real^N`] THEN
2194     REPEAT STRIP_TAC THEN MATCH_MP_TAC NORM_TRIANGLE_LT THEN
2195     MATCH_MP_TAC(REAL_ARITH `x < e / &2 /\ y < e / &2 ==> x + y < e`) THEN
2196     ASM_SIMP_TAC[];
2197     ALL_TAC] THEN
2198   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[has_integral_alt] THEN
2199   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
2200    [ASM_MESON_TAC[]; ALL_TAC] THEN
2201   DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2202   FIRST_X_ASSUM(CONJUNCTS_THEN (MP_TAC o SPEC `e / &2`)) THEN
2203   ASM_REWRITE_TAC[REAL_HALF] THEN
2204   DISCH_THEN(X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) THEN
2205   DISCH_THEN(X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC) THEN
2206   EXISTS_TAC `max B1 B2:real` THEN ASM_REWRITE_TAC[REAL_LT_MAX] THEN
2207   REWRITE_TAC[BALL_MAX_UNION; UNION_SUBSET] THEN
2208   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
2209   DISCH_THEN(CONJUNCTS_THEN(ANTE_RES_THEN MP_TAC)) THEN
2210   DISCH_THEN(X_CHOOSE_THEN `w:real^N` STRIP_ASSUME_TAC) THEN
2211   DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
2212   EXISTS_TAC `w + z:real^N` THEN
2213   SUBGOAL_THEN
2214     `(\x. if x IN s then (f:real^M->real^N) x + g x else vec 0) =
2215      (\x. (if x IN s then f x else vec 0) + (if x IN s then g x else vec 0))`
2216   SUBST1_TAC THENL
2217    [REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN COND_CASES_TAC THEN
2218     ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC;
2219     ALL_TAC] THEN
2220   ASM_SIMP_TAC[] THEN
2221   REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_NOT_LE])) THEN
2222   NORM_ARITH_TAC);;
2223
2224 let HAS_INTEGRAL_SUB = prove
2225  (`!f:real^M->real^N g s.
2226         (f has_integral k) s /\ (g has_integral l) s
2227         ==> ((\x. f(x) - g(x)) has_integral (k - l)) s`,
2228   SIMP_TAC[VECTOR_SUB; HAS_INTEGRAL_NEG; HAS_INTEGRAL_ADD]);;
2229
2230 let INTEGRAL_0 = prove
2231  (`!s. integral s (\x. vec 0) = vec 0`,
2232   MESON_TAC[INTEGRAL_UNIQUE; HAS_INTEGRAL_0]);;
2233
2234 let INTEGRAL_ADD = prove
2235  (`!f:real^M->real^N g k l s.
2236         f integrable_on s /\ g integrable_on s
2237         ==> integral s (\x. f x + g x) = integral s f + integral s g`,
2238   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
2239   MATCH_MP_TAC HAS_INTEGRAL_ADD THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);;
2240
2241 let INTEGRAL_CMUL = prove
2242  (`!f:real^M->real^N c s.
2243         f integrable_on s ==> integral s (\x. c % f(x)) = c % integral s f`,
2244   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
2245   MATCH_MP_TAC HAS_INTEGRAL_CMUL THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);;
2246
2247 let INTEGRAL_NEG = prove
2248  (`!f:real^M->real^N s.
2249         f integrable_on s ==> integral s (\x. --f(x)) = --integral s f`,
2250   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
2251   MATCH_MP_TAC HAS_INTEGRAL_NEG THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);;
2252
2253 let INTEGRAL_SUB = prove
2254  (`!f:real^M->real^N g k l s.
2255         f integrable_on s /\ g integrable_on s
2256         ==> integral s (\x. f x - g x) = integral s f - integral s g`,
2257   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
2258   MATCH_MP_TAC HAS_INTEGRAL_SUB THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);;
2259
2260 let INTEGRABLE_0 = prove
2261  (`!s. (\x. vec 0) integrable_on s`,
2262   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_0]);;
2263
2264 let INTEGRABLE_ADD = prove
2265  (`!f:real^M->real^N g s.
2266         f integrable_on s /\ g integrable_on s
2267         ==> (\x. f x + g x) integrable_on s`,
2268   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_ADD]);;
2269
2270 let INTEGRABLE_CMUL = prove
2271  (`!f:real^M->real^N c s.
2272         f integrable_on s ==> (\x. c % f(x)) integrable_on s`,
2273   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_CMUL]);;
2274
2275 let INTEGRABLE_NEG = prove
2276  (`!f:real^M->real^N s.
2277         f integrable_on s ==> (\x. --f(x)) integrable_on s`,
2278   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_NEG]);;
2279
2280 let INTEGRABLE_SUB = prove
2281  (`!f:real^M->real^N g s.
2282         f integrable_on s /\ g integrable_on s
2283         ==> (\x. f x - g x) integrable_on s`,
2284   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_SUB]);;
2285
2286 let INTEGRABLE_LINEAR = prove
2287  (`!f h s. f integrable_on s /\ linear h ==> (h o f) integrable_on s`,
2288   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_LINEAR]);;
2289
2290 let INTEGRAL_LINEAR = prove
2291  (`!f:real^M->real^N s h:real^N->real^P.
2292         f integrable_on s /\ linear h
2293         ==> integral s (h o f) = h(integral s f)`,
2294   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_UNIQUE THEN
2295   MAP_EVERY EXISTS_TAC
2296    [`(h:real^N->real^P) o (f:real^M->real^N)`; `s:real^M->bool`] THEN
2297   CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC HAS_INTEGRAL_LINEAR] THEN
2298   ASM_SIMP_TAC[GSYM HAS_INTEGRAL_INTEGRAL; INTEGRABLE_LINEAR]);;
2299
2300 let HAS_INTEGRAL_VSUM = prove
2301  (`!f:A->real^M->real^N s t.
2302         FINITE t /\
2303         (!a. a IN t ==> ((f a) has_integral (i a)) s)
2304         ==> ((\x. vsum t (\a. f a x)) has_integral (vsum t i)) s`,
2305   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
2306   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2307   SIMP_TAC[VSUM_CLAUSES; HAS_INTEGRAL_0; IN_INSERT] THEN
2308   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_ADD THEN
2309   ASM_REWRITE_TAC[ETA_AX] THEN CONJ_TAC THEN
2310   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[]);;
2311
2312 let INTEGRAL_VSUM = prove
2313  (`!f:A->real^M->real^N s t.
2314         FINITE t /\
2315         (!a. a IN t ==> (f a) integrable_on s)
2316         ==> integral s (\x. vsum t (\a. f a x)) =
2317                 vsum t (\a. integral s (f a))`,
2318   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
2319   MATCH_MP_TAC HAS_INTEGRAL_VSUM THEN ASM_SIMP_TAC[INTEGRABLE_INTEGRAL]);;
2320
2321 let INTEGRABLE_VSUM = prove
2322  (`!f:A->real^M->real^N s t.
2323         FINITE t /\
2324         (!a. a IN t ==> (f a) integrable_on s)
2325         ==>  (\x. vsum t (\a. f a x)) integrable_on s`,
2326   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_VSUM]);;
2327
2328 let HAS_INTEGRAL_EQ = prove
2329  (`!f:real^M->real^N g k s.
2330         (!x. x IN s ==> (f(x) = g(x))) /\
2331         (f has_integral k) s
2332         ==> (g has_integral k) s`,
2333   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
2334   DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o MATCH_MP HAS_INTEGRAL_IS_0) MP_TAC) THEN
2335   REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_SUB) THEN
2336   SIMP_TAC[VECTOR_ARITH `x - (x - y:real^N) = y`; ETA_AX; VECTOR_SUB_RZERO]);;
2337
2338 let INTEGRABLE_EQ = prove
2339  (`!f:real^M->real^N g s.
2340         (!x. x IN s ==> (f(x) = g(x))) /\
2341         f integrable_on s
2342         ==> g integrable_on s`,
2343   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_EQ]);;
2344
2345 let HAS_INTEGRAL_EQ_EQ = prove
2346  (`!f:real^M->real^N g k s.
2347         (!x. x IN s ==> (f(x) = g(x)))
2348         ==> ((f has_integral k) s <=> (g has_integral k) s)`,
2349   MESON_TAC[HAS_INTEGRAL_EQ]);;
2350
2351 let HAS_INTEGRAL_NULL = prove
2352  (`!f:real^M->real^N a b.
2353     content(interval[a,b]) = &0 ==> (f has_integral vec 0) (interval[a,b])`,
2354   REPEAT STRIP_TAC THEN REWRITE_TAC[has_integral] THEN
2355   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2356   EXISTS_TAC `\x:real^M. ball(x,&1)` THEN REWRITE_TAC[GAUGE_TRIVIAL] THEN
2357   REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_SUB_RZERO] THEN
2358   MATCH_MP_TAC(REAL_ARITH `x = &0 /\ &0 < e ==> x < e`) THEN
2359   ASM_REWRITE_TAC[NORM_EQ_0] THEN ASM_MESON_TAC[VSUM_CONTENT_NULL]);;
2360
2361 let HAS_INTEGRAL_NULL_EQ = prove
2362  (`!f a b i. content(interval[a,b]) = &0
2363              ==> ((f has_integral i) (interval[a,b]) <=> i = vec 0)`,
2364   ASM_MESON_TAC[INTEGRAL_UNIQUE; HAS_INTEGRAL_NULL]);;
2365
2366 let INTEGRAL_NULL = prove
2367  (`!f a b. content(interval[a,b]) = &0
2368            ==> integral(interval[a,b]) f = vec 0`,
2369   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
2370   ASM_MESON_TAC[HAS_INTEGRAL_NULL]);;
2371
2372 let INTEGRABLE_ON_NULL = prove
2373  (`!f a b. content(interval[a,b]) = &0
2374            ==> f integrable_on interval[a,b]`,
2375   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_NULL]);;
2376
2377 let HAS_INTEGRAL_EMPTY = prove
2378  (`!f. (f has_integral vec 0) {}`,
2379   MESON_TAC[HAS_INTEGRAL_NULL; CONTENT_EMPTY; EMPTY_AS_INTERVAL]);;
2380
2381 let HAS_INTEGRAL_EMPTY_EQ = prove
2382  (`!f i. (f has_integral i) {} <=> i = vec 0`,
2383   MESON_TAC[HAS_INTEGRAL_UNIQUE; HAS_INTEGRAL_EMPTY]);;
2384
2385 let INTEGRABLE_ON_EMPTY = prove
2386  (`!f. f integrable_on {}`,
2387   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_EMPTY]);;
2388
2389 let INTEGRAL_EMPTY = prove
2390  (`!f. integral {} f = vec 0`,
2391   MESON_TAC[EMPTY_AS_INTERVAL; INTEGRAL_UNIQUE; HAS_INTEGRAL_EMPTY]);;
2392
2393 let HAS_INTEGRAL_REFL = prove
2394  (`!f a. (f has_integral vec 0) (interval[a,a])`,
2395   REPEAT GEN_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_NULL THEN
2396   SIMP_TAC[INTERVAL_SING; INTERIOR_CLOSED_INTERVAL; CONTENT_EQ_0_INTERIOR]);;
2397
2398 let INTEGRABLE_ON_REFL = prove
2399  (`!f a. f integrable_on interval[a,a]`,
2400   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_REFL]);;
2401
2402 let INTEGRAL_REFL = prove
2403  (`!f a. integral (interval[a,a]) f = vec 0`,
2404   MESON_TAC[INTEGRAL_UNIQUE; HAS_INTEGRAL_REFL]);;
2405
2406 (* ------------------------------------------------------------------------- *)
2407 (* Cauchy-type criterion for integrability.                                  *)
2408 (* ------------------------------------------------------------------------- *)
2409
2410 let INTEGRABLE_CAUCHY = prove
2411  (`!f:real^M->real^N a b.
2412     f integrable_on interval[a,b] <=>
2413         !e. &0 < e
2414             ==> ?d. gauge d /\
2415                     !p1 p2. p1 tagged_division_of interval[a,b] /\ d fine p1 /\
2416                             p2 tagged_division_of interval[a,b] /\ d fine p2
2417                             ==> norm(vsum p1 (\(x,k). content k % f x) -
2418                                      vsum p2 (\(x,k). content k % f x)) < e`,
2419   REPEAT GEN_TAC THEN REWRITE_TAC[integrable_on; has_integral] THEN
2420   EQ_TAC THEN DISCH_TAC THENL
2421    [X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2422     FIRST_X_ASSUM(X_CHOOSE_THEN `y:real^N` (MP_TAC o SPEC `e / &2`)) THEN
2423     ASM_REWRITE_TAC[REAL_HALF] THEN MATCH_MP_TAC MONO_EXISTS THEN
2424     X_GEN_TAC `d:real^M->real^M->bool` THEN
2425     REWRITE_TAC[GSYM dist] THEN MESON_TAC[DIST_TRIANGLE_HALF_L];
2426     ALL_TAC] THEN
2427   FIRST_X_ASSUM(MP_TAC o GEN `n:num` o SPEC `inv(&n + &1)`) THEN
2428   REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`; SKOLEM_THM] THEN
2429   DISCH_THEN(X_CHOOSE_THEN `d:num->real^M->real^M->bool` MP_TAC) THEN
2430   REWRITE_TAC[FORALL_AND_THM] THEN
2431   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*")) THEN
2432   MP_TAC(GEN `n:num`
2433    (ISPECL [`\x. INTERS {(d:num->real^M->real^M->bool) i x | i IN 0..n}`;
2434             `a:real^M`; `b:real^M`]
2435      FINE_DIVISION_EXISTS)) THEN
2436   ASM_SIMP_TAC[GAUGE_INTERS; FINE_INTERS; FINITE_NUMSEG; SKOLEM_THM] THEN
2437   REWRITE_TAC[IN_NUMSEG; LE_0; FORALL_AND_THM] THEN
2438   DISCH_THEN(X_CHOOSE_THEN `p:num->(real^M#(real^M->bool))->bool`
2439     STRIP_ASSUME_TAC) THEN
2440   SUBGOAL_THEN
2441     `cauchy (\n. vsum (p n)
2442                    (\(x,k:real^M->bool). content k % (f:real^M->real^N) x))`
2443   MP_TAC THENL
2444    [REWRITE_TAC[cauchy] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2445     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [REAL_ARCH_INV]) THEN
2446     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
2447     MATCH_MP_TAC WLOG_LE THEN CONJ_TAC THENL
2448      [MESON_TAC[DIST_SYM]; ALL_TAC] THEN
2449     MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN REWRITE_TAC[GE] THEN
2450     REPEAT STRIP_TAC THEN
2451     MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `inv(&m + &1)` THEN
2452     CONJ_TAC THENL
2453      [REWRITE_TAC[dist] THEN ASM_MESON_TAC[LE_REFL]; ALL_TAC] THEN
2454     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `inv(&N)` THEN
2455     ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
2456     REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
2457     ASM_ARITH_TAC;
2458     ALL_TAC] THEN
2459   REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY; LIM_SEQUENTIALLY] THEN
2460   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `y:real^N` THEN
2461   REWRITE_TAC[dist] THEN STRIP_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2462   MP_TAC(SPEC `e / &2` REAL_ARCH_INV) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
2463   DISCH_THEN(X_CHOOSE_THEN `N1:num` STRIP_ASSUME_TAC) THEN
2464   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
2465   DISCH_THEN(X_CHOOSE_TAC `N2:num`) THEN EXISTS_TAC
2466    `(d:num->real^M->real^M->bool) (N1 + N2)` THEN
2467   ASM_REWRITE_TAC[] THEN
2468   X_GEN_TAC `q:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
2469   REWRITE_TAC[GSYM dist] THEN MATCH_MP_TAC DIST_TRIANGLE_HALF_L THEN
2470   EXISTS_TAC `vsum (p(N1+N2:num))
2471                   (\(x,k:real^M->bool). content k % (f:real^M->real^N) x)` THEN
2472   CONJ_TAC THENL
2473    [REWRITE_TAC[dist] THEN MATCH_MP_TAC REAL_LTE_TRANS THEN
2474     EXISTS_TAC `inv(&(N1 + N2) + &1)` THEN CONJ_TAC THENL
2475      [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[LE_REFL]; ALL_TAC] THEN
2476     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `inv(&N1)` THEN
2477     ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
2478     REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
2479     ASM_ARITH_TAC;
2480     ONCE_REWRITE_TAC[DIST_SYM] THEN REWRITE_TAC[dist] THEN
2481     FIRST_X_ASSUM MATCH_MP_TAC THEN ARITH_TAC]);;
2482
2483 (* ------------------------------------------------------------------------- *)
2484 (* Additivity of integral on abutting intervals.                             *)
2485 (* ------------------------------------------------------------------------- *)
2486
2487 let INTERVAL_SPLIT = prove
2488  (`!a b:real^N c k.
2489     1 <= k /\ k <= dimindex(:N)
2490     ==> interval[a,b] INTER {x | x$k <= c} =
2491         interval[a,(lambda i. if i = k then min (b$k) c else b$i)] /\
2492         interval[a,b] INTER {x | x$k >= c} =
2493         interval[(lambda i. if i = k then max (a$k) c else a$i),b]`,
2494   REPEAT STRIP_TAC THEN
2495   REWRITE_TAC[EXTENSION; IN_INTERVAL; IN_INTER; IN_ELIM_THM] THEN
2496   ASM_SIMP_TAC[LAMBDA_BETA] THEN X_GEN_TAC `y:real^N` THEN
2497   MATCH_MP_TAC(TAUT `(c ==> b) /\ (c ==> a) /\ (a /\ b ==> c)
2498                      ==> (a /\ b <=> c)`) THEN
2499   (CONJ_TAC THENL
2500     [ASM_MESON_TAC[REAL_MAX_LE; REAL_LE_MIN; real_ge];  ALL_TAC]) THEN
2501   REWRITE_TAC[LEFT_AND_FORALL_THM; real_ge] THEN CONJ_TAC THEN
2502   MATCH_MP_TAC MONO_FORALL THEN ASM_MESON_TAC[REAL_MAX_LE; REAL_LE_MIN]);;
2503
2504 let CONTENT_SPLIT = prove
2505  (`!a b:real^N k.
2506     1 <= k /\ k <= dimindex(:N)
2507     ==> content(interval[a,b]) =
2508         content(interval[a,b] INTER {x | x$k <= c}) +
2509         content(interval[a,b] INTER {x | x$k >= c})`,
2510   SIMP_TAC[INTERVAL_SPLIT; CONTENT_CLOSED_INTERVAL_CASES; LAMBDA_BETA] THEN
2511   REPEAT GEN_TAC THEN REWRITE_TAC[REAL_ARITH
2512    `((a <= if p then b else c) <=> (p ==> a <= b) /\ (~p ==> a <= c)) /\
2513     ((if p then b else c) <= a <=> (p ==> b <= a) /\ (~p ==> c <= a))`] THEN
2514   REWRITE_TAC[REAL_LE_MIN; REAL_MAX_LE] THEN
2515   REWRITE_TAC[MESON[] `(i = k ==> p i k) <=> (i = k ==> p i i)`] THEN
2516   REWRITE_TAC[TAUT `(p ==> a /\ b) /\ (~p ==> a) <=> a /\ (p ==> b)`] THEN
2517   REWRITE_TAC[TAUT `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN
2518   REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN
2519   ASM_CASES_TAC
2520    `!i. 1 <= i /\ i <= dimindex(:N) ==> (a:real^N)$i <= (b:real^N)$i` THEN
2521   ASM_REWRITE_TAC[REAL_ADD_RID] THEN
2522   REWRITE_TAC[MESON[] `(!i. P i ==> i = k ==> Q i) <=> (P k ==> Q k)`] THEN
2523   ASM_REWRITE_TAC[] THEN
2524   REWRITE_TAC[REAL_ARITH `min b c = if c <= b then c else b`;
2525               REAL_ARITH `max a c = if a <= c then c else a`] THEN
2526   REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_ADD_LID; REAL_ADD_RID]) THEN
2527   REWRITE_TAC[MESON[] `(if i = k then a k else a i) = a i`] THENL
2528    [ALL_TAC; ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL]] THEN
2529   SUBGOAL_THEN `1..dimindex(:N) = k INSERT ((1..dimindex(:N)) DELETE k)`
2530   SUBST1_TAC THENL
2531    [REWRITE_TAC[EXTENSION; IN_INSERT; IN_DELETE; IN_NUMSEG] THEN
2532     ASM_MESON_TAC[];
2533     ALL_TAC] THEN
2534   SIMP_TAC[PRODUCT_CLAUSES; FINITE_DELETE; FINITE_NUMSEG; IN_DELETE] THEN
2535   MATCH_MP_TAC(REAL_RING
2536    `p'' = p /\ p':real = p
2537     ==> (b - a) * p = (c - a) * p' + (b - c) * p''`) THEN
2538   CONJ_TAC THEN MATCH_MP_TAC PRODUCT_EQ THEN SIMP_TAC[IN_DELETE]);;
2539
2540 let DIVISION_SPLIT_LEFT_INJ,DIVISION_SPLIT_RIGHT_INJ = (CONJ_PAIR o prove)
2541  (`(!d i k1 k2 k c.
2542         d division_of i /\ 1 <= k /\ k <= dimindex(:N) /\
2543         k1 IN d /\ k2 IN d /\ ~(k1 = k2) /\
2544         k1 INTER {x | x$k <= c} = k2 INTER {x | x$k <= c}
2545         ==> content(k1 INTER {x:real^N | x$k <= c}) = &0) /\
2546    (!d i k1 k2 k c.
2547         d division_of i /\ 1 <= k /\ k <= dimindex(:N) /\
2548         k1 IN d /\ k2 IN d /\ ~(k1 = k2) /\
2549         k1 INTER {x | x$k >= c} = k2 INTER {x | x$k >= c}
2550         ==> content(k1 INTER {x:real^N | x$k >= c}) = &0)`,
2551   let lemma = prove
2552    (`!a b:real^N c k.
2553       1 <= k /\ k <= dimindex(:N)
2554       ==> (content(interval[a,b] INTER {x | x$k <= c}) = &0 <=>
2555            interior(interval[a,b] INTER {x | x$k <= c}) = {}) /\
2556           (content(interval[a,b] INTER {x | x$k >= c}) = &0 <=>
2557            interior(interval[a,b] INTER {x | x$k >= c}) = {})`,
2558     SIMP_TAC[INTERVAL_SPLIT; CONTENT_EQ_0_INTERIOR]) in
2559   REPEAT STRIP_TAC THEN
2560   REWRITE_TAC[CONTENT_EQ_0_INTERIOR] THEN
2561   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
2562   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (MP_TAC o CONJUNCT1) o CONJUNCT2) THEN
2563   DISCH_THEN(MP_TAC o SPECL
2564     [`k1:real^N->bool`; `k2:real^N->bool`]) THEN
2565   ASM_REWRITE_TAC[PAIR_EQ] THEN DISCH_TAC THEN
2566   DISCH_THEN(MP_TAC o SPEC `k2:real^N->bool`) THEN
2567   ASM_REWRITE_TAC[] THEN
2568   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
2569   DISCH_THEN(X_CHOOSE_THEN `u:real^N` (X_CHOOSE_THEN `v:real^N`
2570     SUBST_ALL_TAC)) THEN
2571   ASM_SIMP_TAC[lemma] THEN
2572   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
2573    `s INTER t = {}
2574     ==> u SUBSET s /\ u SUBSET t ==> u = {}`)) THEN
2575   CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN ASM SET_TAC[]);;
2576
2577 let TAGGED_DIVISION_SPLIT_LEFT_INJ = prove
2578  (`!d i x1 k1 x2 k2 k c.
2579         d tagged_division_of i /\ 1 <= k /\ k <= dimindex(:N) /\
2580         (x1,k1) IN d /\ (x2,k2) IN d /\ ~(k1 = k2) /\
2581         k1 INTER {x | x$k <= c} = k2 INTER {x | x$k <= c}
2582         ==> content(k1 INTER {x:real^N | x$k <= c}) = &0`,
2583   REPEAT STRIP_TAC THEN
2584   FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_TAGGED_DIVISION) THEN
2585   MATCH_MP_TAC DIVISION_SPLIT_LEFT_INJ THEN
2586   EXISTS_TAC `IMAGE SND (d:(real^N#(real^N->bool))->bool)` THEN
2587   ASM_REWRITE_TAC[IN_IMAGE] THEN ASM_MESON_TAC[SND]);;
2588
2589 let TAGGED_DIVISION_SPLIT_RIGHT_INJ = prove
2590  (`!d i x1 k1 x2 k2 k c.
2591         d tagged_division_of i /\ 1 <= k /\ k <= dimindex(:N) /\
2592         (x1,k1) IN d /\ (x2,k2) IN d /\ ~(k1 = k2) /\
2593         k1 INTER {x | x$k >= c} = k2 INTER {x | x$k >= c}
2594         ==> content(k1 INTER {x:real^N | x$k >= c}) = &0`,
2595   REPEAT STRIP_TAC THEN
2596   FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_TAGGED_DIVISION) THEN
2597   MATCH_MP_TAC DIVISION_SPLIT_RIGHT_INJ THEN
2598   EXISTS_TAC `IMAGE SND (d:(real^N#(real^N->bool))->bool)` THEN
2599   ASM_REWRITE_TAC[IN_IMAGE] THEN ASM_MESON_TAC[SND]);;
2600
2601 let DIVISION_SPLIT = prove
2602  (`!p a b:real^N k c.
2603      p division_of interval[a,b] /\ 1 <= k /\ k <= dimindex(:N)
2604      ==> {l INTER {x | x$k <= c} |l| l IN p /\ ~(l INTER {x | x$k <= c} = {})}
2605          division_of (interval[a,b] INTER {x | x$k <= c}) /\
2606          {l INTER {x | x$k >= c} |l| l IN p /\ ~(l INTER {x | x$k >= c} = {})}
2607          division_of (interval[a,b] INTER {x | x$k >= c})`,
2608   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
2609   SIMP_TAC[division_of; FINITE_IMAGE] THEN
2610   SIMP_TAC[SET_RULE `(!x. x IN {f x | P x} ==> Q x) <=> (!x. P x ==> Q (f x))`;
2611            MESON[] `(!x y. x IN s /\ y IN t /\ Q x y ==> P x y) <=>
2612                     (!x. x IN s ==> !y. y IN t ==> Q x y ==> P x y)`;
2613            RIGHT_FORALL_IMP_THM] THEN
2614   REPEAT(MATCH_MP_TAC(TAUT
2615    `(a ==> a' /\ a'') /\ (b ==> b' /\ b'')
2616       ==> a /\ b ==> (a' /\ b') /\ (a'' /\ b'')`) THEN CONJ_TAC)
2617   THENL
2618    [ONCE_REWRITE_TAC[SET_RULE
2619     `{f x |x| x IN s /\ ~(f x = {})} = {y | y IN IMAGE f s /\ ~(y = {})}`] THEN
2620     SIMP_TAC[FINITE_RESTRICT; FINITE_IMAGE];
2621     REWRITE_TAC[AND_FORALL_THM] THEN
2622     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `l:real^N->bool` THEN
2623     DISCH_THEN(fun th -> CONJ_TAC THEN STRIP_TAC THEN MP_TAC th) THEN
2624     (ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_AND THEN
2625      CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
2626      STRIP_TAC THEN ASM_MESON_TAC[INTERVAL_SPLIT]);
2627     DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
2628     (REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2629      DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
2630      REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2631      DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
2632      DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
2633      ANTS_TAC THENL [ASM_MESON_TAC[PAIR_EQ]; ALL_TAC] THEN
2634      MATCH_MP_TAC(SET_RULE
2635       `s SUBSET s' /\ t SUBSET t'
2636        ==> s' INTER t' = {} ==> s INTER t = {}`) THEN
2637      CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]);
2638    DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[INTER_UNIONS] THEN
2639    ONCE_REWRITE_TAC[EXTENSION] THEN REWRITE_TAC[IN_UNIONS] THEN
2640    CONJ_TAC THEN GEN_TAC THEN AP_TERM_TAC THEN
2641    GEN_REWRITE_TAC I [FUN_EQ_THM] THEN GEN_TAC THEN
2642    REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN MESON_TAC[NOT_IN_EMPTY]]);;
2643
2644 let HAS_INTEGRAL_SPLIT = prove
2645  (`!f:real^M->real^N k a b c.
2646       (f has_integral i) (interval[a,b] INTER {x | x$k <= c}) /\
2647       (f has_integral j) (interval[a,b] INTER {x | x$k >= c}) /\
2648       1 <= k /\ k <= dimindex(:M)
2649       ==> (f has_integral (i + j)) (interval[a,b])`,
2650   let lemma1 = prove
2651    (`(!x k. (x,k) IN {x,f k | P x k} ==> Q x k) <=>
2652      (!x k. P x k ==> Q x (f k))`,
2653     REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN
2654     SET_TAC[]) in
2655   let lemma2 = prove
2656    (`!f:B->B s:(A#B)->bool.
2657       FINITE s ==> FINITE {x,f k | (x,k) IN s /\ P x k}`,
2658     REPEAT STRIP_TAC THEN MATCH_MP_TAC FINITE_SUBSET THEN
2659     EXISTS_TAC `IMAGE (\(x:A,k:B). x,(f k:B)) s` THEN
2660     ASM_SIMP_TAC[FINITE_IMAGE] THEN
2661     REWRITE_TAC[SUBSET; FORALL_PAIR_THM; lemma1; IN_IMAGE] THEN
2662     REWRITE_TAC[EXISTS_PAIR_THM; PAIR_EQ] THEN MESON_TAC[]) in
2663   let lemma3 = prove
2664    (`!f:real^M->real^N g:(real^M->bool)->(real^M->bool) p.
2665      FINITE p
2666      ==> vsum {x,g k |x,k| (x,k) IN p /\ ~(g k = {})}
2667               (\(x,k). content k % f x) =
2668          vsum (IMAGE (\(x,k). x,g k) p) (\(x,k). content k % f x)`,
2669     REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN
2670     ASM_SIMP_TAC[FINITE_IMAGE; lemma2] THEN
2671     REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE] THEN
2672     REWRITE_TAC[FORALL_PAIR_THM; SUBSET; IN_IMAGE; EXISTS_PAIR_THM] THEN
2673     REWRITE_TAC[IN_ELIM_THM; PAIR_EQ; VECTOR_MUL_EQ_0] THEN
2674     MESON_TAC[CONTENT_EMPTY]) in
2675   let lemma4 = prove
2676    (`(\(x,l). content (g l) % f x) =
2677      (\(x,l). content l % f x) o (\(x,l). x,g l)`,
2678     REWRITE_TAC[FUN_EQ_THM; o_THM; FORALL_PAIR_THM]) in
2679   REPEAT GEN_TAC THEN
2680   ASM_CASES_TAC `1 <= k /\ k <= dimindex(:M)` THEN ASM_REWRITE_TAC[] THEN
2681   ASM_SIMP_TAC[INTERVAL_SPLIT] THEN REWRITE_TAC[has_integral] THEN
2682   ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THEN FIRST_X_ASSUM STRIP_ASSUME_TAC THEN
2683   DISCH_TAC THEN X_GEN_TAC `e:real` THEN STRIP_TAC THEN
2684   FIRST_X_ASSUM(CONJUNCTS_THEN2 (MP_TAC o SPEC `e / &2`) STRIP_ASSUME_TAC) THEN
2685   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
2686   DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool`
2687    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "I2"))) THEN
2688   DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool`
2689    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "I1"))) THEN
2690   EXISTS_TAC `\x. if x$k = c then (d1(x:real^M) INTER d2(x)):real^M->bool
2691                   else ball(x,abs(x$k - c)) INTER d1(x) INTER d2(x)` THEN
2692   CONJ_TAC THENL
2693    [REWRITE_TAC[gauge] THEN GEN_TAC THEN
2694     RULE_ASSUM_TAC(REWRITE_RULE[gauge]) THEN COND_CASES_TAC THEN
2695     ASM_SIMP_TAC[OPEN_INTER; IN_INTER; OPEN_BALL; IN_BALL] THEN
2696     ASM_REWRITE_TAC[DIST_REFL; GSYM REAL_ABS_NZ; REAL_SUB_0];
2697     ALL_TAC] THEN
2698   X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
2699   SUBGOAL_THEN
2700     `(!x:real^M kk. (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k <= c} = {})
2701                     ==> x$k <= c) /\
2702      (!x:real^M kk. (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k >= c} = {})
2703                     ==> x$k >= c)`
2704   STRIP_ASSUME_TAC THENL
2705    [CONJ_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
2706     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
2707     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `kk:real^M->bool` THEN
2708     DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
2709     COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL; real_ge] THEN DISCH_THEN
2710      (MP_TAC o MATCH_MP (SET_RULE `k SUBSET (a INTER b) ==> k SUBSET a`)) THEN
2711     REWRITE_TAC[SUBSET; IN_BALL; dist] THEN DISCH_TAC THEN
2712     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
2713     DISCH_THEN(X_CHOOSE_THEN `u:real^M` MP_TAC) THEN
2714     REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
2715     FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M`) THEN ASM_REWRITE_TAC[] THEN
2716     ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
2717     REWRITE_TAC[REAL_NOT_LE; REAL_NOT_LT] THEN STRIP_TAC THEN
2718     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((x - u:real^M)$k)` THEN
2719     ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
2720     ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
2721     ASM_REAL_ARITH_TAC;
2722     ALL_TAC] THEN
2723   REMOVE_THEN "I2" (MP_TAC o SPEC
2724    `{(x:real^M,kk INTER {x:real^M | x$k >= c}) |x,kk|
2725      (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k >= c} = {})}`) THEN
2726   REMOVE_THEN "I1" (MP_TAC o SPEC
2727    `{(x:real^M,kk INTER {x:real^M | x$k <= c}) |x,kk|
2728      (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k <= c} = {})}`) THEN
2729   MATCH_MP_TAC(TAUT
2730    `(a /\ b) /\ (a' /\ b' ==> c) ==> (a ==> a') ==> (b ==> b') ==> c`) THEN
2731   CONJ_TAC THENL
2732    [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
2733     REWRITE_TAC[TAGGED_DIVISION_OF] THEN
2734     REPEAT(MATCH_MP_TAC(TAUT
2735      `(a ==> (a' /\ a'')) /\ (b ==> (b' /\ d) /\ (b'' /\ e))
2736       ==> a /\ b ==> ((a' /\ b') /\ d) /\ ((a'' /\ b'') /\ e)`) THEN
2737       CONJ_TAC) THEN
2738     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
2739     REWRITE_TAC[lemma1] THEN REWRITE_TAC[IMP_IMP] THENL
2740      [SIMP_TAC[lemma2];
2741       REWRITE_TAC[AND_FORALL_THM] THEN
2742       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
2743       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `kk:real^M->bool` THEN
2744       DISCH_THEN(fun th -> CONJ_TAC THEN STRIP_TAC THEN MP_TAC th) THEN
2745       (ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
2746         [SIMP_TAC[IN_INTER; IN_ELIM_THM] THEN ASM_MESON_TAC[]; ALL_TAC]) THEN
2747       (MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL [SET_TAC[]; ALL_TAC]) THEN
2748       ASM_MESON_TAC[INTERVAL_SPLIT];
2749       DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
2750       (REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2751        DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
2752        REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2753        DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
2754        ANTS_TAC THENL [ASM_MESON_TAC[PAIR_EQ]; ALL_TAC] THEN
2755        MATCH_MP_TAC(SET_RULE
2756         `s SUBSET s' /\ t SUBSET t'
2757          ==> s' INTER t' = {} ==> s INTER t = {}`) THEN
2758        CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]);
2759       ALL_TAC] THEN
2760     MATCH_MP_TAC(TAUT `(a ==> b /\ c) /\ d /\ e
2761                        ==> (a ==> (b /\ d) /\ (c /\ e))`) THEN
2762     CONJ_TAC THENL
2763      [DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
2764       DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[INTER_UNIONS] THEN
2765       ONCE_REWRITE_TAC[EXTENSION] THEN REWRITE_TAC[IN_UNIONS] THEN
2766       X_GEN_TAC `x:real^M` THEN AP_TERM_TAC THEN
2767       GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `kk:real^M->bool` THEN
2768       REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN MESON_TAC[NOT_IN_EMPTY];
2769       ALL_TAC] THEN
2770     CONJ_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
2771     REWRITE_TAC[fine; lemma1] THEN
2772     REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
2773     DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
2774     ASM_SIMP_TAC[] THEN SET_TAC[];
2775     ALL_TAC] THEN
2776   DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH
2777    `x < e / &2 /\ y < e / &2 ==> x + y < e`)) THEN
2778   DISCH_THEN(MP_TAC o MATCH_MP NORM_TRIANGLE_LT) THEN
2779   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
2780   REWRITE_TAC[VECTOR_ARITH
2781    `(a - i) + (b - j) = c - (i + j) <=> a + b = c:real^N`] THEN
2782   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
2783  MATCH_MP_TAC EQ_TRANS THEN
2784   EXISTS_TAC
2785    `vsum p (\(x,l). content (l INTER {x:real^M | x$k <= c}) %
2786                      (f:real^M->real^N) x) +
2787     vsum p (\(x,l). content (l INTER {x:real^M | x$k >= c}) %
2788                      (f:real^M->real^N) x)` THEN
2789   CONJ_TAC THENL
2790    [ALL_TAC;
2791     ASM_SIMP_TAC[GSYM VSUM_ADD] THEN MATCH_MP_TAC VSUM_EQ THEN
2792     REWRITE_TAC[FORALL_PAIR_THM; GSYM VECTOR_ADD_RDISTRIB] THEN
2793     MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
2794     DISCH_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
2795     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
2796     DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `l:real^M->bool`] o
2797                el 1 o CONJUNCTS) THEN
2798     ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
2799     ASM_SIMP_TAC[GSYM CONTENT_SPLIT]] THEN
2800   ASM_SIMP_TAC[lemma3] THEN BINOP_TAC THEN
2801   (GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [lemma4] THEN
2802    MATCH_MP_TAC VSUM_IMAGE_NONZERO THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
2803    REWRITE_TAC[PAIR_EQ] THEN
2804    ASM_MESON_TAC[TAGGED_DIVISION_SPLIT_LEFT_INJ; VECTOR_MUL_LZERO;
2805                  TAGGED_DIVISION_SPLIT_RIGHT_INJ]));;
2806
2807 (* ------------------------------------------------------------------------- *)
2808 (* A sort of converse, integrability on subintervals.                        *)
2809 (* ------------------------------------------------------------------------- *)
2810
2811 let TAGGED_DIVISION_UNION_INTERVAL = prove
2812  (`!a b:real^N p1 p2 c k.
2813         1 <= k /\ k <= dimindex(:N) /\
2814         p1 tagged_division_of (interval[a,b] INTER {x | x$k <= c}) /\
2815         p2 tagged_division_of (interval[a,b] INTER {x | x$k >= c})
2816         ==> (p1 UNION p2) tagged_division_of (interval[a,b])`,
2817   REPEAT STRIP_TAC THEN SUBGOAL_THEN
2818    `interval[a,b] = (interval[a,b] INTER {x:real^N | x$k <= c}) UNION
2819                     (interval[a,b] INTER {x:real^N | x$k >= c})`
2820   SUBST1_TAC THENL
2821    [MATCH_MP_TAC(SET_RULE
2822      `(t UNION u = UNIV) ==> s = (s INTER t) UNION (s INTER u)`) THEN
2823     REWRITE_TAC[EXTENSION; IN_UNIV; IN_UNION; IN_ELIM_THM] THEN REAL_ARITH_TAC;
2824     ALL_TAC] THEN
2825   MATCH_MP_TAC TAGGED_DIVISION_UNION THEN ASM_REWRITE_TAC[] THEN
2826   ASM_SIMP_TAC[INTERVAL_SPLIT; INTERIOR_CLOSED_INTERVAL] THEN
2827   REWRITE_TAC[EXTENSION; IN_INTER; NOT_IN_EMPTY; IN_INTERVAL] THEN
2828   GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN (MP_TAC o SPEC `k:num`)) THEN
2829     ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC);;
2830
2831 let HAS_INTEGRAL_SEPARATE_SIDES = prove
2832  (`!f:real^M->real^N i a b k.
2833         (f has_integral i) (interval[a,b]) /\
2834         1 <= k /\ k <= dimindex(:M)
2835         ==> !e. &0 < e
2836                 ==> ?d. gauge d /\
2837                         !p1 p2. p1 tagged_division_of
2838                                      (interval[a,b] INTER {x | x$k <= c}) /\
2839                                 d fine p1 /\
2840                                 p2 tagged_division_of
2841                                      (interval[a,b] INTER {x | x$k >= c}) /\
2842                                 d fine p2
2843                                 ==> norm((vsum p1 (\(x,k). content k % f x) +
2844                                           vsum p2 (\(x,k). content k % f x)) -
2845                                          i) < e`,
2846   REWRITE_TAC[has_integral] THEN REPEAT GEN_TAC THEN
2847   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
2848   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
2849   ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
2850   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
2851   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
2852   SUBGOAL_THEN
2853    `vsum p1 (\(x,k). content k % f x) + vsum p2 (\(x,k). content k % f x) =
2854     vsum (p1 UNION p2) (\(x,k:real^M->bool). content k % (f:real^M->real^N) x)`
2855   SUBST1_TAC THENL
2856    [ALL_TAC; ASM_MESON_TAC[TAGGED_DIVISION_UNION_INTERVAL; FINE_UNION]] THEN
2857   CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_UNION_NONZERO THEN
2858   REPEAT(FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I
2859    [TAGGED_DIVISION_OF])) THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
2860   MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
2861   REWRITE_TAC[IN_INTER; VECTOR_MUL_EQ_0] THEN STRIP_TAC THEN DISJ1_TAC THEN
2862   SUBGOAL_THEN
2863    `(?a b:real^M. l = interval[a,b]) /\
2864     l SUBSET (interval[a,b] INTER {x | x$k <= c}) /\
2865     l SUBSET (interval[a,b] INTER {x | x$k >= c})`
2866   MP_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
2867   DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
2868   ASM_REWRITE_TAC[SET_RULE
2869    `s SUBSET t /\ s SUBSET u <=> s SUBSET (t INTER u)`] THEN
2870   ASM_SIMP_TAC[INTERVAL_SPLIT; INTER_INTERVAL] THEN
2871   DISCH_THEN(MP_TAC o MATCH_MP SUBSET_INTERIOR) THEN
2872   REWRITE_TAC[INTERIOR_CLOSED_INTERVAL; CONTENT_EQ_0_INTERIOR] THEN
2873   MATCH_MP_TAC(SET_RULE `t = {} ==> s SUBSET t ==> s = {}`) THEN
2874   REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN EXISTS_TAC `k:num` THEN
2875   ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC);;
2876
2877 let INTEGRABLE_SPLIT = prove
2878  (`!f:real^M->real^N a b.
2879         f integrable_on (interval[a,b]) /\ 1 <= k /\ k <= dimindex(:M)
2880         ==> f integrable_on (interval[a,b] INTER {x | x$k <= c}) /\
2881             f integrable_on (interval[a,b] INTER {x | x$k >= c})`,
2882   let lemma = prove
2883    (`b - a = c
2884      ==> norm(a:real^N) < e / &2 ==> norm(b) < e / &2 ==> norm(c) < e`,
2885     DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[GSYM dist] THEN
2886     REPEAT STRIP_TAC THEN MATCH_MP_TAC DIST_TRIANGLE_HALF_L THEN
2887     EXISTS_TAC `vec 0:real^N` THEN
2888     ASM_REWRITE_TAC[dist; VECTOR_SUB_LZERO; VECTOR_SUB_RZERO; NORM_NEG]) in
2889   REPEAT GEN_TAC THEN
2890   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [integrable_on] THEN
2891   REWRITE_TAC[LEFT_IMP_EXISTS_THM; LEFT_AND_EXISTS_THM] THEN
2892   X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN CONJ_TAC THEN
2893   ASM_SIMP_TAC[INTERVAL_SPLIT; INTEGRABLE_CAUCHY] THEN
2894   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
2895   FIRST_ASSUM(MP_TAC o SPEC `e / &2` o
2896     MATCH_MP HAS_INTEGRAL_SEPARATE_SIDES) THEN
2897   MAP_EVERY ABBREV_TAC
2898    [`b' = (lambda i. if i = k then min ((b:real^M)$k) c else b$i):real^M`;
2899     `a' = (lambda i. if i = k then max ((a:real^M)$k) c else a$i):real^M`] THEN
2900   ASM_SIMP_TAC[REAL_HALF; INTERVAL_SPLIT] 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
2903   FIRST_ASSUM(MP_TAC o MATCH_MP FINE_DIVISION_EXISTS) THENL
2904    [DISCH_THEN(MP_TAC o SPECL [`a':real^M`; `b:real^M`]) THEN
2905     RULE_ASSUM_TAC(ONCE_REWRITE_RULE[SWAP_FORALL_THM]);
2906     DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b':real^M`])] THEN
2907   DISCH_THEN(X_CHOOSE_THEN `p:(real^M#(real^M->bool))->bool`
2908     STRIP_ASSUME_TAC) THEN
2909   REPEAT STRIP_TAC THEN FIRST_X_ASSUM(fun th ->
2910     MP_TAC(SPECL [`p:(real^M#(real^M->bool))->bool`;
2911                   `p1:(real^M#(real^M->bool))->bool`] th) THEN
2912     MP_TAC(SPECL [`p:(real^M#(real^M->bool))->bool`;
2913                   `p2:(real^M#(real^M->bool))->bool`] th)) THEN
2914   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC lemma THEN VECTOR_ARITH_TAC);;
2915
2916 (* ------------------------------------------------------------------------- *)
2917 (* Generalized notion of additivity.                                         *)
2918 (* ------------------------------------------------------------------------- *)
2919
2920 let operative = new_definition
2921  `operative op (f:(real^N->bool)->A) <=>
2922     (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = neutral(op)) /\
2923     (!a b c k. 1 <= k /\ k <= dimindex(:N)
2924                ==> f(interval[a,b]) =
2925                    op (f(interval[a,b] INTER {x | x$k <= c}))
2926                       (f(interval[a,b] INTER {x | x$k >= c})))`;;
2927
2928 let OPERATIVE_TRIVIAL = prove
2929  (`!op f a b.
2930         operative op f /\ content(interval[a,b]) = &0
2931         ==> f(interval[a,b]) = neutral op`,
2932   REWRITE_TAC[operative] THEN MESON_TAC[]);;
2933
2934 let PROPERTY_EMPTY_INTERVAL = prove
2935  (`!P. (!a b:real^N. content(interval[a,b]) = &0 ==> P(interval[a,b]))
2936        ==> P {}`,
2937   MESON_TAC[EMPTY_AS_INTERVAL; CONTENT_EMPTY]);;
2938
2939 let OPERATIVE_EMPTY = prove
2940  (`!op f:(real^N->bool)->A. operative op f ==> f {} = neutral op`,
2941   REPEAT GEN_TAC THEN REWRITE_TAC[operative] THEN
2942   DISCH_THEN(ACCEPT_TAC o MATCH_MP PROPERTY_EMPTY_INTERVAL o CONJUNCT1));;
2943
2944 (* ------------------------------------------------------------------------- *)
2945 (* Using additivity of lifted function to encode definedness.                *)
2946 (* ------------------------------------------------------------------------- *)
2947
2948 let FORALL_OPTION = prove
2949  (`(!x. P x) <=> P NONE /\ !x. P(SOME x)`,
2950   MESON_TAC[cases "option"]);;
2951
2952 let EXISTS_OPTION = prove
2953  (`(?x. P x) <=> P NONE \/ ?x. P(SOME x)`,
2954   MESON_TAC[cases "option"]);;
2955
2956 let lifted = define
2957  `(lifted op NONE _ = NONE) /\
2958   (lifted op _ NONE = NONE) /\
2959   (lifted op (SOME x) (SOME y) = SOME(op x y))`;;
2960
2961 let NEUTRAL_LIFTED = prove
2962  (`!op. monoidal op ==> neutral(lifted op) = SOME(neutral op)`,
2963   REWRITE_TAC[neutral; monoidal] THEN REPEAT STRIP_TAC THEN
2964   MATCH_MP_TAC SELECT_UNIQUE THEN
2965   REWRITE_TAC[FORALL_OPTION; lifted; distinctness "option";
2966               injectivity "option"] THEN
2967   ASM_MESON_TAC[]);;
2968
2969 let MONOIDAL_LIFTED = prove
2970  (`!op. monoidal op ==> monoidal(lifted op)`,
2971   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[NEUTRAL_LIFTED; monoidal] THEN
2972   REWRITE_TAC[FORALL_OPTION; lifted; distinctness "option";
2973               injectivity "option"] THEN
2974   ASM_MESON_TAC[monoidal]);;
2975
2976 let ITERATE_SOME = prove
2977  (`!op. monoidal op
2978         ==> !f s. FINITE s
2979                   ==> iterate (lifted op) s (\x. SOME(f x)) =
2980                       SOME(iterate op s f)`,
2981   GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
2982   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
2983   ASM_SIMP_TAC[ITERATE_CLAUSES; MONOIDAL_LIFTED; NEUTRAL_LIFTED] THEN
2984   REWRITE_TAC[lifted]);;
2985
2986 (* ------------------------------------------------------------------------- *)
2987 (* Two key instances of additivity.                                          *)
2988 (* ------------------------------------------------------------------------- *)
2989
2990 let OPERATIVE_CONTENT = prove
2991  (`operative(+) content`,
2992   REWRITE_TAC[operative; NEUTRAL_REAL_ADD; CONTENT_SPLIT]);;
2993
2994 let OPERATIVE_INTEGRAL = prove
2995  (`!f:real^M->real^N.
2996        operative(lifted(+))
2997          (\i. if f integrable_on i then SOME(integral i f) else NONE)`,
2998   SIMP_TAC[operative; NEUTRAL_LIFTED; MONOIDAL_VECTOR_ADD] THEN
2999   REWRITE_TAC[NEUTRAL_VECTOR_ADD] THEN
3000   REPEAT STRIP_TAC THEN REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN
3001   REWRITE_TAC[lifted; distinctness "option"; injectivity "option"] THENL
3002    [REWRITE_TAC[integral] THEN ASM_MESON_TAC[HAS_INTEGRAL_NULL_EQ];
3003     RULE_ASSUM_TAC(REWRITE_RULE[integrable_on]) THEN
3004     ASM_MESON_TAC[HAS_INTEGRAL_NULL];
3005     REPEAT(FIRST_X_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL)) THEN
3006     ASM_MESON_TAC[HAS_INTEGRAL_SPLIT; HAS_INTEGRAL_UNIQUE];
3007     ASM_MESON_TAC[INTEGRABLE_SPLIT; integrable_on];
3008     ASM_MESON_TAC[INTEGRABLE_SPLIT];
3009     ASM_MESON_TAC[INTEGRABLE_SPLIT];
3010     RULE_ASSUM_TAC(REWRITE_RULE[integrable_on]) THEN
3011     ASM_MESON_TAC[HAS_INTEGRAL_SPLIT]]);;
3012
3013 (* ------------------------------------------------------------------------- *)
3014 (* Points of division of a partition.                                        *)
3015 (* ------------------------------------------------------------------------- *)
3016
3017 let division_points = new_definition
3018  `division_points (k:real^N->bool) (d:(real^N->bool)->bool) =
3019     {j,x | 1 <= j /\ j <= dimindex(:N) /\
3020            (interval_lowerbound k)$j < x /\ x < (interval_upperbound k)$j /\
3021            ?i. i IN d /\
3022                ((interval_lowerbound i)$j = x \/
3023                 (interval_upperbound i)$j = x)}`;;
3024
3025 let DIVISION_POINTS_FINITE = prove
3026  (`!d i:real^N->bool. d division_of i ==> FINITE(division_points i d)`,
3027   REWRITE_TAC[division_of; division_points] THEN
3028   REPEAT STRIP_TAC THEN REWRITE_TAC[CONJ_ASSOC; GSYM IN_NUMSEG] THEN
3029   REWRITE_TAC[IN; GSYM CONJ_ASSOC] THEN
3030   MATCH_MP_TAC(REWRITE_RULE[IN] FINITE_PRODUCT_DEPENDENT) THEN
3031   REWRITE_TAC[ETA_AX; FINITE_NUMSEG] THEN
3032   X_GEN_TAC `j:num` THEN GEN_REWRITE_TAC LAND_CONV [GSYM IN] THEN
3033   REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN
3034   MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC
3035    `IMAGE (\i:real^N->bool. (interval_lowerbound i)$j) d UNION
3036     IMAGE (\i:real^N->bool. (interval_upperbound i)$j) d` THEN
3037   ASM_SIMP_TAC[FINITE_UNION; FINITE_IMAGE] THEN
3038   REWRITE_TAC[SUBSET; IN_IMAGE; IN_UNION; IN_ELIM_THM] THEN MESON_TAC[IN]);;
3039
3040 let DIVISION_POINTS_SUBSET = prove
3041  (`!a b:real^N c d k.
3042         d division_of interval[a,b] /\
3043         (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i) /\
3044         1 <= k /\ k <= dimindex(:N) /\ a$k < c /\ c < b$k
3045         ==> division_points (interval[a,b] INTER {x | x$k <= c})
3046                             {l INTER {x | x$k <= c} | l |
3047                              l IN d /\ ~(l INTER {x | x$k <= c} = {})}
3048             SUBSET division_points (interval[a,b]) d /\
3049             division_points (interval[a,b] INTER {x | x$k >= c})
3050                             {l INTER {x | x$k >= c} | l |
3051                              l IN d /\ ~(l INTER {x | x$k >= c} = {})}
3052             SUBSET division_points (interval[a,b]) d`,
3053   REPEAT STRIP_TAC THEN
3054   (REWRITE_TAC[SUBSET; division_points; FORALL_PAIR_THM] THEN
3055    MAP_EVERY X_GEN_TAC [`j:num`; `x:real`] THEN
3056    REWRITE_TAC[IN_ELIM_PAIR_THM] THEN REWRITE_TAC[IN_ELIM_THM] THEN
3057    ASM_SIMP_TAC[INTERVAL_SPLIT; INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND;
3058                 REAL_LT_IMP_LE] THEN
3059    ASM_SIMP_TAC[REAL_ARITH `a < c ==> max a c = c`;
3060                 REAL_ARITH `c < b ==> min b c = c`] THEN
3061    REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
3062    ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; LAMBDA_BETA;
3063      REAL_LT_IMP_LE; COND_ID;
3064      TAUT `(a <= if p then x else y) <=> (if p then a <= x else a <= y)`;
3065      TAUT `(if p then x else y) <= a <=> (if p then x <= a else y <= a)`] THEN
3066    REPLICATE_TAC 2 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
3067    DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THENL
3068     [DISCH_THEN(K ALL_TAC) THEN REPEAT(POP_ASSUM MP_TAC) THEN
3069      COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC;
3070      ALL_TAC] THEN
3071    REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN
3072    MATCH_MP_TAC MONO_EXISTS THEN
3073    ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c <=> b /\ a /\ c`] THEN
3074    REWRITE_TAC[UNWIND_THM2] THEN SIMP_TAC[GSYM CONJ_ASSOC] THEN
3075    ONCE_REWRITE_TAC[IMP_CONJ] THEN
3076    FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
3077    MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN DISCH_TAC THEN
3078    ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
3079    SUBGOAL_THEN
3080     `!i. 1 <= i /\ i <= dimindex(:N) ==> (u:real^N)$i <= (v:real^N)$i`
3081    ASSUME_TAC THENL
3082     [REWRITE_TAC[GSYM INTERVAL_NE_EMPTY] THEN ASM_MESON_TAC[division_of];
3083      ALL_TAC] THEN
3084    REWRITE_TAC[INTERVAL_NE_EMPTY] THEN
3085    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
3086    ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND] THEN
3087    ASM_SIMP_TAC[LAMBDA_BETA] THEN REPEAT(POP_ASSUM MP_TAC) THEN
3088    COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC));;
3089
3090 let DIVISION_POINTS_PSUBSET = prove
3091  (`!a b:real^N c d k.
3092         d division_of interval[a,b] /\
3093         (!i. 1 <= i /\ i <= dimindex(:N) ==> a$i < b$i) /\
3094         1 <= k /\ k <= dimindex(:N) /\ a$k < c /\ c < b$k /\
3095         (?l. l IN d /\
3096              (interval_lowerbound l$k = c \/ interval_upperbound l$k = c))
3097         ==> division_points (interval[a,b] INTER {x | x$k <= c})
3098                             {l INTER {x | x$k <= c} | l |
3099                              l IN d /\ ~(l INTER {x | x$k <= c} = {})}
3100             PSUBSET division_points (interval[a,b]) d /\
3101             division_points (interval[a,b] INTER {x | x$k >= c})
3102                             {l INTER {x | x$k >= c} | l |
3103                              l IN d /\ ~(l INTER {x | x$k >= c} = {})}
3104             PSUBSET division_points (interval[a,b]) d`,
3105   REPEAT STRIP_TAC THEN
3106   ASM_SIMP_TAC[PSUBSET_MEMBER; DIVISION_POINTS_SUBSET] THENL
3107    [EXISTS_TAC `k,(interval_lowerbound l:real^N)$k`;
3108     EXISTS_TAC `k,(interval_lowerbound l:real^N)$k`;
3109     EXISTS_TAC `k,(interval_upperbound l:real^N)$k`;
3110     EXISTS_TAC `k,(interval_upperbound l:real^N)$k`] THEN
3111   ASM_REWRITE_TAC[division_points; IN_ELIM_PAIR_THM] THEN
3112   ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND; REAL_LT_IMP_LE] THEN
3113   (CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC]) THEN
3114   ASM_SIMP_TAC[INTERVAL_SPLIT; INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND;
3115                REAL_LT_IMP_LE] THEN
3116   ASM_SIMP_TAC[REAL_ARITH `a < c ==> max a c = c`;
3117                REAL_ARITH `c < b ==> min b c = c`] THEN
3118   ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; LAMBDA_BETA;
3119     REAL_LT_IMP_LE; COND_ID;
3120     TAUT `(a <= if p then x else y) <=> (if p then a <= x else a <= y)`;
3121     TAUT `(if p then x else y) <= a <=> (if p then x <= a else y <= a)`] THEN
3122   REWRITE_TAC[REAL_LT_REFL]);;
3123
3124 (* ------------------------------------------------------------------------- *)
3125 (* Preservation by divisions and tagged divisions.                           *)
3126 (* ------------------------------------------------------------------------- *)
3127
3128 let OPERATIVE_DIVISION = prove
3129  (`!op d a b f:(real^N->bool)->A.
3130     monoidal op /\ operative op f /\ d division_of interval[a,b]
3131     ==> iterate(op) d f = f(interval[a,b])`,
3132   REPEAT GEN_TAC THEN CONV_TAC(RAND_CONV SYM_CONV) THEN WF_INDUCT_TAC
3133    `CARD (division_points (interval[a,b]:real^N->bool) d)` THEN
3134   POP_ASSUM(fun th -> REPEAT STRIP_TAC THEN MP_TAC th) THEN
3135   ASM_REWRITE_TAC[] THEN
3136   ASM_CASES_TAC `content(interval[a:real^N,b]) = &0` THENL
3137    [SUBGOAL_THEN `iterate op d (f:(real^N->bool)->A) = neutral op`
3138      (fun th -> ASM_MESON_TAC[th; operative]) THEN
3139     MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
3140      ITERATE_EQ_NEUTRAL) THEN
3141     FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
3142     ASM_MESON_TAC[operative; DIVISION_OF_CONTENT_0];
3143     ALL_TAC] THEN
3144   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM CONTENT_LT_NZ]) THEN
3145   REWRITE_TAC[CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
3146   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
3147   ASM_CASES_TAC `division_points (interval[a,b]:real^N->bool) d = {}` THENL
3148    [DISCH_THEN(K ALL_TAC) THEN
3149     SUBGOAL_THEN
3150      `!i. i IN d
3151           ==> ?u v:real^N. i = interval[u,v] /\
3152                            !j. 1 <= j /\ j <= dimindex(:N)
3153                                ==> u$j = (a:real^N)$j /\ v$j = a$j \/
3154                                    u$j = (b:real^N)$j /\ v$j = b$j \/
3155                                    u$j = a$j /\ v$j = b$j`
3156     (LABEL_TAC "*") THENL
3157      [FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
3158       MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN DISCH_TAC THEN
3159       MAP_EVERY EXISTS_TAC [`u:real^N`; `v:real^N`] THEN REWRITE_TAC[] THEN
3160       REPEAT STRIP_TAC THEN
3161       FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
3162       ASM_REWRITE_TAC[] THEN
3163       DISCH_THEN(MP_TAC o SPEC `interval[u:real^N,v]` o CONJUNCT1) THEN
3164       ASM_REWRITE_TAC[INTERVAL_NE_EMPTY] THEN
3165       DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (ASSUME_TAC o CONJUNCT1)) THEN
3166       ASM_REWRITE_TAC[SUBSET_INTERVAL] THEN STRIP_TAC THEN
3167       MATCH_MP_TAC(REAL_ARITH
3168        `a <= u /\ u <= v /\ v <= b /\ ~(a < u /\ u < b \/ a < v /\ v < b)
3169         ==> u = a /\ v = a \/ u = b /\ v = b \/ u = a /\ v = b`) THEN
3170       ASM_SIMP_TAC[] THEN DISCH_TAC THEN
3171       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
3172       REWRITE_TAC[division_points; NOT_IN_EMPTY; FORALL_PAIR_THM] THEN
3173       REWRITE_TAC[IN_ELIM_PAIR_THM] THEN DISCH_THEN(MP_TAC o SPEC `j:num`) THEN
3174       ASM_REWRITE_TAC[] THEN REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN
3175       REWRITE_TAC[NOT_EXISTS_THM] THEN ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
3176       DISCH_THEN(MP_TAC o SPEC `interval[u:real^N,v]`) THEN
3177       ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND;
3178                    REAL_LT_IMP_LE] THEN
3179       DISCH_THEN(fun th ->
3180         MP_TAC(SPEC `(u:real^N)$j` th) THEN
3181         MP_TAC(SPEC `(v:real^N)$j` th)) THEN
3182       FIRST_X_ASSUM(DISJ_CASES_THEN MP_TAC) THEN REAL_ARITH_TAC;
3183       ALL_TAC] THEN
3184     SUBGOAL_THEN `interval[a:real^N,b] IN d` MP_TAC THENL
3185      [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
3186       ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o last o CONJUNCTS) THEN
3187       REWRITE_TAC[EXTENSION; IN_INTERVAL; IN_UNIONS] THEN
3188       DISCH_THEN(MP_TAC o SPEC `inv(&2) % (a + b:real^N)`) THEN
3189       MATCH_MP_TAC(TAUT `b /\ (a ==> c) ==> (a <=> b) ==> c`) THEN
3190       CONJ_TAC THENL
3191        [SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
3192         X_GEN_TAC `j:num` THEN STRIP_TAC THEN
3193         FIRST_X_ASSUM(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN
3194         REAL_ARITH_TAC;
3195         ALL_TAC] THEN
3196       DISCH_THEN(X_CHOOSE_THEN `i:real^N->bool`
3197        (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
3198       REMOVE_THEN "*" (MP_TAC o SPEC `i:real^N->bool`) THEN
3199       ASM_REWRITE_TAC[] THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
3200       MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN
3201       DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC) THEN
3202       SIMP_TAC[IN_INTERVAL; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
3203       REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN
3204       REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN
3205       ASM_SIMP_TAC[REAL_ARITH
3206        `a < b
3207         ==> ((u = a /\ v = a \/ u = b /\ v = b \/ u = a /\ v = b) /\
3208              u <= inv(&2) * (a + b) /\ inv(&2) * (a +  b) <= v <=>
3209              u = a /\ v = b)`] THEN
3210       ASM_MESON_TAC[CART_EQ];
3211       ALL_TAC] THEN
3212     DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
3213     DISCH_THEN(SUBST1_TAC o MATCH_MP (SET_RULE
3214      `a IN d ==> d = a INSERT (d DELETE a)`)) THEN
3215     ASM_SIMP_TAC[ITERATE_CLAUSES; FINITE_DELETE; IN_DELETE] THEN
3216     SUBGOAL_THEN
3217      `iterate op (d DELETE interval[a,b]) (f:(real^N->bool)->A) = neutral op`
3218      (fun th -> ASM_MESON_TAC[th; monoidal]) THEN
3219     MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
3220      ITERATE_EQ_NEUTRAL) THEN
3221     ASM_REWRITE_TAC[] THEN X_GEN_TAC `l:real^N->bool` THEN
3222     REWRITE_TAC[IN_DELETE] THEN STRIP_TAC THEN
3223     SUBGOAL_THEN `content(l:real^N->bool) = &0`
3224      (fun th -> ASM_MESON_TAC[th; operative]) THEN
3225     REMOVE_THEN "*" (MP_TAC o SPEC `l:real^N->bool`) THEN
3226     ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
3227     MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN
3228     DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC) THEN
3229     UNDISCH_TAC `~(interval[u:real^N,v] = interval[a,b])` THEN
3230     ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
3231     REWRITE_TAC[] THEN DISCH_THEN(fun th -> AP_TERM_TAC THEN MP_TAC th) THEN
3232     REWRITE_TAC[CONS_11; PAIR_EQ; CART_EQ; CONTENT_EQ_0] THEN
3233     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
3234      [TAUT `a ==> b <=> ~a \/ b`] THEN
3235     REWRITE_TAC[NOT_FORALL_THM; OR_EXISTS_THM] THEN
3236     REWRITE_TAC[NOT_EXISTS_THM; AND_FORALL_THM] THEN
3237     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `j:num` THEN
3238     ASM_CASES_TAC `1 <= j /\ j <= dimindex(:N)` THEN ASM_REWRITE_TAC[] THEN
3239     FIRST_X_ASSUM(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN
3240     REAL_ARITH_TAC;
3241     ALL_TAC] THEN
3242   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
3243   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [division_points] THEN
3244   REWRITE_TAC[IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
3245   MAP_EVERY X_GEN_TAC [`whatever:num#real`; `k:num`; `c:real`] THEN
3246   ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND; REAL_LT_IMP_LE] THEN
3247   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (K ALL_TAC)) THEN
3248   DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
3249   MP_TAC(ISPECL [`a:real^N`; `b:real^N`; `c:real`; `d:(real^N->bool)->bool`;
3250         `k:num`] DIVISION_POINTS_PSUBSET) THEN
3251   ASM_REWRITE_TAC[] THEN
3252   DISCH_THEN(CONJUNCTS_THEN
3253    (MP_TAC o MATCH_MP (REWRITE_RULE [IMP_CONJ] CARD_PSUBSET))) THEN
3254   MP_TAC(ISPECL [`d:(real^N->bool)->bool`; `a:real^N`; `b:real^N`; `k:num`;
3255                  `c:real`]
3256       DIVISION_SPLIT) THEN
3257   ASM_SIMP_TAC[DIVISION_POINTS_FINITE] THEN
3258   ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
3259   ASM_SIMP_TAC[REAL_ARITH `a < c ==> max a c = c`;
3260                REAL_ARITH `c < b ==> min b c = c`] THEN
3261   MAP_EVERY ABBREV_TAC
3262    [`d1:(real^N->bool)->bool =
3263      {l INTER {x | x$k <= c} | l | l IN d /\ ~(l INTER {x | x$k <= c} = {})}`;
3264     `d2:(real^N->bool)->bool =
3265      {l INTER {x | x$k >= c} | l | l IN d /\ ~(l INTER {x | x$k >= c} = {})}`;
3266     `cb:real^N = (lambda i. if i = k then c else (b:real^N)$i)`;
3267     `ca:real^N = (lambda i. if i = k then c else (a:real^N)$i)`] THEN
3268   STRIP_TAC THEN STRIP_TAC THEN STRIP_TAC THEN DISCH_THEN(fun th ->
3269    MP_TAC(SPECL [`a:real^N`; `cb:real^N`; `d1:(real^N->bool)->bool`] th) THEN
3270    MP_TAC(SPECL [`ca:real^N`; `b:real^N`; `d2:(real^N->bool)->bool`] th)) THEN
3271   ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
3272   MATCH_MP_TAC EQ_TRANS THEN
3273   EXISTS_TAC `op (iterate op d1 (f:(real^N->bool)->A))
3274                  (iterate op d2 (f:(real^N->bool)->A))` THEN
3275   CONJ_TAC THENL
3276    [FIRST_ASSUM(MP_TAC o CONJUNCT2 o GEN_REWRITE_RULE I [operative]) THEN
3277     DISCH_THEN(MP_TAC o SPECL [`a:real^N`; `b:real^N`; `c:real`; `k:num`]) THEN
3278     ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
3279     ASM_SIMP_TAC[REAL_ARITH `a < c ==> max a c = c`;
3280                  REAL_ARITH `c < b ==> min b c = c`];
3281     ALL_TAC] THEN
3282   MATCH_MP_TAC EQ_TRANS THEN
3283   EXISTS_TAC
3284    `op (iterate op d (\l. f(l INTER {x | x$k <= c}):A))
3285        (iterate op d (\l. f(l INTER {x:real^N | x$k >= c})))` THEN
3286   CONJ_TAC THENL
3287    [ALL_TAC;
3288     ASM_SIMP_TAC[GSYM ITERATE_OP] THEN
3289     MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
3290      ITERATE_EQ) THEN
3291     ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION
3292      (ASSUME `d division_of interval[a:real^N,b]`)] THEN
3293     ASM_MESON_TAC[operative]] THEN
3294   MAP_EVERY EXPAND_TAC ["d1"; "d2"] THEN BINOP_TAC THEN
3295   GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM o_DEF] THEN
3296   MATCH_MP_TAC ITERATE_NONZERO_IMAGE_LEMMA THEN ASM_REWRITE_TAC[] THEN
3297   (CONJ_TAC THENL [ASM_MESON_TAC[OPERATIVE_EMPTY]; ALL_TAC] THEN
3298    MAP_EVERY X_GEN_TAC [`l:real^N->bool`; `m:real^N->bool`] THEN STRIP_TAC THEN
3299    MATCH_MP_TAC(MESON[OPERATIVE_TRIVIAL]
3300     `operative op f /\ (?a b. l = interval[a,b]) /\ content l = &0
3301      ==> f l = neutral op`) THEN
3302    ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
3303     [ALL_TAC; ASM_MESON_TAC[DIVISION_SPLIT_LEFT_INJ;
3304                                  DIVISION_SPLIT_RIGHT_INJ]] THEN
3305    SUBGOAL_THEN `?a b:real^N. m = interval[a,b]` STRIP_ASSUME_TAC THENL
3306     [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
3307    ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MESON_TAC[]));;
3308
3309 let OPERATIVE_TAGGED_DIVISION = prove
3310  (`!op d a b f:(real^N->bool)->A.
3311     monoidal op /\ operative op f /\ d tagged_division_of interval[a,b]
3312     ==> iterate(op) d (\(x,l). f l) = f(interval[a,b])`,
3313   let lemma = prove
3314    (`(\(x,l). f l) = (f o SND)`,
3315     REWRITE_TAC[FUN_EQ_THM; o_THM; FORALL_PAIR_THM]) in
3316   REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC
3317    `iterate op (IMAGE SND (d:(real^N#(real^N->bool)->bool))) f :A` THEN
3318   CONJ_TAC THENL
3319    [ALL_TAC;
3320     ASM_MESON_TAC[DIVISION_OF_TAGGED_DIVISION; OPERATIVE_DIVISION]] THEN
3321   REWRITE_TAC[lemma] THEN CONV_TAC SYM_CONV THEN
3322   MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
3323                ITERATE_IMAGE_NONZERO) THEN
3324   ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
3325   CONJ_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF_FINITE]; ALL_TAC] THEN
3326   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
3327   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o CONJUNCT1 o CONJUNCT2)) THEN
3328   REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN REWRITE_TAC[PAIR_EQ] THEN
3329   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
3330   ASM_SIMP_TAC[INTER_ACI] THEN
3331   ASM_MESON_TAC[CONTENT_EQ_0_INTERIOR; OPERATIVE_TRIVIAL;
3332                 TAGGED_DIVISION_OF]);;
3333
3334 (* ------------------------------------------------------------------------- *)
3335 (* Additivity of content.                                                    *)
3336 (* ------------------------------------------------------------------------- *)
3337
3338 let ADDITIVE_CONTENT_DIVISION = prove
3339  (`!d a b:real^N.
3340     d division_of interval[a,b]
3341     ==> sum d content = content(interval[a,b])`,
3342   REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP
3343    (MATCH_MP
3344      (REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
3345                   OPERATIVE_DIVISION)
3346      (CONJ MONOIDAL_REAL_ADD OPERATIVE_CONTENT))) THEN
3347   REWRITE_TAC[sum]);;
3348
3349 let ADDITIVE_CONTENT_TAGGED_DIVISION = prove
3350  (`!d a b:real^N.
3351     d tagged_division_of interval[a,b]
3352     ==> sum d (\(x,l). content l) = content(interval[a,b])`,
3353   REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP
3354    (MATCH_MP
3355      (REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
3356                   OPERATIVE_TAGGED_DIVISION)
3357      (CONJ MONOIDAL_REAL_ADD OPERATIVE_CONTENT))) THEN
3358   REWRITE_TAC[sum]);;
3359
3360 let SUBADDITIVE_CONTENT_DIVISION = prove
3361  (`!d s a b:real^M.
3362         d division_of s /\ s SUBSET interval[a,b]
3363         ==> sum d content <= content(interval[a,b])`,
3364   REPEAT STRIP_TAC THEN
3365   MP_TAC(ISPECL [`d:(real^M->bool)->bool`; `a:real^M`; `b:real^M`]
3366         PARTIAL_DIVISION_EXTEND_INTERVAL) THEN
3367   ANTS_TAC THENL
3368    [REWRITE_TAC[UNIONS_SUBSET] THEN
3369     ASM_MESON_TAC[division_of; DIVISION_OF_UNION_SELF; SUBSET_TRANS];
3370     DISCH_THEN(X_CHOOSE_THEN `p:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN
3371     MATCH_MP_TAC REAL_LE_TRANS THEN
3372     EXISTS_TAC `sum (p:(real^M->bool)->bool) content` THEN CONJ_TAC THENL
3373      [MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
3374       ASM_MESON_TAC[division_of; CONTENT_POS_LE; IN_DIFF];
3375       ASM_MESON_TAC[ADDITIVE_CONTENT_DIVISION; REAL_LE_REFL]]]);;
3376
3377 (* ------------------------------------------------------------------------- *)
3378 (* Finally, the integral of a constant!                                      *)
3379 (* ------------------------------------------------------------------------- *)
3380
3381 let HAS_INTEGRAL_CONST = prove
3382  (`!a b:real^M c:real^N.
3383     ((\x. c) has_integral (content(interval[a,b]) % c)) (interval[a,b])`,
3384   REWRITE_TAC[has_integral] THEN REPEAT STRIP_TAC THEN
3385   EXISTS_TAC `\x:real^M. ball(x,&1)` THEN REWRITE_TAC[GAUGE_TRIVIAL] THEN
3386   REPEAT STRIP_TAC THEN
3387   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
3388   FIRST_X_ASSUM(fun th ->
3389   ONCE_REWRITE_TAC[GSYM(MATCH_MP ADDITIVE_CONTENT_TAGGED_DIVISION th)]) THEN
3390   ASM_SIMP_TAC[VSUM_VMUL; GSYM VSUM_SUB] THEN
3391   REWRITE_TAC[LAMBDA_PAIR_THM; VECTOR_SUB_REFL] THEN
3392   ASM_REWRITE_TAC[GSYM LAMBDA_PAIR_THM; VSUM_0; NORM_0]);;
3393
3394 let INTEGRABLE_CONST = prove
3395  (`!a b:real^M c:real^N. (\x. c) integrable_on interval[a,b]`,
3396   REPEAT STRIP_TAC THEN REWRITE_TAC[integrable_on] THEN
3397   EXISTS_TAC `content(interval[a:real^M,b]) % c:real^N` THEN
3398   REWRITE_TAC[HAS_INTEGRAL_CONST]);;
3399
3400 let INTEGRAL_CONST = prove
3401  (`!a b c. integral (interval[a,b]) (\x. c) = content(interval[a,b]) % c`,
3402   REPEAT GEN_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
3403   REWRITE_TAC[HAS_INTEGRAL_CONST]);;
3404
3405 let INTEGRAL_PASTECART_CONST = prove
3406  (`!a b:real^M c d:real^N k:real^P.
3407      integral (interval[pastecart a c,pastecart b d]) (\x. k) =
3408      integral (interval[a,b])
3409               (\x. integral (interval[c,d]) (\y. k))`,
3410   REWRITE_TAC[INTEGRAL_CONST; CONTENT_PASTECART; VECTOR_MUL_ASSOC]);;
3411
3412 (* ------------------------------------------------------------------------- *)
3413 (* Bounds on the norm of Riemann sums and the integral itself.               *)
3414 (* ------------------------------------------------------------------------- *)
3415
3416 let DSUM_BOUND = prove
3417  (`!p a b:real^M c:real^N e.
3418        p division_of interval[a,b] /\ norm(c) <= e
3419        ==> norm(vsum p (\l. content l % c)) <= e * content(interval[a,b])`,
3420   REPEAT STRIP_TAC THEN
3421   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
3422   W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
3423   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
3424    `y <= e ==> x <= y ==> x <= e`) THEN
3425   REWRITE_TAC[LAMBDA_PAIR_THM; NORM_MUL] THEN
3426   MATCH_MP_TAC REAL_LE_TRANS THEN
3427   EXISTS_TAC `sum p (\k:real^M->bool. content k * e)` THEN
3428   CONJ_TAC THENL
3429    [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
3430     X_GEN_TAC `l:real^M->bool` THEN DISCH_TAC THEN
3431     MATCH_MP_TAC REAL_LE_MUL2 THEN SIMP_TAC[REAL_ABS_POS; NORM_POS_LE] THEN
3432     ASM_REWRITE_TAC[] THEN
3433     MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> abs(x) <= x`) THEN
3434     ASM_MESON_TAC[DIVISION_OF; CONTENT_POS_LE];
3435     REWRITE_TAC[SUM_RMUL; ETA_AX] THEN
3436     ASM_MESON_TAC[ADDITIVE_CONTENT_DIVISION; REAL_LE_REFL; REAL_MUL_SYM]]);;
3437
3438 let RSUM_BOUND = prove
3439  (`!p a b f:real^M->real^N e.
3440        p tagged_division_of interval[a,b] /\
3441        (!x. x IN interval[a,b] ==> norm(f x) <= e)
3442        ==> norm(vsum p (\(x,k). content k % f x))
3443             <= e * content(interval[a,b])`,
3444   REPEAT STRIP_TAC THEN
3445   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
3446   W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
3447   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
3448    `y <= e ==> x <= y ==> x <= e`) THEN
3449   REWRITE_TAC[LAMBDA_PAIR_THM; NORM_MUL] THEN
3450   MATCH_MP_TAC REAL_LE_TRANS THEN
3451   EXISTS_TAC `sum p (\(x:real^M,k:real^M->bool). content k * e)` THEN
3452   CONJ_TAC THENL
3453    [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
3454     MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN DISCH_TAC THEN
3455     MATCH_MP_TAC REAL_LE_MUL2 THEN SIMP_TAC[REAL_ABS_POS; NORM_POS_LE] THEN
3456     CONJ_TAC THENL
3457      [ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE; REAL_ABS_REFL;
3458                     REAL_LE_REFL];
3459       ASM_MESON_TAC[TAG_IN_INTERVAL]];
3460     FIRST_ASSUM(fun th -> REWRITE_TAC
3461      [GSYM(MATCH_MP ADDITIVE_CONTENT_TAGGED_DIVISION th)]) THEN
3462     REWRITE_TAC[GSYM SUM_LMUL; LAMBDA_PAIR_THM] THEN
3463     REWRITE_TAC[REAL_MUL_AC; REAL_LE_REFL]]);;
3464
3465 let RSUM_DIFF_BOUND = prove
3466  (`!p a b f g:real^M->real^N.
3467        p tagged_division_of interval[a,b] /\
3468        (!x. x IN interval[a,b] ==> norm(f x - g x) <= e)
3469        ==> norm(vsum p (\(x,k). content k % f x) -
3470                 vsum p (\(x,k). content k % g x))
3471            <= e * content(interval[a,b])`,
3472   REPEAT STRIP_TAC THEN
3473   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
3474   MATCH_MP_TAC REAL_LE_TRANS THEN
3475   EXISTS_TAC
3476    `norm(vsum p (\(x,k).
3477       content(k:real^M->bool) % ((f:real^M->real^N) x - g x)))` THEN
3478   CONJ_TAC THENL
3479    [ASM_SIMP_TAC[GSYM VSUM_SUB; VECTOR_SUB_LDISTRIB] THEN
3480     REWRITE_TAC[LAMBDA_PAIR_THM; REAL_LE_REFL];
3481     ASM_SIMP_TAC[RSUM_BOUND]]);;
3482
3483 let HAS_INTEGRAL_BOUND = prove
3484  (`!f:real^M->real^N a b i B.
3485         &0 <= B /\
3486         (f has_integral i) (interval[a,b]) /\
3487         (!x. x IN interval[a,b] ==> norm(f x) <= B)
3488         ==> norm i <= B * content(interval[a,b])`,
3489   let lemma = prove
3490    (`norm(s) <= B ==> ~(norm(s - i) < norm(i) - B)`,
3491     MATCH_MP_TAC(REAL_ARITH `n1 <= n + n2 ==> n <= B ==> ~(n2 < n1 - B)`) THEN
3492     ONCE_REWRITE_TAC[NORM_SUB] THEN REWRITE_TAC[NORM_TRIANGLE_SUB]) in
3493   REPEAT STRIP_TAC THEN
3494   ASM_CASES_TAC `&0 < content(interval[a:real^M,b])` THENL
3495    [ALL_TAC;
3496     SUBGOAL_THEN `i:real^N = vec 0` SUBST1_TAC THEN
3497     ASM_SIMP_TAC[REAL_LE_MUL; NORM_0; CONTENT_POS_LE] THEN
3498     ASM_MESON_TAC[HAS_INTEGRAL_NULL_EQ; CONTENT_LT_NZ]] THEN
3499   ONCE_REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
3500   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [has_integral]) THEN
3501   DISCH_THEN(MP_TAC o SPEC
3502     `norm(i:real^N) - B * content(interval[a:real^M,b])`) THEN
3503   ASM_REWRITE_TAC[REAL_SUB_LT] THEN
3504   DISCH_THEN(X_CHOOSE_THEN `d:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
3505   MP_TAC(SPECL [`d:real^M->real^M->bool`; `a:real^M`; `b:real^M`]
3506         FINE_DIVISION_EXISTS) THEN
3507   ASM_REWRITE_TAC[] THEN DISCH_THEN
3508    (X_CHOOSE_THEN `p:(real^M#(real^M->bool)->bool)` STRIP_ASSUME_TAC) THEN
3509   FIRST_X_ASSUM(MP_TAC o SPEC `p:(real^M#(real^M->bool)->bool)`) THEN
3510   ASM_MESON_TAC[lemma; RSUM_BOUND]);;
3511
3512 (* ------------------------------------------------------------------------- *)
3513 (* Similar theorems about relationship among components.                     *)
3514 (* ------------------------------------------------------------------------- *)
3515
3516 let RSUM_COMPONENT_LE = prove
3517  (`!p a b f:real^M->real^N g:real^M->real^N.
3518        p tagged_division_of interval[a,b] /\ 1 <= i /\ i <= dimindex(:N) /\
3519        (!x. x IN interval[a,b] ==> (f x)$i <= (g x)$i)
3520        ==> vsum p (\(x,k). content k % f x)$i <=
3521            vsum p (\(x,k). content k % g x)$i`,
3522   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[VSUM_COMPONENT] THEN
3523   MATCH_MP_TAC SUM_LE THEN
3524   ASM_SIMP_TAC[FORALL_PAIR_THM; VECTOR_MUL_COMPONENT] THEN
3525   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
3526   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
3527   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
3528   ASM_MESON_TAC[SUBSET; REAL_LE_LMUL; CONTENT_POS_LE]);;
3529
3530 let HAS_INTEGRAL_COMPONENT_LE = prove
3531  (`!f:real^M->real^N g:real^M->real^N s i j k.
3532         1 <= k /\ k <= dimindex(:N) /\
3533         (f has_integral i) s /\ (g has_integral j) s /\
3534         (!x. x IN s ==> (f x)$k <= (g x)$k)
3535         ==> i$k <= j$k`,
3536   SUBGOAL_THEN
3537    `!f:real^M->real^N g:real^M->real^N a b i j k.
3538         1 <= k /\ k <= dimindex(:N) /\
3539         (f has_integral i) (interval[a,b]) /\
3540         (g has_integral j) (interval[a,b]) /\
3541         (!x. x IN interval[a,b] ==> (f x)$k <= (g x)$k)
3542         ==> i$k <= j$k`
3543   ASSUME_TAC THENL
3544    [REPEAT STRIP_TAC THEN
3545     MATCH_MP_TAC(REAL_ARITH `~(&0 < i - j) ==> i <= j`) THEN DISCH_TAC THEN
3546     REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `((i:real^N)$k - (j:real^N)$k) / &3` o
3547        GEN_REWRITE_RULE I [has_integral])) THEN
3548     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
3549     DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
3550     DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
3551     SUBGOAL_THEN `?p. p tagged_division_of interval[a:real^M,b] /\
3552                       d1 fine p /\ d2 fine p`
3553     STRIP_ASSUME_TAC THENL
3554      [REWRITE_TAC[GSYM FINE_INTER] THEN MATCH_MP_TAC FINE_DIVISION_EXISTS THEN
3555       ASM_SIMP_TAC[GAUGE_INTER];
3556       ALL_TAC] THEN
3557     REPEAT
3558      (FIRST_X_ASSUM(MP_TAC o SPEC `p:real^M#(real^M->bool)->bool`) THEN
3559       ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o MATCH_MP REAL_LT_IMP_LE) THEN
3560       DISCH_THEN(MP_TAC o SPEC `k:num` o MATCH_MP NORM_BOUND_COMPONENT_LE) THEN
3561       ASM_SIMP_TAC[VECTOR_SUB_COMPONENT]) THEN
3562     SUBGOAL_THEN
3563      `vsum p (\(x,l:real^M->bool). content l % (f:real^M->real^N) x)$k <=
3564       vsum p (\(x,l). content l % (g:real^M->real^N) x)$k`
3565     MP_TAC THENL
3566      [MATCH_MP_TAC RSUM_COMPONENT_LE THEN ASM_MESON_TAC[];
3567       UNDISCH_TAC `&0 < (i:real^N)$k - (j:real^N)$k` THEN
3568       SPEC_TAC(`vsum p (\(x:real^M,l:real^M->bool).
3569                                 content l % (f x):real^N)$k`,
3570                `fs:real`) THEN
3571       SPEC_TAC(`vsum p (\(x:real^M,l:real^M->bool).
3572                                 content l % (g x):real^N)$k`,
3573                `gs:real`) THEN
3574       REAL_ARITH_TAC];
3575     ALL_TAC] THEN
3576   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[has_integral_alt] THEN
3577   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
3578   STRIP_TAC THEN REWRITE_TAC[GSYM REAL_NOT_LT] THEN DISCH_TAC THEN
3579   REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC
3580    `((i:real^N)$k - (j:real^N)$k) / &2`)) THEN
3581   ASM_REWRITE_TAC[REAL_HALF; REAL_SUB_LT] THEN
3582   DISCH_THEN(X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) THEN
3583   DISCH_THEN(X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC) THEN
3584   MP_TAC(ISPEC
3585    `ball(vec 0,B1) UNION ball(vec 0:real^M,B2)`
3586    BOUNDED_SUBSET_CLOSED_INTERVAL) THEN
3587   REWRITE_TAC[BOUNDED_UNION; BOUNDED_BALL; UNION_SUBSET; NOT_EXISTS_THM] THEN
3588   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
3589   DISCH_THEN(CONJUNCTS_THEN(ANTE_RES_THEN MP_TAC)) THEN
3590   DISCH_THEN(X_CHOOSE_THEN `w:real^N` STRIP_ASSUME_TAC) THEN
3591   DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
3592   SUBGOAL_THEN `(z:real^N)$k <= (w:real^N)$k` MP_TAC THENL
3593    [FIRST_X_ASSUM MATCH_MP_TAC THEN
3594     MAP_EVERY EXISTS_TAC
3595      [`(\x. if x IN s then f x else vec 0):real^M->real^N`;
3596       `(\x. if x IN s then g x else vec 0):real^M->real^N`;
3597       `a:real^M`; `b:real^M`] THEN
3598     ASM_MESON_TAC[REAL_LE_REFL];
3599     MP_TAC(ISPECL [`w - j:real^N`; `k:num`] COMPONENT_LE_NORM) THEN
3600     MP_TAC(ISPECL [`z - i:real^N`; `k:num`] COMPONENT_LE_NORM) THEN
3601     ASM_REWRITE_TAC[] THEN
3602     SIMP_TAC[VECTOR_SUB_COMPONENT; ASSUME `1 <= k`;
3603               ASSUME `k <= dimindex(:N)`] THEN
3604     REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM REAL_NOT_LE])) THEN
3605     NORM_ARITH_TAC]);;
3606
3607 let INTEGRAL_COMPONENT_LE = prove
3608  (`!f:real^M->real^N g:real^M->real^N s k.
3609         1 <= k /\ k <= dimindex(:N) /\
3610         f integrable_on s /\ g integrable_on s /\
3611         (!x. x IN s ==> (f x)$k <= (g x)$k)
3612         ==> (integral s f)$k <= (integral s g)$k`,
3613   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LE THEN
3614   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
3615
3616 let HAS_INTEGRAL_DROP_LE = prove
3617  (`!f:real^M->real^1 g:real^M->real^1 s i j.
3618         (f has_integral i) s /\ (g has_integral j) s /\
3619         (!x. x IN s ==> drop(f x) <= drop(g x))
3620         ==> drop i <= drop j`,
3621   REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN
3622   MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LE THEN
3623   REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN ASM_MESON_TAC[]);;
3624
3625 let INTEGRAL_DROP_LE = prove
3626  (`!f:real^M->real^1 g:real^M->real^1 s.
3627         f integrable_on s /\ g integrable_on s /\
3628         (!x. x IN s ==> drop(f x) <= drop(g x))
3629         ==> drop(integral s f) <= drop(integral s g)`,
3630   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_DROP_LE THEN
3631   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
3632
3633 let HAS_INTEGRAL_COMPONENT_POS = prove
3634  (`!f:real^M->real^N s i k.
3635         1 <= k /\ k <= dimindex(:N) /\
3636         (f has_integral i) s /\
3637         (!x. x IN s ==> &0 <= (f x)$k)
3638         ==> &0 <= i$k`,
3639   REPEAT STRIP_TAC THEN
3640   MP_TAC(ISPECL [`(\x. vec 0):real^M->real^N`; `f:real^M->real^N`;
3641                  `s:real^M->bool`; `vec 0:real^N`;
3642                  `i:real^N`; `k:num`] HAS_INTEGRAL_COMPONENT_LE) THEN
3643   ASM_SIMP_TAC[VEC_COMPONENT; HAS_INTEGRAL_0]);;
3644
3645 let INTEGRAL_COMPONENT_POS = prove
3646  (`!f:real^M->real^N s k.
3647         1 <= k /\ k <= dimindex(:N) /\
3648         f integrable_on s /\
3649         (!x. x IN s ==> &0 <= (f x)$k)
3650         ==> &0 <= (integral s f)$k`,
3651   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_POS THEN
3652   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
3653
3654 let HAS_INTEGRAL_DROP_POS = prove
3655  (`!f:real^M->real^1 s i.
3656         (f has_integral i) s /\
3657         (!x. x IN s ==> &0 <= drop(f x))
3658         ==> &0 <= drop i`,
3659   REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN
3660   MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_POS THEN
3661   REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN ASM_MESON_TAC[]);;
3662
3663 let INTEGRAL_DROP_POS = prove
3664  (`!f:real^M->real^1 s.
3665         f integrable_on s /\
3666         (!x. x IN s ==> &0 <= drop(f x))
3667         ==> &0 <= drop(integral s f)`,
3668   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_DROP_POS THEN
3669   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
3670
3671 let HAS_INTEGRAL_COMPONENT_NEG = prove
3672  (`!f:real^M->real^N s i k.
3673         1 <= k /\ k <= dimindex(:N) /\
3674         (f has_integral i) s /\
3675         (!x. x IN s ==> (f x)$k <= &0)
3676         ==> i$k <= &0`,
3677   REPEAT STRIP_TAC THEN
3678   MP_TAC(ISPECL [`f:real^M->real^N`; `(\x. vec 0):real^M->real^N`;
3679                  `s:real^M->bool`; `i:real^N`; `vec 0:real^N`;
3680                  `k:num`] HAS_INTEGRAL_COMPONENT_LE) THEN
3681   ASM_SIMP_TAC[VEC_COMPONENT; HAS_INTEGRAL_0]);;
3682
3683 let HAS_INTEGRAL_DROP_NEG = prove
3684  (`!f:real^M->real^1 s i.
3685         (f has_integral i) s /\
3686         (!x. x IN s ==> drop(f x) <= &0)
3687         ==> drop i <= &0`,
3688   REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN
3689   MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_NEG THEN
3690   REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN ASM_MESON_TAC[]);;
3691
3692 let HAS_INTEGRAL_COMPONENT_LBOUND = prove
3693  (`!f:real^M->real^N a b i k.
3694         (f has_integral i) (interval[a,b]) /\ 1 <= k /\ k <= dimindex(:N) /\
3695         (!x. x IN interval[a,b] ==> B <= f(x)$k)
3696         ==> B * content(interval[a,b]) <= i$k`,
3697   REPEAT STRIP_TAC THEN
3698   MP_TAC(ISPECL [`(\x. lambda i. B):real^M->real^N`; `f:real^M->real^N`;
3699                  `interval[a:real^M,b]`;
3700                  `content(interval[a:real^M,b]) % (lambda i. B):real^N`;
3701                  `i:real^N`; `k:num`]
3702                 HAS_INTEGRAL_COMPONENT_LE) THEN
3703   ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; LAMBDA_BETA; HAS_INTEGRAL_CONST] THEN
3704   REWRITE_TAC[REAL_MUL_AC]);;
3705
3706 let HAS_INTEGRAL_COMPONENT_UBOUND = prove
3707  (`!f:real^M->real^N a b i k.
3708         (f has_integral i) (interval[a,b]) /\ 1 <= k /\ k <= dimindex(:N) /\
3709         (!x. x IN interval[a,b] ==> f(x)$k <= B)
3710         ==> i$k <= B * content(interval[a,b])`,
3711   REPEAT STRIP_TAC THEN
3712   MP_TAC(ISPECL [`f:real^M->real^N`; `(\x. lambda i. B):real^M->real^N`;
3713                  `interval[a:real^M,b]`; `i:real^N`;
3714                  `content(interval[a:real^M,b]) % (lambda i. B):real^N`;
3715                  `k:num`]
3716                 HAS_INTEGRAL_COMPONENT_LE) THEN
3717   ASM_SIMP_TAC[VECTOR_MUL_COMPONENT; LAMBDA_BETA; HAS_INTEGRAL_CONST] THEN
3718   REWRITE_TAC[REAL_MUL_AC]);;
3719
3720 let INTEGRAL_COMPONENT_LBOUND = prove
3721  (`!f:real^M->real^N a b k.
3722         f integrable_on interval[a,b] /\ 1 <= k /\ k <= dimindex(:N) /\
3723         (!x. x IN interval[a,b] ==> B <= f(x)$k)
3724         ==> B * content(interval[a,b]) <= (integral(interval[a,b]) f)$k`,
3725   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LBOUND THEN
3726   EXISTS_TAC `f:real^M->real^N` THEN
3727   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);;
3728
3729 let INTEGRAL_COMPONENT_UBOUND = prove
3730  (`!f:real^M->real^N a b k.
3731         f integrable_on interval[a,b] /\ 1 <= k /\ k <= dimindex(:N) /\
3732         (!x. x IN interval[a,b] ==> f(x)$k <= B)
3733         ==> (integral(interval[a,b]) f)$k <= B * content(interval[a,b])`,
3734   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_UBOUND THEN
3735   EXISTS_TAC `f:real^M->real^N` THEN
3736   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);;
3737
3738 (* ------------------------------------------------------------------------- *)
3739 (* Uniform limit of integrable functions is integrable.                      *)
3740 (* ------------------------------------------------------------------------- *)
3741
3742 let INTEGRABLE_UNIFORM_LIMIT = prove
3743  (`!f a b. (!e. &0 < e
3744                 ==> ?g. (!x. x IN interval[a,b] ==> norm(f x - g x) <= e) /\
3745                         g integrable_on interval[a,b] )
3746            ==> (f:real^M->real^N) integrable_on interval[a,b]`,
3747   let lemma = prove
3748    (`x <= norm(a + b) + c ==> x <= norm(a) + norm(b) + c`,
3749     MESON_TAC[REAL_ADD_AC; NORM_TRIANGLE; REAL_LE_TRANS; REAL_LE_RADD]) in
3750   let (lemma1,lemma2) = (CONJ_PAIR o prove)
3751    (`(norm(s2 - s1) <= e / &2 /\
3752       norm(s1 - i1) < e / &4 /\ norm(s2 - i2) < e / &4
3753       ==> norm(i1 - i2) < e) /\
3754      (norm(sf - sg) <= e / &3
3755       ==> norm(i - s) < e / &3 ==> norm(sg - i) < e / &3 ==> norm(sf - s) < e)`,
3756     CONJ_TAC THENL
3757      [REWRITE_TAC[CONJ_ASSOC] THEN
3758       GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o ONCE_DEPTH_CONV) [NORM_SUB] THEN
3759       MATCH_MP_TAC(REAL_ARITH
3760        `w <= x + y + z + &0
3761         ==> (x <= e / &2 /\ y < e / &4) /\ z < e / &4 ==> w < e`);
3762       MATCH_MP_TAC(REAL_ARITH
3763       `w <= x + y + z + &0
3764       ==> x <= e / &3 ==> y < e / &3 ==> z < e / &3 ==> w < e`)] THEN
3765     REPEAT(MATCH_MP_TAC lemma) THEN REWRITE_TAC[REAL_ADD_RID] THEN
3766     MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN VECTOR_ARITH_TAC) in
3767   REPEAT STRIP_TAC THEN
3768   ASM_CASES_TAC `&0 < content(interval[a:real^M,b])` THENL
3769    [ALL_TAC;
3770     ASM_MESON_TAC[HAS_INTEGRAL_NULL; CONTENT_LT_NZ; integrable_on]] THEN
3771   FIRST_X_ASSUM(MP_TAC o GEN `n:num` o SPEC `inv(&n + &1)`) THEN
3772   REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
3773   REWRITE_TAC[FORALL_AND_THM; SKOLEM_THM; integrable_on] THEN
3774   DISCH_THEN(X_CHOOSE_THEN `g:num->real^M->real^N` (CONJUNCTS_THEN2
3775    ASSUME_TAC (X_CHOOSE_TAC `i:num->real^N`))) THEN
3776   SUBGOAL_THEN `cauchy(i:num->real^N)` MP_TAC THENL
3777    [REWRITE_TAC[cauchy] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3778     MP_TAC(SPEC `e / &4 / content(interval[a:real^M,b])`
3779         REAL_ARCH_INV) THEN
3780     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
3781     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
3782     MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN REWRITE_TAC[GE] THEN
3783     STRIP_TAC THEN
3784     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV [has_integral]) THEN
3785     ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
3786     DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
3787     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
3788     DISCH_THEN(fun th -> MP_TAC(SPEC `m:num` th) THEN
3789       MP_TAC(SPEC `n:num` th)) THEN
3790     DISCH_THEN(X_CHOOSE_THEN `gn:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
3791     DISCH_THEN(X_CHOOSE_THEN `gm:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
3792     MP_TAC(ISPECL [`(\x. gm(x) INTER gn(x)):real^M->real^M->bool`;
3793                    `a:real^M`; `b:real^M`] FINE_DIVISION_EXISTS) THEN
3794     ASM_SIMP_TAC[GAUGE_INTER; LEFT_IMP_EXISTS_THM] THEN
3795     X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
3796     REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`)) THEN
3797     FIRST_ASSUM(fun th -> REWRITE_TAC[CONV_RULE(REWR_CONV FINE_INTER) th]) THEN
3798     SUBGOAL_THEN `norm(vsum p (\(x,k:real^M->bool). content k % g (n:num) x) -
3799                        vsum p (\(x:real^M,k). content k % g m x :real^N))
3800                   <= e / &2`
3801     MP_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[dist] THEN MESON_TAC[lemma1]] THEN
3802     MATCH_MP_TAC REAL_LE_TRANS THEN
3803     EXISTS_TAC `&2 / &N * content(interval[a:real^M,b])` THEN CONJ_TAC THENL
3804      [MATCH_MP_TAC RSUM_DIFF_BOUND;
3805       ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN
3806       ASM_REAL_ARITH_TAC] THEN
3807     ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
3808     FIRST_X_ASSUM(fun th -> MP_TAC(SPECL [`n:num`; `x:real^M`] th) THEN
3809       MP_TAC(SPECL [`m:num`; `x:real^M`] th)) THEN
3810     ASM_REWRITE_TAC[IMP_IMP] THEN
3811     GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o LAND_CONV) [NORM_SUB] THEN
3812     DISCH_THEN(MP_TAC o MATCH_MP REAL_LE_ADD2) THEN
3813     DISCH_THEN(MP_TAC o MATCH_MP NORM_TRIANGLE_LE) THEN
3814     MATCH_MP_TAC(REAL_ARITH `u = v /\ a <= inv(x) /\ b <= inv(x) ==>
3815                                 u <= a + b ==> v <= &2 / x`) THEN
3816     CONJ_TAC THENL [AP_TERM_TAC THEN VECTOR_ARITH_TAC; ALL_TAC] THEN
3817     CONJ_TAC THEN MATCH_MP_TAC REAL_LE_INV2 THEN
3818     REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
3819     ASM_ARITH_TAC;
3820     ALL_TAC] THEN
3821   REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN
3822   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `s:real^N` THEN DISCH_TAC THEN
3823   REWRITE_TAC[has_integral] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
3824   FIRST_X_ASSUM(MP_TAC o SPEC `e / &3` o GEN_REWRITE_RULE I
3825    [LIM_SEQUENTIALLY]) THEN
3826   ASM_SIMP_TAC[dist; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
3827   DISCH_THEN(X_CHOOSE_TAC `N1:num`) THEN
3828   MP_TAC(SPEC `e / &3 / content(interval[a:real^M,b])` REAL_ARCH_INV) THEN
3829   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
3830   DISCH_THEN(X_CHOOSE_THEN `N2:num` STRIP_ASSUME_TAC) THEN
3831   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV [has_integral]) THEN
3832   DISCH_THEN(MP_TAC o SPECL [`N1 + N2:num`; `e / &3`]) THEN
3833   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
3834   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^M->real^M->bool` THEN
3835   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
3836   X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN
3837   FIRST_X_ASSUM(MP_TAC o SPEC `p:real^M#(real^M->bool)->bool`) THEN
3838   ASM_REWRITE_TAC[] THEN
3839   FIRST_X_ASSUM(MP_TAC o C MATCH_MP (ARITH_RULE `N1:num <= N1 + N2`)) THEN
3840   MATCH_MP_TAC lemma2 THEN MATCH_MP_TAC REAL_LE_TRANS THEN
3841   EXISTS_TAC `inv(&(N1 + N2) + &1) * content(interval[a:real^M,b])` THEN
3842   CONJ_TAC THENL
3843    [MATCH_MP_TAC RSUM_DIFF_BOUND THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN
3844   ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN
3845   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
3846    `x < a ==> y <= x ==> y <= a`)) THEN
3847   MATCH_MP_TAC REAL_LE_INV2 THEN
3848   REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
3849   ASM_ARITH_TAC);;
3850
3851 (* ------------------------------------------------------------------------- *)
3852 (* Negligible sets.                                                          *)
3853 (* ------------------------------------------------------------------------- *)
3854
3855 let indicator = new_definition
3856   `indicator s :real^M->real^1 = \x. if x IN s then vec 1 else vec 0`;;
3857
3858 let DROP_INDICATOR = prove
3859  (`!s x. drop(indicator s x) = if x IN s then &1 else &0`,
3860   REPEAT GEN_TAC THEN REWRITE_TAC[indicator] THEN
3861   COND_CASES_TAC THEN ASM_REWRITE_TAC[DROP_VEC]);;
3862
3863 let DROP_INDICATOR_POS_LE = prove
3864  (`!s x. &0 <= drop(indicator s x)`,
3865   REWRITE_TAC[DROP_INDICATOR] THEN REAL_ARITH_TAC);;
3866
3867 let DROP_INDICATOR_LE_1 = prove
3868  (`!s x. drop(indicator s x) <= &1`,
3869   REWRITE_TAC[DROP_INDICATOR] THEN REAL_ARITH_TAC);;
3870
3871 let DROP_INDICATOR_ABS_LE_1 = prove
3872  (`!s x. abs(drop(indicator s x)) <= &1`,
3873   REWRITE_TAC[DROP_INDICATOR] THEN REAL_ARITH_TAC);;
3874
3875 let negligible = new_definition
3876  `negligible s <=> !a b. (indicator s has_integral (vec 0)) (interval[a,b])`;;
3877
3878 (* ------------------------------------------------------------------------- *)
3879 (* Negligibility of hyperplane.                                              *)
3880 (* ------------------------------------------------------------------------- *)
3881
3882 let VSUM_NONZERO_IMAGE_LEMMA = prove
3883  (`!s f:A->B g:B->real^N a.
3884         FINITE s /\ g(a) = vec 0 /\
3885         (!x y. x IN s /\ y IN s /\ f x = f y /\ ~(x = y) ==> g(f x) = vec 0)
3886        ==> vsum {f x |x| x IN s /\ ~(f x = a)} g =
3887            vsum s (g o f)`,
3888   REPEAT STRIP_TAC THEN
3889   SUBGOAL_THEN `FINITE {(f:A->B) x |x| x IN s /\ ~(f x = a)}`
3890   ASSUME_TAC THENL
3891    [MATCH_MP_TAC FINITE_SUBSET THEN EXISTS_TAC `IMAGE (f:A->B) s` THEN
3892     ASM_SIMP_TAC[FINITE_IMAGE; SUBSET; IN_IMAGE; IN_ELIM_THM] THEN MESON_TAC[];
3893     ASM_SIMP_TAC[VSUM] THEN MATCH_MP_TAC ITERATE_NONZERO_IMAGE_LEMMA THEN
3894     ASM_REWRITE_TAC[NEUTRAL_VECTOR_ADD; MONOIDAL_VECTOR_ADD]]);;
3895
3896 let INTERVAL_DOUBLESPLIT = prove
3897  (`1 <= k /\ k <= dimindex(:N)
3898       ==> interval[a,b] INTER {x:real^N | abs(x$k - c) <= e} =
3899           interval[(lambda i. if i = k then max (a$k) (c - e) else a$i),
3900                    (lambda i. if i = k then min (b$k) (c + e) else b$i)]`,
3901    REWRITE_TAC[REAL_ARITH `abs(x - c) <= e <=> x >= c - e /\ x <= c + e`] THEN
3902    REWRITE_TAC[SET_RULE `s INTER {x | P x /\ Q x} =
3903                         (s INTER {x | Q x}) INTER {x | P x}`] THEN
3904    SIMP_TAC[INTERVAL_SPLIT]);;
3905
3906 let DIVISION_DOUBLESPLIT = prove
3907  (`!p a b:real^N k c e.
3908         p division_of interval[a,b] /\ 1 <= k /\ k <= dimindex(:N)
3909         ==> {l INTER {x | abs(x$k - c) <= e} |l|
3910                 l IN p /\ ~(l INTER {x | abs(x$k - c) <= e} = {})}
3911             division_of (interval[a,b] INTER {x | abs(x$k - c) <= e})`,
3912   REPEAT GEN_TAC THEN DISCH_TAC THEN
3913   FIRST_ASSUM(MP_TAC o SPEC `c + e:real` o MATCH_MP DIVISION_SPLIT) THEN
3914   DISCH_THEN(MP_TAC o CONJUNCT1) THEN
3915   ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
3916   FIRST_ASSUM MP_TAC THEN REWRITE_TAC[IMP_IMP] THEN
3917   DISCH_THEN(MP_TAC o MATCH_MP (TAUT
3918    `(a /\ b /\ c) /\ d ==> d /\ b /\ c`)) THEN
3919   DISCH_THEN(MP_TAC o CONJUNCT2 o SPEC `c - e:real` o
3920     MATCH_MP DIVISION_SPLIT) THEN
3921   ASM_SIMP_TAC[INTERVAL_DOUBLESPLIT; INTERVAL_SPLIT] THEN
3922   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
3923   REWRITE_TAC[REAL_ARITH `abs(x - c) <= e <=> x >= c - e /\ x <= c + e`] THEN
3924   GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN
3925   GEN_TAC THEN REWRITE_TAC[LEFT_AND_EXISTS_THM] THEN
3926   ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN REWRITE_TAC[GSYM CONJ_ASSOC] THEN
3927   ONCE_REWRITE_TAC[TAUT `a /\ b /\ c /\ d <=> c /\ a /\ b /\ d`] THEN
3928   REWRITE_TAC[UNWIND_THM2] THEN AP_TERM_TAC THEN ABS_TAC THEN SET_TAC[]);;
3929
3930 let CONTENT_DOUBLESPLIT = prove
3931  (`!a b:real^N k c e.
3932         &0 < e /\ 1 <= k /\ k <= dimindex(:N)
3933         ==> ?d. &0 < d /\
3934                 content(interval[a,b] INTER {x | abs(x$k - c) <= d}) < e`,
3935   REPEAT STRIP_TAC THEN
3936   ASM_CASES_TAC `content(interval[a:real^N,b]) = &0` THENL
3937    [EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
3938     MATCH_MP_TAC REAL_LET_TRANS THEN
3939     EXISTS_TAC `content(interval[a:real^N,b])` THEN
3940     CONJ_TAC THENL [FIRST_X_ASSUM(K ALL_TAC o SYM); ASM_REWRITE_TAC[]] THEN
3941     ASM_SIMP_TAC[INTERVAL_DOUBLESPLIT] THEN MATCH_MP_TAC CONTENT_SUBSET THEN
3942     ASM_SIMP_TAC[GSYM INTERVAL_DOUBLESPLIT] THEN SET_TAC[];
3943     ALL_TAC] THEN
3944   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CONTENT_EQ_0]) THEN
3945   REWRITE_TAC[NOT_EXISTS_THM; TAUT `~(a /\ b /\ c) <=> a /\ b ==> ~c`] THEN
3946   REWRITE_TAC[REAL_NOT_LE] THEN DISCH_TAC THEN
3947   SUBGOAL_THEN `&0 < product ((1..dimindex (:N)) DELETE k)
3948                               (\i. (b:real^N)$i - (a:real^N)$i)`
3949   ASSUME_TAC THENL
3950    [MATCH_MP_TAC PRODUCT_POS_LT THEN
3951     ASM_SIMP_TAC[FINITE_DELETE; FINITE_NUMSEG; IN_DELETE; IN_NUMSEG;
3952                  REAL_SUB_LT];
3953     ALL_TAC] THEN
3954   ABBREV_TAC `d = e / &3 / product ((1..dimindex (:N)) DELETE k)
3955                                    (\i. (b:real^N)$i - (a:real^N)$i)` THEN
3956   EXISTS_TAC `d:real` THEN SUBGOAL_THEN `&0 < d` ASSUME_TAC THENL
3957    [EXPAND_TAC "d" THEN MATCH_MP_TAC REAL_LT_DIV THEN
3958     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH];
3959     ALL_TAC] THEN
3960   ASM_SIMP_TAC[content; INTERVAL_DOUBLESPLIT] THEN
3961   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
3962   FIRST_X_ASSUM(ASSUME_TAC o GEN_REWRITE_RULE I [INTERVAL_NE_EMPTY]) THEN
3963   SUBGOAL_THEN `1..dimindex(:N) = k INSERT ((1..dimindex(:N)) DELETE k)`
3964   SUBST1_TAC THENL
3965    [REWRITE_TAC[EXTENSION; IN_INSERT; IN_DELETE; IN_NUMSEG] THEN
3966     ASM_MESON_TAC[];
3967     ALL_TAC] THEN
3968   SIMP_TAC[PRODUCT_CLAUSES; FINITE_NUMSEG; FINITE_DELETE; IN_DELETE] THEN
3969   ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND; REAL_LT_IMP_LE;
3970                 LAMBDA_BETA; IN_DELETE; IN_NUMSEG] THEN
3971   SUBGOAL_THEN
3972    `product ((1..dimindex (:N)) DELETE k)
3973      (\j. ((lambda i. if i = k then min (b$k) (c + d) else b$i):real^N)$j -
3974           ((lambda i. if i = k then max (a$k) (c - d) else a$i):real^N)$j) =
3975     product ((1..dimindex (:N)) DELETE k)
3976             (\i. (b:real^N)$i - (a:real^N)$i)`
3977   SUBST1_TAC THENL
3978    [MATCH_MP_TAC PRODUCT_EQ THEN
3979     SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA];
3980     ALL_TAC] THEN
3981   ASM_SIMP_TAC[GSYM REAL_LT_RDIV_EQ] THEN
3982   MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `&2 * d` THEN
3983   CONJ_TAC THENL [REAL_ARITH_TAC; ALL_TAC] THEN
3984   MATCH_MP_TAC(REAL_ARITH `&0 < d /\ &3 * d <= x ==> &2 * d < x`) THEN
3985   ASM_REWRITE_TAC[] THEN EXPAND_TAC "d" THEN REAL_ARITH_TAC);;
3986
3987 let NEGLIGIBLE_STANDARD_HYPERPLANE = prove
3988  (`!c k. 1 <= k /\ k <= dimindex(:N) ==> negligible {x:real^N | x$k = c}`,
3989   REPEAT STRIP_TAC THEN REWRITE_TAC[negligible; has_integral] THEN
3990   REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_SUB_RZERO] THEN
3991   MP_TAC(ISPECL [`a:real^N`; `b:real^N`; `k:num`; `c:real`; `e:real`]
3992         CONTENT_DOUBLESPLIT) THEN
3993   ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
3994   EXISTS_TAC `\x:real^N. ball(x,d)` THEN ASM_SIMP_TAC[GAUGE_BALL] THEN
3995   ABBREV_TAC `i = indicator {x:real^N | x$k = c}` THEN REPEAT STRIP_TAC THEN
3996   SUBGOAL_THEN
3997    `vsum p (\(x,l). content l % i x) =
3998     vsum p (\(x,l). content(l INTER {x:real^N | abs(x$k - c) <= d}) %
3999                     (i:real^N->real^1) x)`
4000   SUBST1_TAC THENL
4001    [MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
4002     MAP_EVERY X_GEN_TAC [`x:real^N`; `l:real^N->bool`] THEN
4003     DISCH_TAC THEN EXPAND_TAC "i" THEN REWRITE_TAC[indicator] THEN
4004     REWRITE_TAC[IN_ELIM_THM] THEN
4005     COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN
4006     AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
4007     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
4008     DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `l:real^N->bool`]) THEN
4009     ASM_REWRITE_TAC[] THEN
4010     MATCH_MP_TAC(SET_RULE `s SUBSET t ==> l SUBSET s ==> l = l INTER t`) THEN
4011     REWRITE_TAC[SUBSET; IN_BALL; IN_ELIM_THM; dist] THEN
4012     UNDISCH_THEN `(x:real^N)$k = c` (SUBST1_TAC o SYM) THEN
4013     ASM_SIMP_TAC[GSYM VECTOR_SUB_COMPONENT] THEN
4014     ONCE_REWRITE_TAC[NORM_SUB] THEN
4015     ASM_MESON_TAC[COMPONENT_LE_NORM; REAL_LE_TRANS; REAL_LT_IMP_LE];
4016     ALL_TAC] THEN
4017   MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC
4018    `norm(vsum p (\(x:real^N,l).
4019           content(l INTER {x:real^N | abs(x$k - c) <= d}) %
4020          vec 1:real^1))` THEN
4021   CONJ_TAC THENL
4022    [FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
4023     ASM_SIMP_TAC[VSUM_REAL; NORM_LIFT] THEN
4024     MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= y ==> abs(x) <= abs(y)`) THEN
4025     REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM; DROP_CMUL] THEN CONJ_TAC THENL
4026      [MATCH_MP_TAC SUM_POS_LE; MATCH_MP_TAC SUM_LE] THEN
4027     ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
4028     MAP_EVERY X_GEN_TAC [`x:real^N`; `l:real^N->bool`] THEN STRIP_TAC THENL
4029      [MATCH_MP_TAC REAL_LE_MUL; MATCH_MP_TAC REAL_LE_LMUL] THEN
4030     EXPAND_TAC "i" THEN REWRITE_TAC[DROP_VEC] THEN
4031     REWRITE_TAC[DROP_INDICATOR_POS_LE; DROP_INDICATOR_LE_1] THEN
4032     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
4033     DISCH_THEN(MP_TAC o SPECL [`x:real^N`; `l:real^N->bool`] o
4034         el 1 o CONJUNCTS) THEN
4035     ASM_REWRITE_TAC[] THEN
4036     STRIP_TAC THEN ASM_SIMP_TAC[INTERVAL_DOUBLESPLIT; CONTENT_POS_LE];
4037     ALL_TAC] THEN
4038   MP_TAC(ISPECL [`(\l. content (l INTER {x | abs (x$k - c) <= d}) % vec 1):
4039                   (real^N->bool)->real^1`;
4040                  `p:real^N#(real^N->bool)->bool`;
4041                  `interval[a:real^N,b]`]
4042         VSUM_OVER_TAGGED_DIVISION_LEMMA) THEN
4043   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
4044    [MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN STRIP_TAC THEN
4045     REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN
4046     MATCH_MP_TAC(REAL_ARITH `!x. x = &0 /\ &0 <= y /\ y <= x ==> y = &0`) THEN
4047     EXISTS_TAC `content(interval[u:real^N,v])` THEN
4048     CONJ_TAC THEN POP_ASSUM MP_TAC THEN REWRITE_TAC[] THEN
4049     DISCH_THEN(K ALL_TAC) THEN
4050     ASM_SIMP_TAC[CONTENT_POS_LE; INTERVAL_DOUBLESPLIT] THEN
4051     MATCH_MP_TAC CONTENT_SUBSET THEN
4052     ASM_SIMP_TAC[GSYM INTERVAL_DOUBLESPLIT] THEN SET_TAC[];
4053     ALL_TAC] THEN
4054   DISCH_THEN SUBST1_TAC THEN
4055   MP_TAC(ISPECL
4056      [`IMAGE SND (p:real^N#(real^N->bool)->bool)`;
4057       `\l. l INTER {x:real^N | abs (x$k - c) <= d}`;
4058       `\l:real^N->bool. content l % vec 1 :real^1`;
4059       `{}:real^N->bool`] VSUM_NONZERO_IMAGE_LEMMA) THEN
4060     REWRITE_TAC[o_DEF] THEN
4061   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_TAGGED_DIVISION) THEN
4062   ANTS_TAC THENL
4063    [CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_FINITE]; ALL_TAC] THEN
4064     REWRITE_TAC[CONTENT_EMPTY; VECTOR_MUL_LZERO] THEN
4065     ONCE_REWRITE_TAC[IMP_CONJ] THEN
4066     REWRITE_TAC[RIGHT_FORALL_IMP_THM] THEN
4067     FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
4068     MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN DISCH_TAC THEN
4069     X_GEN_TAC `m:real^N->bool` THEN STRIP_TAC THEN
4070     REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN
4071     SIMP_TAC[INTERVAL_DOUBLESPLIT; ASSUME `1 <= k`;
4072              ASSUME `k <= dimindex(:N)`] THEN
4073     REWRITE_TAC[CONTENT_EQ_0_INTERIOR] THEN
4074     ASM_SIMP_TAC[GSYM INTERVAL_DOUBLESPLIT] THEN
4075     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
4076     DISCH_THEN(MP_TAC o SPECL [`interval[u:real^N,v]`; `m:real^N->bool`] o
4077       el 2 o CONJUNCTS) THEN ASM_REWRITE_TAC[] THEN
4078     MATCH_MP_TAC(SET_RULE
4079       `u SUBSET s /\ u SUBSET t ==> s INTER t = {} ==> u = {}`) THEN
4080     CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN ASM SET_TAC[];
4081     ALL_TAC] THEN
4082   REWRITE_TAC[o_DEF] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
4083   MATCH_MP_TAC REAL_LET_TRANS THEN
4084   EXISTS_TAC
4085    `&1 * content(interval[a,b] INTER {x:real^N | abs (x$k - c) <= d})` THEN
4086   CONJ_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[REAL_MUL_LID]] THEN
4087   FIRST_ASSUM(MP_TAC o MATCH_MP(REWRITE_RULE[IMP_CONJ]
4088     DIVISION_DOUBLESPLIT)) THEN
4089   DISCH_THEN(MP_TAC o SPECL [`k:num`; `c:real`; `d:real`]) THEN
4090   ASM_SIMP_TAC[INTERVAL_DOUBLESPLIT] THEN DISCH_TAC THEN
4091   MATCH_MP_TAC DSUM_BOUND THEN
4092   ASM_SIMP_TAC[NORM_REAL; VEC_COMPONENT; DIMINDEX_1; LE_REFL] THEN
4093   REAL_ARITH_TAC);;
4094
4095 (* ------------------------------------------------------------------------- *)
4096 (* A technical lemma about "refinement" of division.                         *)
4097 (* ------------------------------------------------------------------------- *)
4098
4099 let TAGGED_DIVISION_FINER = prove
4100  (`!p a b:real^N d. p tagged_division_of interval[a,b] /\ gauge d
4101              ==> ?q. q tagged_division_of interval[a,b] /\ d fine q /\
4102                      !x k. (x,k) IN p /\ k SUBSET d(x) ==> (x,k) IN q`,
4103   let lemma1 = prove
4104    (`{k | ?x. (x,k) IN p} = IMAGE SND p`,
4105     REWRITE_TAC[EXTENSION; EXISTS_PAIR_THM; IN_IMAGE; IN_ELIM_THM] THEN
4106     MESON_TAC[]) in
4107   SUBGOAL_THEN
4108    `!a b:real^N d p.
4109        FINITE p
4110        ==> p tagged_partial_division_of interval[a,b] /\ gauge d
4111            ==> ?q. q tagged_division_of (UNIONS {k | ?x. x,k IN p}) /\
4112                    d fine q /\
4113                    !x k. (x,k) IN p /\ k SUBSET d(x) ==> (x,k) IN q`
4114   ASSUME_TAC THENL
4115    [ALL_TAC;
4116     REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
4117     GEN_REWRITE_TAC LAND_CONV [tagged_division_of] THEN
4118     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (SUBST1_TAC o SYM)) THEN
4119     FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[IMP_IMP]) THEN
4120     ASM_MESON_TAC[tagged_partial_division_of]] THEN
4121   GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN
4122   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN CONJ_TAC THENL
4123    [DISCH_THEN(K ALL_TAC) THEN
4124     REWRITE_TAC[SET_RULE `UNIONS {k | ?x. x,k IN {}} = {}`] THEN
4125     EXISTS_TAC `{}:real^N#(real^N->bool)->bool` THEN
4126     REWRITE_TAC[fine; NOT_IN_EMPTY; TAGGED_DIVISION_OF_EMPTY];
4127     ALL_TAC] THEN
4128   GEN_REWRITE_TAC I [FORALL_PAIR_THM] THEN MAP_EVERY X_GEN_TAC
4129    [`x:real^N`; `k:real^N->bool`; `p:real^N#(real^N->bool)->bool`] THEN
4130   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
4131   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ANTS_TAC THENL
4132    [ASM_REWRITE_TAC[] THEN MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_SUBSET THEN
4133     EXISTS_TAC `(x:real^N,k:real^N->bool) INSERT p` THEN ASM SET_TAC[];
4134     ALL_TAC] THEN
4135   DISCH_THEN(X_CHOOSE_THEN `q1:real^N#(real^N->bool)->bool`
4136     STRIP_ASSUME_TAC) THEN
4137   SUBGOAL_THEN
4138    `UNIONS {l:real^N->bool | ?y:real^N. (y,l) IN (x,k) INSERT p} =
4139     k UNION UNIONS {l | ?y. (y,l) IN p}`
4140   SUBST1_TAC THENL
4141    [GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_UNION; IN_UNIONS] THEN
4142     REWRITE_TAC[IN_ELIM_THM; IN_INSERT; PAIR_EQ] THEN MESON_TAC[];
4143     ALL_TAC] THEN
4144   SUBGOAL_THEN `?u v:real^N. k = interval[u,v]` MP_TAC THENL
4145    [ASM_MESON_TAC[IN_INSERT; tagged_partial_division_of]; ALL_TAC] THEN
4146   DISCH_THEN(REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) THEN
4147   ASM_CASES_TAC `interval[u,v] SUBSET ((d:real^N->real^N->bool) x)` THENL
4148    [EXISTS_TAC `{(x:real^N,interval[u:real^N,v])} UNION q1` THEN CONJ_TAC THENL
4149      [MATCH_MP_TAC TAGGED_DIVISION_UNION THEN ASM_REWRITE_TAC[] THEN
4150       CONJ_TAC THENL
4151        [MATCH_MP_TAC TAGGED_DIVISION_OF_SELF THEN
4152         FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I
4153          [tagged_partial_division_of]) THEN
4154         REWRITE_TAC[IN_INSERT; PAIR_EQ] THEN MESON_TAC[];
4155         ALL_TAC];
4156       CONJ_TAC THENL
4157        [MATCH_MP_TAC FINE_UNION THEN ASM_REWRITE_TAC[] THEN
4158         REWRITE_TAC[fine; IN_SING; PAIR_EQ] THEN ASM_MESON_TAC[];
4159         ALL_TAC] THEN
4160       ASM_REWRITE_TAC[IN_INSERT; PAIR_EQ; IN_UNION; IN_SING] THEN
4161       ASM_MESON_TAC[]];
4162     FIRST_ASSUM(MP_TAC o SPECL [`u:real^N`; `v:real^N`] o MATCH_MP
4163       FINE_DIVISION_EXISTS) THEN
4164     DISCH_THEN(X_CHOOSE_THEN `q2:real^N#(real^N->bool)->bool`
4165       STRIP_ASSUME_TAC) THEN
4166     EXISTS_TAC `q2 UNION q1:real^N#(real^N->bool)->bool` THEN CONJ_TAC THENL
4167      [MATCH_MP_TAC TAGGED_DIVISION_UNION THEN ASM_REWRITE_TAC[];
4168       ASM_SIMP_TAC[FINE_UNION] THEN
4169       ASM_REWRITE_TAC[IN_INSERT; PAIR_EQ; IN_UNION; IN_SING] THEN
4170       ASM_MESON_TAC[]]] THEN
4171   (MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
4172    REWRITE_TAC[lemma1; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
4173    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I
4174       [tagged_partial_division_of]) THEN
4175    REWRITE_TAC[IN_INSERT; FINITE_INSERT; PAIR_EQ] THEN
4176    STRIP_TAC THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN CONJ_TAC THENL
4177     [REWRITE_TAC[INTERIOR_CLOSED_INTERVAL; OPEN_INTERVAL]; ALL_TAC] THEN
4178    CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
4179    REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
4180    ASM_MESON_TAC[]));;
4181
4182 (* ------------------------------------------------------------------------- *)
4183 (* Hence the main theorem about negligible sets.                             *)
4184 (* ------------------------------------------------------------------------- *)
4185
4186 let HAS_INTEGRAL_NEGLIGIBLE = prove
4187  (`!f:real^M->real^N s t.
4188         negligible s /\ (!x. x IN (t DIFF s) ==> f x = vec 0)
4189         ==> (f has_integral (vec 0)) t`,
4190   let lemma = prove
4191    (`!f:B->real g:A#B->real s t.
4192           FINITE s /\ FINITE t /\
4193           (!x y. (x,y) IN t ==> &0 <= g(x,y)) /\
4194           (!y. y IN s ==> ?x. (x,y) IN t /\ f(y) <= g(x,y))
4195           ==> sum s f <= sum t g`,
4196     REPEAT STRIP_TAC THEN MATCH_MP_TAC SUM_LE_INCLUDED THEN
4197     EXISTS_TAC `SND:A#B->B` THEN
4198     REWRITE_TAC[EXISTS_PAIR_THM; FORALL_PAIR_THM] THEN
4199     ASM_MESON_TAC[]) in
4200   SUBGOAL_THEN
4201    `!f:real^M->real^N s a b.
4202         negligible s /\ (!x. ~(x IN s) ==> f x = vec 0)
4203         ==> (f has_integral (vec 0)) (interval[a,b])`
4204   ASSUME_TAC THENL
4205    [ALL_TAC;
4206     REWRITE_TAC[IN_DIFF] THEN REPEAT STRIP_TAC THEN
4207     ONCE_REWRITE_TAC[has_integral_alt] THEN COND_CASES_TAC THENL
4208      [MATCH_MP_TAC HAS_INTEGRAL_EQ THEN
4209       EXISTS_TAC `\x. if x IN t then (f:real^M->real^N) x else vec 0` THEN
4210       SIMP_TAC[] THEN
4211       FIRST_X_ASSUM(CHOOSE_THEN(CHOOSE_THEN SUBST_ALL_TAC)) THEN
4212       FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[];
4213       ALL_TAC] THEN
4214     GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN
4215     REWRITE_TAC[REAL_LT_01] THEN
4216     REPEAT STRIP_TAC THEN EXISTS_TAC `vec 0:real^N` THEN
4217     ASM_REWRITE_TAC[NORM_0; VECTOR_SUB_REFL] THEN
4218     FIRST_X_ASSUM MATCH_MP_TAC THEN
4219     EXISTS_TAC `s:real^M->bool` THEN ASM_MESON_TAC[]] THEN
4220   REWRITE_TAC[negligible; has_integral; RIGHT_FORALL_IMP_THM] THEN
4221   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
4222   MAP_EVERY(fun t -> MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC t)
4223    [`a:real^M`; `b:real^M`] THEN
4224   REWRITE_TAC[VECTOR_SUB_RZERO] THEN DISCH_TAC THEN
4225   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
4226   FIRST_X_ASSUM(MP_TAC o GEN `n:num` o
4227       SPEC `e / &2 / ((&n + &1) * &2 pow n)`) THEN
4228   REWRITE_TAC[real_div; REAL_MUL_POS_LT] THEN REWRITE_TAC[GSYM real_div] THEN
4229   ASM_SIMP_TAC[REAL_LT_INV_EQ; REAL_LT_MUL; REAL_POW_LT; REAL_OF_NUM_LT;
4230            FORALL_AND_THM; ARITH; REAL_ARITH `&0 < &n + &1`; SKOLEM_THM] THEN
4231   DISCH_THEN(X_CHOOSE_THEN `d:num->real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
4232   EXISTS_TAC `\x. (d:num->real^M->real^M->bool)
4233                   (num_of_int(int_of_real(floor(norm(f x:real^N))))) x` THEN
4234   CONJ_TAC THENL [REWRITE_TAC[gauge] THEN ASM_MESON_TAC[gauge]; ALL_TAC] THEN
4235   X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN
4236   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
4237   ASM_CASES_TAC `p:real^M#(real^M->bool)->bool = {}` THEN
4238   ASM_REWRITE_TAC[VSUM_CLAUSES; NORM_0] THEN
4239   MP_TAC(SPEC `sup(IMAGE (\(x,k:real^M->bool). norm((f:real^M->real^N) x)) p)`
4240     REAL_ARCH_SIMPLE) THEN
4241   ASM_SIMP_TAC[REAL_SUP_LE_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
4242   REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN
4243   DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
4244   MP_TAC(GEN `i:num`
4245    (ISPECL [`p:real^M#(real^M->bool)->bool`; `a:real^M`; `b:real^M`;
4246                 `(d:num->real^M->real^M->bool) i`]
4247                 TAGGED_DIVISION_FINER)) THEN
4248   ASM_REWRITE_TAC[SKOLEM_THM; RIGHT_IMP_EXISTS_THM; FORALL_AND_THM] THEN
4249   DISCH_THEN(X_CHOOSE_THEN `q:num->real^M#(real^M->bool)->bool`
4250         STRIP_ASSUME_TAC) THEN
4251   MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC
4252    `sum(0..N+1) (\i. (&i + &1) *
4253                      norm(vsum (q i) (\(x:real^M,k:real^M->bool).
4254                                             content k % indicator s x)))` THEN
4255   CONJ_TAC THENL
4256    [ALL_TAC;
4257     MATCH_MP_TAC REAL_LET_TRANS THEN
4258     EXISTS_TAC `sum (0..N+1) (\i. e / &2 / &2 pow i)` THEN CONJ_TAC THENL
4259      [ALL_TAC;
4260       REWRITE_TAC[real_div; SUM_LMUL; GSYM REAL_POW_INV] THEN
4261       REWRITE_TAC[SUM_GP; LT] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
4262       REWRITE_TAC[REAL_ARITH `(e * &1 / &2) * (&1 - x) / (&1 / &2) < e <=>
4263                                 &0 < e * x`] THEN
4264       ASM_SIMP_TAC[REAL_LT_MUL; REAL_POW_LT; REAL_ARITH `&0 < &1 / &2`]] THEN
4265     MATCH_MP_TAC SUM_LE_NUMSEG THEN REPEAT STRIP_TAC THEN
4266     REWRITE_TAC[] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
4267     ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
4268     REWRITE_TAC[real_div] THEN ONCE_REWRITE_TAC[GSYM REAL_MUL_ASSOC] THEN
4269     REWRITE_TAC[GSYM REAL_INV_MUL] THEN REWRITE_TAC[GSYM real_div] THEN
4270     ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN MATCH_MP_TAC REAL_LT_IMP_LE THEN
4271     FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]] THEN
4272   FIRST_ASSUM(ASSUME_TAC o GEN `i:num` o
4273     MATCH_MP TAGGED_DIVISION_OF_FINITE o SPEC `i:num`) THEN
4274   ASM_SIMP_TAC[VSUM_REAL; NORM_LIFT] THEN
4275   REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM; DROP_CMUL] THEN
4276   REWRITE_TAC[real_abs] THEN
4277   SUBGOAL_THEN
4278    `!i:num. &0 <= sum (q i) (\(x:real^M,y:real^M->bool).
4279               content y * drop (indicator s x))`
4280   ASSUME_TAC THENL
4281    [REPEAT GEN_TAC THEN MATCH_MP_TAC SUM_POS_LE THEN
4282     ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
4283     REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_MUL THEN
4284     REWRITE_TAC[DROP_INDICATOR_POS_LE] THEN
4285     ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE];
4286     ALL_TAC] THEN
4287   ASM_REWRITE_TAC[GSYM SUM_LMUL] THEN
4288   REWRITE_TAC[LAMBDA_PAIR_THM] THEN
4289   W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
4290   ASM_REWRITE_TAC[] THEN
4291   MATCH_MP_TAC(REAL_ARITH `x <= y ==> n <= x ==> n <= y`) THEN
4292   ASM_SIMP_TAC[SUM_SUM_PRODUCT; FINITE_NUMSEG] THEN
4293   MATCH_MP_TAC lemma THEN
4294   ASM_SIMP_TAC[FINITE_PRODUCT_DEPENDENT; FORALL_PAIR_THM; FINITE_NUMSEG] THEN
4295   REWRITE_TAC[IN_ELIM_PAIR_THM] THEN CONJ_TAC THENL
4296    [REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN
4297     CONJ_TAC THENL [REAL_ARITH_TAC; MATCH_MP_TAC REAL_LE_MUL] THEN
4298     REWRITE_TAC[DROP_INDICATOR_POS_LE] THEN
4299     ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE];
4300     ALL_TAC] THEN
4301   MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
4302   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
4303   DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `k:real^M->bool`]) THEN
4304   ASM_REWRITE_TAC[] THEN ABBREV_TAC
4305    `n = num_of_int(int_of_real(floor(norm((f:real^M->real^N) x))))` THEN
4306   SUBGOAL_THEN `&n <= norm((f:real^M->real^N) x) /\
4307                 norm(f x) < &n + &1`
4308   STRIP_ASSUME_TAC THENL
4309    [SUBGOAL_THEN `&n = floor(norm((f:real^M->real^N) x))`
4310      (fun th -> MESON_TAC[th; FLOOR]) THEN
4311     EXPAND_TAC "n" THEN
4312     MP_TAC(ISPEC `norm((f:real^M->real^N) x)` FLOOR_POS) THEN
4313     REWRITE_TAC[NORM_POS_LE; LEFT_IMP_EXISTS_THM] THEN
4314     X_GEN_TAC `m:num` THEN DISCH_THEN SUBST1_TAC THEN
4315     REWRITE_TAC[GSYM int_of_num; NUM_OF_INT_OF_NUM];
4316     ALL_TAC] THEN
4317   DISCH_TAC THEN EXISTS_TAC `n:num` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
4318    [ASM_SIMP_TAC[IN_NUMSEG; LE_0] THEN
4319     REWRITE_TAC[GSYM REAL_OF_NUM_LE; GSYM REAL_OF_NUM_ADD] THEN
4320     MATCH_MP_TAC REAL_LE_TRANS THEN
4321     EXISTS_TAC `norm((f:real^M->real^N) x)` THEN ASM_REWRITE_TAC[] THEN
4322     MATCH_MP_TAC(REAL_ARITH `x <= n ==> x <= n + &1`) THEN
4323     ASM_MESON_TAC[];
4324     ALL_TAC] THEN
4325   ASM_CASES_TAC `(x:real^M) IN s` THEN ASM_SIMP_TAC[indicator] THEN
4326   REWRITE_TAC[DROP_VEC; REAL_MUL_RZERO; NORM_0;
4327               VECTOR_MUL_RZERO; REAL_LE_REFL] THEN
4328   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
4329   REWRITE_TAC[DROP_VEC; REAL_MUL_RID; NORM_MUL] THEN
4330   SUBGOAL_THEN `&0 <= content(k:real^M->bool)` ASSUME_TAC THENL
4331    [ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE]; ALL_TAC] THEN
4332   ASM_REWRITE_TAC[real_abs] THEN MATCH_MP_TAC REAL_LE_LMUL THEN
4333   ASM_SIMP_TAC[REAL_LT_IMP_LE]);;
4334
4335 let HAS_INTEGRAL_SPIKE = prove
4336  (`!f:real^M->real^N g s t.
4337         negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x) /\
4338         (f has_integral y) t
4339         ==> (g has_integral y) t`,
4340   SUBGOAL_THEN
4341    `!f:real^M->real^N g s a b y.
4342         negligible s /\ (!x. x IN (interval[a,b] DIFF s) ==> g x = f x)
4343         ==> (f has_integral y) (interval[a,b])
4344             ==> (g has_integral y) (interval[a,b])`
4345   ASSUME_TAC THENL
4346    [REPEAT STRIP_TAC THEN
4347     SUBGOAL_THEN
4348      `((\x. (f:real^M->real^N)(x) + (g(x) - f(x))) has_integral (y + vec 0))
4349       (interval[a,b])`
4350     MP_TAC THENL
4351      [ALL_TAC;
4352       REWRITE_TAC[VECTOR_ARITH `f + g - f = g /\ f + vec 0 = f`; ETA_AX]] THEN
4353     MATCH_MP_TAC HAS_INTEGRAL_ADD THEN ASM_REWRITE_TAC[] THEN
4354     MATCH_MP_TAC HAS_INTEGRAL_NEGLIGIBLE THEN
4355     EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[VECTOR_SUB_EQ] THEN
4356     ASM_MESON_TAC[];
4357     ALL_TAC] THEN
4358   REPEAT GEN_TAC THEN
4359   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
4360   ONCE_REWRITE_TAC[has_integral_alt] THEN COND_CASES_TAC THEN
4361   ASM_REWRITE_TAC[] THENL
4362    [FIRST_X_ASSUM(CHOOSE_THEN(CHOOSE_THEN SUBST_ALL_TAC)) THEN ASM_MESON_TAC[];
4363     ALL_TAC] THEN
4364   MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
4365   REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
4366   MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
4367   REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
4368   MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
4369   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
4370   MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
4371   FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `s:real^M->bool` THEN
4372   ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);;
4373
4374 let HAS_INTEGRAL_SPIKE_EQ = prove
4375  (`!f:real^M->real^N g s t y.
4376         negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x)
4377         ==> ((f has_integral y) t <=> (g has_integral y) t)`,
4378   REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THEN
4379   MATCH_MP_TAC HAS_INTEGRAL_SPIKE THENL
4380    [EXISTS_TAC `f:real^M->real^N`; EXISTS_TAC `g:real^M->real^N`] THEN
4381   EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN
4382   ASM_MESON_TAC[NORM_SUB]);;
4383
4384 let INTEGRABLE_SPIKE = prove
4385  (`!f:real^M->real^N g s t.
4386         negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x)
4387         ==> f integrable_on t ==> g integrable_on  t`,
4388   REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[integrable_on] THEN
4389   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
4390   MP_TAC(SPEC_ALL HAS_INTEGRAL_SPIKE) THEN ASM_REWRITE_TAC[]);;
4391
4392 let INTEGRAL_SPIKE = prove
4393  (`!f:real^M->real^N g s t y.
4394         negligible s /\ (!x. x IN (t DIFF s) ==> g x = f x)
4395         ==> integral t f = integral t g`,
4396   REPEAT STRIP_TAC THEN REWRITE_TAC[integral] THEN
4397   AP_TERM_TAC THEN ABS_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_EQ THEN
4398   ASM_MESON_TAC[]);;
4399
4400 (* ------------------------------------------------------------------------- *)
4401 (* Some other trivialities about negligible sets.                            *)
4402 (* ------------------------------------------------------------------------- *)
4403
4404 let NEGLIGIBLE_SUBSET = prove
4405  (`!s:real^N->bool t:real^N->bool.
4406         negligible s /\ t SUBSET s ==> negligible t`,
4407   REPEAT STRIP_TAC THEN REWRITE_TAC[negligible] THEN
4408   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
4409   MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN
4410   MAP_EVERY EXISTS_TAC [`(\x. vec 0):real^N->real^1`; `s:real^N->bool`] THEN
4411   ASM_REWRITE_TAC[HAS_INTEGRAL_0] THEN
4412   REWRITE_TAC[indicator] THEN ASM SET_TAC[]);;
4413
4414 let NEGLIGIBLE_DIFF = prove
4415  (`!s t:real^N->bool. negligible s ==> negligible(s DIFF t)`,
4416   REPEAT STRIP_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN
4417   EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[SUBSET_DIFF]);;
4418
4419 let NEGLIGIBLE_INTER = prove
4420  (`!s t. negligible s \/ negligible t ==> negligible(s INTER t)`,
4421   MESON_TAC[NEGLIGIBLE_SUBSET; INTER_SUBSET]);;
4422
4423 let NEGLIGIBLE_UNION = prove
4424  (`!s t:real^N->bool.
4425         negligible s /\ negligible t ==> negligible (s UNION t)`,
4426   REPEAT GEN_TAC THEN DISCH_TAC THEN FIRST_ASSUM MP_TAC THEN
4427   REWRITE_TAC[negligible; AND_FORALL_THM] THEN
4428   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `a:real^N` THEN
4429   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `b:real^N` THEN
4430   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_ADD) THEN
4431   REWRITE_TAC[VECTOR_ADD_LID] THEN MATCH_MP_TAC EQ_IMP THEN
4432   MATCH_MP_TAC HAS_INTEGRAL_SPIKE_EQ THEN
4433   EXISTS_TAC `s:real^N->bool` THEN ASM_REWRITE_TAC[] THEN
4434   SIMP_TAC[indicator; IN_UNION; IN_DIFF; VECTOR_ADD_LID]);;
4435
4436 let NEGLIGIBLE_UNION_EQ = prove
4437  (`!s t:real^N->bool.
4438         negligible (s UNION t) <=> negligible s /\ negligible t`,
4439   MESON_TAC[NEGLIGIBLE_UNION; SUBSET_UNION; NEGLIGIBLE_SUBSET]);;
4440
4441 let NEGLIGIBLE_SING = prove
4442  (`!a:real^N. negligible {a}`,
4443   GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN
4444   EXISTS_TAC `{x | (x:real^N)$1 = (a:real^N)$1}` THEN
4445   SIMP_TAC[NEGLIGIBLE_STANDARD_HYPERPLANE; LE_REFL; DIMINDEX_GE_1] THEN
4446   SET_TAC[]);;
4447
4448 let NEGLIGIBLE_INSERT = prove
4449  (`!a:real^N s. negligible(a INSERT s) <=> negligible s`,
4450   ONCE_REWRITE_TAC[SET_RULE `a INSERT s = {a} UNION s`] THEN
4451   REWRITE_TAC[NEGLIGIBLE_UNION_EQ; NEGLIGIBLE_SING]);;
4452
4453 let NEGLIGIBLE_EMPTY = prove
4454  (`negligible {}`,
4455   MESON_TAC[EMPTY_SUBSET; NEGLIGIBLE_SUBSET; NEGLIGIBLE_SING]);;
4456
4457 let NEGLIGIBLE_FINITE = prove
4458  (`!s. FINITE s ==> negligible s`,
4459   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
4460   SIMP_TAC[NEGLIGIBLE_EMPTY; NEGLIGIBLE_INSERT]);;
4461
4462 let NEGLIGIBLE_UNIONS = prove
4463  (`!s. FINITE s /\ (!t. t IN s ==> negligible t)
4464        ==> negligible(UNIONS s)`,
4465   REWRITE_TAC[IMP_CONJ] THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
4466   REWRITE_TAC[UNIONS_0; UNIONS_INSERT; NEGLIGIBLE_EMPTY; IN_INSERT] THEN
4467   SIMP_TAC[NEGLIGIBLE_UNION]);;
4468
4469 let NEGLIGIBLE = prove
4470  (`!s:real^N->bool. negligible s <=> !t. (indicator s has_integral vec 0) t`,
4471   GEN_TAC THEN EQ_TAC THENL
4472    [ALL_TAC; REWRITE_TAC[negligible] THEN SIMP_TAC[]] THEN
4473   DISCH_TAC THEN GEN_TAC THEN ONCE_REWRITE_TAC[has_integral_alt] THEN
4474   COND_CASES_TAC THENL [ASM_MESON_TAC[negligible]; ALL_TAC] THEN
4475   GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
4476   REPEAT STRIP_TAC THEN EXISTS_TAC `vec 0:real^1` THEN
4477   MP_TAC(ISPECL [`s:real^N->bool`; `s INTER t:real^N->bool`]
4478         NEGLIGIBLE_SUBSET) THEN
4479   ASM_REWRITE_TAC[INTER_SUBSET; negligible; VECTOR_SUB_REFL; NORM_0] THEN
4480   REWRITE_TAC[indicator; IN_INTER] THEN
4481   SIMP_TAC[TAUT `(if p /\ q then r else s) =
4482                  (if q then if p then r else s else s)`]);;
4483
4484 (* ------------------------------------------------------------------------- *)
4485 (* Finite or empty cases of the spike theorem are quite commonly needed.     *)
4486 (* ------------------------------------------------------------------------- *)
4487
4488 let HAS_INTEGRAL_SPIKE_FINITE = prove
4489  (`!f:real^M->real^N g s t y.
4490         FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x) /\
4491         (f has_integral y) t
4492         ==> (g has_integral y) t`,
4493   MESON_TAC[HAS_INTEGRAL_SPIKE; NEGLIGIBLE_FINITE]);;
4494
4495 let HAS_INTEGRAL_SPIKE_FINITE_EQ = prove
4496  (`!f:real^M->real^N g s y.
4497         FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x)
4498         ==> ((f has_integral y) t <=> (g has_integral y) t)`,
4499   MESON_TAC[HAS_INTEGRAL_SPIKE_FINITE]);;
4500
4501 let INTEGRABLE_SPIKE_FINITE = prove
4502  (`!f:real^M->real^N g s.
4503         FINITE s /\ (!x. x IN (t DIFF s) ==> g x = f x)
4504         ==> f integrable_on t
4505             ==> g integrable_on  t`,
4506   REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[integrable_on] THEN
4507   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
4508   MP_TAC(SPEC_ALL HAS_INTEGRAL_SPIKE_FINITE) THEN ASM_REWRITE_TAC[]);;
4509
4510 let INTEGRAL_EQ = prove
4511  (`!f:real^M->real^N g s.
4512         (!x. x IN s ==> f x = g x) ==> integral s f = integral s g`,
4513   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_SPIKE THEN
4514   EXISTS_TAC `{}:real^M->bool` THEN ASM_SIMP_TAC[NEGLIGIBLE_EMPTY; IN_DIFF]);;
4515
4516 let INTEGRAL_EQ_0 = prove
4517  (`!f:real^M->real^N s. (!x. x IN s ==> f x = vec 0) ==> integral s f = vec 0`,
4518   REPEAT STRIP_TAC THEN MATCH_MP_TAC EQ_TRANS THEN
4519   EXISTS_TAC `integral s ((\x. vec 0):real^M->real^N)` THEN
4520   CONJ_TAC THENL
4521    [MATCH_MP_TAC INTEGRAL_EQ THEN ASM_REWRITE_TAC[];
4522     REWRITE_TAC[INTEGRAL_0]]);;
4523
4524 (* ------------------------------------------------------------------------- *)
4525 (* In particular, the boundary of an interval is negligible.                 *)
4526 (* ------------------------------------------------------------------------- *)
4527
4528 let NEGLIGIBLE_FRONTIER_INTERVAL = prove
4529  (`!a b:real^N. negligible(interval[a,b] DIFF interval(a,b))`,
4530   REPEAT GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN
4531   EXISTS_TAC `UNIONS (IMAGE (\k. {x:real^N | x$k = (a:real^N)$k} UNION
4532                                  {x:real^N | x$k = (b:real^N)$k})
4533                             (1..dimindex(:N)))` THEN
4534   CONJ_TAC THENL
4535    [MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN
4536     SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; FORALL_IN_IMAGE] THEN
4537     SIMP_TAC[IN_NUMSEG; NEGLIGIBLE_UNION_EQ; NEGLIGIBLE_STANDARD_HYPERPLANE];
4538     REWRITE_TAC[SUBSET; IN_DIFF; IN_INTERVAL; IN_UNIONS; EXISTS_IN_IMAGE] THEN
4539     REWRITE_TAC[IN_NUMSEG; IN_UNION; IN_ELIM_THM; REAL_LT_LE] THEN
4540     MESON_TAC[]]);;
4541
4542 let HAS_INTEGRAL_SPIKE_INTERIOR = prove
4543  (`!f:real^M->real^N g a b y.
4544         (!x. x IN interval(a,b) ==> g x = f x) /\
4545         (f has_integral y) (interval[a,b])
4546         ==> (g has_integral y) (interval[a,b])`,
4547   REPEAT GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN DISCH_TAC THEN
4548   MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
4549                            HAS_INTEGRAL_SPIKE) THEN
4550   EXISTS_TAC `interval[a:real^M,b] DIFF interval(a,b)` THEN
4551   REWRITE_TAC[NEGLIGIBLE_FRONTIER_INTERVAL] THEN ASM SET_TAC[]);;
4552
4553 let HAS_INTEGRAL_SPIKE_INTERIOR_EQ = prove
4554  (`!f:real^M->real^N g a b y.
4555         (!x. x IN interval(a,b) ==> g x = f x)
4556         ==> ((f has_integral y) (interval[a,b]) <=>
4557              (g has_integral y) (interval[a,b]))`,
4558   MESON_TAC[HAS_INTEGRAL_SPIKE_INTERIOR]);;
4559
4560 let INTEGRABLE_SPIKE_INTERIOR = prove
4561  (`!f:real^M->real^N g a b.
4562         (!x. x IN interval(a,b) ==> g x = f x)
4563         ==> f integrable_on (interval[a,b])
4564             ==> g integrable_on  (interval[a,b])`,
4565   REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[integrable_on] THEN
4566   MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
4567   MP_TAC(SPEC_ALL HAS_INTEGRAL_SPIKE_INTERIOR) THEN ASM_REWRITE_TAC[]);;
4568
4569 (* ------------------------------------------------------------------------- *)
4570 (* Integrability of continuous functions.                                    *)
4571 (* ------------------------------------------------------------------------- *)
4572
4573 let NEUTRAL_AND = prove
4574  (`neutral(/\) = T`,
4575   REWRITE_TAC[neutral; FORALL_BOOL_THM] THEN MESON_TAC[]);;
4576
4577 let MONOIDAL_AND = prove
4578  (`monoidal(/\)`,
4579   REWRITE_TAC[monoidal; NEUTRAL_AND; CONJ_ACI]);;
4580
4581 let ITERATE_AND = prove
4582  (`!p s. FINITE s ==> (iterate(/\) s p <=> !x. x IN s ==> p x)`,
4583   GEN_TAC THEN MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
4584   ASM_SIMP_TAC[MONOIDAL_AND; NEUTRAL_AND; ITERATE_CLAUSES] THEN SET_TAC[]);;
4585
4586 let OPERATIVE_DIVISION_AND = prove
4587  (`!P d a b. operative(/\) P /\ d division_of interval[a,b]
4588              ==> ((!i. i IN d ==> P i) <=> P(interval[a,b]))`,
4589   REPEAT GEN_TAC THEN DISCH_THEN(ASSUME_TAC o CONJ MONOIDAL_AND) THEN
4590   FIRST_ASSUM(MP_TAC o MATCH_MP OPERATIVE_DIVISION) THEN
4591   ASM_MESON_TAC[ITERATE_AND; DIVISION_OF_FINITE]);;
4592
4593 let OPERATIVE_APPROXIMABLE = prove
4594  (`!f:real^M->real^N e.
4595         &0 <= e
4596         ==> operative(/\)
4597                (\i. ?g. (!x. x IN i ==> norm (f x - g x) <= e) /\
4598                         g integrable_on i)`,
4599   REPEAT STRIP_TAC THEN REWRITE_TAC[operative; NEUTRAL_AND] THEN CONJ_TAC THENL
4600    [REPEAT STRIP_TAC THEN EXISTS_TAC `f:real^M->real^N` THEN
4601     ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0; integrable_on] THEN
4602     ASM_MESON_TAC[HAS_INTEGRAL_NULL];
4603     ALL_TAC] THEN
4604   MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`; `c:real`; `k:num`] THEN
4605   STRIP_TAC THEN EQ_TAC THENL
4606    [ASM_MESON_TAC[INTEGRABLE_SPLIT; IN_INTER]; ALL_TAC] THEN
4607   DISCH_THEN(CONJUNCTS_THEN2
4608    (X_CHOOSE_THEN `g1:real^M->real^N` STRIP_ASSUME_TAC)
4609    (X_CHOOSE_THEN `g2:real^M->real^N` STRIP_ASSUME_TAC)) THEN
4610   EXISTS_TAC `\x. if x$k = c then (f:real^M->real^N)(x) else
4611                   if x$k <= c then g1(x) else g2(x)` THEN
4612   CONJ_TAC THENL
4613    [GEN_TAC THEN STRIP_TAC THEN REWRITE_TAC[] THEN
4614     COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN
4615     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTER; IN_ELIM_THM]) THEN
4616     ASM_MESON_TAC[REAL_ARITH `x <= c \/ x >= c`];
4617     ALL_TAC] THEN
4618   SUBGOAL_THEN
4619    `(\x:real^M. if x$k = c then f x else if x$k <= c then g1 x else g2 x)
4620     integrable_on (interval[u,v] INTER {x | x$k <= c}) /\
4621     (\x. if x$k = c then f x :real^N else if x$k <= c then g1 x else g2 x)
4622     integrable_on (interval[u,v] INTER {x | x$k >= c})`
4623   MP_TAC THENL
4624    [ALL_TAC;
4625     REWRITE_TAC[integrable_on] THEN ASM_MESON_TAC[HAS_INTEGRAL_SPLIT]] THEN
4626   CONJ_TAC THENL
4627    [UNDISCH_TAC
4628      `(g1:real^M->real^N) integrable_on (interval[u,v] INTER {x | x$k <= c})`;
4629     UNDISCH_TAC
4630     `(g2:real^M->real^N) integrable_on (interval[u,v] INTER {x | x$k >= c})`
4631    ] THEN
4632   ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MATCH_MP_TAC INTEGRABLE_SPIKE THEN
4633   ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THEN
4634   EXISTS_TAC `{x:real^M | x$k = c}` THEN
4635   ASM_SIMP_TAC[NEGLIGIBLE_STANDARD_HYPERPLANE; IN_DIFF; IN_INTER; IN_ELIM_THM;
4636                REAL_ARITH `x >= c /\ ~(x = c) ==> ~(x <= c)`] THEN
4637   EXISTS_TAC `e:real` THEN REPEAT STRIP_TAC THEN
4638   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[IN_INTER; IN_ELIM_THM]);;
4639
4640 let APPROXIMABLE_ON_DIVISION = prove
4641  (`!f:real^M->real^N d a b.
4642         &0 <= e /\
4643         (d division_of interval[a,b]) /\
4644         (!i. i IN d
4645              ==> ?g. (!x. x IN i ==> norm (f x - g x) <= e) /\
4646                      g integrable_on i)
4647         ==> ?g. (!x. x IN interval[a,b] ==> norm (f x - g x) <= e) /\
4648                 g integrable_on interval[a,b]`,
4649   REPEAT STRIP_TAC THEN
4650   MP_TAC(ISPECL [`(/\)`; `d:(real^M->bool)->bool`;
4651                  `a:real^M`; `b:real^M`;
4652                  `\i. ?g:real^M->real^N.
4653                        (!x. x IN i ==> norm (f x - g x) <= e) /\
4654                        g integrable_on i`]
4655                 OPERATIVE_DIVISION) THEN
4656   ASM_SIMP_TAC[OPERATIVE_APPROXIMABLE; MONOIDAL_AND] THEN
4657   DISCH_THEN(SUBST1_TAC o SYM) THEN
4658   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
4659   ASM_SIMP_TAC[ITERATE_AND]);;
4660
4661 let INTEGRABLE_CONTINUOUS = prove
4662  (`!f:real^M->real^N a b.
4663         f continuous_on interval[a,b] ==> f integrable_on interval[a,b]`,
4664   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_UNIFORM_LIMIT THEN
4665   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
4666   MATCH_MP_TAC APPROXIMABLE_ON_DIVISION THEN
4667   ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN
4668   FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
4669     COMPACT_UNIFORMLY_CONTINUOUS)) THEN
4670   REWRITE_TAC[COMPACT_INTERVAL; uniformly_continuous_on] THEN
4671   DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[dist] THEN
4672   DISCH_THEN(X_CHOOSE_THEN `d:real` STRIP_ASSUME_TAC) THEN
4673   SUBGOAL_THEN
4674    `?p. p tagged_division_of interval[a:real^M,b] /\ (\x. ball(x,d)) fine p`
4675   STRIP_ASSUME_TAC THENL
4676    [ASM_MESON_TAC[FINE_DIVISION_EXISTS; GAUGE_BALL]; ALL_TAC] THEN
4677   EXISTS_TAC `IMAGE SND (p:real^M#(real^M->bool)->bool)` THEN
4678   ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION] THEN
4679   REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN
4680   MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
4681   DISCH_TAC THEN EXISTS_TAC `\y:real^M. (f:real^M->real^N) x` THEN
4682   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
4683   DISCH_THEN(MP_TAC o
4684     SPECL [`x:real^M`; `l:real^M->bool`] o el 1 o CONJUNCTS) THEN
4685   ASM_REWRITE_TAC[SUBSET] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4686   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
4687   REWRITE_TAC[SUBSET; IN_BALL; dist] THEN
4688    FIRST_X_ASSUM SUBST_ALL_TAC THEN REPEAT STRIP_TAC THENL
4689    [ASM_MESON_TAC[REAL_LT_IMP_LE; NORM_SUB];
4690     REWRITE_TAC[integrable_on] THEN
4691     EXISTS_TAC `content(interval[a':real^M,b']) % (f:real^M->real^N) x` THEN
4692     REWRITE_TAC[HAS_INTEGRAL_CONST]]);;
4693
4694 (* ------------------------------------------------------------------------- *)
4695 (* Specialization of additivity to one dimension.                            *)
4696 (* ------------------------------------------------------------------------- *)
4697
4698 let OPERATIVE_1_LT = prove
4699  (`!op. monoidal op
4700         ==> !f. operative op f <=>
4701                 (!a b. drop b <= drop a ==> f(interval[a,b]) = neutral op) /\
4702                 (!a b c. drop a < drop c /\ drop c < drop b
4703                          ==> op (f(interval[a,c])) (f(interval[c,b])) =
4704                              f(interval[a,b]))`,
4705   REPEAT STRIP_TAC THEN REWRITE_TAC[operative; CONTENT_EQ_0_1] THEN
4706   MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> (a /\ b <=> a /\ c)`) THEN
4707   DISCH_TAC THEN REWRITE_TAC[FORALL_1; DIMINDEX_1] THEN
4708   AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `a:real^1` THEN
4709   AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `b:real^1` THEN
4710   EQ_TAC THEN DISCH_TAC THENL
4711    [X_GEN_TAC `c:real^1` THEN FIRST_ASSUM(SUBST1_TAC o SPEC `drop c`) THEN
4712     DISCH_TAC THEN FIRST_ASSUM(ASSUME_TAC o MATCH_MP REAL_LT_TRANS) THEN
4713     ASM_SIMP_TAC[INTERVAL_SPLIT; DIMINDEX_1; LE_REFL; REAL_LT_IMP_LE] THEN
4714     BINOP_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
4715     REWRITE_TAC[CONS_11; PAIR_EQ] THEN
4716     SIMP_TAC[FORALL_1; CART_EQ; DIMINDEX_1; LAMBDA_BETA; LE_REFL] THEN
4717     REWRITE_TAC[GSYM drop] THEN ASM_REAL_ARITH_TAC;
4718     ALL_TAC] THEN
4719   X_GEN_TAC `d:real` THEN ABBREV_TAC `c = lift d` THEN
4720   SUBGOAL_THEN `d = drop c` SUBST1_TAC THENL
4721    [ASM_MESON_TAC[LIFT_DROP]; ALL_TAC] THEN
4722   SIMP_TAC[INTERVAL_SPLIT; LE_REFL; drop; DIMINDEX_1] THEN
4723   REWRITE_TAC[GSYM drop] THEN
4724   DISJ_CASES_TAC(REAL_ARITH `drop c <= drop a \/ drop a < drop c`) THENL
4725    [SUBGOAL_THEN
4726      `content(interval[a:real^1,
4727         (lambda i. if i = 1 then min (drop b) (drop c) else b$i)]) = &0 /\
4728       interval[(lambda i. if i = 1 then max (drop a) (drop c) else a$i),b] =
4729       interval[a,b]`
4730     (CONJUNCTS_THEN2 MP_TAC SUBST1_TAC) THENL
4731      [CONJ_TAC THENL
4732        [SIMP_TAC[CONTENT_EQ_0_1];
4733         AP_TERM_TAC THEN REWRITE_TAC[CONS_11; PAIR_EQ]] THEN
4734       SIMP_TAC[drop; CART_EQ; FORALL_1; LAMBDA_BETA; DIMINDEX_1; LE_REFL] THEN
4735       UNDISCH_TAC `drop c <= drop a` THEN REWRITE_TAC[drop] THEN
4736       REAL_ARITH_TAC;
4737       REWRITE_TAC[CONTENT_EQ_0_1] THEN
4738       DISCH_THEN(ANTE_RES_THEN SUBST1_TAC) THEN ASM_MESON_TAC[monoidal]];
4739     ALL_TAC] THEN
4740   DISJ_CASES_TAC(REAL_ARITH `drop b <= drop c \/ drop c < drop b`) THENL
4741    [SUBGOAL_THEN
4742      `interval[a,(lambda i. if i = 1 then min (drop b) (drop c) else b$i)] =
4743       interval[a,b] /\
4744       content(interval
4745         [(lambda i. if i = 1 then max (drop a) (drop c) else a$i),b]) = &0`
4746       (CONJUNCTS_THEN2 SUBST1_TAC MP_TAC) THENL
4747      [CONJ_TAC THENL
4748        [AP_TERM_TAC THEN REWRITE_TAC[CONS_11; PAIR_EQ];
4749         SIMP_TAC[CONTENT_EQ_0_1]] THEN
4750       SIMP_TAC[drop; CART_EQ; FORALL_1; LAMBDA_BETA; DIMINDEX_1; LE_REFL] THEN
4751       UNDISCH_TAC `drop b <= drop c` THEN REWRITE_TAC[drop] THEN
4752       REAL_ARITH_TAC;
4753       REWRITE_TAC[CONTENT_EQ_0_1] THEN
4754       DISCH_THEN(ANTE_RES_THEN SUBST1_TAC) THEN ASM_MESON_TAC[monoidal]];
4755     ALL_TAC] THEN
4756   SUBGOAL_THEN
4757    `(lambda i. if i = 1 then min (drop b) (drop c) else b$i) = c /\
4758     (lambda i. if i = 1 then max (drop a) (drop c) else a$i) = c`
4759    (fun th -> REWRITE_TAC[th] THEN ASM_MESON_TAC[]) THEN
4760   SIMP_TAC[CART_EQ; FORALL_1; DIMINDEX_1; LE_REFL; LAMBDA_BETA] THEN
4761   REWRITE_TAC[GSYM drop] THEN ASM_REAL_ARITH_TAC);;
4762
4763 let OPERATIVE_1_LE = prove
4764  (`!op. monoidal op
4765         ==> !f. operative op f <=>
4766                 (!a b. drop b <= drop a ==> f(interval[a,b]) = neutral op) /\
4767                 (!a b c. drop a <= drop c /\ drop c <= drop b
4768                          ==> op (f(interval[a,c])) (f(interval[c,b])) =
4769                              f(interval[a,b]))`,
4770   GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN EQ_TAC THENL
4771    [ALL_TAC; ASM_SIMP_TAC[OPERATIVE_1_LT] THEN MESON_TAC[REAL_LT_IMP_LE]] THEN
4772   REWRITE_TAC[operative; CONTENT_EQ_0_1] THEN
4773   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
4774   REWRITE_TAC[FORALL_1; DIMINDEX_1] THEN
4775   MAP_EVERY (fun t -> MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC t)
4776    [`a:real^1`; `b:real^1`] THEN DISCH_TAC THEN
4777   X_GEN_TAC `c:real^1` THEN FIRST_ASSUM(SUBST1_TAC o SPEC `drop c`) THEN
4778   DISCH_TAC THEN FIRST_ASSUM(ASSUME_TAC o MATCH_MP REAL_LE_TRANS) THEN
4779   ASM_SIMP_TAC[INTERVAL_SPLIT; DIMINDEX_1; LE_REFL] THEN
4780   BINOP_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
4781   REWRITE_TAC[CONS_11; PAIR_EQ] THEN
4782   SIMP_TAC[FORALL_1; CART_EQ; DIMINDEX_1; LAMBDA_BETA; LE_REFL] THEN
4783   REWRITE_TAC[GSYM drop] THEN ASM_REAL_ARITH_TAC);;
4784
4785 (* ------------------------------------------------------------------------- *)
4786 (* Special case of additivity we need for the FCT.                           *)
4787 (* ------------------------------------------------------------------------- *)
4788
4789 let ADDITIVE_TAGGED_DIVISION_1 = prove
4790  (`!f:real^1->real^N p a b.
4791         drop a <= drop b /\
4792         p tagged_division_of interval[a,b]
4793         ==> vsum p
4794              (\(x,k). f(interval_upperbound k) - f(interval_lowerbound k)) =
4795             f b - f a`,
4796   REPEAT STRIP_TAC THEN
4797   MP_TAC(ISPECL
4798    [`(+):real^N->real^N->real^N`;
4799     `p:(real^1#(real^1->bool)->bool)`;
4800     `a:real^1`; `b:real^1`;
4801     `(\k. if k = {} then vec 0
4802           else f(interval_upperbound k) - f(interval_lowerbound k)):
4803      ((real^1->bool)->real^N)`] OPERATIVE_TAGGED_DIVISION) THEN
4804   ASM_SIMP_TAC[MONOIDAL_VECTOR_ADD; OPERATIVE_1_LT; NEUTRAL_VECTOR_ADD;
4805                INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
4806   ANTS_TAC THENL
4807    [ASM_SIMP_TAC[INTERVAL_EQ_EMPTY_1; REAL_ARITH `a <= b ==> ~(b < a)`;
4808                  REAL_LT_IMP_LE; CONTENT_EQ_0_1;
4809                  INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
4810     SIMP_TAC[REAL_ARITH `b <= a ==> (b < a <=> ~(b = a))`] THEN
4811     SIMP_TAC[DROP_EQ; TAUT
4812       `(if ~p then x else y) = (if p then y else x)`] THEN
4813     SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1; REAL_LE_REFL] THEN
4814     REWRITE_TAC[VECTOR_SUB_REFL; COND_ID; EQ_SYM_EQ] THEN
4815     REPEAT GEN_TAC THEN DISCH_TAC THEN
4816     FIRST_ASSUM(ASSUME_TAC o MATCH_MP REAL_LT_TRANS) THEN
4817     ASM_SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1;
4818                  REAL_ARITH `b < a ==> ~(a < b)`; REAL_LT_IMP_LE] THEN
4819     MESON_TAC[VECTOR_ARITH `(c - a) + (b - c):real^N = b - a`];
4820     ALL_TAC] THEN
4821   ASM_SIMP_TAC[INTERVAL_EQ_EMPTY_1; GSYM REAL_NOT_LE] THEN
4822   DISCH_THEN(SUBST1_TAC o SYM) THEN
4823   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
4824   ASM_SIMP_TAC[GSYM VSUM] THEN MATCH_MP_TAC VSUM_EQ THEN
4825   REWRITE_TAC[FORALL_PAIR_THM] THEN
4826   ASM_MESON_TAC[TAGGED_DIVISION_OF; MEMBER_NOT_EMPTY]);;
4827
4828 (* ------------------------------------------------------------------------- *)
4829 (* A useful lemma allowing us to factor out the content size.                *)
4830 (* ------------------------------------------------------------------------- *)
4831
4832 let HAS_INTEGRAL_FACTOR_CONTENT = prove
4833  (`!f:real^M->real^N i a b.
4834       (f has_integral i) (interval[a,b]) <=>
4835       (!e. &0 < e
4836            ==> ?d. gauge d /\
4837                    (!p. p tagged_division_of interval[a,b] /\ d fine p
4838                         ==> norm (vsum p (\(x,k). content k % f x) - i)
4839                             <= e * content(interval[a,b])))`,
4840   REPEAT GEN_TAC THEN
4841   ASM_CASES_TAC `content(interval[a:real^M,b]) = &0` THENL
4842    [MP_TAC(SPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`]
4843      VSUM_CONTENT_NULL) THEN
4844     ASM_SIMP_TAC[HAS_INTEGRAL_NULL_EQ; VECTOR_SUB_LZERO; NORM_NEG] THEN
4845     DISCH_TAC THEN REWRITE_TAC[REAL_MUL_RZERO; NORM_LE_0] THEN
4846     ASM_MESON_TAC[FINE_DIVISION_EXISTS; GAUGE_TRIVIAL; REAL_LT_01];
4847     ALL_TAC] THEN
4848   REWRITE_TAC[has_integral] THEN EQ_TAC THEN DISCH_TAC THEN
4849   X_GEN_TAC `e:real` THEN DISCH_TAC THENL
4850    [FIRST_X_ASSUM(MP_TAC o SPEC `e * content(interval[a:real^M,b])`) THEN
4851     ASM_SIMP_TAC[REAL_LT_MUL; CONTENT_LT_NZ] THEN MESON_TAC[REAL_LT_IMP_LE];
4852     ALL_TAC] THEN
4853   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2 / content(interval[a:real^M,b])`) THEN
4854   ASM_SIMP_TAC[REAL_LT_DIV; CONTENT_LT_NZ; REAL_OF_NUM_LT; ARITH] THEN
4855   ASM_SIMP_TAC[REAL_DIV_RMUL] THEN
4856   ASM_MESON_TAC[REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`]);;
4857
4858 (* ------------------------------------------------------------------------- *)
4859 (* Attempt a systematic general set of "offset" results for components.      *)
4860 (* ------------------------------------------------------------------------- *)
4861
4862 let GAUGE_MODIFY = prove
4863  (`!f:real^M->real^N.
4864       (!s. open s ==> open {x | f(x) IN s})
4865       ==> !d. gauge d ==> gauge (\x y. d (f x) (f y))`,
4866   GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
4867   SIMP_TAC[gauge; IN] THEN DISCH_TAC THEN
4868   X_GEN_TAC `x:real^M` THEN
4869   FIRST_X_ASSUM(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN
4870   DISCH_THEN(ANTE_RES_THEN MP_TAC o CONJUNCT2) THEN
4871   MATCH_MP_TAC EQ_IMP THEN
4872   AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
4873   REWRITE_TAC[IN]);;
4874
4875 (* ------------------------------------------------------------------------- *)
4876 (* Integrabibility on subintervals.                                          *)
4877 (* ------------------------------------------------------------------------- *)
4878
4879 let OPERATIVE_INTEGRABLE = prove
4880  (`!f. operative (/\) (\i. f integrable_on i)`,
4881   GEN_TAC THEN REWRITE_TAC[operative; NEUTRAL_AND] THEN CONJ_TAC THENL
4882    [REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_NULL_EQ];
4883     REPEAT STRIP_TAC THEN EQ_TAC THEN ASM_SIMP_TAC[INTEGRABLE_SPLIT] THEN
4884     REWRITE_TAC[integrable_on] THEN ASM_MESON_TAC[HAS_INTEGRAL_SPLIT]]);;
4885
4886 let INTEGRABLE_SUBINTERVAL = prove
4887  (`!f:real^M->real^N a b c d.
4888         f integrable_on interval[a,b] /\
4889         interval[c,d] SUBSET interval[a,b]
4890         ==> f integrable_on interval[c,d]`,
4891   REPEAT STRIP_TAC THEN
4892   ASM_CASES_TAC `interval[c:real^M,d] = {}` THENL
4893    [ASM_REWRITE_TAC[integrable_on] THEN
4894     MESON_TAC[HAS_INTEGRAL_NULL; CONTENT_EMPTY; EMPTY_AS_INTERVAL];
4895     ASM_MESON_TAC[OPERATIVE_INTEGRABLE; OPERATIVE_DIVISION_AND;
4896                   PARTIAL_DIVISION_EXTEND_1]]);;
4897
4898 (* ------------------------------------------------------------------------- *)
4899 (* Combining adjacent intervals in 1 dimension.                              *)
4900 (* ------------------------------------------------------------------------- *)
4901
4902 let HAS_INTEGRAL_COMBINE = prove
4903  (`!f i:real^N j a b c.
4904         drop a <= drop c /\ drop c <= drop b /\
4905         (f has_integral i) (interval[a,c]) /\
4906         (f has_integral j) (interval[c,b])
4907         ==> (f has_integral (i + j)) (interval[a,b])`,
4908   REPEAT STRIP_TAC THEN MP_TAC
4909    ((CONJUNCT2 o GEN_REWRITE_RULE I
4910      [MATCH_MP OPERATIVE_1_LE(MATCH_MP MONOIDAL_LIFTED MONOIDAL_VECTOR_ADD)])
4911     (ISPEC `f:real^1->real^N` OPERATIVE_INTEGRAL)) THEN
4912   DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`; `c:real^1`]) THEN
4913   ASM_REWRITE_TAC[] THEN
4914   REPEAT(COND_CASES_TAC THEN
4915    ASM_REWRITE_TAC[lifted; distinctness "option"; injectivity "option"]) THEN
4916   ASM_MESON_TAC[INTEGRABLE_INTEGRAL; HAS_INTEGRAL_UNIQUE; integrable_on;
4917                 INTEGRAL_UNIQUE]);;
4918
4919 let INTEGRAL_COMBINE = prove
4920  (`!f:real^1->real^N a b c.
4921         drop a <= drop c /\ drop c <= drop b /\ f integrable_on (interval[a,b])
4922         ==> integral(interval[a,c]) f + integral(interval[c,b]) f =
4923             integral(interval[a,b]) f`,
4924   REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
4925   MATCH_MP_TAC INTEGRAL_UNIQUE THEN MATCH_MP_TAC HAS_INTEGRAL_COMBINE THEN
4926   EXISTS_TAC `c:real^1` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THEN
4927   MATCH_MP_TAC INTEGRABLE_INTEGRAL THEN
4928   MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN
4929   MAP_EVERY EXISTS_TAC [`a:real^1`; `b:real^1`] THEN
4930   ASM_REWRITE_TAC[SUBSET_INTERVAL_1; REAL_LE_REFL]);;
4931
4932 let INTEGRABLE_COMBINE = prove
4933  (`!f a b c.
4934         drop a <= drop c /\ drop c <= drop b /\
4935         f integrable_on interval[a,c] /\
4936         f integrable_on interval[c,b]
4937         ==> f integrable_on interval[a,b]`,
4938   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_COMBINE]);;
4939
4940 (* ------------------------------------------------------------------------- *)
4941 (* Reduce integrability to "local" integrability.                            *)
4942 (* ------------------------------------------------------------------------- *)
4943
4944 let INTEGRABLE_ON_LITTLE_SUBINTERVALS = prove
4945  (`!f:real^M->real^N a b.
4946         (!x. x IN interval[a,b]
4947              ==> ?d. &0 < d /\
4948                      !u v. x IN interval[u,v] /\
4949                            interval[u,v] SUBSET ball(x,d) /\
4950                            interval[u,v] SUBSET interval[a,b]
4951                            ==> f integrable_on interval[u,v])
4952         ==> f integrable_on interval[a,b]`,
4953   REPEAT GEN_TAC THEN
4954   REWRITE_TAC[RIGHT_IMP_EXISTS_THM; GAUGE_EXISTENCE_LEMMA] THEN
4955   REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM] THEN
4956   DISCH_THEN(X_CHOOSE_THEN `d:real^M->real` STRIP_ASSUME_TAC) THEN
4957   MP_TAC(ISPECL [`\x:real^M. ball(x,d x)`; `a:real^M`; `b:real^M`]
4958                 FINE_DIVISION_EXISTS) THEN
4959   ASM_SIMP_TAC[GAUGE_BALL_DEPENDENT; LEFT_IMP_EXISTS_THM] THEN
4960   X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN
4961   MP_TAC(MATCH_MP (REWRITE_RULE[IMP_CONJ] OPERATIVE_DIVISION_AND)
4962          (ISPEC `f:real^M->real^N` OPERATIVE_INTEGRABLE)) THEN
4963   DISCH_THEN(MP_TAC o SPECL
4964    [`IMAGE SND (p:real^M#(real^M->bool)->bool)`; `a:real^M`; `b:real^M`]) THEN
4965   ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION] THEN
4966   DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[FORALL_IN_IMAGE] THEN
4967   REWRITE_TAC[FORALL_PAIR_THM] THEN
4968   MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
4969   FIRST_ASSUM(MP_TAC o el 1 o CONJUNCTS o
4970    GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
4971   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
4972   REWRITE_TAC[IMP_IMP; AND_FORALL_THM] THEN
4973   DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `k:real^M->bool`]) THEN
4974   ASM_REWRITE_TAC[] THEN  ASM_MESON_TAC[SUBSET]);;
4975
4976 (* ------------------------------------------------------------------------- *)
4977 (* Second FCT or existence of antiderivative.                                *)
4978 (* ------------------------------------------------------------------------- *)
4979
4980 let INTEGRAL_HAS_VECTOR_DERIVATIVE = prove
4981  (`!f:real^1->real^N a b.
4982      (f continuous_on interval[a,b])
4983      ==> !x. x IN interval[a,b]
4984              ==> ((\u. integral (interval[a,u]) f) has_vector_derivative f(x))
4985                  (at x within interval[a,b])`,
4986   REWRITE_TAC[IN_INTERVAL_1] THEN REPEAT STRIP_TAC THEN
4987   REWRITE_TAC[has_vector_derivative; HAS_DERIVATIVE_WITHIN_ALT] THEN
4988   CONJ_TAC THENL
4989    [REWRITE_TAC[linear; DROP_ADD; DROP_CMUL] THEN
4990     CONJ_TAC THEN VECTOR_ARITH_TAC;
4991     ALL_TAC] THEN
4992   X_GEN_TAC `e:real` THEN DISCH_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
4993   FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
4994     COMPACT_UNIFORMLY_CONTINUOUS)) THEN
4995   REWRITE_TAC[COMPACT_INTERVAL; uniformly_continuous_on] THEN
4996   DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
4997   MATCH_MP_TAC MONO_EXISTS THEN REWRITE_TAC[dist] THEN
4998   X_GEN_TAC `d:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
4999   X_GEN_TAC `y:real^1` THEN STRIP_TAC THEN
5000   REWRITE_TAC[NORM_REAL; GSYM drop; DROP_SUB] THEN
5001   DISJ_CASES_TAC(REAL_ARITH `drop x <= drop y \/ drop y <= drop x`) THENL
5002    [ASM_SIMP_TAC[REAL_ARITH `x <= y ==> abs(y - x) = y - x`];
5003     ONCE_REWRITE_TAC[VECTOR_ARITH
5004      `fy - fx - (x - y) % c = --(fx - fy - (y - x) % c)`] THEN
5005     ASM_SIMP_TAC[NORM_NEG; REAL_ARITH `x <= y ==> abs(x - y) = y - x`]] THEN
5006   ASM_SIMP_TAC[GSYM CONTENT_1] THEN MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN
5007   EXISTS_TAC `(\u. f(u) - f(x)):real^1->real^N` THEN
5008   (ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN CONJ_TAC THENL
5009    [ALL_TAC;
5010     REPEAT STRIP_TAC THEN
5011     MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
5012     REPEAT(POP_ASSUM MP_TAC) THEN
5013     REWRITE_TAC[IN_INTERVAL_1; NORM_REAL; DROP_SUB; GSYM drop] THEN
5014     REAL_ARITH_TAC] THEN
5015    MATCH_MP_TAC HAS_INTEGRAL_SUB THEN REWRITE_TAC[HAS_INTEGRAL_CONST]) THENL
5016     [SUBGOAL_THEN
5017       `integral(interval[a,x]) f + integral(interval[x,y]) f =
5018        integral(interval[a,y]) f /\
5019        ((f:real^1->real^N) has_integral integral(interval[x,y]) f)
5020         (interval[x,y])`
5021       (fun th -> MESON_TAC[th;
5022           VECTOR_ARITH `a + b = c:real^N ==> c - a = b`]);
5023      SUBGOAL_THEN
5024       `integral(interval[a,y]) f + integral(interval[y,x]) f =
5025        integral(interval[a,x]) f /\
5026        ((f:real^1->real^N) has_integral integral(interval[y,x]) f)
5027         (interval[y,x])`
5028        (fun th -> MESON_TAC[th;
5029          VECTOR_ARITH `a + b = c:real^N ==> c - a = b`])] THEN
5030    (CONJ_TAC THENL
5031      [MATCH_MP_TAC INTEGRAL_COMBINE;
5032       MATCH_MP_TAC INTEGRABLE_INTEGRAL] THEN
5033     ASM_REWRITE_TAC[] THEN
5034     MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN
5035     MAP_EVERY EXISTS_TAC [`a:real^1`; `b:real^1`] THEN
5036     ASM_SIMP_TAC[INTEGRABLE_CONTINUOUS; SUBSET_INTERVAL_1] THEN
5037     ASM_REAL_ARITH_TAC));;
5038
5039 let ANTIDERIVATIVE_CONTINUOUS = prove
5040  (`!f:real^1->real^N a b.
5041      (f continuous_on interval[a,b])
5042      ==> ?g. !x. x IN interval[a,b]
5043                  ==> (g has_vector_derivative f(x))
5044                      (at x within interval[a,b])`,
5045   MESON_TAC[INTEGRAL_HAS_VECTOR_DERIVATIVE]);;
5046
5047 (* ------------------------------------------------------------------------- *)
5048 (* General "twiddling" for interval-to-interval function image.              *)
5049 (* ------------------------------------------------------------------------- *)
5050
5051 let HAS_INTEGRAL_TWIDDLE = prove
5052  (`!f:real^N->real^P (g:real^M->real^N) h r i a b.
5053       &0 < r /\
5054       (!x. h(g x) = x) /\ (!x. g(h x) = x) /\ (!x. g continuous at x) /\
5055       (!u v. ?w z. IMAGE g (interval[u,v]) = interval[w,z]) /\
5056       (!u v. ?w z. IMAGE h (interval[u,v]) = interval[w,z]) /\
5057       (!u v. content(IMAGE g (interval[u,v])) = r * content(interval[u,v])) /\
5058       (f has_integral i) (interval[a,b])
5059       ==> ((\x. f(g x)) has_integral (inv r) % i) (IMAGE h (interval[a,b]))`,
5060   let lemma0 = prove
5061    (`(!x k. (x,k) IN IMAGE (\(x,k). f x,g k) p ==> P x k) <=>
5062      (!x k. (x,k) IN p ==> P (f x) (g k))`,
5063     REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM; PAIR_EQ] THEN MESON_TAC[])
5064   and lemma1 = prove
5065    (`{k | ?x. (x,k) IN p} = IMAGE SND p`,
5066     REWRITE_TAC[EXTENSION; EXISTS_PAIR_THM; IN_IMAGE; IN_ELIM_THM] THEN
5067     MESON_TAC[])
5068   and lemma2 = prove
5069    (`SND o (\(x,k). f x,g k) = g o SND`,
5070     REWRITE_TAC[FUN_EQ_THM; FORALL_PAIR_THM; o_DEF]) in
5071   REPEAT GEN_TAC THEN ASM_CASES_TAC `interval[a:real^N,b] = {}` THEN
5072   ASM_SIMP_TAC[IMAGE_CLAUSES; HAS_INTEGRAL_EMPTY_EQ; VECTOR_MUL_RZERO] THEN
5073   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5074   REWRITE_TAC[has_integral] THEN
5075   ASM_REWRITE_TAC[has_integral_def; has_integral_compact_interval] THEN
5076   DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5077   FIRST_X_ASSUM(MP_TAC o SPEC `e * r:real`) THEN
5078   ASM_SIMP_TAC[REAL_LT_MUL] THEN
5079   DISCH_THEN(X_CHOOSE_THEN `d:real^N->real^N->bool` STRIP_ASSUME_TAC) THEN
5080   EXISTS_TAC `\x y:real^M. (d:real^N->real^N->bool) (g x) (g y)` THEN
5081   CONJ_TAC THENL
5082    [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [gauge]) THEN
5083     SIMP_TAC[gauge; IN; FORALL_AND_THM] THEN
5084     STRIP_TAC THEN X_GEN_TAC `x:real^M` THEN
5085     SUBGOAL_THEN `(\y:real^M. (d:real^N->real^N->bool) (g x) (g y)) =
5086                   {y | g y IN (d (g x))}` SUBST1_TAC
5087     THENL [SET_TAC[]; ASM_SIMP_TAC[CONTINUOUS_OPEN_PREIMAGE_UNIV]];
5088     ALL_TAC] THEN
5089   X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN
5090   FIRST_X_ASSUM(MP_TAC o SPEC
5091    `IMAGE (\(x,k). (g:real^M->real^N) x, IMAGE g k) p`) THEN
5092   ANTS_TAC THENL
5093    [CONJ_TAC THENL
5094      [ALL_TAC;
5095       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
5096       REWRITE_TAC[fine; lemma0] THEN
5097       STRIP_TAC THEN REPEAT GEN_TAC THEN DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN
5098       ASM SET_TAC[]] THEN
5099     SUBGOAL_THEN
5100      `interval[a,b] = IMAGE ((g:real^M->real^N) o h) (interval[a,b])`
5101     SUBST1_TAC THENL [SIMP_TAC[o_DEF] THEN ASM SET_TAC[]; ALL_TAC] THEN
5102     SUBGOAL_THEN `?u v. IMAGE (h:real^N->real^M) (interval[a,b]) =
5103                         interval[u,v]`
5104     (REPEAT_TCL CHOOSE_THEN
5105       (fun th -> SUBST_ALL_TAC th THEN ASSUME_TAC th)) THENL
5106       [ASM_MESON_TAC[]; ALL_TAC] THEN
5107     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
5108     REWRITE_TAC[TAGGED_DIVISION_OF; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
5109     REWRITE_TAC[lemma0] THEN REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
5110     REPEAT GEN_TAC THEN STRIP_TAC THEN CONJ_TAC THENL
5111      [ASM_SIMP_TAC[FINITE_IMAGE]; ALL_TAC] THEN
5112     CONJ_TAC THENL
5113      [MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
5114       DISCH_TAC THEN
5115       UNDISCH_TAC
5116        `!x:real^M k.
5117              x,k IN p
5118              ==> x IN k /\
5119                  k SUBSET interval[u,v] /\
5120                  ?w z. k = interval[w,z]` THEN
5121       DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `k:real^M->bool`]) THEN
5122       ASM_REWRITE_TAC[] THEN
5123       REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THENL
5124        [SET_TAC[];
5125         REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[];
5126         STRIP_TAC THEN ASM_REWRITE_TAC[]];
5127       ALL_TAC] THEN
5128     CONJ_TAC THENL
5129      [ALL_TAC;
5130       ASM_REWRITE_TAC[IMAGE_o] THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
5131       REWRITE_TAC[lemma1; GSYM IMAGE_o; lemma2] THEN
5132       REWRITE_TAC[IMAGE_o; GSYM IMAGE_UNIONS; ETA_AX]] THEN
5133     MAP_EVERY X_GEN_TAC [`x1:real^M`; `k1:real^M->bool`] THEN DISCH_TAC THEN
5134     MAP_EVERY X_GEN_TAC [`x2:real^M`; `k2:real^M->bool`] THEN STRIP_TAC THEN
5135     UNDISCH_TAC
5136      `!x1:real^M k1:real^M->bool.
5137              x1,k1 IN p
5138              ==> (!x2 k2.
5139                       x2,k2 IN p /\ ~(x1,k1 = x2,k2)
5140                       ==> interior k1 INTER interior k2 = {})` THEN
5141     DISCH_THEN(MP_TAC o SPECL [`x1:real^M`; `k1:real^M->bool`]) THEN
5142     ASM_REWRITE_TAC[] THEN
5143     DISCH_THEN(MP_TAC o SPECL [`x2:real^M`; `k2:real^M->bool`]) THEN
5144     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
5145      [ASM_MESON_TAC[PAIR_EQ]; ALL_TAC] THEN
5146     MATCH_MP_TAC(SET_RULE
5147      `interior(IMAGE f s) SUBSET IMAGE f (interior s) /\
5148       interior(IMAGE f t) SUBSET IMAGE f (interior t) /\
5149       (!x y. f x = f y ==> x = y)
5150       ==> interior s INTER interior t = {}
5151           ==> interior(IMAGE f s) INTER interior(IMAGE f t) = {}`) THEN
5152     REPEAT CONJ_TAC THEN TRY(MATCH_MP_TAC INTERIOR_IMAGE_SUBSET) THEN
5153     ASM_MESON_TAC[];
5154     ALL_TAC] THEN
5155   W(fun (asl,w) -> MP_TAC(PART_MATCH (lhand o rand) VSUM_IMAGE
5156                 (lhand(rand(lhand(lhand w)))))) THEN
5157   ANTS_TAC THENL
5158    [FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
5159     ASM_REWRITE_TAC[FORALL_PAIR_THM; PAIR_EQ] THEN
5160     REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5161     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5162     MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN ASM SET_TAC[];
5163     ALL_TAC] THEN
5164   DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM] THEN
5165   DISCH_TAC THEN MATCH_MP_TAC REAL_LT_LCANCEL_IMP THEN
5166   EXISTS_TAC `abs r` THEN ASM_SIMP_TAC[REAL_ARITH `&0 < x ==> &0 < abs x`] THEN
5167   REWRITE_TAC[GSYM NORM_MUL] THEN ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE] THEN
5168   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
5169    `x < a * b ==> x = y ==> y < b * a`)) THEN
5170   AP_TERM_TAC THEN REWRITE_TAC[VECTOR_SUB_LDISTRIB] THEN
5171   ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; REAL_LT_IMP_NZ] THEN
5172   REWRITE_TAC[VECTOR_MUL_LID; GSYM VSUM_LMUL] THEN
5173   AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
5174   REWRITE_TAC[FORALL_PAIR_THM; VECTOR_MUL_ASSOC] THEN
5175   REPEAT STRIP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
5176   ASM_MESON_TAC[TAGGED_DIVISION_OF]);;
5177
5178 (* ------------------------------------------------------------------------- *)
5179 (* Special case of a basic affine transformation.                            *)
5180 (* ------------------------------------------------------------------------- *)
5181
5182 let INTERVAL_IMAGE_AFFINITY_INTERVAL = prove
5183  (`!a b m c. ?u v. IMAGE (\x. m % x + c) (interval[a,b]) = interval[u,v]`,
5184   REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN
5185   MESON_TAC[EMPTY_AS_INTERVAL]);;
5186
5187 let CONTENT_IMAGE_AFFINITY_INTERVAL = prove
5188  (`!a b:real^N m c.
5189         content(IMAGE (\x. m % x + c) (interval[a,b])) =
5190         (abs m) pow (dimindex(:N)) * content(interval[a,b])`,
5191   REPEAT STRIP_TAC THEN REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN
5192   COND_CASES_TAC THEN ASM_REWRITE_TAC[CONTENT_EMPTY; REAL_MUL_RZERO] THEN
5193   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN COND_CASES_TAC THEN
5194   W(fun (asl,w) -> MP_TAC(PART_MATCH (lhand o rand) CONTENT_CLOSED_INTERVAL
5195                 (lhs w))) THEN
5196   (ANTS_TAC THENL
5197     [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
5198      FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN
5199      ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
5200                   REAL_LE_RADD; REAL_LE_LMUL] THEN
5201      ONCE_REWRITE_TAC[REAL_ARITH `m * b <= m * a <=> --m * a <= --m * b`] THEN
5202      ASM_SIMP_TAC[REAL_ARITH `~(&0 <= x) ==> &0 <= --x`; REAL_LE_LMUL];
5203      ALL_TAC]) THEN
5204   DISCH_THEN SUBST1_TAC THEN
5205   ONCE_REWRITE_TAC[GSYM PRODUCT_CONST_NUMSEG_1] THEN
5206   ASM_SIMP_TAC[CONTENT_CLOSED_INTERVAL; GSYM PRODUCT_MUL_NUMSEG] THEN
5207   MATCH_MP_TAC PRODUCT_EQ THEN
5208   SIMP_TAC[IN_NUMSEG; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT] THEN
5209   ASM_REAL_ARITH_TAC);;
5210
5211 let HAS_INTEGRAL_AFFINITY = prove
5212  (`!f:real^M->real^N i a b m c.
5213         (f has_integral i) (interval[a,b]) /\ ~(m = &0)
5214         ==> ((\x. f(m % x + c)) has_integral
5215              (inv(abs(m) pow dimindex(:M)) % i))
5216             (IMAGE (\x. inv m % x + --(inv(m) % c)) (interval[a,b]))`,
5217   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_TWIDDLE THEN
5218   ASM_SIMP_TAC[INTERVAL_IMAGE_AFFINITY_INTERVAL; GSYM REAL_ABS_NZ;
5219         REAL_POW_LT; PRODUCT_EQ_0_NUMSEG; CONTENT_IMAGE_AFFINITY_INTERVAL] THEN
5220   ASM_SIMP_TAC[CONTINUOUS_CMUL; CONTINUOUS_AT_ID; CONTINUOUS_CONST;
5221                CONTINUOUS_ADD] THEN
5222   REWRITE_TAC[VECTOR_ADD_LDISTRIB; VECTOR_MUL_ASSOC; VECTOR_MUL_RNEG] THEN
5223   ASM_SIMP_TAC[REAL_MUL_LINV; REAL_MUL_RINV] THEN
5224   CONJ_TAC THEN VECTOR_ARITH_TAC);;
5225
5226 let INTEGRABLE_AFFINITY = prove
5227  (`!f:real^M->real^N a b m c.
5228         f integrable_on interval[a,b] /\ ~(m = &0)
5229         ==> (\x. f(m % x + c)) integrable_on
5230             (IMAGE (\x. inv m % x + --(inv(m) % c)) (interval[a,b]))`,
5231   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_AFFINITY]);;
5232
5233 (* ------------------------------------------------------------------------- *)
5234 (* Special case of stretching coordinate axes separately.                    *)
5235 (* ------------------------------------------------------------------------- *)
5236
5237 let CONTENT_IMAGE_STRETCH_INTERVAL = prove
5238  (`!a b:real^N m.
5239         content(IMAGE (\x. lambda k. m k * x$k) (interval[a,b]):real^N->bool) =
5240         abs(product(1..dimindex(:N)) m) * content(interval[a,b])`,
5241   REPEAT GEN_TAC THEN REWRITE_TAC[content; IMAGE_EQ_EMPTY] THEN
5242   COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_MUL_RZERO] THEN
5243   ASM_REWRITE_TAC[IMAGE_STRETCH_INTERVAL] THEN
5244   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY]) THEN
5245   ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; LAMBDA_BETA;
5246                REAL_ARITH `min a b <= max a b`] THEN
5247   ASM_REWRITE_TAC[REAL_ARITH `max a b - min a b = abs(b - a)`;
5248                   GSYM REAL_SUB_LDISTRIB; REAL_ABS_MUL] THEN
5249   ASM_SIMP_TAC[PRODUCT_MUL; FINITE_NUMSEG;
5250                REAL_ARITH `a <= b ==> abs(b - a) = b - a`] THEN
5251   ASM_SIMP_TAC[PRODUCT_ABS; FINITE_NUMSEG]);;
5252
5253 let HAS_INTEGRAL_STRETCH = prove
5254  (`!f:real^M->real^N i m a b.
5255         (f has_integral i) (interval[a,b]) /\
5256         (!k. 1 <= k /\ k <= dimindex(:M) ==>  ~(m k = &0))
5257         ==> ((\x:real^M. f(lambda k. m k * x$k)) has_integral
5258              (inv(abs(product(1..dimindex(:M)) m)) % i))
5259             (IMAGE (\x. lambda k. inv(m k) * x$k) (interval[a,b]))`,
5260   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_TWIDDLE THEN
5261   SIMP_TAC[CART_EQ; LAMBDA_BETA] THEN
5262   ASM_SIMP_TAC[REAL_MUL_ASSOC; REAL_MUL_LINV; REAL_MUL_RINV; REAL_MUL_LID] THEN
5263   ASM_REWRITE_TAC[GSYM REAL_ABS_NZ; PRODUCT_EQ_0_NUMSEG] THEN
5264   CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN CONJ_TAC THENL
5265    [GEN_TAC THEN MATCH_MP_TAC LINEAR_CONTINUOUS_AT THEN
5266     SIMP_TAC[linear; LAMBDA_BETA; CART_EQ; VECTOR_ADD_COMPONENT;
5267              VECTOR_MUL_COMPONENT] THEN REAL_ARITH_TAC;
5268     REWRITE_TAC[CONTENT_IMAGE_STRETCH_INTERVAL] THEN
5269     REWRITE_TAC[IMAGE_STRETCH_INTERVAL] THEN MESON_TAC[EMPTY_AS_INTERVAL]]);;
5270
5271 let INTEGRABLE_STRETCH = prove
5272  (`!f:real^M->real^N m a b.
5273         f integrable_on interval[a,b] /\
5274         (!k. 1 <= k /\ k <= dimindex(:M) ==>  ~(m k = &0))
5275         ==> (\x:real^M. f(lambda k. m k * x$k)) integrable_on
5276             (IMAGE (\x. lambda k. inv(m k) * x$k) (interval[a,b]))`,
5277   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_STRETCH]);;
5278
5279 (* ------------------------------------------------------------------------- *)
5280 (* Even more special cases.                                                  *)
5281 (* ------------------------------------------------------------------------- *)
5282
5283 let HAS_INTEGRAL_REFLECT_LEMMA = prove
5284  (`!f:real^M->real^N i a b.
5285      (f has_integral i) (interval[a,b])
5286      ==> ((\x. f(--x)) has_integral i) (interval[--b,--a])`,
5287   REPEAT STRIP_TAC THEN
5288   FIRST_ASSUM(MP_TAC o C CONJ (REAL_ARITH `~(-- &1 = &0)`)) THEN
5289   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_AFFINITY) THEN
5290   DISCH_THEN(MP_TAC o SPEC `vec 0:real^M`) THEN
5291   REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN
5292   CONV_TAC REAL_RAT_REDUCE_CONV THEN
5293   REWRITE_TAC[REAL_ABS_NEG; REAL_ABS_NUM; REAL_POW_ONE] THEN
5294   REWRITE_TAC[VECTOR_MUL_RZERO; VECTOR_NEG_0] THEN
5295   REWRITE_TAC[REAL_INV_NEG; REAL_INV_1] THEN
5296   REWRITE_TAC[VECTOR_ARITH `-- &1 % x + vec 0 = --x`] THEN
5297   REWRITE_TAC[VECTOR_MUL_LID] THEN MATCH_MP_TAC EQ_IMP THEN
5298   AP_TERM_TAC THEN POP_ASSUM(K ALL_TAC) THEN
5299   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN CONV_TAC SYM_CONV THEN
5300   POP_ASSUM MP_TAC THEN REWRITE_TAC[INTERVAL_EQ_EMPTY] THEN
5301   REWRITE_TAC[TAUT `a /\ b /\ c <=> ~(a /\ b ==> ~c)`] THEN
5302   SIMP_TAC[VECTOR_NEG_COMPONENT; REAL_LT_NEG2]);;
5303
5304 let HAS_INTEGRAL_REFLECT = prove
5305  (`!f:real^M->real^N i a b.
5306      ((\x. f(--x)) has_integral i) (interval[--b,--a]) <=>
5307      (f has_integral i) (interval[a,b])`,
5308   REPEAT GEN_TAC THEN EQ_TAC THEN
5309   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_REFLECT_LEMMA) THEN
5310   REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);;
5311
5312 let INTEGRABLE_REFLECT = prove
5313  (`!f:real^M->real^N a b.
5314      (\x. f(--x)) integrable_on (interval[--b,--a]) <=>
5315      f integrable_on (interval[a,b])`,
5316   REWRITE_TAC[integrable_on; HAS_INTEGRAL_REFLECT]);;
5317
5318 let INTEGRAL_REFLECT = prove
5319  (`!f:real^M->real^N a b.
5320      integral (interval[--b,--a]) (\x. f(--x)) =
5321      integral (interval[a,b]) f`,
5322   REWRITE_TAC[integral; HAS_INTEGRAL_REFLECT]);;
5323
5324 (* ------------------------------------------------------------------------- *)
5325 (* Technical lemmas about how many non-trivial intervals of a division a     *)
5326 (* point can be in (we sometimes need this for bounding sums).               *)
5327 (* ------------------------------------------------------------------------- *)
5328
5329 let DIVISION_COMMON_POINT_BOUND = prove
5330  (`!d s:real^N->bool x.
5331         d division_of s
5332         ==> CARD {k | k IN d /\ ~(content k = &0) /\ x IN k}
5333             <= 2 EXP (dimindex(:N))`,
5334   let lemma = prove
5335    (`!f s. (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\
5336            FINITE s /\ CARD(IMAGE f s) <= n
5337            ==> CARD(s) <= n`,
5338     MESON_TAC[CARD_IMAGE_INJ]) in
5339   REPEAT STRIP_TAC THEN
5340   SUBGOAL_THEN `!k. k IN d ==> ?a b:real^N. interval[a,b] = k` MP_TAC THENL
5341    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
5342   REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
5343   MAP_EVERY X_GEN_TAC
5344    [`A:(real^N->bool)->real^N`; `B:(real^N->bool)->real^N`] THEN
5345   STRIP_TAC THEN MATCH_MP_TAC(ISPEC
5346    `\d. (lambda i. (x:real^N)$i = (A:(real^N->bool)->real^N)(d)$i):bool^N`
5347    lemma) THEN
5348   REPEAT CONJ_TAC THENL
5349    [ALL_TAC;
5350     MATCH_MP_TAC FINITE_RESTRICT THEN ASM_MESON_TAC[division_of];
5351     MATCH_MP_TAC LE_TRANS THEN EXISTS_TAC `CARD(:bool^N)` THEN CONJ_TAC THENL
5352      [MATCH_MP_TAC CARD_SUBSET THEN REWRITE_TAC[SUBSET_UNIV] THEN
5353       SIMP_TAC[FINITE_CART_UNIV; FINITE_BOOL];
5354       SIMP_TAC[FINITE_BOOL; CARD_CART_UNIV; CARD_BOOL; LE_REFL]]] THEN
5355   MAP_EVERY X_GEN_TAC [`k:real^N->bool`; `l:real^N->bool`] THEN
5356   SIMP_TAC[IN_ELIM_THM; CART_EQ; LAMBDA_BETA] THEN STRIP_TAC THEN
5357   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
5358   DISCH_THEN(MP_TAC o SPECL [`k:real^N->bool`; `l:real^N->bool`] o
5359         el 2 o CONJUNCTS) THEN
5360   ASM_REWRITE_TAC[GSYM INTERIOR_INTER] THEN
5361   MATCH_MP_TAC(TAUT `~q ==> (~p ==> q) ==> p`) THEN
5362   MAP_EVERY UNDISCH_TAC
5363    [`(x:real^N) IN k`; `(x:real^N) IN l`;
5364     `~(content(k:real^N->bool) = &0)`;
5365     `~(content(l:real^N->bool) = &0)`] THEN
5366   SUBGOAL_THEN
5367    `k = interval[A k:real^N,B k] /\ l = interval[A l,B l]`
5368    (CONJUNCTS_THEN SUBST1_TAC)
5369   THENL [ASM_MESON_TAC[]; REWRITE_TAC[INTER_INTERVAL]] THEN
5370   REWRITE_TAC[CONTENT_EQ_0_INTERIOR; INTERIOR_CLOSED_INTERVAL] THEN
5371   SIMP_TAC[IN_INTERVAL; INTERVAL_NE_EMPTY; LAMBDA_BETA] THEN
5372   REPEAT DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
5373   REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN ASM_REWRITE_TAC[] THEN
5374   REAL_ARITH_TAC);;
5375
5376 let TAGGED_PARTIAL_DIVISION_COMMON_POINT_BOUND = prove
5377  (`!p s:real^N->bool y.
5378         p tagged_partial_division_of s
5379         ==> CARD {(x,k) | (x,k) IN p /\ y IN k /\ ~(content k = &0)}
5380             <= 2 EXP (dimindex(:N))`,
5381   let lemma = prove
5382    (`!f s. (!x y. x IN s /\ y IN s /\ f x = f y ==> x = y) /\
5383            FINITE s /\ CARD(IMAGE f s) <= n
5384            ==> CARD(s) <= n`,
5385     MESON_TAC[CARD_IMAGE_INJ]) in
5386   REPEAT STRIP_TAC THEN MATCH_MP_TAC(ISPEC `SND` lemma) THEN
5387   REPEAT CONJ_TAC THENL
5388    [REWRITE_TAC[IMP_CONJ; FORALL_IN_GSPEC; RIGHT_FORALL_IMP_THM; PAIR_EQ] THEN
5389     MAP_EVERY X_GEN_TAC [`x1:real^N`; `k1:real^N->bool`] THEN
5390     REPEAT DISCH_TAC THEN
5391     MAP_EVERY X_GEN_TAC [`x2:real^N`; `k2:real^N->bool`] THEN
5392     REPEAT DISCH_TAC THEN
5393     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [tagged_partial_division_of]) THEN
5394     DISCH_THEN(MP_TAC o SPECL
5395      [`x1:real^N`; `k1:real^N->bool`; `x2:real^N`; `k2:real^N->bool`] o
5396      CONJUNCT2 o CONJUNCT2) THEN
5397     ASM_REWRITE_TAC[PAIR_EQ] THEN
5398     MATCH_MP_TAC(TAUT `~q ==> (~p ==> q) ==> p`) THEN
5399     REWRITE_TAC[INTER_ACI] THEN
5400     ASM_MESON_TAC[CONTENT_EQ_0_INTERIOR; tagged_partial_division_of];
5401     MATCH_MP_TAC FINITE_SUBSET THEN
5402     EXISTS_TAC `p:real^N#(real^N->bool)->bool` THEN CONJ_TAC THENL
5403      [ASM_MESON_TAC[tagged_partial_division_of]; SET_TAC[]];
5404     FIRST_ASSUM(MP_TAC o MATCH_MP PARTIAL_DIVISION_OF_TAGGED_DIVISION) THEN
5405     DISCH_THEN(MP_TAC o SPEC `y:real^N` o
5406       MATCH_MP DIVISION_COMMON_POINT_BOUND) THEN
5407     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LE_TRANS) THEN
5408     MATCH_MP_TAC CARD_SUBSET THEN CONJ_TAC THENL
5409      [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC] THEN
5410       REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; EXISTS_PAIR_THM] THEN MESON_TAC[];
5411       MATCH_MP_TAC FINITE_RESTRICT THEN MATCH_MP_TAC FINITE_IMAGE THEN
5412       ASM_MESON_TAC[tagged_partial_division_of]]]);;
5413
5414 let TAGGED_PARTIAL_DIVISION_COMMON_TAGS = prove
5415  (`!p s:real^N->bool x.
5416         p tagged_partial_division_of s
5417         ==> CARD {(x,k) | k | (x,k) IN p /\ ~(content k = &0)}
5418             <= 2 EXP (dimindex(:N))`,
5419   REPEAT STRIP_TAC THEN FIRST_ASSUM(MP_TAC o SPEC `x:real^N` o
5420    MATCH_MP TAGGED_PARTIAL_DIVISION_COMMON_POINT_BOUND) THEN
5421   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] LE_TRANS) THEN
5422   MATCH_MP_TAC CARD_SUBSET THEN CONJ_TAC THENL
5423    [REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_PAIR_THM] THEN
5424     ASM_MESON_TAC[tagged_partial_division_of];
5425     MATCH_MP_TAC FINITE_SUBSET THEN
5426     EXISTS_TAC `p:real^N#(real^N->bool)->bool` THEN CONJ_TAC THENL
5427      [ASM_MESON_TAC[tagged_partial_division_of]; SET_TAC[]]]);;
5428
5429 (* ------------------------------------------------------------------------- *)
5430 (* Integrating characteristic function of an interval.                       *)
5431 (* ------------------------------------------------------------------------- *)
5432
5433 let HAS_INTEGRAL_RESTRICT_OPEN_SUBINTERVAL = prove
5434  (`!f:real^M->real^N a b c d i.
5435         (f has_integral i) (interval[c,d]) /\
5436         interval[c,d] SUBSET interval[a,b]
5437         ==> ((\x. if x IN interval(c,d) then f x else vec 0) has_integral i)
5438              (interval[a,b])`,
5439   REPEAT GEN_TAC THEN ASM_CASES_TAC `interval[c:real^M,d] = {}` THENL
5440    [FIRST_ASSUM(MP_TAC o AP_TERM
5441      `interior:(real^M->bool)->(real^M->bool)`) THEN
5442     SIMP_TAC[INTERIOR_CLOSED_INTERVAL; INTERIOR_EMPTY] THEN
5443     ASM_SIMP_TAC[NOT_IN_EMPTY; HAS_INTEGRAL_0_EQ; HAS_INTEGRAL_EMPTY_EQ];
5444     ALL_TAC] THEN
5445   ABBREV_TAC `g:real^M->real^N =
5446                  \x. if x IN interval(c,d) then f x else vec 0` THEN
5447   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5448   FIRST_X_ASSUM(MP_TAC o check(is_neg o concl)) THEN
5449   REWRITE_TAC[TAUT `a ==> b ==> c <=> b /\ a ==> c`] THEN
5450   DISCH_THEN(MP_TAC o MATCH_MP PARTIAL_DIVISION_EXTEND_1) THEN
5451   DISCH_THEN(X_CHOOSE_THEN `p:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN
5452   MP_TAC(ISPECL
5453    [`lifted((+):real^N->real^N->real^N)`;
5454     `p:(real^M->bool)->bool`;
5455     `a:real^M`; `b:real^M`;
5456     `\i. if (g:real^M->real^N) integrable_on i
5457          then SOME (integral i g) else NONE`]
5458    OPERATIVE_DIVISION) THEN
5459   ASM_SIMP_TAC[OPERATIVE_INTEGRAL; MONOIDAL_LIFTED; MONOIDAL_VECTOR_ADD] THEN
5460   SUBGOAL_THEN
5461    `iterate (lifted (+)) p
5462      (\i. if (g:real^M->real^N) integrable_on i
5463           then SOME (integral i g) else NONE) =
5464     SOME i`
5465   SUBST1_TAC THENL
5466    [ALL_TAC;
5467     COND_CASES_TAC THEN
5468     REWRITE_TAC[distinctness "option"; injectivity "option"] THEN
5469     ASM_MESON_TAC[INTEGRABLE_INTEGRAL]] THEN
5470   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
5471   FIRST_ASSUM(SUBST1_TAC o MATCH_MP (SET_RULE
5472    `x IN s ==> s = x INSERT (s DELETE x)`)) THEN
5473   ASM_SIMP_TAC[ITERATE_CLAUSES; MONOIDAL_LIFTED; MONOIDAL_VECTOR_ADD;
5474                FINITE_DELETE; IN_DELETE] THEN
5475   SUBGOAL_THEN `(g:real^M->real^N) integrable_on interval[c,d]`
5476   ASSUME_TAC THENL
5477    [FIRST_ASSUM(MP_TAC o MATCH_MP HAS_INTEGRAL_INTEGRABLE) THEN
5478     MATCH_MP_TAC INTEGRABLE_SPIKE_INTERIOR THEN
5479     EXPAND_TAC "g" THEN SIMP_TAC[];
5480     ALL_TAC] THEN
5481   ASM_REWRITE_TAC[] THEN
5482   SUBGOAL_THEN
5483    `iterate (lifted (+)) (p DELETE interval[c,d])
5484       (\i. if (g:real^M->real^N) integrable_on i
5485            then SOME (integral i g) else NONE) = SOME(vec 0)`
5486   SUBST1_TAC THENL
5487    [ALL_TAC;
5488     REWRITE_TAC[lifted; VECTOR_ADD_RID] THEN AP_TERM_TAC THEN
5489     MATCH_MP_TAC INTEGRAL_UNIQUE THEN
5490     MATCH_MP_TAC HAS_INTEGRAL_SPIKE_INTERIOR THEN
5491     EXISTS_TAC `f:real^M->real^N` THEN
5492     EXPAND_TAC "g" THEN ASM_SIMP_TAC[]] THEN
5493   SIMP_TAC[GSYM NEUTRAL_VECTOR_ADD; GSYM NEUTRAL_LIFTED;
5494            MONOIDAL_VECTOR_ADD] THEN
5495   MATCH_MP_TAC(MATCH_MP ITERATE_EQ_NEUTRAL
5496         (MATCH_MP MONOIDAL_LIFTED(SPEC_ALL MONOIDAL_VECTOR_ADD))) THEN
5497   SIMP_TAC[NEUTRAL_LIFTED; NEUTRAL_VECTOR_ADD; MONOIDAL_VECTOR_ADD] THEN
5498   X_GEN_TAC `k:real^M->bool` THEN REWRITE_TAC[IN_DELETE] THEN STRIP_TAC THEN
5499   SUBGOAL_THEN `((g:real^M->real^N) has_integral (vec 0)) k`
5500    (fun th -> MESON_TAC[th; integrable_on; INTEGRAL_UNIQUE]) THEN
5501   SUBGOAL_THEN `?u v:real^M. k = interval[u,v]` MP_TAC THENL
5502    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
5503   DISCH_THEN(REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) THEN
5504   MATCH_MP_TAC HAS_INTEGRAL_SPIKE_INTERIOR THEN
5505   EXISTS_TAC `(\x. vec 0):real^M->real^N` THEN
5506   REWRITE_TAC[HAS_INTEGRAL_0] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
5507   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
5508   DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
5509   DISCH_THEN(MP_TAC o SPECL
5510    [`interval[c:real^M,d]`; `interval[u:real^M,v]`]) THEN
5511   ASM_REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN
5512   EXPAND_TAC "g" THEN REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM SET_TAC[]);;
5513
5514 let HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL = prove
5515  (`!f:real^M->real^N a b c d i.
5516         (f has_integral i) (interval[c,d]) /\
5517         interval[c,d] SUBSET interval[a,b]
5518         ==> ((\x. if x IN interval[c,d] then f x else vec 0) has_integral i)
5519              (interval[a,b])`,
5520   REPEAT GEN_TAC THEN
5521   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_RESTRICT_OPEN_SUBINTERVAL) THEN
5522   MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
5523     HAS_INTEGRAL_SPIKE) THEN
5524   EXISTS_TAC `interval[c:real^M,d] DIFF interval(c,d)` THEN
5525   REWRITE_TAC[NEGLIGIBLE_FRONTIER_INTERVAL] THEN REWRITE_TAC[IN_DIFF] THEN
5526   MP_TAC(ISPECL [`c:real^M`; `d:real^M`] INTERVAL_OPEN_SUBSET_CLOSED) THEN
5527   SET_TAC[]);;
5528
5529 let HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVALS_EQ = prove
5530  (`!f:real^M->real^N a b c d i.
5531         interval[c,d] SUBSET interval[a,b]
5532         ==> (((\x. if x IN interval[c,d] then f x else vec 0) has_integral i)
5533               (interval[a,b]) <=>
5534              (f has_integral i) (interval[c,d]))`,
5535   REPEAT STRIP_TAC THEN ASM_CASES_TAC `interval[c:real^M,d] = {}` THENL
5536    [ASM_REWRITE_TAC[NOT_IN_EMPTY; HAS_INTEGRAL_0_EQ; HAS_INTEGRAL_EMPTY_EQ];
5537     ALL_TAC] THEN
5538   EQ_TAC THEN DISCH_TAC THEN
5539   ASM_SIMP_TAC[HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL] THEN
5540   SUBGOAL_THEN `(f:real^M->real^N) integrable_on interval[c,d]` MP_TAC THENL
5541    [MATCH_MP_TAC INTEGRABLE_EQ THEN
5542     EXISTS_TAC `\x. if x IN interval[c:real^M,d]
5543                     then f x:real^N else vec 0` THEN
5544     SIMP_TAC[] THEN MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN
5545     ASM_MESON_TAC[integrable_on];
5546     ALL_TAC] THEN
5547   DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
5548   DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
5549   MP_TAC(ASSUME `interval[c:real^M,d] SUBSET interval[a,b]`) THEN
5550   REWRITE_TAC[IMP_IMP] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
5551   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL) THEN
5552   ASM_MESON_TAC[HAS_INTEGRAL_UNIQUE; INTEGRABLE_INTEGRAL]);;
5553
5554 (* ------------------------------------------------------------------------- *)
5555 (* Hence we can apply the limit process uniformly to all integrals.          *)
5556 (* ------------------------------------------------------------------------- *)
5557
5558 let HAS_INTEGRAL = prove
5559  (`!f:real^M->real^N i s.
5560      (f has_integral i) s <=>
5561         !e. &0 < e
5562             ==> ?B. &0 < B /\
5563                     !a b. ball(vec 0,B) SUBSET interval[a,b]
5564                           ==> ?z. ((\x. if x IN s then f(x) else vec 0)
5565                                    has_integral z) (interval[a,b]) /\
5566                                   norm(z - i) < e`,
5567   REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [has_integral_alt] THEN
5568   COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
5569   POP_ASSUM(X_CHOOSE_THEN `a:real^M` (X_CHOOSE_THEN `b:real^M`
5570    SUBST_ALL_TAC)) THEN
5571   MP_TAC(ISPECL [`a:real^M`; `b:real^M`] (CONJUNCT1 BOUNDED_INTERVAL)) THEN
5572   REWRITE_TAC[BOUNDED_POS] THEN
5573   DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN EQ_TAC THENL
5574    [DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5575     EXISTS_TAC `B + &1` THEN ASM_SIMP_TAC[REAL_LT_ADD; REAL_LT_01] THEN
5576     MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN
5577     REWRITE_TAC[SUBSET; IN_BALL; NORM_ARITH `dist(vec 0,x) = norm x`] THEN
5578     DISCH_TAC THEN EXISTS_TAC `i:real^N` THEN
5579     ASM_REWRITE_TAC[VECTOR_SUB_REFL; NORM_0] THEN
5580     MATCH_MP_TAC HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL THEN
5581     ASM_MESON_TAC[SUBSET; REAL_ARITH `n <= B ==> n < B + &1`];
5582     ALL_TAC] THEN
5583   DISCH_TAC THEN
5584   SUBGOAL_THEN `?y. ((f:real^M->real^N) has_integral y) (interval[a,b])`
5585   MP_TAC THENL
5586    [SUBGOAL_THEN
5587      `?c d. interval[a,b] SUBSET interval[c,d] /\
5588             (\x. if x IN interval[a,b] then (f:real^M->real^N) x
5589                  else vec 0) integrable_on interval[c,d]`
5590     STRIP_ASSUME_TAC THENL
5591      [FIRST_X_ASSUM(MP_TAC o C MATCH_MP REAL_LT_01) THEN
5592       DISCH_THEN(X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC) THEN
5593       ABBREV_TAC `c:real^M = lambda i. --(max B C)` THEN
5594       ABBREV_TAC `d:real^M = lambda i. max B C` THEN
5595       MAP_EVERY EXISTS_TAC [`c:real^M`; `d:real^M`] THEN CONJ_TAC THENL
5596        [REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^M` THEN
5597         DISCH_TAC THEN REWRITE_TAC[IN_INTERVAL] THEN
5598         X_GEN_TAC `k:num` THEN MAP_EVERY EXPAND_TAC ["c"; "d"] THEN
5599         SIMP_TAC[LAMBDA_BETA; REAL_BOUNDS_LE] THEN STRIP_TAC THEN
5600         MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN
5601         ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
5602         MATCH_MP_TAC(REAL_ARITH `x <= B ==> x <= max B C`) THEN
5603         ASM_SIMP_TAC[];
5604         ALL_TAC] THEN
5605       FIRST_X_ASSUM(MP_TAC o SPECL [`c:real^M`; `d:real^M`]) THEN ANTS_TAC THENL
5606        [REWRITE_TAC[SUBSET; IN_BALL; NORM_ARITH `dist(vec 0,x) = norm x`] THEN
5607         X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[IN_INTERVAL] THEN
5608         X_GEN_TAC `k:num` THEN MAP_EVERY EXPAND_TAC ["c"; "d"] THEN
5609         SIMP_TAC[LAMBDA_BETA; REAL_BOUNDS_LE] THEN STRIP_TAC THEN
5610         MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN
5611         ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
5612         MATCH_MP_TAC(REAL_ARITH `x < C ==> x <= max B C`) THEN
5613         ASM_SIMP_TAC[];
5614         ALL_TAC] THEN
5615       MESON_TAC[integrable_on];
5616       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [integrable_on]) THEN
5617       ASM_SIMP_TAC[HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVALS_EQ]];
5618     ALL_TAC] THEN
5619   DISCH_THEN(X_CHOOSE_TAC `y:real^N`) THEN
5620   SUBGOAL_THEN `i:real^N = y` ASSUME_TAC THEN ASM_REWRITE_TAC[] THEN
5621   MATCH_MP_TAC(NORM_ARITH `~(&0 < norm(y - i)) ==> i = y`) THEN
5622   DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `norm(y - i:real^N)`) THEN
5623   ASM_REWRITE_TAC[NOT_EXISTS_THM] THEN X_GEN_TAC `C:real` THEN
5624   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
5625   REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
5626   ABBREV_TAC `c:real^M = lambda i. --(max B C)` THEN
5627   ABBREV_TAC `d:real^M = lambda i. max B C` THEN
5628   MAP_EVERY EXISTS_TAC [`c:real^M`; `d:real^M`] THEN CONJ_TAC THENL
5629    [REWRITE_TAC[SUBSET; IN_BALL; NORM_ARITH `dist(vec 0,x) = norm x`] THEN
5630     X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[IN_INTERVAL] THEN
5631     X_GEN_TAC `k:num` THEN MAP_EVERY EXPAND_TAC ["c"; "d"] THEN
5632     SIMP_TAC[LAMBDA_BETA; REAL_BOUNDS_LE] THEN STRIP_TAC THEN
5633     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN
5634     ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
5635     MATCH_MP_TAC(REAL_ARITH `x < C ==> x <= max B C`) THEN
5636     ASM_SIMP_TAC[];
5637     ALL_TAC] THEN
5638   SUBGOAL_THEN `interval[a:real^M,b] SUBSET interval[c,d]` ASSUME_TAC THENL
5639    [REWRITE_TAC[SUBSET] THEN X_GEN_TAC `x:real^M` THEN
5640     DISCH_TAC THEN REWRITE_TAC[IN_INTERVAL] THEN
5641     X_GEN_TAC `k:num` THEN MAP_EVERY EXPAND_TAC ["c"; "d"] THEN
5642     SIMP_TAC[LAMBDA_BETA; REAL_BOUNDS_LE] THEN STRIP_TAC THEN
5643     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN
5644     ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
5645     MATCH_MP_TAC(REAL_ARITH `x <= B ==> x <= max B C`) THEN
5646     ASM_SIMP_TAC[];
5647     ALL_TAC] THEN
5648   ASM_SIMP_TAC[HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVALS_EQ] THEN
5649   ASM_MESON_TAC[REAL_LT_REFL; HAS_INTEGRAL_UNIQUE]);;
5650
5651 (* ------------------------------------------------------------------------- *)
5652 (* Hence a general restriction property.                                     *)
5653 (* ------------------------------------------------------------------------- *)
5654
5655 let HAS_INTEGRAL_RESTRICT = prove
5656  (`!f:real^M->real^N s t i.
5657         s SUBSET t
5658         ==> (((\x. if x IN s then f x else vec 0) has_integral i) t <=>
5659              (f has_integral i) s)`,
5660   REWRITE_TAC[SUBSET] THEN REPEAT STRIP_TAC THEN
5661   ONCE_REWRITE_TAC[HAS_INTEGRAL] THEN REWRITE_TAC[] THEN
5662   ONCE_REWRITE_TAC[MESON[] `(if p then if q then x else y else y) =
5663                             (if q then if p then x else y else y)`] THEN
5664   ASM_SIMP_TAC[]);;
5665
5666 let INTEGRAL_RESTRICT = prove
5667  (`!f:real^M->real^N s t.
5668         s SUBSET t
5669         ==> integral t (\x. if x IN s then f x else vec 0) =
5670             integral s f`,
5671   SIMP_TAC[integral; HAS_INTEGRAL_RESTRICT]);;
5672
5673 let INTEGRABLE_RESTRICT = prove
5674  (`!f:real^M->real^N s t.
5675         s SUBSET t
5676         ==> ((\x. if x IN s then f x else vec 0) integrable_on t <=>
5677              f integrable_on s)`,
5678   SIMP_TAC[integrable_on; HAS_INTEGRAL_RESTRICT]);;
5679
5680 let HAS_INTEGRAL_RESTRICT_UNIV = prove
5681  (`!f:real^M->real^N s i.
5682         ((\x. if x IN s then f x else vec 0) has_integral i) (:real^M) <=>
5683          (f has_integral i) s`,
5684   SIMP_TAC[HAS_INTEGRAL_RESTRICT; SUBSET_UNIV]);;
5685
5686 let INTEGRAL_RESTRICT_UNIV = prove
5687  (`!f:real^M->real^N s.
5688         integral (:real^M) (\x. if x IN s then f x else vec 0) =
5689         integral s f`,
5690   REWRITE_TAC[integral; HAS_INTEGRAL_RESTRICT_UNIV]);;
5691
5692 let INTEGRABLE_RESTRICT_UNIV = prove
5693  (`!f s. (\x. if x IN s then f x else vec 0) integrable_on (:real^M) <=>
5694          f integrable_on s`,
5695   REWRITE_TAC[integrable_on; HAS_INTEGRAL_RESTRICT_UNIV]);;
5696
5697 let HAS_INTEGRAL_RESTRICT_INTER = prove
5698  (`!f:real^M->real^N s t.
5699         ((\x. if x IN s then f x else vec 0) has_integral i) t <=>
5700         (f has_integral i) (s INTER t)`,
5701   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
5702   REWRITE_TAC[IN_INTER] THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
5703   REWRITE_TAC[FUN_EQ_THM] THEN MESON_TAC[]);;
5704
5705 let INTEGRAL_RESTRICT_INTER = prove
5706  (`!f:real^M->real^N s t.
5707         integral t (\x. if x IN s then f x else vec 0) =
5708         integral (s INTER t) f`,
5709   REWRITE_TAC[integral; HAS_INTEGRAL_RESTRICT_INTER]);;
5710
5711 let INTEGRABLE_RESTRICT_INTER = prove
5712  (`!f:real^M->real^N s t.
5713         (\x. if x IN s then f x else vec 0) integrable_on t <=>
5714         f integrable_on (s INTER t)`,
5715   REWRITE_TAC[integrable_on; HAS_INTEGRAL_RESTRICT_INTER]);;
5716
5717 let HAS_INTEGRAL_ON_SUPERSET = prove
5718  (`!f s t.
5719         (!x. ~(x IN s) ==> f x = vec 0) /\ s SUBSET t /\ (f has_integral i) s
5720         ==> (f has_integral i) t`,
5721   REPEAT GEN_TAC THEN REWRITE_TAC[SUBSET] THEN
5722   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
5723   ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
5724   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN
5725   AP_TERM_TAC THEN ABS_TAC THEN ASM_MESON_TAC[]);;
5726
5727 let INTEGRABLE_ON_SUPERSET = prove
5728  (`!f s t.
5729         (!x. ~(x IN s) ==> f x = vec 0) /\ s SUBSET t /\ f integrable_on s
5730         ==> f integrable_on t`,
5731   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_ON_SUPERSET]);;
5732
5733 let NEGLIGIBLE_ON_INTERVALS = prove
5734  (`!s. negligible s <=> !a b:real^N. negligible(s INTER interval[a,b])`,
5735   GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
5736    [MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `s:real^N->bool` THEN
5737     ASM_REWRITE_TAC[] THEN SET_TAC[];
5738     ALL_TAC] THEN
5739   REWRITE_TAC[negligible] THEN
5740   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
5741   FIRST_ASSUM(ASSUME_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN
5742   MATCH_MP_TAC HAS_INTEGRAL_NEGLIGIBLE THEN
5743   EXISTS_TAC `s INTER interval[a:real^N,b]` THEN
5744   ASM_REWRITE_TAC[] THEN SIMP_TAC[indicator; IN_DIFF; IN_INTER] THEN
5745   MESON_TAC[]);;
5746
5747 let HAS_INTEGRAL_SPIKE_SET_EQ = prove
5748  (`!f:real^M->real^N s t y.
5749         negligible(s DIFF t UNION t DIFF s)
5750         ==> ((f has_integral y) s <=> (f has_integral y) t)`,
5751   REPEAT STRIP_TAC THEN  ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
5752   MATCH_MP_TAC HAS_INTEGRAL_SPIKE_EQ THEN
5753   EXISTS_TAC `s DIFF t UNION t DIFF s:real^M->bool` THEN
5754   ASM_REWRITE_TAC[] THEN SET_TAC[]);;
5755
5756 let HAS_INTEGRAL_SPIKE_SET = prove
5757  (`!f:real^M->real^N s t y.
5758         negligible(s DIFF t UNION t DIFF s) /\
5759         (f has_integral y) s
5760         ==> (f has_integral y) t`,
5761   MESON_TAC[HAS_INTEGRAL_SPIKE_SET_EQ]);;
5762
5763 let INTEGRABLE_SPIKE_SET = prove
5764  (`!f:real^M->real^N s t.
5765         negligible(s DIFF t UNION t DIFF s)
5766         ==> f integrable_on s ==> f integrable_on t`,
5767   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_SPIKE_SET_EQ]);;
5768
5769 let INTEGRABLE_SPIKE_SET_EQ = prove
5770  (`!f:real^M->real^N s t.
5771         negligible(s DIFF t UNION t DIFF s)
5772         ==> (f integrable_on s <=> f integrable_on t)`,
5773   MESON_TAC[INTEGRABLE_SPIKE_SET; UNION_COMM]);;
5774
5775 let INTEGRAL_SPIKE_SET = prove
5776  (`!f:real^M->real^N g s t.
5777         negligible(s DIFF t UNION t DIFF s)
5778         ==> integral s f = integral t f`,
5779   REPEAT STRIP_TAC THEN REWRITE_TAC[integral] THEN
5780   AP_TERM_TAC THEN ABS_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_SET_EQ THEN
5781   ASM_MESON_TAC[]);;
5782
5783 let HAS_INTEGRAL_INTERIOR = prove
5784  (`!f:real^M->real^N y s.
5785         negligible(frontier s)
5786         ==> ((f has_integral y) (interior s) <=> (f has_integral y) s)`,
5787   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_SET_EQ THEN
5788   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
5789     NEGLIGIBLE_SUBSET)) THEN
5790   REWRITE_TAC[frontier] THEN
5791   MP_TAC(ISPEC `s:real^M->bool` INTERIOR_SUBSET) THEN
5792   MP_TAC(ISPEC `s:real^M->bool` CLOSURE_SUBSET) THEN
5793   SET_TAC[]);;
5794
5795 let HAS_INTEGRAL_CLOSURE = prove
5796  (`!f:real^M->real^N y s.
5797         negligible(frontier s)
5798         ==> ((f has_integral y) (closure s) <=> (f has_integral y) s)`,
5799   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SPIKE_SET_EQ THEN
5800   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
5801     NEGLIGIBLE_SUBSET)) THEN
5802   REWRITE_TAC[frontier] THEN
5803   MP_TAC(ISPEC `s:real^M->bool` INTERIOR_SUBSET) THEN
5804   MP_TAC(ISPEC `s:real^M->bool` CLOSURE_SUBSET) THEN
5805   SET_TAC[]);;
5806
5807 (* ------------------------------------------------------------------------- *)
5808 (* More lemmas that are useful later.                                        *)
5809 (* ------------------------------------------------------------------------- *)
5810
5811 let HAS_INTEGRAL_SUBSET_COMPONENT_LE = prove
5812  (`!f:real^M->real^N s t i j k.
5813         s SUBSET t /\ (f has_integral i) s /\ (f has_integral j) t /\
5814         1 <= k /\ k <= dimindex(:N) /\
5815         (!x. x IN t ==> &0 <= f(x)$k)
5816         ==> i$k <= j$k`,
5817   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
5818   STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_COMPONENT_LE THEN
5819   MAP_EVERY EXISTS_TAC
5820    [`(\x. if x IN s then f x else vec 0):real^M->real^N`;
5821     `(\x. if x IN t then f x else vec 0):real^M->real^N`;
5822     `(:real^M)`] THEN
5823   ASM_REWRITE_TAC[] THEN
5824   REPEAT STRIP_TAC THEN
5825   REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL]) THEN
5826   ASM_SIMP_TAC[VEC_COMPONENT] THEN ASM SET_TAC[]);;
5827
5828 let INTEGRAL_SUBSET_COMPONENT_LE = prove
5829  (`!f:real^M->real^N s t k.
5830         s SUBSET t /\ f integrable_on s /\ f integrable_on t /\
5831         1 <= k /\ k <= dimindex(:N) /\
5832         (!x. x IN t ==> &0 <= f(x)$k)
5833         ==> (integral s f)$k <= (integral t f)$k`,
5834   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SUBSET_COMPONENT_LE THEN
5835   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
5836
5837 let HAS_INTEGRAL_SUBSET_DROP_LE = prove
5838  (`!f:real^M->real^1 s t i j.
5839         s SUBSET t /\ (f has_integral i) s /\ (f has_integral j) t /\
5840         (!x. x IN t ==> &0 <= drop(f x))
5841         ==> drop i <= drop j`,
5842   REWRITE_TAC[drop] THEN REPEAT STRIP_TAC THEN
5843   MATCH_MP_TAC HAS_INTEGRAL_SUBSET_COMPONENT_LE THEN
5844   REWRITE_TAC[DIMINDEX_1; LE_REFL] THEN ASM_MESON_TAC[]);;
5845
5846 let INTEGRAL_SUBSET_DROP_LE = prove
5847  (`!f:real^M->real^1 s t.
5848         s SUBSET t /\ f integrable_on s /\ f integrable_on t /\
5849         (!x. x IN t ==> &0 <= drop(f(x)))
5850         ==> drop(integral s f) <= drop(integral t f)`,
5851   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_INTEGRAL_SUBSET_DROP_LE THEN
5852   ASM_MESON_TAC[INTEGRABLE_INTEGRAL]);;
5853
5854 let HAS_INTEGRAL_ALT = prove
5855  (`!f:real^M->real^N s i.
5856         (f has_integral i) s <=>
5857             (!a b. (\x. if x IN s then f x else vec 0)
5858                    integrable_on interval[a,b]) /\
5859             (!e. &0 < e
5860                  ==> ?B. &0 < B /\
5861                          !a b. ball (vec 0,B) SUBSET interval[a,b]
5862                                ==> norm(integral(interval[a,b])
5863                                           (\x. if x IN s then f x else vec 0) -
5864                                         i) < e)`,
5865   REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [HAS_INTEGRAL] THEN
5866   SPEC_TAC(`\x. if x IN s then (f:real^M->real^N) x else vec 0`,
5867            `f:real^M->real^N`) THEN
5868   GEN_TAC THEN EQ_TAC THENL
5869    [ALL_TAC; MESON_TAC[INTEGRAL_UNIQUE; integrable_on]] THEN
5870   DISCH_TAC THEN CONJ_TAC THENL
5871    [ALL_TAC; ASM_MESON_TAC[INTEGRAL_UNIQUE]] THEN
5872   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
5873   POP_ASSUM(MP_TAC o C MATCH_MP REAL_LT_01) THEN
5874   DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
5875   MATCH_MP_TAC INTEGRABLE_SUBINTERVAL THEN
5876   EXISTS_TAC `(lambda i. min ((a:real^M)$i) (--B)):real^M` THEN
5877   EXISTS_TAC `(lambda i. max ((b:real^M)$i) B):real^M` THEN CONJ_TAC THENL
5878    [FIRST_X_ASSUM(MP_TAC o SPECL
5879      [`(lambda i. min ((a:real^M)$i) (--B)):real^M`;
5880       `(lambda i. max ((b:real^M)$i) B):real^M`]) THEN
5881     ANTS_TAC THENL [ALL_TAC; MESON_TAC[integrable_on]];
5882     SIMP_TAC[SUBSET; IN_INTERVAL; IN_BALL; LAMBDA_BETA;
5883              REAL_MIN_LE; REAL_LE_MAX]] THEN
5884   SIMP_TAC[SUBSET; IN_BALL; IN_INTERVAL; LAMBDA_BETA] THEN
5885   GEN_TAC THEN REWRITE_TAC[NORM_ARITH `dist(vec 0,x) = norm x`] THEN
5886   DISCH_TAC THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
5887   MATCH_MP_TAC(REAL_ARITH
5888     `abs(x) <= B ==> min a (--B) <= x /\ x <= max b B`) THEN
5889   MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^M)` THEN
5890   ASM_SIMP_TAC[REAL_LT_IMP_LE; COMPONENT_LE_NORM]);;
5891
5892 let INTEGRABLE_ALT = prove
5893  (`!f:real^M->real^N s.
5894         f integrable_on s <=>
5895           (!a b. (\x. if x IN s then f x else vec 0) integrable_on
5896                  interval[a,b]) /\
5897           (!e. &0 < e
5898                ==> ?B. &0 < B /\
5899                        !a b c d.
5900                           ball(vec 0,B) SUBSET interval[a,b] /\
5901                           ball(vec 0,B) SUBSET interval[c,d]
5902                           ==> norm(integral (interval[a,b])
5903                                     (\x. if x IN s then f x else vec 0) -
5904                                    integral (interval[c,d])
5905                                     (\x. if x IN s then f x else vec 0)) < e)`,
5906   REPEAT GEN_TAC THEN
5907   GEN_REWRITE_TAC LAND_CONV [integrable_on] THEN
5908   ONCE_REWRITE_TAC[HAS_INTEGRAL_ALT] THEN
5909   REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN
5910   MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> (a /\ b <=> a /\ c)`) THEN
5911   DISCH_TAC THEN EQ_TAC THENL
5912    [DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN
5913     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5914     FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
5915     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
5916     MESON_TAC[NORM_ARITH `norm(a - y) < e / &2 /\ norm(b - y) < e / &2
5917                           ==> norm(a - b) < e`];
5918     ALL_TAC] THEN
5919   DISCH_TAC THEN
5920   SUBGOAL_THEN
5921    `cauchy (\n. integral (interval[(lambda i. --(&n)),(lambda i. &n)])
5922                          (\x. if x IN s then (f:real^M->real^N) x else vec 0))`
5923   MP_TAC THENL
5924    [REWRITE_TAC[cauchy] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5925     FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
5926     DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
5927     MP_TAC(SPEC `B:real` REAL_ARCH_SIMPLE) THEN
5928     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN
5929     REPEAT STRIP_TAC THEN REWRITE_TAC[dist] THEN
5930     FIRST_X_ASSUM MATCH_MP_TAC THEN
5931     REWRITE_TAC[SUBSET; IN_BALL; NORM_ARITH `dist(vec 0,x) = norm x`] THEN
5932     CONJ_TAC;
5933     REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN
5934     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `i:real^N` THEN
5935     REWRITE_TAC[LIM_SEQUENTIALLY] THEN DISCH_THEN(LABEL_TAC "C") THEN
5936     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5937     REMOVE_THEN "C" (MP_TAC o SPEC `e / &2`) THEN
5938     FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
5939     DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
5940     DISCH_THEN(X_CHOOSE_THEN `N:num` ASSUME_TAC) THEN
5941     MP_TAC(SPEC `max (&N) B` REAL_ARCH_SIMPLE) THEN
5942     REWRITE_TAC[REAL_MAX_LE; REAL_OF_NUM_LE] THEN
5943     DISCH_THEN(X_CHOOSE_THEN `n:num` STRIP_ASSUME_TAC) THEN
5944     EXISTS_TAC `&n` THEN CONJ_TAC THENL
5945      [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
5946     MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN STRIP_TAC THEN
5947     FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN ASM_REWRITE_TAC[] THEN
5948     MATCH_MP_TAC(NORM_ARITH
5949      `norm(i1 - i2) < e / &2 ==> dist(i1,i) < e / &2 ==> norm(i2 - i) < e`) THEN
5950     FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THEN
5951     MATCH_MP_TAC SUBSET_TRANS THEN EXISTS_TAC `ball(vec 0:real^M,&n)` THEN
5952     ASM_SIMP_TAC[SUBSET_BALL] THEN
5953     REWRITE_TAC[SUBSET; IN_BALL; NORM_ARITH `dist(vec 0,x) = norm x`]] THEN
5954   X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
5955   SIMP_TAC[IN_INTERVAL; LAMBDA_BETA] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
5956   REWRITE_TAC[REAL_BOUNDS_LE] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
5957   EXISTS_TAC `norm(x:real^M)` THEN ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
5958   REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[GSYM REAL_OF_NUM_GE] THEN
5959   REAL_ARITH_TAC);;
5960
5961 let INTEGRABLE_ALT_SUBSET = prove
5962  (`!f:real^M->real^N s.
5963         f integrable_on s <=>
5964           (!a b. (\x. if x IN s then f x else vec 0) integrable_on
5965                  interval[a,b]) /\
5966           (!e. &0 < e
5967                ==> ?B. &0 < B /\
5968                        !a b c d.
5969                           ball(vec 0,B) SUBSET interval[a,b] /\
5970                           interval[a,b] SUBSET interval[c,d]
5971                           ==> norm(integral (interval[a,b])
5972                                     (\x. if x IN s then f x else vec 0) -
5973                                    integral (interval[c,d])
5974                                     (\x. if x IN s then f x else vec 0)) < e)`,
5975   REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [INTEGRABLE_ALT] THEN
5976   ABBREV_TAC `g:real^M->real^N = \x. if x IN s then f x else vec 0` THEN
5977   POP_ASSUM(K ALL_TAC) THEN
5978   MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> (a /\ b <=> a /\ c)`) THEN
5979   DISCH_TAC THEN EQ_TAC THENL [MESON_TAC[SUBSET_TRANS]; ALL_TAC] THEN
5980   DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
5981   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
5982   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
5983   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
5984   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real^M`; `d:real^M`] THEN
5985   STRIP_TAC THEN
5986   FIRST_X_ASSUM(MP_TAC o SPECL
5987    [`(lambda i. max ((a:real^M)$i) ((c:real^M)$i)):real^M`;
5988     `(lambda i. min ((b:real^M)$i) ((d:real^M)$i)):real^M`]) THEN
5989   ASM_REWRITE_TAC[GSYM INTER_INTERVAL; SUBSET_INTER] THEN
5990   DISCH_THEN(fun th ->
5991     MP_TAC(ISPECL [`a:real^M`; `b:real^M`] th) THEN
5992     MP_TAC(ISPECL [`c:real^M`; `d:real^M`] th)) THEN
5993   ASM_REWRITE_TAC[INTER_SUBSET] THEN NORM_ARITH_TAC);;
5994
5995 let INTEGRABLE_ON_SUBINTERVAL = prove
5996  (`!f:real^M->real^N s a b.
5997         f integrable_on s /\ interval[a,b] SUBSET s
5998         ==> f integrable_on interval[a,b]`,
5999   REPEAT GEN_TAC THEN
6000   GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [INTEGRABLE_ALT] THEN
6001   DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o CONJUNCT1) ASSUME_TAC) THEN
6002   DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN
6003   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] INTEGRABLE_EQ) THEN
6004   ASM SET_TAC[]);;
6005
6006 let INTEGRAL_SPLIT = prove
6007  (`!f:real^M->real^N a b t k.
6008         f integrable_on interval[a,b] /\ 1 <= k /\ k <= dimindex(:M)
6009         ==> integral (interval[a,b]) f =
6010                 integral(interval
6011                  [a,(lambda i. if i = k then min (b$k) t else b$i)]) f +
6012                 integral(interval
6013                  [(lambda i. if i = k then max (a$k) t else a$i),b]) f`,
6014   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
6015   MATCH_MP_TAC HAS_INTEGRAL_SPLIT THEN
6016   MAP_EVERY EXISTS_TAC [`k:num`; `t:real`] THEN
6017   ASM_SIMP_TAC[INTERVAL_SPLIT; GSYM HAS_INTEGRAL_INTEGRAL] THEN
6018   CONJ_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
6019   EXISTS_TAC `interval[a:real^M,b]` THEN
6020   ASM_SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN
6021   REPEAT STRIP_TAC THEN TRY COND_CASES_TAC THEN
6022   ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC);;
6023
6024 let INTEGRAL_SPLIT_SIGNED = prove
6025  (`!f:real^M->real^N a b t k.
6026         1 <= k /\ k <= dimindex(:M) /\ a$k <= t /\ a$k <= b$k /\
6027         f integrable_on
6028         interval[a,(lambda i. if i = k then max (b$k) t else b$i)]
6029         ==> integral (interval[a,b]) f =
6030                 integral(interval
6031                  [a,(lambda i. if i = k then t else b$i)]) f +
6032                 (if b$k < t then -- &1 else &1) %
6033                 integral(interval
6034                  [(lambda i. if i = k then min (b$k) t else a$i),
6035                   (lambda i. if i = k then max (b$k) t else b$i)]) f`,
6036   REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
6037    [MP_TAC(ISPECL
6038     [`f:real^M->real^N`;
6039      `a:real^M`;
6040      `(lambda i. if i = k then t else (b:real^M)$i):real^M`;
6041      `(b:real^M)$k`; `k:num`]
6042         INTEGRAL_SPLIT) THEN
6043     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
6044      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
6045        (REWRITE_RULE[IMP_CONJ] INTEGRABLE_ON_SUBINTERVAL)) THEN
6046       ASM_SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN
6047       REPEAT STRIP_TAC THEN TRY COND_CASES_TAC THEN
6048       ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC;
6049       DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC(VECTOR_ARITH
6050        `x = y /\ w = z
6051         ==> x:real^N = (y + z) + --(&1) % w`) THEN
6052       CONJ_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
6053       REWRITE_TAC[CONS_11; PAIR_EQ; CART_EQ] THEN TRY CONJ_TAC THEN
6054       ASM_SIMP_TAC[LAMBDA_BETA] THEN
6055       GEN_TAC THEN STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN
6056       ASM_REAL_ARITH_TAC];
6057     MP_TAC(ISPECL
6058     [`f:real^M->real^N`;
6059      `a:real^M`;
6060      `b:real^M`;
6061      `t:real`; `k:num`]
6062         INTEGRAL_SPLIT) THEN
6063     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
6064      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
6065        (REWRITE_RULE[IMP_CONJ] INTEGRABLE_ON_SUBINTERVAL)) THEN
6066       ASM_SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN
6067       REPEAT STRIP_TAC THEN TRY COND_CASES_TAC THEN
6068       ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC;
6069       DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[VECTOR_MUL_LID] THEN
6070       BINOP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
6071       REWRITE_TAC[CONS_11; PAIR_EQ; CART_EQ] THEN TRY CONJ_TAC THEN
6072       ASM_SIMP_TAC[LAMBDA_BETA] THEN
6073       GEN_TAC THEN STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN
6074       ASM_REAL_ARITH_TAC]]);;
6075
6076 let INTEGRAL_INTERVALS_INCLUSION_EXCLUSION = prove
6077  (`!f:real^M->real^N a b c d.
6078         f integrable_on interval[a,b] /\
6079         c IN interval[a,b] /\ d IN interval[a,b]
6080         ==> integral(interval[a,d]) f =
6081                 vsum {s | s SUBSET 1..dimindex(:M)}
6082                     (\s. --(&1) pow CARD {i | i IN s /\ d$i < c$i} %
6083                          integral
6084                           (interval[(lambda i. if i IN s
6085                                                then min (c$i) (d$i)
6086                                                else (a:real^M)$i),
6087                                     (lambda i. if i IN s
6088                                                then max (c$i) (d$i)
6089                                                else c$i)]) f)`,
6090   let lemma1 = prove
6091    (`!f:(num->bool)->real^N n.
6092           vsum {s | s SUBSET 1..SUC n} f =
6093           vsum {s | s SUBSET 1..n} f +
6094           vsum {s | s SUBSET 1..n} (\s. f(SUC n INSERT s))`,
6095     REPEAT STRIP_TAC THEN
6096     REWRITE_TAC[NUMSEG_CLAUSES; ARITH_RULE `1 <= SUC n`; POWERSET_CLAUSES] THEN
6097     W(MP_TAC o PART_MATCH (lhs o rand) VSUM_UNION o lhs o snd) THEN
6098     ANTS_TAC THENL
6099      [ASM_SIMP_TAC[FINITE_IMAGE; FINITE_POWERSET; FINITE_NUMSEG] THEN
6100       REWRITE_TAC[SET_RULE
6101        `DISJOINT s (IMAGE f t) <=> !x. x IN t ==> ~(f x IN s)`] THEN
6102       GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM; SUBSET] THEN
6103       DISCH_THEN(MP_TAC o SPEC `SUC n`) THEN
6104       REWRITE_TAC[IN_INSERT; IN_NUMSEG] THEN ARITH_TAC;
6105       DISCH_THEN SUBST1_TAC THEN AP_TERM_TAC THEN
6106       MATCH_MP_TAC(REWRITE_RULE[o_DEF] VSUM_IMAGE) THEN
6107       SIMP_TAC[FINITE_POWERSET; FINITE_NUMSEG] THEN
6108       MAP_EVERY X_GEN_TAC [`s:num->bool`; `t:num->bool`] THEN
6109       REWRITE_TAC[IN_ELIM_THM] THEN MATCH_MP_TAC(SET_RULE
6110        `~(a IN i)
6111         ==> s SUBSET i /\ t SUBSET i /\ a INSERT s = a INSERT t
6112             ==> s = t`) THEN
6113       REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC]) in
6114   let lemma2 = prove
6115    (`!f:real^M->real^N m a:real^M c:real^M d:real^M.
6116           f integrable_on (:real^M) /\ m <= dimindex(:M) /\
6117           (!i. m < i /\ i <= dimindex(:M) ==> a$i = c$i \/ d$i = c$i) /\
6118           (!i. m < i /\ i <= dimindex(:M) ==> a$i = c$i ==> a$i = d$i) /\
6119           (!i. 1 <= i /\ i <= dimindex(:M) ==> a$i <= c$i /\ a$i <= d$i)
6120           ==> integral(interval[a,d]) f =
6121                   vsum {s | s SUBSET 1..m}
6122                       (\s. --(&1) pow CARD {i | i IN s /\ d$i < c$i} %
6123                            integral
6124                             (interval[(lambda i. if i IN s
6125                                                  then min (c$i) (d$i)
6126                                                  else (a:real^M)$i),
6127                                       (lambda i. if i IN s
6128                                                  then max (c$i) (d$i)
6129                                                  else c$i)]) f)`,
6130     GEN_TAC THEN INDUCT_TAC THENL
6131      [REWRITE_TAC[NUMSEG_CLAUSES; ARITH; SUBSET_EMPTY; SING_GSPEC] THEN
6132       REWRITE_TAC[VSUM_SING; NOT_IN_EMPTY; EMPTY_GSPEC; CARD_CLAUSES] THEN
6133       REWRITE_TAC[real_pow; LAMBDA_ETA; VECTOR_MUL_LID] THEN
6134       REWRITE_TAC[ARITH_RULE `0 < i <=> 1 <= i`] THEN REPEAT STRIP_TAC THEN
6135       ASM_CASES_TAC
6136        `?k. 1 <= k /\ k <= dimindex(:M) /\ (a:real^M)$k = (c:real^M)$k`
6137       THENL
6138        [MATCH_MP_TAC(MESON[] `i = vec 0 /\ j = vec 0 ==> i:real^N = j`) THEN
6139         CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_NULL THEN
6140         REWRITE_TAC[CONTENT_EQ_0] THEN ASM_MESON_TAC[];
6141         SUBGOAL_THEN `d:real^M = c:real^M` (fun th -> REWRITE_TAC[th]) THEN
6142         REWRITE_TAC[CART_EQ] THEN ASM_MESON_TAC[]];
6143       ALL_TAC] THEN
6144     REPEAT STRIP_TAC THEN REWRITE_TAC[lemma1] THEN
6145     SUBGOAL_THEN
6146      `!s. s SUBSET 1..m
6147           ==> --(&1) pow CARD {i | i IN SUC m INSERT s /\ d$i < c$i} =
6148               (if (d:real^M)$(SUC m) < (c:real^M)$(SUC m) then -- &1 else &1) *
6149               --(&1) pow CARD {i | i IN s /\ d$i < c$i}`
6150      (fun th -> SIMP_TAC[th; IN_ELIM_THM]) THENL
6151      [X_GEN_TAC `s:num->bool` THEN DISCH_TAC THEN
6152       SUBGOAL_THEN `FINITE(s:num->bool)` ASSUME_TAC THENL
6153        [ASM_MESON_TAC[FINITE_NUMSEG; FINITE_SUBSET]; ALL_TAC] THEN
6154       COND_CASES_TAC THENL
6155        [ASM_SIMP_TAC[CARD_CLAUSES; FINITE_RESTRICT; SET_RULE
6156          `P a ==> {x | x IN a INSERT s /\ P x} =
6157                   a INSERT {x | x IN s /\ P x}`] THEN
6158         REWRITE_TAC[IN_ELIM_THM] THEN COND_CASES_TAC THEN
6159         ASM_REWRITE_TAC[real_pow] THEN
6160         SUBGOAL_THEN `~(SUC m IN 1..m)` (fun th -> ASM SET_TAC[th]) THEN
6161         REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC;
6162         ASM_SIMP_TAC[REAL_MUL_LID; SET_RULE
6163          `~(P a) ==> {x | x IN a INSERT s /\ P x} = {x | x IN s /\ P x}`]];
6164       ALL_TAC] THEN
6165     MP_TAC(ISPECL
6166      [`f:real^M->real^N`; `a:real^M`; `d:real^M`; `(c:real^M)$SUC m`; `SUC m`]
6167          INTEGRAL_SPLIT_SIGNED) THEN
6168     ANTS_TAC THENL
6169      [ASM_MESON_TAC[ARITH_RULE `1 <= SUC n`; INTEGRABLE_ON_SUBINTERVAL;
6170                     SUBSET_UNIV];
6171       DISCH_THEN SUBST1_TAC] THEN
6172     REWRITE_TAC[VSUM_LMUL; GSYM VECTOR_MUL_ASSOC] THEN
6173     BINOP_TAC THENL [ALL_TAC; AP_TERM_TAC] THENL
6174      [FIRST_X_ASSUM(MP_TAC o SPECL
6175        [`a:real^M`;
6176         `c:real^M`;
6177         `(lambda i. if i = SUC m then (c:real^M)$SUC m
6178                     else (d:real^M)$i):real^M`]);
6179       FIRST_X_ASSUM(MP_TAC o SPECL
6180        [`(lambda i. if i = SUC m
6181                     then min ((d:real^M)$SUC m) ((c:real^M)$SUC m)
6182                     else (a:real^M)$i):real^M`;
6183         `(lambda i. if i = SUC m
6184                     then max ((d:real^M)$SUC m) ((c:real^M)$SUC m)
6185                     else (c:real^M)$i):real^M`;
6186         `(lambda i. if i = SUC m
6187                     then max ((d:real^M)$SUC m) ((c:real^M)$SUC m)
6188                     else d$i):real^M`])] THEN
6189     (ANTS_TAC THENL
6190       [ASM_REWRITE_TAC[] THEN
6191        CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
6192        CONJ_TAC THENL
6193         [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
6194          SUBGOAL_THEN `1 <= i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
6195          ASM_SIMP_TAC[LAMBDA_BETA] THEN
6196          COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
6197          FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC;
6198          ALL_TAC] THEN
6199        CONJ_TAC THENL
6200         [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
6201          SUBGOAL_THEN `1 <= i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
6202          ASM_SIMP_TAC[LAMBDA_BETA] THEN
6203          COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
6204          ASM_MESON_TAC[ARITH_RULE `m < i <=> i = SUC m \/ SUC m < i`];
6205          X_GEN_TAC `i:num` THEN STRIP_TAC THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN
6206          COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN TRY REAL_ARITH_TAC THEN
6207          FIRST_X_ASSUM SUBST_ALL_TAC THEN ASM_REWRITE_TAC[] THEN
6208          ASM_MESON_TAC[]];
6209        DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
6210        X_GEN_TAC `s:num->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN
6211        DISCH_TAC THEN BINOP_TAC THENL
6212         [AP_TERM_TAC THEN AP_TERM_TAC THEN
6213          REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
6214          X_GEN_TAC `i:num` THEN
6215          ASM_CASES_TAC `(i:num) IN s` THEN ASM_REWRITE_TAC[] THEN
6216          SUBGOAL_THEN `i IN 1..m` MP_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
6217          REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN
6218          SUBGOAL_THEN `i <= dimindex(:M)` ASSUME_TAC THENL
6219           [ASM_ARITH_TAC; ALL_TAC] THEN
6220          ASM_SIMP_TAC[LAMBDA_BETA] THEN
6221          COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC;
6222          AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
6223          REWRITE_TAC[CONS_11; PAIR_EQ] THEN
6224          SIMP_TAC[CART_EQ; LAMBDA_BETA; AND_FORALL_THM] THEN
6225          X_GEN_TAC `i:num` THEN
6226          ASM_CASES_TAC `1 <= i /\ i <= dimindex(:M)` THEN
6227          ASM_REWRITE_TAC[] THEN
6228          ASM_CASES_TAC `(i:num) IN s` THEN ASM_REWRITE_TAC[IN_INSERT] THEN
6229          COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN TRY REAL_ARITH_TAC THEN
6230          SUBGOAL_THEN `~(SUC m IN 1..m)` (fun th -> ASM SET_TAC[th]) THEN
6231          REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC]])) in
6232   REWRITE_TAC[IN_INTERVAL] THEN REPEAT STRIP_TAC THEN
6233   MP_TAC(ISPECL
6234    [`\x. if x IN interval[a,b] then (f:real^M->real^N) x else vec 0`;
6235     `dimindex(:M)`; `a:real^M`; `c:real^M`; `d:real^M`]
6236    lemma2) THEN
6237   ASM_SIMP_TAC[LTE_ANTISYM; INTEGRABLE_RESTRICT_UNIV; LE_REFL] THEN
6238   MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THENL
6239    [ALL_TAC;
6240     MATCH_MP_TAC VSUM_EQ THEN X_GEN_TAC `s:num->bool` THEN
6241     REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN AP_TERM_TAC] THEN
6242   MATCH_MP_TAC INTEGRAL_EQ THEN ASM_REWRITE_TAC[] THEN
6243   MATCH_MP_TAC(SET_RULE
6244    `i SUBSET j ==> !x. x IN i ==> (if x IN j then f x else b) = f x`) THEN
6245   ASM_SIMP_TAC[SUBSET_INTERVAL; REAL_LE_REFL; LAMBDA_BETA] THEN
6246   DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
6247   REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN
6248   ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;
6249
6250 let INTEGRAL_INTERVALS_DIFF_INCLUSION_EXCLUSION = prove
6251  (`!f:real^M->real^N a b c d.
6252         f integrable_on interval[a,b] /\
6253         c IN interval[a,b] /\ d IN interval[a,b]
6254         ==> integral(interval[a,d]) f - integral(interval[a,c]) f =
6255                 vsum {s | ~(s = {}) /\ s SUBSET 1..dimindex(:M)}
6256                     (\s. --(&1) pow CARD {i | i IN s /\ d$i < c$i} %
6257                          integral
6258                           (interval[(lambda i. if i IN s
6259                                                then min (c$i) (d$i)
6260                                                else (a:real^M)$i),
6261                                     (lambda i. if i IN s
6262                                                then max (c$i) (d$i)
6263                                                else c$i)]) f)`,
6264   REPEAT GEN_TAC THEN DISCH_TAC THEN
6265   FIRST_ASSUM(SUBST1_TAC o
6266    MATCH_MP INTEGRAL_INTERVALS_INCLUSION_EXCLUSION) THEN
6267   REWRITE_TAC[SET_RULE `{s | ~(s = a) /\ P s} = {s | P s} DELETE a`] THEN
6268   SIMP_TAC[VSUM_DELETE; FINITE_POWERSET; FINITE_NUMSEG; EMPTY_SUBSET;
6269            IN_ELIM_THM] THEN
6270   REWRITE_TAC[NOT_IN_EMPTY; EMPTY_GSPEC; CARD_CLAUSES; LAMBDA_ETA] THEN
6271   REWRITE_TAC[real_pow; VECTOR_MUL_LID]);;
6272
6273 let INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_RIGHT = prove
6274  (`!f:real^M->real^N a b c.
6275         f integrable_on interval[a,b] /\ c IN interval[a,b]
6276         ==> integral(interval[a,c]) f =
6277                 vsum {s | s SUBSET 1..dimindex (:M)}
6278                      (\s. --(&1) pow CARD s %
6279                           integral
6280                            (interval[(lambda i. if i IN s then c$i else a$i),
6281                                      b])
6282                            f)`,
6283   REPEAT STRIP_TAC THEN MP_TAC(ISPECL
6284    [`f:real^M->real^N`; `a:real^M`; `b:real^M`; `b:real^M`; `c:real^M`]
6285         INTEGRAL_INTERVALS_INCLUSION_EXCLUSION) THEN
6286   ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN ANTS_TAC THENL
6287    [ASM_MESON_TAC[ENDS_IN_INTERVAL; MEMBER_NOT_EMPTY]; ALL_TAC] THEN
6288   DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
6289   X_GEN_TAC `s:num->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN STRIP_TAC THEN
6290   ASM_CASES_TAC `?k. k IN s /\ (c:real^M)$k = (b:real^M)$k` THENL
6291    [FIRST_X_ASSUM(X_CHOOSE_THEN `k:num` STRIP_ASSUME_TAC) THEN
6292     SUBGOAL_THEN `1 <= k /\ k <= dimindex(:M)` STRIP_ASSUME_TAC THENL
6293      [ASM_MESON_TAC[IN_NUMSEG; SUBSET]; ALL_TAC] THEN
6294     MATCH_MP_TAC(MESON[] `a:real^N = vec 0 /\ b = vec 0 ==> a = b`) THEN
6295     CONJ_TAC THEN REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ2_TAC THEN
6296     MATCH_MP_TAC INTEGRAL_NULL THEN REWRITE_TAC[CONTENT_EQ_0] THEN
6297     EXISTS_TAC `k:num` THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC;
6298     ALL_TAC] THEN
6299   RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN BINOP_TAC THENL
6300    [AP_TERM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
6301     ASM_MESON_TAC[REAL_LT_LE; SUBSET; IN_NUMSEG];
6302     AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
6303     AP_THM_TAC THEN AP_TERM_TAC THEN
6304     ASM_SIMP_TAC[CART_EQ; PAIR_EQ; LAMBDA_BETA] THEN
6305     CONJ_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
6306     FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
6307     REAL_ARITH_TAC]);;
6308
6309 let INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_LEFT = prove
6310  (`!f:real^M->real^N a b c.
6311         f integrable_on interval[a,b] /\ c IN interval[a,b]
6312         ==> integral(interval[c,b]) f =
6313                 vsum {s | s SUBSET 1..dimindex (:M)}
6314                      (\s. --(&1) pow CARD s %
6315                           integral
6316                            (interval[a,(lambda i. if i IN s then c$i else b$i)])
6317                            f)`,
6318   REPEAT STRIP_TAC THEN MP_TAC(ISPECL
6319    [`\x. (f:real^M->real^N) (--x)`;
6320     `--b:real^M`;
6321     `--a:real^M`;
6322     `--c:real^M`]
6323         INTEGRAL_INTERVALS_INCLUSION_EXCLUSION_RIGHT) THEN
6324   REWRITE_TAC[REAL_ARITH `min (--a) (--b) = --(max a b)`;
6325               REAL_ARITH `max (--a) (--b) = --(min a b)`;
6326               VECTOR_NEG_COMPONENT] THEN
6327   SUBGOAL_THEN
6328    `!P x y. (lambda i. if P i then --(x i) else --(y i)):real^M =
6329             --(lambda i. if P i then x i else y i)`
6330    (fun th -> REWRITE_TAC[th])
6331   THENL
6332    [SIMP_TAC[CART_EQ; VECTOR_NEG_COMPONENT; LAMBDA_BETA] THEN MESON_TAC[];
6333     ALL_TAC] THEN
6334   ASM_REWRITE_TAC[INTEGRAL_REFLECT; INTEGRABLE_REFLECT;
6335                   IN_INTERVAL_REFLECT]);;
6336
6337 (* ------------------------------------------------------------------------- *)
6338 (* A straddling criterion for integrability.                                 *)
6339 (* ------------------------------------------------------------------------- *)
6340
6341 let INTEGRABLE_STRADDLE_INTERVAL = prove
6342  (`!f:real^N->real^1 a b.
6343         (!e. &0 < e
6344              ==> ?g h i j. (g has_integral i) (interval[a,b]) /\
6345                            (h has_integral j) (interval[a,b]) /\
6346                            norm(i - j) < e /\
6347                            !x. x IN interval[a,b]
6348                                ==> drop(g x) <= drop(f x) /\
6349                                    drop(f x) <= drop(h x))
6350         ==> f integrable_on interval[a,b]`,
6351   REPEAT STRIP_TAC THEN REWRITE_TAC[INTEGRABLE_CAUCHY] THEN
6352   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6353   FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN
6354   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH; LEFT_IMP_EXISTS_THM] THEN
6355   MAP_EVERY X_GEN_TAC
6356    [`g:real^N->real^1`; `h:real^N->real^1`; `i:real^1`; `j:real^1`] THEN
6357   REWRITE_TAC[has_integral] THEN REWRITE_TAC[IMP_CONJ] THEN
6358   DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
6359   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
6360   DISCH_THEN(X_CHOOSE_THEN `d1:real^N->real^N->bool` STRIP_ASSUME_TAC) THEN
6361   DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
6362   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
6363   DISCH_THEN(X_CHOOSE_THEN `d2:real^N->real^N->bool` STRIP_ASSUME_TAC) THEN
6364   DISCH_TAC THEN DISCH_TAC THEN
6365   EXISTS_TAC `(\x. d1 x INTER d2 x):real^N->real^N->bool` THEN
6366   ASM_SIMP_TAC[GAUGE_INTER; FINE_INTER] THEN
6367   MAP_EVERY X_GEN_TAC
6368    [`p1:(real^N#(real^N->bool))->bool`;
6369     `p2:(real^N#(real^N->bool))->bool`] THEN
6370   REPEAT STRIP_TAC THEN
6371   REPEAT(FIRST_X_ASSUM(fun th ->
6372    MP_TAC(SPEC `p1:(real^N#(real^N->bool))->bool` th) THEN
6373    MP_TAC(SPEC `p2:(real^N#(real^N->bool))->bool` th))) THEN
6374   EVERY_ASSUM(fun th -> try ASSUME_TAC(MATCH_MP TAGGED_DIVISION_OF_FINITE th)
6375                         with Failure _ -> ALL_TAC) THEN
6376   ASM_SIMP_TAC[VSUM_REAL] THEN REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM] THEN
6377   SUBST1_TAC(SYM(ISPEC `i:real^1` (CONJUNCT1 LIFT_DROP))) THEN
6378   SUBST1_TAC(SYM(ISPEC `j:real^1` (CONJUNCT1 LIFT_DROP))) THEN
6379   REWRITE_TAC[GSYM LIFT_SUB; DROP_CMUL; NORM_LIFT] THEN
6380   MATCH_MP_TAC(REAL_ARITH
6381    `g1 - h2 <= f1 - f2 /\ f1 - f2 <= h1 - g2 /\
6382     abs(i - j) < e / &3
6383     ==> abs(g2 - i) < e / &3
6384         ==> abs(g1 - i) < e / &3
6385             ==> abs(h2 - j) < e / &3
6386                 ==> abs(h1 - j) < e / &3
6387                     ==> abs(f1 - f2) < e`) THEN
6388   ASM_REWRITE_TAC[GSYM DROP_SUB; GSYM NORM_LIFT; LIFT_DROP] THEN CONJ_TAC THEN
6389   MATCH_MP_TAC(REAL_ARITH `x <= x' /\ y' <= y ==> x - y <= x' - y'`) THEN
6390   CONJ_TAC THEN MATCH_MP_TAC SUM_LE THEN
6391   REWRITE_TAC[FORALL_PAIR_THM] THEN REPEAT STRIP_TAC THEN
6392   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_LMUL THEN
6393   ASM_MESON_TAC[TAGGED_DIVISION_OF; CONTENT_POS_LE; SUBSET]);;
6394
6395 let INTEGRABLE_STRADDLE = prove
6396  (`!f:real^N->real^1 s.
6397         (!e. &0 < e
6398              ==> ?g h i j. (g has_integral i) s /\
6399                            (h has_integral j) s /\
6400                            norm(i - j) < e /\
6401                            !x. x IN s
6402                                ==> drop(g x) <= drop(f x) /\
6403                                    drop(f x) <= drop(h x))
6404         ==> f integrable_on s`,
6405   let lemma = prove
6406    (`&0 <= drop x /\ drop x <= drop y ==> norm x <= norm y`,
6407     REWRITE_TAC[NORM_REAL; GSYM drop] THEN REAL_ARITH_TAC) in
6408   REPEAT STRIP_TAC THEN
6409   SUBGOAL_THEN
6410    `!a b. (\x. if x IN s then (f:real^N->real^1) x else vec 0)
6411           integrable_on interval[a,b]`
6412   ASSUME_TAC THENL
6413    [RULE_ASSUM_TAC(REWRITE_RULE[HAS_INTEGRAL_ALT]) THEN
6414     MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
6415     MATCH_MP_TAC INTEGRABLE_STRADDLE_INTERVAL THEN
6416     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6417     FIRST_X_ASSUM(MP_TAC o SPEC `e / &4`) THEN
6418     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
6419     REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
6420     MAP_EVERY X_GEN_TAC
6421      [`g:real^N->real^1`; `h:real^N->real^1`; `i:real^1`; `j:real^1`] THEN
6422     REWRITE_TAC[GSYM CONJ_ASSOC] THEN
6423     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6424     DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `e / &4`) MP_TAC) THEN
6425     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6426     DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `e / &4`) STRIP_ASSUME_TAC) THEN
6427     ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
6428     DISCH_THEN(X_CHOOSE_THEN `B2:real`
6429      (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "H"))) THEN
6430     DISCH_THEN(X_CHOOSE_THEN `B1:real`
6431      (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "G"))) THEN
6432     MAP_EVERY EXISTS_TAC
6433      [`\x. if x IN s then (g:real^N->real^1) x else vec 0`;
6434       `\x. if x IN s then (h:real^N->real^1) x else vec 0`;
6435       `integral(interval[a:real^N,b])
6436          (\x. if x IN s then (g:real^N->real^1) x else vec 0:real^1)`;
6437       `integral(interval[a:real^N,b])
6438          (\x. if x IN s then (h:real^N->real^1) x else vec 0:real^1)`] THEN
6439     ASM_SIMP_TAC[INTEGRABLE_INTEGRAL] THEN
6440     CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LE_REFL]] THEN
6441     ABBREV_TAC `c:real^N = lambda i. min ((a:real^N)$i) (--(max B1 B2))` THEN
6442     ABBREV_TAC `d:real^N = lambda i. max ((b:real^N)$i) (max B1 B2)` THEN
6443     REMOVE_THEN "H" (MP_TAC o SPECL [`c:real^N`; `d:real^N`]) THEN
6444     REMOVE_THEN "G" (MP_TAC o SPECL [`c:real^N`; `d:real^N`]) THEN
6445     MATCH_MP_TAC(TAUT
6446         `(a /\ c) /\ (b /\ d ==> e) ==> (a ==> b) ==> (c ==> d) ==> e`) THEN
6447     CONJ_TAC THENL
6448      [CONJ_TAC THEN MAP_EVERY EXPAND_TAC ["c"; "d"] THEN
6449       SIMP_TAC[SUBSET; IN_BALL; IN_INTERVAL; LAMBDA_BETA] THEN
6450       GEN_TAC THEN REWRITE_TAC[NORM_ARITH `dist(vec 0,x) = norm x`] THEN
6451       DISCH_TAC THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
6452       MATCH_MP_TAC(REAL_ARITH
6453         `abs(x) <= B ==> min a (--B) <= x /\ x <= max b B`) THEN
6454       MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `norm(x:real^N)` THEN
6455       ASM_SIMP_TAC[REAL_LT_IMP_LE; COMPONENT_LE_NORM; REAL_LE_MAX];
6456       ALL_TAC] THEN
6457     MATCH_MP_TAC(NORM_ARITH
6458        `norm(i - j) < e / &4 /\
6459         norm(ah - ag) <= norm(ch - cg)
6460         ==> norm(cg - i) < e / &4 /\
6461             norm(ch - j) < e / &4
6462             ==> norm(ag - ah) < e`) THEN
6463     ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[GSYM INTEGRAL_SUB] THEN
6464     MATCH_MP_TAC lemma THEN CONJ_TAC THENL
6465      [MATCH_MP_TAC(INST_TYPE [`:N`,`:M`] HAS_INTEGRAL_DROP_POS) THEN
6466       MAP_EVERY EXISTS_TAC
6467        [`(\x. (if x IN s then h x else vec 0) - (if x IN s then g x else vec 0))
6468          :real^N->real^1`;
6469         `interval[a:real^N,b]`] THEN
6470       ASM_SIMP_TAC[INTEGRABLE_INTEGRAL; HAS_INTEGRAL_SUB] THEN
6471       ASM_SIMP_TAC[INTEGRABLE_SUB; INTEGRABLE_INTEGRAL] THEN
6472       REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
6473       ASM_SIMP_TAC[DROP_SUB; DROP_VEC; REAL_SUB_LE; REAL_POS] THEN
6474       ASM_MESON_TAC[REAL_LE_TRANS];
6475       ALL_TAC] THEN
6476     MATCH_MP_TAC(INST_TYPE [`:N`,`:M`] HAS_INTEGRAL_SUBSET_DROP_LE) THEN
6477     MAP_EVERY EXISTS_TAC
6478      [`(\x. (if x IN s then h x else vec 0) - (if x IN s then g x else vec 0))
6479        :real^N->real^1`;
6480       `interval[a:real^N,b]`; `interval[c:real^N,d]`] THEN
6481     ASM_SIMP_TAC[INTEGRABLE_SUB; INTEGRABLE_INTEGRAL] THEN CONJ_TAC THENL
6482      [REWRITE_TAC[SUBSET_INTERVAL] THEN DISCH_TAC THEN
6483       MAP_EVERY EXPAND_TAC ["c"; "d"] THEN
6484       SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC;
6485       ALL_TAC] THEN
6486     REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
6487     ASM_SIMP_TAC[DROP_SUB; DROP_VEC; REAL_SUB_LE; REAL_POS] THEN
6488     ASM_MESON_TAC[REAL_LE_TRANS];
6489     ALL_TAC] THEN
6490   ONCE_REWRITE_TAC[INTEGRABLE_ALT] THEN ASM_REWRITE_TAC[] THEN
6491   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
6492   FIRST_X_ASSUM(MP_TAC o SPEC `e / &3`) THEN
6493   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
6494   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM; HAS_INTEGRAL_ALT] THEN
6495   MAP_EVERY X_GEN_TAC
6496    [`g:real^N->real^1`; `h:real^N->real^1`; `i:real^1`; `j:real^1`] THEN
6497   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6498   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
6499   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `e / &3`)) THEN
6500   FIRST_X_ASSUM(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `e / &3`)) THEN
6501   ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
6502   DISCH_THEN(X_CHOOSE_THEN `B1:real`
6503     (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "G"))) THEN
6504   DISCH_THEN(X_CHOOSE_THEN `B2:real`
6505     (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "H"))) THEN
6506   EXISTS_TAC `max B1 B2` THEN
6507   ASM_REWRITE_TAC[REAL_LT_MAX; BALL_MAX_UNION; UNION_SUBSET] THEN
6508   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`; `c:real^N`; `d:real^N`] THEN
6509   STRIP_TAC THEN REWRITE_TAC[ABS_DROP; DROP_SUB] THEN
6510   MATCH_MP_TAC(REAL_ARITH
6511    `!ga gc ha hc i j.
6512         ga <= fa /\ fa <= ha /\
6513         gc <= fc /\ fc <= hc /\
6514         abs(ga - i) < e / &3 /\
6515         abs(gc - i) < e / &3 /\
6516         abs(ha - j) < e / &3 /\
6517         abs(hc - j) < e / &3 /\
6518         abs(i - j) < e / &3
6519         ==> abs(fa - fc) < e`) THEN
6520   MAP_EVERY EXISTS_TAC
6521    [`drop(integral(interval[a:real^N,b]) (\x. if x IN s then g x else vec 0))`;
6522     `drop(integral(interval[c:real^N,d]) (\x. if x IN s then g x else vec 0))`;
6523     `drop(integral(interval[a:real^N,b]) (\x. if x IN s then h x else vec 0))`;
6524     `drop(integral(interval[c:real^N,d]) (\x. if x IN s then h x else vec 0))`;
6525     `drop i`; `drop j`] THEN
6526   REWRITE_TAC[GSYM DROP_SUB; GSYM ABS_DROP] THEN ASM_SIMP_TAC[] THEN
6527   REPEAT CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN
6528   ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
6529   COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_LE_REFL]);;
6530
6531 let HAS_INTEGRAL_STRADDLE_NULL = prove
6532  (`!f g:real^N->real^1 s.
6533         (!x. x IN s ==> &0 <= drop(f x) /\ drop(f x) <= drop(g x)) /\
6534         (g has_integral (vec 0)) s
6535         ==> (f has_integral (vec 0)) s`,
6536   REPEAT STRIP_TAC THEN REWRITE_TAC[HAS_INTEGRAL_INTEGRABLE_INTEGRAL] THEN
6537   MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
6538    [MATCH_MP_TAC INTEGRABLE_STRADDLE THEN
6539     GEN_TAC THEN DISCH_TAC THEN
6540     MAP_EVERY EXISTS_TAC
6541      [`(\x. vec 0):real^N->real^1`; `g:real^N->real^1`;
6542       `vec 0:real^1`; `vec 0:real^1`] THEN
6543     ASM_REWRITE_TAC[DROP_VEC; HAS_INTEGRAL_0; VECTOR_SUB_REFL; NORM_0];
6544     DISCH_TAC THEN ONCE_REWRITE_TAC[GSYM DROP_EQ] THEN
6545     REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
6546      [MATCH_MP_TAC(ISPECL [`f:real^N->real^1`; `g:real^N->real^1`]
6547         HAS_INTEGRAL_DROP_LE);
6548       MATCH_MP_TAC(ISPECL [`(\x. vec 0):real^N->real^1`; `f:real^N->real^1`]
6549         HAS_INTEGRAL_DROP_LE)] THEN
6550     EXISTS_TAC `s:real^N->bool` THEN
6551     ASM_SIMP_TAC[GSYM HAS_INTEGRAL_INTEGRAL; DROP_VEC; HAS_INTEGRAL_0]]);;
6552
6553 (* ------------------------------------------------------------------------- *)
6554 (* Adding integrals over several sets.                                       *)
6555 (* ------------------------------------------------------------------------- *)
6556
6557 let HAS_INTEGRAL_UNION = prove
6558  (`!f:real^M->real^N i j s t.
6559         (f has_integral i) s /\ (f has_integral j) t /\ negligible(s INTER t)
6560         ==> (f has_integral (i + j)) (s UNION t)`,
6561   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
6562   REWRITE_TAC[CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
6563   MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN
6564   EXISTS_TAC `(\x. if x IN (s INTER t) then &2 % f(x)
6565                    else if x IN (s UNION t) then f(x)
6566                    else vec 0):real^M->real^N` THEN
6567   EXISTS_TAC `s INTER t:real^M->bool` THEN
6568   ASM_REWRITE_TAC[IN_DIFF; IN_UNION; IN_INTER; IN_UNIV] THEN
6569   CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
6570   FIRST_X_ASSUM(MP_TAC o MATCH_MP HAS_INTEGRAL_ADD) THEN
6571   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
6572   REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN
6573   MAP_EVERY ASM_CASES_TAC [`(x:real^M) IN s`; `(x:real^M) IN t`] THEN
6574   ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);;
6575
6576 let INTEGRAL_UNION = prove
6577  (`!f:real^M->real^N s t.
6578         f integrable_on s /\ f integrable_on t /\ negligible(s INTER t)
6579         ==> integral (s UNION t) f = integral s f + integral t f`,
6580   REPEAT STRIP_TAC THEN
6581   MATCH_MP_TAC INTEGRAL_UNIQUE THEN
6582   MATCH_MP_TAC HAS_INTEGRAL_UNION THEN
6583   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);;
6584
6585 let HAS_INTEGRAL_UNIONS = prove
6586  (`!f:real^M->real^N i t.
6587         FINITE t /\
6588         (!s. s IN t ==> (f has_integral (i s)) s) /\
6589         (!s s'. s IN t /\ s' IN t /\ ~(s = s') ==> negligible(s INTER s'))
6590         ==> (f has_integral (vsum t i)) (UNIONS t)`,
6591   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
6592   REWRITE_TAC[CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
6593   FIRST_ASSUM(MP_TAC o MATCH_MP HAS_INTEGRAL_VSUM) THEN REWRITE_TAC[] THEN
6594   MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
6595                 HAS_INTEGRAL_SPIKE) THEN
6596   EXISTS_TAC
6597    `UNIONS (IMAGE (\(a,b). a INTER b :real^M->bool)
6598                   {a,b | a IN t /\ b IN {y | y IN t /\ ~(a = y)}})` THEN
6599   CONJ_TAC THENL
6600    [MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN CONJ_TAC THENL
6601      [MATCH_MP_TAC FINITE_IMAGE THEN MATCH_MP_TAC FINITE_PRODUCT_DEPENDENT THEN
6602       ASM_SIMP_TAC[FINITE_RESTRICT];
6603       REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN
6604       ASM_SIMP_TAC[IN_ELIM_THM]];
6605     X_GEN_TAC `x:real^M` THEN REWRITE_TAC[IN_UNIV; IN_DIFF] THEN
6606     ASM_CASES_TAC `(x:real^M) IN UNIONS t` THEN ASM_REWRITE_TAC[] THENL
6607      [ALL_TAC;
6608       RULE_ASSUM_TAC(REWRITE_RULE[SET_RULE
6609        `~(x IN UNIONS t) <=> !s. s IN t ==> ~(x IN s)`]) THEN
6610       ASM_SIMP_TAC[VSUM_0]] THEN
6611     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_UNIONS]) THEN
6612     DISCH_THEN(X_CHOOSE_THEN `a:real^M->bool` STRIP_ASSUME_TAC) THEN
6613     REWRITE_TAC[IN_UNIONS; EXISTS_IN_IMAGE; EXISTS_PAIR_THM] THEN
6614     REWRITE_TAC[IN_ELIM_PAIR_THM; NOT_EXISTS_THM] THEN
6615     DISCH_THEN(MP_TAC o SPEC `a:real^M->bool`) THEN
6616     ASM_REWRITE_TAC[IN_ELIM_THM; IN_INTER] THEN
6617     ASM_SIMP_TAC[MESON[]
6618      `x IN a /\ a IN t
6619       ==> ((!b. ~((b IN t /\ ~(a = b)) /\ x IN b)) <=>
6620            (!b. b IN t ==> (x IN b <=> b = a)))`] THEN
6621     ASM_REWRITE_TAC[VSUM_DELTA]]);;
6622
6623 let HAS_INTEGRAL_DIFF = prove
6624  (`!f:real^M->real^N i j s t.
6625     (f has_integral i) s /\
6626     (f has_integral j) t /\
6627     negligible (t DIFF s)
6628     ==> (f has_integral (i - j)) (s DIFF t)`,
6629   REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[GSYM HAS_INTEGRAL_RESTRICT_UNIV] THEN
6630   REWRITE_TAC[CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN ASSUME_TAC) THEN
6631   MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN
6632   EXISTS_TAC `(\x. if x IN (t DIFF s) then --(f x)
6633                    else if x IN (s DIFF t) then f x
6634                    else vec 0):real^M->real^N` THEN
6635   EXISTS_TAC `t DIFF s:real^M->bool` THEN
6636   ASM_REWRITE_TAC[IN_DIFF; IN_UNION; IN_INTER; IN_UNIV] THEN
6637   CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
6638   FIRST_X_ASSUM(MP_TAC o MATCH_MP HAS_INTEGRAL_SUB) THEN
6639   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
6640   REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN
6641   MAP_EVERY ASM_CASES_TAC [`(x:real^M) IN s`; `(x:real^M) IN t`] THEN
6642   ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC);;
6643
6644 let INTEGRAL_DIFF = prove
6645  (`!f:real^M->real^N s t.
6646         f integrable_on s /\ f integrable_on t /\ negligible(t DIFF s)
6647         ==> integral (s DIFF t) f = integral s f - integral t f`,
6648   REPEAT STRIP_TAC THEN
6649   MATCH_MP_TAC INTEGRAL_UNIQUE THEN
6650   MATCH_MP_TAC HAS_INTEGRAL_DIFF THEN
6651   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);;
6652
6653 (* ------------------------------------------------------------------------- *)
6654 (* In particular adding integrals over a division, maybe not of an interval. *)
6655 (* ------------------------------------------------------------------------- *)
6656
6657 let HAS_INTEGRAL_COMBINE_DIVISION = prove
6658  (`!f:real^M->real^N s d i.
6659         d division_of s /\
6660         (!k. k IN d ==> (f has_integral (i k)) k)
6661         ==> (f has_integral (vsum d i)) s`,
6662   REPEAT STRIP_TAC THEN
6663   FIRST_ASSUM(SUBST1_TAC o SYM o last o CONJUNCTS o
6664               GEN_REWRITE_RULE I [division_of]) THEN
6665   MATCH_MP_TAC HAS_INTEGRAL_UNIONS THEN ASM_REWRITE_TAC[] THEN
6666   CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_FINITE]; ALL_TAC] THEN
6667   MAP_EVERY X_GEN_TAC [`k1:real^M->bool`; `k2:real^M->bool`] THEN
6668   STRIP_TAC THEN
6669   SUBGOAL_THEN `?u v:real^M x y:real^M.
6670                 k1 = interval[u,v] /\ k2 = interval[x,y]`
6671    (REPEAT_TCL CHOOSE_THEN (CONJUNCTS_THEN SUBST_ALL_TAC))
6672   THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
6673   FIRST_ASSUM(MP_TAC o el 2 o CONJUNCTS o
6674               GEN_REWRITE_RULE I [division_of]) THEN
6675   DISCH_THEN(MP_TAC o SPECL
6676    [`interval[u:real^M,v]`; `interval[x:real^M,y]`]) THEN
6677   ASM_REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN DISCH_TAC THEN
6678   MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN
6679   EXISTS_TAC `(interval[u,v:real^M] DIFF interval(u,v)) UNION
6680               (interval[x,y] DIFF interval(x,y))` THEN
6681   SIMP_TAC[NEGLIGIBLE_FRONTIER_INTERVAL; NEGLIGIBLE_UNION] THEN
6682   ASM SET_TAC[]);;
6683
6684 let INTEGRAL_COMBINE_DIVISION_BOTTOMUP = prove
6685  (`!f:real^M->real^N d s.
6686         d division_of s /\ (!k. k IN d ==> f integrable_on k)
6687         ==> integral s f = vsum d (\i. integral i f)`,
6688   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
6689   MATCH_MP_TAC HAS_INTEGRAL_COMBINE_DIVISION THEN
6690   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);;
6691
6692 let HAS_INTEGRAL_COMBINE_DIVISION_TOPDOWN = prove
6693  (`!f:real^M->real^N s d k.
6694         f integrable_on s /\ d division_of k /\ k SUBSET s
6695         ==> (f has_integral (vsum d (\i. integral i f))) k`,
6696   REPEAT STRIP_TAC THEN
6697   MATCH_MP_TAC HAS_INTEGRAL_COMBINE_DIVISION THEN
6698   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL] THEN
6699   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
6700   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
6701   EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN
6702   ASM_MESON_TAC[division_of; SUBSET_TRANS]);;
6703
6704 let INTEGRAL_COMBINE_DIVISION_TOPDOWN = prove
6705  (`!f:real^M->real^N d s.
6706         f integrable_on s /\ d division_of s
6707         ==> integral s f = vsum d (\i. integral i f)`,
6708   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
6709   MATCH_MP_TAC HAS_INTEGRAL_COMBINE_DIVISION_TOPDOWN THEN
6710   EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[SUBSET_REFL]);;
6711
6712 let INTEGRABLE_COMBINE_DIVISION = prove
6713  (`!f d s.
6714         d division_of s /\ (!i. i IN d ==> f integrable_on i)
6715         ==> f integrable_on s`,
6716   REWRITE_TAC[integrable_on] THEN MESON_TAC[HAS_INTEGRAL_COMBINE_DIVISION]);;
6717
6718 let INTEGRABLE_ON_SUBDIVISION = prove
6719  (`!f:real^M->real^N s d i.
6720         d division_of i /\
6721         f integrable_on s /\ i SUBSET s
6722         ==> f integrable_on i`,
6723   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_COMBINE_DIVISION THEN
6724   EXISTS_TAC `d:(real^M->bool)->bool` THEN ASM_REWRITE_TAC[] THEN
6725   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
6726   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
6727   ASM_MESON_TAC[division_of; UNIONS_SUBSET]);;
6728
6729 (* ------------------------------------------------------------------------- *)
6730 (* Also tagged divisions.                                                    *)
6731 (* ------------------------------------------------------------------------- *)
6732
6733 let HAS_INTEGRAL_COMBINE_TAGGED_DIVISION = prove
6734  (`!f:real^M->real^N s p i.
6735         p tagged_division_of s /\
6736         (!x k. (x,k) IN p ==> (f has_integral (i k)) k)
6737         ==> (f has_integral (vsum p (\(x,k). i k))) s`,
6738   REPEAT STRIP_TAC THEN
6739   SUBGOAL_THEN
6740    `!x:real^M k:real^M->bool.
6741       (x,k) IN p ==> ((f:real^M->real^N) has_integral integral k f) k`
6742   ASSUME_TAC THENL
6743    [ASM_MESON_TAC[HAS_INTEGRAL_INTEGRAL; integrable_on]; ALL_TAC] THEN
6744   SUBGOAL_THEN
6745    `((f:real^M->real^N) has_integral
6746      (vsum (IMAGE SND (p:real^M#(real^M->bool)->bool))
6747            (\k. integral k f))) s`
6748   MP_TAC THENL
6749    [MATCH_MP_TAC HAS_INTEGRAL_COMBINE_DIVISION THEN
6750     ASM_REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN
6751     ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION];
6752     ALL_TAC] THEN
6753   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN
6754   AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN
6755   MATCH_MP_TAC EQ_TRANS THEN
6756   EXISTS_TAC `vsum p (\(x:real^M,k:real^M->bool). integral k f:real^N)` THEN
6757   CONJ_TAC THENL
6758    [MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
6759     ASM_MESON_TAC[HAS_INTEGRAL_UNIQUE];
6760     MATCH_MP_TAC VSUM_OVER_TAGGED_DIVISION_LEMMA THEN
6761     EXISTS_TAC `s:real^M->bool` THEN ASM_SIMP_TAC[INTEGRAL_NULL]]);;
6762
6763 let INTEGRAL_COMBINE_TAGGED_DIVISION_BOTTOMUP = prove
6764  (`!f:real^M->real^N p a b.
6765         p tagged_division_of interval[a,b] /\
6766         (!x k. (x,k) IN p ==> f integrable_on k)
6767         ==> integral (interval[a,b]) f = vsum p (\(x,k). integral k f)`,
6768   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
6769   MATCH_MP_TAC HAS_INTEGRAL_COMBINE_TAGGED_DIVISION THEN
6770   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]);;
6771
6772 let HAS_INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN = prove
6773  (`!f:real^M->real^N a b p.
6774         f integrable_on interval[a,b] /\ p tagged_division_of interval[a,b]
6775         ==> (f has_integral (vsum p (\(x,k). integral k f))) (interval[a,b])`,
6776   REPEAT STRIP_TAC THEN
6777   MATCH_MP_TAC HAS_INTEGRAL_COMBINE_TAGGED_DIVISION THEN
6778   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL] THEN
6779   ASM_MESON_TAC[INTEGRABLE_SUBINTERVAL; TAGGED_DIVISION_OF]);;
6780
6781 let INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN = prove
6782  (`!f:real^M->real^N a b p.
6783         f integrable_on interval[a,b] /\ p tagged_division_of interval[a,b]
6784         ==> integral (interval[a,b]) f = vsum p (\(x,k). integral k f)`,
6785   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
6786   MATCH_MP_TAC HAS_INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN THEN
6787   ASM_REWRITE_TAC[]);;
6788
6789 (* ------------------------------------------------------------------------- *)
6790 (* Henstock's lemma.                                                         *)
6791 (* ------------------------------------------------------------------------- *)
6792
6793 let HENSTOCK_LEMMA_PART1 = prove
6794  (`!f:real^M->real^N a b d e.
6795         f integrable_on interval[a,b] /\
6796         &0 < e /\ gauge d /\
6797         (!p. p tagged_division_of interval[a,b] /\ d fine p
6798              ==> norm (vsum p (\(x,k). content k % f x) -
6799                        integral(interval[a,b]) f) < e)
6800         ==> !p. p tagged_partial_division_of interval[a,b] /\ d fine p
6801                             ==> norm(vsum p (\(x,k). content k % f x -
6802                                                      integral k f)) <= e`,
6803   let lemma = prove
6804    (`(!k. &0 < k ==> x <= e + k) ==> x <= e`,
6805     DISCH_THEN(MP_TAC o SPEC `(x - e) / &2`) THEN REAL_ARITH_TAC) in
6806   REPEAT GEN_TAC THEN STRIP_TAC THEN GEN_TAC THEN STRIP_TAC THEN
6807   MATCH_MP_TAC lemma THEN X_GEN_TAC `k:real` THEN DISCH_TAC THEN
6808   MP_TAC(ISPECL
6809     [`IMAGE SND (p:(real^M#(real^M->bool))->bool)`; `a:real^M`; `b:real^M`]
6810     PARTIAL_DIVISION_EXTEND_INTERVAL) THEN
6811   ANTS_TAC THENL
6812    [CONJ_TAC THENL
6813      [ASM_MESON_TAC[PARTIAL_DIVISION_OF_TAGGED_DIVISION]; ALL_TAC] THEN
6814     REWRITE_TAC[SUBSET; FORALL_IN_UNIONS] THEN
6815     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
6816     REWRITE_TAC[FORALL_PAIR_THM] THEN
6817     ASM_MESON_TAC[tagged_partial_division_of; SUBSET];
6818     ALL_TAC] THEN
6819   SUBGOAL_THEN `FINITE(p:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
6820    [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
6821   DISCH_THEN(X_CHOOSE_THEN `q:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN
6822   FIRST_X_ASSUM(MP_TAC o MATCH_MP(SET_RULE
6823    `s SUBSET t ==> t = s UNION (t DIFF s)`)) THEN
6824   ABBREV_TAC `r = q DIFF IMAGE SND (p:(real^M#(real^M->bool))->bool)` THEN
6825   SUBGOAL_THEN `IMAGE SND (p:(real^M#(real^M->bool))->bool) INTER r = {}`
6826   ASSUME_TAC THENL [EXPAND_TAC "r" THEN SET_TAC[]; ALL_TAC] THEN
6827   DISCH_THEN SUBST_ALL_TAC THEN
6828   SUBGOAL_THEN `FINITE(r:(real^M->bool)->bool)` ASSUME_TAC THENL
6829    [ASM_MESON_TAC[division_of; FINITE_UNION]; ALL_TAC] THEN
6830   SUBGOAL_THEN
6831    `!i. i IN r
6832         ==> ?p. p tagged_division_of i /\ d fine p /\
6833                 norm(vsum p (\(x,j). content j % f x) -
6834                      integral i (f:real^M->real^N))
6835                 < k / (&(CARD(r:(real^M->bool)->bool)) + &1)`
6836   MP_TAC THENL
6837    [X_GEN_TAC `i:real^M->bool` THEN DISCH_TAC THEN
6838     SUBGOAL_THEN `(i:real^M->bool) SUBSET interval[a,b]` ASSUME_TAC THENL
6839      [ASM_MESON_TAC[division_of; IN_UNION]; ALL_TAC] THEN
6840     SUBGOAL_THEN `?u v:real^M. i = interval[u,v]`
6841      (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
6842     THENL [ASM_MESON_TAC[division_of; IN_UNION]; ALL_TAC] THEN
6843     SUBGOAL_THEN `(f:real^M->real^N) integrable_on interval[u,v]` MP_TAC THENL
6844      [ASM_MESON_TAC[INTEGRABLE_SUBINTERVAL]; ALL_TAC] THEN
6845     DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
6846     REWRITE_TAC[has_integral] THEN
6847     DISCH_THEN(MP_TAC o SPEC `k / (&(CARD(r:(real^M->bool)->bool)) + &1)`) THEN
6848     ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &n + &1`] THEN
6849     DISCH_THEN(X_CHOOSE_THEN `dd:real^M->real^M->bool` MP_TAC) THEN
6850     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
6851     MP_TAC(ISPECL [`d:real^M->real^M->bool`; `dd:real^M->real^M->bool`]
6852       GAUGE_INTER) THEN
6853     ASM_REWRITE_TAC[] THEN
6854     DISCH_THEN(MP_TAC o MATCH_MP FINE_DIVISION_EXISTS) THEN
6855     DISCH_THEN(MP_TAC o SPECL [`u:real^M`; `v:real^M`]) THEN
6856     REWRITE_TAC[FINE_INTER] THEN MESON_TAC[];
6857     ALL_TAC] THEN
6858   REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
6859   REWRITE_TAC[TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN
6860   REWRITE_TAC[FORALL_AND_THM] THEN
6861   DISCH_THEN(X_CHOOSE_THEN `q:(real^M->bool)->(real^M#(real^M->bool))->bool`
6862     STRIP_ASSUME_TAC) THEN
6863   FIRST_X_ASSUM(MP_TAC o SPEC
6864     `p UNION UNIONS {q (i:real^M->bool) | i IN r}
6865      :(real^M#(real^M->bool))->bool`) THEN
6866   ANTS_TAC THENL
6867    [CONJ_TAC THENL
6868      [ALL_TAC;
6869       MATCH_MP_TAC FINE_UNION THEN ASM_REWRITE_TAC[] THEN
6870       MATCH_MP_TAC FINE_UNIONS THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
6871       ASM_REWRITE_TAC[FORALL_IN_IMAGE]] THEN
6872     FIRST_ASSUM(SUBST1_TAC o SYM o last o CONJUNCTS o
6873                 GEN_REWRITE_RULE I [division_of]) THEN
6874     REWRITE_TAC[UNIONS_UNION] THEN
6875     MATCH_MP_TAC TAGGED_DIVISION_UNION THEN CONJ_TAC THENL
6876      [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF]; ALL_TAC] THEN
6877     CONJ_TAC THENL
6878      [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
6879       MATCH_MP_TAC TAGGED_DIVISION_UNIONS THEN
6880       FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
6881       SIMP_TAC[FINITE_UNION; IN_UNION] THEN ASM_MESON_TAC[];
6882       ALL_TAC] THEN
6883     MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
6884     REWRITE_TAC[OPEN_INTERIOR] THEN
6885     REPEAT(CONJ_TAC THENL
6886             [ASM_MESON_TAC[division_of; FINITE_UNION; IN_UNION]; ALL_TAC]) THEN
6887     X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
6888     ONCE_REWRITE_TAC[INTER_COMM] THEN
6889     MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
6890     REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM; OPEN_INTERIOR] THEN
6891     REPEAT(CONJ_TAC THENL
6892      [ASM_MESON_TAC[tagged_partial_division_of; FINITE_IMAGE]; ALL_TAC]) THEN
6893     REPEAT STRIP_TAC THEN
6894     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
6895     DISCH_THEN(MATCH_MP_TAC o el 2 o CONJUNCTS) THEN
6896     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
6897     REWRITE_TAC[NOT_IN_EMPTY; GSYM NOT_EXISTS_THM] THEN
6898     ASM_REWRITE_TAC[EXISTS_PAIR_THM; IN_IMAGE; IN_INTER; IN_UNION] THEN
6899     ASM_MESON_TAC[];
6900     ALL_TAC] THEN
6901   SUBGOAL_THEN
6902    `vsum (p UNION UNIONS {q i | i IN r}) (\(x,k). content k % f x) =
6903     vsum p (\(x:real^M,k:real^M->bool). content k % f x:real^N) +
6904     vsum (UNIONS {q i | (i:real^M->bool) IN r}) (\(x,k). content k % f x)`
6905   SUBST1_TAC THENL
6906    [MATCH_MP_TAC VSUM_UNION_NONZERO THEN ASM_REWRITE_TAC[] THEN
6907     ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
6908     ASM_SIMP_TAC[FINITE_UNIONS; FINITE_IMAGE; FORALL_IN_IMAGE] THEN
6909     CONJ_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF_FINITE]; ALL_TAC] THEN
6910     REWRITE_TAC[IN_INTER] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
6911     REWRITE_TAC[IMP_CONJ; FORALL_IN_UNIONS; FORALL_IN_IMAGE] THEN
6912     REWRITE_TAC[FORALL_PAIR_THM; FORALL_IN_IMAGE; RIGHT_FORALL_IMP_THM] THEN
6913     X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
6914     MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
6915     DISCH_TAC THEN
6916     SUBGOAL_THEN `(l:real^M->bool) SUBSET k` ASSUME_TAC THENL
6917      [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN DISCH_TAC THEN
6918     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
6919     DISCH_THEN(MP_TAC o SPECL [`k:real^M->bool`; `l:real^M->bool`] o
6920                el 2 o CONJUNCTS) THEN
6921     ANTS_TAC THENL
6922      [ASM_REWRITE_TAC[IN_UNION; IN_IMAGE; EXISTS_PAIR_THM] THEN
6923       CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
6924       DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
6925       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
6926       REWRITE_TAC[NOT_IN_EMPTY; GSYM NOT_EXISTS_THM] THEN
6927       ASM_REWRITE_TAC[EXISTS_PAIR_THM; IN_IMAGE; IN_INTER; IN_UNION] THEN
6928       ASM_MESON_TAC[];
6929       ALL_TAC] THEN
6930     ASM_SIMP_TAC[SUBSET_INTERIOR; SET_RULE `s SUBSET t ==> t INTER s = s`] THEN
6931     SUBGOAL_THEN `?u v:real^M. l = interval[u,v]`
6932      (fun th -> REPEAT_TCL CHOOSE_THEN SUBST1_TAC th THEN
6933                 SIMP_TAC[VECTOR_MUL_LZERO; GSYM CONTENT_EQ_0_INTERIOR]) THEN
6934     ASM_MESON_TAC[tagged_partial_division_of];
6935     ALL_TAC] THEN
6936   W(MP_TAC o PART_MATCH (lhand o rand) VSUM_UNIONS_NONZERO o
6937     rand o lhand o rand o lhand o lhand o snd) THEN
6938   ANTS_TAC THENL
6939    [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN
6940     REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; RIGHT_FORALL_IMP_THM] THEN
6941     CONJ_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF; IN_UNION]; ALL_TAC] THEN
6942     X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
6943     X_GEN_TAC `l:real^M->bool` THEN DISCH_TAC THEN
6944     DISCH_TAC THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
6945     MAP_EVERY X_GEN_TAC [`x:real^M`; `m:real^M->bool`] THEN
6946     DISCH_TAC THEN DISCH_TAC THEN
6947     REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN
6948     SUBGOAL_THEN `?u v:real^M. m = interval[u,v]`
6949      (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
6950     THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF; IN_UNION]; ALL_TAC] THEN
6951     REWRITE_TAC[CONTENT_EQ_0_INTERIOR] THEN
6952     MATCH_MP_TAC(SET_RULE `!t. s SUBSET t /\ t = {} ==> s = {}`) THEN
6953     EXISTS_TAC `interior(k INTER l:real^M->bool)` THEN CONJ_TAC THENL
6954      [MATCH_MP_TAC SUBSET_INTERIOR THEN REWRITE_TAC[SUBSET_INTER] THEN
6955       ASM_MESON_TAC[TAGGED_DIVISION_OF];
6956       ALL_TAC] THEN
6957     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
6958     REWRITE_TAC[INTERIOR_INTER] THEN
6959     DISCH_THEN(MATCH_MP_TAC o SPECL [`k:real^M->bool`; `l:real^M->bool`] o
6960                el 2 o CONJUNCTS) THEN
6961     REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM; IN_UNION] THEN ASM_MESON_TAC[];
6962     ALL_TAC] THEN
6963   DISCH_THEN SUBST1_TAC THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
6964   W(MP_TAC o PART_MATCH (lhand o rand) VSUM_IMAGE_NONZERO o
6965     rand o lhand o rand o lhand o lhand o snd) THEN
6966   ASM_REWRITE_TAC[o_DEF] THEN ANTS_TAC THENL
6967    [MAP_EVERY X_GEN_TAC [`k:real^M->bool`; `l:real^M->bool`] THEN
6968     STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ_0 THEN
6969     REWRITE_TAC[FORALL_PAIR_THM] THEN
6970     MAP_EVERY X_GEN_TAC [`x:real^M`; `m:real^M->bool`] THEN DISCH_TAC THEN
6971     MP_TAC(ASSUME `!i:real^M->bool. i IN r ==> q i tagged_division_of i`) THEN
6972     DISCH_THEN(fun th -> MP_TAC(SPEC `l:real^M->bool` th) THEN
6973                          ANTS_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN
6974                          MP_TAC(SPEC `k:real^M->bool` th) THEN
6975                          ANTS_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC]) THEN
6976     ASM_REWRITE_TAC[tagged_division_of] THEN ASM_MESON_TAC[];
6977     ALL_TAC] THEN
6978   DISCH_THEN SUBST1_TAC THEN
6979   SUBGOAL_THEN
6980    `vsum p (\(x,k). content k % (f:real^M->real^N) x - integral k f) =
6981     vsum p (\(x,k). content k % f x) - vsum p (\(x,k). integral k f)`
6982   SUBST1_TAC THENL [ASM_SIMP_TAC[GSYM VSUM_SUB; LAMBDA_PAIR_THM]; ALL_TAC] THEN
6983   MATCH_MP_TAC(NORM_ARITH
6984    `!ir. ip + ir = i /\
6985          norm(cr - ir) < k
6986          ==> norm((cp + cr) - i) < e ==> norm(cp - ip) <= e + k`) THEN
6987   EXISTS_TAC `vsum r (\k. integral k (f:real^M->real^N))` THEN CONJ_TAC THENL
6988    [MATCH_MP_TAC EQ_TRANS THEN
6989     EXISTS_TAC `vsum (IMAGE SND (p:(real^M#(real^M->bool))->bool) UNION r)
6990                      (\k. integral k (f:real^M->real^N))` THEN
6991     CONJ_TAC THENL
6992      [ALL_TAC; ASM_MESON_TAC[INTEGRAL_COMBINE_DIVISION_TOPDOWN]] THEN
6993     MATCH_MP_TAC EQ_TRANS THEN
6994     EXISTS_TAC `vsum (IMAGE SND (p:(real^M#(real^M->bool))->bool))
6995                      (\k. integral k (f:real^M->real^N)) +
6996                 vsum r (\k. integral k f)` THEN
6997     CONJ_TAC THENL
6998      [ALL_TAC;
6999       CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_UNION_NONZERO THEN
7000       ASM_SIMP_TAC[FINITE_IMAGE; NOT_IN_EMPTY]] THEN
7001     AP_THM_TAC THEN AP_TERM_TAC THEN
7002     SUBGOAL_THEN `(\(x:real^M,k). integral k (f:real^M->real^N)) =
7003                   (\k. integral k f) o SND`
7004     SUBST1_TAC THENL
7005      [SIMP_TAC[o_THM; FUN_EQ_THM; FORALL_PAIR_THM]; ALL_TAC] THEN
7006     CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_IMAGE_NONZERO THEN
7007     ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
7008     MAP_EVERY X_GEN_TAC
7009      [`x:real^M`; `l:real^M->bool`; `y:real^M`; `m:real^M->bool`] THEN
7010     REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
7011     DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
7012     FIRST_X_ASSUM(MP_TAC o
7013       GEN_REWRITE_RULE I [tagged_partial_division_of]) THEN
7014     DISCH_THEN(CONJUNCTS_THEN MP_TAC o CONJUNCT2) THEN
7015     DISCH_THEN(MP_TAC o SPECL
7016      [`x:real^M`; `l:real^M->bool`; `y:real^M`; `l:real^M->bool`]) THEN
7017     ASM_REWRITE_TAC[INTER_IDEMPOT] THEN DISCH_TAC THEN
7018     DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `l:real^M->bool`]) THEN
7019     ASM_REWRITE_TAC[] THEN
7020     DISCH_THEN(REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC o last o CONJUNCTS) THEN
7021     MATCH_MP_TAC INTEGRAL_UNIQUE THEN MATCH_MP_TAC HAS_INTEGRAL_NULL THEN
7022     ASM_REWRITE_TAC[CONTENT_EQ_0_INTERIOR];
7023     ALL_TAC] THEN
7024   ASM_SIMP_TAC[GSYM VSUM_SUB] THEN MATCH_MP_TAC REAL_LET_TRANS THEN
7025   EXISTS_TAC `sum (r:(real^M->bool)->bool) (\x. k / (&(CARD r) + &1))` THEN
7026   CONJ_TAC THENL
7027    [MATCH_MP_TAC VSUM_NORM_LE THEN ASM_SIMP_TAC[REAL_LT_IMP_LE];
7028     ASM_SIMP_TAC[SUM_CONST] THEN
7029     REWRITE_TAC[real_div; REAL_MUL_ASSOC] THEN
7030     SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &x + &1`] THEN
7031     REWRITE_TAC[REAL_ARITH `a * k < k * b <=> &0 < k * (b - a)`] THEN
7032     MATCH_MP_TAC REAL_LT_MUL THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC]);;
7033
7034 let HENSTOCK_LEMMA_PART2 = prove
7035  (`!f:real^M->real^N a b d e.
7036         f integrable_on interval[a,b] /\
7037         &0 < e /\ gauge d /\
7038         (!p. p tagged_division_of interval[a,b] /\ d fine p
7039              ==> norm (vsum p (\(x,k). content k % f x) -
7040                        integral(interval[a,b]) f) < e)
7041         ==> !p. p tagged_partial_division_of interval[a,b] /\ d fine p
7042                             ==> sum p (\(x,k). norm(content k % f x -
7043                                                     integral k f))
7044                                 <= &2 * &(dimindex(:N)) * e`,
7045   REPEAT STRIP_TAC THEN REWRITE_TAC[LAMBDA_PAIR] THEN
7046   MATCH_MP_TAC VSUM_NORM_ALLSUBSETS_BOUND THEN
7047   REWRITE_TAC[LAMBDA_PAIR_THM] THEN
7048   CONJ_TAC THENL [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
7049   X_GEN_TAC `q:(real^M#(real^M->bool))->bool` THEN DISCH_TAC THEN
7050   MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
7051     HENSTOCK_LEMMA_PART1) THEN
7052   MAP_EVERY EXISTS_TAC
7053    [`a:real^M`; `b:real^M`; `d:real^M->real^M->bool`] THEN
7054   ASM_REWRITE_TAC[] THEN
7055   ASM_MESON_TAC[FINE_SUBSET; TAGGED_PARTIAL_DIVISION_SUBSET]);;
7056
7057 let HENSTOCK_LEMMA = prove
7058  (`!f:real^M->real^N a b.
7059         f integrable_on interval[a,b]
7060         ==> !e. &0 < e
7061                 ==> ?d. gauge d /\
7062                         !p. p tagged_partial_division_of interval[a,b] /\
7063                             d fine p
7064                             ==> sum p (\(x,k). norm(content k % f x -
7065                                                     integral k f)) < e`,
7066   MP_TAC HENSTOCK_LEMMA_PART2 THEN
7067   REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
7068   DISCH_THEN(fun th -> STRIP_TAC THEN X_GEN_TAC `e:real` THEN
7069                        STRIP_TAC THEN MP_TAC th) THEN
7070   FIRST_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
7071   GEN_REWRITE_TAC LAND_CONV [has_integral] THEN
7072   DISCH_THEN(MP_TAC o SPEC `e / (&2 * (&(dimindex(:N)) + &1))`) THEN
7073   ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &2 * (&n + &1)`] THEN
7074   DISCH_THEN(X_CHOOSE_THEN `d:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
7075   DISCH_THEN(MP_TAC o SPECL
7076    [`d:real^M->real^M->bool`; `e / (&2 * (&(dimindex(:N)) + &1))`]) THEN
7077   ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &2 * (&n + &1)`] THEN
7078   DISCH_THEN(fun th -> EXISTS_TAC `d:real^M->real^M->bool` THEN MP_TAC th) THEN
7079   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
7080   MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
7081   MATCH_MP_TAC(REAL_ARITH `d < e ==> x <= d ==> x < e`) THEN
7082   REWRITE_TAC[real_div; REAL_INV_MUL; REAL_INV_INV; REAL_MUL_ASSOC] THEN
7083   SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
7084   UNDISCH_TAC `&0 < e` THEN REAL_ARITH_TAC);;
7085
7086 (* ------------------------------------------------------------------------- *)
7087 (* Monotone convergence (bounded interval first).                            *)
7088 (* ------------------------------------------------------------------------- *)
7089
7090 let MONOTONE_CONVERGENCE_INTERVAL = prove
7091  (`!f:num->real^N->real^1 g a b.
7092         (!k. (f k) integrable_on interval[a,b]) /\
7093         (!k x. x IN interval[a,b] ==> drop(f k x) <= drop(f (SUC k) x)) /\
7094         (!x. x IN interval[a,b] ==> ((\k. f k x) --> g x) sequentially) /\
7095         bounded {integral (interval[a,b]) (f k) | k IN (:num)}
7096         ==> g integrable_on interval[a,b] /\
7097             ((\k. integral (interval[a,b]) (f k))
7098              --> integral (interval[a,b]) g) sequentially`,
7099   let lemma = prove
7100    (`{(x,y) | P x y} = {p | P (FST p) (SND p)}`,
7101     REWRITE_TAC[EXTENSION; FORALL_PAIR_THM; IN_ELIM_PAIR_THM; IN_ELIM_THM]) in
7102   REPEAT GEN_TAC THEN STRIP_TAC THEN
7103   ASM_CASES_TAC `content(interval[a:real^N,b]) = &0` THENL
7104    [ASM_SIMP_TAC[INTEGRAL_NULL; INTEGRABLE_ON_NULL; LIM_CONST];
7105     RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONTENT_LT_NZ])] THEN
7106   SUBGOAL_THEN
7107    `!x:real^N k:num. x IN interval[a,b] ==> drop(f k x) <= drop(g x)`
7108   ASSUME_TAC THENL
7109    [REPEAT STRIP_TAC THEN
7110     MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LBOUND) THEN
7111     EXISTS_TAC `\k. (f:num->real^N->real^1) k x` THEN
7112     ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
7113     EXISTS_TAC `k:num` THEN SPEC_TAC(`k:num`,`k:num`) THEN
7114     MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN REWRITE_TAC[REAL_LE_TRANS] THEN
7115     ASM_SIMP_TAC[REAL_LE_REFL];
7116     ALL_TAC] THEN
7117   SUBGOAL_THEN
7118    `?i. ((\k. integral (interval[a,b]) (f k:real^N->real^1)) --> i)
7119         sequentially`
7120   CHOOSE_TAC THENL
7121    [MATCH_MP_TAC BOUNDED_INCREASING_CONVERGENT THEN ASM_REWRITE_TAC[] THEN
7122     GEN_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_REWRITE_TAC[];
7123     ALL_TAC] THEN
7124   SUBGOAL_THEN
7125    `!k. drop(integral(interval[a,b]) ((f:num->real^N->real^1) k)) <= drop i`
7126   ASSUME_TAC THENL
7127     [GEN_TAC THEN MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LBOUND) THEN
7128      EXISTS_TAC `\k. integral(interval[a,b]) ((f:num->real^N->real^1) k)` THEN
7129      ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
7130      EXISTS_TAC `k:num` THEN SPEC_TAC(`k:num`,`k:num`) THEN
7131      MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
7132      ASM_REWRITE_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN
7133      GEN_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_REWRITE_TAC[];
7134      ALL_TAC] THEN
7135   SUBGOAL_THEN
7136    `((g:real^N->real^1) has_integral i) (interval[a,b])`
7137   ASSUME_TAC THENL
7138    [REWRITE_TAC[has_integral] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
7139     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV
7140      [HAS_INTEGRAL_INTEGRAL]) THEN
7141     REWRITE_TAC[has_integral] THEN
7142     DISCH_THEN(MP_TAC o GEN `k:num` o
7143       SPECL [`k:num`; `e / &2 pow (k + 2)`]) THEN
7144     ASM_SIMP_TAC[REAL_LT_DIV; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN
7145     GEN_REWRITE_TAC LAND_CONV [SKOLEM_THM] THEN
7146     REWRITE_TAC[LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN
7147     X_GEN_TAC `b:num->real^N->real^N->bool` THEN STRIP_TAC THEN
7148     SUBGOAL_THEN
7149      `?r. !k. r:num <= k
7150                ==> &0 <= drop i - drop(integral(interval[a:real^N,b]) (f k)) /\
7151                    drop i - drop(integral(interval[a,b]) (f k)) < e / &4`
7152     STRIP_ASSUME_TAC THENL
7153      [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
7154       DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
7155       ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
7156       MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
7157       MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
7158       MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[ABS_DROP; dist; DROP_SUB] THEN
7159       MATCH_MP_TAC(REAL_ARITH
7160        `x <= y ==> abs(x - y) < e ==> &0 <= y - x /\ y - x < e`) THEN
7161       ASM_REWRITE_TAC[];
7162       ALL_TAC] THEN
7163     SUBGOAL_THEN
7164      `!x. x IN interval[a:real^N,b]
7165           ==> ?n. r:num <= n /\
7166                   !k. n <= k ==> &0 <= drop(g x) - drop(f k x) /\
7167                                  drop(g x) - drop(f k x) <
7168                                    e / (&4 * content(interval[a,b]))`
7169     MP_TAC THENL
7170      [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7171       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (BINDER_CONV o RAND_CONV)
7172         [LIM_SEQUENTIALLY]) THEN
7173       DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_SIMP_TAC[REAL_SUB_LE] THEN
7174       DISCH_THEN(MP_TAC o SPEC `e / (&4 * content(interval[a:real^N,b]))`) THEN
7175       ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN
7176       REWRITE_TAC[dist; ABS_DROP; DROP_SUB] THEN
7177       ASM_SIMP_TAC[REAL_ARITH `f <= g ==> abs(f - g) = g - f`] THEN
7178       DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
7179       EXISTS_TAC `N + r:num` THEN CONJ_TAC THENL [ARITH_TAC; ALL_TAC] THEN
7180       ASM_MESON_TAC[ARITH_RULE `N + r:num <= k ==> N <= k`];
7181       ALL_TAC] THEN
7182     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
7183     REWRITE_TAC[SKOLEM_THM] THEN
7184     REWRITE_TAC[FORALL_AND_THM; TAUT
7185      `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN
7186     REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN
7187     DISCH_THEN(X_CHOOSE_THEN `m:real^N->num` STRIP_ASSUME_TAC) THEN
7188     ABBREV_TAC `d:real^N->real^N->bool = \x. b(m x:num) x` THEN
7189     EXISTS_TAC `d:real^N->real^N->bool` THEN CONJ_TAC THENL
7190      [EXPAND_TAC "d" THEN REWRITE_TAC[gauge] THEN
7191       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV [gauge]) THEN
7192       SIMP_TAC[];
7193       ALL_TAC] THEN
7194     X_GEN_TAC `p:(real^N#(real^N->bool))->bool` THEN STRIP_TAC THEN
7195     MATCH_MP_TAC(NORM_ARITH
7196      `!b c. norm(a - b) <= e / &4 /\
7197             norm(b - c) < e / &2 /\
7198             norm(c - d) < e / &4
7199             ==> norm(a - d) < e`) THEN
7200     EXISTS_TAC `vsum p (\(x:real^N,k:real^N->bool).
7201                   content k % (f:num->real^N->real^1) (m x) x)` THEN
7202     EXISTS_TAC `vsum p (\(x:real^N,k:real^N->bool).
7203                   integral k ((f:num->real^N->real^1) (m x)))` THEN
7204     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
7205     SUBGOAL_THEN `?s:num. !t:real^N#(real^N->bool). t IN p ==> m(FST t) <= s`
7206     MP_TAC THENL [ASM_SIMP_TAC[UPPER_BOUND_FINITE_SET]; ALL_TAC] THEN
7207     REWRITE_TAC[FORALL_PAIR_THM] THEN DISCH_THEN(X_CHOOSE_TAC `s:num`) THEN
7208     REPEAT CONJ_TAC THENL
7209      [ASM_SIMP_TAC[GSYM VSUM_SUB] THEN REWRITE_TAC[LAMBDA_PAIR_THM] THEN
7210       REWRITE_TAC[GSYM VECTOR_SUB_LDISTRIB] THEN
7211       W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
7212       ASM_REWRITE_TAC[] THEN
7213       MATCH_MP_TAC(REAL_ARITH `y <= e ==> x <= y ==> x <= e`) THEN
7214       REWRITE_TAC[LAMBDA_PAIR_THM] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
7215       EXISTS_TAC
7216        `sum p (\(x:real^N,k:real^N->bool).
7217                  content k * e / (&4 * content (interval[a:real^N,b])))` THEN
7218       CONJ_TAC THENL
7219        [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
7220         MAP_EVERY X_GEN_TAC [`x:real^N`; `k:real^N->bool`] THEN
7221         DISCH_TAC THEN REWRITE_TAC[NORM_MUL; GSYM VECTOR_SUB_LDISTRIB] THEN
7222         MATCH_MP_TAC REAL_LE_MUL2 THEN
7223         REWRITE_TAC[REAL_ABS_POS; NORM_POS_LE] THEN
7224         REWRITE_TAC[ABS_DROP; DROP_SUB] THEN
7225         REWRITE_TAC[REAL_ARITH `abs(x) <= x <=> &0 <= x`] THEN CONJ_TAC THENL
7226          [ASM_MESON_TAC[CONTENT_POS_LE; TAGGED_DIVISION_OF]; ALL_TAC] THEN
7227         MATCH_MP_TAC(REAL_ARITH
7228          `&0 <= g - f /\ g - f < e ==> abs(g - f) <= e`) THEN
7229         CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
7230         REWRITE_TAC[LE_REFL] THEN ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET];
7231         ALL_TAC] THEN
7232       REWRITE_TAC[LAMBDA_PAIR; SUM_RMUL] THEN REWRITE_TAC[LAMBDA_PAIR_THM] THEN
7233       FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP
7234        ADDITIVE_CONTENT_TAGGED_DIVISION th]) THEN
7235       MATCH_MP_TAC REAL_EQ_IMP_LE THEN
7236       UNDISCH_TAC `&0 < content(interval[a:real^N,b])` THEN
7237       CONV_TAC REAL_FIELD;
7238       ASM_SIMP_TAC[GSYM VSUM_SUB] THEN REWRITE_TAC[LAMBDA_PAIR_THM] THEN
7239       MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC
7240         `norm(vsum (0..s)
7241                (\j. vsum {(x:real^N,k:real^N->bool) | (x,k) IN p /\ m(x) = j}
7242                          (\(x,k). content k % f (m x) x :real^1 -
7243                                   integral k (f (m x)))))` THEN
7244       CONJ_TAC THENL
7245        [MATCH_MP_TAC REAL_EQ_IMP_LE THEN REWRITE_TAC[lemma] THEN
7246         AP_TERM_TAC THEN MATCH_MP_TAC(GSYM VSUM_GROUP) THEN
7247         ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG; LE_0] THEN
7248         ASM_REWRITE_TAC[FORALL_PAIR_THM];
7249         ALL_TAC] THEN
7250       MATCH_MP_TAC REAL_LET_TRANS THEN
7251       EXISTS_TAC `sum (0..s) (\i. e / &2 pow (i + 2))` THEN CONJ_TAC THENL
7252        [ALL_TAC;
7253         REWRITE_TAC[real_div; GSYM REAL_POW_INV; SUM_LMUL] THEN
7254         REWRITE_TAC[REAL_POW_ADD; SUM_RMUL] THEN REWRITE_TAC[SUM_GP] THEN
7255         CONV_TAC REAL_RAT_REDUCE_CONV THEN
7256         ASM_SIMP_TAC[REAL_LT_LMUL_EQ; CONJUNCT1 LT] THEN
7257         REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC] THEN
7258         CONV_TAC REAL_RAT_REDUCE_CONV THEN
7259         MATCH_MP_TAC(REAL_ARITH `&0 < x * y ==> (&1 - x) * y < y`) THEN
7260         MATCH_MP_TAC REAL_LT_MUL THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
7261         MATCH_MP_TAC REAL_POW_LT THEN CONV_TAC REAL_RAT_REDUCE_CONV] THEN
7262       MATCH_MP_TAC VSUM_NORM_LE THEN REWRITE_TAC[FINITE_NUMSEG] THEN
7263       X_GEN_TAC `t:num` THEN REWRITE_TAC[IN_NUMSEG; LE_0] THEN DISCH_TAC THEN
7264       MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
7265        `norm(vsum {x:real^N,k:real^N->bool | x,k IN p /\ m x:num = t}
7266                   (\(x,k). content k % f t x - integral k (f t)):real^1)` THEN
7267       CONJ_TAC THENL
7268        [MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
7269         MATCH_MP_TAC VSUM_EQ THEN SIMP_TAC[FORALL_PAIR_THM; IN_ELIM_PAIR_THM];
7270         ALL_TAC] THEN
7271       MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
7272         HENSTOCK_LEMMA_PART1) THEN
7273       MAP_EVERY EXISTS_TAC
7274        [`a:real^N`; `b:real^N`; `(b(t:num)):real^N->real^N->bool`] THEN
7275       ASM_REWRITE_TAC[] THEN
7276       ASM_SIMP_TAC[REAL_LT_DIV; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN
7277       CONJ_TAC THENL
7278        [MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_SUBSET THEN
7279         EXISTS_TAC `p:(real^N#(real^N->bool))->bool` THEN
7280         SIMP_TAC[SUBSET; FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN
7281         ASM_MESON_TAC[tagged_division_of];
7282         ALL_TAC] THEN
7283       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
7284       EXPAND_TAC "d" THEN REWRITE_TAC[fine; IN_ELIM_PAIR_THM] THEN MESON_TAC[];
7285
7286       MP_TAC(ISPECL [`(f:num->real^N->real^1) s`; `a:real^N`; `b:real^N`;
7287                      `p:(real^N#(real^N->bool))->bool`]
7288                     INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN) THEN
7289       MP_TAC(ISPECL [`(f:num->real^N->real^1) r`; `a:real^N`; `b:real^N`;
7290                      `p:(real^N#(real^N->bool))->bool`]
7291                     INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN) THEN
7292       ASM_SIMP_TAC[ABS_DROP; DROP_SUB; DROP_VSUM; GSYM DROP_EQ] THEN
7293       REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM] THEN MATCH_MP_TAC(REAL_ARITH
7294        `sr <= sx /\ sx <= ss /\ ks <= i /\ &0 <= i - kr /\ i - kr < e
7295         ==> kr = sr ==> ks = ss ==> abs(sx - i) < e`) THEN
7296       ASM_SIMP_TAC[LE_REFL] THEN CONJ_TAC THEN MATCH_MP_TAC SUM_LE THEN
7297       ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
7298       MAP_EVERY X_GEN_TAC [`x:real^N`; `i:real^N->bool`] THEN DISCH_TAC THEN
7299       (SUBGOAL_THEN `i SUBSET interval[a:real^N,b]` ASSUME_TAC THENL
7300         [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
7301        SUBGOAL_THEN `?u v:real^N. i = interval[u,v]`
7302         (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
7303        THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC]) THEN
7304       MATCH_MP_TAC INTEGRAL_DROP_LE THEN
7305       REPEAT(CONJ_TAC THENL
7306        [ASM_MESON_TAC[INTEGRABLE_SUBINTERVAL]; ALL_TAC]) THEN
7307       X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
7308       MP_TAC(ISPEC
7309         `\m n:num. drop (f m (y:real^N)) <= drop (f n y)`
7310         TRANSITIVE_STEPWISE_LE) THEN
7311       REWRITE_TAC[REAL_LE_TRANS; REAL_LE_REFL] THEN
7312       (ANTS_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC]) THEN
7313       DISCH_THEN MATCH_MP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
7314       ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET]];
7315     ALL_TAC] THEN
7316   CONJ_TAC THENL [ASM_MESON_TAC[integrable_on]; ALL_TAC] THEN
7317   FIRST_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN
7318   ASM_REWRITE_TAC[]);;
7319
7320 let MONOTONE_CONVERGENCE_INCREASING = prove
7321  (`!f:num->real^N->real^1 g s.
7322         (!k. (f k) integrable_on s) /\
7323         (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\
7324         (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) /\
7325         bounded {integral s (f k) | k IN (:num)}
7326         ==> g integrable_on s /\
7327             ((\k. integral s (f k)) --> integral s g) sequentially`,
7328   SUBGOAL_THEN
7329    `!f:num->real^N->real^1 g s.
7330         (!k x. x IN s ==> &0 <= drop(f k x)) /\
7331         (!k. (f k) integrable_on s) /\
7332         (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\
7333         (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) /\
7334         bounded {integral s (f k) | k IN (:num)}
7335         ==> g integrable_on s /\
7336             ((\k. integral s (f k)) --> integral s g) sequentially`
7337   ASSUME_TAC THENL
7338    [ALL_TAC;
7339     REPEAT GEN_TAC THEN STRIP_TAC THEN
7340     FIRST_X_ASSUM(MP_TAC o ISPECL
7341      [`\n x:real^N. f(SUC n) x - f 0 x:real^1`;
7342       `\x. (g:real^N->real^1) x - f 0 x`; `s:real^N->bool`]) THEN
7343     REWRITE_TAC[] THEN ANTS_TAC THEN REPEAT CONJ_TAC THENL
7344      [REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_SUB; REAL_SUB_LE] THEN
7345       MP_TAC(ISPEC
7346         `\m n:num. drop (f m (x:real^N)) <= drop (f n x)`
7347         TRANSITIVE_STEPWISE_LE) THEN
7348       REWRITE_TAC[REAL_LE_TRANS; REAL_LE_REFL] THEN ASM_MESON_TAC[LE_0];
7349       GEN_TAC THEN MATCH_MP_TAC INTEGRABLE_SUB THEN ASM_REWRITE_TAC[ETA_AX];
7350       REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_SUB; REAL_SUB_LE] THEN
7351       ASM_SIMP_TAC[REAL_ARITH `x - a <= y - a <=> x <= y`];
7352       REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_SUB THEN SIMP_TAC[LIM_CONST] THEN
7353       REWRITE_TAC[ADD1] THEN
7354       MATCH_MP_TAC(ISPECL[`f:num->real^1`; `l:real^1`; `1`] SEQ_OFFSET) THEN
7355       ASM_SIMP_TAC[];
7356       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
7357       ASM_SIMP_TAC[INTEGRAL_SUB; ETA_AX; bounded] THEN
7358       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
7359       REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN
7360       DISCH_THEN(X_CHOOSE_THEN `B:real`
7361         (fun th -> EXISTS_TAC `B + norm(integral s (f 0:real^N->real^1))` THEN
7362                    X_GEN_TAC `k:num` THEN MP_TAC(SPEC `SUC k` th))) THEN
7363       NORM_ARITH_TAC;
7364       ASM_SIMP_TAC[INTEGRAL_SUB; ETA_AX; IMP_CONJ] THEN
7365       SUBGOAL_THEN `(f 0:real^N->real^1) integrable_on s` MP_TAC THENL
7366        [ASM_REWRITE_TAC[]; ONCE_REWRITE_TAC[IMP_IMP]] THEN
7367       DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_ADD) THEN
7368       REWRITE_TAC[ETA_AX; VECTOR_ARITH `f + (g - f):real^N = g`] THEN
7369       DISCH_TAC THEN ASM_SIMP_TAC[INTEGRAL_SUB; ETA_AX] THEN
7370       MP_TAC(ISPECL [`sequentially`; `integral s (f 0:real^N->real^1)`]
7371                     LIM_CONST) THEN
7372       REWRITE_TAC[IMP_IMP] THEN DISCH_THEN(MP_TAC o MATCH_MP LIM_ADD) THEN
7373       REWRITE_TAC[ETA_AX; VECTOR_ARITH `f + (g - f):real^N = g`] THEN
7374       REWRITE_TAC[ADD1] THEN
7375       SIMP_TAC[ISPECL[`f:num->real^1`; `l:real^1`; `1`] SEQ_OFFSET_REV]]] THEN
7376   REPEAT GEN_TAC THEN STRIP_TAC THEN
7377   SUBGOAL_THEN
7378    `!x:real^N k:num. x IN s ==> drop(f k x) <= drop(g x)`
7379   ASSUME_TAC THENL
7380    [REPEAT STRIP_TAC THEN
7381     MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LBOUND) THEN
7382     EXISTS_TAC `\k. (f:num->real^N->real^1) k x` THEN
7383     ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
7384     EXISTS_TAC `k:num` THEN SPEC_TAC(`k:num`,`k:num`) THEN
7385     MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN REWRITE_TAC[REAL_LE_TRANS] THEN
7386     ASM_SIMP_TAC[REAL_LE_REFL];
7387     ALL_TAC] THEN
7388   SUBGOAL_THEN
7389    `?i. ((\k. integral s (f k:real^N->real^1)) --> i)
7390         sequentially`
7391   CHOOSE_TAC THENL
7392    [MATCH_MP_TAC BOUNDED_INCREASING_CONVERGENT THEN ASM_REWRITE_TAC[] THEN
7393     GEN_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_REWRITE_TAC[];
7394     ALL_TAC] THEN
7395   SUBGOAL_THEN
7396    `!k. drop(integral s ((f:num->real^N->real^1) k)) <= drop i`
7397   ASSUME_TAC THENL
7398     [GEN_TAC THEN MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LBOUND) THEN
7399      EXISTS_TAC `\k. integral(s) ((f:num->real^N->real^1) k)` THEN
7400      ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
7401      EXISTS_TAC `k:num` THEN SPEC_TAC(`k:num`,`k:num`) THEN
7402      MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
7403      ASM_REWRITE_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN
7404      GEN_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_REWRITE_TAC[];
7405      ALL_TAC] THEN
7406   SUBGOAL_THEN `((g:real^N->real^1) has_integral i) s` ASSUME_TAC THENL
7407    [ALL_TAC;
7408     CONJ_TAC THENL [ASM_MESON_TAC[integrable_on]; ALL_TAC] THEN
7409     FIRST_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN
7410     ASM_REWRITE_TAC[]] THEN
7411   REWRITE_TAC[HAS_INTEGRAL_ALT] THEN
7412   MP_TAC(ISPECL
7413    [`\k x. if x IN s then (f:num->real^N->real^1) k x else vec 0`;
7414     `\x. if x IN s then (g:real^N->real^1) x else vec 0`]
7415    (MATCH_MP(MESON[] `(!a b c d. P a b c d ==> Q a b c d)
7416                       ==> !a b. (!c d. P a b c d) ==> (!c d. Q a b c d)`)
7417             MONOTONE_CONVERGENCE_INTERVAL)) THEN
7418   ANTS_TAC THENL
7419    [REPEAT GEN_TAC THEN REWRITE_TAC[] THEN
7420     MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
7421      [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV [INTEGRABLE_ALT]) THEN
7422       SIMP_TAC[];
7423       DISCH_TAC] THEN
7424     CONJ_TAC THENL
7425      [REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[REAL_LE_REFL];
7426       ALL_TAC] THEN
7427     CONJ_TAC THENL
7428      [REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[LIM_CONST];
7429       ALL_TAC] THEN
7430     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
7431     ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
7432     REWRITE_TAC[bounded; FORALL_IN_IMAGE; IN_UNIV] THEN
7433     MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
7434     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:num` THEN
7435     REWRITE_TAC[ABS_DROP] THEN MATCH_MP_TAC(REAL_ARITH
7436      `&0 <= y /\ y <= x ==> abs(x) <= a ==> abs(y) <= a`) THEN
7437     CONJ_TAC THENL
7438      [MATCH_MP_TAC INTEGRAL_DROP_POS THEN ASM_REWRITE_TAC[] THEN
7439       REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
7440       ASM_SIMP_TAC[REAL_LE_REFL; DROP_VEC];
7441       ALL_TAC] THEN
7442     GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM INTEGRAL_RESTRICT_UNIV] THEN
7443     MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN
7444     ASM_REWRITE_TAC[SUBSET_UNIV; IN_UNIV] THEN
7445     ASM_REWRITE_TAC[INTEGRABLE_RESTRICT_UNIV; ETA_AX] THEN
7446     GEN_TAC THEN COND_CASES_TAC THEN
7447     ASM_SIMP_TAC[REAL_LE_REFL; DROP_VEC; REAL_LE_REFL];
7448     ALL_TAC] THEN
7449   REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
7450   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
7451   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
7452   DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
7453   ASM_SIMP_TAC[dist; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
7454   DISCH_THEN(X_CHOOSE_THEN `N:num` STRIP_ASSUME_TAC) THEN
7455   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV
7456    [HAS_INTEGRAL_INTEGRAL]) THEN
7457   GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [HAS_INTEGRAL_ALT] THEN
7458   REWRITE_TAC[FORALL_AND_THM] THEN
7459   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
7460   DISCH_THEN(MP_TAC o SPECL [`N:num`; `e / &4`]) THEN
7461   ASM_SIMP_TAC[dist; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
7462   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
7463   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
7464   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN DISCH_TAC THEN
7465   FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^N`; `b:real^N`]) THEN
7466   ASM_REWRITE_TAC[] THEN
7467   FIRST_ASSUM(MP_TAC o C MATCH_MP (ARITH_RULE `N:num <= N`)) THEN
7468   REWRITE_TAC[IMP_IMP] THEN
7469   DISCH_THEN(MP_TAC o MATCH_MP (NORM_ARITH
7470    `norm(x - y) < e / &4 /\ norm(z - x) < e / &4
7471     ==> norm(z - y) < e / &2`)) THEN
7472   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (BINDER_CONV o BINDER_CONV)
7473         [LIM_SEQUENTIALLY]) THEN
7474   DISCH_THEN(MP_TAC o SPECL [`a:real^N`; `b:real^N`; `e / &2`]) THEN
7475   ASM_REWRITE_TAC[dist; REAL_HALF] THEN
7476   DISCH_THEN(X_CHOOSE_THEN `M:num` (MP_TAC o SPEC `M + N:num`)) THEN
7477   REWRITE_TAC[LE_ADD; ABS_DROP; DROP_SUB] THEN
7478   MATCH_MP_TAC(REAL_ARITH
7479    `f1 <= f2 /\ f2 <= i
7480     ==> abs(f2 - g) < e / &2 ==> abs(f1 - i) < e / &2 ==> abs(g - i) < e`) THEN
7481   CONJ_TAC THENL
7482    [MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_REWRITE_TAC[] THEN
7483     X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
7484     COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL] THEN
7485     MP_TAC(ISPEC
7486         `\m n:num. drop (f m (x:real^N)) <= drop (f n x)`
7487         TRANSITIVE_STEPWISE_LE) THEN
7488     REWRITE_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN
7489     ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
7490     DISCH_THEN MATCH_MP_TAC THEN ARITH_TAC;
7491     ALL_TAC] THEN
7492   MATCH_MP_TAC REAL_LE_TRANS THEN
7493   EXISTS_TAC `drop(integral s ((f:num->real^N->real^1) (M + N)))` THEN
7494   ASM_REWRITE_TAC[] THEN
7495   GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM INTEGRAL_RESTRICT_UNIV] THEN
7496   MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN
7497   ASM_REWRITE_TAC[SUBSET_UNIV; IN_UNIV] THEN
7498   ASM_REWRITE_TAC[INTEGRABLE_RESTRICT_UNIV; ETA_AX] THEN
7499   GEN_TAC THEN COND_CASES_TAC THEN
7500   ASM_SIMP_TAC[REAL_LE_REFL; DROP_VEC; REAL_LE_REFL]);;
7501
7502 let MONOTONE_CONVERGENCE_DECREASING = prove
7503  (`!f:num->real^N->real^1 g s.
7504         (!k. (f k) integrable_on s) /\
7505         (!k x. x IN s ==> drop(f (SUC k) x) <= drop(f k x)) /\
7506         (!x. x IN s ==> ((\k. f k x) --> g x) sequentially) /\
7507         bounded {integral s (f k) | k IN (:num)}
7508         ==> g integrable_on s /\
7509             ((\k. integral s (f k)) --> integral s g) sequentially`,
7510   REPEAT GEN_TAC THEN DISCH_TAC THEN
7511   MP_TAC(ISPECL
7512    [`(\k x. --(f k x)):num->real^N->real^1`;
7513     `(\x. --(g x)):real^N->real^1`; `s:real^N->bool`]
7514         MONOTONE_CONVERGENCE_INCREASING) THEN
7515   FIRST_ASSUM MP_TAC THEN
7516   MATCH_MP_TAC(TAUT `(a ==> b) /\ (c ==> d) ==> a ==> (b ==> c) ==> d`) THEN
7517   REWRITE_TAC[] THEN CONJ_TAC THENL
7518    [REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THENL
7519      [MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
7520       DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_NEG) THEN REWRITE_TAC[];
7521       SIMP_TAC[DROP_NEG; REAL_LE_NEG2];
7522       REPEAT STRIP_TAC THEN MATCH_MP_TAC LIM_NEG THEN ASM_SIMP_TAC[];
7523       ALL_TAC] THEN
7524     DISCH_TAC THEN MATCH_MP_TAC BOUNDED_SUBSET THEN
7525     EXISTS_TAC `IMAGE (\x. --x)
7526                       {integral s (f k:real^N->real^1) | k IN (:num)}` THEN
7527     CONJ_TAC THENL
7528      [MATCH_MP_TAC BOUNDED_LINEAR_IMAGE THEN
7529       ASM_SIMP_TAC[LINEAR_COMPOSE_NEG; LINEAR_ID];
7530       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN REWRITE_TAC[GSYM IMAGE_o] THEN
7531       REWRITE_TAC[SUBSET; IN_IMAGE] THEN
7532       GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN
7533       REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[o_THM] THEN
7534       MATCH_MP_TAC INTEGRAL_NEG THEN ASM_REWRITE_TAC[]];
7535     ALL_TAC] THEN
7536   DISCH_THEN(CONJUNCTS_THEN2
7537    (MP_TAC o MATCH_MP INTEGRABLE_NEG) (MP_TAC o MATCH_MP LIM_NEG)) THEN
7538   REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX] THEN
7539   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
7540   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN
7541   BINOP_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN TRY GEN_TAC THEN
7542   MATCH_MP_TAC(VECTOR_ARITH `x:real^N = --y ==> --x = y`) THEN
7543   MATCH_MP_TAC INTEGRAL_NEG THEN ASM_REWRITE_TAC[]);;
7544
7545 (* ------------------------------------------------------------------------- *)
7546 (* More lemmas about existence and bounds between integrals.                 *)
7547 (* ------------------------------------------------------------------------- *)
7548
7549 let INTEGRAL_NORM_BOUND_INTEGRAL = prove
7550  (`!f:real^M->real^N g s.
7551         f integrable_on s /\ g integrable_on s /\
7552         (!x. x IN s ==> norm(f x) <= drop(g x))
7553         ==> norm(integral s f) <= drop(integral s g)`,
7554   let lemma = prove
7555    (`(!e. &0 < e ==> x < y + e) ==> x <= y`,
7556     DISCH_THEN(MP_TAC o SPEC `x - y:real`) THEN REAL_ARITH_TAC) in
7557   SUBGOAL_THEN
7558    `!f:real^M->real^N g a b.
7559         f integrable_on interval[a,b] /\ g integrable_on interval[a,b] /\
7560         (!x. x IN interval[a,b] ==> norm(f x) <= drop(g x))
7561         ==> norm(integral(interval[a,b]) f) <= drop(integral(interval[a,b]) g)`
7562   ASSUME_TAC THENL
7563    [REPEAT STRIP_TAC THEN MATCH_MP_TAC lemma THEN
7564     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
7565     UNDISCH_TAC `(f:real^M->real^N) integrable_on interval[a,b]` THEN
7566     DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
7567     FIRST_X_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
7568     REWRITE_TAC[has_integral] THEN DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
7569     ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN
7570     X_GEN_TAC `d1:real^M->real^M->bool` THEN STRIP_TAC THEN
7571     DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN
7572     ASM_REWRITE_TAC[REAL_HALF; LEFT_IMP_EXISTS_THM] THEN
7573     X_GEN_TAC `d2:real^M->real^M->bool` THEN
7574     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
7575     MP_TAC(ISPECL [`d1:real^M->real^M->bool`; `d2:real^M->real^M->bool`]
7576                   GAUGE_INTER) THEN
7577     ASM_REWRITE_TAC[] THEN
7578     DISCH_THEN(MP_TAC o MATCH_MP FINE_DIVISION_EXISTS) THEN
7579     DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN
7580     REWRITE_TAC[FINE_INTER; LEFT_IMP_EXISTS_THM] THEN
7581     X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
7582     DISCH_THEN(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN
7583     FIRST_X_ASSUM(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN
7584     ASM_REWRITE_TAC[ABS_DROP; DROP_SUB] THEN MATCH_MP_TAC(NORM_ARITH
7585      `norm(sg) <= dsa
7586       ==> abs(dsa - dia) < e / &2 ==> norm(sg - ig) < e / &2
7587           ==> norm(ig) < dia + e`) THEN
7588     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
7589     ASM_SIMP_TAC[DROP_VSUM] THEN MATCH_MP_TAC VSUM_NORM_LE THEN
7590     ASM_REWRITE_TAC[o_DEF; FORALL_PAIR_THM] THEN
7591     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
7592     REWRITE_TAC[NORM_MUL; DROP_CMUL] THEN
7593     MATCH_MP_TAC REAL_LE_MUL2 THEN REWRITE_TAC[REAL_ABS_POS; NORM_POS_LE] THEN
7594     REWRITE_TAC[REAL_ARITH `abs x <= x <=> &0 <= x`] THEN
7595     ASM_MESON_TAC[CONTENT_POS_LE; TAGGED_DIVISION_OF; SUBSET];
7596     ALL_TAC] THEN
7597   REPEAT GEN_TAC THEN REWRITE_TAC[CONJ_ASSOC] THEN
7598   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
7599   DISCH_THEN(CONJUNCTS_THEN (fun th ->
7600      ASSUME_TAC(CONJUNCT1(GEN_REWRITE_RULE I [INTEGRABLE_ALT] th)) THEN
7601      MP_TAC(MATCH_MP INTEGRABLE_INTEGRAL th))) THEN
7602   ONCE_REWRITE_TAC[HAS_INTEGRAL] THEN
7603   DISCH_THEN(LABEL_TAC "A") THEN DISCH_TAC THEN MATCH_MP_TAC lemma THEN
7604   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
7605   REMOVE_THEN "A" (MP_TAC o SPEC `e / &2`) THEN
7606   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
7607   DISCH_THEN(X_CHOOSE_THEN `B1:real`
7608    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "F"))) THEN
7609   DISCH_THEN(X_CHOOSE_THEN `B2:real`
7610    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "A"))) THEN
7611   MP_TAC(ISPEC `ball(vec 0,max B1 B2):real^M->bool`
7612     BOUNDED_SUBSET_CLOSED_INTERVAL) THEN
7613   REWRITE_TAC[BOUNDED_BALL; LEFT_IMP_EXISTS_THM] THEN
7614   REWRITE_TAC[BALL_MAX_UNION; UNION_SUBSET] THEN
7615   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
7616   DISCH_THEN(CONJUNCTS_THEN(ANTE_RES_THEN MP_TAC)) THEN
7617   DISCH_THEN(X_CHOOSE_THEN `z:real^1` (CONJUNCTS_THEN2 ASSUME_TAC
7618      (fun th -> DISCH_THEN(X_CHOOSE_THEN `w:real^N`
7619                 (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN MP_TAC th))) THEN
7620   ASM_REWRITE_TAC[ABS_DROP; DROP_SUB] THEN MATCH_MP_TAC(NORM_ARITH
7621      `norm(sg) <= dsa
7622       ==> abs(dsa - dia) < e / &2 ==> norm(sg - ig) < e / &2
7623           ==> norm(ig) < dia + e`) THEN
7624   REPEAT(FIRST_X_ASSUM(SUBST1_TAC o SYM o MATCH_MP INTEGRAL_UNIQUE)) THEN
7625   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
7626   REPEAT STRIP_TAC THEN
7627   COND_CASES_TAC THEN ASM_SIMP_TAC[NORM_0; DROP_VEC; REAL_LE_REFL]);;
7628
7629 let INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT = prove
7630  (`!f:real^M->real^N g:real^M->real^P s k.
7631         1 <= k /\ k <= dimindex(:P) /\
7632         f integrable_on s /\ g integrable_on s /\
7633         (!x. x IN s ==> norm(f x) <= (g x)$k)
7634         ==> norm(integral s f) <= (integral s g)$k`,
7635   REPEAT STRIP_TAC THEN
7636   MATCH_MP_TAC REAL_LE_TRANS THEN
7637   EXISTS_TAC `drop(integral s ((\y. lift(y$k)) o (g:real^M->real^P)))` THEN
7638   SUBGOAL_THEN `linear(\y:real^P. lift(y$k))` ASSUME_TAC THENL
7639    [ASM_SIMP_TAC[linear; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
7640                  LIFT_ADD; LIFT_CMUL];
7641     ALL_TAC] THEN
7642   CONJ_TAC THENL
7643    [MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
7644     ASM_SIMP_TAC[o_THM; LIFT_DROP] THEN MATCH_MP_TAC INTEGRABLE_LINEAR THEN
7645     ASM_SIMP_TAC[];
7646     ALL_TAC] THEN
7647   SUBGOAL_THEN
7648    `integral s ((\y. lift (y$k)) o (g:real^M->real^P)) =
7649         (\y. lift (y$k)) (integral s g)`
7650   SUBST1_TAC THENL
7651    [MATCH_MP_TAC INTEGRAL_LINEAR THEN ASM_REWRITE_TAC[];
7652     REWRITE_TAC[LIFT_DROP; REAL_LE_REFL]]);;
7653
7654 let HAS_INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT = prove
7655  (`!f:real^M->real^N g:real^M->real^P s i j k.
7656         1 <= k /\ k <= dimindex(:P) /\
7657         (f has_integral i) s /\ (g has_integral j) s /\
7658         (!x. x IN s ==> norm(f x) <= (g x)$k)
7659         ==> norm(i) <= j$k`,
7660   REPEAT STRIP_TAC THEN
7661   REPEAT(FIRST_X_ASSUM(fun th ->
7662    SUBST1_TAC(SYM(MATCH_MP INTEGRAL_UNIQUE th)) THEN
7663    ASSUME_TAC(MATCH_MP HAS_INTEGRAL_INTEGRABLE th))) THEN
7664   MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL_COMPONENT THEN
7665   ASM_REWRITE_TAC[]);;
7666
7667 let INTEGRABLE_ON_ALL_INTERVALS_INTEGRABLE_BOUND = prove
7668  (`!f:real^M->real^N g s.
7669         (!a b. (\x. if x IN s then f x else vec 0)
7670                integrable_on interval[a,b]) /\
7671         (!x. x IN s ==> norm(f x) <= drop(g x)) /\
7672         g integrable_on s
7673         ==> f integrable_on s`,
7674   let lemma = prove
7675    (`!f:real^M->real^N g.
7676           (!a b. f integrable_on interval[a,b]) /\
7677           (!x. norm(f x) <= drop(g x)) /\
7678           g integrable_on (:real^M)
7679           ==> f integrable_on (:real^M)`,
7680     REPEAT GEN_TAC THEN
7681     REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
7682     ONCE_REWRITE_TAC[INTEGRABLE_ALT_SUBSET] THEN
7683     ASM_REWRITE_TAC[IN_UNIV; ETA_AX] THEN
7684     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
7685     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `e:real` THEN
7686     ASM_CASES_TAC `&0 < e` THEN ASM_REWRITE_TAC[] THEN
7687     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
7688     MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
7689     REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
7690     DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
7691     MATCH_MP_TAC(REAL_ARITH `a <= b ==> b < c ==> a < c`) THEN
7692     ONCE_REWRITE_TAC[NORM_SUB] THEN
7693     ASM_SIMP_TAC[GSYM INTEGRAL_DIFF; NEGLIGIBLE_EMPTY;
7694                  SET_RULE `s SUBSET t ==> s DIFF t = {}`] THEN
7695     REWRITE_TAC[ABS_DROP] THEN
7696     MATCH_MP_TAC(REAL_ARITH `x <= y ==> x <= abs y`) THEN
7697     MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
7698     ASM_MESON_TAC[integrable_on; HAS_INTEGRAL_DIFF; NEGLIGIBLE_EMPTY;
7699                  SET_RULE `s SUBSET t ==> s DIFF t = {}`]) in
7700   REPEAT GEN_TAC THEN
7701   REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
7702   ONCE_REWRITE_TAC[GSYM INTEGRABLE_RESTRICT_UNIV] THEN
7703   DISCH_TAC THEN MATCH_MP_TAC lemma THEN
7704   EXISTS_TAC `(\x. if x IN s then g x else vec 0):real^M->real^1` THEN
7705   ASM_REWRITE_TAC[] THEN
7706   GEN_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[NORM_0; DROP_VEC; REAL_POS]);;
7707
7708 (* ------------------------------------------------------------------------- *)
7709 (* Interval functions of bounded variation on a set.                         *)
7710 (* ------------------------------------------------------------------------- *)
7711
7712 parse_as_infix("has_bounded_setvariation_on",(12,"right"));;
7713
7714 let set_variation = new_definition
7715  `set_variation s (f:(real^M->bool)->real^N) =
7716         sup { sum d (\k. norm(f k)) | ?t. d division_of t /\ t SUBSET s}`;;
7717
7718 let has_bounded_setvariation_on = new_definition
7719   `(f:(real^M->bool)->real^N) has_bounded_setvariation_on s <=>
7720         ?B. !d t. d division_of t /\ t SUBSET s
7721                   ==> sum d (\k. norm(f k)) <= B`;;
7722
7723 let HAS_BOUNDED_SETVARIATION_ON = prove
7724  (`!f:(real^M->bool)->real^N s.
7725         f  has_bounded_setvariation_on s <=>
7726         ?B. &0 < B /\ !d t. d division_of t /\ t SUBSET s
7727                             ==> sum d (\k. norm(f k)) <= B`,
7728   REWRITE_TAC[has_bounded_setvariation_on] THEN
7729   MESON_TAC[REAL_ARITH `&0 < abs B + &1 /\ (x <= B ==> x <= abs B + &1)`]);;
7730
7731 let HAS_BOUNDED_SETVARIATION_ON_EQ = prove
7732  (`!f g:(real^M->bool)->real^N s.
7733         (!a b. ~(interval[a,b] = {}) /\ interval[a,b] SUBSET s
7734                ==> f(interval[a,b]) = g(interval[a,b])) /\
7735         f has_bounded_setvariation_on s
7736         ==> g has_bounded_setvariation_on s`,
7737   REPEAT GEN_TAC THEN
7738   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
7739   REWRITE_TAC[has_bounded_setvariation_on] THEN
7740   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
7741   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `d:(real^M->bool)->bool` THEN
7742   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `t:real^M->bool` THEN
7743   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
7744   MATCH_MP_TAC(REAL_ARITH `x = y ==> x <= B ==> y <= B`) THEN
7745   MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th ->
7746   GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION_NONEMPTY th]) THEN
7747   REPEAT STRIP_TAC THEN REWRITE_TAC[] THEN AP_TERM_TAC THEN
7748   FIRST_X_ASSUM MATCH_MP_TAC THEN
7749   ASM_MESON_TAC[division_of; SUBSET_TRANS]);;
7750
7751 let SET_VARIATION_EQ = prove
7752  (`!f g:(real^M->bool)->real^N s.
7753         (!a b. ~(interval[a,b] = {}) /\ interval[a,b] SUBSET s
7754                ==> f(interval[a,b]) = g(interval[a,b]))
7755         ==> set_variation s f = set_variation s g`,
7756   REPEAT STRIP_TAC THEN REWRITE_TAC[set_variation] THEN AP_TERM_TAC THEN
7757   MATCH_MP_TAC(SET_RULE
7758    `(!x. P x ==> f x = g x) ==> {f x | P x} = {g x | P x}`) THEN
7759   X_GEN_TAC `d:(real^M->bool)->bool` THEN
7760   DISCH_THEN(X_CHOOSE_THEN `t:real^M->bool` STRIP_ASSUME_TAC) THEN
7761   MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th ->
7762   GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION_NONEMPTY th]) THEN
7763   REPEAT STRIP_TAC THEN REWRITE_TAC[] THEN AP_TERM_TAC THEN
7764   FIRST_X_ASSUM MATCH_MP_TAC THEN
7765   ASM_MESON_TAC[division_of; SUBSET_TRANS]);;
7766
7767 let HAS_BOUNDED_SETVARIATION_ON_COMPONENTWISE = prove
7768  (`!f:(real^M->bool)->real^N s.
7769         f has_bounded_setvariation_on s <=>
7770         !i. 1 <= i /\ i <= dimindex(:N)
7771             ==> (\k. lift(f k$i)) has_bounded_setvariation_on s`,
7772   REPEAT GEN_TAC THEN
7773   REWRITE_TAC[has_bounded_setvariation_on; NORM_LIFT] THEN EQ_TAC THENL
7774    [DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
7775     X_GEN_TAC `i:num` THEN STRIP_TAC THEN EXISTS_TAC `B:real` THEN
7776     MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN
7777     STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL
7778       [`d:(real^M->bool)->bool`; `t:real^M->bool`]) THEN
7779     ASM_REWRITE_TAC[] THEN
7780     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN
7781     MATCH_MP_TAC SUM_LE THEN ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
7782     ASM_MESON_TAC[DIVISION_OF_FINITE];
7783     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
7784     REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM] THEN
7785     X_GEN_TAC `B:num->real` THEN DISCH_TAC THEN
7786     EXISTS_TAC `sum (1..dimindex(:N)) B` THEN
7787     MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN
7788     STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
7789     EXISTS_TAC `sum d (\k. sum (1..dimindex(:N))
7790                            (\i. abs(((f:(real^M->bool)->real^N) k)$i)))` THEN
7791     FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
7792     ASM_SIMP_TAC[SUM_LE; NORM_LE_L1] THEN
7793     W(MP_TAC o PART_MATCH (lhs o rand) SUM_SWAP o lhand o snd) THEN
7794     ASM_SIMP_TAC[FINITE_NUMSEG] THEN DISCH_THEN SUBST1_TAC THEN
7795     MATCH_MP_TAC SUM_LE_NUMSEG THEN ASM_MESON_TAC[]]);;
7796
7797 let SETVARIATION_EQUAL_LEMMA = prove
7798  (`!mf:((real^M->bool)->real^N)->((real^M->bool)->real^N) ms ms'.
7799         (!s. ms'(ms s) = s /\ ms(ms' s) = s) /\
7800         (!f a b. ~(interval[a,b] = {})
7801                  ==> mf f (ms (interval[a,b])) = f (interval[a,b]) /\
7802                      ?a' b'. ~(interval[a',b'] = {}) /\
7803                              ms' (interval[a,b]) = interval[a',b']) /\
7804         (!t u. t SUBSET u ==> ms t SUBSET ms u /\ ms' t SUBSET ms' u) /\
7805         (!d t. d division_of t
7806                ==> (IMAGE ms d) division_of ms t /\
7807                    (IMAGE ms' d) division_of ms' t)
7808    ==> (!f s. (mf f) has_bounded_setvariation_on (ms s) <=>
7809               f has_bounded_setvariation_on s) /\
7810        (!f s. set_variation (ms s) (mf f) = set_variation s f)`,
7811   REPEAT GEN_TAC THEN STRIP_TAC THEN
7812   REWRITE_TAC[has_bounded_setvariation_on; set_variation] THEN
7813   MATCH_MP_TAC(MESON[]
7814    `((!f s. s1 f s = s2 f s) ==> P) /\
7815     (!f s. s1 f s = s2 f s)
7816     ==> P /\ (!f s. sup (s1 f s) = sup (s2 f s))`) THEN
7817   CONJ_TAC THENL
7818    [REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
7819     REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN MESON_TAC[];
7820     ALL_TAC] THEN
7821   REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN REPEAT GEN_TAC THEN EQ_TAC THEN
7822   STRIP_TAC THEN ASM_REWRITE_TAC[] THENL
7823    [EXISTS_TAC `IMAGE (ms':(real^M->bool)->real^M->bool) d`;
7824     EXISTS_TAC `IMAGE (ms:(real^M->bool)->real^M->bool) d`] THEN
7825   (CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
7826    W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE o rand o snd) THEN
7827    ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_THEN SUBST1_TAC]) THEN
7828   MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[o_THM] THEN FIRST_ASSUM
7829    (fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION_NONEMPTY th]) THEN
7830   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN STRIP_TAC THEN
7831   AP_TERM_TAC THEN ASM_SIMP_TAC[] THEN
7832   SUBGOAL_THEN `?a' b':real^M. ~(interval[a',b'] = {}) /\
7833                         ms' (interval[a:real^M,b]) = interval[a',b']`
7834   STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
7835   ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;
7836
7837 let HAS_BOUNDED_SETVARIATION_ON_ELEMENTARY = prove
7838  (`!f:(real^M->bool)->real^N s.
7839         (?d. d division_of s)
7840         ==> (f has_bounded_setvariation_on s <=>
7841              ?B. !d. d division_of s ==> sum d (\k. norm(f k)) <= B)`,
7842   REPEAT GEN_TAC THEN DISCH_TAC THEN
7843   REWRITE_TAC[has_bounded_setvariation_on] THEN EQ_TAC THEN
7844   MATCH_MP_TAC MONO_EXISTS THENL [MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN
7845   GEN_TAC THEN DISCH_TAC THEN
7846   MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN
7847   STRIP_TAC THEN FIRST_X_ASSUM(X_CHOOSE_TAC `d':(real^M->bool)->bool`) THEN
7848   MP_TAC(ISPECL [`d:(real^M->bool)->bool`; `d':(real^M->bool)->bool`;
7849              `t:real^M->bool`; `s:real^M->bool`] PARTIAL_DIVISION_EXTEND) THEN
7850   ASM_REWRITE_TAC[] THEN
7851   DISCH_THEN(X_CHOOSE_TAC `d'':(real^M->bool)->bool`) THEN
7852   MATCH_MP_TAC REAL_LE_TRANS THEN
7853   EXISTS_TAC `sum d'' (\k:real^M->bool. norm(f k:real^N))` THEN
7854   ASM_SIMP_TAC[] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
7855   ASM_REWRITE_TAC[NORM_POS_LE] THEN ASM_MESON_TAC[DIVISION_OF_FINITE]);;
7856
7857 let HAS_BOUNDED_SETVARIATION_ON_INTERVAL = prove
7858  (`!f:(real^M->bool)->real^N a b.
7859         f has_bounded_setvariation_on interval[a,b] <=>
7860         ?B. !d. d division_of interval[a,b] ==> sum d (\k. norm(f k)) <= B`,
7861   REPEAT GEN_TAC THEN MATCH_MP_TAC HAS_BOUNDED_SETVARIATION_ON_ELEMENTARY THEN
7862   REWRITE_TAC[ELEMENTARY_INTERVAL]);;
7863
7864 let HAS_BOUNDED_SETVARIATION_ON_UNIV = prove
7865  (`!f:(real^M->bool)->real^N.
7866         f has_bounded_setvariation_on (:real^M) <=>
7867         ?B. !d. d division_of UNIONS d ==> sum d (\k. norm(f k)) <= B`,
7868   REPEAT GEN_TAC THEN
7869   REWRITE_TAC[has_bounded_setvariation_on; SUBSET_UNIV] THEN
7870   MESON_TAC[DIVISION_OF_UNION_SELF]);;
7871
7872 let HAS_BOUNDED_SETVARIATION_ON_SUBSET = prove
7873  (`!f:(real^M->bool)->real^N s t.
7874         f has_bounded_setvariation_on s /\ t SUBSET s
7875         ==> f has_bounded_setvariation_on t`,
7876   REPEAT GEN_TAC THEN
7877   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
7878   REWRITE_TAC[has_bounded_setvariation_on] THEN
7879   MATCH_MP_TAC MONO_EXISTS THEN ASM_MESON_TAC[SUBSET_TRANS]);;
7880
7881 let HAS_BOUNDED_SETVARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS = prove
7882  (`!f:(real^M->bool)->real^N s.
7883         f has_bounded_setvariation_on s
7884         ==> bounded { f(interval[c,d]) | interval[c,d] SUBSET s}`,
7885   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_setvariation_on; bounded] THEN
7886   DISCH_THEN(X_CHOOSE_TAC `B:real`) THEN
7887   EXISTS_TAC `max (abs B) (norm((f:(real^M->bool)->real^N) {}))` THEN
7888   REWRITE_TAC[FORALL_IN_GSPEC] THEN
7889   MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN DISCH_TAC THEN
7890   ASM_CASES_TAC `interval[c:real^M,d] = {}` THEN
7891   ASM_REWRITE_TAC[REAL_ARITH `a <= max b a`] THEN
7892   FIRST_X_ASSUM(MP_TAC o SPECL
7893    [`{interval[c:real^M,d]}`; `interval[c:real^M,d]`]) THEN
7894   ASM_SIMP_TAC[DIVISION_OF_SELF; SUM_SING] THEN REAL_ARITH_TAC);;
7895
7896 let HAS_BOUNDED_SETVARIATION_ON_NORM = prove
7897  (`!f:(real^M->bool)->real^N s.
7898         f has_bounded_setvariation_on s
7899         ==> (\x. lift(norm(f x))) has_bounded_setvariation_on s`,
7900   REWRITE_TAC[has_bounded_setvariation_on; NORM_REAL; GSYM drop] THEN
7901   REWRITE_TAC[REAL_ABS_NORM; LIFT_DROP]);;
7902
7903 let HAS_BOUNDED_SETVARIATION_ON_COMPOSE_LINEAR = prove
7904  (`!f:(real^M->bool)->real^N g:real^N->real^P s.
7905         f has_bounded_setvariation_on s /\ linear g
7906         ==> (g o f) has_bounded_setvariation_on s`,
7907   REPEAT GEN_TAC THEN
7908   REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON] THEN
7909   DISCH_THEN(CONJUNCTS_THEN2 (X_CHOOSE_TAC `B:real`) ASSUME_TAC) THEN
7910   FIRST_X_ASSUM(X_CHOOSE_TAC `C:real` o MATCH_MP LINEAR_BOUNDED_POS) THEN
7911   EXISTS_TAC `B * C:real` THEN ASM_SIMP_TAC[REAL_LT_MUL] THEN
7912   MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN
7913   STRIP_TAC THEN REWRITE_TAC[o_THM] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
7914   EXISTS_TAC `sum d (\k. C * norm((f:(real^M->bool)->real^N) k))` THEN
7915   CONJ_TAC THENL
7916    [MATCH_MP_TAC SUM_LE THEN ASM_MESON_TAC[DIVISION_OF_FINITE];
7917     GEN_REWRITE_TAC RAND_CONV [REAL_MUL_SYM] THEN
7918     REWRITE_TAC[SUM_LMUL] THEN ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN
7919     ASM_MESON_TAC[]]);;
7920
7921 let HAS_BOUNDED_SETVARIATION_ON_0 = prove
7922  (`!s:real^N->bool. (\x. vec 0) has_bounded_setvariation_on s`,
7923   REWRITE_TAC[has_bounded_setvariation_on; NORM_0; SUM_0] THEN
7924   MESON_TAC[REAL_LE_REFL]);;
7925
7926 let SET_VARIATION_0 = prove
7927  (`!s:real^N->bool. set_variation s (\x. vec 0) = &0`,
7928   GEN_TAC THEN REWRITE_TAC[set_variation; NORM_0; SUM_0] THEN
7929   GEN_REWRITE_TAC RAND_CONV [GSYM SUP_SING] THEN
7930   AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_SING] THEN
7931   MESON_TAC[ELEMENTARY_EMPTY; EMPTY_SUBSET]);;
7932
7933 let HAS_BOUNDED_SETVARIATION_ON_CMUL = prove
7934  (`!f:(real^M->bool)->real^N c s.
7935         f has_bounded_setvariation_on s
7936         ==> (\x. c % f x) has_bounded_setvariation_on s`,
7937   REPEAT GEN_TAC THEN
7938   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT; o_DEF]
7939      HAS_BOUNDED_SETVARIATION_ON_COMPOSE_LINEAR) THEN
7940   REWRITE_TAC[linear] THEN VECTOR_ARITH_TAC);;
7941
7942 let HAS_BOUNDED_SETVARIATION_ON_NEG = prove
7943  (`!f:(real^M->bool)->real^N s.
7944         f has_bounded_setvariation_on s
7945         ==> (\x. --(f x)) has_bounded_setvariation_on s`,
7946   REWRITE_TAC[VECTOR_ARITH `--x:real^N = -- &1 % x`] THEN
7947   REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_CMUL]);;
7948
7949 let HAS_BOUNDED_SETVARIATION_ON_ADD = prove
7950  (`!f:(real^M->bool)->real^N g s.
7951         f has_bounded_setvariation_on s /\
7952         g has_bounded_setvariation_on s
7953         ==> (\x. f x + g x) has_bounded_setvariation_on s`,
7954   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_setvariation_on] THEN
7955   DISCH_THEN(CONJUNCTS_THEN2
7956    (X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC)
7957    (X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC)) THEN
7958   EXISTS_TAC `B + C:real` THEN
7959   MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN
7960   STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
7961   EXISTS_TAC `sum d (\k. norm((f:(real^M->bool)->real^N) k)) +
7962               sum d (\k. norm((g:(real^M->bool)->real^N) k))` THEN
7963   CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LE_ADD2]] THEN
7964   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
7965   ASM_SIMP_TAC[GSYM SUM_ADD] THEN
7966   MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[NORM_TRIANGLE]);;
7967
7968 let HAS_BOUNDED_SETVARIATION_ON_SUB = prove
7969  (`!f:(real^M->bool)->real^N g s.
7970         f has_bounded_setvariation_on s /\
7971         g has_bounded_setvariation_on s
7972         ==> (\x. f x - g x) has_bounded_setvariation_on s`,
7973   REWRITE_TAC[VECTOR_ARITH `x - y:real^N = x + --y`] THEN
7974   SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_ADD; HAS_BOUNDED_SETVARIATION_ON_NEG]);;
7975
7976 let HAS_BOUNDED_SETVARIATION_ON_NULL = prove
7977  (`!f:(real^M->bool)->real^N s.
7978         (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = vec 0) /\
7979         content s = &0 /\ bounded s
7980         ==> f has_bounded_setvariation_on s`,
7981   REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_setvariation_on] THEN
7982   EXISTS_TAC `&0` THEN REPEAT STRIP_TAC THEN
7983   MATCH_MP_TAC(REAL_ARITH `x = &0 ==> x <= &0`) THEN
7984   MATCH_MP_TAC SUM_EQ_0 THEN REWRITE_TAC[NORM_EQ_0] THEN
7985   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
7986   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
7987   MATCH_MP_TAC CONTENT_0_SUBSET_GEN THEN
7988   EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN
7989   ASM_MESON_TAC[division_of; SUBSET_TRANS]);;
7990
7991 let SET_VARIATION_ELEMENTARY_LEMMA = prove
7992  (`!f:(real^M->bool)->real^N s.
7993         (?d. d division_of s)
7994         ==> ((!d t. d division_of t /\ t SUBSET s
7995                     ==> sum d (\k. norm(f k)) <= b) <=>
7996              (!d. d division_of s ==> sum d (\k. norm(f k)) <= b))`,
7997   REPEAT GEN_TAC THEN DISCH_THEN(X_CHOOSE_TAC `d1:(real^M->bool)->bool`) THEN
7998   EQ_TAC THENL [MESON_TAC[SUBSET_REFL]; ALL_TAC] THEN
7999   DISCH_TAC THEN X_GEN_TAC `d2:(real^M->bool)->bool` THEN
8000   X_GEN_TAC `t:real^M->bool` THEN STRIP_TAC THEN MP_TAC(ISPECL
8001    [`d2:(real^M->bool)->bool`; `d1:(real^M->bool)->bool`;
8002     `t:real^M->bool`; `s:real^M->bool`] PARTIAL_DIVISION_EXTEND) THEN
8003   ASM_REWRITE_TAC[] THEN
8004   DISCH_THEN(X_CHOOSE_TAC `d3:(real^M->bool)->bool`) THEN
8005   MATCH_MP_TAC REAL_LE_TRANS THEN
8006   EXISTS_TAC `sum d3 (\k:real^M->bool. norm(f k:real^N))` THEN
8007   ASM_SIMP_TAC[] THEN MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN
8008   ASM_REWRITE_TAC[NORM_POS_LE] THEN ASM_MESON_TAC[DIVISION_OF_FINITE]);;
8009
8010 let SET_VARIATION_ON_ELEMENTARY = prove
8011  (`!f:(real^M->bool)->real^N s.
8012         (?d. d division_of s)
8013         ==> set_variation s f =
8014              sup { sum d (\k. norm(f k)) | d division_of s}`,
8015   REPEAT GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[set_variation; sup] THEN
8016   REWRITE_TAC[FORALL_IN_GSPEC; LEFT_IMP_EXISTS_THM] THEN
8017   ASM_SIMP_TAC[SET_VARIATION_ELEMENTARY_LEMMA]);;
8018
8019 let SET_VARIATION_ON_INTERVAL = prove
8020  (`!f:(real^M->bool)->real^N a b.
8021         set_variation (interval[a,b]) f =
8022         sup { sum d (\k. norm(f k)) | d division_of interval[a,b]}`,
8023   REPEAT GEN_TAC THEN MATCH_MP_TAC SET_VARIATION_ON_ELEMENTARY THEN
8024   REWRITE_TAC[ELEMENTARY_INTERVAL]);;
8025
8026 let HAS_BOUNDED_SETVARIATION_WORKS = prove
8027  (`!f:(real^M->bool)->real^N s.
8028         f has_bounded_setvariation_on s
8029         ==> (!d t. d division_of t /\ t SUBSET s
8030                    ==> sum d (\k. norm(f k)) <= set_variation s f) /\
8031             (!B. (!d t. d division_of t /\ t SUBSET s
8032                         ==> sum d (\k. norm (f k)) <= B)
8033                  ==> set_variation s f <= B)`,
8034   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_setvariation_on] THEN
8035   DISCH_TAC THEN
8036   MP_TAC(ISPEC `{ sum d (\k. norm((f:(real^M->bool)->real^N) k)) |
8037                   ?t. d division_of t /\ t SUBSET s}`
8038          SUP) THEN
8039   REWRITE_TAC[FORALL_IN_GSPEC; LEFT_IMP_EXISTS_THM] THEN
8040   REWRITE_TAC[set_variation] THEN DISCH_THEN MATCH_MP_TAC THEN
8041   ASM_REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
8042   MAP_EVERY EXISTS_TAC [`&0`; `{}:(real^M->bool)->bool`] THEN
8043   REWRITE_TAC[SUM_CLAUSES] THEN EXISTS_TAC `{}:real^M->bool` THEN
8044   SIMP_TAC[division_of; EMPTY_SUBSET; NOT_IN_EMPTY; FINITE_EMPTY; UNIONS_0]);;
8045
8046 let HAS_BOUNDED_SETVARIATION_WORKS_ON_ELEMENTARY = prove
8047  (`!f:(real^M->bool)->real^N s.
8048         f has_bounded_setvariation_on s /\ (?d. d division_of s)
8049         ==> (!d. d division_of s
8050                  ==> sum d (\k. norm(f k)) <= set_variation s f) /\
8051             (!B. (!d. d division_of s ==> sum d (\k. norm(f k)) <= B)
8052                  ==> set_variation s f <= B)`,
8053   SIMP_TAC[GSYM SET_VARIATION_ELEMENTARY_LEMMA] THEN
8054   MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS]);;
8055
8056 let HAS_BOUNDED_SETVARIATION_WORKS_ON_INTERVAL = prove
8057  (`!f:(real^M->bool)->real^N a b.
8058       f has_bounded_setvariation_on interval[a,b]
8059       ==> (!d. d division_of interval[a,b]
8060                ==> sum d (\k. norm(f k)) <= set_variation (interval[a,b]) f) /\
8061           (!B. (!d. d division_of interval[a,b]
8062                     ==> sum d (\k. norm(f k)) <= B)
8063                ==> set_variation (interval[a,b]) f <= B)`,
8064   SIMP_TAC[HAS_BOUNDED_SETVARIATION_WORKS_ON_ELEMENTARY; ELEMENTARY_INTERVAL]);;
8065
8066 let SET_VARIATION_UBOUND = prove
8067  (`!f:(real^M->bool)->real^N s B.
8068         f has_bounded_setvariation_on s /\
8069         (!d t. d division_of t /\ t SUBSET s ==> sum d (\k. norm(f k)) <= B)
8070         ==> set_variation s f <= B`,
8071   MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS]);;
8072
8073 let SET_VARIATION_UBOUND_ON_INTERVAL = prove
8074  (`!f:(real^M->bool)->real^N a b B.
8075         f has_bounded_setvariation_on interval[a,b] /\
8076         (!d. d division_of interval[a,b] ==> sum d (\k. norm(f k)) <= B)
8077         ==> set_variation (interval[a,b]) f <= B`,
8078   SIMP_TAC[GSYM SET_VARIATION_ELEMENTARY_LEMMA; ELEMENTARY_INTERVAL] THEN
8079   MESON_TAC[SET_VARIATION_UBOUND]);;
8080
8081 let SET_VARIATION_LBOUND = prove
8082  (`!f:(real^M->bool)->real^N s B.
8083         f has_bounded_setvariation_on s /\
8084         (?d t. d division_of t /\ t SUBSET s /\ B <= sum d (\k. norm(f k)))
8085         ==> B <= set_variation s f`,
8086   MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS; REAL_LE_TRANS]);;
8087
8088 let SET_VARIATION_LBOUND_ON_INTERVAL = prove
8089  (`!f:(real^M->bool)->real^N a b B.
8090         f has_bounded_setvariation_on interval[a,b] /\
8091         (?d. d division_of interval[a,b] /\ B <= sum d (\k. norm(f k)))
8092         ==> B <= set_variation (interval[a,b]) f`,
8093   MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS_ON_INTERVAL; REAL_LE_TRANS]);;
8094
8095 let SET_VARIATION = prove
8096  (`!f:(real^M->bool)->real^N s d t.
8097         f has_bounded_setvariation_on s /\ d division_of t /\ t SUBSET s
8098         ==> sum d (\k. norm(f k)) <= set_variation s f`,
8099   MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS]);;
8100
8101 let SET_VARIATION_WORKS_ON_INTERVAL = prove
8102  (`!f:(real^M->bool)->real^N a b d.
8103         f has_bounded_setvariation_on interval[a,b] /\
8104         d division_of interval[a,b]
8105         ==> sum d (\k. norm(f k)) <= set_variation (interval[a,b]) f`,
8106   MESON_TAC[HAS_BOUNDED_SETVARIATION_WORKS_ON_INTERVAL]);;
8107
8108 let SET_VARIATION_POS_LE = prove
8109  (`!f:(real^M->bool)->real^N s.
8110         f has_bounded_setvariation_on s ==> &0 <= set_variation s f`,
8111   REPEAT STRIP_TAC THEN
8112   FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] SET_VARIATION)) THEN
8113   DISCH_THEN(MP_TAC o SPECL[`{}:(real^M->bool)->bool`; `{}:real^M->bool`]) THEN
8114   REWRITE_TAC[EMPTY_SUBSET; SUM_CLAUSES; DIVISION_OF_TRIVIAL]);;
8115
8116 let SET_VARIATION_GE_FUNCTION = prove
8117  (`!f:(real^M->bool)->real^N s a b.
8118         f has_bounded_setvariation_on s /\
8119         interval[a,b] SUBSET s /\ ~(interval[a,b] = {})
8120         ==> norm(f(interval[a,b])) <= set_variation s f`,
8121   REPEAT STRIP_TAC THEN MATCH_MP_TAC SET_VARIATION_LBOUND THEN
8122   ASM_REWRITE_TAC[] THEN EXISTS_TAC `{interval[a:real^M,b]}` THEN
8123   EXISTS_TAC `interval[a:real^M,b]` THEN
8124   ASM_REWRITE_TAC[SUM_SING; REAL_LE_REFL] THEN
8125   ASM_SIMP_TAC[DIVISION_OF_SELF]);;
8126
8127 let SET_VARIATION_ON_NULL = prove
8128  (`!f:(real^M->bool)->real^N s.
8129         (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = vec 0) /\
8130         content s = &0 /\ bounded s
8131         ==> set_variation s f = &0`,
8132   REPEAT STRIP_TAC THEN
8133   ONCE_REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
8134    [MATCH_MP_TAC SET_VARIATION_UBOUND THEN
8135     ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_NULL] THEN
8136     REPEAT STRIP_TAC THEN
8137     MATCH_MP_TAC(REAL_ARITH `x = &0 ==> x <= &0`) THEN
8138     MATCH_MP_TAC SUM_EQ_0 THEN REWRITE_TAC[NORM_EQ_0] THEN
8139     FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
8140     REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
8141     MATCH_MP_TAC CONTENT_0_SUBSET_GEN THEN
8142     EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[] THEN
8143     ASM_MESON_TAC[division_of; SUBSET_TRANS];
8144     MATCH_MP_TAC SET_VARIATION_POS_LE THEN
8145     ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_NULL]]);;
8146
8147 let SET_VARIATION_TRIANGLE = prove
8148  (`!f:(real^M->bool)->real^N g s.
8149         f has_bounded_setvariation_on s /\
8150         g has_bounded_setvariation_on s
8151         ==> set_variation s (\x. f x + g x)
8152              <= set_variation s f + set_variation s g`,
8153   REPEAT STRIP_TAC THEN MATCH_MP_TAC SET_VARIATION_UBOUND THEN
8154   ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_ADD] THEN
8155   MAP_EVERY X_GEN_TAC [`d:(real^M->bool)->bool`; `t:real^M->bool`] THEN
8156   STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
8157   EXISTS_TAC `sum d (\k. norm((f:(real^M->bool)->real^N) k)) +
8158               sum d (\k. norm((g:(real^M->bool)->real^N) k))` THEN
8159   CONJ_TAC THENL
8160    [FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
8161     ASM_SIMP_TAC[GSYM SUM_ADD] THEN
8162     MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[NORM_TRIANGLE];
8163     MATCH_MP_TAC REAL_LE_ADD2 THEN
8164     CONJ_TAC THEN MATCH_MP_TAC SET_VARIATION THEN ASM_MESON_TAC[]]);;
8165
8166 let OPERATIVE_LIFTED_SETVARIATION = prove
8167  (`!f:(real^M->bool)->real^N.
8168         operative(+) f
8169         ==> operative (lifted(+))
8170                       (\i. if f has_bounded_setvariation_on i
8171                            then SOME(set_variation i f) else NONE)`,
8172   let lemma1 = prove
8173    (`!f:(real^M->bool)->real B1 B2 k a b.
8174       1 <= k /\ k <= dimindex(:M) /\
8175       (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = &0) /\
8176       (!a b c. f(interval[a,b]) <=
8177                f(interval[a,b] INTER {x | x$k <= c}) +
8178                f(interval[a,b] INTER {x | x$k >= c})) /\
8179       (!d. d division_of (interval[a,b] INTER {x | x$k <= c})
8180            ==> sum d f <= B1) /\
8181       (!d. d division_of (interval[a,b] INTER {x | x$k >= c})
8182            ==> sum d f <= B2)
8183       ==> !d. d division_of interval[a,b] ==> sum d f <= B1 + B2`,
8184     REPEAT GEN_TAC THEN
8185     REPLICATE_TAC 4 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
8186     DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "L") (LABEL_TAC "R")) THEN
8187     GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
8188     EXISTS_TAC
8189      `sum {l INTER {x:real^M | x$k <= c} | l | l IN d /\
8190                                         ~(l INTER {x | x$k <= c} = {})} f +
8191       sum {l INTER {x | x$k >= c} | l | l IN d /\
8192                                         ~(l INTER {x | x$k >= c} = {})} f` THEN
8193     CONJ_TAC THENL
8194      [ALL_TAC;
8195       MATCH_MP_TAC REAL_LE_ADD2 THEN CONJ_TAC THEN
8196       FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[DIVISION_SPLIT]] THEN
8197     ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
8198     FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
8199     W(fun (asl,w) ->
8200          MP_TAC(PART_MATCH (lhs o rand) SUM_IMAGE_NONZERO (lhand(rand w))) THEN
8201          MP_TAC(PART_MATCH (lhs o rand) SUM_IMAGE_NONZERO (rand(rand w)))) THEN
8202     MATCH_MP_TAC(TAUT
8203      `(a1 /\ a2) /\ (b1 /\ b2 ==> c)
8204       ==> (a1 ==> b1) ==> (a2 ==> b2) ==> c`) THEN
8205     CONJ_TAC THENL
8206      [ASM_SIMP_TAC[FINITE_RESTRICT; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
8207       REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ] THEN
8208       FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
8209       REPEAT STRIP_TAC THEN ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
8210       FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THENL
8211        [MATCH_MP_TAC DIVISION_SPLIT_RIGHT_INJ;
8212         MATCH_MP_TAC DIVISION_SPLIT_LEFT_INJ] THEN
8213       ASM_MESON_TAC[];
8214       DISCH_THEN(CONJUNCTS_THEN SUBST1_TAC)] THEN
8215     MATCH_MP_TAC REAL_LE_TRANS THEN
8216     EXISTS_TAC
8217      `sum d (f o (\l. l INTER {x | x$k <= c})) +
8218       sum d (f o (\l. l INTER {x:real^M | x$k >= c}))` THEN
8219     CONJ_TAC THENL
8220      [ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN
8221       ASM_REWRITE_TAC[o_THM] THEN
8222       FIRST_ASSUM(fun th -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]);
8223       MATCH_MP_TAC(REAL_ARITH `x = y /\ w = z ==> x + w <= y + z`) THEN
8224       CONJ_TAC THEN MATCH_MP_TAC SUM_SUPERSET THEN
8225       REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} SUBSET s`] THEN
8226       REWRITE_TAC[SET_RULE `(x IN s /\ ~(x IN {x | x IN s /\ ~P x}) ==> Q x) <=>
8227                             (x IN s ==> P x ==> Q x)`] THEN
8228       SIMP_TAC[o_THM] THEN ASM_MESON_TAC[EMPTY_AS_INTERVAL; CONTENT_EMPTY]])
8229   and lemma2 = prove
8230    (`!f:(real^M->bool)->real B k.
8231       1 <= k /\ k <= dimindex(:M) /\
8232       (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = &0) /\
8233       (!d. d division_of interval[a,b] ==> sum d f <= B)
8234       ==> !d1 d2. d1 division_of (interval[a,b] INTER {x | x$k <= c}) /\
8235                   d2 division_of (interval[a,b] INTER {x | x$k >= c})
8236                   ==> sum d1 f + sum d2 f <= B`,
8237     REPEAT STRIP_TAC THEN
8238     FIRST_X_ASSUM(MP_TAC o SPEC `d1 UNION d2:(real^M->bool)->bool`) THEN
8239     ANTS_TAC THENL
8240      [SUBGOAL_THEN
8241        `interval[a,b] = (interval[a,b] INTER {x:real^M | x$k <= c}) UNION
8242                         (interval[a,b] INTER {x:real^M | x$k >= c})`
8243       SUBST1_TAC THENL
8244        [MATCH_MP_TAC(SET_RULE
8245          `(!x. x IN t \/ x IN u) ==> (s = s INTER t UNION s INTER u)`) THEN
8246         REWRITE_TAC[IN_ELIM_THM] THEN REAL_ARITH_TAC;
8247         MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN ASM_REWRITE_TAC[] THEN
8248         REWRITE_TAC[GSYM INTERIOR_INTER] THEN
8249         MATCH_MP_TAC(SET_RULE
8250          `!t. interior s SUBSET interior t /\ interior t = {}
8251               ==> interior s = {}`) THEN
8252         EXISTS_TAC `{x:real^M | x$k = c}` THEN CONJ_TAC THENL
8253          [ALL_TAC; REWRITE_TAC[INTERIOR_STANDARD_HYPERPLANE]] THEN
8254         MATCH_MP_TAC SUBSET_INTERIOR THEN
8255         REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN REAL_ARITH_TAC];
8256       MATCH_MP_TAC(REAL_ARITH `x = y ==> x <= b ==> y <= b`) THEN
8257       MATCH_MP_TAC SUM_UNION_NONZERO THEN
8258       REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_FINITE]; ALL_TAC]) THEN
8259       X_GEN_TAC `k:real^M->bool` THEN REWRITE_TAC[IN_INTER] THEN STRIP_TAC THEN
8260       SUBGOAL_THEN `?u v:real^M. k = interval[u,v]`
8261         (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
8262       THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
8263       FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC CONTENT_0_SUBSET_GEN THEN
8264       EXISTS_TAC `interval[a,b] INTER {x:real^M | x$k = c}` THEN CONJ_TAC THENL
8265        [MATCH_MP_TAC SUBSET_TRANS THEN
8266         EXISTS_TAC `(interval[a,b] INTER {x:real^M | x$k <= c}) INTER
8267                     (interval[a,b] INTER {x:real^M | x$k >= c})` THEN
8268         CONJ_TAC THENL
8269          [ONCE_REWRITE_TAC[SUBSET_INTER] THEN ASM_MESON_TAC[division_of];
8270           REWRITE_TAC[SET_RULE
8271             `(s INTER t) INTER (s INTER u) = s INTER t INTER u`] THEN
8272           SIMP_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN REAL_ARITH_TAC];
8273         SIMP_TAC[BOUNDED_INTER; BOUNDED_INTERVAL] THEN
8274         GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
8275          [REAL_ARITH `x = y <=> x <= y /\ x >= y`] THEN
8276         REWRITE_TAC[SET_RULE
8277          `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN
8278         ASM_SIMP_TAC[GSYM INTER_ASSOC; INTERVAL_SPLIT] THEN
8279         REWRITE_TAC[CONTENT_EQ_0] THEN EXISTS_TAC `k:num` THEN
8280         ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC]]) in
8281   REWRITE_TAC[operative; NEUTRAL_VECTOR_ADD] THEN REPEAT GEN_TAC THEN
8282   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (ASSUME_TAC o GSYM)) THEN
8283   ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_NULL; BOUNDED_INTERVAL;
8284    MONOIDAL_REAL_ADD; SET_VARIATION_ON_NULL; NEUTRAL_LIFTED;
8285    NEUTRAL_REAL_ADD] THEN
8286   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real`; `k:num`] THEN
8287   STRIP_TAC THEN ASM_CASES_TAC
8288    `(f:(real^M->bool)->real^N) has_bounded_setvariation_on interval[a,b]` THEN
8289   ASM_REWRITE_TAC[] THENL
8290    [SUBGOAL_THEN
8291      `(f:(real^M->bool)->real^N) has_bounded_setvariation_on
8292       interval[a,b] INTER {x | x$k <= c} /\
8293       (f:(real^M->bool)->real^N) has_bounded_setvariation_on
8294       interval[a,b] INTER {x | x$k >= c}`
8295     ASSUME_TAC THENL
8296      [CONJ_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
8297        (REWRITE_RULE[IMP_CONJ] HAS_BOUNDED_SETVARIATION_ON_SUBSET)) THEN
8298       REWRITE_TAC[INTER_SUBSET];
8299       ALL_TAC] THEN
8300     ASM_REWRITE_TAC[lifted] THEN AP_TERM_TAC THEN
8301     REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
8302      [MATCH_MP_TAC SET_VARIATION_UBOUND_ON_INTERVAL THEN ASM_REWRITE_TAC[] THEN
8303       REPEAT STRIP_TAC THEN MATCH_MP_TAC
8304        (REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM] lemma1) THEN
8305       MAP_EVERY EXISTS_TAC [`k:num`; `a:real^M`; `b:real^M`] THEN
8306       ASM_SIMP_TAC[NORM_0] THEN CONJ_TAC THENL
8307        [REPEAT GEN_TAC THEN
8308         MATCH_MP_TAC(NORM_ARITH
8309           `x:real^N = y + z ==> norm(x) <= norm y + norm z`) THEN
8310         ASM_SIMP_TAC[];
8311         FIRST_X_ASSUM(fun th -> MP_TAC th THEN MATCH_MP_TAC MONO_AND) THEN
8312         ASM_SIMP_TAC[INTERVAL_SPLIT; SET_VARIATION_WORKS_ON_INTERVAL]];
8313       ONCE_REWRITE_TAC[REAL_ARITH `x + y <= z <=> x <= z - y`] THEN
8314       ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
8315       MATCH_MP_TAC SET_VARIATION_UBOUND_ON_INTERVAL THEN
8316       ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THEN
8317       X_GEN_TAC `d1:(real^M->bool)->bool` THEN STRIP_TAC THEN
8318       ONCE_REWRITE_TAC[REAL_ARITH `x <= y - z <=> z <= y - x`] THEN
8319       ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
8320       MATCH_MP_TAC SET_VARIATION_UBOUND_ON_INTERVAL THEN
8321       ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THEN
8322       X_GEN_TAC `d2:(real^M->bool)->bool` THEN STRIP_TAC THEN
8323       REWRITE_TAC[REAL_ARITH `x <= y - z <=> z + x <= y`] THEN
8324       REPEAT STRIP_TAC THEN MATCH_MP_TAC
8325        (REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM] lemma2) THEN
8326       EXISTS_TAC `k:num` THEN
8327       ASM_SIMP_TAC[NORM_0; SET_VARIATION_WORKS_ON_INTERVAL]];
8328     REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[lifted]) THEN
8329     FIRST_X_ASSUM(MP_TAC o check (is_neg o concl)) THEN
8330     MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN
8331     REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_INTERVAL] THEN
8332     EXISTS_TAC `set_variation (interval[a,b] INTER {x | x$k <= c})
8333                               (f:(real^M->bool)->real^N) +
8334                 set_variation (interval[a,b] INTER {x | x$k >= c}) f` THEN
8335     REPEAT STRIP_TAC THEN MATCH_MP_TAC
8336        (REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM] lemma1) THEN
8337       MAP_EVERY EXISTS_TAC [`k:num`; `a:real^M`; `b:real^M`] THEN
8338       ASM_SIMP_TAC[NORM_0] THEN REPEAT CONJ_TAC THENL
8339        [REPEAT GEN_TAC THEN
8340         MATCH_MP_TAC(NORM_ARITH
8341           `x:real^N = y + z ==> norm(x) <= norm y + norm z`) THEN
8342         ASM_SIMP_TAC[];
8343         UNDISCH_TAC
8344          `(f:(real^M->bool)->real^N) has_bounded_setvariation_on
8345           (interval[a,b] INTER {x | x$k <= c})` THEN
8346         ASM_SIMP_TAC[INTERVAL_SPLIT; SET_VARIATION_WORKS_ON_INTERVAL];
8347         UNDISCH_TAC
8348          `(f:(real^M->bool)->real^N) has_bounded_setvariation_on
8349           (interval[a,b] INTER {x | x$k >= c})` THEN
8350         ASM_SIMP_TAC[INTERVAL_SPLIT; SET_VARIATION_WORKS_ON_INTERVAL]]]);;
8351
8352 let HAS_BOUNDED_SETVARIATION_ON_DIVISION = prove
8353  (`!f:(real^M->bool)->real^N a b d.
8354         operative (+) f /\ d division_of interval[a,b]
8355         ==> ((!k. k IN d ==> f has_bounded_setvariation_on k) <=>
8356              f has_bounded_setvariation_on interval[a,b])`,
8357   REPEAT STRIP_TAC THEN MATCH_MP_TAC OPERATIVE_DIVISION_AND THEN
8358   ASM_REWRITE_TAC[operative; NEUTRAL_AND] THEN CONJ_TAC THENL
8359    [RULE_ASSUM_TAC(REWRITE_RULE[operative; NEUTRAL_VECTOR_ADD]) THEN
8360     ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_NULL; BOUNDED_INTERVAL];
8361     FIRST_ASSUM(MP_TAC o MATCH_MP OPERATIVE_LIFTED_SETVARIATION) THEN
8362     REWRITE_TAC[operative] THEN DISCH_THEN(MP_TAC o CONJUNCT2) THEN
8363     REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
8364     REPEAT(COND_CASES_TAC THEN
8365            ASM_REWRITE_TAC[lifted; distinctness "option"])]);;
8366
8367 let SET_VARIATION_ON_DIVISION = prove
8368  (`!f:(real^M->bool)->real^N a b d.
8369         operative (+) f /\ d division_of interval[a,b] /\
8370         f has_bounded_setvariation_on interval[a,b]
8371         ==> sum d (\k. set_variation k f) = set_variation (interval[a,b]) f`,
8372   let lemma0 = prove
8373    (`!op x y. lifted op (SOME x) y = SOME z <=> ?w. y = SOME w /\ op x w = z`,
8374     GEN_TAC THEN GEN_TAC THEN MATCH_MP_TAC option_INDUCT THEN
8375     REWRITE_TAC[lifted; distinctness "option"; injectivity "option"] THEN
8376     MESON_TAC[]) in
8377   let lemma = prove
8378    (`!P op f s z.
8379           monoidal op /\ FINITE s /\
8380           iterate(lifted op) s (\i. if P i then SOME(f i) else NONE) = SOME z
8381           ==> iterate op s f = z`,
8382     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
8383     REPEAT GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
8384     MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
8385     ASM_SIMP_TAC[ITERATE_CLAUSES; MONOIDAL_LIFTED; NEUTRAL_LIFTED] THEN
8386     REWRITE_TAC[injectivity "option"] THEN REPEAT GEN_TAC THEN
8387     STRIP_TAC THEN GEN_TAC THEN COND_CASES_TAC THEN
8388     REWRITE_TAC[lifted; distinctness "option"] THEN ASM_MESON_TAC[lemma0]) in
8389   REPEAT STRIP_TAC THEN
8390   FIRST_ASSUM(MP_TAC o MATCH_MP OPERATIVE_LIFTED_SETVARIATION) THEN
8391   DISCH_THEN(MP_TAC o SPECL[`d:(real^M->bool)->bool`; `a:real^M`; `b:real^M`] o
8392     MATCH_MP (REWRITE_RULE [TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`]
8393         OPERATIVE_DIVISION)) THEN
8394   ASM_SIMP_TAC[MONOIDAL_LIFTED; MONOIDAL_REAL_ADD] THEN
8395   MP_TAC(ISPECL
8396    [`\k. (f:(real^M->bool)->real^N) has_bounded_setvariation_on k`;
8397     `(+):real->real->real`;
8398     `\k. set_variation k (f:(real^M->bool)->real^N)`;
8399     `d:(real^M->bool)->bool`;
8400     `set_variation (interval[a,b]) (f:(real^M->bool)->real^N)`]
8401    lemma) THEN
8402   FIRST_X_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
8403   ASM_REWRITE_TAC[sum; MONOIDAL_REAL_ADD]);;
8404
8405 let SET_VARIATION_MONOTONE = prove
8406  (`!f:(real^M->bool)->real^N s t.
8407         f has_bounded_setvariation_on s /\ t SUBSET s
8408         ==> set_variation t f <= set_variation s f`,
8409   REPEAT STRIP_TAC THEN REWRITE_TAC[set_variation] THEN
8410   MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN REPEAT CONJ_TAC THENL
8411    [REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
8412     MAP_EVERY EXISTS_TAC [`&0`; `{}:(real^M->bool)->bool`] THEN
8413     REWRITE_TAC[SUM_CLAUSES] THEN EXISTS_TAC `{}:real^M->bool` THEN
8414     REWRITE_TAC[EMPTY_SUBSET; DIVISION_OF_TRIVIAL];
8415     MATCH_MP_TAC(SET_RULE
8416      `(!d. P d ==> Q d) ==> {f d | P d} SUBSET {f d | Q d}`) THEN
8417     ASM_MESON_TAC[SUBSET_TRANS];
8418     REWRITE_TAC[FORALL_IN_GSPEC; LEFT_IMP_EXISTS_THM] THEN
8419     ASM_REWRITE_TAC[GSYM has_bounded_setvariation_on]]);;
8420
8421 let HAS_BOUNDED_SETVARIATION_REFLECT2_EQ,SET_VARIATION_REFLECT2 =
8422  (CONJ_PAIR o prove)
8423  (`(!f:(real^M->bool)->real^N s.
8424         (\k. f(IMAGE (--) k)) has_bounded_setvariation_on (IMAGE (--) s) <=>
8425         f has_bounded_setvariation_on s) /\
8426    (!f:(real^M->bool)->real^N s.
8427         set_variation (IMAGE (--) s) (\k. f(IMAGE (--) k)) =
8428         set_variation s f)`,
8429   MATCH_MP_TAC SETVARIATION_EQUAL_LEMMA THEN
8430   EXISTS_TAC `IMAGE ((--):real^M->real^M)` THEN
8431   SIMP_TAC[IMAGE_SUBSET; GSYM IMAGE_o; o_DEF] THEN
8432   REWRITE_TAC[VECTOR_NEG_NEG; IMAGE_ID; REFLECT_INTERVAL] THEN
8433   SIMP_TAC[ETA_AX; DIVISION_OF_REFLECT] THEN
8434   SIMP_TAC[EQ_INTERVAL; TAUT `~q /\ (p /\ q \/ r) <=> ~q /\ r`] THEN
8435   REWRITE_TAC[TAUT `p /\ q /\ r <=> r /\ q /\ p`] THEN
8436   REWRITE_TAC[UNWIND_THM1; CONTRAPOS_THM] THEN
8437   REWRITE_TAC[INTERVAL_EQ_EMPTY; VECTOR_NEG_COMPONENT; REAL_LT_NEG2]);;
8438
8439 let HAS_BOUNDED_SETVARIATION_TRANSLATION2_EQ, SET_VARIATION_TRANSLATION2 =
8440  (CONJ_PAIR o prove)
8441  (`(!a f:(real^M->bool)->real^N s.
8442           (\k. f(IMAGE (\x. a + x) k))
8443           has_bounded_setvariation_on (IMAGE (\x. --a + x) s) <=>
8444           f has_bounded_setvariation_on s) /\
8445    (!a f:(real^M->bool)->real^N s.
8446           set_variation (IMAGE (\x. --a + x) s) (\k. f(IMAGE (\x. a + x) k)) =
8447           set_variation s f)`,
8448   GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `a:real^M` THEN
8449   MATCH_MP_TAC SETVARIATION_EQUAL_LEMMA THEN
8450   EXISTS_TAC `\s. IMAGE (\x:real^M. a + x) s` THEN
8451   SIMP_TAC[IMAGE_SUBSET; GSYM IMAGE_o; o_DEF] THEN
8452   REWRITE_TAC[VECTOR_ARITH `a + --a + x:real^N = x`; IMAGE_ID;
8453               VECTOR_ARITH `--a + a + x:real^N = x`] THEN
8454   REWRITE_TAC[GSYM INTERVAL_TRANSLATION] THEN
8455   SIMP_TAC[EQ_INTERVAL; TAUT `~q /\ (p /\ q \/ r) <=> ~q /\ r`] THEN
8456   REWRITE_TAC[TAUT `p /\ q /\ r <=> r /\ q /\ p`] THEN
8457   REWRITE_TAC[UNWIND_THM1; CONTRAPOS_THM] THEN
8458   REWRITE_TAC[INTERVAL_EQ_EMPTY; VECTOR_ADD_COMPONENT; REAL_LT_LADD] THEN
8459   REPEAT STRIP_TAC THEN
8460   GEN_REWRITE_TAC (LAND_CONV o LAND_CONV) [ETA_AX] THEN
8461   ASM_SIMP_TAC[DIVISION_OF_TRANSLATION]);;
8462
8463 let HAS_BOUNDED_SETVARIATION_TRANSLATION = prove
8464  (`!f:(real^M->bool)->real^N s a.
8465         f has_bounded_setvariation_on s
8466         ==> (\k. f(IMAGE (\x. a + x) k))
8467             has_bounded_setvariation_on (IMAGE (\x. --a + x) s)`,
8468   REWRITE_TAC[HAS_BOUNDED_SETVARIATION_TRANSLATION2_EQ]);;
8469
8470 (* ------------------------------------------------------------------------- *)
8471 (* Absolute integrability (this is the same as Lebesgue integrability).      *)
8472 (* ------------------------------------------------------------------------- *)
8473
8474 parse_as_infix("absolutely_integrable_on",(12,"right"));;
8475
8476 let absolutely_integrable_on = new_definition
8477  `f absolutely_integrable_on s <=>
8478         f integrable_on s /\ (\x. lift(norm(f x))) integrable_on s`;;
8479
8480 let ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE = prove
8481  (`!f s. f absolutely_integrable_on s ==> f integrable_on s`,
8482   SIMP_TAC[absolutely_integrable_on]);;
8483
8484 let ABSOLUTELY_INTEGRABLE_LE = prove
8485  (`!f:real^M->real^N s.
8486         f absolutely_integrable_on s
8487         ==> norm(integral s f) <= drop(integral s (\x. lift(norm(f x))))`,
8488   REWRITE_TAC[absolutely_integrable_on] THEN
8489   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
8490   ASM_REWRITE_TAC[LIFT_DROP; REAL_LE_REFL]);;
8491
8492 let ABSOLUTELY_INTEGRABLE_0 = prove
8493  (`!s. (\x. vec 0) absolutely_integrable_on s`,
8494   REWRITE_TAC[absolutely_integrable_on; NORM_0; LIFT_NUM; INTEGRABLE_0]);;
8495
8496 let ABSOLUTELY_INTEGRABLE_CMUL = prove
8497  (`!f s c. f absolutely_integrable_on s
8498            ==> (\x. c % f(x)) absolutely_integrable_on s`,
8499   SIMP_TAC[absolutely_integrable_on; INTEGRABLE_CMUL; NORM_MUL; LIFT_CMUL]);;
8500
8501 let ABSOLUTELY_INTEGRABLE_NEG = prove
8502  (`!f s. f absolutely_integrable_on s
8503          ==> (\x. --f(x)) absolutely_integrable_on s`,
8504   SIMP_TAC[absolutely_integrable_on; INTEGRABLE_NEG; NORM_NEG]);;
8505
8506 let ABSOLUTELY_INTEGRABLE_NORM = prove
8507  (`!f s. f absolutely_integrable_on s
8508          ==> (\x. lift(norm(f x))) absolutely_integrable_on s`,
8509   SIMP_TAC[absolutely_integrable_on; NORM_LIFT; REAL_ABS_NORM]);;
8510
8511 let ABSOLUTELY_INTEGRABLE_ABS_1 = prove
8512  (`!f s. f absolutely_integrable_on s
8513          ==> (\x. lift(abs(drop(f x)))) absolutely_integrable_on s`,
8514   REWRITE_TAC[GSYM NORM_LIFT; LIFT_DROP; ABSOLUTELY_INTEGRABLE_NORM]);;
8515
8516 let ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL = prove
8517  (`!f:real^M->real^N s a b.
8518         f absolutely_integrable_on s /\ interval[a,b] SUBSET s
8519         ==> f absolutely_integrable_on interval[a,b]`,
8520   REWRITE_TAC[absolutely_integrable_on] THEN
8521   MESON_TAC[INTEGRABLE_ON_SUBINTERVAL]);;
8522
8523 let ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION = prove
8524  (`!f:real^M->real^N s.
8525         f absolutely_integrable_on s
8526         ==> (\k. integral k f) has_bounded_setvariation_on s`,
8527   REWRITE_TAC[has_bounded_setvariation_on] THEN REPEAT STRIP_TAC THEN
8528   EXISTS_TAC
8529    `drop(integral (s:real^M->bool) (\x. lift(norm(f x:real^N))))` THEN
8530   X_GEN_TAC `d:(real^M->bool)->bool` THEN
8531   X_GEN_TAC `t:real^M->bool` THEN STRIP_TAC THEN
8532   SUBGOAL_THEN `(UNIONS d:real^M->bool) SUBSET s` ASSUME_TAC THENL
8533    [ASM_MESON_TAC[SUBSET_TRANS; division_of]; ALL_TAC] THEN
8534   MATCH_MP_TAC REAL_LE_TRANS THEN
8535   EXISTS_TAC
8536    `drop(integral (UNIONS d) (\x. lift(norm((f:real^M->real^N) x))))` THEN
8537   CONJ_TAC THENL
8538    [ALL_TAC;
8539     MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN
8540     ASM_REWRITE_TAC[LIFT_DROP; NORM_POS_LE] THEN CONJ_TAC THENL
8541      [MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
8542       EXISTS_TAC `s:real^M->bool` THEN
8543       EXISTS_TAC `d:(real^M->bool)->bool` THEN CONJ_TAC THENL
8544        [ASM_MESON_TAC[DIVISION_OF_SUBSET; division_of]; ALL_TAC] THEN
8545       ASM_REWRITE_TAC[];
8546       ALL_TAC] THEN
8547     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
8548     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN ASM_REWRITE_TAC[]] THEN
8549   MATCH_MP_TAC REAL_LE_TRANS THEN
8550   EXISTS_TAC
8551    `drop(vsum d (\i. integral i (\x:real^M. lift(norm(f x:real^N)))))` THEN
8552   CONJ_TAC THENL
8553    [FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
8554     ASM_SIMP_TAC[DROP_VSUM] THEN MATCH_MP_TAC SUM_LE THEN
8555     ASM_REWRITE_TAC[o_THM] THEN
8556     FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
8557     MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN
8558     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_LE THEN
8559     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL THEN
8560     EXISTS_TAC `s:real^M->bool` THEN ASM_MESON_TAC[division_of; SUBSET_TRANS];
8561     MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
8562     CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_TOPDOWN THEN
8563     CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[DIVISION_OF_UNION_SELF]] THEN
8564     MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
8565     MAP_EVERY EXISTS_TAC [`s:real^M->bool`; `d:(real^M->bool)->bool`] THEN
8566     CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_UNION_SELF]; ALL_TAC] THEN
8567     ASM_REWRITE_TAC[] THEN
8568     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
8569     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN ASM_REWRITE_TAC[]]);;
8570
8571 let lemma = prove
8572  (`!f:A->real^N g s e.
8573         sum s (\x. norm(f x - g x)) < e
8574         ==> FINITE s
8575             ==> abs(sum s (\x. norm(f x)) - sum s (\x. norm(g x))) < e`,
8576   REPEAT GEN_TAC THEN SIMP_TAC[GSYM SUM_SUB] THEN
8577   DISCH_THEN(fun th -> DISCH_TAC THEN MP_TAC th) THEN
8578   MATCH_MP_TAC(REAL_ARITH `x <= y ==> y < e ==> x < e`) THEN
8579   W(MP_TAC o PART_MATCH (lhand o rand) SUM_ABS o lhand o snd) THEN
8580   ASM_REWRITE_TAC[] THEN
8581   MATCH_MP_TAC(REAL_ARITH `y <= z ==> x <= y ==> x <= z`) THEN
8582   MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[] THEN
8583   REPEAT STRIP_TAC THEN NORM_ARITH_TAC);;
8584
8585 let BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE_INTERVAL = prove
8586  (`!f:real^M->real^N a b.
8587         f integrable_on interval[a,b] /\
8588         (\k. integral k f) has_bounded_setvariation_on interval[a,b]
8589         ==> f absolutely_integrable_on interval[a,b]`,
8590   REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_INTERVAL] THEN
8591   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[absolutely_integrable_on] THEN
8592   MP_TAC(ISPEC `IMAGE (\d. sum d (\k. norm(integral k (f:real^M->real^N))))
8593                       {d | d division_of interval[a,b] }`
8594          SUP) THEN
8595   REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
8596   REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
8597   ABBREV_TAC
8598    `i = sup (IMAGE (\d. sum d (\k. norm(integral k (f:real^M->real^N))))
8599                       {d | d division_of interval[a,b] })` THEN
8600   ANTS_TAC THENL
8601    [REWRITE_TAC[ELEMENTARY_INTERVAL] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
8602   STRIP_TAC THEN REWRITE_TAC[integrable_on] THEN EXISTS_TAC `lift i` THEN
8603   REWRITE_TAC[has_integral] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
8604   FIRST_X_ASSUM(MP_TAC o SPEC `i - e / &2`) THEN
8605   ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(i <= i - e / &2)`] THEN
8606   REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LE; LEFT_IMP_EXISTS_THM] THEN
8607   X_GEN_TAC `d:(real^M->bool)->bool` THEN STRIP_TAC THEN
8608   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
8609   SUBGOAL_THEN
8610    `!x. ?e. &0 < e /\
8611             !i. i IN d /\ ~(x IN i) ==> ball(x:real^M,e) INTER i = {}`
8612   MP_TAC THENL
8613    [X_GEN_TAC `x:real^M` THEN MP_TAC(ISPECL
8614      [`UNIONS {i:real^M->bool | i IN d /\ ~(x IN i)}`; `x:real^M`]
8615      SEPARATE_POINT_CLOSED) THEN
8616     ANTS_TAC THENL
8617      [CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN
8618       MATCH_MP_TAC CLOSED_UNIONS THEN
8619       ASM_SIMP_TAC[FINITE_RESTRICT; IN_ELIM_THM; IMP_CONJ] THEN
8620       FIRST_ASSUM(fun t -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN
8621       REWRITE_TAC[CLOSED_INTERVAL];
8622       ALL_TAC] THEN
8623     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real` THEN
8624     SIMP_TAC[FORALL_IN_UNIONS; EXTENSION; IN_INTER; NOT_IN_EMPTY; IN_BALL] THEN
8625     REWRITE_TAC[IN_ELIM_THM; DE_MORGAN_THM; REAL_NOT_LT] THEN MESON_TAC[];
8626     ALL_TAC] THEN
8627   REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN
8628   X_GEN_TAC `k:real^M->real` THEN STRIP_TAC THEN
8629   FIRST_ASSUM(MP_TAC o SPEC `e / &2` o MATCH_MP HENSTOCK_LEMMA) THEN
8630   ASM_REWRITE_TAC[REAL_HALF] THEN
8631   DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
8632   EXISTS_TAC `\x:real^M. g(x) INTER ball(x,k x)` THEN CONJ_TAC THENL
8633    [MATCH_MP_TAC GAUGE_INTER THEN ASM_REWRITE_TAC[] THEN
8634     ASM_REWRITE_TAC[gauge; CENTRE_IN_BALL; OPEN_BALL];
8635     ALL_TAC] THEN
8636   REWRITE_TAC[FINE_INTER] THEN X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN
8637   STRIP_TAC THEN
8638   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
8639   ABBREV_TAC
8640    `p' = {(x:real^M,k:real^M->bool) |
8641                 ?i l. x IN i /\ i IN d /\ (x,l) IN p /\ k = i INTER l}` THEN
8642   SUBGOAL_THEN `g fine (p':(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
8643    [EXPAND_TAC "p'" THEN
8644     MP_TAC(ASSUME `g fine (p:(real^M#(real^M->bool))->bool)`) THEN
8645     REWRITE_TAC[fine; IN_ELIM_PAIR_THM] THEN
8646     MESON_TAC[SET_RULE `k SUBSET l ==> (i INTER k) SUBSET l`];
8647     ALL_TAC] THEN
8648   SUBGOAL_THEN `p' tagged_division_of interval[a:real^M,b]` ASSUME_TAC THENL
8649    [REWRITE_TAC[TAGGED_DIVISION_OF] THEN EXPAND_TAC "p'" THEN
8650     REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
8651     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
8652     MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
8653      [DISCH_TAC THEN MATCH_MP_TAC FINITE_SUBSET THEN
8654       EXISTS_TAC
8655        `IMAGE (\(k,(x,l)). x,k INTER l)
8656               {k,xl | k IN (d:(real^M->bool)->bool) /\
8657                       xl IN (p:(real^M#(real^M->bool))->bool)}` THEN
8658       ASM_SIMP_TAC[FINITE_IMAGE; FINITE_PRODUCT] THEN
8659       EXPAND_TAC "p'" THEN REWRITE_TAC[SUBSET; FORALL_PAIR_THM] THEN
8660       REWRITE_TAC[IN_ELIM_PAIR_THM; IN_IMAGE; EXISTS_PAIR_THM; PAIR_EQ] THEN
8661       MESON_TAC[];
8662       ALL_TAC] THEN
8663     MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
8664      [DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
8665       REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
8666       MAP_EVERY X_GEN_TAC [`i:real^M->bool`; `l:real^M->bool`] THEN
8667       STRIP_TAC THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN
8668       ASM_SIMP_TAC[IN_INTER] THEN CONJ_TAC THENL
8669        [MATCH_MP_TAC(SET_RULE `l SUBSET s ==> (k INTER l) SUBSET s`) THEN
8670         ASM_MESON_TAC[];
8671         ALL_TAC] THEN
8672       FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `l:real^M->bool`]) THEN
8673       ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
8674       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
8675       DISCH_THEN(MP_TAC o SPEC `i:real^M->bool` o el 1 o CONJUNCTS) THEN
8676       ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
8677       ASM_REWRITE_TAC[INTER_INTERVAL] THEN MESON_TAC[];
8678       ALL_TAC] THEN
8679     MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
8680      [DISCH_TAC THEN MAP_EVERY X_GEN_TAC
8681        [`x1:real^M`; `k1:real^M->bool`; `x2:real^M`; `k2:real^M->bool`] THEN
8682       DISCH_THEN(CONJUNCTS_THEN2
8683        (X_CHOOSE_THEN `i1:real^M->bool` (X_CHOOSE_THEN `l1:real^M->bool`
8684           STRIP_ASSUME_TAC)) MP_TAC) THEN
8685       FIRST_X_ASSUM SUBST_ALL_TAC THEN
8686       DISCH_THEN(CONJUNCTS_THEN2
8687        (X_CHOOSE_THEN `i2:real^M->bool` (X_CHOOSE_THEN `l2:real^M->bool`
8688           STRIP_ASSUME_TAC)) ASSUME_TAC) THEN
8689       FIRST_X_ASSUM SUBST_ALL_TAC THEN
8690       MATCH_MP_TAC(SET_RULE
8691        `(interior(i1) INTER interior(i2) = {} \/
8692          interior(l1) INTER interior(l2) = {}) /\
8693         interior(i1 INTER l1) SUBSET interior(i1) /\
8694         interior(i2 INTER l2) SUBSET interior(i2) /\
8695         interior(i1 INTER l1) SUBSET interior(l1) /\
8696         interior(i2 INTER l2) SUBSET interior(l2)
8697         ==> interior(i1 INTER l1) INTER interior(i2 INTER l2) = {}`) THEN
8698       SIMP_TAC[SUBSET_INTERIOR; INTER_SUBSET] THEN
8699       FIRST_X_ASSUM(MP_TAC o SPECL
8700        [`x1:real^M`; `l1:real^M->bool`; `x2:real^M`; `l2:real^M->bool`]) THEN
8701       ASM_REWRITE_TAC[] THEN
8702       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
8703       DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
8704       DISCH_THEN(MP_TAC o SPECL [`i1:real^M->bool`; `i2:real^M->bool`]) THEN
8705       ASM_REWRITE_TAC[] THEN
8706       FIRST_X_ASSUM(MP_TAC o check(is_neg o concl)) THEN
8707       ASM_REWRITE_TAC[PAIR_EQ] THEN MESON_TAC[];
8708       ALL_TAC] THEN
8709     DISCH_TAC THEN MATCH_MP_TAC SUBSET_ANTISYM THEN CONJ_TAC THENL
8710      [REWRITE_TAC[UNIONS_SUBSET; IN_ELIM_THM] THEN
8711       REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
8712       MATCH_MP_TAC(SET_RULE `i SUBSET s ==> (i INTER k) SUBSET s`) THEN
8713       ASM_MESON_TAC[division_of];
8714       ALL_TAC] THEN
8715     REWRITE_TAC[SUBSET] THEN X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN
8716     REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN
8717     REWRITE_TAC[LEFT_AND_EXISTS_THM; GSYM CONJ_ASSOC] THEN
8718     REWRITE_TAC[MESON[]
8719      `p /\ q /\ r /\ x = t /\ P x <=> x = t /\ p /\ q /\ r /\ P t`] THEN
8720     ONCE_REWRITE_TAC[MESON[]
8721      `(?a b c d. P a b c d) <=> (?d b c a. P a b c d)`] THEN
8722     REWRITE_TAC[IN_INTER; UNWIND_THM2] THEN
8723     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
8724     DISCH_THEN(MP_TAC o SPEC `y:real^M`) THEN ASM_REWRITE_TAC[] THEN
8725     REWRITE_TAC[IN_UNIONS; IN_ELIM_THM; LEFT_AND_EXISTS_THM] THEN
8726     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `l:real^M->bool` THEN
8727     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `x:real^M` THEN
8728     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
8729     FIRST_X_ASSUM(MP_TAC o last o CONJUNCTS o
8730         GEN_REWRITE_RULE I [division_of]) THEN
8731     REWRITE_TAC[EXTENSION] THEN DISCH_THEN(MP_TAC o SPEC `y:real^M`) THEN
8732     ASM_REWRITE_TAC[IN_UNIONS] THEN
8733     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^M->bool` THEN
8734     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
8735     FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `k:real^M->bool`]) THEN
8736     GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN
8737     ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN
8738     REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
8739     EXISTS_TAC `y:real^M` THEN ASM_REWRITE_TAC[INTER; IN_ELIM_THM] THEN
8740     UNDISCH_TAC `(\x:real^M. ball (x,k x)) fine p` THEN
8741     REWRITE_TAC[fine; SUBSET] THEN ASM_MESON_TAC[];
8742     ALL_TAC] THEN
8743   FIRST_X_ASSUM(MP_TAC o SPEC `p':(real^M#(real^M->bool))->bool`) THEN
8744   ASM_REWRITE_TAC[] THEN
8745   ANTS_TAC THENL [ASM_MESON_TAC[tagged_division_of]; ALL_TAC] THEN
8746   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
8747   REWRITE_TAC[LAMBDA_PAIR] THEN DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN
8748   ASM_SIMP_TAC[DROP_VSUM; o_DEF; SUM_SUB; DROP_SUB; ABS_DROP] THEN
8749   REWRITE_TAC[LAMBDA_PAIR_THM; DROP_CMUL; NORM_MUL; LIFT_DROP] THEN
8750   MATCH_MP_TAC(REAL_ARITH
8751     `!sni. i - e / &2 < sni /\
8752            sni' <= i /\ sni <= sni' /\ sf' = sf
8753               ==> abs(sf' - sni') < e / &2
8754                   ==> abs(sf - i) < e`) THEN
8755   EXISTS_TAC `sum d (\k. norm (integral k (f:real^M->real^N)))` THEN
8756   ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
8757    [MP_TAC(ISPECL [`\k. norm(integral k (f:real^M->real^N))`;
8758                    `p':(real^M#(real^M->bool))->bool`;
8759                    `interval[a:real^M,b]`] SUM_OVER_TAGGED_DIVISION_LEMMA) THEN
8760     ASM_SIMP_TAC[INTEGRAL_NULL; NORM_0] THEN DISCH_THEN SUBST1_TAC THEN
8761     FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[DIVISION_OF_TAGGED_DIVISION];
8762     ALL_TAC] THEN
8763   SUBGOAL_THEN
8764    `p' = {x:real^M,(i INTER l:real^M->bool) |
8765             (x,l) IN p /\ i IN d /\ ~(i INTER l = {})}`
8766   (LABEL_TAC "p'") THENL
8767    [EXPAND_TAC "p'" THEN GEN_REWRITE_TAC I [EXTENSION] THEN
8768     REWRITE_TAC[FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN
8769     REWRITE_TAC[IN_ELIM_THM] THEN
8770     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
8771     REWRITE_TAC[PAIR_EQ; GSYM CONJ_ASSOC] THEN
8772     GEN_REWRITE_TAC RAND_CONV [SWAP_EXISTS_THM] THEN
8773     AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
8774     X_GEN_TAC `i:real^M->bool` THEN REWRITE_TAC[] THEN
8775     CONV_TAC(RAND_CONV UNWIND_CONV) THEN
8776     AP_TERM_TAC THEN GEN_REWRITE_TAC I [FUN_EQ_THM] THEN
8777     X_GEN_TAC `l:real^M->bool` THEN REWRITE_TAC[] THEN
8778     ASM_CASES_TAC `k:real^M->bool = i INTER l` THEN ASM_REWRITE_TAC[] THEN
8779     ASM_REWRITE_TAC[IN_INTER; GSYM MEMBER_NOT_EMPTY] THEN
8780     EQ_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
8781     REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
8782     DISCH_THEN(X_CHOOSE_THEN `y:real^M` STRIP_ASSUME_TAC) THEN
8783     ASM_REWRITE_TAC[] THEN
8784     FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `i:real^M->bool`]) THEN
8785     GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN
8786     ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN
8787     REWRITE_TAC[GSYM MEMBER_NOT_EMPTY] THEN
8788     EXISTS_TAC `y:real^M` THEN ASM_REWRITE_TAC[INTER; IN_ELIM_THM] THEN
8789     UNDISCH_TAC `(\x:real^M. ball (x,k x)) fine p` THEN
8790     REWRITE_TAC[fine; SUBSET] THEN ASM_MESON_TAC[];
8791     ALL_TAC] THEN
8792   CONJ_TAC THENL
8793    [MP_TAC(ISPECL
8794      [`\y. norm(integral y (f:real^M->real^N))`;
8795       `p':(real^M#(real^M->bool))->bool`;
8796       `interval[a:real^M,b]`]
8797      SUM_OVER_TAGGED_DIVISION_LEMMA) THEN
8798     ASM_SIMP_TAC[INTEGRAL_NULL; NORM_0] THEN DISCH_THEN SUBST1_TAC THEN
8799     MATCH_MP_TAC REAL_LE_TRANS THEN
8800     EXISTS_TAC `sum {i INTER l | i IN d /\
8801                  (l IN IMAGE SND (p:(real^M#(real^M->bool))->bool))}
8802                     (\k. norm(integral k (f:real^M->real^N)))` THEN
8803     CONJ_TAC THENL
8804      [ALL_TAC;
8805       MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC SUM_SUPERSET THEN
8806       CONJ_TAC THENL
8807        [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
8808         REWRITE_TAC[FORALL_PAIR_THM] THEN
8809         REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; PAIR_EQ; EXISTS_PAIR_THM] THEN
8810         MESON_TAC[];
8811         ALL_TAC] THEN
8812       REWRITE_TAC[IN_ELIM_THM; LEFT_AND_EXISTS_THM; LEFT_IMP_EXISTS_THM] THEN
8813       MAP_EVERY X_GEN_TAC
8814        [`kk:real^M->bool`; `i:real^M->bool`; `l:real^M->bool`] THEN
8815       ASM_CASES_TAC `kk:real^M->bool = i INTER l` THEN ASM_REWRITE_TAC[] THEN
8816       REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM; UNWIND_THM1] THEN
8817       DISCH_THEN(CONJUNCTS_THEN2
8818        (CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_TAC `x:real^M`)) MP_TAC) THEN
8819       REWRITE_TAC[IN_ELIM_THM; PAIR_EQ; NOT_EXISTS_THM] THEN
8820       DISCH_THEN(MP_TAC o SPECL
8821        [`x:real^M`; `x:real^M`; `i:real^M->bool`; `l:real^M->bool`]) THEN
8822       ASM_SIMP_TAC[INTEGRAL_EMPTY; NORM_0]] THEN
8823     SUBGOAL_THEN
8824      `{k INTER l | k IN d /\ l IN IMAGE SND (p:(real^M#(real^M->bool))->bool)} =
8825       IMAGE (\(k,l). k INTER l) {k,l | k IN d /\ l IN IMAGE SND p}`
8826     SUBST1_TAC THENL
8827      [GEN_REWRITE_TAC I [EXTENSION] THEN
8828       REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; EXISTS_PAIR_THM; FORALL_PAIR_THM] THEN
8829       REWRITE_TAC[PAIR_EQ] THEN
8830       CONV_TAC(REDEPTH_CONV UNWIND_CONV) THEN MESON_TAC[];
8831       ALL_TAC] THEN
8832     W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE_NONZERO o rand o snd) THEN
8833     ANTS_TAC THENL
8834      [ASSUME_TAC(MATCH_MP DIVISION_OF_TAGGED_DIVISION
8835         (ASSUME `p tagged_division_of interval[a:real^M,b]`)) THEN
8836       ASM_SIMP_TAC[FINITE_PRODUCT; FINITE_IMAGE] THEN
8837       REWRITE_TAC[FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN
8838       MAP_EVERY X_GEN_TAC
8839        [`l1:real^M->bool`; `k1:real^M->bool`;
8840         `l2:real^M->bool`; `k2:real^M->bool`] THEN
8841       REWRITE_TAC[PAIR_EQ] THEN STRIP_TAC THEN
8842       SUBGOAL_THEN `interior(l2 INTER k2:real^M->bool) = {}` MP_TAC THENL
8843        [ALL_TAC;
8844         MP_TAC(ASSUME `d division_of interval[a:real^M,b]`) THEN
8845         REWRITE_TAC[division_of] THEN
8846         DISCH_THEN(MP_TAC o SPEC `l2:real^M->bool` o el 1 o CONJUNCTS) THEN
8847         ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
8848         MP_TAC(ASSUME
8849          `(IMAGE SND (p:(real^M#(real^M->bool))->bool))
8850                 division_of interval[a:real^M,b]`) THEN
8851         REWRITE_TAC[division_of] THEN
8852         DISCH_THEN(MP_TAC o SPEC `k2:real^M->bool` o el 1 o CONJUNCTS) THEN
8853         ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
8854         ASM_REWRITE_TAC[INTER_INTERVAL] THEN DISCH_TAC THEN
8855         REWRITE_TAC[NORM_EQ_0] THEN
8856         MATCH_MP_TAC INTEGRAL_NULL THEN
8857         ASM_REWRITE_TAC[CONTENT_EQ_0_INTERIOR]] THEN
8858       MATCH_MP_TAC(SET_RULE
8859        `(interior(k1) INTER interior(k2) = {} \/
8860          interior(l1) INTER interior(l2) = {}) /\
8861         interior(l1 INTER k1) SUBSET interior(k1) /\
8862         interior(l2 INTER k2) SUBSET interior(k2) /\
8863         interior(l1 INTER k1) SUBSET interior(l1) /\
8864         interior(l2 INTER k2) SUBSET interior(l2) /\
8865         interior(l1 INTER k1) = interior(l2 INTER k2)
8866         ==> interior(l2 INTER k2) = {}`) THEN
8867       SIMP_TAC[SUBSET_INTERIOR; INTER_SUBSET] THEN ASM_REWRITE_TAC[] THEN
8868       MP_TAC(ASSUME `d division_of interval[a:real^M,b]`) THEN
8869       REWRITE_TAC[division_of] THEN DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
8870       DISCH_THEN(MP_TAC o SPECL [`l1:real^M->bool`; `l2:real^M->bool`]) THEN
8871       ASM_REWRITE_TAC[] THEN
8872       MP_TAC(ASSUME
8873        `(IMAGE SND (p:(real^M#(real^M->bool))->bool))
8874               division_of interval[a:real^M,b]`) THEN
8875       REWRITE_TAC[division_of] THEN DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
8876       DISCH_THEN(MP_TAC o SPECL [`k1:real^M->bool`; `k2:real^M->bool`]) THEN
8877       ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[];
8878       ALL_TAC] THEN
8879     DISCH_THEN SUBST1_TAC THEN
8880     GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM ETA_AX] THEN
8881     GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [LAMBDA_PAIR_THM] THEN
8882     ASM_SIMP_TAC[GSYM SUM_SUM_PRODUCT; FINITE_IMAGE] THEN
8883     MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[] THEN
8884     X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN REWRITE_TAC[o_DEF] THEN
8885     MATCH_MP_TAC REAL_LE_TRANS THEN
8886     EXISTS_TAC
8887      `sum { k INTER l |
8888              l IN IMAGE SND (p:(real^M#(real^M->bool))->bool)}
8889           (\k. norm(integral k (f:real^M->real^N)))` THEN
8890     CONJ_TAC THENL
8891      [ALL_TAC;
8892       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
8893       W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE_NONZERO o lhand o snd) THEN
8894       ANTS_TAC THENL [ALL_TAC; SIMP_TAC[o_DEF; REAL_LE_REFL]] THEN
8895       ASM_SIMP_TAC[FINITE_IMAGE] THEN
8896       MAP_EVERY X_GEN_TAC [`k1:real^M->bool`; `k2:real^M->bool`] THEN
8897       STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
8898       SUBGOAL_THEN `interior(k INTER k2:real^M->bool) = {}` MP_TAC THENL
8899        [ALL_TAC;
8900         MP_TAC(MATCH_MP DIVISION_OF_TAGGED_DIVISION
8901          (ASSUME `p tagged_division_of interval[a:real^M,b]`)) THEN
8902         MP_TAC(ASSUME `d division_of interval[a:real^M,b]`) THEN
8903         REWRITE_TAC[division_of] THEN
8904         DISCH_THEN(MP_TAC o SPEC `k:real^M->bool` o el 1 o CONJUNCTS) THEN
8905         ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
8906         DISCH_THEN(MP_TAC o SPEC `k2:real^M->bool` o el 1 o CONJUNCTS) THEN
8907         ASM_REWRITE_TAC[INTER_INTERVAL; GSYM CONTENT_EQ_0_INTERIOR] THEN
8908         STRIP_TAC THEN ASM_REWRITE_TAC[INTER_INTERVAL] THEN
8909         SIMP_TAC[GSYM CONTENT_EQ_0_INTERIOR; INTEGRAL_NULL; NORM_0]] THEN
8910       MATCH_MP_TAC(SET_RULE
8911        `interior(k INTER k2) SUBSET interior(k1 INTER k2) /\
8912         interior(k1 INTER k2) = {}
8913         ==> interior(k INTER k2) = {}`) THEN
8914       CONJ_TAC THENL
8915        [MATCH_MP_TAC SUBSET_INTERIOR THEN ASM SET_TAC[]; ALL_TAC] THEN
8916       MP_TAC(MATCH_MP DIVISION_OF_TAGGED_DIVISION
8917          (ASSUME `p tagged_division_of interval[a:real^M,b]`)) THEN
8918       REWRITE_TAC[division_of] THEN
8919       DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
8920       REWRITE_TAC[INTERIOR_INTER] THEN DISCH_THEN MATCH_MP_TAC THEN
8921       ASM_REWRITE_TAC[]] THEN
8922     SUBGOAL_THEN `?u v:real^M. k = interval[u,v]`
8923      (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
8924     THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
8925     SUBGOAL_THEN `interval[u:real^M,v] SUBSET interval[a,b]` ASSUME_TAC THENL
8926      [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
8927     ABBREV_TAC `d' =
8928         {interval[u,v] INTER l |l|
8929                 l IN IMAGE SND (p:(real^M#(real^M->bool))->bool) /\
8930                 ~(interval[u,v] INTER l = {})}` THEN
8931     MATCH_MP_TAC REAL_LE_TRANS THEN
8932     EXISTS_TAC
8933      `sum d' (\k. norm (integral k (f:real^M->real^N)))` THEN
8934     CONJ_TAC THENL
8935      [ALL_TAC;
8936       MATCH_MP_TAC REAL_EQ_IMP_LE THEN CONV_TAC SYM_CONV THEN
8937       MATCH_MP_TAC SUM_SUPERSET THEN
8938       EXPAND_TAC "d'" THEN REWRITE_TAC[SUBSET; SET_RULE
8939        `a IN {f x |x| x IN s /\ ~(f x = b)} <=>
8940         a IN {f x | x IN s} /\ ~(a = b)`] THEN
8941       SIMP_TAC[IMP_CONJ; INTEGRAL_EMPTY; NORM_0]] THEN
8942     SUBGOAL_THEN `d' division_of interval[u:real^M,v]` ASSUME_TAC THENL
8943      [EXPAND_TAC "d'" THEN MATCH_MP_TAC DIVISION_INTER_1 THEN
8944       EXISTS_TAC `interval[a:real^M,b]` THEN
8945       ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION];
8946       ALL_TAC] THEN
8947     MATCH_MP_TAC REAL_LE_TRANS THEN
8948     EXISTS_TAC `norm(vsum d' (\i. integral i (f:real^M->real^N)))` THEN
8949     CONJ_TAC THENL
8950      [MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
8951       MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_TOPDOWN THEN
8952       ASM_MESON_TAC[INTEGRABLE_ON_SUBINTERVAL];
8953       ALL_TAC] THEN
8954     MATCH_MP_TAC VSUM_NORM_LE THEN
8955     REWRITE_TAC[REAL_LE_REFL] THEN ASM_MESON_TAC[division_of];
8956     ALL_TAC] THEN
8957   REMOVE_THEN "p'" SUBST_ALL_TAC THEN
8958   MATCH_MP_TAC EQ_TRANS THEN
8959   EXISTS_TAC `sum {x,i INTER l | (x,l) IN p /\ i IN d}
8960                   (\(x,k:real^M->bool).
8961                       abs(content k) * norm((f:real^M->real^N) x))` THEN
8962   CONJ_TAC THENL
8963    [CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_SUPERSET THEN
8964     CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
8965     REWRITE_TAC[FORALL_PAIR_THM] THEN
8966     MAP_EVERY X_GEN_TAC [`x:real^M`; `i:real^M->bool`] THEN
8967     ASM_CASES_TAC `i:real^M->bool = {}` THEN
8968     ASM_SIMP_TAC[CONTENT_EMPTY; REAL_ABS_NUM; REAL_MUL_LZERO] THEN
8969     MATCH_MP_TAC(TAUT `(a <=> b) ==> a /\ ~b ==> c`) THEN
8970     REWRITE_TAC[IN_ELIM_THM] THEN
8971     REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
8972     REWRITE_TAC[PAIR_EQ] THEN ASM_MESON_TAC[];
8973     ALL_TAC] THEN
8974   SUBGOAL_THEN
8975    `{x,i INTER l | x,l IN (p:(real^M#(real^M->bool))->bool) /\ i IN d} =
8976     IMAGE (\((x,l),k). x,k INTER l) {m,k | m IN p /\ k IN d}`
8977   SUBST1_TAC THENL
8978    [GEN_REWRITE_TAC I [EXTENSION] THEN
8979     REWRITE_TAC[IN_ELIM_THM; IN_IMAGE; EXISTS_PAIR_THM; FORALL_PAIR_THM] THEN
8980     REWRITE_TAC[PAIR_EQ] THEN
8981     CONV_TAC(REDEPTH_CONV UNWIND_CONV) THEN MESON_TAC[];
8982     ALL_TAC] THEN
8983   W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE_NONZERO o lhand o snd) THEN
8984   ANTS_TAC THENL
8985    [ASM_SIMP_TAC[FINITE_PRODUCT] THEN
8986     REWRITE_TAC[FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN
8987     MAP_EVERY X_GEN_TAC
8988      [`x1:real^M`; `l1:real^M->bool`; `k1:real^M->bool`;
8989       `x2:real^M`; `l2:real^M->bool`; `k2:real^M->bool`] THEN
8990     REWRITE_TAC[PAIR_EQ] THEN
8991     ASM_CASES_TAC `x1:real^M = x2` THEN ASM_REWRITE_TAC[] THEN
8992     STRIP_TAC THEN
8993     REWRITE_TAC[REAL_ENTIRE] THEN DISJ1_TAC THEN
8994     REWRITE_TAC[REAL_ABS_ZERO] THEN
8995     SUBGOAL_THEN `interior(k2 INTER l2:real^M->bool) = {}` MP_TAC THENL
8996      [ALL_TAC;
8997       FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
8998       DISCH_THEN(MP_TAC o SPEC `k2:real^M->bool` o el 1 o CONJUNCTS) THEN
8999       ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9000       MP_TAC(ASSUME `p tagged_division_of interval[a:real^M,b]`) THEN
9001       REWRITE_TAC[TAGGED_DIVISION_OF] THEN
9002       DISCH_THEN(MP_TAC o el 1 o CONJUNCTS) THEN
9003       DISCH_THEN(MP_TAC o SPECL [`x2:real^M`; `l2:real^M->bool`]) THEN
9004       ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
9005       ASM_REWRITE_TAC[INTER_INTERVAL; CONTENT_EQ_0_INTERIOR]] THEN
9006     MATCH_MP_TAC(SET_RULE
9007      `(interior(k1) INTER interior(k2) = {} \/
9008        interior(l1) INTER interior(l2) = {}) /\
9009       interior(k1 INTER l1) SUBSET interior(k1) /\
9010       interior(k2 INTER l2) SUBSET interior(k2) /\
9011       interior(k1 INTER l1) SUBSET interior(l1) /\
9012       interior(k2 INTER l2) SUBSET interior(l2) /\
9013       interior(k1 INTER l1) = interior(k2 INTER l2)
9014       ==> interior(k2 INTER l2) = {}`) THEN
9015     SIMP_TAC[SUBSET_INTERIOR; INTER_SUBSET] THEN ASM_REWRITE_TAC[] THEN
9016     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
9017     DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
9018     DISCH_THEN(MP_TAC o SPECL [`k1:real^M->bool`; `k2:real^M->bool`]) THEN
9019     MP_TAC(ASSUME `p tagged_division_of interval[a:real^M,b]`) THEN
9020     REWRITE_TAC[TAGGED_DIVISION_OF] THEN
9021     DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
9022     DISCH_THEN(MP_TAC o SPECL
9023      [`x2:real^M`; `l1:real^M->bool`; `x2:real^M`; `l2:real^M->bool`]) THEN
9024     ASM_REWRITE_TAC[PAIR_EQ] THEN ASM_MESON_TAC[];
9025     ALL_TAC] THEN
9026   DISCH_THEN SUBST1_TAC THEN
9027   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM ETA_AX] THEN
9028   GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [LAMBDA_PAIR_THM] THEN
9029   ASM_SIMP_TAC[GSYM SUM_SUM_PRODUCT] THEN
9030   MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
9031   MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
9032   DISCH_TAC THEN REWRITE_TAC[o_THM; SUM_RMUL] THEN
9033   AP_THM_TAC THEN AP_TERM_TAC THEN
9034   SUBGOAL_THEN `?u v:real^M. l = interval[u,v]`
9035    (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
9036   THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
9037   MATCH_MP_TAC EQ_TRANS THEN
9038   EXISTS_TAC `sum d (\k. content(k INTER interval[u:real^M,v]))` THEN
9039   CONJ_TAC THENL
9040    [MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[real_abs] THEN
9041     X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
9042     SUBGOAL_THEN `?w z:real^M. k = interval[w,z]`
9043       (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
9044     THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
9045     REWRITE_TAC[INTER_INTERVAL; CONTENT_POS_LE];
9046     ALL_TAC] THEN
9047   MATCH_MP_TAC EQ_TRANS THEN
9048   EXISTS_TAC `sum {k INTER interval[u:real^M,v] | k IN d} content` THEN
9049   CONJ_TAC THENL
9050    [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN ONCE_REWRITE_TAC[GSYM o_DEF] THEN
9051     CONV_TAC SYM_CONV THEN MATCH_MP_TAC SUM_IMAGE_NONZERO THEN
9052     ASM_REWRITE_TAC[] THEN
9053     MAP_EVERY X_GEN_TAC [`k1:real^M->bool`; `k2:real^M->bool`] THEN
9054     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9055     SUBGOAL_THEN `interior(k2 INTER interval[u:real^M,v]) = {}` MP_TAC THENL
9056      [ALL_TAC;
9057       FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
9058       DISCH_THEN(MP_TAC o SPEC `k2:real^M->bool` o el 1 o CONJUNCTS) THEN
9059       ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
9060       ASM_REWRITE_TAC[INTER_INTERVAL; CONTENT_EQ_0_INTERIOR]] THEN
9061     MATCH_MP_TAC(SET_RULE
9062      `interior(k2 INTER i) SUBSET interior(k1 INTER k2) /\
9063       interior(k1 INTER k2) = {}
9064       ==> interior(k2 INTER i) = {}`) THEN
9065     CONJ_TAC THENL
9066      [MATCH_MP_TAC SUBSET_INTERIOR THEN ASM SET_TAC[]; ALL_TAC] THEN
9067     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
9068     DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
9069     REWRITE_TAC[INTERIOR_INTER] THEN DISCH_THEN MATCH_MP_TAC THEN
9070     ASM_REWRITE_TAC[];
9071     ALL_TAC] THEN
9072   SUBGOAL_THEN `interval[u:real^M,v] SUBSET interval[a,b]` ASSUME_TAC THENL
9073    [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
9074   MATCH_MP_TAC EQ_TRANS THEN
9075   EXISTS_TAC `sum {k INTER interval[u:real^M,v] |k|
9076                       k IN d /\ ~(k INTER interval[u,v] = {})} content` THEN
9077   CONJ_TAC THENL
9078    [MATCH_MP_TAC SUM_SUPERSET THEN
9079     REWRITE_TAC[SUBSET; SET_RULE
9080      `a IN {f x |x| x IN s /\ ~(f x = b)} <=>
9081       a IN {f x | x IN s} /\ ~(a = b)`] THEN
9082     SIMP_TAC[IMP_CONJ; CONTENT_EMPTY];
9083     ALL_TAC] THEN
9084   MATCH_MP_TAC ADDITIVE_CONTENT_DIVISION THEN
9085   ONCE_REWRITE_TAC[INTER_COMM] THEN MATCH_MP_TAC DIVISION_INTER_1 THEN
9086   EXISTS_TAC `interval[a:real^M,b]` THEN ASM_REWRITE_TAC[]);;
9087
9088 let BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE = prove
9089  (`!f:real^M->real^N.
9090         f integrable_on UNIV /\
9091         (\k. integral k f) has_bounded_setvariation_on (:real^M)
9092         ==> f absolutely_integrable_on UNIV`,
9093   REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN
9094   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[absolutely_integrable_on] THEN
9095   MP_TAC(ISPEC `IMAGE (\d. sum d (\k. norm(integral k (f:real^M->real^N))))
9096                       {d | d division_of (UNIONS d) }`
9097          SUP) THEN
9098   REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
9099   REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_ELIM_THM] THEN
9100   ABBREV_TAC
9101    `i = sup (IMAGE (\d. sum d (\k. norm(integral k (f:real^M->real^N))))
9102                       {d | d division_of (UNIONS d) })` THEN
9103   ANTS_TAC THENL
9104    [CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[]] THEN
9105     EXISTS_TAC `{}:(real^M->bool)->bool` THEN
9106     REWRITE_TAC[UNIONS_0; DIVISION_OF_TRIVIAL];
9107     ALL_TAC] THEN
9108   STRIP_TAC THEN REWRITE_TAC[integrable_on] THEN EXISTS_TAC `lift i` THEN
9109   REWRITE_TAC[HAS_INTEGRAL_ALT; IN_UNIV] THEN
9110   MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
9111    [MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
9112     MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`]
9113       (REWRITE_RULE[HAS_BOUNDED_SETVARIATION_ON_INTERVAL]
9114        BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE_INTERVAL)) THEN
9115     ANTS_TAC THENL [ALL_TAC; SIMP_TAC[absolutely_integrable_on]] THEN
9116     CONJ_TAC THENL
9117      [MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN EXISTS_TAC `(:real^M)` THEN
9118       ASM_REWRITE_TAC[SUBSET_UNIV];
9119       ALL_TAC] THEN
9120     EXISTS_TAC `B:real` THEN REPEAT STRIP_TAC THEN
9121     FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[DIVISION_OF_UNION_SELF];
9122     ALL_TAC] THEN
9123   DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
9124   FIRST_X_ASSUM(MP_TAC o SPEC `i - e`) THEN
9125   ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(i <= i - e)`] THEN
9126   REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LE; LEFT_IMP_EXISTS_THM] THEN
9127   X_GEN_TAC `d:(real^M->bool)->bool` THEN STRIP_TAC THEN
9128   SUBGOAL_THEN `bounded(UNIONS d:real^M->bool)` MP_TAC THENL
9129    [ASM_MESON_TAC[ELEMENTARY_BOUNDED]; ALL_TAC] THEN
9130   REWRITE_TAC[BOUNDED_POS] THEN
9131   DISCH_THEN(X_CHOOSE_THEN `K:real` STRIP_ASSUME_TAC) THEN
9132   EXISTS_TAC `K + &1` THEN ASM_SIMP_TAC[REAL_LT_ADD; REAL_LT_01] THEN
9133   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN
9134   REWRITE_TAC[ABS_DROP; DROP_SUB; LIFT_DROP] THEN
9135   MATCH_MP_TAC(REAL_ARITH
9136    `!s1. i - e < s1 /\ s1 <= s /\ s < i + e ==> abs(s - i) < e`) THEN
9137   EXISTS_TAC `sum (d:(real^M->bool)->bool) (\k. norm (integral k
9138                     (f:real^M->real^N)))` THEN
9139   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
9140   ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
9141    [MATCH_MP_TAC REAL_LE_TRANS THEN
9142     EXISTS_TAC `sum d
9143       (\k. drop(integral k (\x. lift(norm((f:real^M->real^N) x)))))` THEN
9144     CONJ_TAC THENL
9145      [MATCH_MP_TAC SUM_LE THEN
9146       FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN
9147       REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_LE THEN
9148       ASM_REWRITE_TAC[absolutely_integrable_on] THEN
9149       MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
9150       EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV];
9151       ALL_TAC] THEN
9152     MATCH_MP_TAC REAL_LE_TRANS THEN
9153     EXISTS_TAC `drop(integral (UNIONS d)
9154                       (\x. lift(norm((f:real^M->real^N) x))))` THEN
9155     CONJ_TAC THENL
9156      [MATCH_MP_TAC(MESON[REAL_LE_REFL; LIFT_DROP]
9157        `lift x = y ==> x <= drop y`) THEN
9158       ASM_SIMP_TAC[LIFT_SUM; o_DEF; LIFT_DROP] THEN CONV_TAC SYM_CONV THEN
9159       MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_BOTTOMUP THEN
9160       FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]);
9161       ALL_TAC] THEN
9162     MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN
9163     ASM_REWRITE_TAC[LIFT_DROP; NORM_POS_LE] THEN
9164     MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
9165      [MATCH_MP_TAC SUBSET_TRANS THEN
9166       EXISTS_TAC `ball(vec 0:real^M,K + &1)` THEN
9167       ASM_REWRITE_TAC[] THEN REWRITE_TAC[SUBSET; IN_BALL] THEN
9168       ASM_SIMP_TAC[NORM_ARITH `norm(x) <= K ==> dist(vec 0,x) < K + &1`];
9169       ALL_TAC] THEN
9170     DISCH_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
9171     EXISTS_TAC `interval[a:real^M,b]` THEN
9172     EXISTS_TAC `d:(real^M->bool)->bool` THEN ASM_REWRITE_TAC[];
9173     ALL_TAC] THEN
9174   FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN
9175   REWRITE_TAC[HAS_INTEGRAL_INTEGRAL; has_integral] THEN
9176   DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
9177   DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool` MP_TAC) THEN
9178   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*")) THEN
9179   MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`]
9180                 HENSTOCK_LEMMA) THEN
9181   ANTS_TAC THENL
9182    [MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
9183     EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV];
9184     ALL_TAC] THEN
9185   DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
9186   DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool` MP_TAC) THEN
9187   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "+")) THEN
9188   SUBGOAL_THEN `?p. p tagged_division_of interval[a:real^M,b] /\
9189                     d1 fine p /\ d2 fine p`
9190   STRIP_ASSUME_TAC THENL
9191    [REWRITE_TAC[GSYM FINE_INTER] THEN MATCH_MP_TAC FINE_DIVISION_EXISTS THEN
9192     ASM_SIMP_TAC[GAUGE_INTER];
9193     ALL_TAC] THEN
9194   REMOVE_THEN "*" (MP_TAC o SPEC `p:(real^M#(real^M->bool)->bool)`) THEN
9195   REMOVE_THEN "+" (MP_TAC o SPEC `p:(real^M#(real^M->bool)->bool)`) THEN
9196   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
9197    [ASM_MESON_TAC[tagged_division_of]; ALL_TAC] THEN
9198   REWRITE_TAC[ABS_DROP; DROP_SUB] THEN
9199   REWRITE_TAC[LAMBDA_PAIR] THEN DISCH_THEN(MP_TAC o MATCH_MP lemma) THEN
9200   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
9201   ASM_SIMP_TAC[DROP_VSUM; o_DEF; SUM_SUB] THEN
9202   REWRITE_TAC[LAMBDA_PAIR_THM; DROP_CMUL; NORM_MUL; LIFT_DROP] THEN
9203   MATCH_MP_TAC(REAL_ARITH
9204    `sf' = sf /\ si <= i
9205     ==> abs(sf - si) < e / &2
9206         ==> abs(sf' - di) < e / &2
9207             ==> di < i + e`) THEN
9208   CONJ_TAC THENL
9209    [MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM; real_abs] THEN
9210     ASM_MESON_TAC[CONTENT_POS_LE; TAGGED_DIVISION_OF];
9211     ALL_TAC] THEN
9212   SUBGOAL_THEN
9213    `sum p (\(x:real^M,k). norm(integral k f)) =
9214     sum (IMAGE SND p) (\k. norm(integral k (f:real^M->real^N)))`
9215   SUBST1_TAC THENL
9216    [MATCH_MP_TAC SUM_OVER_TAGGED_DIVISION_LEMMA THEN
9217     EXISTS_TAC `interval[a:real^M,b]` THEN ASM_REWRITE_TAC[] THEN
9218     SIMP_TAC[INTEGRAL_NULL; NORM_0];
9219     ALL_TAC] THEN
9220   FIRST_X_ASSUM MATCH_MP_TAC THEN
9221   MATCH_MP_TAC PARTIAL_DIVISION_OF_TAGGED_DIVISION THEN
9222   EXISTS_TAC `interval[a:real^M,b]` THEN ASM_MESON_TAC[tagged_division_of]);;
9223
9224 let ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_UNIV_EQ = prove
9225  (`!f:real^M->real^N.
9226         f absolutely_integrable_on (:real^M) <=>
9227         f integrable_on (:real^M) /\
9228         (\k. integral k f) has_bounded_setvariation_on (:real^M)`,
9229   GEN_TAC THEN EQ_TAC THEN
9230   SIMP_TAC[ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION;
9231            BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE;
9232            ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE]);;
9233
9234 let ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_EQ = prove
9235  (`!f:real^M->real^N a b.
9236         f absolutely_integrable_on interval[a,b] <=>
9237         f integrable_on interval[a,b] /\
9238         (\k. integral k f) has_bounded_setvariation_on interval[a,b]`,
9239   REPEAT GEN_TAC THEN EQ_TAC THEN
9240   SIMP_TAC[ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION;
9241            BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE_INTERVAL;
9242            ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE]);;
9243
9244 let ABSOLUTELY_INTEGRABLE_SET_VARIATION = prove
9245  (`!f:real^M->real^N a b.
9246         f absolutely_integrable_on interval[a,b]
9247         ==> set_variation (interval[a,b]) (\k. integral k f) =
9248                  drop(integral (interval[a,b]) (\x. lift(norm(f x))))`,
9249   REPEAT STRIP_TAC THEN REWRITE_TAC[set_variation] THEN
9250   MATCH_MP_TAC REAL_SUP_UNIQUE THEN
9251   REWRITE_TAC[FORALL_IN_GSPEC; EXISTS_IN_GSPEC] THEN CONJ_TAC THENL
9252    [X_GEN_TAC `d:(real^M->bool)->bool` THEN
9253     DISCH_THEN(X_CHOOSE_THEN `s:real^M->bool` STRIP_ASSUME_TAC) THEN
9254     MATCH_MP_TAC REAL_LE_TRANS THEN
9255     EXISTS_TAC `drop(integral s (\x. lift(norm((f:real^M->real^N) x))))` THEN
9256     CONJ_TAC THENL
9257      [MP_TAC(ISPECL [`\x. lift(norm((f:real^M->real^N) x))`;
9258                      `d:(real^M->bool)->bool`; `s:real^M->bool`]
9259         INTEGRAL_COMBINE_DIVISION_TOPDOWN) THEN
9260       ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
9261        [RULE_ASSUM_TAC(REWRITE_RULE[absolutely_integrable_on]) THEN
9262         ASM_REWRITE_TAC[] THEN
9263         MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
9264         EXISTS_TAC `interval[a:real^M,b]` THEN ASM_MESON_TAC[];
9265         DISCH_THEN SUBST1_TAC] THEN
9266       FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
9267       ASM_SIMP_TAC[DROP_VSUM] THEN MATCH_MP_TAC SUM_LE THEN
9268       ASM_REWRITE_TAC[o_THM] THEN
9269       REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
9270       REWRITE_TAC[LIFT_DROP; REAL_LE_REFL; GSYM absolutely_integrable_on] THEN
9271       RULE_ASSUM_TAC(REWRITE_RULE[division_of]) THEN
9272       ASM_MESON_TAC[ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL; SUBSET_TRANS];
9273       MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN
9274       ASM_REWRITE_TAC[LIFT_DROP; NORM_POS_LE] THEN
9275       RULE_ASSUM_TAC(REWRITE_RULE[absolutely_integrable_on]) THEN
9276       ASM_REWRITE_TAC[] THEN
9277       MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
9278       EXISTS_TAC `interval[a:real^M,b]` THEN ASM_MESON_TAC[]];
9279     X_GEN_TAC `B:real` THEN ONCE_REWRITE_TAC[GSYM REAL_SUB_LT] THEN
9280     ABBREV_TAC `e = drop(integral (interval [a,b])
9281                                   (\x. lift(norm((f:real^M->real^N) x)))) -
9282                     B` THEN
9283     DISCH_TAC THEN
9284     FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE) THEN
9285     DISCH_THEN(MP_TAC o SPEC `e / &2` o MATCH_MP HENSTOCK_LEMMA) THEN
9286     ASM_REWRITE_TAC[REAL_HALF] THEN
9287     DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool`
9288      (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "F"))) THEN
9289     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [absolutely_integrable_on]) THEN
9290     DISCH_THEN(MP_TAC o CONJUNCT2) THEN
9291     REWRITE_TAC[HAS_INTEGRAL_INTEGRAL; has_integral] THEN
9292     DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
9293     DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool`
9294      (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "A"))) THEN
9295     MP_TAC(ISPECL
9296      [`\x. (d1:real^M->real^M->bool) x INTER d2 x`;
9297       `a:real^M`; `b:real^M`]
9298      FINE_DIVISION_EXISTS) THEN
9299     ASM_SIMP_TAC[GAUGE_INTER; FINE_INTER] THEN
9300     DISCH_THEN(X_CHOOSE_THEN `p:real^M#(real^M->bool)->bool`
9301         STRIP_ASSUME_TAC) THEN
9302     REMOVE_THEN "A" (MP_TAC o SPEC  `p:real^M#(real^M->bool)->bool`) THEN
9303     REMOVE_THEN "F" (MP_TAC o SPEC  `p:real^M#(real^M->bool)->bool`) THEN
9304     ASM_REWRITE_TAC[] THEN
9305     ANTS_TAC THENL [ASM_MESON_TAC[tagged_division_of]; ALL_TAC] THEN
9306     MP_TAC(ISPECL
9307      [`\x. lift(norm((f:real^M->real^N) x))`;
9308       `a:real^M`; `b:real^M`; `p:real^M#(real^M->bool)->bool`]
9309       INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN) THEN
9310     ANTS_TAC THENL
9311      [RULE_ASSUM_TAC(REWRITE_RULE[absolutely_integrable_on]) THEN
9312       ASM_REWRITE_TAC[];
9313       DISCH_THEN SUBST_ALL_TAC] THEN
9314     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
9315     DISCH_TAC THEN
9316     SUBGOAL_THEN
9317      `abs(sum p (\(x,k). content k * norm((f:real^M->real^N) x)) -
9318           sum p (\(x,k:real^M->bool). norm(integral k f))) < e / &2`
9319     MP_TAC THENL
9320      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT]
9321         REAL_LET_TRANS)) THEN
9322       ASM_SIMP_TAC[GSYM SUM_SUB] THEN MATCH_MP_TAC SUM_ABS_LE THEN
9323       ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN REPEAT STRIP_TAC THEN
9324       MATCH_MP_TAC(NORM_ARITH
9325        `x = norm u ==> abs(x - norm v) <= norm(u - v:real^N)`) THEN
9326       REWRITE_TAC[NORM_MUL; real_abs] THEN
9327       ASM_MESON_TAC[CONTENT_POS_LE; TAGGED_DIVISION_OF];
9328       ALL_TAC] THEN
9329     ONCE_REWRITE_TAC[GSYM NORM_LIFT] THEN
9330     ASM_SIMP_TAC[LIFT_SUB; LIFT_SUM] THEN
9331     REWRITE_TAC[LAMBDA_PAIR_THM; o_DEF; LIFT_CMUL; IMP_IMP] THEN
9332     DISCH_THEN(MP_TAC o MATCH_MP (NORM_ARITH
9333      `norm(x - y:real^N) < e / &2 /\ norm(x - z) < e / &2
9334       ==> norm(y - z) < e`)) THEN
9335     REWRITE_TAC[NORM_1; DROP_SUB] THEN
9336     DISCH_THEN(MP_TAC o SPEC `B:real` o MATCH_MP
9337      (REAL_ARITH `!B. abs(x - y) < e ==> y - B = e ==> &0 < x - B`)) THEN
9338     ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[DROP_VSUM; REAL_SUB_LT] THEN
9339     REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM; LIFT_DROP] THEN DISCH_TAC THEN
9340     EXISTS_TAC `IMAGE SND (p:real^M#(real^M->bool)->bool)` THEN CONJ_TAC THENL
9341      [EXISTS_TAC `interval[a:real^M,b]` THEN
9342       ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION; SUBSET_REFL];
9343       FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
9344         SUM_OVER_TAGGED_DIVISION_LEMMA)) THEN
9345       DISCH_THEN(fun th ->
9346        W(MP_TAC o PART_MATCH (rand o rand) th o rand o snd)) THEN
9347       SIMP_TAC[INTEGRAL_NULL; NORM_0] THEN
9348       DISCH_THEN(SUBST1_TAC o SYM) THEN ASM_REWRITE_TAC[]]]);;
9349
9350 let ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV = prove
9351  (`!f s. (\x. if x IN s then f x else vec 0)
9352               absolutely_integrable_on (:real^M) <=>
9353          f absolutely_integrable_on s`,
9354   REWRITE_TAC[absolutely_integrable_on; INTEGRABLE_RESTRICT_UNIV;
9355               COND_RAND; NORM_0; LIFT_NUM]);;
9356
9357 let ABSOLUTELY_INTEGRABLE_CONST = prove
9358  (`!a b c. (\x. c) absolutely_integrable_on interval[a,b]`,
9359   REWRITE_TAC[absolutely_integrable_on; INTEGRABLE_CONST]);;
9360
9361 let ABSOLUTELY_INTEGRABLE_ADD = prove
9362  (`!f:real^M->real^N g s.
9363         f absolutely_integrable_on s /\
9364         g absolutely_integrable_on s
9365         ==> (\x. f(x) + g(x)) absolutely_integrable_on s`,
9366   SUBGOAL_THEN
9367    `!f:real^M->real^N g.
9368         f absolutely_integrable_on (:real^M) /\
9369         g absolutely_integrable_on (:real^M)
9370         ==> (\x. f(x) + g(x)) absolutely_integrable_on (:real^M)`
9371   ASSUME_TAC THENL
9372    [ALL_TAC;
9373     ONCE_REWRITE_TAC[GSYM ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV] THEN
9374     REPEAT GEN_TAC THEN DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN
9375     REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN
9376     AP_THM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN
9377     GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_ADD_LID]] THEN
9378   REPEAT STRIP_TAC THEN
9379   EVERY_ASSUM(STRIP_ASSUME_TAC o
9380    GEN_REWRITE_RULE I [absolutely_integrable_on]) THEN
9381   MATCH_MP_TAC BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE THEN
9382   ASM_SIMP_TAC[INTEGRABLE_ADD] THEN
9383   MP_TAC(ISPECL [`g:real^M->real^N`; `(:real^M)`]
9384      ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION) THEN
9385   MP_TAC(ISPECL [`f:real^M->real^N`; `(:real^M)`]
9386      ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION) THEN
9387   ASM_REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN
9388   DISCH_THEN(X_CHOOSE_TAC `B1:real`) THEN
9389   DISCH_THEN(X_CHOOSE_TAC `B2:real`) THEN EXISTS_TAC `B1 + B2:real` THEN
9390   X_GEN_TAC `d:(real^M->bool)->bool` THEN DISCH_TAC THEN
9391   REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `d:(real^M->bool)->bool`)) THEN
9392   ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
9393   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
9394    `a <= B1 ==> x <= a + B2 ==> x <= B1 + B2`)) THEN
9395   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
9396    `b <= B2 ==> x <= a + b ==> x <= a + B2`)) THEN
9397   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
9398   ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN
9399   FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN
9400   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN STRIP_TAC THEN
9401   MATCH_MP_TAC(NORM_ARITH `x = y + z ==> norm(x) <= norm(y) + norm(z)`) THEN
9402   MATCH_MP_TAC INTEGRAL_ADD THEN CONJ_TAC THEN
9403   MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
9404   EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]);;
9405
9406 let ABSOLUTELY_INTEGRABLE_SUB = prove
9407  (`!f:real^M->real^N g s.
9408         f absolutely_integrable_on s /\
9409         g absolutely_integrable_on s
9410         ==> (\x. f(x) - g(x)) absolutely_integrable_on s`,
9411   REWRITE_TAC[VECTOR_SUB] THEN
9412   SIMP_TAC[ABSOLUTELY_INTEGRABLE_ADD; ABSOLUTELY_INTEGRABLE_NEG]);;
9413
9414 let ABSOLUTELY_INTEGRABLE_LINEAR = prove
9415  (`!f:real^M->real^N h:real^N->real^P s.
9416         f absolutely_integrable_on s /\ linear h
9417         ==> (h o f) absolutely_integrable_on s`,
9418   SUBGOAL_THEN
9419    `!f:real^M->real^N h:real^N->real^P.
9420         f absolutely_integrable_on (:real^M) /\ linear h
9421         ==> (h o f) absolutely_integrable_on (:real^M)`
9422   ASSUME_TAC THENL
9423    [ALL_TAC;
9424     ONCE_REWRITE_TAC[GSYM ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV] THEN
9425     REPEAT GEN_TAC THEN DISCH_THEN(fun th ->
9426      ANTE_RES_THEN MP_TAC th THEN
9427      ASSUME_TAC(MATCH_MP LINEAR_0 (CONJUNCT2 th))) THEN
9428     ASM_REWRITE_TAC[o_DEF; COND_RAND]] THEN
9429   REPEAT STRIP_TAC THEN
9430   MATCH_MP_TAC BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE THEN
9431   FIRST_ASSUM(MP_TAC o
9432     MATCH_MP ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION) THEN
9433   RULE_ASSUM_TAC(REWRITE_RULE[absolutely_integrable_on]) THEN
9434   ASM_SIMP_TAC[INTEGRABLE_LINEAR; HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN
9435   FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o MATCH_MP
9436               LINEAR_BOUNDED_POS) THEN
9437   DISCH_THEN(X_CHOOSE_TAC `b:real`) THEN EXISTS_TAC `B * b:real` THEN
9438   X_GEN_TAC `d:(real^M->bool)->bool` THEN DISCH_TAC THEN
9439   MATCH_MP_TAC REAL_LE_TRANS THEN
9440   EXISTS_TAC `B * sum d (\k. norm(integral k (f:real^M->real^N)))` THEN
9441   ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN REWRITE_TAC[GSYM SUM_LMUL] THEN
9442   MATCH_MP_TAC SUM_LE THEN
9443   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
9444   FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN
9445   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN
9446   MATCH_MP_TAC REAL_LE_TRANS THEN
9447   EXISTS_TAC `norm(h(integral (interval[a,b]) (f:real^M->real^N)):real^P)` THEN
9448   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
9449   MATCH_MP_TAC INTEGRAL_UNIQUE THEN MATCH_MP_TAC HAS_INTEGRAL_LINEAR THEN
9450   ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL] THEN
9451   MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
9452   EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV]);;
9453
9454 let ABSOLUTELY_INTEGRABLE_VSUM = prove
9455  (`!f:A->real^M->real^N s t.
9456         FINITE t /\
9457         (!a. a IN t ==> (f a) absolutely_integrable_on s)
9458         ==>  (\x. vsum t (\a. f a x)) absolutely_integrable_on s`,
9459   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
9460   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN
9461   SIMP_TAC[VSUM_CLAUSES; ABSOLUTELY_INTEGRABLE_0; IN_INSERT;
9462            ABSOLUTELY_INTEGRABLE_ADD; ETA_AX]);;
9463
9464 let ABSOLUTELY_INTEGRABLE_ABS = prove
9465  (`!f:real^M->real^N s.
9466         f absolutely_integrable_on s
9467         ==> (\x. (lambda i. abs(f(x)$i)):real^N) absolutely_integrable_on s`,
9468   REPEAT STRIP_TAC THEN
9469   SUBGOAL_THEN
9470    `(\x. (lambda i. abs(f(x)$i))):real^M->real^N =
9471     (\x. vsum (1..dimindex(:N))
9472         (\i. (((\y. (lambda j. if j = i then drop y else &0)) o
9473                (\x. lift(norm((lambda j. if j = i then x$i else &0):real^N))) o
9474                (f:real^M->real^N)) x)))`
9475   SUBST1_TAC THENL
9476    [REWRITE_TAC[FUN_EQ_THM] THEN X_GEN_TAC `x:real^M` THEN
9477     GEN_REWRITE_TAC I [CART_EQ] THEN
9478     X_GEN_TAC `i:num` THEN STRIP_TAC THEN
9479     ASM_SIMP_TAC[LAMBDA_BETA; VSUM_COMPONENT; o_THM] THEN
9480     GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN
9481     ASM_SIMP_TAC[SUM_DELTA; IN_NUMSEG; LIFT_DROP] THEN
9482     GEN_REWRITE_TAC (RAND_CONV o ONCE_DEPTH_CONV) [EQ_SYM_EQ] THEN
9483     REWRITE_TAC[vector_norm; dot] THEN MATCH_MP_TAC EQ_TRANS THEN
9484     EXISTS_TAC `sqrt(sum (1..dimindex(:N))
9485                          (\k. if k = i then ((f:real^M->real^N) x)$i pow 2
9486                               else &0))` THEN
9487     CONJ_TAC THENL
9488      [ASM_REWRITE_TAC[SUM_DELTA; IN_NUMSEG; POW_2_SQRT_ABS]; ALL_TAC] THEN
9489     AP_TERM_TAC THEN MATCH_MP_TAC SUM_EQ THEN
9490     SIMP_TAC[IN_NUMSEG; LAMBDA_BETA] THEN
9491     REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
9492     ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_POW_2];
9493     ALL_TAC] THEN
9494   MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_VSUM THEN
9495   REWRITE_TAC[IN_NUMSEG; FINITE_NUMSEG] THEN
9496   REPEAT STRIP_TAC THEN REWRITE_TAC[ETA_AX] THEN
9497   MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_LINEAR THEN CONJ_TAC THENL
9498    [ALL_TAC;
9499     SIMP_TAC[linear; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
9500              LAMBDA_BETA] THEN
9501     REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
9502     ASM_REWRITE_TAC[DROP_ADD; REAL_ADD_LID; DROP_CMUL; REAL_MUL_RZERO]] THEN
9503   REWRITE_TAC[o_DEF] THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_NORM THEN
9504   SUBGOAL_THEN
9505     `(\x. lambda j. if j = i then (f x:real^N)$i else &0):real^M->real^N =
9506      (\x. lambda j. if j = i then x$i else &0) o f`
9507   SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
9508   MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_LINEAR THEN ASM_REWRITE_TAC[] THEN
9509   SIMP_TAC[linear; CART_EQ; VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT;
9510              LAMBDA_BETA] THEN
9511   REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
9512   ASM_REWRITE_TAC[REAL_MUL_RZERO; REAL_ADD_LID] THEN
9513   FIRST_X_ASSUM SUBST_ALL_TAC THEN
9514   ASM_SIMP_TAC[VECTOR_ADD_COMPONENT; VECTOR_MUL_COMPONENT]);;
9515
9516 let ABSOLUTELY_INTEGRABLE_MAX = prove
9517  (`!f:real^M->real^N g:real^M->real^N s.
9518         f absolutely_integrable_on s /\ g absolutely_integrable_on s
9519         ==> (\x. (lambda i. max (f(x)$i) (g(x)$i)):real^N)
9520             absolutely_integrable_on s`,
9521   REPEAT GEN_TAC THEN DISCH_TAC THEN
9522   FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_SUB) THEN
9523   DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ABS) THEN
9524   FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ADD) THEN
9525   REWRITE_TAC[IMP_IMP] THEN
9526   DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ADD) THEN
9527   DISCH_THEN(MP_TAC o SPEC `inv(&2)` o
9528      MATCH_MP ABSOLUTELY_INTEGRABLE_CMUL) THEN
9529   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
9530   REWRITE_TAC[FUN_EQ_THM; CART_EQ] THEN
9531   SIMP_TAC[LAMBDA_BETA; VECTOR_MUL_COMPONENT; VECTOR_SUB_COMPONENT;
9532            VECTOR_ADD_COMPONENT] THEN
9533   REPEAT STRIP_TAC THEN REAL_ARITH_TAC);;
9534
9535 let ABSOLUTELY_INTEGRABLE_MAX_1 = prove
9536  (`!f:real^M->real g:real^M->real s.
9537         (\x. lift(f x)) absolutely_integrable_on s /\
9538         (\x. lift(g x)) absolutely_integrable_on s
9539         ==> (\x. lift(max (f x) (g x))) absolutely_integrable_on s`,
9540   REPEAT STRIP_TAC THEN
9541   SUBGOAL_THEN `(\x. (lambda i. max (lift(f x)$i) (lift(g x)$i)):real^1)
9542                 absolutely_integrable_on (s:real^M->bool)`
9543   MP_TAC THENL [ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_MAX]; ALL_TAC] THEN
9544   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
9545   REWRITE_TAC[FUN_EQ_THM; CART_EQ] THEN SIMP_TAC[LAMBDA_BETA; lift]);;
9546
9547 let ABSOLUTELY_INTEGRABLE_MIN = prove
9548  (`!f:real^M->real^N g:real^M->real^N s.
9549         f absolutely_integrable_on s /\ g absolutely_integrable_on s
9550         ==> (\x. (lambda i. min (f(x)$i) (g(x)$i)):real^N)
9551             absolutely_integrable_on s`,
9552   REPEAT GEN_TAC THEN DISCH_TAC THEN
9553   FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_SUB) THEN
9554   DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ABS) THEN
9555   FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_ADD) THEN
9556   REWRITE_TAC[IMP_IMP] THEN
9557   DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_SUB) THEN
9558   DISCH_THEN(MP_TAC o SPEC `inv(&2)` o
9559      MATCH_MP ABSOLUTELY_INTEGRABLE_CMUL) THEN
9560   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
9561   REWRITE_TAC[FUN_EQ_THM; CART_EQ] THEN
9562   SIMP_TAC[LAMBDA_BETA; VECTOR_MUL_COMPONENT; VECTOR_SUB_COMPONENT;
9563            VECTOR_ADD_COMPONENT] THEN
9564   REPEAT STRIP_TAC THEN REAL_ARITH_TAC);;
9565
9566 let ABSOLUTELY_INTEGRABLE_MIN_1 = prove
9567  (`!f:real^M->real g:real^M->real s.
9568         (\x. lift(f x)) absolutely_integrable_on s /\
9569         (\x. lift(g x)) absolutely_integrable_on s
9570         ==> (\x. lift(min (f x) (g x))) absolutely_integrable_on s`,
9571   REPEAT STRIP_TAC THEN
9572   SUBGOAL_THEN `(\x. (lambda i. min (lift(f x)$i) (lift(g x)$i)):real^1)
9573                 absolutely_integrable_on (s:real^M->bool)`
9574   MP_TAC THENL [ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_MIN]; ALL_TAC] THEN
9575   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
9576   REWRITE_TAC[FUN_EQ_THM; CART_EQ] THEN SIMP_TAC[LAMBDA_BETA; lift]);;
9577
9578 let ABSOLUTELY_INTEGRABLE_ABS_EQ = prove
9579  (`!f:real^M->real^N s.
9580         f absolutely_integrable_on s <=>
9581           f integrable_on s /\
9582           (\x. (lambda i. abs(f(x)$i)):real^N) integrable_on s`,
9583   REPEAT GEN_TAC THEN EQ_TAC THEN
9584   SIMP_TAC[ABSOLUTELY_INTEGRABLE_ABS;
9585            ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE] THEN
9586   SUBGOAL_THEN
9587    `!f:real^M->real^N.
9588         f integrable_on (:real^M) /\
9589         (\x. (lambda i. abs(f(x)$i)):real^N) integrable_on (:real^M)
9590         ==> f absolutely_integrable_on (:real^M)`
9591   ASSUME_TAC THENL
9592    [ALL_TAC;
9593     ONCE_REWRITE_TAC[GSYM ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV;
9594                      GSYM INTEGRABLE_RESTRICT_UNIV] THEN
9595     DISCH_THEN(fun th -> FIRST_X_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN
9596     MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN MATCH_MP_TAC EQ_IMP THEN
9597     AP_THM_TAC THEN AP_TERM_TAC THEN REWRITE_TAC[FUN_EQ_THM] THEN
9598     REWRITE_TAC[CART_EQ] THEN REPEAT STRIP_TAC THEN
9599     ASM_SIMP_TAC[LAMBDA_BETA; COND_COMPONENT; VEC_COMPONENT] THEN
9600     COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_ABS_0]] THEN
9601   REPEAT STRIP_TAC THEN
9602   MATCH_MP_TAC BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE THEN
9603   ASM_REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN
9604   EXISTS_TAC
9605    `sum (1..dimindex(:N))
9606         (\i. integral (:real^M)
9607               (\x. (lambda j. abs ((f:real^M->real^N) x$j)):real^N)$i)` THEN
9608   X_GEN_TAC `d:(real^M->bool)->bool` THEN DISCH_TAC THEN
9609   MATCH_MP_TAC REAL_LE_TRANS THEN
9610   EXISTS_TAC `sum d (\k. sum (1..dimindex(:N))
9611       (\i. integral k
9612               (\x. (lambda j. abs ((f:real^M->real^N) x$j)):real^N)$i))` THEN
9613   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN CONJ_TAC THENL
9614    [MATCH_MP_TAC SUM_LE THEN
9615     FIRST_ASSUM(fun t -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION t]) THEN
9616     MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN
9617     MATCH_MP_TAC REAL_LE_TRANS THEN
9618     EXISTS_TAC `sum (1..dimindex(:N))
9619              (\i. abs((integral (interval[a,b]) (f:real^M->real^N))$i))` THEN
9620     REWRITE_TAC[NORM_LE_L1] THEN MATCH_MP_TAC SUM_LE_NUMSEG THEN
9621     X_GEN_TAC `k:num` THEN STRIP_TAC THEN REWRITE_TAC[] THEN
9622     MATCH_MP_TAC(REAL_ARITH `x <= y /\ --x <= y ==> abs(x) <= y`) THEN
9623     ASM_SIMP_TAC[GSYM VECTOR_NEG_COMPONENT] THEN
9624     SUBGOAL_THEN `(f:real^M->real^N) integrable_on interval[a,b] /\
9625         (\x. (lambda i. abs (f x$i)):real^N) integrable_on interval[a,b]`
9626     STRIP_ASSUME_TAC THENL
9627      [CONJ_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
9628       EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV];
9629       ALL_TAC] THEN
9630     ASM_SIMP_TAC[GSYM INTEGRAL_NEG] THEN
9631     CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_COMPONENT_LE THEN
9632     ASM_SIMP_TAC[INTEGRABLE_NEG; LAMBDA_BETA] THEN
9633     ASM_SIMP_TAC[VECTOR_NEG_COMPONENT] THEN
9634     REPEAT STRIP_TAC THEN REAL_ARITH_TAC;
9635     ALL_TAC] THEN
9636   W(MP_TAC o PART_MATCH (lhs o rand) SUM_SWAP o lhand o snd) THEN
9637   ASM_REWRITE_TAC[FINITE_NUMSEG] THEN DISCH_THEN SUBST_ALL_TAC THEN
9638   MATCH_MP_TAC SUM_LE_NUMSEG THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
9639   REWRITE_TAC[] THEN
9640   MATCH_MP_TAC REAL_LE_TRANS THEN
9641   EXISTS_TAC
9642    `(integral (UNIONS d)
9643               (\x. (lambda j. abs ((f:real^M->real^N) x$j)):real^N))$k` THEN
9644   CONJ_TAC THENL
9645    [ASM_SIMP_TAC[GSYM VSUM_COMPONENT] THEN
9646     MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_THM_TAC THEN AP_TERM_TAC THEN
9647     CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_TOPDOWN THEN
9648     ASM_REWRITE_TAC[];
9649     MATCH_MP_TAC INTEGRAL_SUBSET_COMPONENT_LE THEN
9650     ASM_SIMP_TAC[LAMBDA_BETA; SUBSET_UNIV; REAL_ABS_POS]] THEN
9651   MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
9652   MAP_EVERY EXISTS_TAC [`(:real^M)`; `d:(real^M->bool)->bool`] THEN
9653   ASM_REWRITE_TAC[SUBSET_UNIV]);;
9654
9655 let NONNEGATIVE_ABSOLUTELY_INTEGRABLE = prove
9656  (`!f:real^M->real^N s.
9657         (!x i. x IN s /\ 1 <= i /\ i <= dimindex(:N)
9658                ==> &0 <= f(x)$i) /\
9659         f integrable_on s
9660         ==> f absolutely_integrable_on s`,
9661   SIMP_TAC[ABSOLUTELY_INTEGRABLE_ABS_EQ] THEN
9662   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_EQ THEN
9663   EXISTS_TAC `f:real^M->real^N` THEN
9664   ASM_SIMP_TAC[CART_EQ; LAMBDA_BETA; real_abs]);;
9665
9666 let ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND = prove
9667  (`!f:real^M->real^N g s.
9668         (!x. x IN s ==> norm(f x) <= drop(g x)) /\
9669         f integrable_on s /\ g integrable_on s
9670         ==> f absolutely_integrable_on s`,
9671   SUBGOAL_THEN
9672    `!f:real^M->real^N g.
9673         (!x. norm(f x) <= drop(g x)) /\
9674         f integrable_on (:real^M) /\ g integrable_on (:real^M)
9675         ==> f absolutely_integrable_on (:real^M)`
9676   ASSUME_TAC THENL
9677    [ALL_TAC;
9678     ONCE_REWRITE_TAC[GSYM INTEGRABLE_RESTRICT_UNIV; GSYM
9679                      ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV] THEN
9680     REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
9681     EXISTS_TAC `(\x. if x IN s then g x else vec 0):real^M->real^1` THEN
9682     ASM_REWRITE_TAC[] THEN GEN_TAC THEN COND_CASES_TAC THEN
9683     ASM_SIMP_TAC[REAL_LE_REFL; NORM_0; DROP_VEC]] THEN
9684   REPEAT STRIP_TAC THEN
9685   MATCH_MP_TAC BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE THEN
9686   ASM_REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_UNIV] THEN
9687   EXISTS_TAC `drop(integral(:real^M) g)` THEN
9688   X_GEN_TAC `d:(real^M->bool)->bool` THEN DISCH_TAC THEN
9689   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
9690   MATCH_MP_TAC REAL_LE_TRANS THEN
9691   EXISTS_TAC `sum d (\k. drop(integral k (g:real^M->real^1)))` THEN
9692   CONJ_TAC THENL
9693    [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[] THEN
9694     FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
9695     REPEAT STRIP_TAC THEN
9696     MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN ASM_REWRITE_TAC[] THEN
9697     CONJ_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
9698     EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV];
9699     ALL_TAC] THEN
9700   MATCH_MP_TAC REAL_LE_TRANS THEN
9701   EXISTS_TAC `drop(integral (UNIONS d:real^M->bool) g)` THEN CONJ_TAC THENL
9702    [MATCH_MP_TAC(REAL_ARITH `x = y ==> y <= x`) THEN
9703     ASM_SIMP_TAC[GSYM LIFT_EQ; LIFT_DROP; LIFT_SUM; o_DEF] THEN
9704     MATCH_MP_TAC INTEGRAL_COMBINE_DIVISION_BOTTOMUP THEN
9705     FIRST_ASSUM(fun th -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
9706     REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
9707     EXISTS_TAC `(:real^M)` THEN ASM_REWRITE_TAC[SUBSET_UNIV];
9708     MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE THEN
9709     ASM_REWRITE_TAC[SUBSET_UNIV; IN_UNIV] THEN CONJ_TAC THENL
9710      [ALL_TAC; ASM_MESON_TAC[NORM_ARITH `norm(x) <= y ==> &0 <= y`]] THEN
9711     MATCH_MP_TAC INTEGRABLE_ON_SUBDIVISION THEN
9712     MAP_EVERY EXISTS_TAC [`(:real^M)`; `d:(real^M->bool)->bool`] THEN
9713     ASM_REWRITE_TAC[SUBSET_UNIV]]);;
9714
9715 let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_BOUND = prove
9716  (`!f:real^M->real^N g:real^M->real^P s.
9717         (!x. x IN s ==> norm(f x) <= norm(g x)) /\
9718         f integrable_on s /\ g absolutely_integrable_on s
9719         ==> f absolutely_integrable_on s`,
9720   REPEAT STRIP_TAC THEN
9721   FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I
9722     [absolutely_integrable_on]) THEN
9723   MP_TAC(ISPECL
9724    [`f:real^M->real^N`; `(\x. lift(norm((g:real^M->real^P) x)))`;
9725     `s:real^M->bool`] ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND) THEN
9726   ASM_REWRITE_TAC[LIFT_DROP]);;
9727
9728 let ABSOLUTELY_INTEGRABLE_INF_1 = prove
9729  (`!fs s:real^N->bool k:A->bool.
9730         FINITE k /\ ~(k = {}) /\
9731         (!i. i IN k ==> (\x. lift(fs x i)) absolutely_integrable_on s)
9732         ==> (\x. lift(inf (IMAGE (fs x) k))) absolutely_integrable_on s`,
9733   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
9734   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[IMAGE_CLAUSES] THEN
9735   SIMP_TAC[INF_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
9736   MAP_EVERY X_GEN_TAC [`a:A`; `k:A->bool`] THEN
9737   ASM_CASES_TAC `k:A->bool = {}` THEN ASM_REWRITE_TAC[] THEN
9738   SIMP_TAC[IN_SING; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
9739   REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
9740   REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MIN_1 THEN
9741   CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INSERT] THEN
9742   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
9743   ASM_REWRITE_TAC[IN_INSERT]);;
9744
9745 let ABSOLUTELY_INTEGRABLE_SUP_1 = prove
9746  (`!fs s:real^N->bool k:A->bool.
9747         FINITE k /\ ~(k = {}) /\
9748         (!i. i IN k ==> (\x. lift(fs x i)) absolutely_integrable_on s)
9749         ==> (\x. lift(sup (IMAGE (fs x) k))) absolutely_integrable_on s`,
9750   GEN_TAC THEN GEN_TAC THEN REWRITE_TAC[IMP_CONJ] THEN
9751   MATCH_MP_TAC FINITE_INDUCT_STRONG THEN REWRITE_TAC[IMAGE_CLAUSES] THEN
9752   SIMP_TAC[SUP_INSERT_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY] THEN
9753   MAP_EVERY X_GEN_TAC [`a:A`; `k:A->bool`] THEN
9754   ASM_CASES_TAC `k:A->bool = {}` THEN ASM_REWRITE_TAC[] THEN
9755   SIMP_TAC[IN_SING; LEFT_FORALL_IMP_THM; EXISTS_REFL] THEN
9756   REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
9757   REPEAT STRIP_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MAX_1 THEN
9758   CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INSERT] THEN
9759   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
9760   ASM_REWRITE_TAC[IN_INSERT]);;
9761
9762 let ABSOLUTELY_INTEGRABLE_CONTINUOUS = prove
9763  (`!f:real^M->real^N a b.
9764         f continuous_on interval[a,b]
9765         ==> f absolutely_integrable_on interval[a,b]`,
9766   REPEAT STRIP_TAC THEN
9767   MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
9768   SUBGOAL_THEN `compact(IMAGE (f:real^M->real^N) (interval[a,b]))` MP_TAC THENL
9769    [ASM_SIMP_TAC[COMPACT_CONTINUOUS_IMAGE; COMPACT_INTERVAL]; ALL_TAC] THEN
9770   DISCH_THEN(MP_TAC o MATCH_MP COMPACT_IMP_BOUNDED) THEN
9771   REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE] THEN
9772   DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
9773   EXISTS_TAC `\x:real^M. lift(B)` THEN
9774   ASM_SIMP_TAC[INTEGRABLE_CONST; LIFT_DROP; INTEGRABLE_CONTINUOUS]);;
9775
9776 let INTEGRABLE_MIN_CONST_1 = prove
9777  (`!f s t.
9778         &0 <= t /\ (!x. x IN s ==> &0 <= f x) /\
9779         (\x:real^N. lift(f x)) integrable_on s
9780         ==> (\x. lift(min (f x) t)) integrable_on s`,
9781   REPEAT STRIP_TAC THEN
9782   MATCH_MP_TAC INTEGRABLE_ON_ALL_INTERVALS_INTEGRABLE_BOUND THEN
9783   EXISTS_TAC `\x:real^N. lift(f x)` THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
9784    [REPEAT GEN_TAC THEN
9785     MP_TAC(ISPECL
9786      [`\x:real^N. if x IN s then f x else &0`;
9787       `(\x. t):real^N->real`;
9788       `interval[a:real^N,b]`] ABSOLUTELY_INTEGRABLE_MIN_1) THEN
9789     REWRITE_TAC[] THEN ANTS_TAC THENL
9790      [SIMP_TAC[ABSOLUTELY_INTEGRABLE_CONTINUOUS; CONTINUOUS_ON_CONST] THEN
9791       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_ON_SUBINTERVAL THEN
9792       EXISTS_TAC `(:real^N)` THEN REWRITE_TAC[SUBSET_UNIV] THEN
9793       REWRITE_TAC[COND_RAND; LIFT_DROP; LIFT_NUM] THEN
9794       REWRITE_TAC[ABSOLUTELY_INTEGRABLE_RESTRICT_UNIV] THEN
9795       MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN
9796       ASM_SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
9797       ASM_REWRITE_TAC[IMP_IMP; DIMINDEX_1; FORALL_1; LIFT_DROP; GSYM drop];
9798       DISCH_THEN(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE) THEN
9799       MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
9800       REWRITE_TAC[FUN_EQ_THM] THEN GEN_TAC THEN
9801       COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
9802       CONV_TAC REAL_RAT_REDUCE_CONV THEN
9803       REWRITE_TAC[GSYM DROP_EQ; DROP_VEC; LIFT_DROP] THEN ASM_REAL_ARITH_TAC];
9804     X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
9805     FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
9806     ASM_REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP] THEN
9807     ASM_REAL_ARITH_TAC]);;
9808
9809 let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_UBOUND = prove
9810  (`!f:real^M->real^N g:real^M->real^N s.
9811         (!x i. x IN s /\ 1 <= i /\ i <= dimindex(:N) ==> f(x)$i <= g(x)$i) /\
9812         f integrable_on s /\ g absolutely_integrable_on s
9813         ==> f absolutely_integrable_on s`,
9814   REPEAT STRIP_TAC THEN SUBGOAL_THEN
9815    `(\x. (g:real^M->real^N)(x) - (g(x) - f(x))) absolutely_integrable_on s`
9816   MP_TAC THENL
9817    [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_SUB THEN
9818     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN
9819     ASM_REWRITE_TAC[REAL_SUB_LE; VECTOR_SUB_COMPONENT] THEN
9820     MATCH_MP_TAC INTEGRABLE_SUB THEN
9821     ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE];
9822     REWRITE_TAC[VECTOR_ARITH `x - (x - y):real^N = y`; ETA_AX]]);;
9823
9824 let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_LBOUND = prove
9825  (`!f:real^M->real^N g:real^M->real^N s.
9826         (!x i. x IN s /\ 1 <= i /\ i <= dimindex(:N) ==> f(x)$i <= g(x)$i) /\
9827         f absolutely_integrable_on s /\ g integrable_on s
9828         ==> g absolutely_integrable_on s`,
9829   REPEAT STRIP_TAC THEN SUBGOAL_THEN
9830    `(\x. (f:real^M->real^N)(x) + (g(x) - f(x))) absolutely_integrable_on s`
9831   MP_TAC THENL
9832    [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_ADD THEN
9833     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN
9834     ASM_REWRITE_TAC[REAL_SUB_LE; VECTOR_SUB_COMPONENT] THEN
9835     MATCH_MP_TAC INTEGRABLE_SUB THEN
9836     ASM_SIMP_TAC[ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE];
9837     REWRITE_TAC[VECTOR_ARITH `y + (x - y):real^N = x`; ETA_AX]]);;
9838
9839 let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_UBOUND = prove
9840  (`!f:real^M->real^1 g:real^M->real^1 s.
9841         (!x. x IN s ==> drop(f(x)) <= drop(g(x))) /\
9842         f integrable_on s /\ g absolutely_integrable_on s
9843         ==> f absolutely_integrable_on s`,
9844   REPEAT STRIP_TAC THEN MATCH_MP_TAC
9845     ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_UBOUND THEN
9846   EXISTS_TAC `g:real^M->real^1` THEN
9847   ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
9848   ASM_REWRITE_TAC[IMP_IMP; FORALL_1; DIMINDEX_1; GSYM drop]);;
9849
9850 let ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_DROP_LBOUND = prove
9851  (`!f:real^M->real^1 g:real^M->real^1 s.
9852         (!x. x IN s ==> drop(f(x)) <= drop(g(x))) /\
9853         f absolutely_integrable_on s /\ g integrable_on s
9854         ==> g absolutely_integrable_on s`,
9855   REPEAT STRIP_TAC THEN MATCH_MP_TAC
9856     ABSOLUTELY_INTEGRABLE_ABSOLUTELY_INTEGRABLE_COMPONENT_LBOUND THEN
9857   EXISTS_TAC `f:real^M->real^1` THEN
9858   ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
9859   ASM_REWRITE_TAC[IMP_IMP; FORALL_1; DIMINDEX_1; GSYM drop]);;
9860
9861 (* ------------------------------------------------------------------------- *)
9862 (* Relating vector integrals to integrals of components.                     *)
9863 (* ------------------------------------------------------------------------- *)
9864
9865 let HAS_INTEGRAL_COMPONENTWISE = prove
9866  (`!f:real^M->real^N s y.
9867         (f has_integral y) s <=>
9868         !i. 1 <= i /\ i <= dimindex(:N)
9869             ==> ((\x. lift((f x)$i)) has_integral (lift(y$i))) s`,
9870   REPEAT GEN_TAC THEN EQ_TAC THEN REPEAT STRIP_TAC THENL
9871    [FIRST_X_ASSUM(MP_TAC o ISPEC `\u:real^N. lift(u$i)` o
9872         MATCH_MP (REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_LINEAR)) THEN
9873     REWRITE_TAC[o_DEF] THEN DISCH_THEN MATCH_MP_TAC THEN
9874     REWRITE_TAC[LINEAR_LIFT_COMPONENT];
9875     GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
9876     GEN_REWRITE_TAC LAND_CONV [GSYM BASIS_EXPANSION] THEN
9877     GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV o BINDER_CONV)
9878      [GSYM BASIS_EXPANSION] THEN
9879     MATCH_MP_TAC HAS_INTEGRAL_VSUM THEN
9880     REWRITE_TAC[FINITE_NUMSEG; IN_NUMSEG] THEN
9881     X_GEN_TAC `i:num` THEN STRIP_TAC THEN
9882     FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
9883     DISCH_THEN(MP_TAC o ISPEC `\v. drop(v) % (basis i:real^N)` o
9884         MATCH_MP (REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_LINEAR)) THEN
9885     SIMP_TAC[o_DEF; LIFT_DROP; LINEAR_VMUL_DROP; LINEAR_ID]]);;
9886
9887 let INTEGRABLE_COMPONENTWISE = prove
9888  (`!f:real^M->real^N s.
9889         f integrable_on s <=>
9890         !i. 1 <= i /\ i <= dimindex(:N)
9891             ==> (\x. lift((f x)$i)) integrable_on s`,
9892    REPEAT GEN_TAC THEN REWRITE_TAC[integrable_on] THEN
9893    GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
9894     [HAS_INTEGRAL_COMPONENTWISE] THEN
9895    REWRITE_TAC[GSYM LAMBDA_SKOLEM; GSYM EXISTS_LIFT]);;
9896
9897 let LIFT_INTEGRAL_COMPONENT = prove
9898  (`!f:real^M->real^N.
9899         f integrable_on s
9900         ==> lift((integral s f)$k) = integral s (\x. lift((f x)$k))`,
9901   REPEAT STRIP_TAC THEN
9902   SUBGOAL_THEN `?j. 1 <= j /\ j <= dimindex(:N) /\ !z:real^N. z$k = z$j`
9903   CHOOSE_TAC THENL [REWRITE_TAC[FINITE_INDEX_INRANGE]; ALL_TAC] THEN
9904   ASM_REWRITE_TAC[] THEN CONV_TAC SYM_CONV THEN
9905   MATCH_MP_TAC INTEGRAL_UNIQUE THEN
9906   FIRST_X_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
9907   GEN_REWRITE_TAC LAND_CONV [HAS_INTEGRAL_COMPONENTWISE] THEN
9908   ASM_SIMP_TAC[]);;
9909
9910 let INTEGRAL_COMPONENT = prove
9911  (`!f:real^M->real^N.
9912         f integrable_on s
9913         ==> (integral s f)$k = drop(integral s (\x. lift((f x)$k)))`,
9914   SIMP_TAC[GSYM LIFT_INTEGRAL_COMPONENT; LIFT_DROP]);;
9915
9916 let ABSOLUTELY_INTEGRABLE_COMPONENTWISE = prove
9917  (`!f:real^M->real^N s.
9918      f absolutely_integrable_on s <=>
9919      (!i. 1 <= i /\ i <= dimindex(:N)
9920           ==> (\x. lift(f x$i)) absolutely_integrable_on s)`,
9921   REPEAT GEN_TAC THEN REWRITE_TAC[absolutely_integrable_on] THEN
9922   MATCH_MP_TAC(MESON[]
9923    `(p <=> !i. a i ==> P i) /\
9924     (p /\ (!i. a i ==> P i) ==> (q <=> (!i. a i ==> Q i)))
9925     ==> (p /\ q <=> (!i. a i ==> P i /\ Q i))`) THEN
9926   CONJ_TAC THENL [REWRITE_TAC[GSYM INTEGRABLE_COMPONENTWISE]; ALL_TAC] THEN
9927   REPEAT(STRIP_TAC ORELSE EQ_TAC) THENL
9928    [SUBGOAL_THEN
9929      `(\x. lift((f:real^M->real^N) x$i)) absolutely_integrable_on s`
9930     MP_TAC THENL [ALL_TAC; SIMP_TAC[absolutely_integrable_on]] THEN
9931     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
9932     EXISTS_TAC `\x. lift(norm((f:real^M->real^N) x))` THEN
9933     ASM_SIMP_TAC[ABS_DROP; LIFT_DROP; COMPONENT_LE_NORM];
9934     SUBGOAL_THEN
9935      `(f:real^M->real^N) absolutely_integrable_on s`
9936     MP_TAC THENL [ALL_TAC; SIMP_TAC[absolutely_integrable_on]] THEN
9937     MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
9938     EXISTS_TAC
9939      `\x. vsum (1..dimindex(:N))
9940                (\i. lift(norm(lift((f:real^M->real^N)(x)$i))))` THEN
9941     ASM_SIMP_TAC[INTEGRABLE_VSUM; IN_NUMSEG; FINITE_NUMSEG] THEN
9942     SIMP_TAC[DROP_VSUM; FINITE_NUMSEG; o_DEF; LIFT_DROP] THEN
9943     REWRITE_TAC[NORM_LIFT; NORM_LE_L1]]);;
9944
9945 (* ------------------------------------------------------------------------- *)
9946 (* Dominated convergence.                                                    *)
9947 (* ------------------------------------------------------------------------- *)
9948
9949 let DOMINATED_CONVERGENCE = prove
9950  (`!f:num->real^M->real^N g h s.
9951         (!k. (f k) integrable_on s) /\ h integrable_on s /\
9952         (!k x. x IN s ==> norm(f k x) <= drop(h x)) /\
9953         (!x. x IN s ==> ((\k. f k x) --> g x) sequentially)
9954         ==> g integrable_on s /\
9955             ((\k. integral s (f k)) --> integral s g) sequentially`,
9956   SUBGOAL_THEN
9957     `!f:num->real^M->real^1 g h s.
9958         (!k. (f k) integrable_on s) /\ h integrable_on s /\
9959         (!k x. x IN s ==> norm(f k x) <= drop(h x)) /\
9960         (!x. x IN s ==> ((\k. f k x) --> g x) sequentially)
9961         ==> g integrable_on s /\
9962             ((\k. integral s (f k)) --> integral s g) sequentially`
9963   ASSUME_TAC THENL
9964    [ALL_TAC;
9965     REPEAT GEN_TAC THEN STRIP_TAC THEN
9966     SUBGOAL_THEN
9967      `!j. 1 <= j /\ j <= dimindex(:N)
9968           ==> (\x. lift((g x)$j)) integrable_on s /\
9969               ((\k. integral s (\x. lift (((f:num->real^M->real^N) k x)$j)))
9970                --> integral s (\x. lift ((g x:real^N)$j))) sequentially`
9971     STRIP_ASSUME_TAC THENL
9972      [REPEAT GEN_TAC THEN STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
9973       EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[] THEN
9974       REPEAT CONJ_TAC THENL
9975        [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV
9976           [INTEGRABLE_COMPONENTWISE]) THEN
9977         ASM_SIMP_TAC[];
9978         MAP_EVERY X_GEN_TAC [`i:num`; `x:real^M`] THEN DISCH_TAC THEN
9979         MATCH_MP_TAC REAL_LE_TRANS THEN
9980         EXISTS_TAC `norm((f:num->real^M->real^N) i x)` THEN
9981         ASM_SIMP_TAC[NORM_LIFT; COMPONENT_LE_NORM];
9982         X_GEN_TAC `x:real^M` THEN STRIP_TAC THEN
9983         FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN
9984         GEN_REWRITE_TAC LAND_CONV [LIM_COMPONENTWISE_LIFT] THEN
9985         ASM_SIMP_TAC[]];
9986       MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
9987        [GEN_REWRITE_TAC I [INTEGRABLE_COMPONENTWISE] THEN ASM_SIMP_TAC[];
9988         DISCH_TAC THEN  ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT] THEN
9989         ASM_SIMP_TAC[LIFT_INTEGRAL_COMPONENT]]]] THEN
9990   REPEAT GEN_TAC THEN STRIP_TAC THEN
9991   MP_TAC(MATCH_MP MONO_FORALL (GEN `m:num`
9992    (ISPECL [`\k:num x:real^M. lift(inf {drop(f j x) | j IN m..(m+k)})`;
9993             `\x:real^M. lift(inf {drop(f j x) | m:num <= j})`;
9994             `s:real^M->bool`]
9995            MONOTONE_CONVERGENCE_DECREASING))) THEN
9996   REWRITE_TAC[LIFT_DROP] THEN ANTS_TAC THENL
9997    [X_GEN_TAC `m:num` THEN REPEAT CONJ_TAC THENL
9998      [GEN_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
9999       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10000       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INF_1 THEN
10001       REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10002       ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN
10003       REPEAT STRIP_TAC THEN
10004       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
10005       EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[];
10006
10007       REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10008       MATCH_MP_TAC REAL_LE_INF_SUBSET THEN
10009       REWRITE_TAC[IMAGE_EQ_EMPTY; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10010       CONJ_TAC THENL
10011        [MATCH_MP_TAC IMAGE_SUBSET THEN
10012         REWRITE_TAC[SUBSET_NUMSEG] THEN ARITH_TAC;
10013         ALL_TAC] THEN
10014       REWRITE_TAC[FORALL_IN_IMAGE] THEN
10015       MATCH_MP_TAC LOWER_BOUND_FINITE_SET_REAL THEN
10016       REWRITE_TAC[FINITE_NUMSEG];
10017
10018       X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10019       REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10020       REWRITE_TAC[dist; ABS_DROP; LIFT_DROP; DROP_SUB] THEN
10021       MP_TAC(SPEC `{drop((f:num->real^M->real^1) j x) | m <= j}` INF) THEN
10022       ABBREV_TAC `i = inf {drop((f:num->real^M->real^1) j x) | m <= j}` THEN
10023       ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
10024       REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
10025       REWRITE_TAC[IN_ELIM_THM; EXTENSION; NOT_IN_EMPTY] THEN ANTS_TAC THENL
10026        [CONJ_TAC THENL [MESON_TAC[LE_REFL]; ALL_TAC] THEN
10027         EXISTS_TAC `--drop(h(x:real^M))` THEN X_GEN_TAC `j:num` THEN
10028         FIRST_X_ASSUM(MP_TAC o SPECL [`j:num`; `x:real^M`]) THEN
10029         ASM_REWRITE_TAC[ABS_DROP] THEN REAL_ARITH_TAC;
10030         ALL_TAC] THEN
10031       DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `i + e:real`)) THEN
10032       ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(i + e <= i)`] THEN
10033       REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LE] THEN
10034       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN STRIP_TAC THEN
10035       X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10036       FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
10037        `y < i + e ==> i <= ix /\ ix <= y ==> abs(ix - i) < e`)) THEN
10038       CONJ_TAC THENL
10039        [EXPAND_TAC "i" THEN MATCH_MP_TAC REAL_LE_INF_SUBSET THEN
10040         REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
10041         REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10042         ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN CONJ_TAC THENL
10043          [MATCH_MP_TAC IMAGE_SUBSET THEN
10044           REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM] THEN ARITH_TAC;
10045           REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN ASM_MESON_TAC[]];
10046         ALL_TAC] THEN
10047       W(MP_TAC o C SPEC INF o rand o lhand o snd) THEN ANTS_TAC THENL
10048        [REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
10049         REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10050         REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10051         EXISTS_TAC `i:real` THEN GEN_TAC THEN REWRITE_TAC[IN_NUMSEG] THEN
10052         DISCH_THEN(fun th -> FIRST_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN
10053         ARITH_TAC;
10054         ALL_TAC] THEN
10055       REWRITE_TAC[FORALL_IN_IMAGE] THEN
10056       DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN
10057       REWRITE_TAC[IN_ELIM_THM; IN_NUMSEG] THEN
10058       ASM_ARITH_TAC;
10059
10060       REWRITE_TAC[bounded] THEN
10061       EXISTS_TAC `drop(integral s (h:real^M->real^1))` THEN
10062       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10063       REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN
10064       X_GEN_TAC `p:num` THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
10065       ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
10066        [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
10067         ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10068         MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INF_1 THEN
10069         REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10070         ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN REPEAT STRIP_TAC THEN
10071         MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
10072         EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[];
10073         ALL_TAC] THEN
10074       X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10075       REWRITE_TAC[ABS_DROP; LIFT_DROP] THEN
10076       MATCH_MP_TAC REAL_ABS_INF_LE THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10077       REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
10078       ASM_SIMP_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD; GSYM ABS_DROP]];
10079     REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN
10080   MP_TAC(MATCH_MP MONO_FORALL (GEN `m:num`
10081    (ISPECL [`\k:num x:real^M. lift(sup {drop(f j x) | j IN m..(m+k)})`;
10082             `\x:real^M. lift(sup {drop(f j x) | m:num <= j})`;
10083             `s:real^M->bool`]
10084            MONOTONE_CONVERGENCE_INCREASING))) THEN
10085   REWRITE_TAC[LIFT_DROP] THEN ANTS_TAC THENL
10086    [X_GEN_TAC `m:num` THEN REPEAT CONJ_TAC THENL
10087      [GEN_TAC THEN MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
10088       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10089       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_SUP_1 THEN
10090       REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10091       ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN
10092       REPEAT STRIP_TAC THEN
10093       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
10094       EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[];
10095
10096       REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10097       MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN
10098       REWRITE_TAC[IMAGE_EQ_EMPTY; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10099       CONJ_TAC THENL
10100        [MATCH_MP_TAC IMAGE_SUBSET THEN
10101         REWRITE_TAC[SUBSET_NUMSEG] THEN ARITH_TAC;
10102         ALL_TAC] THEN
10103       REWRITE_TAC[FORALL_IN_IMAGE] THEN
10104       MATCH_MP_TAC UPPER_BOUND_FINITE_SET_REAL THEN
10105       REWRITE_TAC[FINITE_NUMSEG];
10106
10107       X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10108       REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10109       REWRITE_TAC[dist; ABS_DROP; LIFT_DROP; DROP_SUB] THEN
10110       MP_TAC(SPEC `{drop((f:num->real^M->real^1) j x) | m <= j}` SUP) THEN
10111       ABBREV_TAC `i = sup {drop((f:num->real^M->real^1) j x) | m <= j}` THEN
10112       ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
10113       REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
10114       REWRITE_TAC[IN_ELIM_THM; EXTENSION; NOT_IN_EMPTY] THEN ANTS_TAC THENL
10115        [CONJ_TAC THENL [MESON_TAC[LE_REFL]; ALL_TAC] THEN
10116         EXISTS_TAC `drop(h(x:real^M))` THEN X_GEN_TAC `j:num` THEN
10117         FIRST_X_ASSUM(MP_TAC o SPECL [`j:num`; `x:real^M`]) THEN
10118         ASM_REWRITE_TAC[ABS_DROP] THEN REAL_ARITH_TAC;
10119         ALL_TAC] THEN
10120       DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `i - e:real`)) THEN
10121       ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(i <= i - e)`] THEN
10122       REWRITE_TAC[NOT_FORALL_THM; NOT_IMP; REAL_NOT_LE] THEN
10123       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN STRIP_TAC THEN
10124       X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10125       FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
10126        `i - e < y ==> ix <= i /\ y <= ix ==> abs(ix - i) < e`)) THEN
10127       CONJ_TAC THENL
10128        [EXPAND_TAC "i" THEN MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN
10129         REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
10130         REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10131         ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN CONJ_TAC THENL
10132          [MATCH_MP_TAC IMAGE_SUBSET THEN
10133           REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM] THEN ARITH_TAC;
10134           REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN ASM_MESON_TAC[]];
10135         ALL_TAC] THEN
10136       W(MP_TAC o C SPEC SUP o rand o rand o snd) THEN ANTS_TAC THENL
10137        [REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
10138         REWRITE_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10139         REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10140         EXISTS_TAC `i:real` THEN GEN_TAC THEN REWRITE_TAC[IN_NUMSEG] THEN
10141         DISCH_THEN(fun th -> FIRST_ASSUM MATCH_MP_TAC THEN MP_TAC th) THEN
10142         ARITH_TAC;
10143         ALL_TAC] THEN
10144       REWRITE_TAC[FORALL_IN_IMAGE] THEN
10145       DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN
10146       REWRITE_TAC[IN_ELIM_THM; IN_NUMSEG] THEN
10147       ASM_ARITH_TAC;
10148
10149       REWRITE_TAC[bounded] THEN
10150       EXISTS_TAC `drop(integral s (h:real^M->real^1))` THEN
10151       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10152       REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN
10153       X_GEN_TAC `p:num` THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
10154       ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
10155        [MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
10156         ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10157         MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_SUP_1 THEN
10158         REWRITE_TAC[FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; LE_ADD] THEN
10159         ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN REPEAT STRIP_TAC THEN
10160         MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
10161         EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[];
10162         ALL_TAC] THEN
10163       X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10164       REWRITE_TAC[ABS_DROP; LIFT_DROP] THEN
10165       MATCH_MP_TAC REAL_ABS_SUP_LE THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10166       REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
10167       ASM_SIMP_TAC[NUMSEG_EMPTY; NOT_LT; LE_ADD; GSYM ABS_DROP]];
10168     REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN
10169   MP_TAC(ISPECL
10170    [`\k:num x:real^M. lift(inf {drop(f j x) | k <= j})`;
10171     `g:real^M->real^1`;
10172     `s:real^M->bool`]
10173            MONOTONE_CONVERGENCE_INCREASING) THEN
10174   ASM_REWRITE_TAC[LIFT_DROP] THEN ANTS_TAC THENL
10175    [ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN CONJ_TAC THENL
10176      [REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_INF_SUBSET THEN
10177       REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
10178       REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; NOT_LE] THEN
10179       CONJ_TAC THENL [MESON_TAC[LT_REFL]; ALL_TAC] THEN CONJ_TAC THENL
10180        [MATCH_MP_TAC IMAGE_SUBSET THEN
10181         REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM] THEN ARITH_TAC;
10182         ALL_TAC] THEN
10183       REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10184       EXISTS_TAC `--drop(h(x:real^M))` THEN REPEAT STRIP_TAC THEN
10185       MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> --a <= x`) THEN
10186       ASM_SIMP_TAC[GSYM ABS_DROP];
10187       ALL_TAC] THEN
10188     CONJ_TAC THENL
10189      [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10190       FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN
10191       REWRITE_TAC[LIM_SEQUENTIALLY] THEN
10192       DISCH_THEN(fun th -> X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10193                  MP_TAC(SPEC `e / &2` th)) THEN
10194       ASM_REWRITE_TAC[REAL_HALF] THEN
10195       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN
10196       REWRITE_TAC[dist; ABS_DROP; DROP_SUB; LIFT_DROP] THEN
10197       STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10198       MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
10199       ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_INF_ASCLOSE THEN
10200       REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10201       CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LE_TRANS; REAL_LT_IMP_LE]] THEN
10202       REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN
10203       MESON_TAC[LE_REFL];
10204       ALL_TAC] THEN
10205     REWRITE_TAC[bounded; FORALL_IN_IMAGE; IN_ELIM_THM; IN_UNIV] THEN
10206     EXISTS_TAC `drop(integral s (h:real^M->real^1))` THEN
10207     X_GEN_TAC `p:num` THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
10208     ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10209     REWRITE_TAC[ABS_DROP; LIFT_DROP] THEN
10210     MATCH_MP_TAC REAL_ABS_INF_LE THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
10211     REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
10212     ASM_SIMP_TAC[GSYM ABS_DROP; IN_ELIM_THM] THEN
10213     REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN
10214     MESON_TAC[LE_REFL];
10215     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "A"))] THEN
10216   MP_TAC(ISPECL
10217    [`\k:num x:real^M. lift(sup {drop(f j x) | k <= j})`;
10218     `g:real^M->real^1`;
10219     `s:real^M->bool`]
10220            MONOTONE_CONVERGENCE_DECREASING) THEN
10221   ASM_REWRITE_TAC[LIFT_DROP] THEN ANTS_TAC THENL
10222    [ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN CONJ_TAC THENL
10223      [REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_SUP_LE_SUBSET THEN
10224       REWRITE_TAC[IMAGE_EQ_EMPTY; SET_RULE `{x | x IN s} = s`] THEN
10225       REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; NOT_LE] THEN
10226       CONJ_TAC THENL [MESON_TAC[LT_REFL]; ALL_TAC] THEN CONJ_TAC THENL
10227        [MATCH_MP_TAC IMAGE_SUBSET THEN
10228         REWRITE_TAC[SUBSET; IN_NUMSEG; IN_ELIM_THM] THEN ARITH_TAC;
10229         ALL_TAC] THEN
10230       REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10231       EXISTS_TAC `drop(h(x:real^M))` THEN REPEAT STRIP_TAC THEN
10232       MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> x <= a`) THEN
10233       ASM_SIMP_TAC[GSYM ABS_DROP];
10234       ALL_TAC] THEN
10235     CONJ_TAC THENL
10236      [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10237       FIRST_X_ASSUM(MP_TAC o SPEC `x:real^M`) THEN ASM_REWRITE_TAC[] THEN
10238       REWRITE_TAC[LIM_SEQUENTIALLY] THEN
10239       DISCH_THEN(fun th -> X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10240                  MP_TAC(SPEC `e / &2` th)) THEN
10241       ASM_REWRITE_TAC[REAL_HALF] THEN
10242       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `M:num` THEN
10243       REWRITE_TAC[dist; ABS_DROP; DROP_SUB; LIFT_DROP] THEN
10244       STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10245       MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
10246       ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_SUP_ASCLOSE THEN
10247       REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10248       CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[LE_TRANS; REAL_LT_IMP_LE]] THEN
10249       REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN
10250       MESON_TAC[LE_REFL];
10251       ALL_TAC] THEN
10252     REWRITE_TAC[bounded; FORALL_IN_IMAGE; IN_ELIM_THM; IN_UNIV] THEN
10253     EXISTS_TAC `drop(integral s (h:real^M->real^1))` THEN
10254     X_GEN_TAC `p:num` THEN MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
10255     ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
10256     REWRITE_TAC[ABS_DROP; LIFT_DROP] THEN
10257     MATCH_MP_TAC REAL_ABS_SUP_LE THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
10258     REWRITE_TAC[FORALL_IN_IMAGE; IMAGE_EQ_EMPTY] THEN
10259     ASM_SIMP_TAC[GSYM ABS_DROP; IN_ELIM_THM] THEN
10260     REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN
10261     MESON_TAC[LE_REFL];
10262     DISCH_THEN(LABEL_TAC "B")] THEN
10263   ASM_REWRITE_TAC[LIM_SEQUENTIALLY] THEN
10264   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10265   REMOVE_THEN "A" (MP_TAC o REWRITE_RULE[LIM_SEQUENTIALLY]) THEN
10266   DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
10267   DISCH_THEN(X_CHOOSE_THEN `N1:num` (LABEL_TAC "N1")) THEN
10268   REMOVE_THEN "B" (MP_TAC o REWRITE_RULE[LIM_SEQUENTIALLY]) THEN
10269   DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
10270   DISCH_THEN(X_CHOOSE_THEN `N2:num` (LABEL_TAC "N2")) THEN
10271   EXISTS_TAC `N1 + N2:num` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10272   REMOVE_THEN "N1" (MP_TAC o SPEC `n:num`) THEN
10273   ANTS_TAC THENL
10274    [ASM_MESON_TAC[ARITH_RULE `N1 + N2 <= n ==> N1:num <= n`]; ALL_TAC] THEN
10275   REMOVE_THEN "N2" (MP_TAC o SPEC `n:num`) THEN
10276   ANTS_TAC THENL
10277    [ASM_MESON_TAC[ARITH_RULE `N1 + N2 <= n ==> N2:num <= n`]; ALL_TAC] THEN
10278   REWRITE_TAC[dist; ABS_DROP; DROP_SUB; LIFT_DROP] THEN
10279   MATCH_MP_TAC(REAL_ARITH
10280    `i0 <= i /\ i <= i1
10281     ==> abs(i1 - g) < e ==> abs(i0 - g) < e ==> abs(i - g) < e`) THEN
10282   CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN
10283   ASM_REWRITE_TAC[LIFT_DROP] THEN X_GEN_TAC `x:real^M` THEN DISCH_TAC THENL
10284    [W(MP_TAC o C SPEC INF o rand o lhand o snd) THEN
10285     REWRITE_TAC[] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
10286     REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10287     ANTS_TAC THENL
10288      [REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN
10289       CONJ_TAC THENL [MESON_TAC[LE_REFL]; ALL_TAC] THEN
10290       EXISTS_TAC `--drop(h(x:real^M))` THEN GEN_TAC THEN DISCH_TAC THEN
10291       MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> --a <= x`) THEN
10292       REWRITE_TAC[GSYM ABS_DROP] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
10293       ASM_REWRITE_TAC[];
10294       DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN REWRITE_TAC[LE_REFL]];
10295     W(MP_TAC o C SPEC SUP o rand o rand o snd) THEN
10296     REWRITE_TAC[] THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
10297     REWRITE_TAC[IMAGE_EQ_EMPTY; FORALL_IN_IMAGE; IN_ELIM_THM] THEN
10298     ANTS_TAC THENL
10299      [REWRITE_TAC[EXTENSION; NOT_IN_EMPTY; IN_ELIM_THM; NOT_FORALL_THM] THEN
10300       CONJ_TAC THENL [MESON_TAC[LE_REFL]; ALL_TAC] THEN
10301       EXISTS_TAC `drop(h(x:real^M))` THEN GEN_TAC THEN DISCH_TAC THEN
10302       MATCH_MP_TAC(REAL_ARITH `abs(x) <= a ==> x <= a`) THEN
10303       REWRITE_TAC[GSYM ABS_DROP] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
10304       ASM_REWRITE_TAC[];
10305       DISCH_THEN(MATCH_MP_TAC o CONJUNCT1) THEN REWRITE_TAC[LE_REFL]]]);;
10306
10307 let DOMINATED_CONVERGENCE_INTEGRABLE = prove
10308  (`!f:num->real^M->real^N g h s.
10309          (!k. f k absolutely_integrable_on s) /\
10310          h integrable_on s /\
10311          (!k x. x IN s ==> norm(g x) <= drop(h x)) /\
10312          (!x. x IN s ==> ((\k. f k x) --> g x) sequentially)
10313          ==> g integrable_on s`,
10314   let lemma = prove
10315    (`!f:num->real^N->real^1 g h s.
10316           (!k. f k absolutely_integrable_on s) /\
10317           h integrable_on s /\
10318           (!x. x IN s ==> norm(g x) <= drop(h x)) /\
10319           (!x. x IN s ==> ((\k. f k x) --> g x) sequentially)
10320           ==> g integrable_on s`,
10321     REPEAT STRIP_TAC THEN
10322     SUBGOAL_THEN `(h:real^N->real^1) absolutely_integrable_on s`
10323     ASSUME_TAC THENL
10324      [MATCH_MP_TAC NONNEGATIVE_ABSOLUTELY_INTEGRABLE THEN
10325       ASM_REWRITE_TAC[DIMINDEX_1; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
10326       REWRITE_TAC[DIMINDEX_1; FORALL_1; GSYM drop; IMP_IMP] THEN
10327       ASM_MESON_TAC[REAL_LE_TRANS; NORM_POS_LE];
10328       ALL_TAC] THEN
10329     MP_TAC(ISPECL
10330      [`\n:num x:real^N.
10331          lift(min (max (--(drop(h x))) (drop(f n x))) (drop(h x)))`;
10332       `g:real^N->real^1`;
10333       `h:real^N->real^1`;
10334       `s:real^N->bool`] DOMINATED_CONVERGENCE) THEN
10335     ANTS_TAC THENL [ASM_REWRITE_TAC[]; SIMP_TAC[]] THEN REPEAT CONJ_TAC THENL
10336      [X_GEN_TAC `n:num` THEN
10337       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_IMP_INTEGRABLE THEN
10338       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MIN_1 THEN
10339       ASM_REWRITE_TAC[LIFT_DROP; ETA_AX] THEN
10340       MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_MAX_1 THEN
10341       ASM_SIMP_TAC[LIFT_NEG; LIFT_DROP; ETA_AX; ABSOLUTELY_INTEGRABLE_NEG];
10342       MAP_EVERY X_GEN_TAC [`n:num`; `x:real^N`] THEN DISCH_TAC THEN
10343       REWRITE_TAC[LIFT_DROP; ABS_DROP] THEN
10344       SUBGOAL_THEN `&0 <= drop((h:real^N->real^1) x)` MP_TAC THENL
10345        [ASM_MESON_TAC[REAL_LE_TRANS; NORM_POS_LE]; REAL_ARITH_TAC];
10346       X_GEN_TAC `x:real^N` THEN REWRITE_TAC[IN_DIFF] THEN STRIP_TAC THEN
10347       UNDISCH_TAC
10348        `!x. x IN s ==> ((\n. (f:num->real^N->real^1) n x) --> g x)
10349                           sequentially` THEN
10350       DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_REWRITE_TAC[] THEN
10351       REWRITE_TAC[tendsto] THEN MATCH_MP_TAC MONO_FORALL THEN
10352       X_GEN_TAC `e:real` THEN ASM_CASES_TAC `&0 < e` THEN
10353       ASM_REWRITE_TAC[] THEN
10354       MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] EVENTUALLY_MONO) THEN
10355       X_GEN_TAC `n:num` THEN REWRITE_TAC[] THEN
10356       FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
10357       ASM_REWRITE_TAC[dist; ABS_DROP; DROP_SUB; LIFT_DROP] THEN
10358       REAL_ARITH_TAC]) in
10359   REPEAT GEN_TAC THEN
10360   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
10361   ONCE_REWRITE_TAC[ABSOLUTELY_INTEGRABLE_COMPONENTWISE;
10362                    INTEGRABLE_COMPONENTWISE] THEN
10363   DISCH_TAC THEN X_GEN_TAC `k:num` THEN STRIP_TAC THEN
10364   MATCH_MP_TAC lemma THEN
10365   EXISTS_TAC `\i x. lift(((f:num->real^M->real^N) i x)$k)` THEN
10366   EXISTS_TAC `h:real^M->real^1` THEN ASM_SIMP_TAC[] THEN CONJ_TAC THENL
10367    [ASM_MESON_TAC[COMPONENT_LE_NORM; NORM_LIFT; REAL_LE_TRANS];
10368     RULE_ASSUM_TAC(ONCE_REWRITE_RULE[LIM_COMPONENTWISE_LIFT]) THEN
10369     RULE_ASSUM_TAC BETA_RULE THEN ASM_SIMP_TAC[]]);;
10370
10371 let DOMINATED_CONVERGENCE_ABSOLUTELY_INTEGRABLE = prove
10372  (`!f:num->real^M->real^N g h s.
10373          (!k. f k absolutely_integrable_on s) /\
10374          h integrable_on s /\
10375          (!k x. x IN s ==> norm(g x) <= drop(h x)) /\
10376          (!x. x IN s ==> ((\k. f k x) --> g x) sequentially)
10377          ==> g absolutely_integrable_on s`,
10378   REPEAT STRIP_TAC THEN
10379   MATCH_MP_TAC ABSOLUTELY_INTEGRABLE_INTEGRABLE_BOUND THEN
10380   EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[] THEN
10381   MATCH_MP_TAC DOMINATED_CONVERGENCE_INTEGRABLE THEN
10382   EXISTS_TAC `f:num->real^M->real^N` THEN
10383   EXISTS_TAC `h:real^M->real^1` THEN ASM_REWRITE_TAC[]);;
10384
10385 (* ------------------------------------------------------------------------- *)
10386 (* A few more properties of negligible sets.                                 *)
10387 (* ------------------------------------------------------------------------- *)
10388
10389 let NEGLIGIBLE_ON_UNIV = prove
10390  (`!s. negligible s <=> (indicator s has_integral vec 0) (:real^N)`,
10391   GEN_TAC THEN EQ_TAC THENL [SIMP_TAC[NEGLIGIBLE]; ALL_TAC] THEN
10392   DISCH_TAC THEN REWRITE_TAC[negligible] THEN
10393   MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
10394   SUBGOAL_THEN `indicator s integrable_on interval[a:real^N,b]`
10395   ASSUME_TAC THENL
10396    [MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
10397     EXISTS_TAC `(:real^N)` THEN ASM_MESON_TAC[SUBSET_UNIV; integrable_on];
10398     ASM_SIMP_TAC[GSYM INTEGRAL_EQ_HAS_INTEGRAL] THEN
10399     REWRITE_TAC[GSYM DROP_EQ; GSYM REAL_LE_ANTISYM] THEN
10400     CONJ_TAC THENL
10401      [FIRST_ASSUM(SUBST1_TAC o SYM o MATCH_MP INTEGRAL_UNIQUE) THEN
10402       MATCH_MP_TAC INTEGRAL_SUBSET_DROP_LE;
10403       REWRITE_TAC[DROP_VEC] THEN MATCH_MP_TAC INTEGRAL_DROP_POS] THEN
10404     ASM_REWRITE_TAC[SUBSET_UNIV; DROP_INDICATOR_POS_LE] THEN
10405     ASM_MESON_TAC[integrable_on]]);;
10406
10407 let NEGLIGIBLE_COUNTABLE_UNIONS = prove
10408  (`!s:num->real^N->bool.
10409         (!n. negligible(s n)) ==> negligible(UNIONS {s(n) | n IN (:num)})`,
10410   REPEAT STRIP_TAC THEN
10411   MP_TAC(ISPECL [`\n. indicator(UNIONS {(s:num->real^N->bool)(m) | m <= n})`;
10412              `indicator(UNIONS {(s:num->real^N->bool)(m) | m IN (:num)})`;
10413                  `(:real^N)`] MONOTONE_CONVERGENCE_INCREASING) THEN
10414   SUBGOAL_THEN
10415    `!n. negligible(UNIONS {(s:num->real^N->bool)(m) | m <= n})`
10416   ASSUME_TAC THENL
10417    [GEN_TAC THEN MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN
10418     ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
10419     ASM_SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG_LE; FORALL_IN_IMAGE];
10420     ALL_TAC] THEN
10421   SUBGOAL_THEN
10422    `!n:num. (indicator (UNIONS {s m | m <= n})) integrable_on (:real^N)`
10423   ASSUME_TAC THENL
10424    [ASM_MESON_TAC[NEGLIGIBLE_ON_UNIV; integrable_on]; ALL_TAC] THEN
10425   SUBGOAL_THEN
10426    `!n:num. integral (:real^N) (indicator (UNIONS {s m | m <= n})) = vec 0`
10427   ASSUME_TAC THENL
10428    [ASM_MESON_TAC[NEGLIGIBLE_ON_UNIV; INTEGRAL_UNIQUE]; ALL_TAC] THEN
10429   ASM_SIMP_TAC[NEGLIGIBLE_ON_UNIV; LIM_CONST_EQ;
10430                TRIVIAL_LIMIT_SEQUENTIALLY] THEN
10431   ANTS_TAC THENL [ALL_TAC; MESON_TAC[INTEGRAL_EQ_HAS_INTEGRAL]] THEN
10432   REPEAT CONJ_TAC THENL
10433    [MAP_EVERY X_GEN_TAC [`k:num`; `x:real^N`] THEN DISCH_TAC THEN
10434     REWRITE_TAC[indicator] THEN
10435     SUBGOAL_THEN
10436      `x IN UNIONS {(s:num->real^N->bool) m | m <= k}
10437       ==> x IN UNIONS {s m | m <= SUC k}`
10438     MP_TAC THENL
10439      [SPEC_TAC(`x:real^N`,`x:real^N`) THEN
10440       REWRITE_TAC[GSYM SUBSET] THEN MATCH_MP_TAC SUBSET_UNIONS THEN
10441       ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN MATCH_MP_TAC IMAGE_SUBSET THEN
10442       REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN ARITH_TAC;
10443       REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[]) THEN
10444       REWRITE_TAC[DROP_VEC; REAL_LE_REFL; REAL_POS]];
10445     X_GEN_TAC `x:real^N` THEN DISCH_THEN(K ALL_TAC) THEN
10446     MATCH_MP_TAC LIM_EVENTUALLY THEN
10447     REWRITE_TAC[EVENTUALLY_SEQUENTIALLY; indicator] THEN
10448     ASM_CASES_TAC `x IN UNIONS {(s:num->real^N->bool) m | m IN (:num)}` THENL
10449      [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [UNIONS_GSPEC]) THEN
10450       REWRITE_TAC[IN_ELIM_THM; IN_UNIV] THEN MATCH_MP_TAC MONO_EXISTS THEN
10451       X_GEN_TAC `m:num` THEN DISCH_TAC THEN
10452       X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10453       REWRITE_TAC[UNIONS_GSPEC; IN_ELIM_THM] THEN ASM_MESON_TAC[];
10454       EXISTS_TAC `0` THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10455       ASM_REWRITE_TAC[] THEN
10456       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (RAND_CONV o RAND_CONV)
10457         [UNIONS_GSPEC]) THEN
10458       REWRITE_TAC[UNIONS_GSPEC; IN_ELIM_THM; IN_UNIV] THEN MESON_TAC[]];
10459     REWRITE_TAC[SET_RULE `{c | x | x IN UNIV} = {c}`;
10460                 BOUNDED_INSERT; BOUNDED_EMPTY]]);;
10461
10462 let HAS_INTEGRAL_NEGLIGIBLE_EQ = prove
10463  (`!f:real^M->real^N s.
10464         (!x i. x IN s /\ 1 <= i /\ i <= dimindex(:N) ==> &0 <= f(x)$i)
10465         ==> ((f has_integral vec 0) s <=>
10466              negligible {x | x IN s /\ ~(f x = vec 0)})`,
10467   let lemma = prove
10468    (`!f:real^N->real^1 s.
10469           (!x. x IN s ==> &0 <= drop(f x)) /\ (f has_integral vec 0) s
10470           ==> negligible {x | x IN s /\ ~(f x = vec 0)}`,
10471     REPEAT STRIP_TAC THEN MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC
10472      `UNIONS {{x | x IN s /\ norm((f:real^N->real^1) x) >= &1 / (&n + &1)} |
10473               n IN (:num)}` THEN
10474     CONJ_TAC THENL
10475      [MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS THEN
10476       X_GEN_TAC `n:num` THEN REWRITE_TAC[NEGLIGIBLE_ON_UNIV; indicator] THEN
10477       MATCH_MP_TAC HAS_INTEGRAL_STRADDLE_NULL THEN
10478       EXISTS_TAC `(\x. if x IN s then (&n + &1) % f(x) else vec 0):
10479                   real^N->real^1` THEN
10480       CONJ_TAC THENL
10481        [REWRITE_TAC[IN_UNIV; IN_ELIM_THM; real_ge] THEN
10482         X_GEN_TAC `x:real^N` THEN COND_CASES_TAC THEN
10483         ASM_SIMP_TAC[DROP_VEC; DROP_CMUL; REAL_POS] THENL
10484          [ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
10485           ASM_SIMP_TAC[GSYM REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
10486           MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ a <= abs x ==> a <= x`) THEN
10487           ASM_SIMP_TAC[GSYM ABS_DROP];
10488           COND_CASES_TAC THEN REWRITE_TAC[DROP_VEC; REAL_POS; DROP_CMUL] THEN
10489           ASM_SIMP_TAC[REAL_POS; REAL_LE_MUL; REAL_LE_ADD]];
10490         REWRITE_TAC[HAS_INTEGRAL_RESTRICT_UNIV] THEN
10491         SUBST1_TAC(VECTOR_ARITH `vec 0:real^1 = (&n + &1) % vec 0`) THEN
10492         MATCH_MP_TAC HAS_INTEGRAL_CMUL THEN ASM_REWRITE_TAC[]];
10493       REWRITE_TAC[SUBSET; IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN
10494       REWRITE_TAC[GSYM NORM_POS_LT] THEN ONCE_REWRITE_TAC[REAL_ARCH_INV] THEN
10495       DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_THEN `n:num`
10496         STRIP_ASSUME_TAC)) THEN
10497       REWRITE_TAC[IN_UNIONS; EXISTS_IN_GSPEC] THEN
10498       EXISTS_TAC `n - 1` THEN ASM_SIMP_TAC[IN_UNIV; IN_ELIM_THM; real_ge] THEN
10499       ASM_SIMP_TAC[REAL_OF_NUM_ADD; SUB_ADD; LE_1] THEN
10500       ASM_SIMP_TAC[real_div; REAL_MUL_LID; REAL_LT_IMP_LE]]) in
10501   REPEAT STRIP_TAC THEN EQ_TAC THEN DISCH_TAC THENL
10502    [ALL_TAC;
10503     MATCH_MP_TAC HAS_INTEGRAL_NEGLIGIBLE THEN
10504     EXISTS_TAC `{x | x IN s /\ ~((f:real^M->real^N) x = vec 0)}` THEN
10505     ASM_REWRITE_TAC[IN_DIFF; IN_ELIM_THM] THEN MESON_TAC[]] THEN
10506   MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN
10507   EXISTS_TAC `UNIONS {{x | x IN s /\ ~(((f:real^M->real^N) x)$k = &0)} |
10508                       k IN 1..dimindex(:N)}` THEN
10509   CONJ_TAC THENL
10510    [MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN
10511     SIMP_TAC[SIMPLE_IMAGE; FINITE_IMAGE; FINITE_NUMSEG; FORALL_IN_IMAGE] THEN
10512     X_GEN_TAC `k:num` THEN REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN
10513     REWRITE_TAC[GSYM LIFT_EQ; LIFT_NUM] THEN MATCH_MP_TAC lemma THEN
10514     ASM_SIMP_TAC[LIFT_DROP] THEN
10515     FIRST_X_ASSUM(MP_TAC o ISPEC `\y:real^N. lift(y$k)` o
10516       MATCH_MP(REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_LINEAR)) THEN
10517     REWRITE_TAC[o_DEF; VEC_COMPONENT; LIFT_NUM] THEN
10518     DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[linear] THEN
10519     SIMP_TAC[LIFT_ADD; VECTOR_ADD_COMPONENT; LIFT_CMUL; VECTOR_MUL_COMPONENT];
10520     REWRITE_TAC[SUBSET; IN_UNIONS; EXISTS_IN_GSPEC; CART_EQ; IN_NUMSEG] THEN
10521     REWRITE_TAC[VEC_COMPONENT; IN_ELIM_THM] THEN MESON_TAC[]]);;
10522
10523 let NEGLIGIBLE_COUNTABLE = prove
10524  (`!s:real^N->bool. COUNTABLE s ==> negligible s`,
10525   let lemma = prove
10526    (`IMAGE f s = UNIONS {{f x} | x IN s}`,
10527     REWRITE_TAC[EXTENSION; IN_IMAGE; IN_UNIONS; IN_SING; IN_ELIM_THM] THEN
10528     MESON_TAC[IN_SING]) in
10529   GEN_TAC THEN ASM_CASES_TAC `s:real^N->bool = {}` THEN
10530   ASM_REWRITE_TAC[NEGLIGIBLE_EMPTY] THEN
10531   POP_ASSUM MP_TAC THEN REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN
10532   DISCH_THEN(X_CHOOSE_THEN `f:num->real^N` SUBST1_TAC o
10533     MATCH_MP COUNTABLE_AS_IMAGE) THEN
10534   ONCE_REWRITE_TAC[lemma] THEN MATCH_MP_TAC NEGLIGIBLE_COUNTABLE_UNIONS THEN
10535   REWRITE_TAC[NEGLIGIBLE_SING]);;
10536
10537 (* ------------------------------------------------------------------------- *)
10538 (* Beppo Levi theorem.                                                       *)
10539 (* ------------------------------------------------------------------------- *)
10540
10541 let BEPPO_LEVI_INCREASING = prove
10542  (`!f:num->real^N->real^1 s.
10543         (!k. (f k) integrable_on s) /\
10544         (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\
10545         bounded {integral s (f k) | k IN (:num)}
10546         ==> ?g k. negligible k /\
10547                   !x. x IN (s DIFF k) ==> ((\k. f k x) --> g x) sequentially`,
10548   SUBGOAL_THEN
10549    `!f:num->real^N->real^1 s.
10550         (!k x. x IN s ==> &0 <= drop(f k x)) /\
10551         (!k. (f k) integrable_on s) /\
10552         (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\
10553         bounded {integral s (f k) | k IN (:num)}
10554         ==> ?g k. negligible k /\
10555                   !x. x IN (s DIFF k) ==> ((\k. f k x) --> g x) sequentially`
10556   ASSUME_TAC THENL
10557    [ALL_TAC;
10558     REPEAT GEN_TAC THEN STRIP_TAC THEN
10559     FIRST_X_ASSUM(MP_TAC o ISPECL
10560      [`\n x:real^N. f(n:num) x - f 0 x:real^1`; `s:real^N->bool`]) THEN
10561     REWRITE_TAC[] THEN ANTS_TAC THEN REPEAT CONJ_TAC THENL
10562      [REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_SUB; REAL_SUB_LE] THEN
10563       MP_TAC(ISPEC
10564         `\m n:num. drop (f m (x:real^N)) <= drop (f n x)`
10565         TRANSITIVE_STEPWISE_LE) THEN
10566       REWRITE_TAC[REAL_LE_TRANS; REAL_LE_REFL] THEN ASM_MESON_TAC[LE_0];
10567       GEN_TAC THEN MATCH_MP_TAC INTEGRABLE_SUB THEN ASM_REWRITE_TAC[ETA_AX];
10568       REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_SUB; REAL_SUB_LE] THEN
10569       ASM_SIMP_TAC[REAL_ARITH `x - a <= y - a <=> x <= y`];
10570       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
10571       ASM_SIMP_TAC[INTEGRAL_SUB; ETA_AX; bounded] THEN
10572       ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
10573       REWRITE_TAC[FORALL_IN_IMAGE; IN_UNIV] THEN
10574       DISCH_THEN(X_CHOOSE_THEN `B:real`
10575         (fun th -> EXISTS_TAC `B + norm(integral s (f 0:real^N->real^1))` THEN
10576                    X_GEN_TAC `k:num` THEN MP_TAC(SPEC `k:num` th))) THEN
10577       NORM_ARITH_TAC;
10578       ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
10579       GEN_TAC THEN
10580       DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^1` STRIP_ASSUME_TAC) THEN
10581       EXISTS_TAC `(\x. g x + f 0 x):real^N->real^1` THEN
10582       ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^N` THEN
10583       DISCH_TAC THEN FIRST_X_ASSUM(MP_TAC o SPEC `x:real^N`) THEN
10584       ASM_REWRITE_TAC[LIM_SEQUENTIALLY; dist] THEN
10585       REWRITE_TAC[VECTOR_ARITH `a - b - c:real^1 = a - (c + b)`]]] THEN
10586   REPEAT STRIP_TAC THEN
10587   ABBREV_TAC
10588    `g = \i n:num x:real^N. lift(min (drop(f n x) / (&i + &1)) (&1))` THEN
10589   SUBGOAL_THEN
10590    `!i n. ((g:num->num->real^N->real^1) i n) integrable_on s`
10591   ASSUME_TAC THENL
10592    [REPEAT GEN_TAC THEN EXPAND_TAC "g" THEN
10593     MATCH_MP_TAC INTEGRABLE_MIN_CONST_1 THEN
10594     ASM_SIMP_TAC[REAL_POS; REAL_LE_DIV; REAL_LE_ADD] THEN
10595     REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div] THEN
10596     ASM_SIMP_TAC[LIFT_CMUL; LIFT_DROP; INTEGRABLE_CMUL; ETA_AX];
10597     ALL_TAC] THEN
10598   SUBGOAL_THEN
10599    `!i:num k:num x:real^N. x IN s ==> drop(g i k x) <= drop(g i (SUC k) x)`
10600   ASSUME_TAC THENL
10601    [REPEAT STRIP_TAC THEN EXPAND_TAC "g" THEN REWRITE_TAC[LIFT_DROP] THEN
10602     MATCH_MP_TAC(REAL_ARITH `x <= y ==> min x a <= min y a`) THEN
10603     ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_ARITH `&0 < &n + &1`];
10604     ALL_TAC] THEN
10605   SUBGOAL_THEN `!i:num k:num x:real^N. x IN s ==> norm(g i k x:real^1) <= &1`
10606   ASSUME_TAC THENL
10607    [REPEAT STRIP_TAC THEN EXPAND_TAC "g" THEN
10608     REWRITE_TAC[LIFT_DROP; NORM_REAL; GSYM drop] THEN
10609     MATCH_MP_TAC(REAL_ARITH `&0 <= x ==> abs(min x (&1)) <= &1`) THEN
10610     ASM_SIMP_TAC[REAL_POS; REAL_LE_DIV; REAL_LE_ADD];
10611     ALL_TAC] THEN
10612   SUBGOAL_THEN
10613    `!i:num x:real^N. x IN s ==> ?h:real^1. ((\n. g i n x) --> h) sequentially`
10614   MP_TAC THENL
10615    [REPEAT STRIP_TAC THEN
10616     MP_TAC(ISPECL
10617      [`\n. drop(g (i:num) (n:num) (x:real^N))`; `&1`]
10618      CONVERGENT_BOUNDED_MONOTONE) THEN
10619     REWRITE_TAC[] THEN ANTS_TAC THENL
10620      [ASM_SIMP_TAC[GSYM ABS_DROP] THEN DISJ1_TAC THEN
10621       MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
10622       ASM_SIMP_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN REAL_ARITH_TAC;
10623       DISCH_THEN(X_CHOOSE_THEN `l:real` (fun th ->
10624         EXISTS_TAC `lift l` THEN MP_TAC th)) THEN
10625       REWRITE_TAC[LIM_SEQUENTIALLY; DIST_REAL; GSYM drop; LIFT_DROP]];
10626     GEN_REWRITE_TAC (LAND_CONV o REDEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
10627     REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM]] THEN
10628   X_GEN_TAC `h:num->real^N->real^1` THEN STRIP_TAC THEN
10629   MP_TAC(GEN `i:num `(ISPECL
10630    [`g(i:num):num->real^N->real^1`; `h(i:num):real^N->real^1`;
10631     `s:real^N->bool`] MONOTONE_CONVERGENCE_INCREASING)) THEN
10632   DISCH_THEN(MP_TAC o MATCH_MP MONO_FORALL) THEN
10633   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
10634    [GEN_TAC THEN REWRITE_TAC[bounded] THEN
10635     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
10636     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `K:real` THEN
10637     REWRITE_TAC[FORALL_IN_GSPEC] THEN REWRITE_TAC[IN_UNIV] THEN
10638     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:num` THEN
10639     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN
10640     MATCH_MP_TAC(REAL_ARITH
10641      `norm a = drop a /\ x <= drop a ==> x <= norm a`) THEN
10642     CONJ_TAC THENL
10643      [REWRITE_TAC[NORM_REAL; GSYM drop; REAL_ABS_REFL] THEN
10644       MATCH_MP_TAC INTEGRAL_DROP_POS THEN ASM_SIMP_TAC[];
10645       MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
10646       ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
10647       EXPAND_TAC "g" THEN REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP] THEN
10648       MATCH_MP_TAC(REAL_ARITH
10649        `&0 <= x /\ x <= y ==> abs(min x (&1)) <= y`) THEN
10650       ASM_SIMP_TAC[REAL_LE_ADD; REAL_POS; REAL_LE_DIV] THEN
10651       SIMP_TAC[REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &i + &1`] THEN
10652       REWRITE_TAC[REAL_ARITH `a <= a * (x + &1) <=> &0 <= a * x`] THEN
10653       ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS]];
10654     REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC] THEN
10655   ABBREV_TAC
10656    `Z =
10657     {x:real^N | x IN s /\ ~(?l:real^1. ((\k. f k x) --> l) sequentially)}` THEN
10658   ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN EXISTS_TAC `Z:real^N->bool` THEN
10659   REWRITE_TAC[RIGHT_EXISTS_AND_THM; GSYM SKOLEM_THM; RIGHT_EXISTS_IMP_THM] THEN
10660   CONJ_TAC THENL
10661    [ALL_TAC; EXPAND_TAC "Z" THEN REWRITE_TAC[IN_ELIM_THM] THEN SET_TAC[]] THEN
10662   MP_TAC(ISPECL
10663    [`h:num->real^N->real^1`;
10664     `(\x. if x IN Z then vec 1 else vec 0):real^N->real^1`;
10665     `s:real^N->bool`]
10666         MONOTONE_CONVERGENCE_DECREASING) THEN
10667   ASM_REWRITE_TAC[] THEN
10668   SUBGOAL_THEN
10669    `!i x:real^N. x IN s ==> drop(h (SUC i) x) <= drop(h i x)`
10670   ASSUME_TAC THENL
10671    [MAP_EVERY X_GEN_TAC [`i:num`; `x:real^N`] THEN DISCH_TAC THEN
10672     MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LE) THEN
10673     EXISTS_TAC `\n. (g:num->num->real^N->real^1) (SUC i) n x` THEN
10674     EXISTS_TAC `\n. (g:num->num->real^N->real^1) i n x` THEN
10675     ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
10676     MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `n:num` THEN
10677     EXPAND_TAC "g" THEN REWRITE_TAC[LIFT_DROP] THEN
10678     MATCH_MP_TAC(REAL_ARITH `x <= y ==> min x a <= min y a`) THEN
10679     REWRITE_TAC[real_div] THEN MATCH_MP_TAC REAL_LE_LMUL THEN
10680     ASM_SIMP_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
10681     REWRITE_TAC[GSYM REAL_OF_NUM_SUC] THEN REAL_ARITH_TAC;
10682     ASM_REWRITE_TAC[]] THEN
10683   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [BOUNDED_POS]) THEN
10684   REWRITE_TAC[FORALL_IN_GSPEC; IN_UNIV] THEN
10685   DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
10686   SUBGOAL_THEN
10687    `!i. norm(integral s ((h:num->real^N->real^1) i)) <= B / (&i + &1)`
10688   ASSUME_TAC THENL
10689    [X_GEN_TAC `i:num` THEN
10690     MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN
10691     EXISTS_TAC `\k. integral s ((g:num->num->real^N->real^1) i k)` THEN
10692     ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
10693     MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `n:num` THEN
10694     REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
10695     EXISTS_TAC
10696      `drop(integral s (\x. inv(&i + &1) % (f:num->real^N->real^1) n x))` THEN
10697     CONJ_TAC THENL
10698      [MATCH_MP_TAC INTEGRAL_NORM_BOUND_INTEGRAL THEN
10699       ASM_SIMP_TAC[INTEGRABLE_CMUL; ETA_AX] THEN
10700       X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN EXPAND_TAC "g" THEN
10701       REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP; DROP_CMUL] THEN
10702       MATCH_MP_TAC(REAL_ARITH
10703        `&0 <= x /\ x <= y ==> abs(min x (&1)) <= y`) THEN
10704       ASM_SIMP_TAC[REAL_LE_ADD; REAL_POS; REAL_LE_DIV] THEN
10705       REAL_ARITH_TAC;
10706       ASM_SIMP_TAC[INTEGRAL_CMUL; ETA_AX; DROP_CMUL] THEN
10707       ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
10708       ASM_SIMP_TAC[GSYM real_div; REAL_LE_DIV2_EQ;
10709                    REAL_ARITH `&0 < &n + &1`] THEN
10710       MATCH_MP_TAC(REAL_ARITH `abs x <= a ==> x <= a`) THEN
10711       ASM_REWRITE_TAC[GSYM ABS_DROP]];
10712     ALL_TAC] THEN
10713   ANTS_TAC THENL
10714    [REWRITE_TAC[bounded; FORALL_IN_GSPEC] THEN CONJ_TAC THENL
10715      [ALL_TAC;
10716       EXISTS_TAC `B:real` THEN X_GEN_TAC `i:num` THEN
10717       MATCH_MP_TAC REAL_LE_TRANS THEN
10718       EXISTS_TAC `B / (&i + &1)` THEN ASM_REWRITE_TAC[] THEN
10719       ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_ARITH `&0 < &i + &1`] THEN
10720       REWRITE_TAC[REAL_ARITH `B <= B * (i + &1) <=> &0 <= i * B`] THEN
10721       ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS; REAL_LT_IMP_LE]] THEN
10722     X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
10723     ASM_CASES_TAC `(x:real^N) IN Z` THEN ASM_REWRITE_TAC[] THENL
10724      [MATCH_MP_TAC LIM_EVENTUALLY THEN
10725       UNDISCH_TAC `(x:real^N) IN Z` THEN EXPAND_TAC "Z" THEN
10726       REWRITE_TAC[IN_ELIM_THM] THEN ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
10727       MP_TAC(GEN `B:real` (ISPECL
10728         [`\n. drop(f (n:num) (x:real^N))`; `B:real`]
10729         CONVERGENT_BOUNDED_MONOTONE)) THEN
10730       REWRITE_TAC[LEFT_FORALL_IMP_THM; LEFT_EXISTS_AND_THM] THEN
10731       MATCH_MP_TAC(TAUT
10732        `q /\ ~r /\ (q ==> ~p ==> s)
10733         ==> (p /\ (q \/ q') ==> r) ==> s`) THEN
10734       CONJ_TAC THENL
10735        [MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
10736         ASM_SIMP_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN REAL_ARITH_TAC;
10737         ALL_TAC] THEN
10738       CONJ_TAC THENL
10739        [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [NOT_EXISTS_THM]) THEN
10740         ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN REWRITE_TAC[] THEN
10741         DISCH_THEN(X_CHOOSE_THEN `l:real` STRIP_ASSUME_TAC) THEN
10742         DISCH_THEN(MP_TAC o SPEC `lift l`) THEN
10743         REWRITE_TAC[LIM_SEQUENTIALLY] THEN
10744         X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10745         FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
10746         REWRITE_TAC[DIST_REAL; GSYM drop; DROP_SUB; LIFT_DROP];
10747         ALL_TAC] THEN
10748       DISCH_TAC THEN REWRITE_TAC[NOT_FORALL_THM; EVENTUALLY_SEQUENTIALLY] THEN
10749       REWRITE_TAC[NOT_EXISTS_THM; NOT_FORALL_THM; REAL_NOT_LE] THEN
10750       DISCH_TAC THEN
10751       EXISTS_TAC `0` THEN  X_GEN_TAC `i:num` THEN DISCH_TAC THEN
10752       MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
10753       EXISTS_TAC `(\n. (g:num->num->real^N->real^1) i n x)` THEN
10754       ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
10755       MATCH_MP_TAC LIM_EVENTUALLY THEN
10756       EXPAND_TAC "g" THEN REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
10757       FIRST_X_ASSUM(MP_TAC o SPEC `&i + &1`) THEN
10758       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
10759       DISCH_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10760       REWRITE_TAC[GSYM DROP_EQ; DROP_VEC; LIFT_DROP] THEN
10761       REWRITE_TAC[REAL_ARITH `min a b = b <=> b <= a`] THEN
10762       SIMP_TAC[REAL_LE_RDIV_EQ; REAL_ARITH `&0 < &i + &1`; REAL_MUL_LID] THEN
10763       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
10764        `a < abs N ==> &0 <= N /\ N <= n ==> a <= n`)) THEN
10765       ASM_SIMP_TAC[];
10766       UNDISCH_TAC `~((x:real^N) IN Z)` THEN EXPAND_TAC "Z" THEN
10767       REWRITE_TAC[IN_ELIM_THM] THEN ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
10768       X_GEN_TAC `l:real^1` THEN
10769       DISCH_THEN(MP_TAC o MATCH_MP CONVERGENT_IMP_BOUNDED) THEN
10770       REWRITE_TAC[BOUNDED_POS; FORALL_IN_IMAGE; IN_UNIV] THEN
10771       DISCH_THEN(X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC) THEN
10772       REWRITE_TAC[LIM_SEQUENTIALLY; DIST_0] THEN
10773       X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10774       MP_TAC(ISPEC `e / C:real` REAL_ARCH_INV) THEN
10775       ASM_SIMP_TAC[REAL_LT_DIV] THEN MATCH_MP_TAC MONO_EXISTS THEN
10776       X_GEN_TAC `N:num` THEN ASM_SIMP_TAC[REAL_LT_RDIV_EQ] THEN STRIP_TAC THEN
10777       X_GEN_TAC `i:num` THEN DISCH_TAC THEN
10778       MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N) * C` THEN
10779       ASM_REWRITE_TAC[] THEN
10780       MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `C / (&i + &1)` THEN
10781       CONJ_TAC THENL
10782        [ALL_TAC;
10783         REWRITE_TAC[ONCE_REWRITE_RULE[REAL_MUL_SYM] real_div] THEN
10784         ASM_SIMP_TAC[REAL_LE_RMUL_EQ] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
10785         ASM_REWRITE_TAC[REAL_OF_NUM_LT; REAL_OF_NUM_LE; REAL_OF_NUM_ADD] THEN
10786         ASM_ARITH_TAC] THEN
10787       MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN
10788       EXISTS_TAC `\n. (g:num->num->real^N->real^1) i n x` THEN
10789       ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
10790       MATCH_MP_TAC ALWAYS_EVENTUALLY THEN X_GEN_TAC `n:num` THEN
10791       EXPAND_TAC "g" THEN REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP] THEN
10792       MATCH_MP_TAC(REAL_ARITH
10793        `&0 <= x /\ x <= a ==> abs(min x (&1)) <= a`) THEN
10794       ASM_SIMP_TAC[REAL_LE_DIV; REAL_LE_ADD; REAL_POS] THEN
10795       ASM_SIMP_TAC[REAL_LE_DIV2_EQ; REAL_ARITH `&0 < &i + &1`] THEN
10796       MATCH_MP_TAC(REAL_ARITH `abs x <= a ==> x <= a`) THEN
10797       ASM_REWRITE_TAC[GSYM NORM_LIFT; LIFT_DROP]];
10798     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
10799     MATCH_MP_TAC(MESON[LIM_UNIQUE; TRIVIAL_LIMIT_SEQUENTIALLY]
10800      `(f --> vec 0) sequentially /\ (i = vec 0 ==> p)
10801       ==> (f --> i) sequentially ==> p`) THEN
10802     CONJ_TAC THENL
10803      [MATCH_MP_TAC LIM_NULL_COMPARISON THEN
10804       EXISTS_TAC `\i. B / (&i + &1)` THEN
10805       ASM_SIMP_TAC[ALWAYS_EVENTUALLY] THEN
10806       REWRITE_TAC[real_div; LIFT_CMUL] THEN
10807       SUBST1_TAC(VECTOR_ARITH `vec 0:real^1 = B % vec 0`) THEN
10808       MATCH_MP_TAC LIM_CMUL THEN
10809       REWRITE_TAC[LIM_SEQUENTIALLY; DIST_0] THEN
10810       X_GEN_TAC `e:real` THEN GEN_REWRITE_TAC LAND_CONV [REAL_ARCH_INV] THEN
10811       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
10812       X_GEN_TAC `n:num` THEN DISCH_TAC THEN
10813       REWRITE_TAC[NORM_LIFT; GSYM drop; LIFT_DROP; REAL_ABS_INV] THEN
10814       MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN
10815       ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
10816       REWRITE_TAC[REAL_ARITH `abs(&n + &1) = &n + &1`] THEN
10817       REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
10818       ASM_ARITH_TAC;
10819       ASM_SIMP_TAC[INTEGRAL_EQ_HAS_INTEGRAL] THEN
10820       W(MP_TAC o PART_MATCH (lhs o rand) HAS_INTEGRAL_NEGLIGIBLE_EQ o
10821         lhand o snd) THEN
10822       ANTS_TAC THENL
10823        [REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
10824         REWRITE_TAC[IMP_IMP; DIMINDEX_1; FORALL_1; GSYM drop] THEN
10825         REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
10826         REWRITE_TAC[DROP_VEC; REAL_POS];
10827         DISCH_THEN SUBST1_TAC THEN
10828         MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] NEGLIGIBLE_SUBSET) THEN
10829         SIMP_TAC[SUBSET; IN_ELIM_THM; VEC_EQ; ARITH_EQ] THEN
10830         EXPAND_TAC "Z" THEN SIMP_TAC[IN_ELIM_THM]]]]);;
10831
10832 let BEPPO_LEVI_DECREASING = prove
10833  (`!f:num->real^N->real^1 s.
10834         (!k. (f k) integrable_on s) /\
10835         (!k x. x IN s ==> drop(f (SUC k) x) <= drop(f k x)) /\
10836         bounded {integral s (f k) | k IN (:num)}
10837         ==> ?g k. negligible k /\
10838                   !x. x IN (s DIFF k) ==> ((\k. f k x) --> g x) sequentially`,
10839   REPEAT STRIP_TAC THEN
10840   MP_TAC(ISPECL [`\n x. --((f:num->real^N->real^1) n x)`; `s:real^N->bool`]
10841         BEPPO_LEVI_INCREASING) THEN
10842   ASM_SIMP_TAC[INTEGRABLE_NEG; DROP_NEG; ETA_AX; REAL_LE_NEG2] THEN
10843   ANTS_TAC THENL
10844    [REWRITE_TAC[bounded] THEN
10845     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [bounded]) THEN
10846     REWRITE_TAC[FORALL_IN_GSPEC] THEN
10847     ASM_SIMP_TAC[INTEGRAL_NEG; ETA_AX; NORM_NEG];
10848     ONCE_REWRITE_TAC[SWAP_EXISTS_THM] THEN MATCH_MP_TAC MONO_EXISTS THEN
10849     X_GEN_TAC `k:real^N->bool` THEN
10850     DISCH_THEN(X_CHOOSE_THEN `g:real^N->real^1` STRIP_ASSUME_TAC) THEN
10851     EXISTS_TAC `\x. --((g:real^N->real^1) x)` THEN
10852     ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
10853     GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV o ABS_CONV)
10854       [GSYM VECTOR_NEG_NEG] THEN
10855     ASM_SIMP_TAC[LIM_NEG_EQ]]);;
10856
10857 let BEPPO_LEVI_MONOTONE_CONVERGENCE_INCREASING = prove
10858  (`!f:num->real^N->real^1 s.
10859         (!k. (f k) integrable_on s) /\
10860         (!k x. x IN s ==> drop(f k x) <= drop(f (SUC k) x)) /\
10861         bounded {integral s (f k) | k IN (:num)}
10862         ==> ?g k. negligible k /\
10863                   (!x. x IN (s DIFF k)
10864                        ==> ((\k. f k x) --> g x) sequentially) /\
10865                   g integrable_on s /\
10866                   ((\k. integral s (f k)) --> integral s g) sequentially`,
10867   REPEAT GEN_TAC THEN DISCH_TAC THEN
10868   FIRST_ASSUM(MP_TAC o MATCH_MP BEPPO_LEVI_INCREASING) THEN
10869   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^1` THEN
10870   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^N->bool` THEN
10871   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
10872   SUBGOAL_THEN
10873    `(g:real^N->real^1) integrable_on (s DIFF k) /\
10874     ((\i. integral (s DIFF k) (f i)) --> integral (s DIFF k) g) sequentially`
10875   MP_TAC THENL
10876    [MATCH_MP_TAC MONOTONE_CONVERGENCE_INCREASING THEN
10877     ASM_REWRITE_TAC[] THEN
10878     FIRST_X_ASSUM(MP_TAC o check (is_conj o concl));
10879     ALL_TAC] THEN
10880   (SUBGOAL_THEN
10881     `!f:real^N->real^1. integral (s DIFF k) f = integral s f /\
10882                         (f integrable_on (s DIFF k) <=> f integrable_on s)`
10883     (fun th -> SIMP_TAC[th; IN_DIFF]) THEN
10884    GEN_TAC THEN CONJ_TAC THEN TRY EQ_TAC THEN
10885    (MATCH_MP_TAC INTEGRABLE_SPIKE_SET ORELSE
10886     MATCH_MP_TAC INTEGRAL_SPIKE_SET) THEN
10887    FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
10888         NEGLIGIBLE_SUBSET)) THEN
10889      SET_TAC[]));;
10890
10891 let BEPPO_LEVI_MONOTONE_CONVERGENCE_DECREASING = prove
10892  (`!f:num->real^N->real^1 s.
10893         (!k. (f k) integrable_on s) /\
10894         (!k x. x IN s ==> drop(f (SUC k) x) <= drop(f k x)) /\
10895         bounded {integral s (f k) | k IN (:num)}
10896         ==> ?g k. negligible k /\
10897                   (!x. x IN (s DIFF k)
10898                        ==> ((\k. f k x) --> g x) sequentially) /\
10899                   g integrable_on s /\
10900                   ((\k. integral s (f k)) --> integral s g) sequentially`,
10901   REPEAT GEN_TAC THEN DISCH_TAC THEN
10902   FIRST_ASSUM(MP_TAC o MATCH_MP BEPPO_LEVI_DECREASING) THEN
10903   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^N->real^1` THEN
10904   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `k:real^N->bool` THEN
10905   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
10906   SUBGOAL_THEN
10907    `(g:real^N->real^1) integrable_on (s DIFF k) /\
10908     ((\i. integral (s DIFF k) (f i)) --> integral (s DIFF k) g) sequentially`
10909   MP_TAC THENL
10910    [MATCH_MP_TAC MONOTONE_CONVERGENCE_DECREASING THEN
10911     ASM_REWRITE_TAC[] THEN
10912     FIRST_X_ASSUM(MP_TAC o check (is_conj o concl));
10913     ALL_TAC] THEN
10914   (SUBGOAL_THEN
10915     `!f:real^N->real^1. integral (s DIFF k) f = integral s f /\
10916                         (f integrable_on (s DIFF k) <=> f integrable_on s)`
10917     (fun th -> SIMP_TAC[th; IN_DIFF]) THEN
10918    GEN_TAC THEN CONJ_TAC THEN TRY EQ_TAC THEN
10919    (MATCH_MP_TAC INTEGRABLE_SPIKE_SET ORELSE
10920     MATCH_MP_TAC INTEGRAL_SPIKE_SET) THEN
10921    FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
10922         NEGLIGIBLE_SUBSET)) THEN
10923      SET_TAC[]));;
10924
10925 (* ------------------------------------------------------------------------- *)
10926 (* Fundamental theorem of calculus, starting with strong forms.              *)
10927 (* ------------------------------------------------------------------------- *)
10928
10929 let FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG = prove
10930  (`!f:real^1->real^N f' s a b.
10931         COUNTABLE s /\
10932         drop a <= drop b /\ f continuous_on interval[a,b] /\
10933         (!x. x IN interval[a,b] DIFF s
10934              ==> (f has_vector_derivative f'(x)) (at x within interval[a,b]))
10935         ==> (f' has_integral (f(b) - f(a))) (interval[a,b])`,
10936   REPEAT STRIP_TAC THEN
10937   MATCH_MP_TAC HAS_INTEGRAL_SPIKE THEN
10938   EXISTS_TAC `(\x. if x IN s then vec 0 else f' x):real^1->real^N` THEN
10939   EXISTS_TAC `s:real^1->bool` THEN
10940   ASM_SIMP_TAC[NEGLIGIBLE_COUNTABLE; IN_DIFF] THEN
10941   SUBGOAL_THEN
10942    `?f t. s = IMAGE (f:num->real^1) t /\
10943           (!m n. m IN t /\ n IN t /\ f m = f n ==> m = n)`
10944   MP_TAC THENL
10945    [ASM_CASES_TAC `FINITE(s:real^1->bool)` THENL
10946      [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [FINITE_INDEX_NUMSEG]) THEN
10947       ASM_MESON_TAC[];
10948       MP_TAC(ISPEC `s:real^1->bool` COUNTABLE_AS_INJECTIVE_IMAGE) THEN
10949       ASM_REWRITE_TAC[INFINITE] THEN MESON_TAC[IN_UNIV]];
10950     REWRITE_TAC[LEFT_IMP_EXISTS_THM; INJECTIVE_ON_LEFT_INVERSE] THEN
10951     MAP_EVERY X_GEN_TAC [`r:num->real^1`; `t:num->bool`] THEN
10952     DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC) THEN
10953     DISCH_THEN(X_CHOOSE_TAC `n:real^1->num`)] THEN
10954   REWRITE_TAC[HAS_INTEGRAL_FACTOR_CONTENT] THEN
10955   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
10956   SUBGOAL_THEN
10957    `!x. ?d. &0 < d /\
10958             (x IN interval[a,b]
10959              ==> (x IN IMAGE (r:num->real^1) t
10960                   ==> !y. norm(y - x) < d /\ y IN interval[a,b]
10961                           ==> norm(f y - f x)
10962                               <= e / &2 pow (4 + n x) * norm(b - a)) /\
10963                  (~(x IN IMAGE r t)
10964                   ==> !y. norm(y - x) < d /\ y IN interval[a,b]
10965                           ==> norm(f y - f x - drop(y - x) % f' x:real^N)
10966                                 <= e / &2 * norm(y - x)))`
10967   MP_TAC THENL
10968    [X_GEN_TAC `x:real^1` THEN
10969     ASM_CASES_TAC `(x:real^1) IN interval[a,b]` THENL
10970      [ALL_TAC; EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[REAL_LT_01]] THEN
10971     ASM_CASES_TAC `x IN IMAGE (r:num->real^1) t` THEN ASM_REWRITE_TAC[] THENL
10972      [FIRST_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH
10973        `a <= b ==> a = b \/ a < b`)) THEN
10974       REWRITE_TAC[DROP_EQ] THEN STRIP_TAC THENL
10975        [EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01] THEN
10976         UNDISCH_TAC `(x:real^1) IN interval[a,b]` THEN
10977         ASM_SIMP_TAC[INTERVAL_SING; IN_SING; VECTOR_SUB_REFL; NORM_0] THEN
10978         REAL_ARITH_TAC;
10979         FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [continuous_on]) THEN
10980         DISCH_THEN(MP_TAC o SPEC `x:real^1`) THEN ASM_REWRITE_TAC[dist] THEN
10981         DISCH_THEN(MP_TAC o SPEC
10982          `e / &2 pow (4 + n(x:real^1)) * norm(b - a:real^1)`) THEN
10983         ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; NORM_POS_LT; VECTOR_SUB_EQ;
10984                      REAL_LT_POW2; GSYM DROP_EQ; REAL_LT_IMP_NE] THEN
10985         MESON_TAC[REAL_LT_IMP_LE]];
10986       FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN
10987       ASM_REWRITE_TAC[IN_DIFF; has_vector_derivative;
10988                       HAS_DERIVATIVE_WITHIN_ALT] THEN
10989       DISCH_THEN(MP_TAC o SPEC `e / &2` o CONJUNCT2) THEN
10990       ASM_REWRITE_TAC[REAL_HALF] THEN MESON_TAC[]];
10991     GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
10992     REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM; IMP_IMP;
10993                 TAUT `p ==> q /\ r <=> (p ==> q) /\ (p ==> r)`] THEN
10994     X_GEN_TAC `d:real^1->real` THEN
10995     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
10996     DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "E") (LABEL_TAC "U"))] THEN
10997   EXISTS_TAC `\x. ball(x:real^1,d(x))` THEN
10998   ASM_SIMP_TAC[GAUGE_BALL_DEPENDENT] THEN
10999   X_GEN_TAC `p:(real^1#(real^1->bool))->bool` THEN STRIP_TAC THEN
11000   MP_TAC(ISPECL [`f:real^1->real^N`; `p:(real^1#(real^1->bool))->bool`;
11001                  `a:real^1`; `b:real^1`]
11002                 ADDITIVE_TAGGED_DIVISION_1) THEN
11003   ASM_SIMP_TAC[CONTENT_1] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
11004   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
11005   ASM_SIMP_TAC[GSYM VSUM_SUB; LAMBDA_PAIR_THM] THEN
11006   SUBGOAL_THEN
11007    `p:(real^1#(real^1->bool))->bool =
11008     {(x,k) | (x,k) IN p /\ x IN IMAGE r (t:num->bool)} UNION
11009     {(x,k) | (x,k) IN p /\ ~(x IN IMAGE r (t:num->bool))}`
11010   SUBST1_TAC THENL
11011    [REWRITE_TAC[EXTENSION; FORALL_PAIR_THM; IN_ELIM_PAIR_THM; IN_UNION] THEN
11012     MESON_TAC[];
11013     ALL_TAC] THEN
11014   W(MP_TAC o PART_MATCH (lhs o rand) VSUM_UNION o rand o lhand o snd) THEN
11015   ANTS_TAC THENL
11016    [REWRITE_TAC[SET_RULE `DISJOINT s t <=> !x. x IN s ==> ~(x IN t)`] THEN
11017     SIMP_TAC[FORALL_IN_GSPEC; IN_ELIM_PAIR_THM] THEN CONJ_TAC THEN
11018     MATCH_MP_TAC FINITE_SUBSET THEN
11019     EXISTS_TAC `p:(real^1#(real^1->bool))->bool` THEN
11020     ASM_SIMP_TAC[SUBSET; FORALL_IN_GSPEC; IN_ELIM_PAIR_THM];
11021     DISCH_THEN SUBST1_TAC] THEN
11022   SUBGOAL_THEN
11023    `(!P. FINITE {(x:real^1,k:real^1->bool) | (x,k) IN p /\ P x k}) /\
11024     (!P x. FINITE {(x:real^1,k:real^1->bool) |k| (x,k) IN p /\ P x k})`
11025   STRIP_ASSUME_TAC THENL
11026    [REPEAT STRIP_TAC THEN MATCH_MP_TAC FINITE_SUBSET THEN
11027     EXISTS_TAC `p:real^1#(real^1->bool)->bool` THEN
11028     ASM_SIMP_TAC[SUBSET; FORALL_IN_GSPEC];
11029     ALL_TAC] THEN
11030   MATCH_MP_TAC(NORM_ARITH
11031    `norm(x:real^N) <= e / &2 * a /\ norm(y) <= e / &2 * a
11032     ==> norm(x + y) <= e * a`) THEN
11033   CONJ_TAC THENL
11034    [MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
11035      `norm(vsum {(x,k) | (x,k) IN p /\ x IN IMAGE (r:num->real^1) t /\
11036                          ~(content k = &0)}
11037                 (\(x,k). --(f(interval_upperbound k) -
11038                             (f:real^1->real^N)(interval_lowerbound k))))` THEN
11039     CONJ_TAC THENL
11040      [MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
11041       MATCH_MP_TAC VSUM_EQ_SUPERSET THEN
11042       ASM_REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ] THEN
11043       CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
11044       SIMP_TAC[VECTOR_ARITH `a % vec 0 - x:real^N = --x`] THEN
11045       REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
11046       MAP_EVERY X_GEN_TAC [`x:real^1`; `k:real^1->bool`] THEN DISCH_TAC THEN
11047       SUBGOAL_THEN `?u v:real^1. k = interval[u,v] /\ x IN interval[u,v]`
11048       STRIP_ASSUME_TAC THENL
11049        [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
11050       ASM_REWRITE_TAC[CONTENT_EQ_0_1] THEN
11051       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1]) THEN
11052       DISCH_THEN(MP_TAC o MATCH_MP REAL_LE_TRANS) THEN
11053       SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1;
11054                INTERVAL_EQ_EMPTY; REAL_NOT_LE; REAL_NOT_LT] THEN
11055       REPEAT STRIP_TAC THEN MATCH_MP_TAC(VECTOR_ARITH
11056        `x:real^N = y ==> --(x - y) = vec 0`) THEN
11057       AP_TERM_TAC THEN ASM_REWRITE_TAC[GSYM DROP_EQ; GSYM REAL_LE_ANTISYM];
11058       ALL_TAC] THEN
11059     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
11060      `sum {(x,k:real^1->bool) | (x,k) IN p /\ x IN IMAGE (r:num->real^1) t /\
11061                                 ~(content k = &0)}
11062           ((\(x,k). e / &2 pow (3 + n x) * norm (b - a:real^1)))` THEN
11063     CONJ_TAC THENL
11064      [MATCH_MP_TAC VSUM_NORM_LE THEN
11065       ASM_REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ] THEN
11066       MAP_EVERY X_GEN_TAC [`x:real^1`; `k:real^1->bool`] THEN DISCH_TAC THEN
11067       SUBGOAL_THEN `?u v:real^1. k = interval[u,v] /\ x IN interval[u,v]`
11068       MP_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
11069       DISCH_THEN(REPEAT_TCL CHOOSE_THEN
11070         (CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC)) THEN
11071       SIMP_TAC[CONTENT_EQ_0_1; REAL_NOT_LE; REAL_LT_IMP_LE; IN_INTERVAL_1;
11072                INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
11073       REPEAT STRIP_TAC THEN
11074       REMOVE_THEN "E" (MP_TAC o SPEC `x:real^1`) THEN ANTS_TAC THENL
11075        [ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET]; ALL_TAC] THEN
11076       DISCH_THEN(fun th ->
11077         MP_TAC(ISPEC `u:real^1` th) THEN MP_TAC(ISPEC `v:real^1` th)) THEN
11078       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
11079       DISCH_THEN(MP_TAC o SPECL [`x:real^1`; `interval[u:real^1,v]`]) THEN
11080       ASM_REWRITE_TAC[SUBSET; IN_BALL] THEN
11081       DISCH_THEN(fun th ->
11082         MP_TAC(ISPEC `u:real^1` th) THEN MP_TAC(ISPEC `v:real^1` th)) THEN
11083       ASM_REWRITE_TAC[dist; ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY_1] THEN
11084       ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_SUB] THEN DISCH_TAC THEN DISCH_TAC THEN
11085       SUBGOAL_THEN `interval[u:real^1,v] SUBSET interval[a,b]` ASSUME_TAC THENL
11086        [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
11087       REPEAT(ANTS_TAC THENL
11088        [ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET; INTERVAL_NE_EMPTY_1;
11089                       REAL_LT_IMP_LE];
11090         ONCE_REWRITE_TAC[TAUT `p ==> q ==> r <=> q ==> p ==> r`]]) THEN
11091       REWRITE_TAC[REAL_POW_ADD; real_div; REAL_INV_MUL] THEN NORM_ARITH_TAC;
11092       ALL_TAC] THEN
11093     MP_TAC(ISPECL
11094      [`FST:real^1#(real^1->bool)->real^1`;
11095       `\(x:real^1,k:real^1->bool). e / &2 pow (3 + n x) * norm (b - a:real^1)`;
11096       `{(x,k:real^1->bool) | (x,k) IN p /\ x IN IMAGE (r:num->real^1) t /\
11097                                 ~(content k = &0)}`;
11098       `IMAGE (r:num->real^1) t`
11099      ] SUM_GROUP) THEN
11100     ANTS_TAC THENL
11101      [ASM_REWRITE_TAC[] THEN
11102       SIMP_TAC[SUBSET; FORALL_IN_IMAGE; FORALL_IN_GSPEC];
11103       DISCH_THEN(SUBST1_TAC o SYM)] THEN
11104     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
11105      `sum (IMAGE (r:num->real^1) t)
11106           (\x. sum {(x,k:real^1->bool) |k|
11107                     (x,k) IN p /\ ~(content k = &0)}
11108                    (\yk. e / &2 pow (3 + n x) * norm(b - a:real^1)))` THEN
11109     CONJ_TAC THENL
11110      [MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC SUM_EQ THEN
11111       X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN REWRITE_TAC[] THEN
11112       MATCH_MP_TAC SUM_EQ_SUPERSET THEN
11113       ASM_REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IMP_CONJ] THEN
11114       REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN ASM_MESON_TAC[];
11115       ALL_TAC] THEN
11116     ASM_SIMP_TAC[SUM_CONST] THEN
11117     REWRITE_TAC[SUM_RMUL; NORM_1; DROP_SUB; REAL_MUL_ASSOC] THEN
11118     ASM_REWRITE_TAC[real_abs; REAL_SUB_LE] THEN MATCH_MP_TAC REAL_LE_RMUL THEN
11119     ASM_REWRITE_TAC[REAL_SUB_LE; REAL_POW_ADD; real_div; REAL_INV_MUL] THEN
11120     ONCE_REWRITE_TAC[REAL_ARITH
11121      `p * e * inv(&2 pow 3) * n = e / &8 * (p * n)`] THEN
11122     ASM_SIMP_TAC[REAL_LE_LMUL_EQ; SUM_LMUL; REAL_ARITH
11123      `e / &8 * x <= e * inv(&2) <=> e * x <= e * &4`] THEN
11124     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
11125      `sum (IMAGE (r:num->real^1) t INTER
11126            IMAGE (FST:real^1#(real^1->bool)->real^1) p)
11127           (\x. &(CARD {(x,k:real^1->bool) | k |
11128                       (x,k) IN p /\ ~(content k = &0)}) *
11129                inv(&2 pow n x))` THEN
11130     CONJ_TAC THENL
11131      [MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC SUM_SUPERSET THEN
11132       REWRITE_TAC[INTER_SUBSET; IMP_CONJ; FORALL_IN_IMAGE] THEN
11133       SIMP_TAC[IN_INTER; FUN_IN_IMAGE] THEN
11134       REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM] THEN
11135       REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_ENTIRE] THEN
11136       DISJ1_TAC THEN AP_TERM_TAC THEN
11137       MATCH_MP_TAC(MESON[CARD_CLAUSES] `s = {} ==> CARD s = 0`) THEN
11138       ASM SET_TAC[];
11139       ALL_TAC] THEN
11140     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
11141      `sum (IMAGE (r:num->real^1) t INTER
11142            IMAGE (FST:real^1#(real^1->bool)->real^1) p)
11143           (\x. &2 / &2 pow (n x))` THEN
11144     CONJ_TAC THENL
11145      [MATCH_MP_TAC SUM_LE THEN
11146       ASM_SIMP_TAC[FINITE_IMAGE; FINITE_INTER] THEN
11147       GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[real_div] THEN
11148       MATCH_MP_TAC REAL_LE_RMUL THEN
11149       SIMP_TAC[REAL_LE_INV_EQ; REAL_POW_LE; REAL_POS; REAL_OF_NUM_LE] THEN
11150       GEN_REWRITE_TAC RAND_CONV [ARITH_RULE `2 = 2 EXP 1`] THEN
11151       GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM DIMINDEX_1] THEN
11152       MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_COMMON_TAGS THEN
11153       ASM_MESON_TAC[tagged_division_of];
11154       ALL_TAC] THEN
11155     REWRITE_TAC[real_div; SUM_LMUL; REAL_ARITH `&2 * x <= &4 <=> x <= &2`;
11156                 REAL_INV_POW] THEN
11157     SUBGOAL_THEN
11158      `(\x:real^1. inv (&2) pow n x) = (\n. inv(&2) pow n) o n`
11159     SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
11160     W(MP_TAC o PART_MATCH (rand o rand) SUM_IMAGE o lhand o snd) THEN
11161     ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN(SUBST1_TAC o SYM)] THEN
11162     SUBGOAL_THEN
11163      `?m. IMAGE (n:real^1->num)
11164                 (IMAGE (r:num->real^1) t INTER
11165                 IMAGE (FST:real^1#(real^1->bool)->real^1) p) SUBSET 0..m`
11166     STRIP_ASSUME_TAC THENL
11167      [REWRITE_TAC[SUBSET; IN_NUMSEG; LE_0] THEN
11168       MATCH_MP_TAC UPPER_BOUND_FINITE_SET THEN
11169       ASM_SIMP_TAC[FINITE_IMAGE; FINITE_INTER];
11170       ALL_TAC] THEN
11171     MATCH_MP_TAC REAL_LE_TRANS THEN
11172     EXISTS_TAC `sum(0..m) (\n. inv(&2) pow n)` THEN CONJ_TAC THENL
11173      [MATCH_MP_TAC SUM_SUBSET THEN
11174       ASM_SIMP_TAC[FINITE_IMAGE; FINITE_INTER; FINITE_NUMSEG] THEN
11175       SIMP_TAC[REAL_LE_INV_EQ; REAL_POW_LE; REAL_POS] THEN ASM SET_TAC[];
11176       REWRITE_TAC[SUM_GP; LT; SUB_0] THEN
11177       CONV_TAC REAL_RAT_REDUCE_CONV THEN
11178       REWRITE_TAC[REAL_ARITH `(&1 - x) / (&1 / &2) <= &2 <=> &0 <= x`] THEN
11179       MATCH_MP_TAC REAL_POW_LE THEN CONV_TAC REAL_RAT_REDUCE_CONV];
11180     MP_TAC(ISPECL [`\x:real^1. x`; `p:(real^1#(real^1->bool))->bool`;
11181                    `a:real^1`; `b:real^1`]
11182                   ADDITIVE_TAGGED_DIVISION_1) THEN
11183     ASM_SIMP_TAC[] THEN DISCH_THEN(MP_TAC o AP_TERM `drop`) THEN
11184     ASM_SIMP_TAC[DROP_VSUM; DROP_SUB] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
11185     REWRITE_TAC[GSYM SUM_LMUL] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
11186     EXISTS_TAC
11187      `sum {(x:real^1,k:real^1->bool) |
11188            (x,k) IN p /\ ~(x IN IMAGE r (t:num->bool))}
11189           (\x. e / &2 * (drop o
11190             (\(x,k). interval_upperbound k - interval_lowerbound k)) x)` THEN
11191     CONJ_TAC THENL
11192      [MATCH_MP_TAC VSUM_NORM_LE THEN ASM_REWRITE_TAC[FORALL_IN_GSPEC] THEN
11193       SIMP_TAC[o_DEF] THEN
11194       REWRITE_TAC[NORM_ARITH `norm(a - (b - c):real^N) = norm(b - c - a)`] THEN
11195       MAP_EVERY X_GEN_TAC [`x:real^1`; `k:real^1->bool`] THEN STRIP_TAC THEN
11196       SUBGOAL_THEN `?u v:real^1. k = interval[u,v] /\ x IN interval[u,v]`
11197       MP_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
11198       DISCH_THEN(REPEAT_TCL CHOOSE_THEN
11199        (CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC)) THEN
11200       REWRITE_TAC[IN_INTERVAL_1] THEN DISCH_THEN(fun th ->
11201         ASSUME_TAC th THEN MP_TAC(MATCH_MP REAL_LE_TRANS th)) THEN
11202       SIMP_TAC[CONTENT_1; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
11203       DISCH_TAC THEN REMOVE_THEN "U" (MP_TAC o SPEC `x:real^1`) THEN
11204       ASM_REWRITE_TAC[] THEN
11205       SUBGOAL_THEN `interval[u:real^1,v] SUBSET interval[a,b]` ASSUME_TAC THENL
11206        [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
11207       ANTS_TAC THENL [ASM_MESON_TAC[SUBSET; IN_INTERVAL_1]; ALL_TAC] THEN
11208       DISCH_THEN(fun th ->
11209         MP_TAC(ISPEC `u:real^1` th) THEN MP_TAC(ISPEC `v:real^1` th)) THEN
11210       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
11211       DISCH_THEN(MP_TAC o SPECL [`x:real^1`; `interval[u:real^1,v]`]) THEN
11212       ASM_REWRITE_TAC[SUBSET; IN_BALL] THEN
11213       DISCH_THEN(fun th ->
11214         MP_TAC(ISPEC `u:real^1` th) THEN MP_TAC(ISPEC `v:real^1` th)) THEN
11215       ASM_REWRITE_TAC[dist; ENDS_IN_INTERVAL; INTERVAL_NE_EMPTY_1] THEN
11216       ASM_SIMP_TAC[REAL_LT_IMP_LE; NORM_SUB] THEN DISCH_TAC THEN DISCH_TAC THEN
11217       REPEAT(ANTS_TAC THENL
11218        [ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET; INTERVAL_NE_EMPTY_1;
11219                       REAL_LT_IMP_LE];
11220         ONCE_REWRITE_TAC[TAUT `p ==> q ==> r <=> q ==> p ==> r`]]) THEN
11221       REWRITE_TAC[NORM_1; DROP_SUB] THEN
11222       ASM_SIMP_TAC[REAL_ARITH `a <= b ==> abs(a - b) = b - a`;
11223                    REAL_ARITH `b <= a ==> abs(a - b) = a - b`] THEN
11224       REWRITE_TAC[REAL_SUB_LDISTRIB] THEN MATCH_MP_TAC(NORM_ARITH
11225        `x - y:real^N = z ==> norm(x) <= c - b
11226                    ==> norm(y) <= b - a ==> norm(z) <= c - a`) THEN
11227       VECTOR_ARITH_TAC;
11228       MATCH_MP_TAC SUM_SUBSET_SIMPLE THEN ASM_REWRITE_TAC[] THEN
11229       CONJ_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[FORALL_PAIR_THM]] THEN
11230       REWRITE_TAC[IN_DIFF; IN_ELIM_PAIR_THM] THEN
11231       MAP_EVERY X_GEN_TAC [`x:real^1`; `k:real^1->bool`] THEN STRIP_TAC THEN
11232       SUBGOAL_THEN `?u v:real^1. k = interval[u,v] /\ x IN interval[u,v]`
11233       MP_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
11234       DISCH_THEN(REPEAT_TCL CHOOSE_THEN
11235        (CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC)) THEN
11236       REWRITE_TAC[IN_INTERVAL_1; o_THM] THEN
11237       DISCH_THEN(MP_TAC o MATCH_MP REAL_LE_TRANS) THEN
11238       SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
11239       REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_MUL THEN
11240       ASM_REWRITE_TAC[DROP_SUB] THEN ASM_REAL_ARITH_TAC]]);;
11241
11242 let FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG = prove
11243  (`!f:real^1->real^N f' s a b.
11244         COUNTABLE s /\
11245         drop a <= drop b /\ f continuous_on interval[a,b] /\
11246         (!x. x IN interval(a,b) DIFF s
11247              ==> (f has_vector_derivative f'(x)) (at x))
11248         ==> (f' has_integral (f(b) - f(a))) (interval[a,b])`,
11249   REPEAT STRIP_TAC THEN
11250   MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG THEN
11251   EXISTS_TAC `(a:real^1) INSERT (b:real^1) INSERT s` THEN
11252   ASM_REWRITE_TAC[COUNTABLE_INSERT; IN_INTERVAL_1; IN_DIFF] THEN
11253   REWRITE_TAC[DE_MORGAN_THM; IN_INSERT] THEN
11254   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_AT_WITHIN THEN
11255   FIRST_X_ASSUM MATCH_MP_TAC THEN
11256   ASM_REWRITE_TAC[IN_INTERVAL_1; IN_DIFF; IN_INSERT] THEN
11257   ASM_REWRITE_TAC[REAL_LT_LE; DROP_EQ]);;
11258
11259 let FUNDAMENTAL_THEOREM_OF_CALCULUS = prove
11260  (`!f:real^1->real^N f' a b.
11261         drop a <= drop b /\
11262         (!x. x IN interval[a,b]
11263              ==> (f has_vector_derivative f'(x)) (at x within interval[a,b]))
11264         ==> (f' has_integral (f(b) - f(a))) (interval[a,b])`,
11265   REPEAT STRIP_TAC THEN
11266   MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG THEN
11267   EXISTS_TAC `{}:real^1->bool` THEN
11268   ASM_REWRITE_TAC[COUNTABLE_EMPTY; DIFF_EMPTY] THEN
11269   MATCH_MP_TAC DIFFERENTIABLE_IMP_CONTINUOUS_ON THEN
11270   REWRITE_TAC[differentiable_on] THEN
11271   ASM_MESON_TAC[has_vector_derivative; differentiable]);;
11272
11273 let FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR = prove
11274  (`!f:real^1->real^N f' a b.
11275         drop a <= drop b /\ f continuous_on interval[a,b] /\
11276         (!x. x IN interval(a,b)
11277              ==> (f has_vector_derivative f'(x)) (at x))
11278         ==> (f' has_integral (f(b) - f(a))) (interval[a,b])`,
11279   REPEAT STRIP_TAC THEN
11280   MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG THEN
11281   EXISTS_TAC `{}:real^1->bool` THEN
11282   ASM_REWRITE_TAC[COUNTABLE_EMPTY; DIFF_EMPTY]);;
11283
11284 let ANTIDERIVATIVE_INTEGRAL_CONTINUOUS = prove
11285  (`!f:real^1->real^N a b.
11286      (f continuous_on interval[a,b])
11287      ==> ?g. !u v. u IN interval[a,b] /\ v IN interval[a,b] /\ drop u <= drop v
11288                    ==> (f has_integral (g(v) - g(u))) (interval[u,v])`,
11289   REPEAT STRIP_TAC THEN
11290   FIRST_ASSUM(MP_TAC o MATCH_MP ANTIDERIVATIVE_CONTINUOUS) THEN
11291   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^1->real^N` THEN
11292   REPEAT STRIP_TAC THEN MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS THEN
11293   ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^1` THEN
11294   STRIP_TAC THEN MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_WITHIN_SUBSET THEN
11295   EXISTS_TAC `interval[a:real^1,b]` THEN CONJ_TAC THENL
11296    [FIRST_X_ASSUM MATCH_MP_TAC; ALL_TAC] THEN
11297   REPEAT(POP_ASSUM MP_TAC) THEN
11298   REWRITE_TAC[SUBSET_INTERVAL_1; IN_INTERVAL_1] THEN REAL_ARITH_TAC);;
11299
11300 (* ------------------------------------------------------------------------- *)
11301 (* This doesn't directly involve integration, but that gives an easy proof.  *)
11302 (* ------------------------------------------------------------------------- *)
11303
11304 let HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL = prove
11305  (`!f:real^1->real^N a b k y.
11306         COUNTABLE k /\ f continuous_on interval[a,b] /\ f a = y /\
11307         (!x. x IN (interval[a,b] DIFF k)
11308              ==> (f has_derivative (\h. vec 0)) (at x within interval[a,b]))
11309         ==> !x. x IN interval[a,b] ==> f x = y`,
11310   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
11311   MATCH_MP_TAC(ISPEC `(\x. vec 0):real^1->real^N` HAS_INTEGRAL_UNIQUE) THEN
11312   EXISTS_TAC `interval[a:real^1,x]` THEN
11313   REWRITE_TAC[HAS_INTEGRAL_0] THEN FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
11314   MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_INTERIOR_STRONG THEN
11315   EXISTS_TAC `k:real^1->bool` THEN ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
11316    [REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN
11317     REAL_ARITH_TAC;
11318     MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN
11319     EXISTS_TAC `interval[a:real^1,b]` THEN
11320     ASM_REWRITE_TAC[SUBSET_INTERVAL_1] THEN
11321     REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_INTERVAL_1])) THEN
11322     REAL_ARITH_TAC;
11323     X_GEN_TAC `y:real^1` THEN DISCH_TAC THEN
11324     FIRST_X_ASSUM(MP_TAC o SPEC `y:real^1`) THEN ANTS_TAC THENL
11325      [REPEAT(POP_ASSUM MP_TAC) THEN
11326       SIMP_TAC[IN_DIFF; IN_INTERVAL_1] THEN REAL_ARITH_TAC;
11327       ALL_TAC] THEN
11328     DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
11329       HAS_DERIVATIVE_WITHIN_SUBSET)) THEN
11330     DISCH_THEN(MP_TAC o SPEC `interval(a:real^1,b)`) THEN
11331     REWRITE_TAC[INTERVAL_OPEN_SUBSET_CLOSED] THEN
11332     REWRITE_TAC[has_vector_derivative; VECTOR_MUL_RZERO] THEN
11333     MATCH_MP_TAC EQ_IMP THEN MATCH_MP_TAC HAS_DERIVATIVE_WITHIN_OPEN THEN
11334     REPEAT(POP_ASSUM MP_TAC) THEN
11335     SIMP_TAC[OPEN_INTERVAL; IN_INTERVAL_1; IN_DIFF] THEN REAL_ARITH_TAC]);;
11336
11337 (* ------------------------------------------------------------------------- *)
11338 (* Generalize a bit to any convex set.                                       *)
11339 (* ------------------------------------------------------------------------- *)
11340
11341 let HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX = prove
11342  (`!f:real^M->real^N s k c y.
11343       convex s /\ COUNTABLE k /\ f continuous_on s /\ c IN s /\ f c = y /\
11344       (!x. x IN (s DIFF k) ==> (f has_derivative (\h. vec 0)) (at x within s))
11345       ==> !x. x IN s ==> f x = y`,
11346   GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN
11347   MAP_EVERY X_GEN_TAC [`x:real^M`; `z:real^N`] THEN STRIP_TAC THEN
11348   FIRST_X_ASSUM(SUBST_ALL_TAC o SYM) THEN
11349   X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN
11350   ASM_CASES_TAC `x:real^M = y` THEN ASM_REWRITE_TAC[] THEN
11351   MP_TAC(ISPECL [`(f:real^M->real^N) o (\t. (&1 - drop t) % x + drop t % y)`;
11352                  `vec 0:real^1`; `vec 1:real^1`;
11353                  `{t | ((&1 - drop t) % (x:real^M) + drop t % y) IN k}`;
11354                  `(f:real^M->real^N) x`]
11355                 HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_INTERVAL) THEN
11356   REWRITE_TAC[o_THM] THEN ANTS_TAC THENL
11357    [ALL_TAC;
11358     DISCH_THEN(MP_TAC o SPEC `vec 1:real^1`) THEN
11359     REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; REAL_POS; REAL_LE_REFL] THEN
11360     DISCH_THEN(SUBST1_TAC o SYM) THEN AP_TERM_TAC THEN VECTOR_ARITH_TAC] THEN
11361   REPEAT CONJ_TAC THENL
11362    [MATCH_MP_TAC COUNTABLE_IMAGE_INJ THEN ASM_REWRITE_TAC[] THEN
11363     ASM_REWRITE_TAC[VECTOR_MUL_EQ_0; VECTOR_SUB_EQ; REAL_SUB_0; DROP_EQ;
11364     VECTOR_ARITH `(&1 - t) % x + t % y = (&1 - u) % x + u % y <=>
11365                   (t - u) % (x - y) = vec 0`];
11366     MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN CONJ_TAC THENL
11367      [MATCH_MP_TAC CONTINUOUS_ON_ADD THEN CONJ_TAC THEN
11368       MATCH_MP_TAC CONTINUOUS_ON_VMUL THEN
11369       REWRITE_TAC[o_DEF; LIFT_DROP; CONTINUOUS_ON_ID; LIFT_SUB] THEN
11370       SIMP_TAC[CONTINUOUS_ON_SUB; CONTINUOUS_ON_CONST; CONTINUOUS_ON_ID];
11371       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
11372           CONTINUOUS_ON_SUBSET)) THEN
11373       REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_INTERVAL_1; GSYM FORALL_DROP] THEN
11374       REWRITE_TAC[DROP_VEC] THEN ASM_MESON_TAC[CONVEX_ALT]];
11375     AP_TERM_TAC THEN REWRITE_TAC[DROP_VEC] THEN VECTOR_ARITH_TAC;
11376     ALL_TAC] THEN
11377   X_GEN_TAC `t:real^1` THEN DISCH_TAC THEN
11378   SUBGOAL_THEN `(\h. vec 0) = ((\h. vec 0):real^M->real^N) o
11379                                (\t. drop t % (y - x))`
11380   SUBST1_TAC THENL [REWRITE_TAC[o_DEF]; ALL_TAC] THEN
11381   MATCH_MP_TAC DIFF_CHAIN_WITHIN THEN CONJ_TAC THENL
11382    [REWRITE_TAC[VECTOR_ARITH `t % (y - x) = ((&0 - t) % x) + t % y`] THEN
11383     MATCH_MP_TAC HAS_DERIVATIVE_ADD THEN
11384     REWRITE_TAC[GSYM DROP_NEG; GSYM DROP_VEC; GSYM DROP_SUB] THEN
11385     SIMP_TAC[HAS_DERIVATIVE_VMUL_DROP; HAS_DERIVATIVE_ID] THEN
11386     REWRITE_TAC[DROP_SUB; VECTOR_SUB_RDISTRIB] THEN
11387     MATCH_MP_TAC HAS_DERIVATIVE_SUB THEN
11388     REWRITE_TAC[VECTOR_MUL_LZERO; DROP_VEC; HAS_DERIVATIVE_CONST] THEN
11389     SIMP_TAC[HAS_DERIVATIVE_VMUL_DROP; HAS_DERIVATIVE_ID];
11390     ALL_TAC] THEN
11391   MATCH_MP_TAC HAS_DERIVATIVE_WITHIN_SUBSET THEN
11392   EXISTS_TAC `s:real^M->bool` THEN REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
11393   REWRITE_TAC[IN_INTERVAL_1; GSYM FORALL_DROP; DROP_VEC] THEN
11394   CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[CONVEX_ALT]] THEN
11395   FIRST_X_ASSUM MATCH_MP_TAC THEN
11396   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [IN_DIFF]) THEN
11397   SIMP_TAC[IN_ELIM_THM; IN_DIFF] THEN REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
11398   REWRITE_TAC[IN_INTERVAL_1; GSYM FORALL_DROP; DROP_VEC] THEN
11399   ASM_MESON_TAC[CONVEX_ALT]);;
11400
11401 (* ------------------------------------------------------------------------- *)
11402 (* Also to any open connected set with finite set of exceptions. Could       *)
11403 (* generalize to locally convex set with limpt-free set of exceptions.       *)
11404 (* ------------------------------------------------------------------------- *)
11405
11406 let HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONNECTED = prove
11407  (`!f:real^M->real^N s k c y.
11408       connected s /\ open s /\ COUNTABLE k /\ f continuous_on s /\
11409       c IN s /\ f c = y /\
11410       (!x. x IN (s DIFF k) ==> (f has_derivative (\h. vec 0)) (at x within s))
11411       ==> !x. x IN s ==> f x = y`,
11412   REPEAT STRIP_TAC THEN
11413   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONNECTED_CLOPEN]) THEN
11414   DISCH_THEN(MP_TAC o SPEC
11415    `{x | x IN s /\ (f:real^M->real^N) x IN {y}}`) THEN
11416   ANTS_TAC THENL [ALL_TAC; ASM SET_TAC[]] THEN CONJ_TAC THEN
11417   ASM_SIMP_TAC[CONTINUOUS_CLOSED_IN_PREIMAGE; CLOSED_SING] THEN
11418   MATCH_MP_TAC OPEN_OPEN_IN_TRANS THEN ASM_REWRITE_TAC[] THEN
11419   CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN
11420   UNDISCH_TAC `open(s:real^M->bool)` THEN REWRITE_TAC[OPEN_CONTAINS_BALL] THEN
11421   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `u:real^M` THEN
11422   REWRITE_TAC[SUBSET; IN_ELIM_THM; IN_SING] THEN
11423   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
11424   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN
11425   GEN_TAC THEN STRIP_TAC THEN ASM_SIMP_TAC[] THEN
11426   MATCH_MP_TAC HAS_DERIVATIVE_ZERO_UNIQUE_STRONG_CONVEX THEN
11427   MAP_EVERY EXISTS_TAC [`k:real^M->bool`; `u:real^M`] THEN
11428   ASM_REWRITE_TAC[CONVEX_BALL; IN_DIFF; CENTRE_IN_BALL] THEN
11429   CONJ_TAC THENL [ASM_MESON_TAC[SUBSET; CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN
11430   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_DERIVATIVE_WITHIN_SUBSET THEN
11431   EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[SUBSET] THEN
11432   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[IN_DIFF]);;
11433
11434 (* ------------------------------------------------------------------------- *)
11435 (* Equiintegrability. The definition here only really makes sense for an     *)
11436 (* elementary set. We just use compact intervals in applications below.      *)
11437 (* ------------------------------------------------------------------------- *)
11438
11439 parse_as_infix("equiintegrable_on",(12,"right"));;
11440
11441 let equiintegrable_on = new_definition
11442   `fs equiintegrable_on i <=>
11443         (!f:real^M->real^N. f IN fs ==> f integrable_on i) /\
11444         (!e. &0 < e
11445              ==> ?d. gauge d /\
11446                     !f p. f IN fs /\ p tagged_division_of i /\ d fine p
11447                         ==> norm(vsum p (\(x,k). content(k) % f(x)) -
11448                                  integral i f) < e)`;;
11449
11450 let EQUIINTEGRABLE_ON_SING = prove
11451  (`!f:real^M->real^N a b.
11452         {f} equiintegrable_on interval[a,b] <=>
11453         f integrable_on interval[a,b]`,
11454   REPEAT GEN_TAC THEN REWRITE_TAC[equiintegrable_on] THEN
11455   REWRITE_TAC[IN_SING; FORALL_UNWIND_THM2] THEN
11456   ASM_CASES_TAC `(f:real^M->real^N) integrable_on interval[a,b]` THEN
11457   ASM_REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_UNWIND_THM2] THEN
11458   FIRST_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
11459   REWRITE_TAC[has_integral; IMP_IMP]);;
11460
11461 (* ------------------------------------------------------------------------- *)
11462 (* Basic combining theorems for the interval of integration.                 *)
11463 (* ------------------------------------------------------------------------- *)
11464
11465 let EQUIINTEGRABLE_ON_NULL = prove
11466  (`!fs:(real^M->real^N)->bool a b.
11467      content(interval[a,b]) = &0 ==> fs equiintegrable_on interval[a,b]`,
11468   REPEAT STRIP_TAC THEN REWRITE_TAC[equiintegrable_on] THEN
11469   ASM_SIMP_TAC[INTEGRABLE_ON_NULL] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11470   EXISTS_TAC `\x:real^M. ball(x,&1)` THEN REWRITE_TAC[GAUGE_TRIVIAL] THEN
11471   FIRST_ASSUM(fun th -> SIMP_TAC[MATCH_MP (REWRITE_RULE[IMP_CONJ]
11472                                            VSUM_CONTENT_NULL) th]) THEN
11473   ASM_SIMP_TAC[INTEGRAL_NULL; VECTOR_SUB_REFL; NORM_0]);;
11474
11475 let EQUIINTEGRABLE_ON_SPLIT = prove
11476  (`!fs:(real^M->real^N)->bool k a b c.
11477       fs equiintegrable_on (interval[a,b] INTER {x | x$k <= c}) /\
11478       fs equiintegrable_on (interval[a,b] INTER {x | x$k >= c}) /\
11479       1 <= k /\ k <= dimindex(:M)
11480       ==> fs equiintegrable_on (interval[a,b])`,
11481   let lemma1 = prove
11482    (`(!x k. (x,k) IN {x,f k | P x k} ==> Q x k) <=>
11483      (!x k. P x k ==> Q x (f k))`,
11484     REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN
11485     SET_TAC[]) in
11486   let lemma2 = prove
11487    (`!f:B->B s:(A#B)->bool.
11488       FINITE s ==> FINITE {x,f k | (x,k) IN s /\ P x k}`,
11489     REPEAT STRIP_TAC THEN MATCH_MP_TAC FINITE_SUBSET THEN
11490     EXISTS_TAC `IMAGE (\(x:A,k:B). x,(f k:B)) s` THEN
11491     ASM_SIMP_TAC[FINITE_IMAGE] THEN
11492     REWRITE_TAC[SUBSET; FORALL_PAIR_THM; lemma1; IN_IMAGE] THEN
11493     REWRITE_TAC[EXISTS_PAIR_THM; PAIR_EQ] THEN MESON_TAC[]) in
11494   let lemma3 = prove
11495    (`!f:real^M->real^N g:(real^M->bool)->(real^M->bool) p.
11496      FINITE p
11497      ==> vsum {x,g k |x,k| (x,k) IN p /\ ~(g k = {})}
11498               (\(x,k). content k % f x) =
11499          vsum (IMAGE (\(x,k). x,g k) p) (\(x,k). content k % f x)`,
11500     REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN
11501     ASM_SIMP_TAC[FINITE_IMAGE; lemma2] THEN
11502     REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE] THEN
11503     REWRITE_TAC[FORALL_PAIR_THM; SUBSET; IN_IMAGE; EXISTS_PAIR_THM] THEN
11504     REWRITE_TAC[IN_ELIM_THM; PAIR_EQ; VECTOR_MUL_EQ_0] THEN
11505     MESON_TAC[CONTENT_EMPTY]) in
11506   let lemma4 = prove
11507    (`(\(x,l). content (g l) % f x) =
11508      (\(x,l). content l % f x) o (\(x,l). x,g l)`,
11509     REWRITE_TAC[FUN_EQ_THM; o_THM; FORALL_PAIR_THM]) in
11510   REPEAT GEN_TAC THEN
11511   ASM_CASES_TAC `1 <= k /\ k <= dimindex(:M)` THEN ASM_REWRITE_TAC[] THEN
11512   REWRITE_TAC[equiintegrable_on] THEN
11513   MATCH_MP_TAC(TAUT
11514    `(a /\ b ==> c) /\ (a /\ b /\ c ==> a' /\ b' ==> c')
11515     ==> (a /\ a') /\ (b /\ b') ==> c /\ c'`) THEN
11516   CONJ_TAC THENL
11517    [REWRITE_TAC[integrable_on] THEN ASM MESON_TAC[HAS_INTEGRAL_SPLIT];
11518     STRIP_TAC] THEN
11519   SUBGOAL_THEN
11520    `!f:real^M->real^N.
11521         f IN fs
11522         ==> integral (interval[a,b]) f =
11523                 integral (interval [a,b] INTER {x | x$k <= c}) f +
11524                 integral (interval [a,b] INTER {x | x$k >= c}) f`
11525    (fun th -> SIMP_TAC[th])
11526   THENL
11527    [REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
11528     MATCH_MP_TAC HAS_INTEGRAL_SPLIT THEN
11529     MAP_EVERY EXISTS_TAC [`k:num`; `c:real`] THEN
11530     ASM_SIMP_TAC[GSYM HAS_INTEGRAL_INTEGRAL];
11531     ALL_TAC] THEN
11532   DISCH_TAC THEN X_GEN_TAC `e:real` THEN STRIP_TAC THEN
11533   FIRST_X_ASSUM(CONJUNCTS_THEN2 (MP_TAC o SPEC `e / &2`) STRIP_ASSUME_TAC) THEN
11534   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
11535   DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool`
11536    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "I2"))) THEN
11537   DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool`
11538    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "I1"))) THEN
11539   EXISTS_TAC `\x. if x$k = c then (d1(x:real^M) INTER d2(x)):real^M->bool
11540                   else ball(x,abs(x$k - c)) INTER d1(x) INTER d2(x)` THEN
11541   CONJ_TAC THENL
11542    [REWRITE_TAC[gauge] THEN GEN_TAC THEN
11543     RULE_ASSUM_TAC(REWRITE_RULE[gauge]) THEN COND_CASES_TAC THEN
11544     ASM_SIMP_TAC[OPEN_INTER; IN_INTER; OPEN_BALL; IN_BALL] THEN
11545     ASM_REWRITE_TAC[DIST_REFL; GSYM REAL_ABS_NZ; REAL_SUB_0];
11546     ALL_TAC] THEN
11547   X_GEN_TAC `f:real^M->real^N` THEN
11548   X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
11549   SUBGOAL_THEN
11550     `(!x:real^M kk. (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k <= c} = {})
11551                     ==> x$k <= c) /\
11552      (!x:real^M kk. (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k >= c} = {})
11553                     ==> x$k >= c)`
11554   STRIP_ASSUME_TAC THENL
11555    [CONJ_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
11556     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
11557     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `kk:real^M->bool` THEN
11558     DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
11559     COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL; real_ge] THEN DISCH_THEN
11560      (MP_TAC o MATCH_MP (SET_RULE `k SUBSET (a INTER b) ==> k SUBSET a`)) THEN
11561     REWRITE_TAC[SUBSET; IN_BALL; dist] THEN DISCH_TAC THEN
11562     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
11563     DISCH_THEN(X_CHOOSE_THEN `u:real^M` MP_TAC) THEN
11564     REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
11565     FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M`) THEN ASM_REWRITE_TAC[] THEN
11566     ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
11567     REWRITE_TAC[REAL_NOT_LE; REAL_NOT_LT] THEN STRIP_TAC THEN
11568     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((x - u:real^M)$k)` THEN
11569     ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
11570     ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
11571     ASM_REAL_ARITH_TAC;
11572     ALL_TAC] THEN
11573   REMOVE_THEN "I2" (MP_TAC o SPEC
11574    `{(x:real^M,kk INTER {x:real^M | x$k >= c}) |x,kk|
11575      (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k >= c} = {})}` o
11576    SPEC `f:real^M->real^N`) THEN
11577   REMOVE_THEN "I1" (MP_TAC o SPEC
11578    `{(x:real^M,kk INTER {x:real^M | x$k <= c}) |x,kk|
11579      (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k <= c} = {})}` o
11580    SPEC `f:real^M->real^N`) THEN
11581   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT
11582    `(a /\ b) /\ (a' /\ b' ==> c) ==> (a ==> a') ==> (b ==> b') ==> c`) THEN
11583   CONJ_TAC THENL
11584    [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
11585     REWRITE_TAC[TAGGED_DIVISION_OF] THEN
11586     REPEAT(MATCH_MP_TAC(TAUT
11587      `(a ==> (a' /\ a'')) /\ (b ==> (b' /\ d) /\ (b'' /\ e))
11588       ==> a /\ b ==> ((a' /\ b') /\ d) /\ ((a'' /\ b'') /\ e)`) THEN
11589       CONJ_TAC) THEN
11590     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
11591     REWRITE_TAC[lemma1] THEN REWRITE_TAC[IMP_IMP] THENL
11592      [SIMP_TAC[lemma2];
11593       REWRITE_TAC[AND_FORALL_THM] THEN
11594       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
11595       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `kk:real^M->bool` THEN
11596       DISCH_THEN(fun th -> CONJ_TAC THEN STRIP_TAC THEN MP_TAC th) THEN
11597       (ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
11598         [SIMP_TAC[IN_INTER; IN_ELIM_THM] THEN ASM_MESON_TAC[]; ALL_TAC]) THEN
11599       (MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL [SET_TAC[]; ALL_TAC]) THEN
11600       ASM_MESON_TAC[INTERVAL_SPLIT];
11601       DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
11602       (REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
11603        DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
11604        REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
11605        DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
11606        ANTS_TAC THENL [ASM_MESON_TAC[PAIR_EQ]; ALL_TAC] THEN
11607        MATCH_MP_TAC(SET_RULE
11608         `s SUBSET s' /\ t SUBSET t'
11609          ==> s' INTER t' = {} ==> s INTER t = {}`) THEN
11610        CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]);
11611       ALL_TAC] THEN
11612     MATCH_MP_TAC(TAUT `(a ==> b /\ c) /\ d /\ e
11613                        ==> (a ==> (b /\ d) /\ (c /\ e))`) THEN
11614     CONJ_TAC THENL
11615      [DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
11616       DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[INTER_UNIONS] THEN
11617       ONCE_REWRITE_TAC[EXTENSION] THEN REWRITE_TAC[IN_UNIONS] THEN
11618       X_GEN_TAC `x:real^M` THEN AP_TERM_TAC THEN
11619       GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `kk:real^M->bool` THEN
11620       REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN MESON_TAC[NOT_IN_EMPTY];
11621       ALL_TAC] THEN
11622     CONJ_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
11623     REWRITE_TAC[fine; lemma1] THEN
11624     REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
11625     DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
11626     ASM_SIMP_TAC[] THEN SET_TAC[];
11627     ALL_TAC] THEN
11628   DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH
11629    `x < e / &2 /\ y < e / &2 ==> x + y < e`)) THEN
11630   DISCH_THEN(MP_TAC o MATCH_MP NORM_TRIANGLE_LT) THEN
11631   MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
11632   REWRITE_TAC[VECTOR_ARITH
11633    `(a - i) + (b - j) = c - (i + j) <=> a + b = c:real^N`] THEN
11634   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
11635  MATCH_MP_TAC EQ_TRANS THEN
11636   EXISTS_TAC
11637    `vsum p (\(x,l). content (l INTER {x:real^M | x$k <= c}) %
11638                      (f:real^M->real^N) x) +
11639     vsum p (\(x,l). content (l INTER {x:real^M | x$k >= c}) %
11640                      (f:real^M->real^N) x)` THEN
11641   CONJ_TAC THENL
11642    [ALL_TAC;
11643     ASM_SIMP_TAC[GSYM VSUM_ADD] THEN MATCH_MP_TAC VSUM_EQ THEN
11644     REWRITE_TAC[FORALL_PAIR_THM; GSYM VECTOR_ADD_RDISTRIB] THEN
11645     MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
11646     DISCH_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
11647     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
11648     DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `l:real^M->bool`] o
11649                el 1 o CONJUNCTS) THEN
11650     ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
11651     ASM_SIMP_TAC[GSYM CONTENT_SPLIT]] THEN
11652   ASM_SIMP_TAC[lemma3] THEN BINOP_TAC THEN
11653   (GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [lemma4] THEN
11654    MATCH_MP_TAC VSUM_IMAGE_NONZERO THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
11655    REWRITE_TAC[PAIR_EQ] THEN
11656    ASM_MESON_TAC[TAGGED_DIVISION_SPLIT_LEFT_INJ; VECTOR_MUL_LZERO;
11657                  TAGGED_DIVISION_SPLIT_RIGHT_INJ]));;
11658
11659 let EQUIINTEGRABLE_DIVISION = prove
11660  (`!fs:(real^M->real^N)->bool d a b.
11661         d division_of interval[a,b]
11662         ==> (fs equiintegrable_on interval[a,b] <=>
11663              !i. i IN d ==> fs equiintegrable_on i)`,
11664   REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN
11665   MATCH_MP_TAC OPERATIVE_DIVISION_AND THEN
11666   ASM_REWRITE_TAC[operative; NEUTRAL_AND] THEN
11667   POP_ASSUM_LIST(K ALL_TAC) THEN CONJ_TAC THENL
11668    [MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN DISCH_TAC THEN
11669     ASM_SIMP_TAC[equiintegrable_on; INTEGRABLE_ON_NULL] THEN
11670     GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `\x:real^M. ball(x,&1)` THEN
11671     ASM_SIMP_TAC[GAUGE_TRIVIAL; INTEGRAL_NULL; VECTOR_SUB_RZERO] THEN
11672     REPEAT STRIP_TAC THEN
11673     FIRST_ASSUM(MATCH_MP_TAC o MATCH_MP (NORM_ARITH
11674      `&0 < e ==> x = vec 0 ==> norm x < e`)) THEN
11675     MATCH_MP_TAC VSUM_EQ_0 THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
11676     REPEAT STRIP_TAC THEN REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN
11677     RULE_ASSUM_TAC(REWRITE_RULE[TAGGED_DIVISION_OF]) THEN
11678     ASM_MESON_TAC[CONTENT_EQ_0_INTERIOR; SUBSET_INTERIOR;
11679                   SET_RULE `s = {} <=> s SUBSET {}`];
11680     ALL_TAC] THEN
11681   MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real`; `k:num`] THEN
11682   STRIP_TAC THEN EQ_TAC THENL
11683    [ALL_TAC; ASM_MESON_TAC[EQUIINTEGRABLE_ON_SPLIT]] THEN
11684   ASM_SIMP_TAC[INTEGRABLE_SPLIT; equiintegrable_on] THEN
11685   STRIP_TAC THEN CONJ_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11686   (FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
11687    MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
11688    ASM_CASES_TAC `gauge(d:real^M->real^M->bool)` THEN ASM_REWRITE_TAC[] THEN
11689    MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `f:real^M->real^N` THEN
11690    ASM_CASES_TAC `(f:real^M->real^N) IN fs` THEN ASM_REWRITE_TAC[] THEN
11691    DISCH_TAC THEN
11692    MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`;
11693                   `d:real^M->real^M->bool`; `e / &2`]
11694          HENSTOCK_LEMMA_PART1) THEN ASM_SIMP_TAC[REAL_HALF] THEN
11695    MATCH_MP_TAC MONO_FORALL THEN
11696    X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN
11697    DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ANTS_TAC THENL
11698     [ASM_REWRITE_TAC[] THEN MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_OF_SUBSET THEN
11699      RULE_ASSUM_TAC(REWRITE_RULE[tagged_division_of]) THEN
11700      ASM_MESON_TAC[INTER_SUBSET];
11701      ALL_TAC] THEN
11702    MATCH_MP_TAC(NORM_ARITH
11703     `&0 < e /\ x:real^N = y ==> norm(x) <= e / &2 ==> norm(y) < e`) THEN
11704    ASM_REWRITE_TAC[] THEN ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
11705    W(MP_TAC o PART_MATCH (lhand o rand)
11706      INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN o rand o rand o snd) THEN
11707    ASM_SIMP_TAC[GSYM INTERVAL_SPLIT; INTEGRABLE_SPLIT] THEN
11708    DISCH_THEN SUBST1_TAC THEN
11709    FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
11710    ASM_SIMP_TAC[GSYM VSUM_SUB] THEN MATCH_MP_TAC VSUM_EQ THEN
11711    REWRITE_TAC[FORALL_PAIR_THM]));;
11712
11713 (* ------------------------------------------------------------------------- *)
11714 (* Main limit theorem for an equiintegrable sequence.                        *)
11715 (* ------------------------------------------------------------------------- *)
11716
11717 let EQUIINTEGRABLE_LIMIT = prove
11718  (`!f g:real^M->real^N a b.
11719         {f n | n IN (:num)} equiintegrable_on interval[a,b] /\
11720         (!x. x IN interval[a,b] ==> ((\n. f n x) --> g x) sequentially)
11721         ==> g integrable_on interval[a,b] /\
11722             ((\n. integral(interval[a,b]) (f n)) --> integral(interval[a,b]) g)
11723             sequentially`,
11724   REPEAT GEN_TAC THEN STRIP_TAC THEN
11725   ASM_CASES_TAC `content(interval[a:real^M,b]) = &0` THEN
11726   ASM_SIMP_TAC[INTEGRABLE_ON_NULL; INTEGRAL_NULL; LIM_CONST] THEN
11727   SUBGOAL_THEN `cauchy (\n. integral(interval[a,b]) (f n :real^M->real^N))`
11728   MP_TAC THENL
11729    [REWRITE_TAC[cauchy] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11730     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [equiintegrable_on]) THEN
11731     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC; IN_UNIV] THEN
11732     DISCH_TAC THEN REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
11733     DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
11734     ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
11735     DISCH_THEN(X_CHOOSE_THEN `d:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
11736     FIRST_ASSUM(MP_TAC o MATCH_MP FINE_DIVISION_EXISTS) THEN
11737     DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN
11738     DISCH_THEN(X_CHOOSE_THEN `p:(real^M#(real^M->bool))->bool`
11739         STRIP_ASSUME_TAC) THEN
11740     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
11741     FIRST_X_ASSUM(MP_TAC o GEN `n:num` o SPECL
11742      [`n:num`; `p:(real^M#(real^M->bool))->bool`]) THEN
11743     ASM_REWRITE_TAC[] THEN DISCH_TAC THEN SUBGOAL_THEN
11744      `cauchy (\n. vsum p (\(x,k:real^M->bool).
11745                content k % (f:num->real^M->real^N) n x))`
11746     MP_TAC THENL
11747      [MATCH_MP_TAC CONVERGENT_IMP_CAUCHY THEN
11748       EXISTS_TAC `vsum p (\(x,k:real^M->bool).
11749           content k % (g:real^M->real^N) x)` THEN
11750       MATCH_MP_TAC
11751        (REWRITE_RULE[LAMBDA_PAIR_THM]
11752         (REWRITE_RULE[FORALL_PAIR_THM]
11753          (ISPEC `\(x:real^M,k:real^M->bool) (n:num).
11754                   content k % (f n x:real^N)` LIM_VSUM))) THEN
11755       ASM_REWRITE_TAC[] THEN
11756       MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
11757       MATCH_MP_TAC LIM_CMUL THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
11758       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
11759       ASM_SIMP_TAC[SUBSET] THEN ASM_MESON_TAC[];
11760       REWRITE_TAC[cauchy] THEN DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
11761       ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
11762       REWRITE_TAC[IMP_IMP; RIGHT_IMP_FORALL_THM; GE] THEN
11763       MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
11764       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `m:num` THEN
11765       MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `n:num` THEN
11766       ASM_CASES_TAC `N:num <= m /\ N <= n` THEN ASM_REWRITE_TAC[] THEN
11767       MATCH_MP_TAC(NORM_ARITH
11768        `norm(sm - gm:real^N) < e / &3 /\ norm(sn - gn) < e / &3
11769         ==> dist(sm,sn) < e / &3 ==> dist(gm,gn) < e`) THEN
11770       ASM_REWRITE_TAC[]];
11771     REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN
11772     DISCH_THEN(X_CHOOSE_TAC `l:real^N`) THEN
11773     SUBGOAL_THEN `((g:real^M->real^N) has_integral l) (interval[a,b])`
11774      (fun th -> ASM_MESON_TAC[th; integrable_on; INTEGRAL_UNIQUE]) THEN
11775     REWRITE_TAC[has_integral] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11776     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [equiintegrable_on]) THEN
11777     REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC; IN_UNIV] THEN
11778     DISCH_TAC THEN REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
11779     DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
11780     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
11781     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
11782     X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
11783     MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
11784     ASM_REWRITE_TAC[] THEN
11785     MATCH_MP_TAC(ISPEC `sequentially` LIM_NORM_UBOUND) THEN
11786     EXISTS_TAC `\n:num. vsum p (\(x,k:real^M->bool). content k % f n x) -
11787                        integral (interval [a,b]) (f n :real^M->real^N)` THEN
11788     ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; REAL_LT_IMP_LE] THEN
11789     REWRITE_TAC[EVENTUALLY_TRUE] THEN
11790     MATCH_MP_TAC LIM_SUB THEN ASM_REWRITE_TAC[] THEN
11791     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
11792     MATCH_MP_TAC
11793      (REWRITE_RULE[LAMBDA_PAIR_THM]
11794       (REWRITE_RULE[FORALL_PAIR_THM]
11795        (ISPEC `\(x:real^M,k:real^M->bool) (n:num).
11796                 content k % (f n x:real^N)` LIM_VSUM))) THEN
11797     ASM_REWRITE_TAC[] THEN
11798     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
11799     MATCH_MP_TAC LIM_CMUL THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
11800     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
11801     ASM_SIMP_TAC[SUBSET] THEN ASM_MESON_TAC[]]);;
11802
11803 (* ------------------------------------------------------------------------- *)
11804 (* Combining theorems for the set of equiintegrable functions.               *)
11805 (* ------------------------------------------------------------------------- *)
11806
11807 let EQUIINTEGRABLE_SUBSET = prove
11808  (`!fs gs s.
11809    fs equiintegrable_on s /\ gs SUBSET fs ==> gs equiintegrable_on s`,
11810   REWRITE_TAC[equiintegrable_on; SUBSET] THEN MESON_TAC[]);;
11811
11812 let EQUIINTEGRABLE_UNION = prove
11813  (`!fs:(real^M->real^N)->bool gs s.
11814         fs equiintegrable_on s /\ gs equiintegrable_on s
11815         ==> (fs UNION gs) equiintegrable_on s`,
11816   REPEAT GEN_TAC THEN REWRITE_TAC[equiintegrable_on; IN_UNION] THEN
11817   REWRITE_TAC[TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
11818   REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
11819   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11820   REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `e:real`)) THEN ASM_REWRITE_TAC[] THEN
11821   DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
11822   DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
11823   EXISTS_TAC `\x. (d1:real^M->real^M->bool) x INTER d2 x` THEN
11824   ASM_SIMP_TAC[GAUGE_INTER; FINE_INTER] THEN
11825   REPEAT STRIP_TAC THEN ASM_SIMP_TAC[]);;
11826
11827 let EQUIINTEGRABLE_EQ = prove
11828  (`!fs gs:(real^M->real^N)->bool s.
11829         fs equiintegrable_on s /\
11830         (!g. g IN gs ==> ?f. f IN fs /\ (!x. x IN s ==> f x = g x))
11831         ==> gs equiintegrable_on s`,
11832   REPEAT GEN_TAC THEN REWRITE_TAC[equiintegrable_on] THEN
11833   DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC (LABEL_TAC "*")) THEN
11834   CONJ_TAC THENL
11835    [X_GEN_TAC `g:real^M->real^N` THEN DISCH_TAC THEN
11836     REMOVE_THEN "*" (MP_TAC o SPEC `g:real^M->real^N`) THEN
11837     ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
11838     X_GEN_TAC `f:real^M->real^N` THEN STRIP_TAC THEN
11839     FIRST_X_ASSUM(MP_TAC o SPEC `f:real^M->real^N`) THEN
11840     ASM_MESON_TAC[INTEGRABLE_SPIKE; IN_DIFF; NEGLIGIBLE_EMPTY];
11841     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11842     FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
11843     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
11844     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
11845     MAP_EVERY X_GEN_TAC
11846      [`g:real^M->real^N`;`p:(real^M#(real^M->bool))->bool`] THEN
11847     STRIP_TAC THEN REMOVE_THEN "*" (MP_TAC o SPEC `g:real^M->real^N`) THEN
11848     ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
11849     X_GEN_TAC `f:real^M->real^N` THEN STRIP_TAC THEN
11850     FIRST_X_ASSUM(MP_TAC o SPECL
11851      [`f:real^M->real^N`;`p:(real^M#(real^M->bool))->bool`]) THEN
11852     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(MESON[]
11853      `x:real^N = y /\ a = b ==> norm(x - a) < e ==> norm(y - b) < e`) THEN
11854     CONJ_TAC THENL
11855      [MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
11856       RULE_ASSUM_TAC(REWRITE_RULE[TAGGED_DIVISION_OF; SUBSET]) THEN
11857       ASM_MESON_TAC[];
11858       ASM_MESON_TAC[INTEGRAL_EQ]]]);;
11859
11860 let EQUIINTEGRABLE_CMUL = prove
11861  (`!fs:(real^M->real^N)->bool s k.
11862         fs equiintegrable_on s
11863         ==> {(\x. c % f x) | abs(c) <= k /\ f IN fs} equiintegrable_on s`,
11864   REPEAT GEN_TAC THEN
11865   SIMP_TAC[equiintegrable_on; INTEGRABLE_CMUL; FORALL_IN_GSPEC] THEN
11866   STRIP_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11867   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
11868   ASM_SIMP_TAC[RIGHT_IMP_FORALL_THM; INTEGRAL_CMUL; IMP_IMP] THEN
11869   FIRST_X_ASSUM(MP_TAC o SPEC `e / (abs(k) + &1)`) THEN
11870   ASM_SIMP_TAC[REAL_LT_RDIV_EQ; REAL_MUL_LZERO;
11871                REAL_ARITH `&0 < abs(k) + &1`] THEN
11872   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
11873   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
11874   MAP_EVERY X_GEN_TAC [`c:real`; `f:real^M->real^N`;
11875                        `p:(real^M#(real^M->bool))->bool`] THEN
11876   STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o
11877    SPECL [`f:real^M->real^N`; `p:(real^M#(real^M->bool))->bool`]) THEN
11878   ASM_REWRITE_TAC[] THEN
11879   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN
11880   MATCH_MP_TAC(REAL_ARITH `&0 <= y /\ x <= c * y ==> x <= y * (c + &1)`) THEN
11881   REWRITE_TAC[NORM_POS_LE] THEN MATCH_MP_TAC(REAL_ARITH
11882    `!c. x = c * y /\ c *  y <= k * y ==> x <= k * y`) THEN
11883   EXISTS_TAC `abs c:real` THEN CONJ_TAC THENL
11884    [REWRITE_TAC[GSYM NORM_MUL; GSYM VSUM_LMUL; VECTOR_SUB_LDISTRIB] THEN
11885     REWRITE_TAC[LAMBDA_PAIR_THM; VECTOR_MUL_ASSOC; REAL_MUL_SYM];
11886     MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN
11887     ASM_REAL_ARITH_TAC]);;
11888
11889 let EQUIINTEGRABLE_ADD = prove
11890  (`!fs:(real^M->real^N)->bool gs s.
11891         fs equiintegrable_on s /\ gs equiintegrable_on s
11892         ==> {(\x. f x + g x) | f IN fs /\ g IN gs} equiintegrable_on s`,
11893   REPEAT GEN_TAC THEN
11894   SIMP_TAC[equiintegrable_on; INTEGRABLE_ADD; FORALL_IN_GSPEC] THEN
11895   DISCH_THEN(CONJUNCTS_THEN2
11896    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "f"))
11897    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "g"))) THEN
11898   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11899   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
11900   ASM_SIMP_TAC[RIGHT_IMP_FORALL_THM; INTEGRAL_ADD; IMP_IMP] THEN
11901   REMOVE_THEN "g" (MP_TAC o SPEC `e / &2`) THEN
11902   REMOVE_THEN "f" (MP_TAC o SPEC `e / &2`) THEN
11903   ASM_REWRITE_TAC[REAL_HALF] THEN
11904   DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool`
11905    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "f"))) THEN
11906   DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool`
11907    (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "g"))) THEN
11908   EXISTS_TAC `\x. (d1:real^M->real^M->bool) x INTER d2 x` THEN
11909   ASM_SIMP_TAC[GAUGE_INTER; FINE_INTER] THEN
11910   MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^M->real^N`;
11911                        `p:(real^M#(real^M->bool))->bool`] THEN STRIP_TAC THEN
11912   REMOVE_THEN "g" (MP_TAC o SPECL
11913    [`g:real^M->real^N`; `p:(real^M#(real^M->bool))->bool`]) THEN
11914   REMOVE_THEN "f" (MP_TAC o SPECL
11915    [`f:real^M->real^N`; `p:(real^M#(real^M->bool))->bool`]) THEN
11916   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(NORM_ARITH
11917    `s + s' = t
11918     ==> norm(s - i) < e / &2 ==> norm(s' - i') < e / &2
11919         ==> norm(t - (i + i')) < e`) THEN
11920   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
11921   ASM_SIMP_TAC[GSYM VSUM_ADD] THEN
11922   REWRITE_TAC[LAMBDA_PAIR_THM; VECTOR_ADD_LDISTRIB]);;
11923
11924 let EQUIINTEGRABLE_NEG = prove
11925  (`!fs:(real^M->real^N)->bool s.
11926         fs equiintegrable_on s
11927         ==> {(\x. --(f x)) | f IN fs} equiintegrable_on s`,
11928   REPEAT STRIP_TAC THEN
11929   FIRST_ASSUM(MP_TAC o SPEC `&1` o MATCH_MP EQUIINTEGRABLE_CMUL) THEN
11930   MATCH_MP_TAC (REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
11931   REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN REWRITE_TAC[IN_ELIM_THM] THEN
11932   X_GEN_TAC `f:real^M->real^N` THEN DISCH_TAC THEN EXISTS_TAC `-- &1` THEN
11933   EXISTS_TAC `f:real^M->real^N` THEN
11934   ASM_REWRITE_TAC[VECTOR_MUL_LNEG; VECTOR_MUL_LID] THEN REAL_ARITH_TAC);;
11935
11936 let EQUIINTEGRABLE_SUB = prove
11937  (`!fs:(real^M->real^N)->bool gs s.
11938         fs equiintegrable_on s /\ gs equiintegrable_on s
11939         ==> {(\x. f x - g x) | f IN fs /\ g IN gs} equiintegrable_on s`,
11940   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2
11941    MP_TAC (MP_TAC o MATCH_MP EQUIINTEGRABLE_NEG)) THEN
11942   REWRITE_TAC[GSYM IMP_CONJ_ALT] THEN
11943   DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_ADD) THEN
11944   MATCH_MP_TAC (REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
11945   REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN REWRITE_TAC[IN_ELIM_THM] THEN
11946   MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^M->real^N`] THEN
11947   STRIP_TAC THEN EXISTS_TAC `f:real^M->real^N` THEN
11948   EXISTS_TAC `\x. --((g:real^M->real^N) x)` THEN
11949   ASM_REWRITE_TAC[VECTOR_SUB] THEN EXISTS_TAC `g:real^M->real^N` THEN
11950   ASM_REWRITE_TAC[]);;
11951
11952 let EQUIINTEGRABLE_SUM = prove
11953  (`!fs:(real^M->real^N)->bool a b.
11954         fs equiintegrable_on interval[a,b]
11955         ==> {(\x. vsum t (\i. c i % f i x)) |
11956                FINITE t /\
11957                (!i:A. i IN t ==> &0 <= c i /\ (f i) IN fs) /\
11958                sum t c = &1}
11959             equiintegrable_on interval[a,b]`,
11960   REPEAT GEN_TAC THEN REWRITE_TAC[equiintegrable_on] THEN
11961   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
11962   REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC; RIGHT_IMP_FORALL_THM] THEN
11963   STRIP_TAC THEN
11964   ASM (CONV_TAC o GEN_SIMPLIFY_CONV TOP_DEPTH_SQCONV (basic_ss []) 5)
11965    [INTEGRABLE_CMUL; INTEGRABLE_VSUM; ETA_AX; INTEGRAL_VSUM] THEN
11966   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
11967   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
11968   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
11969   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MAP_EVERY X_GEN_TAC
11970    [`t:A->bool`; `c:A->real`; `f:A->real^M->real^N`;
11971     `p:(real^M#(real^M->bool))->bool`] THEN
11972   STRIP_TAC THEN
11973   SUBGOAL_THEN
11974    `!i:A. i IN t
11975           ==> integral (interval[a,b]) (\x:real^M. c i % f i x:real^N) =
11976               vsum p (\(x:real^M,k).
11977                        integral (k:real^M->bool) (\x:real^M. c i % f i x))`
11978    (fun th -> SIMP_TAC[th])
11979   THENL
11980    [REPEAT STRIP_TAC THEN
11981     MATCH_MP_TAC INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN THEN
11982     ASM_SIMP_TAC[INTEGRABLE_CMUL; ETA_AX];
11983     ALL_TAC] THEN
11984   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
11985   SUBGOAL_THEN
11986    `vsum p (\(x,k:real^M->bool). content k % vsum t (\i. c i % f i x)) =
11987     vsum t (\i. c i %
11988                 vsum p (\(x,k). content k % (f:A->real^M->real^N) i x))`
11989   SUBST1_TAC THENL
11990    [REWRITE_TAC[GSYM VSUM_LMUL] THEN
11991     W(MP_TAC o PART_MATCH (lhs o rand) VSUM_SWAP o
11992       rand o snd) THEN
11993     ASM_REWRITE_TAC[] THEN DISCH_THEN SUBST1_TAC THEN
11994     MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
11995     REWRITE_TAC[VECTOR_MUL_ASSOC; REAL_MUL_SYM];
11996     ALL_TAC] THEN
11997   MATCH_MP_TAC REAL_LET_TRANS THEN
11998   EXISTS_TAC `sum t (\i:A. c i * e / &2)` THEN CONJ_TAC THENL
11999    [ALL_TAC;
12000     ASM_SIMP_TAC[SUM_RMUL; ETA_AX; REAL_MUL_LID] THEN ASM_REAL_ARITH_TAC] THEN
12001   ASM_SIMP_TAC[GSYM VSUM_SUB] THEN MATCH_MP_TAC VSUM_NORM_LE THEN
12002   ASM_REWRITE_TAC[] THEN X_GEN_TAC `i:A` THEN DISCH_TAC THEN
12003   ASM_SIMP_TAC[GSYM VSUM_LMUL; GSYM VSUM_SUB] THEN
12004   REWRITE_TAC[LAMBDA_PAIR_THM] THEN FIRST_X_ASSUM(MP_TAC o SPECL
12005    [`(f:A->real^M->real^N) i`; `p:(real^M#(real^M->bool))->bool`]) THEN
12006   ASM_SIMP_TAC[] THEN DISCH_THEN(MP_TAC o MATCH_MP REAL_LT_IMP_LE) THEN
12007   DISCH_THEN(MP_TAC o SPEC `abs((c:A->real) i)` o
12008     MATCH_MP(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_LMUL)) THEN
12009   ASM_REWRITE_TAC[REAL_ABS_POS; GSYM NORM_MUL] THEN
12010   ASM_SIMP_TAC[GSYM VSUM_LMUL; VECTOR_SUB_LDISTRIB; real_abs] THEN
12011   REWRITE_TAC[LAMBDA_PAIR_THM] THEN
12012   MATCH_MP_TAC(REAL_ARITH `x = y ==> x <= a ==> y <= a`) THEN
12013   AP_TERM_TAC THEN
12014   SUBGOAL_THEN
12015    `integral (interval[a,b]) ((f:A->real^M->real^N) i) =
12016     vsum p (\(x:real^M,k). integral (k:real^M->bool) (f i))`
12017   SUBST1_TAC THENL
12018    [MATCH_MP_TAC INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN THEN ASM_SIMP_TAC[];
12019     ALL_TAC] THEN
12020   ASM_SIMP_TAC[GSYM VSUM_LMUL; GSYM VSUM_SUB] THEN
12021   MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
12022   MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
12023   AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_CMUL THEN
12024   RULE_ASSUM_TAC(REWRITE_RULE[TAGGED_DIVISION_OF]) THEN
12025   ASM_MESON_TAC[INTEGRABLE_SUBINTERVAL]);;
12026
12027 let EQUIINTEGRABLE_UNIFORM_LIMIT = prove
12028  (`!fs:(real^M->real^N)->bool a b.
12029         fs equiintegrable_on interval[a,b]
12030         ==> {g | !e. &0 < e
12031                      ==> ?f. f IN fs /\
12032                              !x. x IN interval[a,b] ==> norm(g x - f x) < e}
12033             equiintegrable_on interval[a,b]`,
12034   REPEAT STRIP_TAC THEN
12035   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [equiintegrable_on]) THEN
12036   REWRITE_TAC[equiintegrable_on; IN_ELIM_THM] THEN REPEAT GEN_TAC THEN
12037   STRIP_TAC THEN CONJ_TAC THENL
12038    [ASM_MESON_TAC[INTEGRABLE_UNIFORM_LIMIT; REAL_LT_IMP_LE]; ALL_TAC] THEN
12039   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
12040   FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
12041   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
12042   STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MAP_EVERY X_GEN_TAC
12043    [`g:real^M->real^N`;`p:(real^M#(real^M->bool))->bool`] THEN
12044   STRIP_TAC THEN
12045   FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
12046   SUBGOAL_THEN `(g:real^M->real^N) integrable_on interval[a,b]`
12047   ASSUME_TAC THENL
12048    [ASM_MESON_TAC[INTEGRABLE_UNIFORM_LIMIT; REAL_LT_IMP_LE]; ALL_TAC] THEN
12049   FIRST_X_ASSUM(MP_TAC o GEN `n:num` o SPEC `inv(&n + &1)`) THEN
12050   REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
12051   REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM; LEFT_IMP_EXISTS_THM] THEN
12052   X_GEN_TAC `f:num->real^M->real^N` THEN STRIP_TAC THEN
12053   SUBGOAL_THEN
12054    `!x. x IN interval[a,b]
12055         ==> ((\n. f n x) --> (g:real^M->real^N) x) sequentially`
12056   ASSUME_TAC THENL
12057    [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
12058     REWRITE_TAC[LIM_SEQUENTIALLY] THEN X_GEN_TAC `k:real` THEN DISCH_TAC THEN
12059     MP_TAC(SPEC `k:real` REAL_ARCH_INV) THEN ASM_REWRITE_TAC[] THEN
12060     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
12061     STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
12062     REWRITE_TAC[NORM_ARITH `dist(a:real^N,b) = norm(b - a)`] THEN
12063     MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `inv(&n + &1)` THEN
12064     ASM_SIMP_TAC[] THEN
12065     MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN
12066     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
12067     REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
12068     ASM_ARITH_TAC;
12069     ALL_TAC] THEN
12070   MP_TAC(ISPECL [`f:num->real^M->real^N`; `g:real^M->real^N`;
12071                  `a:real^M`; `b:real^M`] EQUIINTEGRABLE_LIMIT) THEN
12072   ANTS_TAC THENL
12073    [ASM_REWRITE_TAC[] THEN MATCH_MP_TAC EQUIINTEGRABLE_SUBSET THEN
12074     EXISTS_TAC `fs:(real^M->real^N)->bool` THEN ASM SET_TAC[];
12075     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*"))] THEN
12076   SUBGOAL_THEN
12077    `((\n. vsum p (\(x,k:real^M->bool).
12078                     content k % (f:num->real^M->real^N) n x)) -->
12079      vsum p (\(x,k). content k % g x)) sequentially`
12080    (LABEL_TAC "+")
12081   THENL
12082    [MATCH_MP_TAC
12083        (REWRITE_RULE[LAMBDA_PAIR_THM]
12084         (REWRITE_RULE[FORALL_PAIR_THM]
12085          (ISPEC `\(x:real^M,k:real^M->bool) (n:num).
12086                   content k % (f n x:real^N)` LIM_VSUM))) THEN
12087     ASM_REWRITE_TAC[] THEN
12088     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
12089     MATCH_MP_TAC LIM_CMUL THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
12090     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
12091     ASM_SIMP_TAC[SUBSET] THEN ASM_MESON_TAC[];
12092     ALL_TAC] THEN
12093   REMOVE_THEN "*" (MP_TAC o REWRITE_RULE[LIM_SEQUENTIALLY]) THEN
12094   DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
12095   ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[dist]] THEN
12096   DISCH_THEN(X_CHOOSE_THEN `N1:num` (LABEL_TAC "*")) THEN
12097   REMOVE_THEN "+" (MP_TAC o REWRITE_RULE[LIM_SEQUENTIALLY]) THEN
12098   DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
12099   ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[dist]] THEN
12100   DISCH_THEN(X_CHOOSE_THEN `N2:num` (LABEL_TAC "+")) THEN
12101   SUBGOAL_THEN `?n:num. N1 <= n /\ N2 <= n` STRIP_ASSUME_TAC THENL
12102    [EXISTS_TAC `N1 + N2:num` THEN ARITH_TAC; ALL_TAC] THEN
12103   REMOVE_THEN "*" (MP_TAC o SPEC `n:num`) THEN
12104   REMOVE_THEN "+" (MP_TAC o SPEC `n:num`) THEN
12105   FIRST_X_ASSUM(MP_TAC o SPECL
12106    [`(f:num->real^M->real^N) n`;`p:(real^M#(real^M->bool))->bool`]) THEN
12107   ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);;
12108
12109 let EQUIINTEGRABLE_REFLECT = prove
12110  (`!fs:(real^M->real^N)->bool a b.
12111         fs equiintegrable_on interval[a,b]
12112         ==> {(\x. f(--x)) | f IN fs} equiintegrable_on interval[--b,--a]`,
12113   let lemma = prove
12114    (`(!x k. (x,k) IN IMAGE (\(x,k). f x k,g x k) s ==> Q x k) <=>
12115      (!x k. (x,k) IN s ==> Q (f x k) (g x k))`,
12116     REWRITE_TAC[IN_IMAGE; PAIR_EQ; EXISTS_PAIR_THM] THEN SET_TAC[]) in
12117   REPEAT GEN_TAC THEN REWRITE_TAC[equiintegrable_on] THEN
12118   REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_GSPEC] THEN
12119   DISCH_TAC THEN DISCH_TAC THEN
12120   ASM_REWRITE_TAC[INTEGRABLE_REFLECT; INTEGRAL_REFLECT] THEN
12121   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
12122   FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
12123   FIRST_X_ASSUM(K ALL_TAC o check (is_forall o concl)) THEN
12124   DISCH_THEN(X_CHOOSE_THEN `d:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
12125   EXISTS_TAC `\x. IMAGE (--) ((d:real^M->real^M->bool) (--x))` THEN
12126   CONJ_TAC THENL
12127    [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [gauge]) THEN
12128     SIMP_TAC[gauge; OPEN_NEGATIONS] THEN DISCH_TAC THEN
12129     GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM VECTOR_NEG_NEG] THEN
12130     MATCH_MP_TAC FUN_IN_IMAGE THEN ASM_REWRITE_TAC[];
12131     ALL_TAC] THEN
12132   X_GEN_TAC `f:real^M->real^N` THEN DISCH_TAC THEN
12133   X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN REPEAT DISCH_TAC THEN
12134   FIRST_X_ASSUM(MP_TAC o SPEC `f:real^M->real^N`) THEN ASM_REWRITE_TAC[] THEN
12135   DISCH_THEN(MP_TAC o SPEC
12136    `IMAGE (\(x,k). (--x:real^M,IMAGE (--) (k:real^M->bool))) p`) THEN
12137   ANTS_TAC THENL
12138    [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
12139     REWRITE_TAC[TAGGED_DIVISION_OF] THEN
12140     STRIP_TAC THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN
12141     REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; lemma] THEN
12142     REPEAT CONJ_TAC THENL
12143      [MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
12144       ASM_SIMP_TAC[FUN_IN_IMAGE] THEN CONJ_TAC THENL
12145        [REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
12146         ONCE_REWRITE_TAC[GSYM IN_INTERVAL_REFLECT] THEN
12147         ASM_SIMP_TAC[VECTOR_NEG_NEG; GSYM SUBSET] THEN ASM_MESON_TAC[];
12148         REWRITE_TAC[EXTENSION; IN_IMAGE] THEN
12149         REWRITE_TAC[VECTOR_ARITH `x:real^N = --y <=> --x = y`] THEN
12150         ONCE_REWRITE_TAC[GSYM IN_INTERVAL_REFLECT] THEN
12151         REWRITE_TAC[UNWIND_THM1] THEN
12152         SUBGOAL_THEN `?u v:real^M. k = interval[u,v]`
12153          (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
12154         THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
12155         ASM_MESON_TAC[VECTOR_NEG_NEG]];
12156       MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
12157       MAP_EVERY X_GEN_TAC [`y:real^M`; `l:real^M->bool`] THEN DISCH_TAC THEN
12158       FIRST_X_ASSUM(MP_TAC o SPECL
12159        [`x:real^M`; `k:real^M->bool`;
12160         `y:real^M`; `l:real^M->bool`]) THEN
12161       ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_IMP THEN
12162       CONJ_TAC THENL [MESON_TAC[PAIR_EQ]; ALL_TAC] THEN
12163       REWRITE_TAC[INTERIOR_NEGATIONS] THEN
12164       MATCH_MP_TAC(SET_RULE
12165        `(!x. f(f x) = x)
12166         ==> s INTER t = {} ==> IMAGE f s INTER IMAGE f t = {}`) THEN
12167       REWRITE_TAC[VECTOR_NEG_NEG];
12168       GEN_REWRITE_TAC I [EXTENSION] THEN
12169       ONCE_REWRITE_TAC[GSYM IN_INTERVAL_REFLECT] THEN
12170       FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN X_GEN_TAC `y:real^M` THEN
12171       REWRITE_TAC[IN_UNIONS; IN_ELIM_THM] THEN
12172       MATCH_MP_TAC(MESON[]
12173        `!f. (!x. f(f x) = x) /\ (!x. P x <=> Q(f x))
12174             ==> ((?x. P x) <=> (?x. Q x))`) THEN
12175       EXISTS_TAC `IMAGE ((--):real^M->real^M)` THEN CONJ_TAC THENL
12176        [REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_NEG_NEG; IMAGE_ID];
12177         ALL_TAC] THEN
12178       X_GEN_TAC `t:real^M->bool` THEN BINOP_TAC THENL
12179        [REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM; PAIR_EQ] THEN
12180         SUBGOAL_THEN `!k:real^M->bool. IMAGE (--) (IMAGE (--) k) = k`
12181         MP_TAC THENL
12182          [REWRITE_TAC[GSYM IMAGE_o; o_DEF; VECTOR_NEG_NEG; IMAGE_ID];
12183           MESON_TAC[]];
12184         MATCH_MP_TAC(SET_RULE
12185          `(!x. f(f x) = x) ==> (y IN s <=> f y IN IMAGE f s)`) THEN
12186         REWRITE_TAC[VECTOR_NEG_NEG]]];
12187     ANTS_TAC THENL
12188      [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
12189       REWRITE_TAC[fine; lemma] THEN
12190       REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
12191       MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
12192       MATCH_MP_TAC(SET_RULE
12193        `(!x. f(f x) = x) ==> k SUBSET IMAGE f s ==> IMAGE f k SUBSET s`) THEN
12194       REWRITE_TAC[VECTOR_NEG_NEG];
12195       ALL_TAC] THEN
12196     MATCH_MP_TAC(NORM_ARITH
12197      `x:real^N = y ==> norm(x - i) < e ==> norm(y - i) < e`) THEN
12198     W(MP_TAC o PART_MATCH (lhs o rand) VSUM_IMAGE o lhs o snd) THEN
12199     FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
12200     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
12201      [MATCH_MP_TAC(MESON[]
12202        `(!x. f(f x) = x)
12203         ==> !x y. x IN p /\ y IN p /\ f x = f y ==> x = y`) THEN
12204       REWRITE_TAC[FORALL_PAIR_THM; GSYM IMAGE_o; o_DEF; VECTOR_NEG_NEG;
12205                   IMAGE_ID];
12206       DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
12207       REWRITE_TAC[FORALL_PAIR_THM; o_THM] THEN
12208       MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
12209       SUBGOAL_THEN `?u v:real^M. k = interval[u,v]`
12210        (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
12211       THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
12212       AP_THM_TAC THEN AP_TERM_TAC THEN
12213       SUBGOAL_THEN `(--):real^M->real^M = (\x. --(&1) % x + vec 0)` SUBST1_TAC
12214       THENL [REWRITE_TAC[FUN_EQ_THM] THEN VECTOR_ARITH_TAC; ALL_TAC] THEN
12215       REWRITE_TAC[CONTENT_IMAGE_AFFINITY_INTERVAL; REAL_ABS_NEG] THEN
12216       REWRITE_TAC[REAL_POW_ONE; REAL_MUL_LID; REAL_ABS_NUM]]]);;
12217
12218 (* ------------------------------------------------------------------------- *)
12219 (* Some technical lemmas about minimizing a "flat" part of a sum over a      *)
12220 (* division, followed by subinterval resictions for equiintegrable family.   *)
12221 (* ------------------------------------------------------------------------- *)
12222
12223 let SUM_CONTENT_AREA_OVER_THIN_DIVISION = prove
12224  (`!d a b:real^M s i c.
12225         d division_of s /\ s SUBSET interval[a,b] /\
12226         1 <= i /\ i <= dimindex(:M) /\ a$i <= c /\ c <= b$i /\
12227         (!k. k IN d ==> ~(k INTER {x | x$i = c} = {}))
12228         ==> (b$i - a$i) *
12229             sum d (\k. content k /
12230                        (interval_upperbound k$i - interval_lowerbound k$i))
12231             <= &2 * content(interval[a,b])`,
12232   let lemma0 = prove
12233    (`!k:real^M->bool i.
12234           1 <= i /\ i <= dimindex(:M)
12235           ==> content k / (interval_upperbound k$i - interval_lowerbound k$i) =
12236               if content k = &0 then &0
12237               else product ((1..dimindex(:M)) DELETE i)
12238                            (\j. interval_upperbound k$j -
12239                                 interval_lowerbound k$j)`,
12240     REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
12241     ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO] THEN
12242     REWRITE_TAC[content] THEN
12243     COND_CASES_TAC THENL [ASM_MESON_TAC[CONTENT_EMPTY]; ALL_TAC] THEN
12244     SUBGOAL_THEN
12245      `1..dimindex(:M) = i INSERT ((1..dimindex(:M)) DELETE i)`
12246     MP_TAC THENL
12247      [REWRITE_TAC[SET_RULE `s = x INSERT (s DELETE x) <=> x IN s`] THEN
12248       ASM_REWRITE_TAC[IN_NUMSEG];
12249       DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
12250        [th])] THEN
12251     ASM_SIMP_TAC[PRODUCT_CLAUSES; IN_NUMSEG; FINITE_DELETE; FINITE_NUMSEG;
12252                  IN_DELETE] THEN
12253     MATCH_MP_TAC(REAL_FIELD `~(y = &0) ==> (y * x) * inv y = x`) THEN
12254     DISCH_TAC THEN
12255     UNDISCH_TAC `~(content(k:real^M->bool) = &0)` THEN
12256     ASM_REWRITE_TAC[content; PRODUCT_EQ_0_NUMSEG] THEN ASM_MESON_TAC[])
12257   and lemma1 = prove
12258    (`!d a b:real^M s i.
12259           d division_of s /\ s SUBSET interval[a,b] /\
12260           1 <= i /\ i <= dimindex(:M) /\
12261           ((!k. k IN d
12262                 ==> ~(content k = &0) /\ ~(k INTER {x | x$i = a$i} = {})) \/
12263            (!k. k IN d
12264                 ==> ~(content k = &0) /\ ~(k INTER {x | x$i = b$i} = {})))
12265           ==> (b$i - a$i) *
12266               sum d (\k. content k /
12267                          (interval_upperbound k$i - interval_lowerbound k$i))
12268               <= content(interval[a,b])`,
12269     REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
12270     FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
12271     ABBREV_TAC
12272      `extend =
12273       \k:real^M->bool. interval
12274            [(lambda j. if j = i then (a:real^M)$i
12275                        else interval_lowerbound k$j):real^M,
12276             (lambda j. if j = i then (b:real^M)$i
12277                        else interval_upperbound k$j)]` THEN
12278     SUBGOAL_THEN `!k. k IN d ==> k SUBSET interval[a:real^M,b]`
12279     ASSUME_TAC THENL
12280      [RULE_ASSUM_TAC(REWRITE_RULE[division_of]) THEN ASM SET_TAC[];
12281       ALL_TAC] THEN
12282     SUBGOAL_THEN `!k:real^M->bool. k IN d ==> ~(k = {})` ASSUME_TAC THENL
12283      [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
12284     SUBGOAL_THEN
12285      `(!k. k IN d ==> ~((extend:(real^M->bool)->(real^M->bool)) k = {})) /\
12286       (!k. k IN d ==> extend k SUBSET interval[a,b])`
12287     STRIP_ASSUME_TAC THENL
12288      [FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
12289       CONJ_TAC THEN MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN
12290       (DISCH_TAC THEN EXPAND_TAC "extend" THEN
12291        SUBGOAL_THEN `interval[u:real^M,v] SUBSET interval[a,b]` MP_TAC THENL
12292         [ASM_SIMP_TAC[]; ALL_TAC] THEN
12293        SUBGOAL_THEN `~(interval[u:real^M,v] = {})` MP_TAC THENL
12294         [ASM_SIMP_TAC[]; ALL_TAC] THEN
12295        SIMP_TAC[SUBSET_INTERVAL; INTERVAL_NE_EMPTY; LAMBDA_BETA;
12296                 INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN
12297        MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL]);
12298       ALL_TAC] THEN
12299     SUBGOAL_THEN
12300      `!k1 k2. k1 IN d /\ k2 IN d /\ ~(k1 = k2)
12301               ==> interior((extend:(real^M->bool)->(real^M->bool)) k1) INTER
12302                   interior(extend k2) = {}`
12303     ASSUME_TAC THENL
12304      [REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
12305       FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
12306       MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN DISCH_TAC THEN
12307       MAP_EVERY X_GEN_TAC [`w:real^M`; `z:real^M`] THEN DISCH_TAC THEN
12308       DISCH_TAC THEN
12309       FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
12310       DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN DISCH_THEN(MP_TAC o SPECL
12311        [`interval[u:real^M,v]`; `interval[w:real^M,z]`]) THEN
12312       ASM_REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN
12313       ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
12314       REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN
12315       EXPAND_TAC "extend" THEN
12316       SIMP_TAC[INTERIOR_CLOSED_INTERVAL; IN_INTERVAL; LAMBDA_BETA] THEN
12317       SUBGOAL_THEN `~(interval[u:real^M,v] = {}) /\
12318                     ~(interval[w:real^M,z] = {})`
12319       MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
12320       SIMP_TAC[SUBSET_INTERVAL; INTERVAL_NE_EMPTY; LAMBDA_BETA;
12321                INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN
12322       STRIP_TAC THEN DISCH_THEN(X_CHOOSE_THEN `x:real^M` MP_TAC) THEN
12323       MP_TAC(MESON[]
12324        `(!P. (!j:num. P j) <=> P i /\ (!j. ~(j = i) ==> P j))`) THEN
12325       DISCH_THEN(fun th -> GEN_REWRITE_TAC
12326        (LAND_CONV o ONCE_DEPTH_CONV) [th]) THEN
12327       ASM_SIMP_TAC[IMP_IMP] THEN STRIP_TAC THEN
12328       FIRST_X_ASSUM(DISJ_CASES_THEN
12329        (fun th -> MP_TAC(SPEC `interval[u:real^M,v]` th) THEN
12330                   MP_TAC(SPEC `interval[w:real^M,z]` th))) THEN
12331       ASM_REWRITE_TAC[CONTENT_EQ_0_INTERIOR; INTERIOR_CLOSED_INTERVAL] THEN
12332       REWRITE_TAC[IMP_CONJ; GSYM MEMBER_NOT_EMPTY; IN_INTER; IN_ELIM_THM] THEN
12333       REWRITE_TAC[IN_INTERVAL; LEFT_IMP_EXISTS_THM] THEN
12334       X_GEN_TAC `q:real^M` THEN STRIP_TAC THEN
12335       X_GEN_TAC `r:real^M` THEN STRIP_TAC THEN
12336       X_GEN_TAC `s:real^M` THEN STRIP_TAC THEN
12337       X_GEN_TAC `t:real^M` THEN STRIP_TAC THENL
12338        [EXISTS_TAC `(lambda j. if j = i then min ((q:real^M)$i) ((s:real^M)$i)
12339                                else (x:real^M)$j):real^M`;
12340         EXISTS_TAC `(lambda j. if j = i then max ((q:real^M)$i) ((s:real^M)$i)
12341                                else (x:real^M)$j):real^M`] THEN
12342       (SIMP_TAC[AND_FORALL_THM; LAMBDA_BETA] THEN X_GEN_TAC `j:num` THEN
12343        ASM_CASES_TAC `j:num = i` THEN ASM_SIMP_TAC[] THEN
12344        UNDISCH_THEN `j:num = i` SUBST_ALL_TAC THEN
12345        SUBGOAL_THEN `interval[u:real^M,v] SUBSET interval[a,b] /\
12346                      interval[w:real^M,z] SUBSET interval[a,b]`
12347        MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
12348        SUBGOAL_THEN `~(interval[u:real^M,v] = {}) /\
12349                      ~(interval[w:real^M,z] = {})`
12350        MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
12351        SIMP_TAC[INTERVAL_NE_EMPTY; SUBSET_INTERVAL] THEN
12352        REPEAT STRIP_TAC THEN
12353        REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN ASM_REWRITE_TAC[] THEN
12354        ASM_REAL_ARITH_TAC);
12355       ALL_TAC] THEN
12356     MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
12357      `sum (IMAGE (extend:(real^M->bool)->(real^M->bool)) d) content` THEN
12358     CONJ_TAC THENL
12359      [W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE_NONZERO o rand o snd) THEN
12360       ANTS_TAC THENL
12361        [ASM_REWRITE_TAC[] THEN
12362         MAP_EVERY X_GEN_TAC [`k1:real^M->bool`; `k2:real^M->bool`] THEN
12363         STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL
12364          [`k1:real^M->bool`; `k2:real^M->bool`]) THEN
12365         ASM_REWRITE_TAC[INTER_IDEMPOT] THEN
12366         EXPAND_TAC "extend" THEN REWRITE_TAC[CONTENT_EQ_0_INTERIOR];
12367         DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[GSYM SUM_LMUL] THEN
12368         MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[] THEN
12369         FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
12370         MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN DISCH_TAC THEN
12371         ASM_CASES_TAC `content(interval[u:real^M,v]) = &0` THENL
12372          [ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO; REAL_MUL_RZERO; o_THM] THEN
12373           EXPAND_TAC "extend" THEN REWRITE_TAC[CONTENT_POS_LE];
12374           ALL_TAC] THEN
12375         FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM CONTENT_LT_NZ]) THEN
12376         DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
12377         REWRITE_TAC[CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
12378         ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND;
12379                      REAL_LT_IMP_LE; real_div; REAL_MUL_ASSOC] THEN
12380         ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ; REAL_SUB_LT] THEN
12381         SUBGOAL_THEN
12382          `~((extend:(real^M->bool)->(real^M->bool)) (interval[u,v]) = {})`
12383         MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
12384         EXPAND_TAC "extend" THEN ASM_SIMP_TAC[content; o_THM] THEN
12385         ASM_SIMP_TAC[INTERVAL_NE_EMPTY; INTERVAL_LOWERBOUND;
12386                      INTERVAL_UPPERBOUND; REAL_LT_IMP_LE] THEN
12387         DISCH_THEN(K ALL_TAC) THEN
12388         SUBGOAL_THEN
12389          `1..dimindex(:M) = i INSERT ((1..dimindex(:M)) DELETE i)`
12390         SUBST1_TAC THENL
12391          [MATCH_MP_TAC(SET_RULE `x IN s ==> s = x INSERT (s DELETE x)`) THEN
12392           ASM_REWRITE_TAC[IN_NUMSEG];
12393           ALL_TAC] THEN
12394         SIMP_TAC[PRODUCT_CLAUSES; FINITE_NUMSEG; FINITE_DELETE] THEN
12395         ASM_SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA] THEN
12396         MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC(REAL_RING
12397           `x:real = y ==> ab * uv * x = (ab * y) * uv`) THEN
12398         MATCH_MP_TAC PRODUCT_EQ THEN
12399         SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA]];
12400       MATCH_MP_TAC SUBADDITIVE_CONTENT_DIVISION THEN EXISTS_TAC
12401        `UNIONS (IMAGE (extend:(real^M->bool)->(real^M->bool)) d)` THEN
12402       ASM_SIMP_TAC[UNIONS_SUBSET; division_of; FINITE_IMAGE] THEN
12403       REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
12404       FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
12405       REPEAT CONJ_TAC THEN MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN
12406       DISCH_TAC THENL
12407        [CONJ_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[]] THEN
12408         EXPAND_TAC "extend" THEN REWRITE_TAC[] THEN MESON_TAC[];
12409         ASM_MESON_TAC[];
12410         ASM_SIMP_TAC[]]]) in
12411   REPEAT STRIP_TAC THEN
12412   ASM_CASES_TAC `content(interval[a:real^M,b]) = &0` THENL
12413    [MATCH_MP_TAC(REAL_ARITH `x = &0 /\ &0 <= y ==> x <= &2 * y`) THEN
12414     REWRITE_TAC[CONTENT_POS_LE; REAL_ENTIRE] THEN DISJ2_TAC THEN
12415     MATCH_MP_TAC SUM_EQ_0 THEN X_GEN_TAC `k:real^M->bool` THEN
12416     DISCH_TAC THEN REWRITE_TAC[real_div; REAL_ENTIRE] THEN DISJ1_TAC THEN
12417     MATCH_MP_TAC CONTENT_0_SUBSET THEN
12418     MAP_EVERY EXISTS_TAC [`a:real^M`; `b:real^M`] THEN
12419     ASM_MESON_TAC[division_of; SUBSET_TRANS];
12420     ALL_TAC] THEN
12421   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM CONTENT_LT_NZ]) THEN
12422   DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
12423   REWRITE_TAC[CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
12424   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
12425   MP_TAC(ISPECL
12426    [`{k | k IN {l INTER {x | x$i <= c} | l |
12427                 l IN d /\ ~(l INTER {x:real^M | x$i <= c} = {})} /\
12428           ~(content k = &0)}`;
12429     `a:real^M`;
12430     `(lambda j. if j = i then c else (b:real^M)$j):real^M`;
12431     `UNIONS {k | k IN {l INTER {x | x$i <= c} | l |
12432                        l IN d /\ ~(l INTER {x:real^M | x$i <= c} = {})} /\
12433                  ~(content k = &0)}`;
12434     `i:num`] lemma1) THEN
12435   MP_TAC(ISPECL
12436    [`{k | k IN {l INTER {x | x$i >= c} | l |
12437                 l IN d /\ ~(l INTER {x:real^M | x$i >= c} = {})} /\
12438           ~(content k = &0)}`;
12439     `(lambda j. if j = i then c else (a:real^M)$j):real^M`;
12440     `b:real^M`;
12441     `UNIONS {k | k IN {l INTER {x | x$i >= c} | l |
12442                        l IN d /\ ~(l INTER {x:real^M | x$i >= c} = {})} /\
12443                  ~(content k = &0)}`;
12444     `i:num`] lemma1) THEN
12445   ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT
12446    `(p1 /\ p2) /\ (q1 /\ q2 ==> r) ==> (p2 ==> q2) ==> (p1 ==> q1) ==> r`) THEN
12447   CONJ_TAC THENL
12448    [CONJ_TAC THEN
12449     (REPEAT CONJ_TAC THENL
12450      [REWRITE_TAC[division_of] THEN CONJ_TAC THENL
12451        [MATCH_MP_TAC FINITE_RESTRICT THEN
12452         ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
12453         MATCH_MP_TAC FINITE_IMAGE THEN MATCH_MP_TAC FINITE_RESTRICT THEN
12454         ASM_REWRITE_TAC[];
12455         ALL_TAC] THEN
12456       REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
12457       CONJ_TAC THENL
12458        [FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
12459         MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN
12460         REPEAT DISCH_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
12461          [REWRITE_TAC[IN_ELIM_THM; SUBSET; IN_UNIONS] THEN ASM_MESON_TAC[];
12462           ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MESON_TAC[]];
12463         X_GEN_TAC `k:real^M->bool` THEN REPEAT DISCH_TAC THEN
12464         X_GEN_TAC `l:real^M->bool` THEN REPEAT DISCH_TAC THEN
12465         FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
12466         DISCH_THEN(MP_TAC o SPECL [`k:real^M->bool`; `l:real^M->bool`] o
12467           el 2 o CONJUNCTS) THEN
12468         ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
12469         MATCH_MP_TAC(SET_RULE
12470          `s SUBSET s' /\ t SUBSET t'
12471           ==> s' INTER t' = {} ==> s INTER t = {}`) THEN
12472         CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]];
12473       REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC; IMP_CONJ] THEN
12474       X_GEN_TAC `k:real^M->bool` THEN REPEAT DISCH_TAC THEN
12475       SUBGOAL_THEN `k SUBSET interval[a:real^M,b]` MP_TAC THENL
12476        [ASM_MESON_TAC[division_of; SUBSET_TRANS]; ALL_TAC] THEN
12477       MATCH_MP_TAC(SET_RULE
12478        `i INTER h SUBSET j ==> k SUBSET i ==> k INTER h SUBSET j`) THEN
12479       ASM_SIMP_TAC[INTERVAL_SPLIT; SUBSET_INTERVAL; LAMBDA_BETA] THEN
12480       MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
12481       REAL_ARITH_TAC;
12482       ALL_TAC])
12483     THENL [DISJ2_TAC; DISJ1_TAC] THEN
12484     REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ] THEN
12485     ASM_SIMP_TAC[LAMBDA_BETA; real_ge] THEN ASM SET_TAC[REAL_LE_REFL];
12486     ASM_SIMP_TAC[LAMBDA_BETA]] THEN
12487   SUBGOAL_THEN
12488    `sum {k | k IN
12489              { l INTER {x | x$i <= c} | l |
12490                l IN d /\ ~(l INTER {x:real^M | x$i <= c} = {})} /\
12491              ~(content k = &0)}
12492         (\k. content k /
12493              (interval_upperbound k$i - interval_lowerbound k$i)) =
12494     sum d ((\k. content k /
12495              (interval_upperbound k$i - interval_lowerbound k$i)) o
12496            (\k. k INTER {x | x$i <= c})) /\
12497     sum {k | k IN
12498              { l INTER {x | x$i >= c} | l |
12499                l IN d /\ ~(l INTER {x:real^M | x$i >= c} = {})} /\
12500              ~(content k = &0)}
12501         (\k. content k /
12502              (interval_upperbound k$i - interval_lowerbound k$i)) =
12503     sum d ((\k. content k /
12504              (interval_upperbound k$i - interval_lowerbound k$i)) o
12505            (\k. k INTER {x | x$i >= c}))`
12506   (CONJUNCTS_THEN SUBST1_TAC) THENL
12507    [CONJ_TAC THEN
12508     (W(MP_TAC o PART_MATCH (rand o rand) SUM_IMAGE_NONZERO o rand o snd) THEN
12509      ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
12510       [MAP_EVERY X_GEN_TAC [`k:real^M->bool`; `l:real^M->bool`] THEN
12511        STRIP_TAC THEN
12512        REWRITE_TAC[real_div; REAL_ENTIRE] THEN DISJ1_TAC THEN
12513        (MATCH_MP_TAC DIVISION_SPLIT_LEFT_INJ ORELSE
12514         MATCH_MP_TAC DIVISION_SPLIT_RIGHT_INJ) THEN ASM_MESON_TAC[];
12515        DISCH_THEN(SUBST1_TAC o SYM) THEN CONV_TAC SYM_CONV THEN
12516        MATCH_MP_TAC SUM_SUPERSET THEN CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
12517        GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
12518         `x IN IMAGE f d /\
12519          ~(x IN {x | x IN {f y |y| y IN d /\ ~(f y = a)} /\ ~P x})
12520          ==> (!y. f y = a ==> P(f y)) ==> P x`)) THEN
12521        SIMP_TAC[CONTENT_EMPTY; real_div; REAL_MUL_LZERO]]);
12522      ALL_TAC] THEN
12523   MAP_EVERY (fun (t,tac) ->
12524     ASM_CASES_TAC t THENL
12525      [FIRST_X_ASSUM SUBST_ALL_TAC THEN DISCH_THEN(MP_TAC o tac) THEN
12526       MATCH_MP_TAC(REAL_ARITH `x = y /\ a <= b ==> x <= a ==> y <= b`) THEN
12527       CONJ_TAC THENL
12528        [AP_TERM_TAC THEN MATCH_MP_TAC SUM_EQ THEN
12529         X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
12530         PURE_REWRITE_TAC[o_THM] THEN AP_TERM_TAC THEN
12531         REWRITE_TAC[real_ge; SET_RULE
12532          `k INTER {x | P x} = k <=> (!x. x IN k ==> P x)`] THEN
12533         X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
12534         SUBGOAL_THEN `x IN interval[a:real^M,b]` MP_TAC THENL
12535          [ASM_MESON_TAC[SUBSET; division_of]; ALL_TAC] THEN
12536         ASM_SIMP_TAC[IN_INTERVAL];
12537         MATCH_MP_TAC(REAL_ARITH `&0 <= y /\ x <= y ==> x <= &2 * y`) THEN
12538         REWRITE_TAC[CONTENT_POS_LE] THEN MATCH_MP_TAC CONTENT_SUBSET THEN
12539         SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN
12540         MESON_TAC[REAL_LE_REFL]];
12541       ALL_TAC])
12542     [`c = (a:real^M)$i`,CONJUNCT2; `c = (b:real^M)$i`,CONJUNCT1] THEN
12543   SUBGOAL_THEN `(a:real^M)$i < c /\ c < (b:real^M)$i` STRIP_ASSUME_TAC THENL
12544    [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
12545   ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
12546   ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN
12547   REWRITE_TAC[REAL_ARITH `(x * &2) / y = &2 * x / y`] THEN
12548   MATCH_MP_TAC(REAL_ARITH
12549    `s <= s1 + s2 /\ c1 = c /\ c2 = c
12550     ==> s1 <= c1 /\ s2 <= c2 ==> s <= &2 * c`) THEN
12551   CONJ_TAC THENL
12552    [ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN
12553     ASM_SIMP_TAC[lemma0] THEN
12554     FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
12555     MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN DISCH_TAC THEN
12556     SUBGOAL_THEN
12557      `~(interval[u:real^M,v] = {}) /\ interval[u,v] SUBSET interval[a,b]`
12558     MP_TAC THENL [ASM_MESON_TAC[division_of; SUBSET_TRANS]; ALL_TAC] THEN
12559     SIMP_TAC[INTERVAL_NE_EMPTY; SUBSET_INTERVAL; IMP_CONJ] THEN
12560     REPEAT STRIP_TAC THEN REWRITE_TAC[o_THM] THEN
12561     MATCH_MP_TAC(REAL_ARITH
12562      `&0 <= x /\ c1 + c2 = c /\
12563       (~(c1 = &0) ==> x1 = x) /\ (~(c2 = &0) ==> x2 = x)
12564       ==> (if c = &0 then &0 else x) <=
12565           (if c1 = &0 then &0 else x1) +
12566           (if c2 = &0 then &0 else x2)`) THEN
12567     ASM_SIMP_TAC[GSYM CONTENT_SPLIT] THEN
12568     ASM_SIMP_TAC[INTERVAL_SPLIT; CONTENT_POS_LE] THEN CONJ_TAC THENL
12569      [MATCH_MP_TAC PRODUCT_POS_LE THEN
12570       ASM_SIMP_TAC[FINITE_DELETE; FINITE_NUMSEG; IN_DELETE; IN_NUMSEG;
12571                    INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_SUB_LE];
12572       REWRITE_TAC[CONTENT_EQ_0; REAL_NOT_LE; MESON[]
12573        `~(?i. P i /\ Q i /\ R i) <=> (!i. P i /\ Q i ==> ~R i)`] THEN
12574       SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_LT_IMP_LE] THEN
12575       REPEAT STRIP_TAC THEN MATCH_MP_TAC PRODUCT_EQ THEN
12576       ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; IN_DELETE;
12577                    IN_NUMSEG; LAMBDA_BETA]];
12578     SUBGOAL_THEN
12579      `~(interval[a,b] = {}) /\
12580       ~(interval[a:real^M,(lambda j. if j = i then c else b$j)] = {}) /\
12581       ~(interval[(lambda j. if j = i then c else a$j):real^M,b] = {})`
12582     MP_TAC THENL
12583      [SIMP_TAC[INTERVAL_NE_EMPTY; LAMBDA_BETA] THEN
12584       ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_LE_REFL];
12585       ALL_TAC] THEN
12586     SIMP_TAC[content] THEN
12587     SIMP_TAC[INTERVAL_NE_EMPTY; INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND] THEN
12588     STRIP_TAC THEN
12589     SUBGOAL_THEN
12590      `1..dimindex(:M) = i INSERT ((1..dimindex(:M)) DELETE i)`
12591     SUBST1_TAC THENL
12592      [MATCH_MP_TAC(SET_RULE `x IN s ==> s = x INSERT (s DELETE x)`) THEN
12593       ASM_REWRITE_TAC[IN_NUMSEG];
12594       ALL_TAC] THEN
12595     SIMP_TAC[PRODUCT_CLAUSES; FINITE_NUMSEG; FINITE_DELETE] THEN
12596     ASM_SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA] THEN
12597     CONJ_TAC THEN MATCH_MP_TAC(REAL_FIELD
12598      `y < x /\ z < w /\ a = b
12599       ==> ((x - y) * a) / (x - y) = ((w - z) * b) / (w - z)`) THEN
12600     ASM_SIMP_TAC[] THEN MATCH_MP_TAC PRODUCT_EQ THEN
12601     SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA]]);;
12602
12603 let BOUNDED_EQUIINTEGRAL_OVER_THIN_TAGGED_PARTIAL_DIVISION = prove
12604  (`!fs f:real^M->real^N a b e.
12605     fs equiintegrable_on interval[a,b] /\ f IN fs /\
12606     (!h x. h IN fs /\ x IN interval[a,b] ==> norm(h x) <= norm(f x)) /\
12607     &0 < e
12608     ==> ?d. gauge d /\
12609             !c i p h. c IN interval[a,b] /\ 1 <= i /\ i <= dimindex(:M) /\
12610                       p tagged_partial_division_of interval[a,b] /\
12611                       d fine p /\
12612                       h IN fs /\
12613                       (!x k. (x,k) IN p ==> ~(k INTER {x | x$i = c$i} = {}))
12614                       ==> sum p(\(x,k). norm(integral k h)) < e`,
12615   REPEAT STRIP_TAC THEN
12616   ASM_CASES_TAC `content(interval[a:real^M,b]) = &0` THENL
12617    [EXISTS_TAC `\x:real^M. ball(x,&1)` THEN REWRITE_TAC[GAUGE_TRIVIAL] THEN
12618     REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
12619      `&0 < e ==> x = &0 ==> x < e`)) THEN
12620     MATCH_MP_TAC SUM_EQ_0 THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
12621     GEN_TAC THEN X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
12622     SUBGOAL_THEN
12623      `?u v:real^M. k = interval[u,v] /\ interval[u,v] SUBSET interval[a,b]`
12624     STRIP_ASSUME_TAC THENL
12625      [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
12626     ASM_REWRITE_TAC[NORM_EQ_0] THEN MATCH_MP_TAC INTEGRAL_NULL THEN
12627     ASM_MESON_TAC[CONTENT_0_SUBSET];
12628     ALL_TAC] THEN
12629   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM CONTENT_LT_NZ]) THEN
12630   DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
12631   REWRITE_TAC[CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
12632   SUBGOAL_THEN
12633    `?d. gauge d /\
12634         !p h. p tagged_partial_division_of interval [a,b] /\
12635               d fine p /\ (h:real^M->real^N) IN fs
12636               ==> sum p (\(x,k). norm(content k % h x - integral k h)) <
12637                   e / &2`
12638    (X_CHOOSE_THEN `g0:real^M->real^M->bool` STRIP_ASSUME_TAC)
12639   THENL
12640    [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [equiintegrable_on]) THEN
12641     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC
12642       `e / &5 / (&(dimindex(:N)) + &1)`)) THEN
12643     ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &5 /\ &0 < &n + &1`] THEN
12644     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^M->real^M->bool` THEN
12645     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MAP_EVERY X_GEN_TAC
12646      [`p:(real^M#(real^M->bool))->bool`; `h:real^M->real^N`] THEN
12647     STRIP_TAC THEN
12648     MP_TAC(ISPECL [`h:real^M->real^N`; `a:real^M`; `b:real^M`;
12649            `g:real^M->real^M->bool`; `e / &5 / (&(dimindex(:N)) + &1)`]
12650         HENSTOCK_LEMMA_PART2) THEN
12651     ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &5 /\ &0 < &n + &1`] THEN
12652     DISCH_THEN(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN
12653     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
12654      `a < b ==> x <= a ==> x < b`) THEN
12655     REWRITE_TAC[REAL_ARITH `&2 * d * e / &5 / (d + &1) =
12656                             (e * &2 / &5 * d) / (d + &1)`] THEN
12657     SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
12658     MATCH_MP_TAC(REAL_ARITH
12659      `&0 < e /\ &0 < e * d ==> e * &2 / &5 * d < e / &2 * (d + &1)`) THEN
12660     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_MUL THEN
12661     ASM_SIMP_TAC[REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1];
12662     ALL_TAC] THEN
12663   ABBREV_TAC
12664    `g:real^M->real^M->bool =
12665        \x. g0(x) INTER
12666            ball(x,(e / &8 / (norm(f x:real^N) + &1)) *
12667                   inf(IMAGE (\m. b$m - a$m) (1..dimindex(:M))) /
12668                   content(interval[a:real^M,b]))` THEN
12669   SUBGOAL_THEN `gauge(g:real^M->real^M->bool)` ASSUME_TAC THENL
12670    [EXPAND_TAC "g" THEN MATCH_MP_TAC GAUGE_INTER THEN ASM_REWRITE_TAC[] THEN
12671     REWRITE_TAC[gauge; OPEN_BALL; CENTRE_IN_BALL] THEN
12672     X_GEN_TAC `x:real^M` THEN MATCH_MP_TAC REAL_LT_MUL THEN
12673     ASM_SIMP_TAC[REAL_LT_DIV; NORM_ARITH
12674      `&0 < &8 /\ &0 < norm(x:real^N) + &1`] THEN
12675     MATCH_MP_TAC REAL_LT_DIV THEN ASM_REWRITE_TAC[] THEN
12676     W(MP_TAC o PART_MATCH (lhand o rand) REAL_LT_INF_FINITE o snd) THEN
12677     ANTS_TAC THENL
12678      [ASM_SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; FINITE_RESTRICT] THEN
12679       SIMP_TAC[IMAGE_EQ_EMPTY; NUMSEG_EMPTY;
12680                GSYM NOT_LE; DIMINDEX_GE_1] THEN
12681       FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CART_EQ]) THEN
12682       REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY; IN_NUMSEG] THEN
12683       MESON_TAC[];
12684       DISCH_THEN SUBST1_TAC THEN
12685       REWRITE_TAC[FORALL_IN_IMAGE] THEN
12686       ASM_SIMP_TAC[REAL_SUB_LT; IN_NUMSEG; GSYM REAL_ABS_NZ; REAL_SUB_0;
12687                    IN_ELIM_THM]];
12688     ALL_TAC] THEN
12689   EXISTS_TAC `g:real^M->real^M->bool` THEN ASM_REWRITE_TAC[] THEN
12690   MAP_EVERY X_GEN_TAC
12691    [`c:real^M`; `i:num`; `p:(real^M#(real^M->bool))->bool`;
12692     `h:real^M->real^N`] THEN
12693   STRIP_TAC THEN
12694   SUBGOAL_THEN
12695    `interval[c:real^M,b] SUBSET interval[a,b]`
12696   ASSUME_TAC THENL
12697    [UNDISCH_TAC `c IN interval[a:real^M,b]` THEN
12698     SIMP_TAC[IN_INTERVAL; SUBSET_INTERVAL; REAL_LE_REFL];
12699     ALL_TAC] THEN
12700   SUBGOAL_THEN `FINITE(p:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
12701    [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
12702   MP_TAC(ASSUME `(g:real^M->real^M->bool) fine p`) THEN
12703   EXPAND_TAC "g" THEN REWRITE_TAC[FINE_INTER] THEN
12704   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "F")) THEN
12705   FIRST_X_ASSUM(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN
12706   DISCH_THEN(MP_TAC o SPEC `h:real^M->real^N`) THEN
12707   ANTS_TAC THENL
12708    [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_SUBSET]; ALL_TAC] THEN
12709   MATCH_MP_TAC(REAL_ARITH
12710    `x - y <= e / &2 ==> y < e / &2 ==> x < e`) THEN
12711   ASM_SIMP_TAC[GSYM SUM_SUB] THEN
12712   ONCE_REWRITE_TAC[LAMBDA_PAIR_THM] THEN REWRITE_TAC[] THEN
12713   MATCH_MP_TAC REAL_LE_TRANS THEN
12714   EXISTS_TAC
12715    `sum p (\(x:real^M,k:real^M->bool). norm(content k % h x:real^N))` THEN
12716   CONJ_TAC THENL
12717    [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
12718     REWRITE_TAC[NORM_ARITH `norm y - norm(x - y:real^N) <= norm x`];
12719     ALL_TAC] THEN
12720   MATCH_MP_TAC REAL_LE_TRANS THEN
12721   EXISTS_TAC
12722    `sum p (\(x:real^M,k).
12723                    e / &4 * (b$i - a$i) / content(interval[a:real^M,b]) *
12724                    content(k:real^M->bool) /
12725                    (interval_upperbound k$i - interval_lowerbound k$i))` THEN
12726   CONJ_TAC THENL
12727    [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
12728     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
12729     ASM_CASES_TAC `content(k:real^M->bool) = &0` THENL
12730      [ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO; VECTOR_MUL_LZERO; NORM_0;
12731                       REAL_MUL_RZERO; REAL_LE_REFL];
12732       ALL_TAC] THEN
12733     REWRITE_TAC[REAL_ARITH `a * b * content k / d = content k * (a * b) / d`;
12734                 NORM_MUL] THEN
12735     SUBGOAL_THEN `&0 < content(k:real^M->bool)` ASSUME_TAC THENL
12736      [ASM_MESON_TAC[CONTENT_LT_NZ; tagged_partial_division_of]; ALL_TAC] THEN
12737     ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE; REAL_LE_LMUL_EQ] THEN
12738     MATCH_MP_TAC(REAL_ARITH `x + &1 <= y ==> x <= y`) THEN
12739     SUBGOAL_THEN `?u v. k = interval[u:real^M,v]` MP_TAC THENL
12740      [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
12741     DISCH_THEN(REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) THEN
12742     MP_TAC(ISPECL [`u:real^M`; `v:real^M`] CONTENT_POS_LT_EQ) THEN
12743     ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_LT_IMP_LE] THEN
12744     DISCH_TAC THEN
12745     W(MP_TAC o PART_MATCH (lhand o rand) REAL_LE_RDIV_EQ o snd) THEN
12746     ASM_SIMP_TAC[REAL_SUB_LT] THEN DISCH_THEN SUBST1_TAC THEN
12747     GEN_REWRITE_TAC LAND_CONV [REAL_MUL_SYM] THEN
12748     SIMP_TAC[GSYM REAL_LE_RDIV_EQ; NORM_ARITH `&0 < norm(x:real^N) + &1`] THEN
12749     REMOVE_THEN "F" MP_TAC THEN REWRITE_TAC[fine] THEN
12750     DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `interval[u:real^M,v]`]) THEN
12751     ASM_REWRITE_TAC[SUBSET] THEN
12752     DISCH_THEN(fun th -> MP_TAC(SPEC `v:real^M` th) THEN
12753                          MP_TAC(SPEC `u:real^M` th)) THEN
12754     ASM_SIMP_TAC[INTERVAL_NE_EMPTY; REAL_LT_IMP_LE; ENDS_IN_INTERVAL] THEN
12755     REWRITE_TAC[IN_BALL; IMP_IMP] THEN
12756     MATCH_MP_TAC(NORM_ARITH
12757      `abs(vi - ui) <= norm(v - u:real^N) /\ &2 * a <= b
12758       ==> dist(x,u) < a /\ dist(x,v) < a ==> vi - ui <= b`) THEN
12759     ASM_SIMP_TAC[GSYM VECTOR_SUB_COMPONENT; COMPONENT_LE_NORM] THEN
12760     REWRITE_TAC[REAL_ARITH `&2 * e / &8 / x * y = e / &4 * y / x`] THEN
12761     REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC] THEN
12762     MATCH_MP_TAC REAL_LE_LMUL THEN ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN
12763     MATCH_MP_TAC REAL_LE_LMUL THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
12764     ONCE_REWRITE_TAC[REAL_ARITH `a * inv b * inv c:real = (a / c) / b`] THEN
12765     ASM_SIMP_TAC[REAL_LE_DIV2_EQ] THEN
12766     MATCH_MP_TAC(REAL_ARITH `abs x <= e ==> x <= e`) THEN
12767     REWRITE_TAC[real_div; REAL_ABS_MUL] THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
12768     REWRITE_TAC[REAL_ABS_POS] THEN CONJ_TAC THENL
12769      [MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= y ==> abs x <= y`) THEN
12770       SIMP_TAC[REAL_INF_LE_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY; FINITE_NUMSEG;
12771                NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1; REAL_LE_INF_FINITE] THEN
12772       REWRITE_TAC[FORALL_IN_IMAGE; EXISTS_IN_IMAGE; IN_NUMSEG] THEN
12773       ASM_SIMP_TAC[VECTOR_SUB_COMPONENT; REAL_LE_REFL; REAL_SUB_LE;
12774                    REAL_LT_IMP_LE] THEN
12775       ASM_MESON_TAC[REAL_LE_REFL];
12776       REWRITE_TAC[REAL_ABS_INV] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
12777       CONJ_TAC THENL [NORM_ARITH_TAC; ALL_TAC] THEN
12778       MATCH_MP_TAC(REAL_ARITH `x <= y ==> x + &1 <= abs(y + &1)`) THEN
12779       FIRST_X_ASSUM MATCH_MP_TAC THEN
12780       ASM_MESON_TAC[tagged_partial_division_of; SUBSET]];
12781     ALL_TAC] THEN
12782   FIRST_ASSUM(MP_TAC o MATCH_MP TAGGED_PARTIAL_DIVISION_OF_UNION_SELF) THEN
12783   DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
12784     SUM_OVER_TAGGED_DIVISION_LEMMA)) THEN
12785   DISCH_THEN(fun th ->
12786     W(MP_TAC o PART_MATCH (lhs o rand) th o lhand o snd)) THEN
12787   REWRITE_TAC[] THEN ANTS_TAC THENL
12788    [SIMP_TAC[real_div; REAL_MUL_LZERO; REAL_MUL_RZERO];
12789     DISCH_THEN SUBST1_TAC] THEN
12790   REWRITE_TAC[SUM_LMUL; REAL_ARITH
12791    `e / &4 * ba / c * s <= e / &2 <=> e * (ba * s) / c <= e * &2`] THEN
12792   ASM_SIMP_TAC[REAL_LE_LMUL_EQ] THEN ASM_SIMP_TAC[REAL_LE_LDIV_EQ] THEN
12793   MATCH_MP_TAC SUM_CONTENT_AREA_OVER_THIN_DIVISION THEN
12794   EXISTS_TAC `UNIONS(IMAGE SND (p:(real^M#(real^M->bool))->bool))` THEN
12795   EXISTS_TAC `(c:real^M)$i` THEN
12796   RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN ASM_SIMP_TAC[] THEN
12797   REPEAT CONJ_TAC THENL
12798    [MATCH_MP_TAC DIVISION_OF_TAGGED_DIVISION THEN
12799     ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF];
12800     REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN
12801     ASM_MESON_TAC[tagged_partial_division_of];
12802     ASM_REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM]]);;
12803
12804 let EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE = prove
12805  (`!fs f:real^M->real^N a b.
12806         fs equiintegrable_on interval[a,b] /\ f IN fs /\
12807         (!h x. h IN fs /\ x IN interval[a,b] ==> norm(h x) <= norm(f x))
12808         ==> { (\x. if x$i <= c then h x else vec 0) |
12809               i IN 1..dimindex(:M) /\ c IN (:real) /\ h IN fs }
12810             equiintegrable_on interval[a,b]`,
12811   let lemma = prove
12812    (`(!x k. (x,k) IN IMAGE (\(x,k). f x k,g x k) s ==> Q x k) <=>
12813      (!x k. (x,k) IN s ==> Q (f x k) (g x k))`,
12814     REWRITE_TAC[IN_IMAGE; PAIR_EQ; EXISTS_PAIR_THM] THEN SET_TAC[]) in
12815   REPEAT STRIP_TAC THEN
12816   ASM_CASES_TAC `content(interval[a:real^M,b]) = &0` THEN
12817   ASM_SIMP_TAC[EQUIINTEGRABLE_ON_NULL] THEN
12818   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM CONTENT_LT_NZ]) THEN
12819   DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
12820   REWRITE_TAC[CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
12821   REWRITE_TAC[equiintegrable_on] THEN
12822   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
12823   REWRITE_TAC[IN_UNIV; IMP_IMP; GSYM CONJ_ASSOC; RIGHT_IMP_FORALL_THM;
12824               IN_NUMSEG] THEN
12825   FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o REWRITE_RULE[equiintegrable_on]) THEN
12826   MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
12827    [REPEAT GEN_TAC THEN
12828     ONCE_REWRITE_TAC[SET_RULE `x$i <= c <=> x IN {x:real^N | x$i <= c}`] THEN
12829     REWRITE_TAC[INTEGRABLE_RESTRICT_INTER] THEN
12830     ONCE_REWRITE_TAC[INTER_COMM] THEN SIMP_TAC[INTERVAL_SPLIT] THEN
12831     REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
12832     EXISTS_TAC `interval[a:real^M,b]` THEN ASM_SIMP_TAC[] THEN
12833     SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA; REAL_LE_REFL] THEN
12834     REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
12835     REAL_ARITH_TAC;
12836     DISCH_TAC] THEN
12837   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
12838   MP_TAC(ISPECL [`fs:(real^M->real^N)->bool`; `f:real^M->real^N`;
12839                  `a:real^M`; `b:real^M`; `e / &12`]
12840         BOUNDED_EQUIINTEGRAL_OVER_THIN_TAGGED_PARTIAL_DIVISION) THEN
12841   ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &12`] THEN
12842   DISCH_THEN(X_CHOOSE_THEN `g0:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
12843   SUBGOAL_THEN
12844    `?d. gauge d /\
12845         !p h. p tagged_partial_division_of interval [a,b] /\
12846               d fine p /\ (h:real^M->real^N) IN fs
12847               ==> sum p (\(x,k). norm(content k % h x - integral k h)) <
12848                   e / &3`
12849    (X_CHOOSE_THEN `g1:real^M->real^M->bool` STRIP_ASSUME_TAC)
12850   THENL
12851    [FIRST_ASSUM(MP_TAC o CONJUNCT2 o REWRITE_RULE[equiintegrable_on]) THEN
12852     DISCH_THEN(MP_TAC o SPEC `e / &7 / (&(dimindex(:N)) + &1)`) THEN
12853     ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &7 /\ &0 < &n + &1`] THEN
12854     MATCH_MP_TAC MONO_EXISTS THEN
12855     X_GEN_TAC `d:real^M->real^M->bool` THEN STRIP_TAC THEN
12856     ASM_REWRITE_TAC[] THEN
12857     MAP_EVERY X_GEN_TAC
12858      [`p:(real^M#(real^M->bool))->bool`; `h:real^M->real^N`] THEN
12859     STRIP_TAC THEN
12860     MP_TAC(ISPECL [`h:real^M->real^N`; `a:real^M`; `b:real^M`;
12861            `d:real^M->real^M->bool`; `e / &7 / (&(dimindex(:N)) + &1)`]
12862         HENSTOCK_LEMMA_PART2) THEN
12863     ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &7 /\ &0 < &n + &1`] THEN
12864     DISCH_THEN(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN
12865     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
12866      `a < b ==> x <= a ==> x < b`) THEN
12867     REWRITE_TAC[REAL_ARITH `&2 * d * e / &7 / (d + &1) =
12868                             (e * &2 / &7 * d) / (d + &1)`] THEN
12869     SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
12870     MATCH_MP_TAC(REAL_ARITH
12871      `&0 < e /\ &0 < e * d ==> e * &2 / &7 * d < e / &3 * (d + &1)`) THEN
12872     ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_MUL THEN
12873     ASM_SIMP_TAC[REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1];
12874     ALL_TAC] THEN
12875   EXISTS_TAC `\x. (g0:real^M->real^M->bool) x INTER g1 x` THEN
12876   ASM_SIMP_TAC[GAUGE_INTER; FINE_INTER] THEN
12877   X_GEN_TAC `i:num` THEN
12878   ASM_CASES_TAC `1 <= i` THEN ASM_REWRITE_TAC[] THEN
12879   ASM_CASES_TAC `i <= dimindex(:M)` THEN ASM_REWRITE_TAC[] THEN
12880   MP_TAC(MESON[]
12881    `!P. ((!c. (a:real^M)$i <= c /\ c <= (b:real^M)$i ==> P c) ==> (!c. P c)) /\
12882         (!c. (a:real^M)$i <= c /\ c <= (b:real^M)$i ==> P c)
12883         ==> !c. P c`) THEN
12884   DISCH_THEN MATCH_MP_TAC THEN CONJ_TAC THENL
12885    [DISCH_THEN(LABEL_TAC "*") THEN
12886     X_GEN_TAC `c:real` THEN
12887     ASM_CASES_TAC `(a:real^M)$i <= c /\ c <= (b:real^M)$i` THENL
12888      [REMOVE_THEN "*" MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN
12889     REMOVE_THEN "*" (MP_TAC o SPEC `(b:real^M)$i`) THEN
12890     ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL] THEN
12891     MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `h:real^M->real^N` THEN
12892     MATCH_MP_TAC MONO_FORALL THEN
12893     X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN
12894     DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
12895     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DE_MORGAN_THM]) THEN
12896     REWRITE_TAC[REAL_NOT_LE] THEN STRIP_TAC THENL
12897      [DISCH_TAC THEN MATCH_MP_TAC(NORM_ARITH
12898        `x:real^N = vec 0 /\ y = vec 0 /\ &0 < e ==> norm(x - y) < e`) THEN
12899       ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
12900        [MATCH_MP_TAC VSUM_EQ_0 THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
12901         MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
12902         COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN
12903         SUBGOAL_THEN `(x:real^M) IN interval[a,b]` MP_TAC THENL
12904          [ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET]; ALL_TAC] THEN
12905         REWRITE_TAC[IN_INTERVAL] THEN
12906         DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
12907         ASM_REAL_ARITH_TAC;
12908         MATCH_MP_TAC EQ_TRANS THEN
12909         EXISTS_TAC `integral(interval[a,b]) ((\x. vec 0):real^M->real^N)` THEN
12910         CONJ_TAC THENL [ALL_TAC; REWRITE_TAC[INTEGRAL_0]] THEN
12911         MATCH_MP_TAC INTEGRAL_EQ THEN REWRITE_TAC[] THEN GEN_TAC THEN
12912         COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL] THEN
12913         DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
12914         ASM_REAL_ARITH_TAC];
12915       MATCH_MP_TAC(NORM_ARITH
12916        `x:real^N = y /\ w = z ==> norm(x - w) < e ==> norm(y - z) < e`) THEN
12917       CONJ_TAC THENL
12918        [MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
12919         MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
12920         SUBGOAL_THEN `(x:real^M) IN interval[a,b]` MP_TAC THENL
12921          [ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET]; ALL_TAC] THEN
12922         REWRITE_TAC[IN_INTERVAL] THEN
12923         DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
12924         STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
12925         COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN
12926         ASM_REAL_ARITH_TAC;
12927         MATCH_MP_TAC INTEGRAL_EQ THEN REWRITE_TAC[] THEN GEN_TAC THEN
12928         COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL] THEN
12929         DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
12930         ASM_REAL_ARITH_TAC]];
12931     ALL_TAC] THEN
12932   X_GEN_TAC `c:real` THEN DISCH_TAC THEN
12933   MAP_EVERY X_GEN_TAC [`h:real^M->real^N`;
12934                   `p:(real^M#(real^M->bool))->bool`] THEN STRIP_TAC THEN
12935   ABBREV_TAC
12936    `q:(real^M#(real^M->bool))->bool =
12937         {(x,k) | (x,k) IN p /\ ~(k INTER {x | x$i <= c} = {})}` THEN
12938   MP_TAC(ISPECL
12939    [`\x. if x$i <= c then (h:real^M->real^N) x else vec 0`;
12940     `a:real^M`; `b:real^M`; `p:(real^M#(real^M->bool))->bool`]
12941         INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN) THEN
12942   ASM_SIMP_TAC[] THEN DISCH_THEN SUBST1_TAC THEN
12943   SUBGOAL_THEN `FINITE(p:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
12944    [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
12945   SUBGOAL_THEN `q SUBSET (p:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
12946    [EXPAND_TAC "q" THEN SIMP_TAC[SUBSET; FORALL_PAIR_THM; IN_ELIM_PAIR_THM];
12947     ALL_TAC] THEN
12948   SUBGOAL_THEN `FINITE(q:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
12949    [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN
12950   ASM_SIMP_TAC[GSYM VSUM_SUB] THEN ONCE_REWRITE_TAC[LAMBDA_PAIR_THM] THEN
12951   REWRITE_TAC[] THEN
12952   SUBGOAL_THEN `q tagged_partial_division_of interval[a:real^M,b] /\
12953                 g0 fine q /\ g1 fine q`
12954   STRIP_ASSUME_TAC THENL
12955    [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_SUBSET; tagged_division_of;
12956                   FINE_SUBSET];
12957     ALL_TAC] THEN
12958   MATCH_MP_TAC(MESON[] `!q. vsum p s = vsum q s /\ norm(vsum q s) < e
12959                             ==> norm(vsum p s:real^N) < e`) THEN
12960   EXISTS_TAC `q:(real^M#(real^M->bool))->bool` THEN CONJ_TAC THENL
12961    [MATCH_MP_TAC VSUM_SUPERSET THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
12962     EXPAND_TAC "q" THEN REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
12963     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
12964     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
12965     SUBGOAL_THEN `(x:real^M) IN k` ASSUME_TAC THENL
12966      [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
12967     DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
12968     REWRITE_TAC[EXTENSION] THEN DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN
12969     REWRITE_TAC[IN_INTER; NOT_IN_EMPTY] THEN ASM_REWRITE_TAC[] THEN
12970     REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN
12971     ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN
12972     REWRITE_TAC[VECTOR_NEG_EQ_0; VECTOR_SUB_LZERO] THEN
12973     MATCH_MP_TAC EQ_TRANS THEN
12974     EXISTS_TAC `integral k ((\x. vec 0):real^M->real^N)` THEN
12975     CONJ_TAC THENL [ALL_TAC; REWRITE_TAC[INTEGRAL_0]] THEN
12976     MATCH_MP_TAC INTEGRAL_EQ THEN ASM SET_TAC[];
12977     ALL_TAC] THEN
12978   SUBGOAL_THEN
12979    `norm(vsum q (\(x,k). content k % h x - integral k (h:real^M->real^N)))
12980         < e / &3`
12981   MP_TAC THENL
12982    [MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `sum q
12983       (\(x,k). norm(content k % h x - integral k (h:real^M->real^N)))` THEN
12984     ASM_SIMP_TAC[] THEN MATCH_MP_TAC VSUM_NORM_LE THEN
12985     ASM_REWRITE_TAC[FORALL_PAIR_THM; REAL_LE_REFL];
12986     ALL_TAC] THEN
12987   MATCH_MP_TAC(NORM_ARITH
12988    `norm(x - y:real^N) <= &2 * e / &3
12989     ==> norm(x) < e / &3 ==> norm(y) < e`) THEN
12990   ASM_SIMP_TAC[GSYM VSUM_SUB] THEN ONCE_REWRITE_TAC[LAMBDA_PAIR_THM] THEN
12991   REWRITE_TAC[] THEN
12992   ABBREV_TAC
12993    `r:(real^M#(real^M->bool))->bool =
12994         {(x,k) | (x,k) IN q /\ ~(k SUBSET {x | x$i <= c})}` THEN
12995   SUBGOAL_THEN `r SUBSET (q:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
12996    [EXPAND_TAC "r" THEN SIMP_TAC[SUBSET; FORALL_PAIR_THM; IN_ELIM_PAIR_THM];
12997     ALL_TAC] THEN
12998   SUBGOAL_THEN `FINITE(r:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
12999    [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN
13000   SUBGOAL_THEN `r tagged_partial_division_of interval[a:real^M,b] /\
13001                 g0 fine r /\ g1 fine r`
13002   STRIP_ASSUME_TAC THENL
13003    [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_SUBSET; FINE_SUBSET];
13004     ALL_TAC] THEN
13005   MATCH_MP_TAC(MESON[] `!r. vsum q s = vsum r s /\ norm(vsum r s) <= e
13006                             ==> norm(vsum q s:real^N) <= e`) THEN
13007   EXISTS_TAC `r:(real^M#(real^M->bool))->bool` THEN CONJ_TAC THENL
13008    [MATCH_MP_TAC VSUM_SUPERSET THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
13009     EXPAND_TAC "r" THEN REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
13010     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
13011     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
13012     SUBGOAL_THEN `(x:real^M) IN k` ASSUME_TAC THENL
13013      [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
13014     DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
13015     REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN
13016     ASM_REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
13017     REWRITE_TAC[VECTOR_ARITH `c - i - (c - j):real^N = j - i`] THEN
13018     REWRITE_TAC[VECTOR_SUB_EQ] THEN MATCH_MP_TAC INTEGRAL_EQ THEN
13019     ASM SET_TAC[];
13020     ALL_TAC] THEN
13021   W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
13022   ASM_REWRITE_TAC[] THEN
13023   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
13024   ONCE_REWRITE_TAC[LAMBDA_PAIR_THM] THEN REWRITE_TAC[] THEN
13025   MAP_EVERY ABBREV_TAC
13026    [`s:(real^M#(real^M->bool))->bool =
13027         {(x,k) | (x,k) IN r /\ x IN {x | x$i <= c}}`;
13028     `t:(real^M#(real^M->bool))->bool =
13029         {(x,k) | (x,k) IN r /\ ~(x IN {x | x$i <= c})}`] THEN
13030   SUBGOAL_THEN
13031    `(s:(real^M#(real^M->bool))->bool) SUBSET r /\
13032     (t:(real^M#(real^M->bool))->bool) SUBSET r`
13033   STRIP_ASSUME_TAC THENL
13034    [MAP_EVERY EXPAND_TAC ["s"; "t"] THEN
13035     SIMP_TAC[SUBSET; FORALL_PAIR_THM; IN_ELIM_PAIR_THM];
13036     ALL_TAC] THEN
13037   SUBGOAL_THEN
13038    `FINITE(s:(real^M#(real^M->bool))->bool) /\
13039     FINITE(t:(real^M#(real^M->bool))->bool)`
13040   STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN
13041   SUBGOAL_THEN `DISJOINT (s:(real^M#(real^M->bool))->bool) t` ASSUME_TAC THENL
13042    [MAP_EVERY EXPAND_TAC ["s"; "t"] THEN
13043     REWRITE_TAC[EXTENSION; DISJOINT; IN_INTER; FORALL_PAIR_THM;
13044                 IN_ELIM_PAIR_THM] THEN SET_TAC[];
13045     ALL_TAC] THEN
13046   SUBGOAL_THEN `r:(real^M#(real^M->bool))->bool = s UNION t` SUBST1_TAC THENL
13047    [MAP_EVERY EXPAND_TAC ["s"; "t"] THEN
13048     REWRITE_TAC[EXTENSION; IN_UNION; FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN
13049     SET_TAC[];
13050     ALL_TAC] THEN
13051   ASM_SIMP_TAC[SUM_UNION] THEN MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
13052    `sum s (\(x:real^M,k). norm
13053           (integral k (h:real^M->real^N) -
13054            integral k (\x. if x$i <= c then h x else vec 0))) +
13055     sum t (\(x:real^M,k). norm
13056           ((content k % (h:real^M->real^N) x - integral k h) +
13057            integral k (\x. if x$i <= c then h x else vec 0)))` THEN
13058   CONJ_TAC THENL
13059    [MATCH_MP_TAC REAL_EQ_IMP_LE THEN BINOP_TAC THEN
13060     MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
13061     MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
13062     MAP_EVERY EXPAND_TAC ["s"; "t"] THEN
13063     REWRITE_TAC[IN_ELIM_PAIR_THM] THEN REWRITE_TAC[IN_ELIM_THM] THEN
13064     STRIP_TAC THEN ASM_REWRITE_TAC[] THENL
13065      [MATCH_MP_TAC(NORM_ARITH `a:real^N = --b ==> norm a = norm b`) THEN
13066       VECTOR_ARITH_TAC;
13067       AP_TERM_TAC THEN VECTOR_ARITH_TAC];
13068     ALL_TAC] THEN
13069   SUBGOAL_THEN `s tagged_partial_division_of interval[a:real^M,b] /\
13070                 t tagged_partial_division_of interval[a:real^M,b] /\
13071                 g0 fine s /\ g1 fine s /\ g0 fine t /\ g1 fine t`
13072   STRIP_ASSUME_TAC THENL
13073    [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_SUBSET; FINE_SUBSET];
13074     ALL_TAC] THEN
13075   MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
13076    `(sum s (\(x:real^M,k). norm(integral k (h:real^M->real^N))) +
13077      sum (IMAGE (\(x,k). (x,k INTER {x | x$i <= c})) s)
13078          (\(x:real^M,k). norm(integral k (h:real^M->real^N)))) +
13079     (sum t (\(x:real^M,k). norm(content k % h x - integral k h)) +
13080      sum t (\(x:real^M,k). norm(integral k (h:real^M->real^N))) +
13081      sum (IMAGE (\(x,k). (x,k INTER {x | x$i >= c})) t)
13082          (\(x:real^M,k). norm(integral k (h:real^M->real^N))))` THEN
13083   CONJ_TAC THENL
13084    [MATCH_MP_TAC REAL_LE_ADD2 THEN CONJ_TAC THENL
13085      [W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE_NONZERO o
13086         rand o rand o snd) THEN
13087       ANTS_TAC THENL
13088        [ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
13089         MAP_EVERY X_GEN_TAC
13090          [`x:real^M`; `k:real^M->bool`; `y:real^M`; `l:real^M->bool`] THEN
13091         ASM_CASES_TAC `x:real^M = y` THEN ASM_REWRITE_TAC[PAIR_EQ] THEN
13092         REPEAT STRIP_TAC THEN MP_TAC(ISPECL
13093          [`s:real^M#(real^M->bool)->bool`;
13094           `UNIONS(IMAGE SND (s:real^M#(real^M->bool)->bool))`;
13095           `x:real^M`; `k:real^M->bool`;
13096           `y:real^M`; `l:real^M->bool`; `i:num`; `c:real`]
13097          TAGGED_DIVISION_SPLIT_LEFT_INJ) THEN
13098         ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
13099          [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF]; ALL_TAC] THEN
13100         REWRITE_TAC[NORM_EQ_0] THEN
13101         SUBGOAL_THEN `?u v:real^M. l = interval[u,v]`
13102          (REPEAT_TCL CHOOSE_THEN SUBST1_TAC)
13103         THENL [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
13104         ASM_SIMP_TAC[INTERVAL_SPLIT; INTEGRAL_NULL];
13105         DISCH_THEN SUBST1_TAC THEN
13106         ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN
13107         ASM_REWRITE_TAC[o_THM; FORALL_PAIR_THM] THEN
13108         ONCE_REWRITE_TAC[SET_RULE
13109          `x$i <= c <=> x IN {x:real^M | x$i <= c}`] THEN
13110         REWRITE_TAC[INTEGRAL_RESTRICT_INTER] THEN
13111         REWRITE_TAC[IN_ELIM_THM; INTER_COMM] THEN
13112         REWRITE_TAC[NORM_ARITH `norm(a - b:real^N) <= norm a + norm b`]];
13113       W(MP_TAC o PART_MATCH (lhand o rand) SUM_IMAGE_NONZERO o
13114         rand o rand o rand o snd) THEN
13115       ANTS_TAC THENL
13116        [ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
13117         MAP_EVERY X_GEN_TAC
13118          [`x:real^M`; `k:real^M->bool`; `y:real^M`; `l:real^M->bool`] THEN
13119         ASM_CASES_TAC `x:real^M = y` THEN ASM_REWRITE_TAC[PAIR_EQ] THEN
13120         REPEAT STRIP_TAC THEN MP_TAC(ISPECL
13121          [`t:real^M#(real^M->bool)->bool`;
13122           `UNIONS(IMAGE SND (t:real^M#(real^M->bool)->bool))`;
13123           `x:real^M`; `k:real^M->bool`;
13124           `y:real^M`; `l:real^M->bool`; `i:num`; `c:real`]
13125          TAGGED_DIVISION_SPLIT_RIGHT_INJ) THEN
13126         ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
13127          [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF]; ALL_TAC] THEN
13128         REWRITE_TAC[NORM_EQ_0] THEN
13129         SUBGOAL_THEN `?u v:real^M. l = interval[u,v]`
13130          (REPEAT_TCL CHOOSE_THEN SUBST1_TAC)
13131         THENL [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
13132         ASM_SIMP_TAC[INTERVAL_SPLIT; INTEGRAL_NULL];
13133         DISCH_THEN SUBST1_TAC THEN
13134         ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN
13135         ASM_REWRITE_TAC[o_THM; FORALL_PAIR_THM] THEN
13136         MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
13137         MATCH_MP_TAC(NORM_ARITH
13138          `i = i1 + i2
13139           ==> norm(c + i1:real^N) <= norm(c) + norm(i) + norm(i2)`) THEN
13140         ONCE_REWRITE_TAC[SET_RULE
13141          `x$i <= c <=> x IN {x:real^M | x$i <= c}`] THEN
13142         REWRITE_TAC[INTEGRAL_RESTRICT_INTER] THEN
13143         ONCE_REWRITE_TAC[SET_RULE `{x | P x} INTER s = s INTER {x | P x}`] THEN
13144         SUBGOAL_THEN `?u v:real^M. k = interval[u,v]`
13145          (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
13146         THENL [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
13147         ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MATCH_MP_TAC INTEGRAL_SPLIT THEN
13148         ASM_REWRITE_TAC[] THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
13149         EXISTS_TAC `interval[a:real^M,b]` THEN
13150         ASM_SIMP_TAC[] THEN ASM_MESON_TAC[tagged_partial_division_of]]];
13151     ALL_TAC] THEN
13152   SUBGOAL_THEN
13153    `!x:real^M k. (x,k) IN r ==> ~(k INTER {x:real^M | x$i = c} = {})`
13154   ASSUME_TAC THENL
13155    [REPEAT GEN_TAC THEN MAP_EVERY EXPAND_TAC ["r"; "q"] THEN
13156     REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
13157     REWRITE_TAC[GSYM CONJ_ASSOC; SUBSET; EXTENSION; NOT_FORALL_THM] THEN
13158     REWRITE_TAC[IN_ELIM_THM; NOT_IN_EMPTY; IN_INTER; NOT_IMP] THEN
13159     DISCH_TAC THEN MATCH_MP_TAC CONNECTED_IVT_COMPONENT THEN
13160     REWRITE_TAC[RIGHT_EXISTS_AND_THM] THEN
13161     CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LE_TOTAL]] THEN
13162     SUBGOAL_THEN `?u v:real^M. k = interval[u,v]`
13163      (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
13164     THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
13165     MATCH_MP_TAC CONVEX_CONNECTED THEN REWRITE_TAC[CONVEX_INTERVAL];
13166     ALL_TAC] THEN
13167   MATCH_MP_TAC(REAL_ARITH
13168    `x <= e / &6 /\ y <= e / &2 ==> x + y <= &2 * e / &3`) THEN
13169   CONJ_TAC THENL
13170    [MATCH_MP_TAC(REAL_ARITH
13171      `x < e / &12 /\ y < e / &12 ==> x + y <= e / &6`) THEN
13172     CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
13173     EXISTS_TAC `(lambda j. if j = i then c else (a:real^M)$j):real^M` THEN
13174     EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[LAMBDA_BETA; IN_INTERVAL] THENL
13175      [CONJ_TAC THENL
13176        [X_GEN_TAC `j:num` THEN COND_CASES_TAC THEN
13177         ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL];
13178         EXPAND_TAC "s" THEN REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
13179         ASM_MESON_TAC[]];
13180       REPEAT CONJ_TAC THENL
13181        [X_GEN_TAC `j:num` THEN COND_CASES_TAC THEN
13182         ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL];
13183         UNDISCH_TAC `s tagged_partial_division_of interval[a:real^M,b]`;
13184         UNDISCH_TAC `(g0:real^M->real^M->bool) fine s` THEN
13185         REWRITE_TAC[fine; FORALL_IN_IMAGE; lemma] THEN SET_TAC[];
13186         REWRITE_TAC[lemma] THEN
13187         REPEAT GEN_TAC THEN EXPAND_TAC "s" THEN REWRITE_TAC[IN_ELIM_THM] THEN
13188         DISCH_TAC THEN MATCH_MP_TAC(SET_RULE
13189         `~(k INTER t = {}) /\ t SUBSET s ==> ~((k INTER s) INTER t = {})`) THEN
13190         SIMP_TAC[SUBSET; IN_ELIM_THM; REAL_LE_REFL] THEN
13191         FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]]];
13192     MATCH_MP_TAC(REAL_ARITH
13193      `x < e / &3 /\ y < e / &12 /\ z < e / &12 ==> x + y + z <= e / &2`) THEN
13194     REPEAT CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
13195     EXISTS_TAC `(lambda j. if j = i then c else (a:real^M)$j):real^M` THEN
13196     EXISTS_TAC `i:num` THEN ASM_SIMP_TAC[LAMBDA_BETA; IN_INTERVAL] THENL
13197      [CONJ_TAC THENL
13198        [X_GEN_TAC `j:num` THEN COND_CASES_TAC THEN
13199         ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL];
13200         EXPAND_TAC "t" THEN REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
13201         ASM_MESON_TAC[]];
13202       REPEAT CONJ_TAC THENL
13203        [X_GEN_TAC `j:num` THEN COND_CASES_TAC THEN
13204         ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL];
13205         UNDISCH_TAC `t tagged_partial_division_of interval[a:real^M,b]`;
13206         UNDISCH_TAC `(g0:real^M->real^M->bool) fine t` THEN
13207         REWRITE_TAC[fine; FORALL_IN_IMAGE; lemma] THEN SET_TAC[];
13208         REWRITE_TAC[lemma] THEN
13209         REPEAT GEN_TAC THEN EXPAND_TAC "t" THEN REWRITE_TAC[IN_ELIM_THM] THEN
13210         DISCH_TAC THEN MATCH_MP_TAC(SET_RULE
13211         `~(k INTER t = {}) /\ t SUBSET s ==> ~((k INTER s) INTER t = {})`) THEN
13212         SIMP_TAC[SUBSET; IN_ELIM_THM; REAL_LE_REFL; real_ge] THEN
13213         FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]]]] THEN
13214   REWRITE_TAC[tagged_partial_division_of] THEN
13215   (MATCH_MP_TAC MONO_AND THEN SIMP_TAC[FINITE_IMAGE] THEN
13216    MATCH_MP_TAC MONO_AND THEN
13217    REWRITE_TAC[RIGHT_FORALL_IMP_THM; IMP_CONJ; FORALL_IN_GSPEC] THEN
13218    REWRITE_TAC[lemma] THEN CONJ_TAC THEN
13219    MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
13220    MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `k:real^M->bool` THEN
13221    DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THENL
13222     [MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
13223       [SIMP_TAC[real_ge; IN_INTER; IN_ELIM_THM] THEN ASM SET_TAC[REAL_LE_TOTAL];
13224        MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
13225         [SET_TAC[];
13226          STRIP_TAC THEN ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MESON_TAC[]]];
13227      REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
13228      MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
13229      MATCH_MP_TAC MONO_IMP THEN SIMP_TAC[PAIR_EQ; CONTRAPOS_THM] THEN
13230      MATCH_MP_TAC(SET_RULE
13231       `s SUBSET s' /\ t SUBSET t'
13232        ==> s' INTER t' = {} ==> s INTER t = {}`) THEN CONJ_TAC THEN
13233      MATCH_MP_TAC SUBSET_INTERIOR THEN REWRITE_TAC[INTER_SUBSET]]));;
13234
13235 let EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE = prove
13236  (`!fs f:real^M->real^N a b.
13237         fs equiintegrable_on interval[a,b] /\ f IN fs /\
13238         (!h x. h IN fs /\ x IN interval[a,b] ==> norm(h x) <= norm(f x))
13239         ==> { (\x. if x$i >= c then h x else vec 0) |
13240               i IN 1..dimindex(:M) /\ c IN (:real) /\ h IN fs }
13241             equiintegrable_on interval[a,b]`,
13242   REPEAT STRIP_TAC THEN
13243   MP_TAC(ISPECL
13244    [`{\x. (f:real^M->real^N) (--x) | f IN fs}`;
13245     `\x. (f:real^M->real^N)(--x)`;
13246     `--b:real^M`; `--a:real^M`]
13247         EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE) THEN
13248   ASM_SIMP_TAC[EQUIINTEGRABLE_REFLECT] THEN ANTS_TAC THENL
13249    [ASM_SIMP_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
13250     ONCE_REWRITE_TAC[GSYM IN_INTERVAL_REFLECT] THEN
13251     ASM_SIMP_TAC[VECTOR_NEG_NEG] THEN
13252     REWRITE_TAC[SIMPLE_IMAGE; IN_IMAGE] THEN
13253     EXISTS_TAC `f:real^M->real^N` THEN ASM_REWRITE_TAC[];
13254     DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_REFLECT) THEN
13255     REWRITE_TAC[VECTOR_NEG_NEG] THEN MATCH_MP_TAC
13256      (REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
13257     REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN
13258     MAP_EVERY X_GEN_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN
13259     STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC
13260      `(\x. if (--x)$i >= c then (h:real^M->real^N)(--x) else vec 0)` THEN
13261     REWRITE_TAC[VECTOR_NEG_NEG] THEN MAP_EVERY EXISTS_TAC
13262      [`i:num`; `--c:real`; `\x. (h:real^M->real^N)(--x)`] THEN
13263     ASM_REWRITE_TAC[IN_UNIV; VECTOR_NEG_COMPONENT] THEN
13264     REWRITE_TAC[REAL_ARITH `--x >= c <=> x <= --c`] THEN
13265     EXISTS_TAC `h:real^M->real^N` THEN ASM_REWRITE_TAC[]]);;
13266
13267 let EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LT = prove
13268  (`!fs f:real^M->real^N a b.
13269         fs equiintegrable_on interval[a,b] /\ f IN fs /\
13270         (!h x. h IN fs /\ x IN interval[a,b] ==> norm(h x) <= norm(f x))
13271         ==> { (\x. if x$i < c then h x else vec 0) |
13272               i IN 1..dimindex(:M) /\ c IN (:real) /\ h IN fs }
13273             equiintegrable_on interval[a,b]`,
13274   REPEAT STRIP_TAC THEN
13275   MP_TAC(ISPECL [`fs:(real^M->real^N)->bool`; `f:real^M->real^N`;
13276                  `a:real^M`; `b:real^M`]
13277     EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE) THEN
13278   ASM_REWRITE_TAC[] THEN UNDISCH_TAC
13279    `(fs:(real^M->real^N)->bool) equiintegrable_on interval[a,b]` THEN
13280   REWRITE_TAC[IMP_IMP] THEN
13281   DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_SUB) THEN
13282   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
13283   REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN
13284   MAP_EVERY X_GEN_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN
13285   STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
13286   EXISTS_TAC `h:real^M->real^N` THEN
13287   EXISTS_TAC `\x. if x$i >= c then (h:real^M->real^N) x else vec 0` THEN
13288   ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
13289    [MAP_EVERY EXISTS_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN
13290     ASM_REWRITE_TAC[];
13291     REWRITE_TAC[FUN_EQ_THM; real_ge; GSYM REAL_NOT_LT] THEN
13292     GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
13293     VECTOR_ARITH_TAC]);;
13294
13295 let EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GT = prove
13296  (`!fs f:real^M->real^N a b.
13297         fs equiintegrable_on interval[a,b] /\ f IN fs /\
13298         (!h x. h IN fs /\ x IN interval[a,b] ==> norm(h x) <= norm(f x))
13299         ==> { (\x. if x$i > c then h x else vec 0) |
13300               i IN 1..dimindex(:M) /\ c IN (:real) /\ h IN fs }
13301             equiintegrable_on interval[a,b]`,
13302   REPEAT STRIP_TAC THEN
13303   MP_TAC(ISPECL [`fs:(real^M->real^N)->bool`; `f:real^M->real^N`;
13304                  `a:real^M`; `b:real^M`]
13305     EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE) THEN
13306   ASM_REWRITE_TAC[] THEN UNDISCH_TAC
13307    `(fs:(real^M->real^N)->bool) equiintegrable_on interval[a,b]` THEN
13308   REWRITE_TAC[IMP_IMP] THEN
13309   DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_SUB) THEN
13310   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
13311   REWRITE_TAC[SUBSET; FORALL_IN_GSPEC] THEN
13312   MAP_EVERY X_GEN_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN
13313   STRIP_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
13314   EXISTS_TAC `h:real^M->real^N` THEN
13315   EXISTS_TAC `\x. if x$i <= c then (h:real^M->real^N) x else vec 0` THEN
13316   ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
13317    [MAP_EVERY EXISTS_TAC [`i:num`; `c:real`; `h:real^M->real^N`] THEN
13318     ASM_REWRITE_TAC[];
13319     REWRITE_TAC[FUN_EQ_THM; real_gt; GSYM REAL_NOT_LE] THEN
13320     GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
13321     VECTOR_ARITH_TAC]);;
13322
13323 let EQUIINTEGRABLE_OPEN_INTERVAL_RESTRICTIONS = prove
13324  (`!f:real^M->real^N a b.
13325         f integrable_on interval[a,b]
13326         ==> { (\x. if x IN interval(c,d) then f x else vec 0) |
13327               c IN (:real^M) /\ d IN (:real^M) }
13328             equiintegrable_on interval[a,b]`,
13329   REPEAT STRIP_TAC THEN
13330   SUBGOAL_THEN
13331    `!n. n <= dimindex(:M)
13332         ==> f INSERT
13333             { (\x. if !i. 1 <= i /\ i <= n ==> c$i < x$i /\ x$i < d$i
13334                    then (f:real^M->real^N) x else vec 0) |
13335               c IN (:real^M) /\ d IN (:real^M) }
13336             equiintegrable_on interval[a,b]`
13337   MP_TAC THENL
13338    [MATCH_MP_TAC num_INDUCTION THEN
13339     REWRITE_TAC[ARITH_RULE `~(1 <= i /\ i <= 0)`] THEN
13340     ASM_REWRITE_TAC[ETA_AX; EQUIINTEGRABLE_ON_SING; SET_RULE
13341      `f INSERT {f |c,d| c IN UNIV /\ d IN UNIV} = {f}`] THEN
13342     X_GEN_TAC `n:num` THEN ASM_CASES_TAC `SUC n <= dimindex(:M)` THEN
13343     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
13344     DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o
13345         MATCH_MP (REWRITE_RULE[IMP_CONJ]
13346           EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LT)) THEN
13347     REWRITE_TAC[IN_INSERT] THEN ANTS_TAC THENL
13348      [REWRITE_TAC[TAUT
13349        `a \/ b ==> c ==> d <=> (a ==> c ==> d) /\ (b ==> c ==> d)`] THEN
13350       SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN
13351       REWRITE_TAC[FORALL_IN_GSPEC] THEN
13352       REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
13353       ASM_SIMP_TAC[NORM_0; REAL_LE_REFL; NORM_POS_LE];
13354       ALL_TAC] THEN
13355     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN
13356     REWRITE_TAC[IMP_IMP] THEN
13357     DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION) THEN
13358     DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o
13359         MATCH_MP (REWRITE_RULE[IMP_CONJ]
13360           EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GT)) THEN
13361     ASM_REWRITE_TAC[IN_UNION; IN_SING] THEN ANTS_TAC THENL
13362      [REWRITE_TAC[TAUT
13363        `a \/ b ==> c ==> d <=> (a ==> c ==> d) /\ (b ==> c ==> d)`] THEN
13364       SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN
13365       REWRITE_TAC[FORALL_IN_GSPEC; LEFT_OR_DISTRIB] THEN
13366       REWRITE_TAC[TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
13367       SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM]  THEN
13368       REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC;
13369                   FORALL_AND_THM] THEN
13370       SIMP_TAC[IN_UNIV] THEN
13371       REPEAT STRIP_TAC THEN
13372       REPEAT(COND_CASES_TAC THEN
13373              ASM_SIMP_TAC[NORM_0; REAL_LE_REFL; NORM_POS_LE]);
13374       ALL_TAC] THEN
13375     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN
13376     REWRITE_TAC[IMP_IMP] THEN
13377     DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION) THEN
13378     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
13379     MATCH_MP_TAC(SET_RULE
13380       `s SUBSET t ==> (x INSERT s) SUBSET ({x} UNION t)`) THEN
13381     REWRITE_TAC[SUBSET; real_gt; FORALL_IN_GSPEC; IN_UNIV] THEN
13382     MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN
13383     REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `SUC n` THEN
13384     ASM_REWRITE_TAC[IN_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN
13385     EXISTS_TAC `(c:real^M)$(SUC n)` THEN
13386     MATCH_MP_TAC(MESON[]
13387      `(?i c k. P i c k /\ Q (g i c k))
13388       ==> ?h. (h = f \/ ?i c k. P i c k /\ h = g i c k) /\ Q h`) THEN
13389     EXISTS_TAC `SUC n` THEN
13390     ASM_REWRITE_TAC[IN_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN
13391     EXISTS_TAC `(d:real^M)$(SUC n)` THEN
13392     EXISTS_TAC
13393      `\x. if !i. 1 <= i /\ i <= n ==> (c:real^M)$i < x$i /\ x$i < (d:real^M)$i
13394           then (f:real^M->real^N) x else vec 0` THEN
13395     REWRITE_TAC[] THEN CONJ_TAC THENL
13396      [DISJ2_TAC THEN
13397       MAP_EVERY EXISTS_TAC [`c:real^M`; `d:real^M`] THEN REWRITE_TAC[];
13398       REWRITE_TAC[FUN_EQ_THM; LE] THEN
13399       ASM_MESON_TAC[ARITH_RULE `1 <= SUC n`]];
13400     DISCH_THEN(MP_TAC o SPEC `dimindex(:M)`) THEN
13401     REWRITE_TAC[IN_INTERVAL; LE_REFL] THEN
13402     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
13403     SET_TAC[]]);;
13404
13405 let EQUIINTEGRABLE_CLOSED_INTERVAL_RESTRICTIONS = prove
13406  (`!f:real^M->real^N a b.
13407         f integrable_on interval[a,b]
13408         ==> { (\x. if x IN interval[c,d] then f x else vec 0) |
13409               c IN (:real^M) /\ d IN (:real^M) }
13410             equiintegrable_on interval[a,b]`,
13411   REPEAT STRIP_TAC THEN
13412   SUBGOAL_THEN
13413    `!n. n <= dimindex(:M)
13414         ==> f INSERT
13415             { (\x. if !i. 1 <= i /\ i <= n ==> c$i <= x$i /\ x$i <= d$i
13416                    then (f:real^M->real^N) x else vec 0) |
13417               c IN (:real^M) /\ d IN (:real^M) }
13418             equiintegrable_on interval[a,b]`
13419   MP_TAC THENL
13420    [MATCH_MP_TAC num_INDUCTION THEN
13421     REWRITE_TAC[ARITH_RULE `~(1 <= i /\ i <= 0)`] THEN
13422     ASM_REWRITE_TAC[ETA_AX; EQUIINTEGRABLE_ON_SING; SET_RULE
13423      `f INSERT {f |c,d| c IN UNIV /\ d IN UNIV} = {f}`] THEN
13424     X_GEN_TAC `n:num` THEN ASM_CASES_TAC `SUC n <= dimindex(:M)` THEN
13425     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
13426     DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o
13427         MATCH_MP (REWRITE_RULE[IMP_CONJ]
13428           EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE)) THEN
13429     REWRITE_TAC[IN_INSERT] THEN ANTS_TAC THENL
13430      [REWRITE_TAC[TAUT
13431        `a \/ b ==> c ==> d <=> (a ==> c ==> d) /\ (b ==> c ==> d)`] THEN
13432       SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN
13433       REWRITE_TAC[FORALL_IN_GSPEC] THEN
13434       REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
13435       ASM_SIMP_TAC[NORM_0; REAL_LE_REFL; NORM_POS_LE];
13436       ALL_TAC] THEN
13437     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN
13438     REWRITE_TAC[IMP_IMP] THEN
13439     DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION) THEN
13440     DISCH_THEN(MP_TAC o SPEC `f:real^M->real^N` o
13441         MATCH_MP (REWRITE_RULE[IMP_CONJ]
13442           EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE)) THEN
13443     ASM_REWRITE_TAC[IN_UNION; IN_SING] THEN ANTS_TAC THENL
13444      [REWRITE_TAC[TAUT
13445        `a \/ b ==> c ==> d <=> (a ==> c ==> d) /\ (b ==> c ==> d)`] THEN
13446       SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM] THEN
13447       REWRITE_TAC[FORALL_IN_GSPEC; LEFT_OR_DISTRIB] THEN
13448       REWRITE_TAC[TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
13449       SIMP_TAC[REAL_LE_REFL; RIGHT_FORALL_IMP_THM]  THEN
13450       REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC;
13451                   FORALL_AND_THM] THEN
13452       SIMP_TAC[IN_UNIV] THEN
13453       REPEAT STRIP_TAC THEN
13454       REPEAT(COND_CASES_TAC THEN
13455              ASM_SIMP_TAC[NORM_0; REAL_LE_REFL; NORM_POS_LE]);
13456       ALL_TAC] THEN
13457     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN
13458     REWRITE_TAC[IMP_IMP] THEN
13459     DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION) THEN
13460     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
13461     MATCH_MP_TAC(SET_RULE
13462       `s SUBSET t ==> (x INSERT s) SUBSET ({x} UNION t)`) THEN
13463     REWRITE_TAC[SUBSET; real_ge; FORALL_IN_GSPEC; IN_UNIV] THEN
13464     MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN
13465     REWRITE_TAC[IN_ELIM_THM] THEN EXISTS_TAC `SUC n` THEN
13466     ASM_REWRITE_TAC[IN_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN
13467     EXISTS_TAC `(c:real^M)$(SUC n)` THEN
13468     MATCH_MP_TAC(MESON[]
13469      `(?i c k. P i c k /\ Q (g i c k))
13470       ==> ?h. (h = f \/ ?i c k. P i c k /\ h = g i c k) /\ Q h`) THEN
13471     EXISTS_TAC `SUC n` THEN
13472     ASM_REWRITE_TAC[IN_NUMSEG; ARITH_RULE `1 <= SUC n`] THEN
13473     EXISTS_TAC `(d:real^M)$(SUC n)` THEN
13474     EXISTS_TAC
13475      `\x. if !i. 1 <= i /\ i <= n ==> (c:real^M)$i <= x$i /\ x$i <= (d:real^M)$i
13476           then (f:real^M->real^N) x else vec 0` THEN
13477     REWRITE_TAC[] THEN CONJ_TAC THENL
13478      [DISJ2_TAC THEN
13479       MAP_EVERY EXISTS_TAC [`c:real^M`; `d:real^M`] THEN REWRITE_TAC[];
13480       REWRITE_TAC[FUN_EQ_THM; LE] THEN
13481       ASM_MESON_TAC[ARITH_RULE `1 <= SUC n`]];
13482     DISCH_THEN(MP_TAC o SPEC `dimindex(:M)`) THEN
13483     REWRITE_TAC[IN_INTERVAL; LE_REFL] THEN
13484     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
13485     SET_TAC[]]);;
13486
13487 (* ------------------------------------------------------------------------- *)
13488 (* Continuity of the indefinite integral.                                    *)
13489 (* ------------------------------------------------------------------------- *)
13490
13491 let INDEFINITE_INTEGRAL_CONTINUOUS = prove
13492  (`!f:real^M->real^N a b c d e.
13493         f integrable_on interval[a,b] /\
13494         c IN interval[a,b] /\ d IN interval[a,b] /\ &0 < e
13495         ==> ?k. &0 < k /\
13496                 !c' d'. c' IN interval[a,b] /\
13497                         d' IN interval[a,b] /\
13498                         norm(c' - c) <= k /\ norm(d' - d) <= k
13499                         ==> norm(integral(interval[c',d']) f -
13500                                  integral(interval[c,d]) f) < e`,
13501   REPEAT STRIP_TAC THEN
13502   ONCE_REWRITE_TAC[MESON[] `(?k. P k /\ Q k) <=> ~(!k. P k ==> ~Q k)`] THEN
13503   DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `inv(&n + &1)`) THEN
13504   PURE_REWRITE_TAC[NOT_FORALL_THM; NOT_IMP] THEN
13505   REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`; SKOLEM_THM] THEN
13506   REWRITE_TAC[NOT_EXISTS_THM; REAL_NOT_LT; GSYM CONJ_ASSOC] THEN
13507   MAP_EVERY X_GEN_TAC [`u:num->real^M`; `v:num->real^M`] THEN
13508   REWRITE_TAC[FORALL_AND_THM] THEN STRIP_TAC THEN
13509   ABBREV_TAC
13510    `k:real^M->bool =
13511     UNIONS (IMAGE (\i. {x | x$i = (c:real^M)$i} UNION {x | x$i = (d:real^M)$i})
13512                   (1..dimindex(:M)))` THEN
13513   SUBGOAL_THEN `negligible(k:real^M->bool)` ASSUME_TAC THENL
13514    [EXPAND_TAC "k" THEN MATCH_MP_TAC NEGLIGIBLE_UNIONS THEN
13515     SIMP_TAC[FINITE_IMAGE; FINITE_NUMSEG; FORALL_IN_IMAGE] THEN
13516     X_GEN_TAC `i:num` THEN REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN
13517     ASM_SIMP_TAC[NEGLIGIBLE_UNION; NEGLIGIBLE_STANDARD_HYPERPLANE];
13518     ALL_TAC] THEN
13519   MP_TAC(ISPECL
13520    [`\n:num x. if x IN interval[u n,v n] then
13521                  if x IN k then vec 0 else (f:real^M->real^N) x
13522                else vec 0`;
13523     `\x. if x IN interval[c,d] then
13524             if x IN k then vec 0 else (f:real^M->real^N) x
13525          else vec 0`;
13526     `a:real^M`; `b:real^M`] EQUIINTEGRABLE_LIMIT) THEN
13527   REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL
13528    [SUBGOAL_THEN
13529      `(\x. if x IN k then vec 0 else (f:real^M->real^N) x)
13530       integrable_on interval[a,b]`
13531     MP_TAC THENL
13532      [UNDISCH_TAC `(f:real^M->real^N) integrable_on interval[a,b]` THEN
13533       MATCH_MP_TAC INTEGRABLE_SPIKE THEN EXISTS_TAC `k:real^M->bool` THEN
13534       ASM_REWRITE_TAC[] THEN SET_TAC[];
13535       ALL_TAC] THEN
13536     DISCH_THEN(MP_TAC o MATCH_MP
13537       EQUIINTEGRABLE_CLOSED_INTERVAL_RESTRICTIONS) THEN
13538     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
13539     REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_UNIV] THEN
13540     REWRITE_TAC[IN_ELIM_THM] THEN
13541     X_GEN_TAC `n:num` THEN MAP_EVERY EXISTS_TAC
13542      [`(u:num->real^M) n`; `(v:num->real^M) n`] THEN
13543     REWRITE_TAC[];
13544     X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
13545     ASM_CASES_TAC `(x:real^M) IN k` THEN
13546     ASM_REWRITE_TAC[COND_ID; LIM_CONST] THEN MATCH_MP_TAC LIM_EVENTUALLY THEN
13547     REWRITE_TAC[EVENTUALLY_SEQUENTIALLY] THEN
13548     MP_TAC(SPEC `inf (IMAGE (\i. min (abs((x:real^M)$i - (c:real^M)$i))
13549                                      (abs((x:real^M)$i - (d:real^M)$i)))
13550                             (1..dimindex(:M)))` REAL_ARCH_INV) THEN
13551     SIMP_TAC[REAL_LT_INF_FINITE; FINITE_IMAGE; IMAGE_EQ_EMPTY;
13552              FINITE_NUMSEG; NUMSEG_EMPTY; NOT_LT; DIMINDEX_GE_1] THEN
13553     ASM_SIMP_TAC[FORALL_IN_IMAGE; REAL_LT_MIN; IN_NUMSEG] THEN
13554     UNDISCH_TAC `~((x:real^M) IN k)` THEN EXPAND_TAC "k" THEN
13555     REWRITE_TAC[UNIONS_IMAGE; IN_ELIM_THM; NOT_EXISTS_THM] THEN
13556     REWRITE_TAC[IN_NUMSEG; SET_RULE
13557      `~(p /\ x IN (s UNION t)) <=> p ==> ~(x IN s) /\ ~(x IN t)`] THEN
13558     REWRITE_TAC[IN_ELIM_THM; REAL_ARITH `&0 < abs(x - y) <=> ~(x = y)`] THEN
13559     DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
13560     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
13561     X_GEN_TAC `n:num` THEN DISCH_TAC THEN
13562     SUBGOAL_THEN `x IN interval[(u:num->real^M) n,v n] <=> x IN interval[c,d]`
13563      (fun th -> REWRITE_TAC[th]) THEN
13564     REWRITE_TAC[IN_INTERVAL] THEN AP_TERM_TAC THEN
13565     GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `i:num` THEN
13566     ASM_CASES_TAC `1 <= i /\ i <= dimindex(:M)` THEN ASM_REWRITE_TAC[] THEN
13567     MATCH_MP_TAC(REAL_ARITH
13568      `!N n. abs(u - c) <= n /\ abs(v - d) <= n /\
13569             N < abs(x - c) /\ N < abs(x - d) /\ n <= N
13570       ==> (u <= x /\ x <= v <=> c <= x /\ x <= d)`) THEN
13571     MAP_EVERY EXISTS_TAC [`inv(&N)`; `inv(&n + &1)`] THEN
13572     ASM_SIMP_TAC[] THEN REPEAT (CONJ_TAC THENL
13573      [ASM_MESON_TAC[REAL_LE_TRANS; COMPONENT_LE_NORM; VECTOR_SUB_COMPONENT];
13574       ALL_TAC]) THEN
13575     MATCH_MP_TAC REAL_LE_INV2 THEN
13576     REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
13577     ASM_ARITH_TAC;
13578     DISCH_THEN(MP_TAC o CONJUNCT2) THEN
13579     REWRITE_TAC[INTEGRAL_RESTRICT_INTER] THEN
13580     SUBGOAL_THEN
13581      `interval[c:real^M,d] INTER interval[a,b] = interval[c,d] /\
13582       !n:num. interval[u n,v n] INTER interval[a,b] = interval[u n,v n]`
13583      (fun th -> SIMP_TAC[th])
13584     THENL
13585      [REWRITE_TAC[SET_RULE `s INTER t = s <=> s SUBSET t`] THEN
13586       REWRITE_TAC[SUBSET_INTERVAL] THEN
13587       RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL]) THEN ASM_MESON_TAC[];
13588       ALL_TAC] THEN
13589     REWRITE_TAC[LIM_SEQUENTIALLY] THEN
13590     DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
13591     DISCH_THEN(X_CHOOSE_THEN `N:num` (MP_TAC o SPEC `N:num`)) THEN
13592     REWRITE_TAC[LE_REFL; REAL_NOT_LT] THEN
13593     FIRST_ASSUM(fun th -> MP_TAC(SPEC `N:num` th) THEN MATCH_MP_TAC
13594     (NORM_ARITH `x = a /\ y = b ==> e <= norm(x - y) ==> e <= dist(a,b)`)) THEN
13595     CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_SPIKE THEN
13596     EXISTS_TAC `k:real^M->bool` THEN ASM_SIMP_TAC[IN_DIFF]]);;
13597
13598 let INDEFINITE_INTEGRAL_CONTINUOUS_RIGHT = prove
13599  (`!f:real^M->real^N a b.
13600         f integrable_on interval[a,b]
13601          ==> (\x. integral (interval[a,x]) f) continuous_on interval[a,b]`,
13602   REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
13603   X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[continuous_within] THEN
13604   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
13605   MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`;
13606                  `a:real^M`; `x:real^M`; `e:real`]
13607         INDEFINITE_INTEGRAL_CONTINUOUS) THEN
13608   ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN
13609   ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[dist]] THEN
13610   MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
13611   FIRST_X_ASSUM MATCH_MP_TAC THEN
13612   ASM_SIMP_TAC[ENDS_IN_INTERVAL; VECTOR_SUB_REFL; NORM_0; REAL_LT_IMP_LE] THEN
13613   ASM SET_TAC[]);;
13614
13615 let INDEFINITE_INTEGRAL_CONTINUOUS_LEFT = prove
13616  (`!f:real^M->real^N a b.
13617         f integrable_on interval[a,b]
13618         ==> (\x. integral(interval[x,b]) f) continuous_on interval[a,b]`,
13619   REPEAT STRIP_TAC THEN REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
13620   X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[continuous_within] THEN
13621   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
13622   MP_TAC(ISPECL [`f:real^M->real^N`; `a:real^M`; `b:real^M`;
13623                  `x:real^M`; `b:real^M`; `e:real`]
13624         INDEFINITE_INTEGRAL_CONTINUOUS) THEN
13625   ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN
13626   ANTS_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[dist]] THEN
13627   MATCH_MP_TAC MONO_EXISTS THEN REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
13628   FIRST_X_ASSUM MATCH_MP_TAC THEN
13629   ASM_SIMP_TAC[ENDS_IN_INTERVAL; VECTOR_SUB_REFL; NORM_0; REAL_LT_IMP_LE] THEN
13630   ASM SET_TAC[]);;
13631
13632 let INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS = prove
13633  (`!f:real^M->real^N a b.
13634         f integrable_on interval[a,b]
13635         ==> (\y. integral (interval[fstcart y,sndcart y]) f)
13636             uniformly_continuous_on interval[pastecart a a,pastecart b b]`,
13637   REPEAT STRIP_TAC THEN MATCH_MP_TAC COMPACT_UNIFORMLY_CONTINUOUS THEN
13638   REWRITE_TAC[COMPACT_INTERVAL; continuous_on] THEN
13639   REWRITE_TAC[FORALL_PASTECART; GSYM PCROSS_INTERVAL; PCROSS] THEN
13640   REWRITE_TAC[IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN
13641   MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN STRIP_TAC THEN
13642   X_GEN_TAC `e:real` THEN DISCH_TAC THEN MP_TAC(ISPECL
13643    [`f:real^M->real^N`; `a:real^M`; `b:real^M`; `c:real^M`; `d:real^M`;
13644     `e:real`] INDEFINITE_INTEGRAL_CONTINUOUS) THEN
13645   ASM_REWRITE_TAC[dist] THEN MATCH_MP_TAC MONO_EXISTS THEN
13646   X_GEN_TAC `k:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[PASTECART_SUB] THEN
13647   ASM_MESON_TAC[NORM_LE_PASTECART; REAL_LT_IMP_LE; REAL_LE_TRANS]);;
13648
13649 let INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS_EXPLICIT = prove
13650  (`!f:real^M->real^N a b e.
13651         f integrable_on interval[a,b] /\ &0 < e
13652         ==> ?k. &0 < k /\
13653                 !c d c' d'. c IN interval[a,b] /\ d IN interval[a,b] /\
13654                             c' IN interval[a,b] /\ d' IN interval[a,b] /\
13655                             norm (c' - c) <= k /\ norm (d' - d) <= k
13656                             ==> norm(integral(interval[c',d']) f -
13657                                      integral(interval[c,d]) f) < e`,
13658   REPEAT STRIP_TAC THEN MP_TAC(ISPECL
13659    [`f:real^M->real^N`; `a:real^M`; `b:real^M`]
13660     INDEFINITE_INTEGRAL_UNIFORMLY_CONTINUOUS) THEN
13661   ASM_REWRITE_TAC[uniformly_continuous_on] THEN
13662   DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
13663   DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
13664   EXISTS_TAC `k / &3` THEN CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
13665   MAP_EVERY X_GEN_TAC [`c:real^M`; `c':real^M`; `d:real^M`; `d':real^M`] THEN
13666   STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL
13667    [`pastecart (c:real^M) (c':real^M)`;
13668     `pastecart (d:real^M) (d':real^M)`]) THEN
13669   REWRITE_TAC[GSYM PCROSS_INTERVAL; PCROSS] THEN
13670   REWRITE_TAC[IN_ELIM_PASTECART_THM; FSTCART_PASTECART; SNDCART_PASTECART] THEN
13671   ASM_REWRITE_TAC[dist; PASTECART_SUB] THEN DISCH_THEN MATCH_MP_TAC THEN
13672   ASM_MESON_TAC[NORM_PASTECART_LE; REAL_LET_TRANS;
13673     REAL_ARITH `&0 < k /\ x <= k / &3 /\ y <= k / &3 ==> x + y < k`]);;
13674
13675 (* ------------------------------------------------------------------------- *)
13676 (* Second mean value theorem and corollaries.                                *)
13677 (* ------------------------------------------------------------------------- *)
13678
13679 let SECOND_MEAN_VALUE_THEOREM_FULL = prove
13680  (`!f:real^1->real^1 g a b.
13681         ~(interval[a,b] = {}) /\
13682         f integrable_on interval [a,b] /\
13683         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
13684                ==> g x <= g y)
13685         ==> ?c. c IN interval [a,b] /\
13686                 ((\x. g x % f x) has_integral
13687                  (g(a) % integral (interval[a,c]) f +
13688                   g(b) % integral (interval[c,b]) f)) (interval[a,b])`,
13689   let lemma1 = prove
13690    (`!f:real->real s.
13691       (!x. x IN s ==> &0 <= f x /\ f x <= &1)
13692       ==> (!n x. x IN s /\ ~(n = 0)
13693                  ==> abs(f x -
13694                          sum(1..n) (\k. if &k / &n <= f(x)
13695                                         then inv(&n) else &0)) < inv(&n))`,
13696     REPEAT STRIP_TAC THEN
13697     SUBGOAL_THEN `?m. floor(&n * (f:real->real) x) = &m` CHOOSE_TAC THENL
13698      [MATCH_MP_TAC FLOOR_POS THEN ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS];
13699       ALL_TAC] THEN
13700     SUBGOAL_THEN `!k. &k / &n <= (f:real->real) x <=> k <= m` ASSUME_TAC THENL
13701      [REWRITE_TAC[GSYM REAL_OF_NUM_LE] THEN
13702       FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
13703       ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN
13704       SIMP_TAC[REAL_LE_FLOOR; INTEGER_CLOSED; REAL_MUL_SYM];
13705       ALL_TAC] THEN
13706     ASM_REWRITE_TAC[GSYM SUM_RESTRICT_SET] THEN
13707     FIRST_X_ASSUM(MP_TAC o SPEC `n + 1`) THEN
13708     REWRITE_TAC[GSYM REAL_OF_NUM_ADD; real_div; REAL_ADD_RDISTRIB] THEN
13709     ASM_SIMP_TAC[REAL_MUL_RINV; REAL_MUL_LID; REAL_OF_NUM_EQ] THEN
13710     ASM_SIMP_TAC[REAL_ARITH `y <= &1 /\ &0 < i ==> ~(&1 + i <= y)`;
13711                  REAL_LT_INV_EQ; REAL_OF_NUM_LT; LE_1; NOT_LE] THEN
13712     SIMP_TAC[IN_NUMSEG; ARITH_RULE
13713      `m < n + 1 ==> ((1 <= k /\ k <= n) /\ k <= m <=> 1 <= k /\ k <= m)`] THEN
13714     DISCH_TAC THEN REWRITE_TAC[GSYM numseg; SUM_CONST_NUMSEG; ADD_SUB] THEN
13715     MATCH_MP_TAC REAL_LT_LCANCEL_IMP THEN EXISTS_TAC `abs(&n)` THEN
13716     REWRITE_TAC[GSYM REAL_ABS_MUL] THEN
13717     ASM_SIMP_TAC[REAL_ABS_NUM; REAL_MUL_RINV; REAL_OF_NUM_EQ] THEN
13718     ASM_SIMP_TAC[REAL_OF_NUM_LT; LE_1; REAL_SUB_LDISTRIB; GSYM real_div] THEN
13719     ASM_SIMP_TAC[REAL_DIV_LMUL; REAL_OF_NUM_EQ] THEN
13720     MATCH_MP_TAC(REAL_ARITH `f <= x /\ x < f + &1 ==> abs(x - f) < &1`) THEN
13721     FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[FLOOR]) in
13722   let lemma2 = prove
13723    (`!f:real^1->real^N g a b.
13724           f integrable_on interval[a,b] /\
13725           (!x y. drop x <= drop y ==> g(x) <= g(y))
13726           ==> {(\x. if c <= g(x) then f x else vec 0) | c IN (:real)}
13727               equiintegrable_on interval[a,b]`,
13728     REPEAT STRIP_TAC THEN
13729     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN
13730     DISCH_THEN(fun th ->
13731      MP_TAC(SPEC `f:real^1->real^N` (MATCH_MP (REWRITE_RULE[IMP_CONJ]
13732        EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE) th)) THEN
13733      MP_TAC(SPEC `f:real^1->real^N` (MATCH_MP (REWRITE_RULE[IMP_CONJ]
13734        EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GT) th)) THEN
13735       MP_TAC th) THEN
13736     SIMP_TAC[IN_SING; REAL_LE_REFL] THEN
13737     SUBGOAL_THEN `{(\x. vec 0):real^1->real^N} equiintegrable_on interval[a,b]`
13738     MP_TAC THENL
13739      [REWRITE_TAC[EQUIINTEGRABLE_ON_SING; INTEGRABLE_CONST]; ALL_TAC] THEN
13740     REPEAT(ONCE_REWRITE_TAC[IMP_IMP] THEN
13741            DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION)) THEN
13742     REWRITE_TAC[NUMSEG_SING; DIMINDEX_1; IN_SING] THEN
13743     REWRITE_TAC[SET_RULE `{m i c h | i = 1 /\ c IN (:real) /\ h = f} =
13744                           {m 1 c f | c IN (:real)}`] THEN
13745     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
13746     REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_UNIV] THEN
13747     X_GEN_TAC `y:real` THEN
13748     ASM_CASES_TAC `!x. y <= (g:real^1->real) x` THENL
13749      [ASM_REWRITE_TAC[ETA_AX; IN_UNION; IN_SING]; ALL_TAC] THEN
13750     ASM_CASES_TAC `!x. ~(y <= (g:real^1->real) x)` THENL
13751      [ASM_REWRITE_TAC[ETA_AX; IN_UNION; IN_SING]; ALL_TAC] THEN
13752     MP_TAC(ISPEC `IMAGE drop {x | y <= (g:real^1->real) x}` INF) THEN
13753     REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM; IMAGE_EQ_EMPTY] THEN
13754     ANTS_TAC THENL
13755      [ASM_REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN
13756       ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL];
13757       STRIP_TAC THEN REWRITE_TAC[real_gt; real_ge]] THEN
13758     REWRITE_TAC[IN_UNION; GSYM DISJ_ASSOC] THEN
13759     ASM_CASES_TAC `y <= g(lift(inf(IMAGE drop {x | y <= g x})))` THENL
13760      [REPEAT DISJ2_TAC; REPLICATE_TAC 2 DISJ2_TAC THEN DISJ1_TAC] THEN
13761     REWRITE_TAC[IN_ELIM_THM] THEN
13762     EXISTS_TAC `inf(IMAGE drop {x | y <= g x})` THEN
13763     REWRITE_TAC[FUN_EQ_THM] THEN
13764     MATCH_MP_TAC(MESON[]
13765      `(!x. P x <=> Q x)
13766       ==> !x. (if P x then f x else b) = (if Q x then f x else b)`) THEN
13767     X_GEN_TAC `x:real^1` THEN REWRITE_TAC[GSYM REAL_NOT_LE; GSYM drop] THEN
13768     ASM_MESON_TAC[REAL_LE_TOTAL; REAL_LT_ANTISYM; REAL_LE_TRANS; LIFT_DROP]) in
13769   let lemma3 = prove
13770    (`!f:real^1->real^N g a b.
13771           f integrable_on interval[a,b] /\
13772           (!x y. drop x <= drop y ==> g(x) <= g(y))
13773           ==> {(\x. vsum (1..n)
13774                      (\k. if &k / &n <= g x then inv(&n) % f(x) else vec 0)) |
13775                ~(n = 0)}
13776               equiintegrable_on interval[a,b]`,
13777     REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o
13778      MATCH_MP lemma2) THEN
13779     DISCH_THEN(MP_TAC o MATCH_MP
13780      (INST_TYPE [`:num`,`:A`] EQUIINTEGRABLE_SUM)) THEN
13781     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
13782     REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_UNIV] THEN X_GEN_TAC `n:num` THEN
13783     DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
13784     MAP_EVERY EXISTS_TAC [`1..n`; `\k:num. inv(&n)`;
13785      `\k x. if &k / &n <= g x then (f:real^1->real^N) x else vec 0`] THEN
13786     ASM_SIMP_TAC[SUM_CONST_NUMSEG; ADD_SUB; REAL_MUL_RINV; REAL_OF_NUM_EQ] THEN
13787     REWRITE_TAC[FINITE_NUMSEG; COND_RAND; COND_RATOR; VECTOR_MUL_RZERO] THEN
13788     X_GEN_TAC `k:num` THEN
13789     REWRITE_TAC[IN_NUMSEG; REAL_LE_INV_EQ; REAL_POS] THEN STRIP_TAC THEN
13790     EXISTS_TAC `&k / &n` THEN REWRITE_TAC[]) in
13791   let lemma4 = prove
13792    (`!f:real^1->real^1 g a b.
13793           ~(interval[a,b] = {}) /\
13794           f integrable_on interval[a,b] /\
13795           (!x y. drop x <= drop y ==> g(x) <= g(y)) /\
13796           (!x. x IN interval[a,b] ==> &0 <= g x /\ g x <= &1)
13797           ==> (\x. g(x) % f(x)) integrable_on interval[a,b] /\
13798               ?c. c IN interval[a,b] /\
13799                   integral (interval[a,b]) (\x. g(x) % f(x)) =
13800                   integral (interval[c,b]) f`,
13801     REPEAT GEN_TAC THEN STRIP_TAC THEN
13802     SUBGOAL_THEN
13803      `?m M. IMAGE (\x. integral (interval[x,b]) (f:real^1->real^1))
13804                   (interval[a,b]) = interval[m,M]`
13805     STRIP_ASSUME_TAC THENL
13806      [REWRITE_TAC[GSYM CONNECTED_COMPACT_INTERVAL_1] THEN CONJ_TAC THENL
13807        [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE;
13808         MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE] THEN
13809       ASM_SIMP_TAC[INDEFINITE_INTEGRAL_CONTINUOUS_LEFT; CONVEX_CONNECTED;
13810                    CONVEX_INTERVAL; COMPACT_INTERVAL];
13811       ALL_TAC] THEN
13812     MP_TAC(ISPECL[`f:real^1->real^1`; `g:real^1->real`; `a:real^1`; `b:real^1`]
13813           lemma3) THEN
13814     ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
13815     SUBGOAL_THEN
13816      `!n. ?c. c IN interval[a,b] /\
13817               integral (interval[c,b]) (f:real^1->real^1) =
13818               integral (interval[a,b])
13819                 (\x. vsum (1..n)
13820                     (\k. if &k / &n <= g x then inv(&n) % f x else vec 0))`
13821     MP_TAC THENL
13822      [X_GEN_TAC `n:num` THEN ASM_CASES_TAC `n = 0` THENL
13823        [ASM_REWRITE_TAC[VSUM_CLAUSES_NUMSEG; ARITH_EQ; INTEGRAL_0] THEN
13824         EXISTS_TAC `b:real^1` THEN ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN
13825         SIMP_TAC[INTEGRAL_NULL; CONTENT_EQ_0_1; REAL_LE_REFL];
13826         ALL_TAC] THEN
13827       MP_TAC(ISPECL [`f:real^1->real^1`; `g:real^1->real`;
13828                      `a:real^1`; `b:real^1`] lemma2) THEN
13829       ASM_REWRITE_TAC[equiintegrable_on; FORALL_IN_GSPEC; IN_UNIV] THEN
13830       DISCH_THEN(ASSUME_TAC o CONJUNCT1) THEN
13831       REWRITE_TAC[MESON[VECTOR_MUL_RZERO]
13832        `(if p then a % x else vec 0:real^1) =
13833         a % (if p then x else vec 0)`] THEN
13834       ASM_SIMP_TAC[VSUM_LMUL; INTEGRAL_CMUL; INTEGRABLE_VSUM; ETA_AX;
13835                    FINITE_NUMSEG; INTEGRAL_VSUM] THEN
13836       SUBGOAL_THEN
13837        `!y:real. ?d:real^1.
13838           d IN interval[a,b] /\
13839           integral (interval[a,b]) (\x. if y <= g x then f x else vec 0) =
13840           integral (interval[d,b]) (f:real^1->real^1)`
13841       MP_TAC THENL
13842        [X_GEN_TAC `y:real` THEN
13843         SUBGOAL_THEN
13844          `{x | y <= g x} = {} \/
13845           {x | y <= g x} = (:real^1) \/
13846           (?a. {x | y <= g x} = {x | a <= drop x}) \/
13847           (?a. {x | y <= g x} = {x | a < drop x})`
13848         MP_TAC THENL
13849          [MATCH_MP_TAC(TAUT `(~a /\ ~b ==> c \/ d) ==> a \/ b \/ c \/ d`) THEN
13850           DISCH_TAC THEN
13851           MP_TAC(ISPEC `IMAGE drop {x | y <= (g:real^1->real) x}` INF) THEN
13852           ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM; IMAGE_EQ_EMPTY] THEN
13853           ANTS_TAC THENL
13854            [FIRST_ASSUM(MP_TAC o CONJUNCT2) THEN
13855             REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_UNIV] THEN
13856             ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL];
13857             STRIP_TAC] THEN
13858           ASM_CASES_TAC `y <= g(lift(inf(IMAGE drop {x | y <= g x})))` THENL
13859            [DISJ1_TAC; DISJ2_TAC] THEN
13860           REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
13861           EXISTS_TAC `inf(IMAGE drop {x | y <= g x})` THEN
13862           REWRITE_TAC[FUN_EQ_THM] THEN
13863           X_GEN_TAC `x:real^1` THEN
13864           REWRITE_TAC[GSYM REAL_NOT_LE; GSYM drop] THEN
13865           ASM_MESON_TAC[REAL_LE_TOTAL; REAL_LT_ANTISYM;
13866                         REAL_LE_TRANS; LIFT_DROP];
13867           REWRITE_TAC[EXTENSION; IN_UNIV; NOT_IN_EMPTY; IN_ELIM_THM] THEN
13868           DISCH_THEN(DISJ_CASES_THEN2 ASSUME_TAC MP_TAC) THENL
13869            [EXISTS_TAC `b:real^1` THEN ASM_REWRITE_TAC[] THEN
13870             SIMP_TAC[INTEGRAL_NULL; CONTENT_EQ_0_1; REAL_LE_REFL] THEN
13871             ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTEGRAL_0];
13872             ALL_TAC] THEN
13873           DISCH_THEN(DISJ_CASES_THEN2 ASSUME_TAC MP_TAC) THENL
13874            [EXISTS_TAC `a:real^1` THEN
13875             ASM_REWRITE_TAC[ETA_AX; ENDS_IN_INTERVAL];
13876             ALL_TAC] THEN
13877           GEN_REWRITE_TAC LAND_CONV [OR_EXISTS_THM] THEN
13878           REWRITE_TAC[EXISTS_DROP] THEN
13879           DISCH_THEN(X_CHOOSE_THEN `d:real^1` ASSUME_TAC) THEN
13880           ASM_CASES_TAC `drop d < drop a` THENL
13881            [EXISTS_TAC `a:real^1` THEN
13882             ASM_REWRITE_TAC[ETA_AX; ENDS_IN_INTERVAL] THEN
13883             MATCH_MP_TAC INTEGRAL_EQ THEN
13884             REWRITE_TAC[IN_DIFF; IN_INTERVAL_1; NOT_IN_EMPTY] THEN
13885             GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
13886             UNDISCH_TAC `~(y <= (g:real^1->real) x)` THEN
13887             FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
13888             ASM_REAL_ARITH_TAC;
13889             ALL_TAC] THEN
13890           ASM_CASES_TAC `drop b < drop d` THENL
13891            [EXISTS_TAC `b:real^1` THEN
13892             SIMP_TAC[INTEGRAL_NULL; CONTENT_EQ_0_1; REAL_LE_REFL] THEN
13893             ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTEGRAL_0] THEN
13894             MATCH_MP_TAC INTEGRAL_EQ_0 THEN REWRITE_TAC[IN_INTERVAL_1] THEN
13895             REPEAT STRIP_TAC THEN
13896             COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
13897             UNDISCH_TAC `y <= (g:real^1->real) x` THEN
13898             FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
13899             ASM_REAL_ARITH_TAC;
13900             ALL_TAC] THEN
13901           EXISTS_TAC `d:real^1` THEN
13902           ASM_REWRITE_TAC[IN_INTERVAL_1; GSYM REAL_NOT_LT] THEN
13903           ONCE_REWRITE_TAC[SET_RULE
13904             `~((g:real^1->real) x < y) <=> x IN {x | ~(g x < y)}`] THEN
13905           REWRITE_TAC[INTEGRAL_RESTRICT_INTER] THEN
13906           MATCH_MP_TAC INTEGRAL_SPIKE_SET THEN
13907           MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `{d:real^1}` THEN
13908           REWRITE_TAC[NEGLIGIBLE_SING; REAL_NOT_LT; SUBSET] THEN GEN_TAC THEN
13909           REWRITE_TAC[SUBSET; IN_UNION; IN_INTER; IN_DIFF; IN_INTERVAL_1;
13910                       IN_ELIM_THM; IN_SING; GSYM DROP_EQ] THEN
13911           FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
13912           ASM_REAL_ARITH_TAC];
13913         DISCH_THEN(MP_TAC o GEN `k:num` o SPEC `&k / &n`) THEN
13914         REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM; LEFT_IMP_EXISTS_THM] THEN
13915         X_GEN_TAC `d:num->real^1` THEN STRIP_TAC THEN
13916         FIRST_ASSUM(MP_TAC o MATCH_MP (SET_RULE
13917          `IMAGE f s = t ==> !y. y IN t ==> ?x. x IN s /\ f x = y`)) THEN
13918         REWRITE_TAC[GSYM VSUM_LMUL] THEN DISCH_THEN MATCH_MP_TAC THEN
13919         MATCH_MP_TAC(REWRITE_RULE[CONVEX_INDEXED]
13920          (CONJUNCT1(SPEC_ALL CONVEX_INTERVAL))) THEN
13921         REWRITE_TAC[SUM_CONST_NUMSEG; ADD_SUB; REAL_LE_INV_EQ; REAL_POS] THEN
13922         ASM_SIMP_TAC[REAL_MUL_RINV; REAL_OF_NUM_EQ] THEN ASM SET_TAC[]];
13923       REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN
13924       X_GEN_TAC `c:num->real^1` THEN DISCH_THEN(STRIP_ASSUME_TAC o GSYM)] THEN
13925     SUBGOAL_THEN `compact(interval[a:real^1,b])` MP_TAC THENL
13926      [REWRITE_TAC[COMPACT_INTERVAL]; REWRITE_TAC[compact]] THEN
13927     DISCH_THEN(MP_TAC o SPEC `c:num->real^1`) THEN
13928     ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC
13929      [`d:real^1`; `s:num->num`] THEN STRIP_TAC THEN
13930     MP_TAC(ISPECL
13931      [`\n:num x. vsum (1..(s n))
13932                       (\k. if &k / &(s n) <= g x
13933                            then inv(&(s n)) % (f:real^1->real^1) x
13934                            else vec 0)`;
13935       `\x. g x % (f:real^1->real^1) x`; `a:real^1`; `b:real^1`]
13936      EQUIINTEGRABLE_LIMIT) THEN
13937     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
13938      [CONJ_TAC THENL
13939        [MATCH_MP_TAC EQUIINTEGRABLE_SUBSET THEN
13940         EXISTS_TAC
13941          `{\x. vsum(1..0) (\k. if &k / &0 <= g x
13942                                then inv(&0) % (f:real^1->real^1) x else vec 0)}
13943           UNION
13944           {\x. vsum (1..n)
13945                     (\k. if &k / &n <= g x then inv (&n) % f x else vec 0)
13946            | ~(n = 0)}` THEN
13947         CONJ_TAC THENL
13948          [MATCH_MP_TAC EQUIINTEGRABLE_UNION THEN ASM_REWRITE_TAC[] THEN
13949           REWRITE_TAC[EQUIINTEGRABLE_ON_SING; VSUM_CLAUSES_NUMSEG;
13950                       ARITH_EQ] THEN
13951           REWRITE_TAC[INTEGRABLE_0];
13952           REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_UNIV; IN_UNION] THEN
13953           REWRITE_TAC[IN_ELIM_THM; IN_SING] THEN
13954           X_GEN_TAC `n:num` THEN ASM_CASES_TAC `(s:num->num) n = 0` THEN
13955           ASM_REWRITE_TAC[] THEN DISJ2_TAC THEN
13956           EXISTS_TAC `(s:num->num) n` THEN ASM_REWRITE_TAC[]];
13957         X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN REWRITE_TAC[] THEN
13958         ONCE_REWRITE_TAC[MESON[VECTOR_MUL_LZERO]
13959          `(if p then a % x else vec 0) = (if p then a else &0) % x`] THEN
13960         REWRITE_TAC[VSUM_RMUL] THEN MATCH_MP_TAC LIM_VMUL THEN
13961         REWRITE_TAC[LIM_SEQUENTIALLY; o_DEF; DIST_LIFT] THEN
13962         X_GEN_TAC `e:real` THEN DISCH_TAC THEN
13963         MP_TAC(ISPEC `e:real` REAL_ARCH_INV) THEN
13964         ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN
13965         X_GEN_TAC `N:num` THEN STRIP_TAC THEN X_GEN_TAC `n:num` THEN
13966         DISCH_TAC THEN
13967         ONCE_REWRITE_TAC[REAL_ABS_SUB] THEN
13968         MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `inv(&n)` THEN
13969         CONJ_TAC THENL
13970          [MP_TAC(ISPECL
13971            [`(g:real^1->real) o lift`; `IMAGE drop (interval[a,b])`]
13972             lemma1) THEN
13973           ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_DEF; LIFT_DROP; IMP_CONJ;
13974                           RIGHT_FORALL_IMP_THM] THEN
13975           REWRITE_TAC[IMP_IMP] THEN DISCH_TAC THEN
13976           MATCH_MP_TAC REAL_LTE_TRANS THEN
13977           EXISTS_TAC `inv(&((s:num->num) n))` THEN CONJ_TAC THENL
13978            [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[];
13979             MATCH_MP_TAC REAL_LE_INV2 THEN
13980             REWRITE_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_LT]] THEN
13981           FIRST_ASSUM(MP_TAC o SPEC `n:num` o MATCH_MP MONOTONE_BIGGER) THEN
13982           ASM_ARITH_TAC;
13983           MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN
13984           ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
13985           REWRITE_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN ASM_ARITH_TAC]];
13986       STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
13987       EXISTS_TAC `d:real^1` THEN ASM_REWRITE_TAC[] THEN
13988       MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
13989       EXISTS_TAC `\n. integral (interval [c((s:num->num) n),b])
13990                                (f:real^1->real^1)` THEN
13991       ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
13992       MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`]
13993           INDEFINITE_INTEGRAL_CONTINUOUS_LEFT) THEN
13994       ASM_REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
13995       DISCH_THEN(MP_TAC o SPEC `d:real^1`) THEN ASM_REWRITE_TAC[] THEN
13996       REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY] THEN
13997       DISCH_THEN(MP_TAC o SPEC `(c:num->real^1) o (s:num->num)`) THEN
13998       ASM_REWRITE_TAC[] THEN ASM_REWRITE_TAC[o_DEF]]) in
13999   REPEAT GEN_TAC THEN STRIP_TAC THEN
14000   SUBGOAL_THEN `(g:real^1->real) a <= g b` MP_TAC THENL
14001    [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN
14002     ASM_MESON_TAC[INTERVAL_EQ_EMPTY_1; REAL_LET_TOTAL];
14003     ALL_TAC] THEN
14004   REWRITE_TAC[REAL_LE_LT] THEN STRIP_TAC THENL
14005    [ALL_TAC;
14006     SUBGOAL_THEN
14007      `!x. x IN interval[a,b] ==> g(x) % (f:real^1->real^1)(x) = g(a) % f x`
14008     ASSUME_TAC THENL
14009      [X_GEN_TAC `x:real^1` THEN
14010       REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN
14011       AP_THM_TAC THEN AP_TERM_TAC THEN
14012       RULE_ASSUM_TAC(REWRITE_RULE
14013        [IN_INTERVAL_1; INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
14014       ASM_MESON_TAC[REAL_LE_ANTISYM; REAL_LE_TRANS; REAL_LE_TOTAL];
14015       ALL_TAC] THEN
14016     EXISTS_TAC `a:real^1` THEN ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN
14017     MATCH_MP_TAC HAS_INTEGRAL_EQ THEN
14018     EXISTS_TAC `\x. g(a:real^1) % (f:real^1->real^1) x` THEN
14019     ASM_SIMP_TAC[INTEGRAL_NULL; CONTENT_EQ_0_1; REAL_LE_REFL] THEN
14020     ASM_SIMP_TAC[INTEGRAL_CMUL; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN
14021     MATCH_MP_TAC HAS_INTEGRAL_CMUL THEN
14022     ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]] THEN
14023   MP_TAC(ISPECL
14024    [`f:real^1->real^1`;
14025     `\x. if drop x < drop a then &0
14026          else if drop b < drop x then &1
14027          else (g(x) - g(a)) / (g(b) - g(a))`;
14028     `a:real^1`; `b:real^1`]
14029    lemma4) THEN ASM_REWRITE_TAC[] THEN
14030   ANTS_TAC THENL
14031    [CONJ_TAC THEN
14032     REPEAT GEN_TAC THEN
14033     REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_POS; REAL_LE_REFL]) THEN
14034     TRY ASM_REAL_ARITH_TAC THEN
14035     ASM_SIMP_TAC[IN_INTERVAL_1; REAL_LE_DIV2_EQ; REAL_SUB_LT] THEN
14036     ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN
14037     ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; REAL_SUB_LE;
14038                     REAL_ARITH `x - a <= y - a <=> x <= y`] THEN
14039     REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
14040     REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
14041     ALL_TAC] THEN
14042   REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN
14043   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN
14044   ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`] THEN
14045   DISCH_TAC THEN ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRABLE_INTEGRAL] THEN
14046   DISCH_THEN(MP_TAC o SPEC `(g:real^1->real) b - g a` o
14047         MATCH_MP HAS_INTEGRAL_CMUL) THEN
14048   FIRST_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
14049   DISCH_THEN(MP_TAC o SPEC `(g:real^1->real)(a)` o
14050       MATCH_MP HAS_INTEGRAL_CMUL) THEN REWRITE_TAC[IMP_IMP] THEN
14051   DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_ADD) THEN
14052   MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`]
14053         INTEGRAL_COMBINE) THEN
14054   ANTS_TAC THENL [ASM_MESON_TAC[IN_INTERVAL_1]; ALL_TAC] THEN
14055   DISCH_THEN(SUBST1_TAC o SYM) THEN
14056   REWRITE_TAC[VECTOR_ARITH
14057    `ga % (i1 + i2) + (gb - ga) % i2:real^N = ga % i1 + gb % i2`] THEN
14058   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_EQ) THEN
14059   X_GEN_TAC `x:real^1` THEN REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN
14060   ASM_SIMP_TAC[GSYM REAL_NOT_LE; VECTOR_MUL_ASSOC] THEN
14061   ASM_SIMP_TAC[REAL_DIV_LMUL; REAL_LT_IMP_NZ; REAL_SUB_LT] THEN
14062   VECTOR_ARITH_TAC);;
14063
14064 let SECOND_MEAN_VALUE_THEOREM = prove
14065  (`!f:real^1->real^1 g a b.
14066         ~(interval[a,b] = {}) /\
14067         f integrable_on interval [a,b] /\
14068         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
14069                ==> g x <= g y)
14070         ==> ?c. c IN interval [a,b] /\
14071                 integral (interval[a,b]) (\x. g x % f x) =
14072                  g(a) % integral (interval[a,c]) f +
14073                  g(b) % integral (interval[c,b]) f`,
14074   REPEAT GEN_TAC THEN
14075   DISCH_THEN(MP_TAC o MATCH_MP SECOND_MEAN_VALUE_THEOREM_FULL) THEN
14076   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN
14077   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
14078   FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN REWRITE_TAC[]);;
14079
14080 let SECOND_MEAN_VALUE_THEOREM_GEN_FULL = prove
14081  (`!f:real^1->real^1 g a b u v.
14082         ~(interval[a,b] = {}) /\ f integrable_on interval [a,b] /\
14083         (!x. x IN interval(a,b) ==> u <= g x /\ g x <= v) /\
14084         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
14085                ==> g x <= g y)
14086         ==> ?c. c IN interval [a,b] /\
14087                 ((\x. g x % f x) has_integral
14088                  (u % integral (interval[a,c]) f +
14089                   v % integral (interval[c,b]) f)) (interval[a,b])`,
14090   REPEAT STRIP_TAC THEN ASM_CASES_TAC `b:real^1 = a` THENL
14091    [EXISTS_TAC `a:real^1` THEN ASM_REWRITE_TAC[INTERVAL_SING; IN_SING] THEN
14092     ASM_SIMP_TAC[GSYM INTERVAL_SING; INTEGRAL_NULL; CONTENT_EQ_0_1;
14093       VECTOR_ADD_LID; REAL_LE_REFL; VECTOR_MUL_RZERO; HAS_INTEGRAL_NULL];
14094     ALL_TAC] THEN
14095   SUBGOAL_THEN `drop a < drop b` ASSUME_TAC THENL
14096    [ASM_MESON_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LE; DROP_EQ; REAL_LT_LE];
14097     ALL_TAC] THEN
14098   SUBGOAL_THEN `u <= v` ASSUME_TAC THENL
14099    [ASM_MESON_TAC[INTERVAL_EQ_EMPTY_1; MEMBER_NOT_EMPTY; REAL_NOT_LT;
14100                   REAL_LE_TRANS];
14101     ALL_TAC] THEN
14102   MP_TAC(ISPECL
14103    [`f:real^1->real^1`;
14104     `\x:real^1. if x = a then u else if x = b then v else g x:real`;
14105     `a:real^1`; `b:real^1`] SECOND_MEAN_VALUE_THEOREM_FULL) THEN
14106   ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN ANTS_TAC THENL
14107    [MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN
14108     ASM_CASES_TAC `x:real^1 = a` THEN ASM_REWRITE_TAC[] THENL
14109      [ASM_MESON_TAC[REAL_LE_REFL; INTERVAL_CASES_1]; ALL_TAC] THEN
14110     ASM_CASES_TAC `y:real^1 = b` THEN ASM_REWRITE_TAC[] THENL
14111      [ASM_MESON_TAC[REAL_LE_REFL; INTERVAL_CASES_1]; ALL_TAC] THEN
14112     REPEAT(COND_CASES_TAC THEN ASM_SIMP_TAC[]) THEN
14113     RULE_ASSUM_TAC(REWRITE_RULE[GSYM DROP_EQ]) THEN
14114     REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
14115     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN
14116     MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN MATCH_MP_TAC
14117      (REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
14118         HAS_INTEGRAL_SPIKE) THEN
14119     EXISTS_TAC `{a:real^1,b}` THEN
14120     SIMP_TAC[NEGLIGIBLE_EMPTY; NEGLIGIBLE_INSERT; IN_DIFF; IN_INSERT;
14121              NOT_IN_EMPTY; DE_MORGAN_THM]]);;
14122
14123 let SECOND_MEAN_VALUE_THEOREM_GEN = prove
14124  (`!f:real^1->real^1 g a b u v.
14125         ~(interval[a,b] = {}) /\ f integrable_on interval [a,b] /\
14126         (!x. x IN interval(a,b) ==> u <= g x /\ g x <= v) /\
14127         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
14128                ==> g x <= g y)
14129         ==> ?c. c IN interval [a,b] /\
14130                 integral (interval[a,b]) (\x. g x % f x) =
14131                 u % integral (interval[a,c]) f +
14132                 v % integral (interval[c,b]) f`,
14133   REPEAT GEN_TAC THEN
14134   DISCH_THEN(MP_TAC o MATCH_MP SECOND_MEAN_VALUE_THEOREM_GEN_FULL) THEN
14135   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN
14136   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
14137   FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN REWRITE_TAC[]);;
14138
14139 let SECOND_MEAN_VALUE_THEOREM_BONNET_FULL = prove
14140  (`!f:real^1->real^1 g a b.
14141         ~(interval[a,b] = {}) /\ f integrable_on interval [a,b] /\
14142         (!x. x IN interval[a,b] ==> &0 <= g x) /\
14143         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
14144                ==> g x <= g y)
14145         ==> ?c. c IN interval [a,b] /\
14146                 ((\x. g x % f x) has_integral
14147                  (g(b) % integral (interval[c,b]) f)) (interval[a,b])`,
14148   REPEAT STRIP_TAC THEN
14149   MP_TAC(ISPECL
14150    [`f:real^1->real^1`; `g:real^1->real`; `a:real^1`; `b:real^1`;
14151     `&0`; `(g:real^1->real) b`] SECOND_MEAN_VALUE_THEOREM_GEN_FULL) THEN
14152   ASM_REWRITE_TAC[VECTOR_MUL_LZERO; VECTOR_ADD_LID] THEN
14153   DISCH_THEN MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
14154   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
14155   REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC);;
14156
14157 let SECOND_MEAN_VALUE_THEOREM_BONNET = prove
14158  (`!f:real^1->real^1 g a b.
14159         ~(interval[a,b] = {}) /\ f integrable_on interval[a,b] /\
14160         (!x. x IN interval[a,b] ==> &0 <= g x) /\
14161         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
14162                ==> g x <= g y)
14163         ==> ?c. c IN interval [a,b] /\
14164                 integral (interval[a,b]) (\x. g x % f x) =
14165                 g(b) % integral (interval[c,b]) f`,
14166   REPEAT GEN_TAC THEN
14167   DISCH_THEN(MP_TAC o MATCH_MP SECOND_MEAN_VALUE_THEOREM_BONNET_FULL) THEN
14168   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN
14169   REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
14170   FIRST_X_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN REWRITE_TAC[]);;
14171
14172 let INTEGRABLE_INCREASING_PRODUCT = prove
14173  (`!f:real^1->real^N g a b.
14174         f integrable_on interval[a,b] /\
14175         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
14176                ==> g(x) <= g(y))
14177         ==> (\x. g(x) % f(x)) integrable_on interval[a,b]`,
14178   REPEAT STRIP_TAC THEN ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN
14179   ASM_REWRITE_TAC[INTEGRABLE_ON_EMPTY] THEN
14180   ONCE_REWRITE_TAC[INTEGRABLE_COMPONENTWISE] THEN
14181   X_GEN_TAC `i:num` THEN STRIP_TAC THEN
14182   MP_TAC(ISPECL [`\x. lift((f:real^1->real^N) x$i)`;
14183                  `g:real^1->real`; `a:real^1`; `b:real^1`]
14184     SECOND_MEAN_VALUE_THEOREM_FULL) THEN
14185   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
14186    [RULE_ASSUM_TAC(ONCE_REWRITE_RULE[INTEGRABLE_COMPONENTWISE]) THEN
14187     ASM_SIMP_TAC[];
14188     REWRITE_TAC[VECTOR_MUL_COMPONENT; LIFT_CMUL; integrable_on] THEN
14189     MESON_TAC[]]);;
14190
14191 let INTEGRABLE_INCREASING_PRODUCT_UNIV = prove
14192  (`!f:real^1->real^N g B.
14193         f integrable_on (:real^1) /\
14194         (!x y. drop x <= drop y ==> g x <= g y) /\
14195         (!x. abs(g x) <= B)
14196          ==> (\x. g x % f x) integrable_on (:real^1)`,
14197   let lemma = prove
14198    (`!f:real^1->real^1 g B.
14199           f integrable_on (:real^1) /\
14200           (!x y. drop x <= drop y ==> g x <= g y) /\
14201           (!x. abs(g x) <= B)
14202            ==> (\x. g x % f x) integrable_on (:real^1)`,
14203     REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[INTEGRABLE_ALT_SUBSET] THEN
14204     REWRITE_TAC[IN_UNIV; ETA_AX] THEN STRIP_TAC THEN
14205     MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
14206      [REPEAT GEN_TAC THEN MATCH_MP_TAC INTEGRABLE_INCREASING_PRODUCT THEN
14207       ASM_SIMP_TAC[];
14208       DISCH_TAC] THEN
14209     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
14210     FIRST_X_ASSUM(MP_TAC o SPEC `e / (&8 * abs B + &8)`) THEN
14211     ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &8 * abs B + &8`] THEN
14212     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `C:real` THEN STRIP_TAC THEN
14213     ASM_REWRITE_TAC[] THEN
14214     SUBGOAL_THEN `~(ball(vec 0:real^1,C) = {})` ASSUME_TAC THENL
14215      [ASM_REWRITE_TAC[BALL_EQ_EMPTY; REAL_NOT_LE]; ALL_TAC] THEN
14216     MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`; `c:real^1`; `d:real^1`] THEN
14217     STRIP_TAC THEN SUBGOAL_THEN
14218      `~(interval[a:real^1,b] = {}) /\ ~(interval[c:real^1,d] = {})`
14219     MP_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
14220     REWRITE_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN STRIP_TAC THEN
14221     FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET_INTERVAL_1]) THEN
14222     ASM_REWRITE_TAC[GSYM REAL_NOT_LE] THEN STRIP_TAC THEN
14223     MP_TAC(ISPECL [`\x. g x % (f:real^1->real^1) x`;
14224                    `c:real^1`; `b:real^1`; `a:real^1`] INTEGRAL_COMBINE) THEN
14225     MP_TAC(ISPECL [`\x. g x % (f:real^1->real^1) x`;
14226                    `c:real^1`; `d:real^1`; `b:real^1`] INTEGRAL_COMBINE) THEN
14227     ASM_REWRITE_TAC[] THEN
14228     ANTS_TAC THENL [ASM_REAL_ARITH_TAC; DISCH_THEN(SUBST1_TAC o SYM)] THEN
14229     DISCH_THEN(SUBST1_TAC o SYM) THEN
14230     REWRITE_TAC[REAL_NOT_LE; NORM_ARITH
14231      `norm(ab - ((ca + ab) + bd):real^1) = norm(ca + bd)`] THEN
14232     MP_TAC(ISPECL[`f:real^1->real^1`; `g:real^1->real`; `c:real^1`; `a:real^1`]
14233           SECOND_MEAN_VALUE_THEOREM) THEN
14234     ASM_SIMP_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN
14235     DISCH_THEN(X_CHOOSE_THEN `u:real^1` STRIP_ASSUME_TAC) THEN
14236     MP_TAC(ISPECL[`f:real^1->real^1`; `g:real^1->real`; `b:real^1`; `d:real^1`]
14237           SECOND_MEAN_VALUE_THEOREM) THEN
14238     ASM_SIMP_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN
14239     DISCH_THEN(X_CHOOSE_THEN `v:real^1` STRIP_ASSUME_TAC) THEN
14240     ASM_REWRITE_TAC[] THEN
14241     SUBGOAL_THEN
14242      `!x y. drop y <= drop a
14243             ==> norm(integral (interval[x,y]) (f:real^1->real^1))
14244                 < e / (&4 * abs B + &4)`
14245      (LABEL_TAC "L")
14246     THENL
14247      [REPEAT STRIP_TAC THEN
14248       ASM_CASES_TAC `drop x <= drop y` THENL
14249        [FIRST_X_ASSUM(fun th ->
14250          MP_TAC(SPECL[`a:real^1`; `b:real^1`; `y:real^1`; `b:real^1`] th) THEN
14251          MP_TAC(SPECL[`a:real^1`; `b:real^1`; `x:real^1`; `b:real^1`] th)) THEN
14252         ASM_REWRITE_TAC[SUBSET_INTERVAL_1; REAL_LE_REFL] THEN
14253         ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
14254         MP_TAC(ISPECL [`f:real^1->real^1`; `x:real^1`; `b:real^1`; `y:real^1`]
14255           INTEGRAL_COMBINE) THEN
14256         ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
14257          [ASM_ARITH_TAC; DISCH_THEN(SUBST1_TAC o SYM)] THEN
14258         MATCH_MP_TAC(NORM_ARITH
14259          `&2 * d = e
14260           ==> norm(ab - (xy + yb)) < d
14261               ==> norm(ab - yb) < d
14262                   ==> norm(xy:real^1) < e`) THEN
14263         CONV_TAC REAL_FIELD;
14264         SUBGOAL_THEN `interval[x:real^1,y] = {}` SUBST1_TAC THENL
14265          [REWRITE_TAC[INTERVAL_EQ_EMPTY_1] THEN ASM_REAL_ARITH_TAC;
14266           REWRITE_TAC[INTEGRAL_EMPTY; NORM_0] THEN
14267           MATCH_MP_TAC REAL_LT_DIV THEN ASM_REAL_ARITH_TAC]];
14268       ALL_TAC] THEN
14269     SUBGOAL_THEN
14270      `!x y. drop b <= drop x
14271             ==> norm(integral (interval[x,y]) (f:real^1->real^1))
14272                 < e / (&4 * abs B + &4)`
14273      (LABEL_TAC "R")
14274     THENL
14275      [REPEAT STRIP_TAC THEN
14276       ASM_CASES_TAC `drop x <= drop y` THENL
14277        [FIRST_X_ASSUM(fun th ->
14278          MP_TAC(SPECL[`a:real^1`; `b:real^1`; `a:real^1`; `x:real^1`] th) THEN
14279          MP_TAC(SPECL[`a:real^1`; `b:real^1`; `a:real^1`; `y:real^1`] th)) THEN
14280         ASM_REWRITE_TAC[SUBSET_INTERVAL_1; REAL_LE_REFL] THEN
14281         ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
14282         MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `y:real^1`; `x:real^1`]
14283           INTEGRAL_COMBINE) THEN
14284         ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
14285          [ASM_ARITH_TAC; DISCH_THEN(SUBST1_TAC o SYM)] THEN
14286         MATCH_MP_TAC(NORM_ARITH
14287          `&2 * d = e
14288           ==> norm(ab - (ax + xy)) < d
14289               ==> norm(ab - ax) < d
14290                   ==> norm(xy:real^1) < e`) THEN
14291         CONV_TAC REAL_FIELD;
14292         SUBGOAL_THEN `interval[x:real^1,y] = {}` SUBST1_TAC THENL
14293          [REWRITE_TAC[INTERVAL_EQ_EMPTY_1] THEN ASM_REAL_ARITH_TAC;
14294           REWRITE_TAC[INTEGRAL_EMPTY; NORM_0] THEN
14295           MATCH_MP_TAC REAL_LT_DIV THEN ASM_REAL_ARITH_TAC]];
14296       ALL_TAC] THEN
14297     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
14298     MATCH_MP_TAC REAL_LET_TRANS THEN
14299     EXISTS_TAC `&4 * B * e / (&4 * abs B + &4)` THEN CONJ_TAC THENL
14300      [MATCH_MP_TAC(NORM_ARITH
14301        `(norm a <= e /\ norm b <= e) /\ (norm c <= e /\ norm d <= e)
14302         ==> norm((a + b) + (c + d):real^1) <= &4 * e`) THEN
14303       REWRITE_TAC[NORM_MUL] THEN CONJ_TAC THENL
14304        [CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
14305         ASM_REWRITE_TAC[NORM_POS_LE; REAL_ABS_POS] THEN
14306         MATCH_MP_TAC REAL_LT_IMP_LE THEN
14307         REMOVE_THEN "L" MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC;
14308         CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
14309         ASM_REWRITE_TAC[NORM_POS_LE; REAL_ABS_POS] THEN
14310         MATCH_MP_TAC REAL_LT_IMP_LE THEN
14311         REMOVE_THEN "R" MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC];
14312       REWRITE_TAC[REAL_ARITH
14313        `&4 * B * e / y < e <=> e * (&4 * B) / y < e * &1`] THEN
14314       ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_LT_LDIV_EQ;
14315                    REAL_ARITH `&0 < &4 * abs B + &4`] THEN
14316       REAL_ARITH_TAC]) in
14317   GEN_TAC THEN ONCE_REWRITE_TAC[INTEGRABLE_COMPONENTWISE] THEN
14318   REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
14319   REWRITE_TAC[VECTOR_MUL_COMPONENT; LIFT_CMUL] THEN
14320   MATCH_MP_TAC lemma THEN EXISTS_TAC `B:real` THEN ASM_SIMP_TAC[]);;
14321
14322 let INTEGRABLE_INCREASING = prove
14323  (`!f:real^1->real^N a b.
14324         (!x y i. x IN interval[a,b] /\ y IN interval[a,b] /\
14325                  drop x <= drop y /\ 1 <= i /\ i <= dimindex(:N)
14326                  ==> f(x)$i <= f(y)$i)
14327         ==> f integrable_on interval[a,b]`,
14328   REPEAT STRIP_TAC THEN ONCE_REWRITE_TAC[INTEGRABLE_COMPONENTWISE] THEN
14329   X_GEN_TAC `i:num` THEN STRIP_TAC THEN
14330   ONCE_REWRITE_TAC[GSYM REAL_MUL_RID] THEN
14331   REWRITE_TAC[LIFT_CMUL; LIFT_NUM] THEN
14332   MATCH_MP_TAC INTEGRABLE_INCREASING_PRODUCT THEN
14333   ASM_SIMP_TAC[INTEGRABLE_CONST]);;
14334
14335 let INTEGRABLE_INCREASING_1 = prove
14336  (`!f:real^1->real^1 a b.
14337         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
14338                ==> drop(f x) <= drop(f y))
14339         ==> f integrable_on interval[a,b]`,
14340   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_INCREASING THEN
14341   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
14342   ASM_SIMP_TAC[IMP_IMP; FORALL_1; DIMINDEX_1; GSYM drop]);;
14343
14344 let INTEGRABLE_DECREASING_PRODUCT = prove
14345  (`!f:real^1->real^N g a b.
14346         f integrable_on interval[a,b] /\
14347         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
14348                ==> g(y) <= g(x))
14349         ==> (\x. g(x) % f(x)) integrable_on interval[a,b]`,
14350   REPEAT STRIP_TAC THEN
14351   ONCE_REWRITE_TAC[VECTOR_ARITH `x % y:real^N = --(--x % y)`] THEN
14352   MATCH_MP_TAC INTEGRABLE_NEG THEN
14353   MATCH_MP_TAC INTEGRABLE_INCREASING_PRODUCT THEN
14354   ASM_REWRITE_TAC[REAL_LE_NEG2]);;
14355
14356 let INTEGRABLE_DECREASING_PRODUCT_UNIV = prove
14357  (`!f:real^1->real^N g B.
14358         f integrable_on (:real^1) /\
14359         (!x y. drop x <= drop y ==> g y <= g x) /\
14360         (!x. abs(g x) <= B)
14361          ==> (\x. g x % f x) integrable_on (:real^1)`,
14362   REPEAT STRIP_TAC THEN
14363   ONCE_REWRITE_TAC[VECTOR_ARITH `x % y:real^N = --(--x % y)`] THEN
14364   MATCH_MP_TAC INTEGRABLE_NEG THEN
14365   MATCH_MP_TAC INTEGRABLE_INCREASING_PRODUCT_UNIV THEN
14366   EXISTS_TAC `B:real` THEN ASM_REWRITE_TAC[REAL_LE_NEG2; REAL_ABS_NEG]);;
14367
14368 let INTEGRABLE_DECREASING = prove
14369  (`!f:real^1->real^N a b.
14370         (!x y i. x IN interval[a,b] /\ y IN interval[a,b] /\
14371                  drop x <= drop y /\ 1 <= i /\ i <= dimindex(:N)
14372                  ==> f(y)$i <= f(x)$i)
14373         ==> f integrable_on interval[a,b]`,
14374   REPEAT STRIP_TAC THEN GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN
14375   GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [GSYM VECTOR_NEG_NEG] THEN
14376   MATCH_MP_TAC INTEGRABLE_NEG THEN MATCH_MP_TAC INTEGRABLE_INCREASING THEN
14377   ASM_SIMP_TAC[VECTOR_NEG_COMPONENT; REAL_LE_NEG2]);;
14378
14379 let INTEGRABLE_DECREASING_1 = prove
14380  (`!f:real^1->real^1 a b.
14381         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
14382                ==> drop(f y) <= drop(f x))
14383         ==> f integrable_on interval[a,b]`,
14384   REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_DECREASING THEN
14385   REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
14386   ASM_SIMP_TAC[IMP_IMP; FORALL_1; DIMINDEX_1; GSYM drop]);;
14387
14388 (* ------------------------------------------------------------------------- *)
14389 (* Bounded variation and variation function, for real^1->real^N functions.   *)
14390 (* ------------------------------------------------------------------------- *)
14391
14392 parse_as_infix("has_bounded_variation_on",(12,"right"));;
14393
14394 let has_bounded_variation_on = new_definition
14395  `(f:real^1->real^N) has_bounded_variation_on s <=>
14396         (\k. f(interval_upperbound k) - f(interval_lowerbound k))
14397         has_bounded_setvariation_on s`;;
14398
14399 let vector_variation = new_definition
14400  `vector_variation s (f:real^1->real^N) =
14401   set_variation s (\k. f(interval_upperbound k) - f(interval_lowerbound k))`;;
14402
14403 let HAS_BOUNDED_VARIATION_ON_EQ = prove
14404  (`!f g:real^1->real^N s.
14405         (!x. x IN s ==> f x = g x) /\ f has_bounded_variation_on s
14406         ==> g has_bounded_variation_on s`,
14407   REPEAT GEN_TAC THEN
14408   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
14409   REWRITE_TAC[has_bounded_variation_on] THEN
14410   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_BOUNDED_SETVARIATION_ON_EQ) THEN
14411   SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND;
14412            GSYM INTERVAL_NE_EMPTY] THEN
14413   ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET]);;
14414
14415 let VECTOR_VARIATION_EQ = prove
14416  (`!f g:real^1->real^N s.
14417         (!x. x IN s ==> f x = g x)
14418         ==> vector_variation s f = vector_variation s g`,
14419   REPEAT STRIP_TAC THEN REWRITE_TAC[vector_variation] THEN
14420   MATCH_MP_TAC SET_VARIATION_EQ THEN
14421   SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND;
14422            GSYM INTERVAL_NE_EMPTY] THEN
14423   ASM_MESON_TAC[ENDS_IN_INTERVAL; SUBSET]);;
14424
14425 let HAS_BOUNDED_VARIATION_ON_COMPONENTWISE = prove
14426  (`!f:real^1->real^N s.
14427         f has_bounded_variation_on s <=>
14428         !i. 1 <= i /\ i <= dimindex(:N)
14429             ==> (\x. lift(f x$i)) has_bounded_variation_on s`,
14430   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
14431   GEN_REWRITE_TAC LAND_CONV [HAS_BOUNDED_SETVARIATION_ON_COMPONENTWISE] THEN
14432   REWRITE_TAC[VECTOR_SUB_COMPONENT; LIFT_SUB]);;
14433
14434 let VARIATION_EQUAL_LEMMA = prove
14435  (`!ms ms'.
14436         (!s. ms'(ms s) = s /\ ms(ms' s) = s) /\
14437         (!d t. d division_of t
14438                ==> (IMAGE (IMAGE ms) d) division_of IMAGE ms t /\
14439                    (IMAGE (IMAGE ms') d) division_of IMAGE ms' t) /\
14440         (!a b. ~(interval[a,b] = {})
14441                ==> IMAGE ms' (interval [a,b]) = interval[ms' a,ms' b] \/
14442                    IMAGE ms' (interval [a,b]) = interval[ms' b,ms' a])
14443    ==> (!f:real^1->real^N s.
14444             (\x. f(ms' x)) has_bounded_variation_on (IMAGE ms s) <=>
14445             f has_bounded_variation_on s) /\
14446        (!f:real^1->real^N s.
14447             vector_variation (IMAGE ms s) (\x. f(ms' x)) =
14448             vector_variation s f)`,
14449   REPEAT GEN_TAC THEN STRIP_TAC THEN
14450   REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN
14451   GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `f:real^1->real^N` THEN
14452   MP_TAC(ISPECL
14453    [`\f k. (f:(real^1->bool)->real^N) (IMAGE (ms':real^1->real^1) k)`;
14454     `IMAGE (ms:real^1->real^1)`;
14455     `IMAGE (ms':real^1->real^1)`]
14456   SETVARIATION_EQUAL_LEMMA) THEN
14457   ANTS_TAC THENL
14458    [ASM_SIMP_TAC[GSYM IMAGE_o; o_DEF; IMAGE_ID; IMAGE_SUBSET] THEN
14459     MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`] THEN STRIP_TAC THEN
14460     FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN
14461     ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
14462     ASM_MESON_TAC[IMAGE_EQ_EMPTY];
14463     ALL_TAC] THEN
14464   REWRITE_TAC[] THEN GEN_REWRITE_TAC LAND_CONV [AND_FORALL_THM] THEN
14465   DISCH_THEN(fun th ->
14466     MP_TAC(SPEC `\k. (f:real^1->real^N) (interval_upperbound k) -
14467                      f (interval_lowerbound k)` th)) THEN
14468   REWRITE_TAC[] THEN DISCH_THEN(fun th -> ONCE_REWRITE_TAC[GSYM th]) THEN
14469   GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `s:real^1->bool` THEN
14470   REWRITE_TAC[has_bounded_setvariation_on; set_variation] THEN
14471   CONJ_TAC THENL
14472    [REPLICATE_TAC 3 (AP_TERM_TAC THEN ABS_TAC) THEN
14473     REWRITE_TAC[TAUT `((p ==> q) <=> (p ==> r)) <=> p ==> (q <=> r)`] THEN
14474     STRIP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC;
14475     AP_TERM_TAC THEN
14476     MATCH_MP_TAC(SET_RULE
14477      `(!x. P x ==> f x = g x) ==> {f x | P x} = {g x | P x}`) THEN
14478     GEN_TAC THEN STRIP_TAC] THEN
14479   MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th ->
14480    GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION_NONEMPTY th]) THEN
14481   MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`] THEN STRIP_TAC THEN
14482   FIRST_X_ASSUM(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN
14483   ASM_REWRITE_TAC[] THEN DISCH_THEN(DISJ_CASES_THEN MP_TAC) THEN
14484   DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
14485    `IMAGE f s = s' ==> ~(s = {}) ==> IMAGE f s = s' /\ ~(s' = {})`)) THEN
14486   ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
14487   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY_1]) THEN
14488   ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1] THEN
14489   NORM_ARITH_TAC);;
14490
14491 let HAS_BOUNDED_VARIATION_ON_SUBSET = prove
14492  (`!f:real^1->real^N s t.
14493         f has_bounded_variation_on s /\ t SUBSET s
14494         ==> f has_bounded_variation_on t`,
14495   REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_SUBSET; has_bounded_variation_on]);;
14496
14497 let HAS_BOUNDED_VARIATION_ON_CONST = prove
14498  (`!s c:real^N. (\x. c) has_bounded_variation_on s`,
14499   REWRITE_TAC[has_bounded_variation_on; VECTOR_SUB_REFL;
14500               HAS_BOUNDED_SETVARIATION_ON_0]);;
14501
14502 let VECTOR_VARIATION_CONST = prove
14503  (`!s c:real^N. vector_variation s (\x. c) = &0`,
14504   REWRITE_TAC[vector_variation; VECTOR_SUB_REFL; SET_VARIATION_0]);;
14505
14506 let HAS_BOUNDED_VARIATION_ON_CMUL = prove
14507  (`!f:real^1->real^N c s.
14508         f has_bounded_variation_on s
14509         ==> (\x. c % f x) has_bounded_variation_on s`,
14510   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
14511   REWRITE_TAC[GSYM VECTOR_SUB_LDISTRIB; HAS_BOUNDED_SETVARIATION_ON_CMUL]);;
14512
14513 let HAS_BOUNDED_VARIATION_ON_NEG = prove
14514  (`!f:real^1->real^N s.
14515         f has_bounded_variation_on s
14516         ==> (\x. --f x) has_bounded_variation_on s`,
14517   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
14518   REWRITE_TAC[VECTOR_ARITH `--a - --b:real^N = --(a - b)`;
14519               HAS_BOUNDED_SETVARIATION_ON_NEG]);;
14520
14521 let HAS_BOUNDED_VARIATION_ON_ADD = prove
14522  (`!f g:real^1->real^N s.
14523         f has_bounded_variation_on s /\ g has_bounded_variation_on s
14524         ==> (\x. f x + g x) has_bounded_variation_on s`,
14525   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
14526   REWRITE_TAC[VECTOR_ARITH `(f + g) - (f' + g'):real^N = (f - f') + (g - g')`;
14527               HAS_BOUNDED_SETVARIATION_ON_ADD]);;
14528
14529 let HAS_BOUNDED_VARIATION_ON_SUB = prove
14530  (`!f g:real^1->real^N s.
14531         f has_bounded_variation_on s /\ g has_bounded_variation_on s
14532         ==> (\x. f x - g x) has_bounded_variation_on s`,
14533   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
14534   REWRITE_TAC[VECTOR_ARITH `(f - g) - (f' - g'):real^N = (f - f') - (g - g')`;
14535               HAS_BOUNDED_SETVARIATION_ON_SUB]);;
14536
14537 let HAS_BOUNDED_VARIATION_ON_COMPOSE_LINEAR = prove
14538  (`!f:real^1->real^M g:real^M->real^N s.
14539         f has_bounded_variation_on s /\ linear g
14540         ==> (g o f) has_bounded_variation_on s`,
14541   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
14542   SIMP_TAC[o_THM; GSYM LINEAR_SUB] THEN
14543   DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_SETVARIATION_ON_COMPOSE_LINEAR) THEN
14544   REWRITE_TAC[o_DEF]);;
14545
14546 let HAS_BOUNDED_VARIATION_ON_NULL = prove
14547  (`!f:real^1->real^N s.
14548         content s = &0 /\ bounded s ==> f has_bounded_variation_on s`,
14549   REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
14550   MATCH_MP_TAC HAS_BOUNDED_SETVARIATION_ON_NULL THEN
14551   ASM_SIMP_TAC[INTERVAL_BOUNDS_NULL_1; VECTOR_SUB_REFL]);;
14552
14553 let HAS_BOUNDED_VARIATION_ON_EMPTY = prove
14554  (`!f:real^1->real^N. f has_bounded_variation_on {}`,
14555   MESON_TAC[CONTENT_EMPTY; BOUNDED_EMPTY; HAS_BOUNDED_VARIATION_ON_NULL]);;
14556
14557 let VECTOR_VARIATION_ON_NULL = prove
14558  (`!f s. content s = &0 /\ bounded s ==> vector_variation s f = &0`,
14559   REPEAT STRIP_TAC THEN REWRITE_TAC[vector_variation] THEN
14560   MATCH_MP_TAC SET_VARIATION_ON_NULL THEN ASM_REWRITE_TAC[] THEN
14561   SIMP_TAC[INTERVAL_BOUNDS_NULL_1; VECTOR_SUB_REFL]);;
14562
14563 let HAS_BOUNDED_VARIATION_ON_NORM = prove
14564  (`!f:real^1->real^N s.
14565         f has_bounded_variation_on s
14566         ==> (\x. lift(norm(f x))) has_bounded_variation_on s`,
14567   REWRITE_TAC[has_bounded_variation_on; has_bounded_setvariation_on] THEN
14568   REPEAT GEN_TAC THEN MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
14569   REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
14570   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
14571   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LE_TRANS) THEN
14572   MATCH_MP_TAC SUM_LE THEN
14573   REWRITE_TAC[NORM_REAL; GSYM drop; LIFT_DROP; DROP_SUB] THEN
14574   CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_FINITE]; NORM_ARITH_TAC]);;
14575
14576 let HAS_BOUNDED_VARIATION_ON_MAX = prove
14577  (`!f g s. f has_bounded_variation_on s /\ g has_bounded_variation_on s
14578            ==> (\x. lift(max (drop(f x)) (drop(g x))))
14579                has_bounded_variation_on s`,
14580   REPEAT STRIP_TAC THEN
14581   REWRITE_TAC[REAL_ARITH `max a b = inv(&2) * (a + b + abs(a - b))`] THEN
14582   REWRITE_TAC[LIFT_CMUL; LIFT_ADD; LIFT_DROP; GSYM DROP_SUB] THEN
14583   REWRITE_TAC[drop; GSYM NORM_REAL] THEN
14584   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_CMUL THEN
14585   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_ADD THEN ASM_REWRITE_TAC[] THEN
14586   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_ADD THEN ASM_REWRITE_TAC[] THEN
14587   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NORM THEN
14588   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN ASM_REWRITE_TAC[]);;
14589
14590 let HAS_BOUNDED_VARIATION_ON_MIN = prove
14591  (`!f g s. f has_bounded_variation_on s /\ g has_bounded_variation_on s
14592            ==> (\x. lift(min (drop(f x)) (drop(g x))))
14593                has_bounded_variation_on s`,
14594   REPEAT STRIP_TAC THEN
14595   REWRITE_TAC[REAL_ARITH `min a b = inv(&2) * ((a + b) - abs(a - b))`] THEN
14596   REWRITE_TAC[LIFT_CMUL; LIFT_ADD; LIFT_DROP; LIFT_SUB; GSYM DROP_SUB] THEN
14597   REWRITE_TAC[drop; GSYM NORM_REAL] THEN
14598   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_CMUL THEN
14599   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN
14600   ASM_SIMP_TAC[HAS_BOUNDED_VARIATION_ON_ADD] THEN
14601   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NORM THEN
14602   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN ASM_REWRITE_TAC[]);;
14603
14604 let HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS = prove
14605  (`!f:real^1->real^N s.
14606         f has_bounded_variation_on s
14607         ==> bounded { f(d) - f(c) | interval[c,d] SUBSET s /\
14608                                     ~(interval[c,d] = {})}`,
14609   REPEAT GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
14610   DISCH_THEN(MP_TAC o MATCH_MP
14611    HAS_BOUNDED_SETVARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS) THEN
14612   MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] BOUNDED_SUBSET) THEN
14613   GEN_REWRITE_TAC I [SUBSET] THEN REWRITE_TAC[FORALL_IN_GSPEC] THEN
14614   MAP_EVERY X_GEN_TAC [`d:real^1`; `c:real^1`] THEN
14615   REWRITE_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN STRIP_TAC THEN
14616   REWRITE_TAC[IN_ELIM_THM] THEN
14617   MAP_EVERY EXISTS_TAC [`c:real^1`; `d:real^1`] THEN
14618   ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1]);;
14619
14620 let HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL = prove
14621  (`!f:real^1->real^N a b.
14622         f has_bounded_variation_on interval[a,b]
14623         ==> bounded(IMAGE f (interval[a,b]))`,
14624   REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP
14625    HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_SUBINTERVALS) THEN
14626   REWRITE_TAC[BOUNDED_POS_LT; FORALL_IN_GSPEC; FORALL_IN_IMAGE] THEN
14627   DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
14628   EXISTS_TAC `B + norm((f:real^1->real^N) a)` THEN
14629   ASM_SIMP_TAC[NORM_ARITH `&0 < B ==> &0 < B + norm(x:real^N)`] THEN
14630   X_GEN_TAC `x:real^1` THEN REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN
14631   FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^1`; `a:real^1`]) THEN
14632   REWRITE_TAC[SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1] THEN ANTS_TAC THENL
14633    [ASM_REAL_ARITH_TAC; NORM_ARITH_TAC]);;
14634
14635 let HAS_BOUNDED_VARIATION_ON_MUL = prove
14636  (`!f g:real^1->real^N a b.
14637         f has_bounded_variation_on interval[a,b] /\
14638         g has_bounded_variation_on interval[a,b]
14639         ==> (\x. drop(f x) % g x) has_bounded_variation_on interval[a,b]`,
14640   REPEAT GEN_TAC THEN DISCH_TAC THEN
14641   SUBGOAL_THEN
14642     `bounded(IMAGE (f:real^1->real^1) (interval[a,b])) /\
14643      bounded(IMAGE (g:real^1->real^N) (interval[a,b]))`
14644   MP_TAC THENL
14645    [ASM_SIMP_TAC[HAS_BOUNDED_VARIATION_ON_IMP_BOUNDED_ON_INTERVAL];
14646     REWRITE_TAC[BOUNDED_POS_LT; FORALL_IN_IMAGE]] THEN
14647   DISCH_THEN(CONJUNCTS_THEN2
14648    (X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC)
14649    (X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC)) THEN
14650   FIRST_X_ASSUM(CONJUNCTS_THEN MP_TAC) THEN
14651   REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_INTERVAL;
14652               has_bounded_variation_on] THEN
14653   DISCH_THEN(X_CHOOSE_THEN `C2:real` (LABEL_TAC "G")) THEN
14654   DISCH_THEN(X_CHOOSE_THEN `C1:real` (LABEL_TAC "F")) THEN
14655   EXISTS_TAC `B1 * C2 + B2 * C1:real` THEN
14656   X_GEN_TAC `d:(real^1->bool)->bool` THEN DISCH_TAC THEN
14657   MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
14658    `B1 * sum d (\k. norm((g:real^1->real^N)(interval_upperbound k) -
14659                          g(interval_lowerbound k))) +
14660     B2 * sum d (\k. norm((f:real^1->real^1)(interval_upperbound k) -
14661                          f(interval_lowerbound k)))` THEN
14662   CONJ_TAC THENL
14663    [ALL_TAC; MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_SIMP_TAC[REAL_LE_LMUL_EQ]] THEN
14664   FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
14665   ASM_SIMP_TAC[GSYM SUM_LMUL; GSYM SUM_ADD] THEN
14666   MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[] THEN
14667   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
14668   MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN
14669   ONCE_REWRITE_TAC[VECTOR_ARITH
14670    `f' % g' - f % g:real^N = f' % (g' - g) + (f' - f) % g`] THEN
14671   MATCH_MP_TAC(NORM_ARITH
14672     `norm x <= a /\ norm y <= b ==> norm(x + y) <= a + b`) THEN
14673   REWRITE_TAC[NORM_MUL; NORM_REAL] THEN
14674   REWRITE_TAC[drop; GSYM NORM_REAL; GSYM VECTOR_SUB_COMPONENT] THEN
14675   SUBGOAL_THEN `~(interval[u:real^1,v] = {})` MP_TAC THENL
14676    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
14677   REWRITE_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN DISCH_TAC THEN
14678   ASM_SIMP_TAC[INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
14679   SUBGOAL_THEN `interval[u:real^1,v] SUBSET interval[a,b]` MP_TAC THENL
14680    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
14681   ASM_REWRITE_TAC[SUBSET_INTERVAL_1; GSYM REAL_NOT_LE] THEN
14682   STRIP_TAC THEN
14683   GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [REAL_MUL_SYM] THEN
14684   CONJ_TAC THEN MATCH_MP_TAC REAL_LE_RMUL THEN REWRITE_TAC[NORM_POS_LE] THEN
14685   MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
14686   REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC);;
14687
14688 let VECTOR_VARIATION_POS_LE = prove
14689  (`!f:real^1->real^N s.
14690         f has_bounded_variation_on s ==> &0 <= vector_variation s f`,
14691   REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN
14692   REWRITE_TAC[SET_VARIATION_POS_LE]);;
14693
14694 let VECTOR_VARIATION_GE_NORM_FUNCTION = prove
14695  (`!f:real^1->real^N s a b.
14696         f has_bounded_variation_on s /\ segment[a,b] SUBSET s
14697         ==> norm(f b - f a) <= vector_variation s f`,
14698   REWRITE_TAC[FORALL_LIFT] THEN GEN_TAC THEN GEN_TAC THEN
14699   MATCH_MP_TAC REAL_WLOG_LE THEN CONJ_TAC THENL
14700    [MESON_TAC[SEGMENT_SYM; NORM_SUB]; ALL_TAC] THEN
14701   REWRITE_TAC[FORALL_DROP; LIFT_DROP; has_bounded_variation_on] THEN
14702   REPEAT STRIP_TAC THEN MP_TAC(ISPECL
14703   [`\k. (f:real^1->real^N)(interval_upperbound k) - f(interval_lowerbound k)`;
14704    `s:real^1->bool`; `a:real^1`; `b:real^1`] SET_VARIATION_GE_FUNCTION) THEN
14705   ASM_REWRITE_TAC[vector_variation; INTERVAL_NE_EMPTY_1] THEN
14706   ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1] THEN
14707   ASM_MESON_TAC[SEGMENT_1]);;
14708
14709 let VECTOR_VARIATION_GE_DROP_FUNCTION = prove
14710  (`!f s a b.
14711         f has_bounded_variation_on s /\ segment[a,b] SUBSET s
14712         ==> drop(f b) - drop(f a) <= vector_variation s f`,
14713   REPEAT STRIP_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
14714   EXISTS_TAC `norm((f:real^1->real^1) b - f a)` THEN
14715   ASM_SIMP_TAC[VECTOR_VARIATION_GE_NORM_FUNCTION] THEN
14716   REWRITE_TAC[NORM_REAL; DROP_SUB; GSYM drop] THEN REAL_ARITH_TAC);;
14717
14718 let VECTOR_VARIATION_CONST_EQ = prove
14719  (`!f:real^1->real^N s.
14720         is_interval s /\ f has_bounded_variation_on s
14721         ==> (vector_variation s f = &0 <=> ?c. !x. x IN s ==> f x = c)`,
14722   REPEAT STRIP_TAC THEN EQ_TAC THENL
14723    [DISCH_TAC THEN REWRITE_TAC[MESON[]
14724      `(?c. !x. P x ==> f x = c) <=> !a b. P a /\ P b ==> f a = f b`] THEN
14725     MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`] THEN STRIP_TAC THEN
14726     MP_TAC(ISPECL [`f:real^1->real^N`; `s:real^1->bool`;
14727         `a:real^1`; `b:real^1`] VECTOR_VARIATION_GE_NORM_FUNCTION) THEN
14728     ANTS_TAC THENL
14729      [ASM_MESON_TAC[IS_INTERVAL_CONVEX_1; CONVEX_CONTAINS_SEGMENT];
14730       ASM_REWRITE_TAC[] THEN CONV_TAC NORM_ARITH];
14731     DISCH_THEN(X_CHOOSE_TAC `c:real^N`) THEN
14732     MP_TAC(ISPECL [`f:real^1->real^N`; `(\x. c):real^1->real^N`;
14733                    `s:real^1->bool`] VECTOR_VARIATION_EQ) THEN
14734     ASM_SIMP_TAC[VECTOR_VARIATION_CONST]]);;
14735
14736 let VECTOR_VARIATION_MONOTONE = prove
14737  (`!f s t. f has_bounded_variation_on s /\ t SUBSET s
14738            ==> vector_variation t f <= vector_variation s f`,
14739   REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN
14740   REWRITE_TAC[SET_VARIATION_MONOTONE]);;
14741
14742 let VECTOR_VARIATION_NEG = prove
14743  (`!f:real^1->real^N s.
14744         vector_variation s (\x. --(f x)) = vector_variation s f`,
14745   REPEAT GEN_TAC THEN REWRITE_TAC[vector_variation; set_variation] THEN
14746   REWRITE_TAC[NORM_ARITH `norm(--x - --y:real^N) = norm(x - y)`]);;
14747
14748 let VECTOR_VARIATION_TRIANGLE = prove
14749  (`!f g:real^1->real^N s.
14750         f has_bounded_variation_on s /\ g has_bounded_variation_on s
14751         ==> vector_variation s (\x. f x + g x)
14752               <= vector_variation s f + vector_variation s g`,
14753   REPEAT GEN_TAC THEN
14754   REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN
14755   DISCH_THEN(MP_TAC o MATCH_MP SET_VARIATION_TRIANGLE) THEN
14756   REWRITE_TAC[VECTOR_ARITH `(a + b) - (c + d):real^N = (a - c) + (b - d)`]);;
14757
14758 let OPERATIVE_FUNCTION_ENDPOINT_DIFF = prove
14759  (`!f:real^1->real^N.
14760     operative (+) (\k. f (interval_upperbound k) - f (interval_lowerbound k))`,
14761   GEN_TAC THEN
14762   SIMP_TAC[operative; INTERVAL_BOUNDS_NULL_1; VECTOR_SUB_REFL] THEN
14763   REWRITE_TAC[NEUTRAL_VECTOR_ADD; DIMINDEX_1; FORALL_1; GSYM drop] THEN
14764   REWRITE_TAC[FORALL_DROP] THEN
14765   MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`; `c:real^1`] THEN
14766   ASM_CASES_TAC `interval[a:real^1,b] = {}` THENL
14767    [ASM_REWRITE_TAC[INTER_EMPTY; INTERVAL_BOUNDS_EMPTY_1] THEN
14768     VECTOR_ARITH_TAC;
14769     ALL_TAC] THEN
14770   ASM_CASES_TAC `interval[a,b] INTER {x | drop x <= drop c} = {}` THENL
14771    [ASM_REWRITE_TAC[INTERVAL_BOUNDS_EMPTY_1; VECTOR_SUB_REFL] THEN
14772     SUBGOAL_THEN `interval[a,b] INTER {x | drop x >= drop c} = interval[a,b]`
14773      (fun th -> REWRITE_TAC[th; VECTOR_ADD_LID]) THEN
14774     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
14775      `i INTER s = {} ==> s UNION t = UNIV ==> i INTER t = i`)) THEN
14776     REWRITE_TAC[EXTENSION; IN_UNIV; IN_UNION; IN_ELIM_THM] THEN
14777     REAL_ARITH_TAC;
14778     ALL_TAC] THEN
14779   ASM_CASES_TAC `interval[a,b] INTER {x | drop x >= drop c} = {}` THENL
14780    [ASM_REWRITE_TAC[INTERVAL_BOUNDS_EMPTY_1; VECTOR_SUB_REFL] THEN
14781     SUBGOAL_THEN `interval[a,b] INTER {x | drop x <= drop c} = interval[a,b]`
14782      (fun th -> REWRITE_TAC[th; VECTOR_ADD_RID]) THEN
14783     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
14784      `i INTER s = {} ==> s UNION t = UNIV ==> i INTER t = i`)) THEN
14785     REWRITE_TAC[EXTENSION; IN_UNIV; IN_UNION; IN_ELIM_THM] THEN
14786     REAL_ARITH_TAC;
14787     ALL_TAC] THEN
14788   POP_ASSUM_LIST(MP_TAC o end_itlist CONJ) THEN
14789   SIMP_TAC[INTERVAL_SPLIT; drop; DIMINDEX_1; LE_REFL] THEN
14790   REWRITE_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN
14791   SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1] THEN
14792   SIMP_TAC[drop; LAMBDA_BETA; DIMINDEX_1; LE_REFL] THEN STRIP_TAC THEN
14793   MATCH_MP_TAC(VECTOR_ARITH
14794    `fx:real^N = fy ==> fb - fa = fx - fa + fb - fy`) THEN
14795   AP_TERM_TAC THEN REWRITE_TAC[GSYM DROP_EQ; drop] THEN
14796   SIMP_TAC[LAMBDA_BETA; DIMINDEX_1; LE_REFL] THEN ASM_REAL_ARITH_TAC);;
14797
14798 let OPERATIVE_REAL_FUNCTION_ENDPOINT_DIFF = prove
14799  (`!f:real^1->real.
14800     operative (+) (\k. f (interval_upperbound k) - f (interval_lowerbound k))`,
14801   GEN_TAC THEN
14802   MP_TAC(ISPEC `lift o (f:real^1->real)` OPERATIVE_FUNCTION_ENDPOINT_DIFF) THEN
14803   REWRITE_TAC[operative; NEUTRAL_REAL_ADD; NEUTRAL_VECTOR_ADD] THEN
14804   REWRITE_TAC[o_THM; GSYM LIFT_SUB; GSYM LIFT_ADD; GSYM LIFT_NUM] THEN
14805   REWRITE_TAC[LIFT_EQ]);;
14806
14807 let OPERATIVE_LIFTED_VECTOR_VARIATION = prove
14808  (`!f:real^1->real^N.
14809         operative (lifted(+))
14810                   (\i. if f has_bounded_variation_on i
14811                        then SOME(vector_variation i f) else NONE)`,
14812   GEN_TAC THEN REWRITE_TAC[has_bounded_variation_on; vector_variation] THEN
14813   MATCH_MP_TAC OPERATIVE_LIFTED_SETVARIATION THEN
14814   REWRITE_TAC[OPERATIVE_FUNCTION_ENDPOINT_DIFF]);;
14815
14816 let HAS_BOUNDED_VARIATION_ON_DIVISION = prove
14817  (`!f:real^1->real^N a b d.
14818         d division_of interval[a,b]
14819         ==> ((!k. k IN d ==> f has_bounded_variation_on k) <=>
14820              f has_bounded_variation_on interval[a,b])`,
14821   REPEAT STRIP_TAC THEN REWRITE_TAC[has_bounded_variation_on] THEN
14822   MATCH_MP_TAC HAS_BOUNDED_SETVARIATION_ON_DIVISION THEN
14823   ASM_REWRITE_TAC[OPERATIVE_FUNCTION_ENDPOINT_DIFF]);;
14824
14825 let VECTOR_VARIATION_ON_DIVISION = prove
14826  (`!f:real^1->real^N a b d.
14827         d division_of interval[a,b] /\
14828         f has_bounded_variation_on interval[a,b]
14829         ==> sum d (\k. vector_variation k f) =
14830             vector_variation (interval[a,b]) f`,
14831   REPEAT STRIP_TAC THEN REWRITE_TAC[vector_variation] THEN
14832   MATCH_MP_TAC SET_VARIATION_ON_DIVISION THEN
14833   ASM_REWRITE_TAC[OPERATIVE_FUNCTION_ENDPOINT_DIFF; GSYM
14834                   has_bounded_variation_on]);;
14835
14836 let HAS_BOUNDED_VARIATION_ON_COMBINE = prove
14837  (`!f:real^1->real^N a b c.
14838         drop a <= drop c /\ drop c <= drop b
14839         ==> (f has_bounded_variation_on interval[a,b] <=>
14840              f has_bounded_variation_on interval[a,c] /\
14841              f has_bounded_variation_on interval[c,b])`,
14842   REPEAT STRIP_TAC THEN MP_TAC
14843    (ISPEC `f:real^1->real^N` OPERATIVE_LIFTED_VECTOR_VARIATION) THEN
14844   REWRITE_TAC[operative; FORALL_1; FORALL_DROP; DIMINDEX_1] THEN
14845   DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`; `c:real^1`] o
14846    CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN
14847   SUBGOAL_THEN
14848    `interval[a,b] INTER {x:real^1 | x$1 <= drop c} = interval[a,c] /\
14849     interval[a,b] INTER {x:real^1 | x$1 >= drop c} = interval[c,b]`
14850    (fun th -> REWRITE_TAC[th])
14851   THENL
14852    [SIMP_TAC[EXTENSION; IN_INTER; GSYM drop; IN_INTERVAL_1; IN_ELIM_THM] THEN
14853     ASM_REAL_ARITH_TAC;
14854     REPEAT(COND_CASES_TAC THEN
14855            ASM_REWRITE_TAC[distinctness "option"; lifted])]);;
14856
14857 let VECTOR_VARIATION_COMBINE = prove
14858  (`!f:real^1->real^N a b c.
14859         drop a <= drop c /\
14860         drop c <= drop b /\
14861         f has_bounded_variation_on interval[a,b]
14862         ==> vector_variation (interval[a,c]) f +
14863             vector_variation (interval[c,b]) f =
14864             vector_variation (interval[a,b]) f`,
14865   REPEAT STRIP_TAC THEN MP_TAC
14866    (ISPEC `f:real^1->real^N` OPERATIVE_LIFTED_VECTOR_VARIATION) THEN
14867   REWRITE_TAC[operative; FORALL_1; FORALL_DROP; DIMINDEX_1] THEN
14868   DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`; `c:real^1`] o
14869    CONJUNCT2) THEN ASM_REWRITE_TAC[] THEN REPEAT(COND_CASES_TAC THENL
14870     [ALL_TAC;
14871      ASM_MESON_TAC[HAS_BOUNDED_VARIATION_ON_SUBSET; INTER_SUBSET]]) THEN
14872   REWRITE_TAC[lifted; injectivity "option"] THEN DISCH_THEN SUBST1_TAC THEN
14873   SIMP_TAC[INTERVAL_SPLIT; DIMINDEX_1; LE_REFL] THEN
14874   BINOP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
14875   SIMP_TAC[EXTENSION; IN_INTERVAL_1; drop; LAMBDA_BETA;
14876            DIMINDEX_1; LE_REFL] THEN
14877   REWRITE_TAC[GSYM drop] THEN ASM_REAL_ARITH_TAC);;
14878
14879 let VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE = prove
14880  (`!f a b c d.
14881         f has_bounded_variation_on interval[a,b] /\
14882         interval[c,d] SUBSET interval[a,b] /\ ~(interval[c,d] = {})
14883         ==> vector_variation (interval[c,d]) f - drop(f d - f c) <=
14884             vector_variation (interval[a,b]) f - drop(f b - f a)`,
14885   REWRITE_TAC[SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN
14886   REPEAT STRIP_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
14887   SUBGOAL_THEN
14888    `drop(f c) - drop(f a) <= vector_variation(interval[a,c]) f /\
14889     drop(f b) - drop(f d) <= vector_variation(interval[d,b]) f`
14890   MP_TAC THENL
14891    [CONJ_TAC THEN MATCH_MP_TAC VECTOR_VARIATION_GE_DROP_FUNCTION THEN
14892     ASM_REWRITE_TAC[SEGMENT_1; SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1] THEN
14893     (CONJ_TAC THENL [ALL_TAC; ASM_REAL_ARITH_TAC]) THEN
14894     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
14895       HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
14896     REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
14897     ALL_TAC] THEN
14898   REWRITE_TAC[DROP_SUB] THEN
14899   MP_TAC(ISPEC `f:real^1->real^1` VECTOR_VARIATION_COMBINE) THEN
14900   DISCH_THEN(fun th ->
14901     MP_TAC(SPECL [`a:real^1`; `b:real^1`; `d:real^1`] th) THEN
14902     MP_TAC(SPECL [`a:real^1`; `d:real^1`; `c:real^1`] th)) THEN
14903   ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
14904    [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
14905      HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
14906     REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
14907     ASM_REAL_ARITH_TAC]);;
14908
14909 let INCREASING_BOUNDED_VARIATION = prove
14910  (`!f a b.
14911         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
14912                ==> drop(f x) <= drop(f y))
14913         ==> f has_bounded_variation_on interval[a,b]`,
14914   REPEAT STRIP_TAC THEN
14915   ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN
14916   ASM_REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_EMPTY] THEN
14917   REWRITE_TAC[has_bounded_variation_on;
14918               HAS_BOUNDED_SETVARIATION_ON_INTERVAL] THEN
14919   EXISTS_TAC `drop(f b) - drop(f(a:real^1))` THEN
14920   MP_TAC(MATCH_MP (REWRITE_RULE
14921    [TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`]
14922    OPERATIVE_DIVISION) (SPEC `drop o (f:real^1->real^1)`
14923       OPERATIVE_REAL_FUNCTION_ENDPOINT_DIFF)) THEN
14924   MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
14925   DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN
14926   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
14927   ASM_REWRITE_TAC[GSYM sum; MONOIDAL_REAL_ADD] THEN
14928   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
14929   ASM_SIMP_TAC[o_THM; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
14930   DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC REAL_EQ_IMP_LE THEN
14931   MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[NORM_REAL; GSYM drop] THEN
14932   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
14933   MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN
14934   SUBGOAL_THEN `~(interval[u:real^1,v] = {})` ASSUME_TAC THENL
14935    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
14936    RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
14937   ASM_SIMP_TAC[DROP_SUB; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
14938   MATCH_MP_TAC(REAL_ARITH `x <= y ==> abs(y - x) = y - x`) THEN
14939   FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
14940   SUBGOAL_THEN `interval[u:real^1,v] SUBSET interval[a,b]` MP_TAC THENL
14941    [ASM_MESON_TAC[division_of]; REWRITE_TAC[SUBSET_INTERVAL_1]] THEN
14942   ASM_REAL_ARITH_TAC);;
14943
14944 let DECREASING_BOUNDED_VARIATION = prove
14945  (`!f a b.
14946         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
14947                ==> drop(f y) <= drop(f x))
14948          ==> f has_bounded_variation_on interval[a,b]`,
14949   REPEAT GEN_TAC THEN
14950   GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV o BINDER_CONV o RAND_CONV)
14951    [GSYM REAL_LE_NEG2] THEN
14952   REWRITE_TAC[GSYM DROP_NEG] THEN
14953   DISCH_THEN(MP_TAC o MATCH_MP INCREASING_BOUNDED_VARIATION) THEN
14954   DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_ON_NEG) THEN
14955   REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX]);;
14956
14957 let INCREASING_VECTOR_VARIATION = prove
14958  (`!f a b.
14959         ~(interval[a,b] = {}) /\
14960         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
14961                ==> drop(f x) <= drop(f y))
14962         ==> vector_variation (interval[a,b]) f = drop(f b) - drop(f a)`,
14963   REPEAT STRIP_TAC THEN REWRITE_TAC[vector_variation] THEN
14964   REWRITE_TAC[SET_VARIATION_ON_INTERVAL] THEN
14965   SUBGOAL_THEN
14966    `{sum d (\k. norm (f (interval_upperbound k) - f (interval_lowerbound k))) |
14967      d division_of interval[a:real^1,b]} =
14968     {drop (f b) - drop(f a)}`
14969    (fun th -> SIMP_TAC[SUP_INSERT_FINITE; FINITE_EMPTY; th]) THEN
14970   MATCH_MP_TAC(SET_RULE
14971    `(?x. P x) /\ (!x. P x ==> f x = a) ==> {f x | P x} = {a}`) THEN
14972   CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_SELF]; ALL_TAC] THEN
14973   MP_TAC(MATCH_MP (REWRITE_RULE
14974    [TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`]
14975    OPERATIVE_DIVISION) (SPEC `drop o (f:real^1->real^1)`
14976       OPERATIVE_REAL_FUNCTION_ENDPOINT_DIFF)) THEN
14977    MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
14978   DISCH_THEN(MP_TAC o SPECL [`a:real^1`; `b:real^1`]) THEN
14979   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
14980   ASM_REWRITE_TAC[GSYM sum; MONOIDAL_REAL_ADD] THEN
14981   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
14982   ASM_SIMP_TAC[o_THM; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
14983   DISCH_THEN(SUBST1_TAC o SYM) THEN
14984   MATCH_MP_TAC SUM_EQ THEN REWRITE_TAC[NORM_REAL; GSYM drop] THEN
14985   FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
14986   MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN
14987   SUBGOAL_THEN `~(interval[u:real^1,v] = {})` ASSUME_TAC THENL
14988    [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
14989    RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
14990   ASM_SIMP_TAC[DROP_SUB; INTERVAL_LOWERBOUND_1; INTERVAL_UPPERBOUND_1] THEN
14991   MATCH_MP_TAC(REAL_ARITH `x <= y ==> abs(y - x) = y - x`) THEN
14992   FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
14993   SUBGOAL_THEN `interval[u:real^1,v] SUBSET interval[a,b]` MP_TAC THENL
14994    [ASM_MESON_TAC[division_of]; REWRITE_TAC[SUBSET_INTERVAL_1]] THEN
14995   ASM_REAL_ARITH_TAC);;
14996
14997 let DECREASING_VECTOR_VARIATION = prove
14998  (`!f a b.
14999         ~(interval[a,b] = {}) /\
15000         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15001                ==> drop(f y) <= drop(f x))
15002         ==> vector_variation (interval[a,b]) f = drop(f a) - drop(f b)`,
15003   REPEAT GEN_TAC THEN GEN_REWRITE_TAC
15004    (LAND_CONV o RAND_CONV o BINDER_CONV o BINDER_CONV o RAND_CONV)
15005    [GSYM REAL_LE_NEG2] THEN
15006   REWRITE_TAC[GSYM DROP_NEG] THEN
15007   DISCH_THEN(MP_TAC o MATCH_MP INCREASING_VECTOR_VARIATION) THEN
15008   SIMP_TAC[VECTOR_VARIATION_NEG; DROP_NEG] THEN
15009   DISCH_TAC THEN REAL_ARITH_TAC);;
15010
15011 let HAS_BOUNDED_VARIATION_TRANSLATION2_EQ,VECTOR_VARIATION_TRANSLATION2 =
15012  (CONJ_PAIR o prove)
15013  (`(!a f:real^1->real^N s.
15014         (\x. f(a + x)) has_bounded_variation_on (IMAGE (\x. --a + x) s) <=>
15015         f has_bounded_variation_on s) /\
15016    (!a f:real^1->real^N s.
15017         vector_variation (IMAGE (\x. --a + x) s) (\x. f(a + x)) =
15018         vector_variation s f)`,
15019   GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `a:real^1` THEN
15020   MATCH_MP_TAC VARIATION_EQUAL_LEMMA THEN
15021   REWRITE_TAC[] THEN CONJ_TAC THENL [VECTOR_ARITH_TAC; ALL_TAC] THEN
15022   SIMP_TAC[DIVISION_OF_TRANSLATION; GSYM INTERVAL_TRANSLATION]);;
15023
15024 let HAS_BOUNDED_VARIATION_AFFINITY2_EQ,VECTOR_VARIATION_AFFINITY2 =
15025  (CONJ_PAIR o prove)
15026  (`(!m c f:real^1->real^N s.
15027         (\x. f (m % x + c)) has_bounded_variation_on
15028         IMAGE (\x. inv m % x + --(inv m % c)) s <=>
15029         m = &0 \/ f has_bounded_variation_on s) /\
15030    (!m c f:real^1->real^N s.
15031         vector_variation (IMAGE (\x. inv m % x + --(inv m % c)) s)
15032                          (\x. f (m % x + c)) =
15033         if m = &0 then &0 else vector_variation s f)`,
15034   GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `m:real` THEN
15035   GEN_REWRITE_TAC I [AND_FORALL_THM] THEN X_GEN_TAC `c:real^1` THEN
15036   ASM_CASES_TAC `m = &0` THEN ASM_REWRITE_TAC[] THENL
15037    [ASM_REWRITE_TAC[VECTOR_MUL_LZERO; HAS_BOUNDED_VARIATION_ON_CONST] THEN
15038     REWRITE_TAC[VECTOR_VARIATION_CONST];
15039     MATCH_MP_TAC VARIATION_EQUAL_LEMMA THEN
15040     ASM_SIMP_TAC[REWRITE_RULE[FUN_EQ_THM; o_DEF] AFFINITY_INVERSES; I_THM] THEN
15041     ASM_SIMP_TAC[IMAGE_AFFINITY_INTERVAL] THEN
15042     ASM_REWRITE_TAC[DIVISION_OF_AFFINITY; REAL_INV_EQ_0] THEN
15043     MESON_TAC[]]);;
15044
15045 let HAS_BOUNDED_VARIATION_AFFINITY_EQ,VECTOR_VARIATION_AFFINITY =
15046  (CONJ_PAIR o prove)
15047  (`(!m c f:real^1->real^N s.
15048         (\x. f(m % x + c)) has_bounded_variation_on s <=>
15049         m = &0 \/ f has_bounded_variation_on (IMAGE (\x. m % x + c) s)) /\
15050    (!m c f:real^1->real^N s.
15051         vector_variation s (\x. f(m % x + c)) =
15052         if m = &0 then &0 else vector_variation (IMAGE (\x. m % x + c) s) f)`,
15053   REWRITE_TAC[AND_FORALL_THM] THEN REPEAT GEN_TAC THEN
15054   ASM_CASES_TAC `m = &0` THEN
15055   ASM_REWRITE_TAC[VECTOR_MUL_LZERO; HAS_BOUNDED_VARIATION_ON_CONST;
15056                   VECTOR_VARIATION_CONST] THEN
15057   CONJ_TAC THENL
15058    [MP_TAC(ISPECL[`m:real`; `c:real^1`; `f:real^1->real^N`;
15059                   `IMAGE (\x:real^1. m % x + c) s`]
15060           HAS_BOUNDED_VARIATION_AFFINITY2_EQ);
15061     MP_TAC(ISPECL[`m:real`; `c:real^1`; `f:real^1->real^N`;
15062                   `IMAGE (\x:real^1. m % x + c) s`]
15063           VECTOR_VARIATION_AFFINITY2)] THEN
15064   ASM_SIMP_TAC[AFFINITY_INVERSES; GSYM IMAGE_o; IMAGE_I]);;
15065
15066 let HAS_BOUNDED_VARIATION_TRANSLATION_EQ,VECTOR_VARIATION_TRANSLATION =
15067  (CONJ_PAIR o prove)
15068  (`(!a f:real^1->real^N s.
15069         (\x. f(a + x)) has_bounded_variation_on s <=>
15070         f has_bounded_variation_on (IMAGE (\x. a + x) s)) /\
15071    (!a f:real^1->real^N s.
15072         vector_variation s (\x. f(a + x)) =
15073         vector_variation (IMAGE (\x. a + x) s) f)`,
15074   REPEAT STRIP_TAC THENL
15075    [MP_TAC(ISPECL[`a:real^1`; `f:real^1->real^N`; `IMAGE (\x:real^1. a + x) s`]
15076           HAS_BOUNDED_VARIATION_TRANSLATION2_EQ);
15077     MP_TAC(ISPECL[`a:real^1`; `f:real^1->real^N`; `IMAGE (\x:real^1. a + x) s`]
15078           VECTOR_VARIATION_TRANSLATION2)] THEN
15079   REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN
15080   REWRITE_TAC[IMAGE_ID; VECTOR_ARITH `--a + a + x:real^N = x`;
15081               VECTOR_ARITH `a + --a + x:real^N = x`]);;
15082
15083 let HAS_BOUNDED_VARIATION_TRANSLATION_EQ_INTERVAL,
15084     VECTOR_VARIATION_TRANSLATION_INTERVAL =
15085  (CONJ_PAIR o prove)
15086  (`(!a f:real^1->real^N u v.
15087         (\x. f(a + x)) has_bounded_variation_on interval[u,v] <=>
15088         f has_bounded_variation_on interval[a+u,a+v]) /\
15089    (!a f:real^1->real^N u v.
15090         vector_variation (interval[u,v]) (\x. f(a + x)) =
15091         vector_variation (interval[a+u,a+v]) f)`,
15092   REWRITE_TAC[INTERVAL_TRANSLATION; HAS_BOUNDED_VARIATION_TRANSLATION_EQ;
15093               VECTOR_VARIATION_TRANSLATION]);;
15094
15095 let HAS_BOUNDED_VARIATION_TRANSLATION = prove
15096  (`!f:real^1->real^N s a.
15097         f has_bounded_variation_on s
15098         ==> (\x. f(a + x)) has_bounded_variation_on (IMAGE (\x. --a + x) s)`,
15099   REWRITE_TAC[HAS_BOUNDED_VARIATION_TRANSLATION2_EQ]);;
15100
15101 let HAS_BOUNDED_VARIATION_REFLECT2_EQ,VECTOR_VARIATION_REFLECT2 =
15102  (CONJ_PAIR o prove)
15103  (`(!f:real^1->real^N s.
15104         (\x. f(--x)) has_bounded_variation_on (IMAGE (--) s) <=>
15105         f has_bounded_variation_on s) /\
15106    (!f:real^1->real^N s.
15107         vector_variation (IMAGE (--) s) (\x. f(--x)) =
15108         vector_variation s f)`,
15109   MATCH_MP_TAC VARIATION_EQUAL_LEMMA THEN
15110   REWRITE_TAC[] THEN CONJ_TAC THENL [VECTOR_ARITH_TAC; ALL_TAC] THEN
15111   SIMP_TAC[DIVISION_OF_REFLECT; REFLECT_INTERVAL]);;
15112
15113 let HAS_BOUNDED_VARIATION_REFLECT_EQ,VECTOR_VARIATION_REFLECT =
15114  (CONJ_PAIR o prove)
15115  (`(!f:real^1->real^N s.
15116         (\x. f(--x)) has_bounded_variation_on s <=>
15117         f has_bounded_variation_on (IMAGE (--) s)) /\
15118    (!f:real^1->real^N s.
15119         vector_variation s (\x. f(--x)) =
15120         vector_variation (IMAGE (--) s) f)`,
15121   REPEAT STRIP_TAC THENL
15122    [MP_TAC(ISPECL[`f:real^1->real^N`; `IMAGE (--) (s:real^1->bool)`]
15123           HAS_BOUNDED_VARIATION_REFLECT2_EQ);
15124     MP_TAC(ISPECL[`f:real^1->real^N`; `IMAGE (--) (s:real^1->bool)`]
15125           VECTOR_VARIATION_REFLECT2)] THEN
15126   REWRITE_TAC[GSYM IMAGE_o; o_DEF] THEN
15127   REWRITE_TAC[IMAGE_ID; VECTOR_NEG_NEG]);;
15128
15129 let HAS_BOUNDED_VARIATION_REFLECT_EQ_INTERVAL,
15130     VECTOR_VARIATION_REFLECT_INTERVAL =
15131  (CONJ_PAIR o prove)
15132  (`(!f:real^1->real^N u v.
15133         (\x. f(--x)) has_bounded_variation_on interval[u,v] <=>
15134         f has_bounded_variation_on interval[--v,--u]) /\
15135    (!f:real^1->real^N u v.
15136         vector_variation (interval[u,v]) (\x. f(--x)) =
15137         vector_variation (interval[--v,--u]) f)`,
15138   REWRITE_TAC[GSYM REFLECT_INTERVAL; HAS_BOUNDED_VARIATION_REFLECT_EQ;
15139               VECTOR_VARIATION_REFLECT]);;
15140
15141 let HAS_BOUNDED_VARIATION_DARBOUX = prove
15142  (`!f a b.
15143      f has_bounded_variation_on interval[a,b] <=>
15144      ?g h. (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15145                   ==> drop(g x) <= drop(g y)) /\
15146            (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15147                   ==> drop(h x) <= drop(h y)) /\
15148            (!x. f x = g x - h x)`,
15149   REPEAT GEN_TAC THEN EQ_TAC THEN STRIP_TAC THENL
15150    [MAP_EVERY EXISTS_TAC
15151      [`\x:real^1. lift(vector_variation (interval[a,x]) (f:real^1->real^1))`;
15152       `\x:real^1. lift(vector_variation (interval[a,x]) f) - f x`] THEN
15153     REWRITE_TAC[VECTOR_ARITH `a - (a - x):real^1 = x`] THEN
15154     REWRITE_TAC[LIFT_DROP; DROP_SUB] THEN REPEAT STRIP_TAC THENL
15155      [MATCH_MP_TAC VECTOR_VARIATION_MONOTONE;
15156       MATCH_MP_TAC(REAL_ARITH
15157        `!x. a - (b - x) <= c - (d - x) ==> a - b <= c - d`) THEN
15158       EXISTS_TAC `drop(f(a:real^1))` THEN
15159       REWRITE_TAC[GSYM DROP_SUB] THEN
15160       MATCH_MP_TAC VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE] THEN
15161     (CONJ_TAC THENL
15162        [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
15163          HAS_BOUNDED_VARIATION_ON_SUBSET));
15164         ALL_TAC] THEN
15165       RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
15166       REWRITE_TAC[SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1] THEN
15167       ASM_REAL_ARITH_TAC);
15168     GEN_REWRITE_TAC LAND_CONV [GSYM ETA_AX] THEN ASM_REWRITE_TAC[] THEN
15169     MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN
15170     CONJ_TAC THEN MATCH_MP_TAC INCREASING_BOUNDED_VARIATION THEN
15171     ASM_REWRITE_TAC[]]);;
15172
15173 let HAS_BOUNDED_VARIATION_DARBOUX_STRICT = prove
15174  (`!f a b.
15175      f has_bounded_variation_on interval[a,b] <=>
15176      ?g h. (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x < drop y
15177                   ==> drop(g x) < drop(g y)) /\
15178            (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x < drop y
15179                   ==> drop(h x) < drop(h y)) /\
15180            (!x. f x = g x - h x)`,
15181   REPEAT GEN_TAC THEN REWRITE_TAC[HAS_BOUNDED_VARIATION_DARBOUX] THEN
15182   EQ_TAC THEN REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
15183   MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN
15184   STRIP_TAC THENL
15185    [MAP_EVERY EXISTS_TAC [`\x:real^1. g x + x`; `\x:real^1. h x + x`] THEN
15186     ASM_REWRITE_TAC[VECTOR_ARITH `(a + x) - (b + x):real^1 = a - b`] THEN
15187     REPEAT STRIP_TAC THEN REWRITE_TAC[DROP_ADD] THEN
15188     MATCH_MP_TAC REAL_LET_ADD2 THEN ASM_REWRITE_TAC[] THEN
15189     FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[REAL_LT_IMP_LE];
15190     MAP_EVERY EXISTS_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN
15191     ASM_REWRITE_TAC[REAL_LE_LT; DROP_EQ] THEN ASM_MESON_TAC[]]);;
15192
15193 let HAS_BOUNDED_VARIATION_COMPOSE_INCREASING = prove
15194  (`!f g:real^1->real^N a b.
15195         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15196                ==> drop(f x) <= drop(f y)) /\
15197         g has_bounded_variation_on interval[f a,f b]
15198         ==> (g o f) has_bounded_variation_on interval[a,b]`,
15199   REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
15200   ONCE_REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_COMPONENTWISE] THEN
15201   MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `i:num` THEN
15202   DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
15203   ASM_REWRITE_TAC[HAS_BOUNDED_VARIATION_DARBOUX; LEFT_IMP_EXISTS_THM] THEN
15204   MAP_EVERY X_GEN_TAC [`h:real^1->real^1`; `k:real^1->real^1`] THEN
15205   STRIP_TAC THEN
15206   MAP_EVERY EXISTS_TAC [`(h:real^1->real^1) o (f:real^1->real^1)`;
15207                         `(k:real^1->real^1) o (f:real^1->real^1)`] THEN
15208   ASM_REWRITE_TAC[o_THM] THEN
15209   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
15210   REPEAT STRIP_TAC THEN TRY(FIRST_X_ASSUM MATCH_MP_TAC) THEN
15211   ASM_REWRITE_TAC[] THEN
15212   REWRITE_TAC[IN_INTERVAL_1] THEN CONJ_TAC THEN
15213   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[] THEN
15214   RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REWRITE_TAC[] THEN
15215   REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC);;
15216
15217 let HAS_BOUNDED_VARIATION_ON_REFLECT = prove
15218  (`!f:real^1->real^N s.
15219         f has_bounded_variation_on IMAGE (--) s
15220         ==> (\x. f(--x)) has_bounded_variation_on s`,
15221   REPEAT GEN_TAC THEN
15222   REWRITE_TAC[has_bounded_variation_on] THEN
15223   REWRITE_TAC[has_bounded_setvariation_on] THEN
15224   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `B:real` THEN DISCH_TAC THEN
15225   MAP_EVERY X_GEN_TAC [`d:(real^1->bool)->bool`; `t:real^1->bool`] THEN
15226   STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL
15227    [`IMAGE (IMAGE (--)) (d:(real^1->bool)->bool)`;
15228     `IMAGE (--) (t:real^1->bool)`]) THEN
15229   ASM_SIMP_TAC[DIVISION_OF_REFLECT] THEN
15230   REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
15231   ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
15232   ASM_REWRITE_TAC[GSYM SUBSET] THEN
15233   W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o lhand o lhand o snd) THEN
15234   ANTS_TAC THENL
15235    [MESON_TAC[VECTOR_ARITH `--x:real^N = --y <=> x = y`; INJECTIVE_IMAGE];
15236     DISCH_THEN SUBST1_TAC THEN
15237     MATCH_MP_TAC(REAL_ARITH `x = y ==> x <= d ==> y <= d`) THEN
15238     MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th ->
15239       GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION th]) THEN
15240     MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN
15241     SUBGOAL_THEN `drop u <= drop v` ASSUME_TAC THENL
15242      [ASM_MESON_TAC[INTERVAL_NE_EMPTY_1; division_of]; ALL_TAC] THEN
15243     ASM_REWRITE_TAC[o_THM; REFLECT_INTERVAL] THEN
15244     ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1;
15245                  DROP_NEG; REAL_LE_NEG2] THEN
15246     NORM_ARITH_TAC]);;
15247
15248 let HAS_BOUNDED_VARIATION_ON_REFLECT_INTERVAL = prove
15249  (`!f:real^1->real^N a b.
15250         f has_bounded_variation_on interval[--b,--a]
15251         ==> (\x. f(--x)) has_bounded_variation_on interval[a,b]`,
15252   REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_REFLECT THEN
15253   ASM_REWRITE_TAC[REFLECT_INTERVAL]);;
15254
15255 let VECTOR_VARIATION_REFLECT = prove
15256  (`!f:real^1->real^N s.
15257         vector_variation s (\x. f(--x)) =
15258         vector_variation (IMAGE (--) s) f`,
15259   REPEAT GEN_TAC THEN REWRITE_TAC[vector_variation; set_variation] THEN
15260   AP_TERM_TAC THEN REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
15261   X_GEN_TAC `y:real` THEN EQ_TAC THEN
15262   DISCH_THEN(X_CHOOSE_THEN `d:(real^1->bool)->bool`
15263    (CONJUNCTS_THEN2 MP_TAC SUBST1_TAC)) THEN
15264   DISCH_THEN(X_CHOOSE_THEN `t:real^1->bool` STRIP_ASSUME_TAC) THEN
15265   EXISTS_TAC `IMAGE (IMAGE (--)) (d:(real^1->bool)->bool)` THEN
15266   (CONJ_TAC THENL
15267     [EXISTS_TAC `IMAGE (--) (t:real^1->bool)` THEN
15268      ASM_SIMP_TAC[DIVISION_OF_REFLECT] THEN
15269      ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE] THEN
15270      RULE_ASSUM_TAC(REWRITE_RULE[SUBSET; IN_IMAGE]) THEN
15271      ASM_MESON_TAC[VECTOR_NEG_NEG; IN_IMAGE];
15272      ALL_TAC]) THEN
15273   W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE o rand o snd) THEN
15274   (ANTS_TAC THENL
15275    [MESON_TAC[VECTOR_ARITH `--x:real^N = --y <=> x = y`; INJECTIVE_IMAGE];
15276     DISCH_THEN SUBST1_TAC]) THEN
15277   MATCH_MP_TAC SUM_EQ THEN FIRST_ASSUM(fun th ->
15278     GEN_REWRITE_TAC I [MATCH_MP FORALL_IN_DIVISION th]) THEN
15279   MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN DISCH_TAC THEN
15280   (SUBGOAL_THEN `drop u <= drop v` ASSUME_TAC THENL
15281    [ASM_MESON_TAC[INTERVAL_NE_EMPTY_1; division_of]; ALL_TAC]) THEN
15282   ASM_REWRITE_TAC[o_THM; REFLECT_INTERVAL] THEN
15283   ASM_SIMP_TAC[INTERVAL_UPPERBOUND_1; INTERVAL_LOWERBOUND_1;
15284                DROP_NEG; REAL_LE_NEG2; VECTOR_NEG_NEG] THEN
15285   NORM_ARITH_TAC);;
15286
15287 let VECTOR_VARIATION_REFLECT_INTERVAL = prove
15288  (`!f:real^1->real^N a b.
15289         vector_variation (interval[a,b]) (\x. f(--x)) =
15290         vector_variation (interval[--b,--a]) f`,
15291   REWRITE_TAC[VECTOR_VARIATION_REFLECT; REFLECT_INTERVAL]);;
15292
15293 let HAS_BOUNDED_VARIATION_COMPOSE_DECREASING = prove
15294  (`!f g:real^1->real^N a b.
15295         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15296                ==> drop(f y) <= drop(f x)) /\
15297         g has_bounded_variation_on interval[f b,f a]
15298         ==> (g o f) has_bounded_variation_on interval[a,b]`,
15299   REPEAT GEN_TAC THEN
15300   DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
15301   DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[VECTOR_NEG_NEG]
15302     (ISPECL [`f:real^1->real^N`; `--b:real^1`; `--a:real^1`]
15303         HAS_BOUNDED_VARIATION_ON_REFLECT_INTERVAL))) THEN
15304   POP_ASSUM MP_TAC THEN
15305   GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV o BINDER_CONV o RAND_CONV)
15306    [GSYM REAL_LE_NEG2] THEN
15307   REWRITE_TAC[GSYM DROP_NEG; IMP_IMP] THEN
15308   DISCH_THEN(MP_TAC o MATCH_MP HAS_BOUNDED_VARIATION_COMPOSE_INCREASING) THEN
15309   REWRITE_TAC[o_DEF; VECTOR_NEG_NEG]);;
15310
15311 let HAS_BOUNDED_VARIATION_ON_ID = prove
15312  (`!a b. (\x. x) has_bounded_variation_on interval[a,b]`,
15313   REPEAT GEN_TAC THEN MATCH_MP_TAC INCREASING_BOUNDED_VARIATION THEN
15314   SIMP_TAC[]);;
15315
15316 let HAS_BOUNDED_VARIATION_ON_LINEAR_IMAGE = prove
15317  (`!f:real^1->real^1 g:real^1->real^N a b.
15318         linear f /\ g has_bounded_variation_on IMAGE f (interval[a,b])
15319         ==> (g o f) has_bounded_variation_on interval[a,b]`,
15320   REPEAT STRIP_TAC THEN
15321   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LINEAR_1]) THEN
15322   DISCH_THEN(X_CHOOSE_THEN `c:real` SUBST_ALL_TAC) THEN
15323   REPEAT_TCL DISJ_CASES_THEN ASSUME_TAC (REAL_ARITH
15324    `c = &0 \/ &0 <= c /\ &0 < c \/ ~(&0 <= c) /\ &0 < --c`)
15325   THENL
15326    [ASM_REWRITE_TAC[o_DEF; VECTOR_MUL_LZERO; HAS_BOUNDED_VARIATION_ON_CONST];
15327     MATCH_MP_TAC HAS_BOUNDED_VARIATION_COMPOSE_INCREASING THEN
15328     REWRITE_TAC[DROP_CMUL];
15329     MATCH_MP_TAC HAS_BOUNDED_VARIATION_COMPOSE_DECREASING THEN
15330     REWRITE_TAC[DROP_CMUL] THEN
15331     ONCE_REWRITE_TAC[REAL_ARITH `c * y <= c * x <=> --c * x <= --c * y`]] THEN
15332   ASM_SIMP_TAC[REAL_LE_LMUL; REAL_LT_IMP_LE] THEN
15333   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP(MESON[]
15334    `g has_bounded_variation_on s
15335     ==> s = t ==> g has_bounded_variation_on t`)) THEN
15336   ONCE_REWRITE_TAC[VECTOR_ARITH `c % x:real^N = c % x + vec 0`] THEN
15337   ASM_REWRITE_TAC[IMAGE_AFFINITY_INTERVAL] THEN
15338   COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_ADD_RID] THEN
15339   CONV_TAC SYM_CONV THEN REWRITE_TAC[INTERVAL_EQ_EMPTY_1; DROP_CMUL] THENL
15340    [ALL_TAC;
15341    ONCE_REWRITE_TAC[REAL_ARITH `c * y < c * x <=> --c * x < --c * y`]] THEN
15342   MATCH_MP_TAC REAL_LT_LMUL THEN
15343   ASM_REWRITE_TAC[GSYM INTERVAL_EQ_EMPTY_1]);;
15344
15345 let INCREASING_LEFT_LIMIT_1 = prove
15346  (`!f a b c.
15347         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15348                ==> drop(f x) <= drop(f y)) /\
15349         c IN interval[a,b]
15350        ==> ?l. (f --> l) (at c within interval[a,c])`,
15351   REPEAT STRIP_TAC THEN EXISTS_TAC
15352    `lift(sup {drop(f x) | x IN interval[a,b] /\ drop x < drop c})` THEN
15353   ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN REWRITE_TAC[LIM_WITHIN] THEN
15354   REWRITE_TAC[DIST_REAL; GSYM drop] THEN
15355   ASM_CASES_TAC `{x | x IN interval[a,b] /\ drop x < drop c} = {}` THENL
15356    [GEN_TAC THEN DISCH_TAC THEN EXISTS_TAC `&1` THEN
15357     REWRITE_TAC[REAL_LT_01] THEN
15358     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
15359     MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC(TAUT
15360      `(a ==> ~b) ==> a ==> b ==> c`) THEN
15361     REWRITE_TAC[NOT_IN_EMPTY; IN_ELIM_THM; IN_INTERVAL_1] THEN
15362     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
15363     ALL_TAC] THEN
15364   X_GEN_TAC `e:real` THEN DISCH_TAC THEN
15365   MP_TAC(ISPEC `{drop(f x) | x IN interval[a,b] /\ drop x < drop c}` SUP) THEN
15366   ASM_REWRITE_TAC[FORALL_IN_GSPEC] THEN ANTS_TAC THENL
15367    [CONJ_TAC THENL
15368      [ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN ASM_SIMP_TAC[IMAGE_EQ_EMPTY];
15369       EXISTS_TAC `drop(f(b:real^1))` THEN REPEAT STRIP_TAC THEN
15370       FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
15371       RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC];
15372     ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN REWRITE_TAC[IMAGE_ID] THEN
15373     ABBREV_TAC `s = sup (IMAGE (\x. drop(f x))
15374                         {x | x IN interval[a,b] /\ drop x < drop c})` THEN
15375     REWRITE_TAC[LIFT_DROP] THEN
15376     DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC `s - e:real`)) THEN
15377     ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(s <= s - e)`; NOT_FORALL_THM] THEN
15378     REWRITE_TAC[NOT_IMP; REAL_NOT_LE; IN_INTERVAL_1] THEN
15379     DISCH_THEN(X_CHOOSE_THEN `d:real^1` STRIP_ASSUME_TAC) THEN
15380     EXISTS_TAC `drop c - drop d` THEN
15381     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
15382     CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
15383     X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN
15384     FIRST_X_ASSUM(MP_TAC o SPECL [`d:real^1`; `x:real^1`]) THEN
15385     FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN ASM_REAL_ARITH_TAC]);;
15386
15387 let DECREASING_LEFT_LIMIT_1 = prove
15388  (`!f a b c.
15389         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15390                ==> drop(f y) <= drop(f x)) /\
15391         c IN interval[a,b]
15392         ==> ?l. (f --> l) (at c within interval[a,c])`,
15393   REPEAT STRIP_TAC THEN
15394   MP_TAC(ISPECL
15395    [`\x. --((f:real^1->real^1) x)`; `a:real^1`; `b:real^1`; `c:real^1`]
15396         INCREASING_LEFT_LIMIT_1) THEN
15397   ASM_REWRITE_TAC[REAL_LE_NEG2; DROP_NEG] THEN
15398   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM LIM_NEG_EQ] THEN
15399   REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX] THEN MESON_TAC[]);;
15400
15401 let INCREASING_RIGHT_LIMIT_1 = prove
15402  (`!f a b c.
15403         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15404                ==> drop(f x) <= drop(f y)) /\
15405         c IN interval[a,b]
15406        ==> ?l. (f --> l) (at c within interval[c,b])`,
15407   REPEAT STRIP_TAC THEN
15408   MP_TAC(ISPECL [`\x. (f:real^1->real^1) (--x)`;
15409                  `--b:real^1`; `--a:real^1`; `--c:real^1`]
15410         DECREASING_LEFT_LIMIT_1) THEN
15411   ASM_REWRITE_TAC[IN_INTERVAL_REFLECT] THEN
15412   ONCE_REWRITE_TAC[MESON[VECTOR_NEG_NEG]
15413    `(!x:real^1 y:real^1. P x y) <=> (!x y. P (--x) (--y))`] THEN
15414   REWRITE_TAC[DROP_NEG; IN_INTERVAL_REFLECT; VECTOR_NEG_NEG] THEN
15415   ASM_SIMP_TAC[REAL_LE_NEG2] THEN MATCH_MP_TAC MONO_EXISTS THEN
15416   X_GEN_TAC `l:real^1` THEN REWRITE_TAC[LIM_WITHIN] THEN
15417   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
15418    [MESON[VECTOR_NEG_NEG] `(!x:real^1. P x) <=> (!x. P (--x))`] THEN
15419   REWRITE_TAC[IN_INTERVAL_REFLECT; VECTOR_NEG_NEG;
15420               NORM_ARITH `dist(--x:real^1,--y) = dist(x,y)`]);;
15421
15422 let DECREASING_RIGHT_LIMIT_1 = prove
15423  (`!f a b c.
15424         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15425                ==> drop(f y) <= drop(f x)) /\
15426         c IN interval[a,b]
15427        ==> ?l. (f --> l) (at c within interval[c,b])`,
15428   REPEAT STRIP_TAC THEN
15429   MP_TAC(ISPECL
15430    [`\x. --((f:real^1->real^1) x)`; `a:real^1`; `b:real^1`; `c:real^1`]
15431         INCREASING_RIGHT_LIMIT_1) THEN
15432   ASM_REWRITE_TAC[REAL_LE_NEG2; DROP_NEG] THEN
15433   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [GSYM LIM_NEG_EQ] THEN
15434   REWRITE_TAC[VECTOR_NEG_NEG; ETA_AX] THEN MESON_TAC[]);;
15435
15436 let HAS_BOUNDED_VECTOR_VARIATION_LEFT_LIMIT = prove
15437  (`!f:real^1->real^N a b c.
15438         f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b]
15439         ==> ?l. (f --> l) (at c within interval[a,c])`,
15440   ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT;
15441                    HAS_BOUNDED_VARIATION_ON_COMPONENTWISE] THEN
15442   REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
15443   X_GEN_TAC `i:num` THEN STRIP_TAC THEN
15444   FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
15445   SPEC_TAC(`\x. lift((f:real^1->real^N)x$i)`,`f:real^1->real^1`) THEN
15446   UNDISCH_TAC `(c:real^1) IN interval[a,b]` THEN POP_ASSUM_LIST(K ALL_TAC) THEN
15447   REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM EXISTS_LIFT] THEN
15448   FIRST_X_ASSUM
15449    (MP_TAC o GEN_REWRITE_RULE I [HAS_BOUNDED_VARIATION_DARBOUX]) THEN
15450   REWRITE_TAC[LEFT_IMP_EXISTS_THM; CONJ_ASSOC] THEN REPEAT GEN_TAC THEN
15451   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
15452   REWRITE_TAC[GSYM CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN
15453    (MP_TAC o SPEC `c:real^1` o MATCH_MP
15454      (ONCE_REWRITE_RULE[IMP_CONJ] INCREASING_LEFT_LIMIT_1))) THEN
15455   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
15456   X_GEN_TAC `l2:real^1` THEN DISCH_TAC THEN
15457   X_GEN_TAC `l1:real^1` THEN DISCH_TAC THEN
15458   EXISTS_TAC `l1 - l2:real^1` THEN
15459   GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
15460   ASM_SIMP_TAC[LIM_SUB]);;
15461
15462 let HAS_BOUNDED_VECTOR_VARIATION_RIGHT_LIMIT = prove
15463  (`!f:real^1->real^N a b c.
15464         f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b]
15465         ==> ?l. (f --> l) (at c within interval[c,b])`,
15466   ONCE_REWRITE_TAC[LIM_COMPONENTWISE_LIFT;
15467                    HAS_BOUNDED_VARIATION_ON_COMPONENTWISE] THEN
15468   REWRITE_TAC[GSYM LAMBDA_SKOLEM] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
15469   X_GEN_TAC `i:num` THEN STRIP_TAC THEN
15470   FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
15471   SPEC_TAC(`\x. lift((f:real^1->real^N)x$i)`,`f:real^1->real^1`) THEN
15472   UNDISCH_TAC `(c:real^1) IN interval[a,b]` THEN POP_ASSUM_LIST(K ALL_TAC) THEN
15473   REPEAT STRIP_TAC THEN REWRITE_TAC[GSYM EXISTS_LIFT] THEN
15474   FIRST_X_ASSUM
15475    (MP_TAC o GEN_REWRITE_RULE I [HAS_BOUNDED_VARIATION_DARBOUX]) THEN
15476   REWRITE_TAC[LEFT_IMP_EXISTS_THM; CONJ_ASSOC] THEN REPEAT GEN_TAC THEN
15477   DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
15478   REWRITE_TAC[GSYM CONJ_ASSOC] THEN DISCH_THEN(CONJUNCTS_THEN
15479    (MP_TAC o SPEC `c:real^1` o MATCH_MP
15480      (ONCE_REWRITE_RULE[IMP_CONJ] INCREASING_RIGHT_LIMIT_1))) THEN
15481   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
15482   X_GEN_TAC `l2:real^1` THEN DISCH_TAC THEN
15483   X_GEN_TAC `l1:real^1` THEN DISCH_TAC THEN
15484   EXISTS_TAC `l1 - l2:real^1` THEN
15485   GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
15486   ASM_SIMP_TAC[LIM_SUB]);;
15487
15488 let VECTOR_VARIATION_CONTINUOUS_LEFT = prove
15489  (`!f:real^1->real^1 a b c.
15490         f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b]
15491         ==> ((\x. lift(vector_variation(interval[a,x]) f))
15492              continuous (at c within interval[a,c]) <=>
15493             f continuous (at c within interval[a,c]))`,
15494   REPEAT STRIP_TAC THEN EQ_TAC THENL
15495    [REWRITE_TAC[continuous_within] THEN
15496     REWRITE_TAC[DIST_LIFT; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN
15497     DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
15498     FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
15499     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN
15500     ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN
15501     FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN ASM_REWRITE_TAC[] THEN
15502     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN
15503     REWRITE_TAC[GSYM DROP_SUB] THEN
15504     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `c:real^1`; `x:real^1`]
15505         VECTOR_VARIATION_COMBINE) THEN
15506     ANTS_TAC THENL
15507      [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
15508       REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
15509       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
15510          HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
15511       REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
15512       ALL_TAC] THEN
15513     DISCH_THEN(SUBST1_TAC o SYM) THEN
15514     REWRITE_TAC[REAL_ARITH `abs(a - (a + b)) = abs b`] THEN
15515     REWRITE_TAC[drop; GSYM NORM_REAL] THEN
15516     MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs a`) THEN
15517     ONCE_REWRITE_TAC[NORM_SUB] THEN
15518     MATCH_MP_TAC VECTOR_VARIATION_GE_NORM_FUNCTION THEN CONJ_TAC THENL
15519      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
15520         HAS_BOUNDED_VARIATION_ON_SUBSET));
15521       REWRITE_TAC[SEGMENT_1] THEN COND_CASES_TAC] THEN
15522     REWRITE_TAC[SUBSET_INTERVAL_1] THEN
15523     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
15524     ALL_TAC] THEN
15525   DISCH_TAC THEN ASM_CASES_TAC `c limit_point_of interval[a:real^1,c]` THENL
15526    [ALL_TAC;
15527     ASM_REWRITE_TAC[CONTINUOUS_WITHIN; LIM; TRIVIAL_LIMIT_WITHIN]] THEN
15528   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HAS_BOUNDED_VARIATION_DARBOUX]) THEN
15529   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
15530   MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN
15531   STRIP_TAC THEN
15532   MP_TAC(ISPECL [`h:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`]
15533    INCREASING_LEFT_LIMIT_1) THEN
15534   MP_TAC(ISPECL [`g:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`]
15535    INCREASING_LEFT_LIMIT_1) THEN
15536   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
15537   X_GEN_TAC `gc:real^1` THEN DISCH_TAC THEN
15538   X_GEN_TAC `hc:real^1` THEN DISCH_TAC THEN
15539   ABBREV_TAC `k = gc - (g:real^1->real^1) c` THEN
15540   SUBGOAL_THEN `hc - (h:real^1->real^1) c = k` ASSUME_TAC THENL
15541    [EXPAND_TAC "k" THEN
15542     ONCE_REWRITE_TAC[VECTOR_ARITH
15543      `hc' - hc:real^1 = gc' - gc <=> gc' - hc' = gc - hc`] THEN
15544     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_WITHIN]) THEN
15545     ASM_REWRITE_TAC[] THEN
15546     MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
15547       LIM_UNIQUE) THEN
15548     ASM_REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN
15549     GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
15550     ASM_SIMP_TAC[LIM_SUB];
15551     ALL_TAC] THEN
15552   MAP_EVERY ABBREV_TAC
15553    [`g':real^1->real^1 = \x. if drop c <= drop x then g(x) + k else g(x)`;
15554     `h':real^1->real^1 = \x. if drop c <= drop x then h(x) + k else h(x)`] THEN
15555   SUBGOAL_THEN
15556    `(!x y. x IN interval[a,c] /\ y IN interval[a,c] /\ drop x <= drop y
15557            ==> drop(g' x) <= drop(g' y)) /\
15558     (!x y. x IN interval[a,c] /\ y IN interval[a,c] /\ drop x <= drop y
15559            ==> drop(h' x) <= drop(h' y))`
15560   STRIP_ASSUME_TAC THENL
15561    [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN REWRITE_TAC[] THEN CONJ_TAC THEN
15562     MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN
15563     REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN
15564     (ASM_CASES_TAC `drop c <= drop x` THENL
15565       [SUBGOAL_THEN `drop c <= drop y` ASSUME_TAC THENL
15566         [ASM_REAL_ARITH_TAC; ASM_REWRITE_TAC[]] THEN
15567        REWRITE_TAC[DROP_ADD; REAL_LE_RADD] THEN
15568        FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
15569        RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
15570        ALL_TAC] THEN
15571      ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
15572       [ALL_TAC;
15573        FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
15574        RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC] THEN
15575      SUBGOAL_THEN `y:real^1 = c` SUBST_ALL_TAC THENL
15576       [REWRITE_TAC[GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN
15577      FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[]
15578       `gc - g c = k
15579        ==> b <= drop(g c + (gc - g c)) ==> b <= drop(g c + k)`)) THEN
15580      REWRITE_TAC[VECTOR_ARITH `a + b - a:real^1 = b`] THEN
15581      MATCH_MP_TAC(ISPEC `at c within interval[a:real^1,c]`
15582         LIM_DROP_LBOUND))
15583     THENL [EXISTS_TAC `g:real^1->real^1`; EXISTS_TAC `h:real^1->real^1`] THEN
15584     ASM_REWRITE_TAC[TRIVIAL_LIMIT_WITHIN; EVENTUALLY_WITHIN] THEN
15585     EXISTS_TAC `drop c - drop x` THEN
15586     (CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
15587     REWRITE_TAC[DIST_REAL; GSYM drop; IN_INTERVAL_1] THEN
15588     REWRITE_TAC[IN_INTERVAL_1] THEN REPEAT STRIP_TAC THEN
15589     FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
15590     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
15591     ALL_TAC] THEN
15592   SUBGOAL_THEN
15593    `(g':real^1->real^1) continuous (at c within interval[a,c]) /\
15594     (h':real^1->real^1) continuous (at c within interval[a,c])`
15595   MP_TAC THENL
15596    [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN
15597     REWRITE_TAC[CONTINUOUS_WITHIN; REAL_LE_REFL] THEN
15598     RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_ARITH
15599      `g - g':real^1 = k <=> g' + k = g`]) THEN
15600     ASM_REWRITE_TAC[] THEN CONJ_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
15601      (REWRITE_RULE[IMP_CONJ_ALT] LIM_TRANSFORM)) THEN
15602     MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN
15603     REWRITE_TAC[LIM_WITHIN; DIST_REAL; GSYM drop; IN_INTERVAL_1] THEN
15604     SIMP_TAC[REAL_ARITH `x <= c /\ &0 < abs(x - c) ==> ~(c <= x)`] THEN
15605     REWRITE_TAC[VECTOR_SUB_REFL; DROP_VEC; REAL_SUB_REFL; REAL_ABS_NUM] THEN
15606     MESON_TAC[REAL_LT_01];
15607     ALL_TAC] THEN
15608   REWRITE_TAC[continuous_within] THEN
15609   REWRITE_TAC[DIST_LIFT; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN
15610   DISCH_THEN(fun th ->
15611     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
15612     CONJUNCTS_THEN (MP_TAC o SPEC `e / &2`) th) THEN
15613   ASM_REWRITE_TAC[REAL_HALF] THEN
15614   DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN
15615   DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN
15616   EXISTS_TAC `min d1 d2:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
15617   X_GEN_TAC `d:real^1` THEN STRIP_TAC THEN
15618   MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `c:real^1`; `d:real^1`]
15619         VECTOR_VARIATION_COMBINE) THEN
15620   ANTS_TAC THENL
15621    [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
15622     REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
15623     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
15624        HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
15625     REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
15626     DISCH_THEN(SUBST1_TAC o SYM)] THEN
15627   REWRITE_TAC[REAL_ARITH `abs(a - (a + b)) = abs b`] THEN
15628   MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x < a ==> abs x < a`) THEN
15629   CONJ_TAC THENL
15630    [MATCH_MP_TAC VECTOR_VARIATION_POS_LE THEN
15631     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
15632        HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
15633     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
15634     REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
15635     ALL_TAC] THEN
15636   SUBGOAL_THEN `f:real^1->real^1 = \x. g' x - h' x` SUBST1_TAC THENL
15637    [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN REWRITE_TAC[FUN_EQ_THM] THEN
15638     GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC;
15639     ALL_TAC] THEN
15640   MP_TAC(ISPECL
15641    [`g':real^1->real^1`; `\x. --((h':real^1->real^1) x)`;
15642     `interval[d:real^1,c]`] VECTOR_VARIATION_TRIANGLE) THEN
15643   ANTS_TAC THENL
15644    [CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NEG] THEN
15645     MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUBSET THEN
15646     EXISTS_TAC `interval[a:real^1,c]` THEN
15647     ASM_SIMP_TAC[INCREASING_BOUNDED_VARIATION; SUBSET_INTERVAL_1] THEN
15648     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN  ASM_REAL_ARITH_TAC;
15649     ALL_TAC] THEN
15650   REWRITE_TAC[VECTOR_SUB] THEN MATCH_MP_TAC(REAL_ARITH
15651    `y < a / &2 /\ z < a / &2 ==> x <= y + z ==> x < a`) THEN
15652   REWRITE_TAC[VECTOR_VARIATION_NEG] THEN CONJ_TAC THEN
15653   W(MP_TAC o PART_MATCH (lhs o rand)
15654     INCREASING_VECTOR_VARIATION o lhand o snd) THEN
15655   (ANTS_TAC THENL
15656     [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
15657      ASM_REWRITE_TAC[INTERVAL_EQ_EMPTY_1; IN_INTERVAL_1; REAL_NOT_LT] THEN
15658      REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC;
15659      DISCH_THEN SUBST1_TAC]) THEN
15660   MATCH_MP_TAC(REAL_ARITH `abs(x - y) < e ==> y - x < e`) THEN
15661   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]);;
15662
15663 let VECTOR_VARIATION_CONTINUOUS_RIGHT = prove
15664  (`!f:real^1->real^1 a b c.
15665         f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b]
15666         ==> ((\x. lift(vector_variation(interval[a,x]) f))
15667              continuous (at c within interval[c,b]) <=>
15668             f continuous (at c within interval[c,b]))`,
15669   REPEAT STRIP_TAC THEN EQ_TAC THENL
15670    [REWRITE_TAC[continuous_within] THEN
15671     REWRITE_TAC[DIST_LIFT; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN
15672     DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
15673     FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
15674     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN STRIP_TAC THEN
15675     ASM_REWRITE_TAC[] THEN X_GEN_TAC `x:real^1` THEN STRIP_TAC THEN
15676     FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN ASM_REWRITE_TAC[] THEN
15677     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] REAL_LET_TRANS) THEN
15678     REWRITE_TAC[GSYM DROP_SUB] THEN
15679     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `x:real^1`; `c:real^1`]
15680         VECTOR_VARIATION_COMBINE) THEN
15681     ANTS_TAC THENL
15682      [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
15683       REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
15684       FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
15685          HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
15686       REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
15687       ALL_TAC] THEN
15688     DISCH_THEN(SUBST1_TAC o SYM) THEN
15689     REWRITE_TAC[REAL_ARITH `abs((a + b) - a) = abs b`] THEN
15690     REWRITE_TAC[drop; GSYM NORM_REAL] THEN
15691     MATCH_MP_TAC(REAL_ARITH `x <= a ==> x <= abs a`) THEN
15692     MATCH_MP_TAC VECTOR_VARIATION_GE_NORM_FUNCTION THEN CONJ_TAC THENL
15693      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
15694         HAS_BOUNDED_VARIATION_ON_SUBSET));
15695       REWRITE_TAC[SEGMENT_1] THEN COND_CASES_TAC] THEN
15696     REWRITE_TAC[SUBSET_INTERVAL_1] THEN
15697     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
15698     ALL_TAC] THEN
15699   DISCH_TAC THEN ASM_CASES_TAC `c limit_point_of interval[c:real^1,b]` THENL
15700    [ALL_TAC;
15701     ASM_REWRITE_TAC[CONTINUOUS_WITHIN; LIM; TRIVIAL_LIMIT_WITHIN]] THEN
15702   FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [HAS_BOUNDED_VARIATION_DARBOUX]) THEN
15703   REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
15704   MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN
15705   STRIP_TAC THEN
15706   MP_TAC(ISPECL [`h:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`]
15707    INCREASING_RIGHT_LIMIT_1) THEN
15708   MP_TAC(ISPECL [`g:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`]
15709    INCREASING_RIGHT_LIMIT_1) THEN
15710   ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
15711   X_GEN_TAC `gc:real^1` THEN DISCH_TAC THEN
15712   X_GEN_TAC `hc:real^1` THEN DISCH_TAC THEN
15713   ABBREV_TAC `k = gc - (g:real^1->real^1) c` THEN
15714   SUBGOAL_THEN `hc - (h:real^1->real^1) c = k` ASSUME_TAC THENL
15715    [EXPAND_TAC "k" THEN
15716     ONCE_REWRITE_TAC[VECTOR_ARITH
15717      `hc' - hc:real^1 = gc' - gc <=> gc' - hc' = gc - hc`] THEN
15718     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [CONTINUOUS_WITHIN]) THEN
15719     ASM_REWRITE_TAC[] THEN
15720     MATCH_MP_TAC(REWRITE_RULE[TAUT `a /\ b /\ c ==> d <=> a /\ b ==> c ==> d`]
15721       LIM_UNIQUE) THEN
15722     ASM_REWRITE_TAC[TRIVIAL_LIMIT_WITHIN] THEN
15723     GEN_REWRITE_TAC (RATOR_CONV o LAND_CONV) [GSYM ETA_AX] THEN
15724     ASM_SIMP_TAC[LIM_SUB];
15725     ALL_TAC] THEN
15726   MAP_EVERY ABBREV_TAC
15727    [`g':real^1->real^1 = \x. if drop x <= drop c then g(x) + k else g(x)`;
15728     `h':real^1->real^1 = \x. if drop x <= drop c then h(x) + k else h(x)`] THEN
15729   SUBGOAL_THEN
15730    `(!x y. x IN interval[c,b] /\ y IN interval[c,b] /\ drop x <= drop y
15731            ==> drop(g' x) <= drop(g' y)) /\
15732     (!x y. x IN interval[c,b] /\ y IN interval[c,b] /\ drop x <= drop y
15733            ==> drop(h' x) <= drop(h' y))`
15734   STRIP_ASSUME_TAC THENL
15735    [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN REWRITE_TAC[] THEN CONJ_TAC THEN
15736     MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN
15737     REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN
15738     (ASM_CASES_TAC `drop y <= drop c` THENL
15739       [SUBGOAL_THEN `drop x <= drop c` ASSUME_TAC THENL
15740         [ASM_REAL_ARITH_TAC; ASM_REWRITE_TAC[]] THEN
15741        REWRITE_TAC[DROP_ADD; REAL_LE_RADD] THEN
15742        FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
15743        RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
15744        ALL_TAC] THEN
15745      ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
15746       [ALL_TAC;
15747        FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
15748        RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC] THEN
15749      SUBGOAL_THEN `x:real^1 = c` SUBST_ALL_TAC THENL
15750       [REWRITE_TAC[GSYM DROP_EQ] THEN ASM_REAL_ARITH_TAC; ALL_TAC] THEN
15751      FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (MESON[]
15752       `gc - g c = k
15753        ==> drop(g c + (gc - g c)) <= b ==> drop(g c + k) <= b`)) THEN
15754      REWRITE_TAC[VECTOR_ARITH `a + b - a:real^1 = b`] THEN
15755      MATCH_MP_TAC(ISPEC `at c within interval[c:real^1,b]`
15756         LIM_DROP_UBOUND))
15757     THENL [EXISTS_TAC `g:real^1->real^1`; EXISTS_TAC `h:real^1->real^1`] THEN
15758     ASM_REWRITE_TAC[TRIVIAL_LIMIT_WITHIN; EVENTUALLY_WITHIN] THEN
15759     EXISTS_TAC `drop y - drop c` THEN
15760     (CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
15761     REWRITE_TAC[DIST_REAL; GSYM drop; IN_INTERVAL_1] THEN
15762     REWRITE_TAC[IN_INTERVAL_1] THEN REPEAT STRIP_TAC THEN
15763     FIRST_X_ASSUM MATCH_MP_TAC THEN REWRITE_TAC[IN_INTERVAL_1] THEN
15764     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
15765     ALL_TAC] THEN
15766   SUBGOAL_THEN
15767    `(g':real^1->real^1) continuous (at c within interval[c,b]) /\
15768     (h':real^1->real^1) continuous (at c within interval[c,b])`
15769   MP_TAC THENL
15770    [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN
15771     REWRITE_TAC[CONTINUOUS_WITHIN; REAL_LE_REFL] THEN
15772     RULE_ASSUM_TAC(REWRITE_RULE[VECTOR_ARITH
15773      `g - g':real^1 = k <=> g' + k = g`]) THEN
15774     ASM_REWRITE_TAC[] THEN CONJ_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
15775      (REWRITE_RULE[IMP_CONJ_ALT] LIM_TRANSFORM)) THEN
15776     MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN
15777     REWRITE_TAC[LIM_WITHIN; DIST_REAL; GSYM drop; IN_INTERVAL_1] THEN
15778     SIMP_TAC[REAL_ARITH `c <= x /\ &0 < abs(x - c) ==> ~(x <= c)`] THEN
15779     REWRITE_TAC[VECTOR_SUB_REFL; DROP_VEC; REAL_SUB_REFL; REAL_ABS_NUM] THEN
15780     MESON_TAC[REAL_LT_01];
15781     ALL_TAC] THEN
15782   REWRITE_TAC[continuous_within] THEN
15783   REWRITE_TAC[DIST_LIFT; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN
15784   DISCH_THEN(fun th ->
15785     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
15786     CONJUNCTS_THEN (MP_TAC o SPEC `e / &2`) th) THEN
15787   ASM_REWRITE_TAC[REAL_HALF] THEN
15788   DISCH_THEN(X_CHOOSE_THEN `d2:real` STRIP_ASSUME_TAC) THEN
15789   DISCH_THEN(X_CHOOSE_THEN `d1:real` STRIP_ASSUME_TAC) THEN
15790   EXISTS_TAC `min d1 d2:real` THEN ASM_REWRITE_TAC[REAL_LT_MIN] THEN
15791   X_GEN_TAC `d:real^1` THEN STRIP_TAC THEN
15792   MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `d:real^1`; `c:real^1`]
15793         VECTOR_VARIATION_COMBINE) THEN
15794   ANTS_TAC THENL
15795    [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
15796     REPEAT(CONJ_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC]) THEN
15797     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
15798        HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
15799     REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
15800     DISCH_THEN(SUBST1_TAC o SYM)] THEN
15801   REWRITE_TAC[REAL_ARITH `(a + b) - a:real = b`] THEN
15802   MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x < a ==> abs x < a`) THEN
15803   CONJ_TAC THENL
15804    [MATCH_MP_TAC VECTOR_VARIATION_POS_LE THEN
15805     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
15806        HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
15807     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
15808     REWRITE_TAC[SUBSET_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
15809     ALL_TAC] THEN
15810   SUBGOAL_THEN `f:real^1->real^1 = \x. g' x - h' x` SUBST1_TAC THENL
15811    [MAP_EVERY EXPAND_TAC ["g'"; "h'"] THEN REWRITE_TAC[FUN_EQ_THM] THEN
15812     GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC;
15813     ALL_TAC] THEN
15814   MP_TAC(ISPECL
15815    [`g':real^1->real^1`; `\x. --((h':real^1->real^1) x)`;
15816     `interval[c:real^1,d]`] VECTOR_VARIATION_TRIANGLE) THEN
15817   ANTS_TAC THENL
15818    [CONJ_TAC THENL [ALL_TAC; MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_NEG] THEN
15819     MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUBSET THEN
15820     EXISTS_TAC `interval[c:real^1,b]` THEN
15821     ASM_SIMP_TAC[INCREASING_BOUNDED_VARIATION; SUBSET_INTERVAL_1] THEN
15822     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN  ASM_REAL_ARITH_TAC;
15823     ALL_TAC] THEN
15824   REWRITE_TAC[VECTOR_SUB] THEN MATCH_MP_TAC(REAL_ARITH
15825    `y < a / &2 /\ z < a / &2 ==> x <= y + z ==> x < a`) THEN
15826   REWRITE_TAC[VECTOR_VARIATION_NEG] THEN CONJ_TAC THEN
15827   W(MP_TAC o PART_MATCH (lhs o rand)
15828     INCREASING_VECTOR_VARIATION o lhand o snd) THEN
15829   (ANTS_TAC THENL
15830     [RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
15831      ASM_REWRITE_TAC[INTERVAL_EQ_EMPTY_1; IN_INTERVAL_1; REAL_NOT_LT] THEN
15832      REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC;
15833      DISCH_THEN SUBST1_TAC]) THEN
15834   MATCH_MP_TAC(REAL_ARITH `abs x < e ==> x < e`) THEN
15835   FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[]);;
15836
15837 let VECTOR_VARIATION_CONTINUOUS = prove
15838  (`!f:real^1->real^1 a b c.
15839         f has_bounded_variation_on interval[a,b] /\ c IN interval[a,b]
15840         ==> ((\x. lift(vector_variation(interval[a,x]) f))
15841              continuous (at c within interval[a,b]) <=>
15842             f continuous (at c within interval[a,b]))`,
15843   REPEAT STRIP_TAC THEN
15844   SUBGOAL_THEN
15845    `!f:real^1->real^1.
15846         f continuous (at c within interval[a,b]) <=>
15847         f continuous (at c within interval[a,c]) /\
15848         f continuous (at c within interval[c,b])`
15849    (fun th -> REWRITE_TAC[th] THEN
15850               ASM_MESON_TAC[VECTOR_VARIATION_CONTINUOUS_LEFT;
15851                             VECTOR_VARIATION_CONTINUOUS_RIGHT]) THEN
15852   GEN_TAC THEN REWRITE_TAC[CONTINUOUS_WITHIN] THEN EQ_TAC THENL
15853    [DISCH_THEN(ASSUME_TAC o GEN_ALL o
15854      MATCH_MP (REWRITE_RULE[IMP_CONJ] LIM_WITHIN_SUBSET)) THEN
15855     CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC;
15856     DISCH_THEN(MP_TAC o MATCH_MP LIM_UNION) THEN
15857     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] LIM_WITHIN_SUBSET)] THEN
15858   REWRITE_TAC[SUBSET; IN_UNION; IN_INTERVAL_1] THEN
15859   RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC);;
15860
15861 let HAS_BOUNDED_VARIATION_DARBOUX_STRONG = prove
15862  (`!f a b.
15863      f has_bounded_variation_on interval[a,b]
15864      ==> ?g h. (!x. f x = g x - h x) /\
15865                (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\
15866                       drop x <= drop y
15867                       ==> drop(g x) <= drop(g y)) /\
15868                (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\
15869                       drop x <= drop y
15870                       ==> drop(h x) <= drop(h y)) /\
15871                (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\
15872                       drop x < drop y
15873                       ==> drop(g x) < drop(g y)) /\
15874                (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\
15875                       drop x < drop y
15876                       ==> drop(h x) < drop(h y)) /\
15877                (!x. x IN interval[a,b] /\
15878                     f continuous (at x within interval[a,x])
15879                     ==> g continuous (at x within interval[a,x]) /\
15880                         h continuous (at x within interval[a,x])) /\
15881                (!x. x IN interval[a,b] /\
15882                     f continuous (at x within interval[x,b])
15883                     ==> g continuous (at x within interval[x,b]) /\
15884                         h continuous (at x within interval[x,b])) /\
15885                (!x. x IN interval[a,b] /\
15886                     f continuous (at x within interval[a,b])
15887                     ==> g continuous (at x within interval[a,b]) /\
15888                         h continuous (at x within interval[a,b]))`,
15889   REPEAT STRIP_TAC THEN
15890   MAP_EVERY EXISTS_TAC
15891    [`\x:real^1. x + lift(vector_variation (interval[a,x]) (f:real^1->real^1))`;
15892     `\x:real^1. x + lift(vector_variation (interval[a,x]) f) - f x`] THEN
15893   REWRITE_TAC[VECTOR_ARITH `(x + l) - (x + l - f):real^1 = f`] THEN
15894   REWRITE_TAC[LIFT_DROP; DROP_SUB; DROP_ADD] THEN REPEAT STRIP_TAC THENL
15895    [MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC[] THEN
15896     MATCH_MP_TAC VECTOR_VARIATION_MONOTONE;
15897     MATCH_MP_TAC REAL_LE_ADD2 THEN ASM_REWRITE_TAC[] THEN
15898     MATCH_MP_TAC(REAL_ARITH
15899      `!x. a - (b - x) <= c - (d - x) ==> a - b <= c - d`) THEN
15900     EXISTS_TAC `drop(f(a:real^1))` THEN
15901     REWRITE_TAC[GSYM DROP_SUB] THEN
15902     MATCH_MP_TAC VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE;
15903     MATCH_MP_TAC REAL_LTE_ADD2 THEN ASM_REWRITE_TAC[] THEN
15904     MATCH_MP_TAC VECTOR_VARIATION_MONOTONE;
15905     MATCH_MP_TAC REAL_LTE_ADD2 THEN ASM_REWRITE_TAC[] THEN
15906     MATCH_MP_TAC(REAL_ARITH
15907      `!x. a - (b - x) <= c - (d - x) ==> a - b <= c - d`) THEN
15908     EXISTS_TAC `drop(f(a:real^1))` THEN
15909     REWRITE_TAC[GSYM DROP_SUB] THEN
15910     MATCH_MP_TAC VECTOR_VARIATION_MINUS_FUNCTION_MONOTONE;
15911     MATCH_MP_TAC CONTINUOUS_ADD THEN
15912     REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN
15913     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`]
15914         VECTOR_VARIATION_CONTINUOUS_LEFT) THEN
15915     ASM_REWRITE_TAC[];
15916     MATCH_MP_TAC CONTINUOUS_ADD THEN
15917     REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN
15918     MATCH_MP_TAC CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN
15919     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`]
15920         VECTOR_VARIATION_CONTINUOUS_LEFT) THEN
15921     ASM_REWRITE_TAC[];
15922     MATCH_MP_TAC CONTINUOUS_ADD THEN
15923     REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN
15924     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`]
15925         VECTOR_VARIATION_CONTINUOUS_RIGHT) THEN
15926     ASM_REWRITE_TAC[];
15927     MATCH_MP_TAC CONTINUOUS_ADD THEN
15928     REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN
15929     MATCH_MP_TAC CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN
15930     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`]
15931         VECTOR_VARIATION_CONTINUOUS_RIGHT) THEN
15932     ASM_REWRITE_TAC[];
15933     MATCH_MP_TAC CONTINUOUS_ADD THEN
15934     REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN
15935     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`]
15936         VECTOR_VARIATION_CONTINUOUS) THEN
15937     ASM_REWRITE_TAC[];
15938     MATCH_MP_TAC CONTINUOUS_ADD THEN
15939     REWRITE_TAC[CONTINUOUS_WITHIN_ID] THEN
15940     MATCH_MP_TAC CONTINUOUS_SUB THEN ASM_REWRITE_TAC[] THEN
15941     MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `x:real^1`]
15942         VECTOR_VARIATION_CONTINUOUS) THEN
15943     ASM_REWRITE_TAC[]] THEN
15944   (CONJ_TAC THENL
15945      [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
15946        HAS_BOUNDED_VARIATION_ON_SUBSET));
15947       ALL_TAC] THEN
15948     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
15949     REWRITE_TAC[SUBSET_INTERVAL_1; INTERVAL_EQ_EMPTY_1] THEN
15950     ASM_REAL_ARITH_TAC));;
15951
15952 let HAS_BOUNDED_VARIATION_COUNTABLE_DISCONTINUITIES = prove
15953  (`!f:real^1->real^1 a b.
15954         f has_bounded_variation_on interval[a,b]
15955         ==> COUNTABLE {x | x IN interval[a,b] /\ ~(f continuous at x)}`,
15956   SUBGOAL_THEN
15957    `!f a b.
15958         (!x y. x IN interval[a,b] /\ y IN interval[a,b] /\ drop x <= drop y
15959                ==> drop(f x) <= drop(f y))
15960         ==> COUNTABLE {x | x IN interval[a,b] /\ ~(f continuous at x)}`
15961   ASSUME_TAC THENL
15962    [ALL_TAC;
15963     REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o
15964      GEN_REWRITE_RULE I [HAS_BOUNDED_VARIATION_DARBOUX]) THEN
15965     REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
15966     MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN
15967     STRIP_TAC THEN FIRST_X_ASSUM(fun th ->
15968       MP_TAC(ISPECL [`g:real^1->real^1`; `a:real^1`; `b:real^1`] th) THEN
15969       MP_TAC(ISPECL [`h:real^1->real^1`; `a:real^1`; `b:real^1`] th)) THEN
15970     ASM_REWRITE_TAC[IMP_IMP; GSYM COUNTABLE_UNION] THEN
15971     MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] COUNTABLE_SUBSET) THEN
15972     REWRITE_TAC[SUBSET; IN_UNION; IN_ELIM_THM] THEN GEN_TAC THEN
15973     MATCH_MP_TAC(TAUT
15974      `(p /\ q ==> r) ==> a /\ ~r ==> a /\ ~p \/ a /\ ~q`) THEN
15975     GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [GSYM ETA_AX] THEN
15976     ASM_SIMP_TAC[CONTINUOUS_SUB]] THEN
15977   REPEAT STRIP_TAC THEN ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN
15978   ASM_REWRITE_TAC[NOT_IN_EMPTY; EMPTY_GSPEC; COUNTABLE_EMPTY] THEN
15979   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
15980   ASM_SIMP_TAC[CLOSED_OPEN_INTERVAL_1] THEN
15981   MATCH_MP_TAC COUNTABLE_SUBSET THEN EXISTS_TAC
15982    `a INSERT b INSERT
15983     {x | x IN interval(a,b) /\ ~((f:real^1->real^1) continuous at x)}` THEN
15984   CONJ_TAC THENL [REWRITE_TAC[COUNTABLE_INSERT]; SET_TAC[]] THEN
15985   SUBGOAL_THEN
15986    `(!c:real^1. c IN interval(a,b) ==> c limit_point_of interval[a,c]) /\
15987     (!c:real^1. c IN interval(a,b) ==> c limit_point_of interval[c,b])`
15988   STRIP_ASSUME_TAC THENL
15989    [SIMP_TAC[IN_INTERVAL_1; REAL_LE_REFL; LIMPT_OF_CONVEX;
15990              CONVEX_INTERVAL; REAL_LT_IMP_LE] THEN
15991     REWRITE_TAC[GSYM INTERVAL_SING; GSYM SUBSET_ANTISYM_EQ] THEN
15992     REWRITE_TAC[SUBSET_INTERVAL_1] THEN REAL_ARITH_TAC;
15993     ALL_TAC] THEN
15994   MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`]
15995         INCREASING_LEFT_LIMIT_1) THEN
15996   ASM_REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
15997   DISCH_THEN(X_CHOOSE_THEN `l:real^1->real^1` (LABEL_TAC "l")) THEN
15998   MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`]
15999         INCREASING_RIGHT_LIMIT_1) THEN
16000   ASM_REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
16001   DISCH_THEN(X_CHOOSE_THEN `r:real^1->real^1` (LABEL_TAC "r")) THEN
16002   SUBGOAL_THEN
16003    `!c. c IN interval(a:real^1,b)
16004         ==> drop(l c) <= drop(f c) /\ drop(f c) <= drop(r c)`
16005   ASSUME_TAC THENL
16006    [REPEAT STRIP_TAC THENL
16007      [MATCH_MP_TAC(ISPEC `at c within interval[a:real^1,c]`
16008         LIM_DROP_UBOUND);
16009       MATCH_MP_TAC(ISPEC `at c within interval[c:real^1,b]`
16010         LIM_DROP_LBOUND)] THEN
16011     EXISTS_TAC `f:real^1->real^1` THEN
16012     ASM_SIMP_TAC[REWRITE_RULE[SUBSET] INTERVAL_OPEN_SUBSET_CLOSED;
16013                  TRIVIAL_LIMIT_WITHIN; EVENTUALLY_WITHIN] THEN
16014     EXISTS_TAC `&1` THEN REWRITE_TAC[REAL_LT_01; IN_INTERVAL_1] THEN
16015     REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
16016     REWRITE_TAC[IN_INTERVAL_1] THEN
16017     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
16018     ALL_TAC] THEN
16019   SUBGOAL_THEN
16020    `(!c x. c IN interval(a:real^1,b) /\ x IN interval[a,b] /\ drop x < drop c
16021            ==> drop(f x) <= drop(l c)) /\
16022     (!c x. c IN interval(a:real^1,b) /\ x IN interval[a,b] /\ drop c < drop x
16023            ==> drop(r c) <= drop(f x))`
16024   STRIP_ASSUME_TAC THENL
16025    [REPEAT STRIP_TAC THENL
16026      [MATCH_MP_TAC(ISPEC `at c within interval[a:real^1,c]`
16027         LIM_DROP_LBOUND);
16028       MATCH_MP_TAC(ISPEC `at c within interval[c:real^1,b]`
16029         LIM_DROP_UBOUND)] THEN
16030     EXISTS_TAC `f:real^1->real^1` THEN
16031     ASM_SIMP_TAC[REWRITE_RULE[SUBSET] INTERVAL_OPEN_SUBSET_CLOSED;
16032                  TRIVIAL_LIMIT_WITHIN; EVENTUALLY_WITHIN]
16033     THENL
16034      [EXISTS_TAC `drop c - drop x`; EXISTS_TAC `drop x - drop c`] THEN
16035     ASM_REWRITE_TAC[REAL_SUB_LT] THEN
16036     X_GEN_TAC `y:real^1` THEN
16037     REWRITE_TAC[IN_INTERVAL_1; IN_ELIM_THM; DIST_REAL; GSYM drop] THEN
16038     STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
16039     ASM_REWRITE_TAC[IN_INTERVAL_1] THEN
16040     RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
16041     ALL_TAC] THEN
16042   REWRITE_TAC[COUNTABLE; ge_c] THEN
16043   TRANS_TAC CARD_LE_TRANS `rational` THEN
16044   GEN_REWRITE_TAC RAND_CONV [GSYM ge_c] THEN
16045   REWRITE_TAC[COUNTABLE_RATIONAL; GSYM COUNTABLE; le_c] THEN
16046   SUBGOAL_THEN
16047    `!c. c IN interval(a,b) /\ ~((f:real^1->real^1) continuous at c)
16048           ==> drop(l(c:real^1)) < drop(r c)`
16049   ASSUME_TAC THENL
16050    [REPEAT STRIP_TAC THEN REWRITE_TAC[REAL_LT_LE] THEN
16051     CONJ_TAC THENL [ASM_MESON_TAC[REAL_LE_TRANS]; ALL_TAC] THEN
16052     REWRITE_TAC[DROP_EQ] THEN DISCH_TAC THEN
16053     SUBGOAL_THEN `l c = (f:real^1->real^1) c /\ r c = f c` ASSUME_TAC THENL
16054      [ASM_MESON_TAC[REAL_LE_ANTISYM; DROP_EQ]; ALL_TAC] THEN
16055     FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [CONTINUOUS_AT]) THEN
16056     REWRITE_TAC[] THEN
16057     SUBGOAL_THEN
16058      `((f:real^1->real^1) --> f c) (at c within interval(a,b))`
16059     MP_TAC THENL
16060      [ALL_TAC; ASM_SIMP_TAC[OPEN_INTERVAL; LIM_WITHIN_OPEN]] THEN
16061     MATCH_MP_TAC LIM_WITHIN_SUBSET THEN
16062     EXISTS_TAC `interval[a:real^1,c] UNION interval[c,b]` THEN
16063     REWRITE_TAC[LIM_WITHIN_UNION] THEN CONJ_TAC THENL
16064      [ASM_MESON_TAC[REWRITE_RULE[SUBSET] INTERVAL_OPEN_SUBSET_CLOSED];
16065       REWRITE_TAC[SUBSET; IN_UNION; IN_INTERVAL_1] THEN REAL_ARITH_TAC];
16066     ALL_TAC] THEN
16067   SUBGOAL_THEN
16068    `!c. c IN interval(a,b) /\ ~((f:real^1->real^1) continuous at c)
16069         ==> ?q. rational q /\ drop(l c) < q /\ q < drop(r c)`
16070   MP_TAC THENL
16071    [REPEAT STRIP_TAC THEN
16072     SUBGOAL_THEN `drop(l(c:real^1)) < drop(r c)` ASSUME_TAC THENL
16073      [ASM_MESON_TAC[]; ALL_TAC] THEN
16074     MP_TAC(ISPECL [`(drop(l(c:real^1)) + drop(r c)) / &2`;
16075                    `(drop(r c) - drop(l(c:real^1))) / &2`]
16076       RATIONAL_APPROXIMATION) THEN
16077     ASM_REWRITE_TAC[REAL_HALF; REAL_SUB_LT] THEN
16078     MATCH_MP_TAC MONO_EXISTS THEN SIMP_TAC[] THEN REAL_ARITH_TAC;
16079     ALL_TAC] THEN
16080   GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
16081   REWRITE_TAC[SKOLEM_THM; IN_ELIM_THM; IN_INTERVAL_1] THEN
16082   MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `q:real^1->real` THEN
16083   SIMP_TAC[IN] THEN DISCH_THEN(LABEL_TAC "*") THEN
16084   MATCH_MP_TAC(MESON[REAL_LE_TOTAL]
16085    `(!x y. P x y ==> P y x) /\ (!x y. drop x <= drop y ==> P x y)
16086     ==> !x y. P x y`) THEN
16087   CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
16088   MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN
16089   REWRITE_TAC[REAL_LE_LT; DROP_EQ] THEN
16090   ASM_CASES_TAC `x:real^1 = y` THEN ASM_REWRITE_TAC[] THEN
16091   REPEAT STRIP_TAC THEN
16092   SUBGOAL_THEN `q(x:real^1) < q(y)` MP_TAC THENL
16093    [ALL_TAC; ASM_REWRITE_TAC[REAL_LT_REFL]] THEN
16094   MATCH_MP_TAC REAL_LTE_TRANS THEN EXISTS_TAC `drop(r(x:real^1))` THEN
16095   ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN
16096   MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `drop(l(y:real^1))` THEN
16097   ASM_SIMP_TAC[REAL_LT_IMP_LE] THEN
16098   MATCH_MP_TAC REAL_LE_TRANS THEN
16099   EXISTS_TAC `drop(f(inv(&2) % (x + y):real^1))` THEN
16100   CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
16101   ASM_REWRITE_TAC[IN_INTERVAL_1; DROP_CMUL; DROP_ADD] THEN
16102   ASM_REAL_ARITH_TAC);;
16103
16104 let HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE = prove
16105  (`!f:real^1->real^N s a b.
16106         COUNTABLE s /\ f continuous_on interval[a,b] /\
16107         (!x. x IN interval[a,b] DIFF s ==> f differentiable at x)
16108         ==> (f has_bounded_variation_on interval[a,b] <=>
16109              (\x. vector_derivative f (at x))
16110              absolutely_integrable_on interval[a,b])`,
16111   REPEAT STRIP_TAC THEN
16112   REWRITE_TAC[ABSOLUTELY_INTEGRABLE_BOUNDED_SETVARIATION_EQ] THEN
16113   REWRITE_TAC[has_bounded_variation_on] THEN
16114   MATCH_MP_TAC(TAUT `q /\ (p <=> r) ==> (p <=> q /\ r)`) THEN CONJ_TAC THENL
16115    [ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN
16116     ASM_REWRITE_TAC[INTEGRABLE_ON_EMPTY] THEN
16117     RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY_1]) THEN
16118     MP_TAC(ISPECL [`f:real^1->real^N`;
16119                    `\x. vector_derivative (f:real^1->real^N) (at x)`;
16120                    `s:real^1->bool`; `a:real^1`; `b:real^1`]
16121       FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG) THEN
16122     ASM_MESON_TAC[VECTOR_DERIVATIVE_WORKS; integrable_on;
16123                   HAS_VECTOR_DERIVATIVE_AT_WITHIN];
16124     MATCH_MP_TAC(MESON[HAS_BOUNDED_SETVARIATION_ON_EQ]
16125      `(!a b. ~(interval[a,b] = {}) /\ interval[a,b] SUBSET s
16126                ==> f(interval[a,b]) = g(interval[a,b]))
16127       ==> (f has_bounded_setvariation_on s <=>
16128            g has_bounded_setvariation_on s)`) THEN
16129     SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND;
16130              GSYM INTERVAL_NE_EMPTY] THEN
16131     MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN
16132     REWRITE_TAC[INTERVAL_NE_EMPTY_1] THEN STRIP_TAC THEN
16133     MP_TAC(ISPECL [`f:real^1->real^N`;
16134                    `\x. vector_derivative (f:real^1->real^N) (at x)`;
16135                    `s:real^1->bool`; `u:real^1`; `v:real^1`]
16136       FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG) THEN
16137     ASM_REWRITE_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN
16138     ANTS_TAC THENL [ALL_TAC; MESON_TAC[INTEGRAL_UNIQUE]] THEN CONJ_TAC THENL
16139      [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; IN_DIFF; SUBSET];
16140       REPEAT STRIP_TAC THEN MATCH_MP_TAC HAS_VECTOR_DERIVATIVE_AT_WITHIN THEN
16141       ASM_SIMP_TAC[GSYM VECTOR_DERIVATIVE_WORKS] THEN ASM SET_TAC[]]]);;
16142
16143 let HAS_BOUNDED_VARIATION_INTEGRABLE_NORM_DERIVATIVE = prove
16144  (`!f:real^1->real^N s a b.
16145         COUNTABLE s /\ f continuous_on interval[a,b] /\
16146         (!x. x IN interval[a,b] DIFF s ==> f differentiable at x)
16147         ==> (f has_bounded_variation_on interval[a,b] <=>
16148              (\x. lift(norm(vector_derivative f (at x))))
16149              integrable_on interval[a,b])`,
16150   REPEAT GEN_TAC THEN DISCH_THEN(fun th ->
16151     STRIP_ASSUME_TAC th THEN
16152     REWRITE_TAC[MATCH_MP HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE
16153                 th]) THEN
16154   REWRITE_TAC[absolutely_integrable_on] THEN
16155   MATCH_MP_TAC(TAUT `p ==> (p /\ q <=> q)`) THEN
16156   ASM_CASES_TAC `interval[a:real^1,b] = {}` THEN
16157   ASM_REWRITE_TAC[INTEGRABLE_ON_EMPTY] THEN
16158   RULE_ASSUM_TAC(REWRITE_RULE[INTERVAL_NE_EMPTY_1]) THEN
16159   MP_TAC(ISPECL [`f:real^1->real^N`;
16160                  `\x. vector_derivative (f:real^1->real^N) (at x)`;
16161                  `s:real^1->bool`; `a:real^1`; `b:real^1`]
16162     FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG) THEN
16163   ASM_MESON_TAC[VECTOR_DERIVATIVE_WORKS; integrable_on;
16164                 HAS_VECTOR_DERIVATIVE_AT_WITHIN]);;
16165
16166 let VECTOR_VARIATION_INTEGRAL_NORM_DERIVATIVE = prove
16167  (`!f:real^1->real^N s a b.
16168         COUNTABLE s /\ f continuous_on interval[a,b] /\
16169         (!x. x IN interval[a,b] DIFF s ==> f differentiable at x) /\
16170         f has_bounded_variation_on interval[a,b]
16171         ==> vector_variation (interval[a,b]) f =
16172                 drop(integral (interval[a,b])
16173                         (\x. lift(norm(vector_derivative f (at x)))))`,
16174   REPEAT STRIP_TAC THEN MP_TAC(ISPECL
16175    [`f:real^1->real^N`; `s:real^1->bool`; `a:real^1`; `b:real^1`]
16176    HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE) THEN
16177   ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
16178   FIRST_ASSUM(MP_TAC o MATCH_MP ABSOLUTELY_INTEGRABLE_SET_VARIATION) THEN
16179   REWRITE_TAC[vector_variation] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
16180   MATCH_MP_TAC SET_VARIATION_EQ THEN
16181   MAP_EVERY X_GEN_TAC [`u:real^1`; `v:real^1`] THEN
16182   SIMP_TAC[INTERVAL_NE_EMPTY_1; INTERVAL_LOWERBOUND_1;
16183            INTERVAL_UPPERBOUND_1] THEN
16184   STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
16185   MATCH_MP_TAC FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG THEN
16186   EXISTS_TAC `s:real^1->bool` THEN ASM_REWRITE_TAC[] THEN
16187   CONJ_TAC THENL [ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]; ALL_TAC] THEN
16188   ASM_MESON_TAC[VECTOR_DERIVATIVE_WORKS; HAS_VECTOR_DERIVATIVE_AT_WITHIN;
16189                 IN_DIFF; SUBSET]);;
16190
16191 (* ------------------------------------------------------------------------- *)
16192 (* Baby Fubini theorems for continuous functions. Will be generalized.       *)
16193 (* ------------------------------------------------------------------------- *)
16194
16195 let INTEGRAL_PASTECART_CONTINUOUS = prove
16196  (`!f:real^(M,N)finite_sum->real^P a b c d.
16197         f continuous_on interval[pastecart a c,pastecart b d]
16198         ==> integral (interval[pastecart a c,pastecart b d]) f =
16199             integral (interval[a,b])
16200                      (\x. integral (interval[c,d])
16201                                    (\y. f(pastecart x y)))`,
16202   let lemma1 = prove
16203    (`!(f:real^(M,N)finite_sum->real^P) a b c d x.
16204           f continuous_on interval [pastecart a c,pastecart b d] /\
16205           x IN interval[a,b]
16206           ==> (\y. (f:real^(M,N)finite_sum->real^P) (pastecart x y))
16207               integrable_on interval[c,d]`,
16208     REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_CONTINUOUS THEN
16209     GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
16210     MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
16211     SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_CONST;
16212              CONTINUOUS_ON_ID] THEN
16213     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16214       CONTINUOUS_ON_SUBSET)) THEN
16215     ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; GSYM PCROSS_INTERVAL; PCROSS;
16216                  IN_ELIM_PASTECART_THM]) in
16217   let lemma2 = prove
16218    (`!(f:real^(M,N)finite_sum->real^P) a b c d.
16219       f continuous_on interval [pastecart a c,pastecart b d]
16220       ==> (\x. integral (interval [c,d]) (\y. f (pastecart x y))) integrable_on
16221           interval [a,b]`,
16222     REPEAT STRIP_TAC THEN
16223     FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] lemma1)) THEN
16224     MATCH_MP_TAC INTEGRABLE_CONTINUOUS THEN REWRITE_TAC[continuous_on] THEN
16225     X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
16226     X_GEN_TAC `e:real` THEN DISCH_TAC THEN
16227     ASM_SIMP_TAC[dist; GSYM INTEGRAL_SUB] THEN
16228     ASM_CASES_TAC `content(interval[c:real^N,d]) = &0` THENL
16229      [ASM_SIMP_TAC[INTEGRAL_NULL; NORM_0] THEN MESON_TAC[REAL_LT_01];
16230       ALL_TAC] THEN
16231     FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16232           COMPACT_UNIFORMLY_CONTINUOUS)) THEN
16233     REWRITE_TAC[COMPACT_INTERVAL; uniformly_continuous_on] THEN
16234     RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONTENT_LT_NZ]) THEN
16235     DISCH_THEN(MP_TAC o SPEC `e / &2 / content(interval[c:real^N,d])`) THEN
16236     ASM_SIMP_TAC[REAL_LT_DIV; REAL_HALF; FORALL_PASTECART] THEN
16237     MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN
16238     REWRITE_TAC[GSYM PCROSS_INTERVAL; PCROSS; dist;
16239                 IN_ELIM_PASTECART_THM] THEN
16240     STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
16241     X_GEN_TAC `x':real^M` THEN DISCH_TAC THEN
16242     MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
16243     ASM_REWRITE_TAC[] THEN
16244     SUBGOAL_THEN
16245      `e / &2 = e / &2 / content(interval[c:real^N,d]) * content(interval[c,d])`
16246     SUBST1_TAC THENL
16247      [UNDISCH_TAC `&0 < content(interval[c:real^N,d])` THEN
16248       CONV_TAC REAL_FIELD;
16249       MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN
16250       EXISTS_TAC `\y. (f:real^(M,N)finite_sum->real^P) (pastecart x' y) -
16251                       (f:real^(M,N)finite_sum->real^P) (pastecart x y)` THEN
16252       ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_HALF; REAL_LT_DIV;
16253                    GSYM HAS_INTEGRAL_INTEGRAL; INTEGRABLE_SUB; lemma1] THEN
16254       REPEAT STRIP_TAC THEN
16255       MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
16256       ASM_SIMP_TAC[NORM_PASTECART; PASTECART_SUB; VECTOR_SUB_REFL; NORM_0] THEN
16257       CONV_TAC REAL_RAT_REDUCE_CONV THEN
16258       ASM_SIMP_TAC[REAL_ADD_RID; POW_2_SQRT; NORM_POS_LE]]) in
16259   let lemma3 = prove
16260    (`!f:real^(M,N)finite_sum->real^P e s.
16261       &0 < e /\ f continuous_on s
16262       ==> operative(/\)
16263            (\k. !a b c d.
16264                 interval[pastecart a c,pastecart b d] SUBSET k /\
16265                 interval[pastecart a c,pastecart b d] SUBSET s
16266                 ==> norm(integral (interval[pastecart a c,pastecart b d]) f -
16267                          integral (interval[a,b])
16268                            (\x. integral (interval[c,d])
16269                                     (\y. f(pastecart x y))))
16270                     <= e * content(interval[pastecart a c,pastecart b d]))`,
16271     REPEAT STRIP_TAC THEN REWRITE_TAC[operative; NEUTRAL_AND] THEN
16272     CONJ_TAC THEN MAP_EVERY X_GEN_TAC
16273      [`A:real^(M,N)finite_sum`;`B:real^(M,N)finite_sum`] THENL
16274      [DISCH_TAC THEN
16275       MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real^N`; `d:real^N`] THEN
16276       DISCH_TAC THEN
16277       SUBGOAL_THEN
16278        `content(interval[pastecart (a:real^M) (c:real^N),pastecart b d]) = &0`
16279        (fun th -> ASSUME_TAC th THEN MP_TAC th)
16280       THENL [ASM_MESON_TAC[CONTENT_0_SUBSET]; ALL_TAC] THEN
16281       REWRITE_TAC[CONTENT_PASTECART; REAL_ENTIRE] THEN STRIP_TAC THEN
16282       ASM_SIMP_TAC[INTEGRAL_NULL; REAL_MUL_LZERO; REAL_MUL_RZERO;
16283                    VECTOR_SUB_REFL; NORM_0; REAL_LE_REFL; INTEGRAL_0];
16284       MAP_EVERY X_GEN_TAC [`l:real`; `k:num`] THEN STRIP_TAC THEN EQ_TAC THENL
16285        [REWRITE_TAC[AND_FORALL_THM] THEN
16286         REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
16287         MATCH_MP_TAC(TAUT
16288          `(P1 ==> P) /\ (P2 ==> P)
16289           ==> (P ==> Q) ==> (P1 ==> Q) /\ (P2 ==> Q)`) THEN
16290         SET_TAC[];
16291         DISCH_TAC]] THEN
16292     MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real^N`; `d:real^N`] THEN
16293     STRIP_TAC THEN RULE_ASSUM_TAC(REWRITE_RULE[DIMINDEX_FINITE_SUM]) THEN
16294     ASM_CASES_TAC `k <= dimindex(:M)` THENL
16295      [FIRST_X_ASSUM(CONJUNCTS_THEN2
16296        (MP_TAC o SPECL
16297          [`a:real^M`;
16298           `(lambda i. if i = k then min (b$k) l else (b:real^M)$i):real^M`;
16299           `c:real^N`; `d:real^N`])
16300        (MP_TAC o SPECL
16301          [`(lambda i. if i = k then max (a$k) l else (a:real^M)$i):real^M`;
16302           `b:real^M`; `c:real^N`; `d:real^N`])) THEN
16303       ASM_SIMP_TAC[GSYM INTERVAL_SPLIT; GSYM PCROSS_INTERVAL; PCROSS] THEN
16304       SUBGOAL_THEN
16305        `!P Q. { pastecart (x:real^M) (y:real^N) |
16306                 x IN interval[a,b] INTER {x | P (x$k)} /\ Q y} =
16307               {pastecart x y | x IN interval[a,b] /\ Q y} INTER {x | P (x$k)}`
16308        (fun th -> REWRITE_TAC[th])
16309       THENL
16310        [REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_PASTECART_THM;
16311                     IN_INTER] THEN
16312         ASM_SIMP_TAC[pastecart; IN_ELIM_THM; LAMBDA_BETA; DIMINDEX_FINITE_SUM;
16313                      ARITH_RULE `i:num <= m ==> i <= m + n`] THEN
16314         MESON_TAC[];
16315         ALL_TAC] THEN
16316       REWRITE_TAC[REWRITE_RULE[PCROSS] PCROSS_INTERVAL] THEN
16317       ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER u SUBSET t INTER u`] THEN
16318       ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER u SUBSET t`] THEN
16319       MATCH_MP_TAC(NORM_ARITH
16320        `y = y1 + y2 /\ x = x1 + x2 /\ e = e1 + e2
16321         ==> norm(y2 - x2:real^N) <= e2 ==> norm(y1 - x1) <= e1
16322             ==> norm(y - x) <= e`) THEN
16323       REPEAT CONJ_TAC THENL
16324        [MATCH_MP_TAC(SIMP_RULE[GSYM INTERVAL_SPLIT] INTEGRAL_SPLIT) THEN
16325         ASM_SIMP_TAC[DIMINDEX_FINITE_SUM;
16326                      ARITH_RULE `i:num <= m ==> i <= m + n`] THEN
16327         ASM_MESON_TAC[INTEGRABLE_CONTINUOUS; CONTINUOUS_ON_SUBSET];
16328         MATCH_MP_TAC(SIMP_RULE[GSYM INTERVAL_SPLIT] INTEGRAL_SPLIT) THEN
16329         ASM_REWRITE_TAC[] THEN MATCH_MP_TAC lemma2 THEN
16330         ASM_MESON_TAC[CONTINUOUS_ON_SUBSET];
16331         REWRITE_TAC[GSYM REAL_ADD_LDISTRIB] THEN AP_TERM_TAC THEN
16332         MATCH_MP_TAC CONTENT_SPLIT THEN
16333         ASM_REWRITE_TAC[DIMINDEX_FINITE_SUM]];
16334       FIRST_X_ASSUM(CONJUNCTS_THEN2
16335        (MP_TAC o SPECL
16336          [`a:real^M`; `b:real^M`; `c:real^N`;
16337           `(lambda i. if i = k - dimindex(:M)
16338                       then min (d$(k - dimindex(:M))) l
16339                       else (d:real^N)$i):real^N`])
16340        (MP_TAC o SPECL
16341          [`a:real^M`; `b:real^M`;
16342           `(lambda i. if i = k - dimindex(:M)
16343                       then max (c$(k - dimindex(:M))) l
16344                       else (c:real^N)$i):real^N`;
16345           `d:real^N`])) THEN
16346       ASM_SIMP_TAC[GSYM INTERVAL_SPLIT; GSYM PCROSS_INTERVAL; PCROSS;
16347                 ARITH_RULE `~(i <= m) ==> 1 <= i - m`;
16348                 ARITH_RULE `~(i <= m) /\ i:num <= m + n ==> i - m <= n`] THEN
16349       SUBGOAL_THEN
16350        `!P Q. { pastecart (x:real^M) (y:real^N) |
16351               P x /\ y IN interval[c,d] INTER {y | Q (y$(k - dimindex(:M)))}} =
16352               {pastecart x y | P x /\ y IN interval[c,d]} INTER
16353               {x | Q (x$k)}`
16354        (fun th -> REWRITE_TAC[th])
16355       THENL
16356        [REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_PASTECART_THM;
16357                     IN_INTER] THEN
16358         ASM_SIMP_TAC[pastecart; IN_ELIM_THM; LAMBDA_BETA;
16359                      DIMINDEX_FINITE_SUM] THEN
16360         MESON_TAC[];
16361         ALL_TAC] THEN
16362       REWRITE_TAC[REWRITE_RULE[PCROSS] PCROSS_INTERVAL] THEN
16363       ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER u SUBSET t INTER u`] THEN
16364       ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER u SUBSET t`] THEN
16365       MATCH_MP_TAC(NORM_ARITH
16366        `y = y1 + y2 /\ x = x1 + x2 /\ e = e1 + e2
16367         ==> norm(y2 - x2:real^N) <= e2 ==> norm(y1 - x1) <= e1
16368             ==> norm(y - x) <= e`) THEN
16369       REPEAT CONJ_TAC THENL
16370        [MATCH_MP_TAC(SIMP_RULE[GSYM INTERVAL_SPLIT] INTEGRAL_SPLIT) THEN
16371         ASM_SIMP_TAC[DIMINDEX_FINITE_SUM;
16372                      ARITH_RULE `i:num <= m ==> i <= m + n`] THEN
16373         ASM_MESON_TAC[INTEGRABLE_CONTINUOUS; CONTINUOUS_ON_SUBSET];
16374         W(MP_TAC o PART_MATCH (rand o rand) INTEGRAL_ADD o rand o snd) THEN
16375         REWRITE_TAC[] THEN ANTS_TAC THENL
16376          [ASM_SIMP_TAC[INTERVAL_SPLIT; DIMINDEX_FINITE_SUM;
16377                  ARITH_RULE `~(i <= m) ==> 1 <= i - m`;
16378                  ARITH_RULE `~(i <= m) /\ i:num <= m + n ==> i - m <= n`] THEN
16379           CONJ_TAC THEN MATCH_MP_TAC lemma2 THEN
16380           MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN
16381           EXISTS_TAC `s:real^(M,N)finite_sum->bool` THEN
16382           ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MATCH_MP_TAC o
16383              MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] SUBSET_TRANS)) THEN
16384           REWRITE_TAC[SUBSET_INTERVAL] THEN DISCH_THEN(K ALL_TAC) THEN
16385           ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM;
16386                   ARITH_RULE `~(i <= m) ==> 1 <= i - m`;
16387                   ARITH_RULE `~(i <= m) /\ i:num <= m + n ==> i - m <= n`] THEN
16388           REPEAT STRIP_TAC THEN
16389           REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL]) THEN
16390           REAL_ARITH_TAC;
16391           DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC INTEGRAL_EQ THEN
16392           X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[] THEN
16393           MATCH_MP_TAC(SIMP_RULE[GSYM INTERVAL_SPLIT] INTEGRAL_SPLIT) THEN
16394           CONJ_TAC THENL [ALL_TAC; ASM_ARITH_TAC] THEN
16395           MATCH_MP_TAC lemma1 THEN ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]];
16396         REWRITE_TAC[GSYM REAL_ADD_LDISTRIB] THEN AP_TERM_TAC THEN
16397         MATCH_MP_TAC CONTENT_SPLIT THEN
16398         ASM_REWRITE_TAC[DIMINDEX_FINITE_SUM]]]) in
16399   REPEAT STRIP_TAC THEN ASM_CASES_TAC
16400    `content(interval[pastecart(a:real^M) (c:real^N),pastecart b d]) = &0` THEN
16401   ASM_SIMP_TAC[INTEGRAL_NULL] THEN
16402   RULE_ASSUM_TAC(REWRITE_RULE[CONTENT_PASTECART]) THEN
16403   RULE_ASSUM_TAC(REWRITE_RULE[REAL_ENTIRE; DE_MORGAN_THM]) THENL
16404    [FIRST_X_ASSUM DISJ_CASES_TAC THEN
16405     ASM_SIMP_TAC[INTEGRAL_NULL; INTEGRAL_0];
16406     ALL_TAC] THEN
16407   SUBGOAL_THEN
16408    `&0 < content(interval[pastecart(a:real^M) (c:real^N),pastecart b d])`
16409   ASSUME_TAC THENL
16410    [ASM_REWRITE_TAC[CONTENT_LT_NZ; CONTENT_PASTECART; REAL_ENTIRE];
16411     ALL_TAC] THEN
16412   ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
16413   ONCE_REWRITE_TAC[GSYM NORM_EQ_0] THEN
16414   MATCH_MP_TAC(MESON[REAL_ARITH
16415    `~(x = &0) ==> &0 < abs x / &2 /\ ~(abs x <= abs x / &2)`]
16416    `(!e. &0 < e ==> abs x <= e) ==> x = &0`) THEN
16417   X_GEN_TAC `e:real` THEN DISCH_TAC THEN REWRITE_TAC[REAL_ABS_NORM] THEN
16418   MP_TAC(ISPECL
16419    [`f:real^(M,N)finite_sum->real^P`;
16420     `e / content(interval[pastecart(a:real^M) (c:real^N),pastecart b d])`;
16421     `interval[pastecart(a:real^M) (c:real^N),pastecart b d]`]
16422    lemma3) THEN
16423   ASM_SIMP_TAC[REAL_LT_DIV] THEN DISCH_THEN(MP_TAC o MATCH_MP
16424    (REWRITE_RULE[IMP_CONJ] OPERATIVE_DIVISION_AND)) THEN
16425   REWRITE_TAC[] THEN
16426   FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16427     COMPACT_UNIFORMLY_CONTINUOUS)) THEN
16428   REWRITE_TAC[COMPACT_INTERVAL; uniformly_continuous_on] THEN
16429   DISCH_THEN(MP_TAC o SPEC
16430     `e / &2 /
16431      content(interval[pastecart(a:real^M) (c:real^N),pastecart b d])`) THEN
16432   ASM_SIMP_TAC[dist; REAL_HALF; REAL_LT_DIV] THEN
16433   DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
16434   SUBGOAL_THEN
16435    `?p. p tagged_division_of
16436         interval[pastecart(a:real^M) (c:real^N),pastecart b d] /\
16437         (\x. ball(x,k)) fine p`
16438   STRIP_ASSUME_TAC THENL
16439    [ASM_MESON_TAC[FINE_DIVISION_EXISTS; GAUGE_BALL]; ALL_TAC] THEN
16440   DISCH_THEN(MP_TAC o SPEC
16441   `IMAGE SND (p:real^(M,N)finite_sum#(real^(M,N)finite_sum->bool)->bool)`) THEN
16442   DISCH_THEN(MP_TAC o SPECL
16443    [`pastecart(a:real^M) (c:real^N)`; `pastecart(b:real^M) (d:real^N)`]) THEN
16444   ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION] THEN
16445   REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN
16446   MATCH_MP_TAC(TAUT `(b ==> c) /\ a ==> (a <=> b) ==> c`) THEN CONJ_TAC THENL
16447    [DISCH_THEN(MP_TAC o SPECL
16448      [`a:real^M`; `b:real^M`; `c:real^N`; `d:real^N`]) THEN
16449     ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_LT_IMP_NZ; SUBSET_REFL];
16450     ALL_TAC] THEN
16451   MAP_EVERY X_GEN_TAC
16452    [`t:real^(M,N)finite_sum`; `l:real^(M,N)finite_sum->bool`] THEN
16453   DISCH_TAC THEN
16454   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
16455   DISCH_THEN(MP_TAC o SPECL
16456     [`t:real^(M,N)finite_sum`; `l:real^(M,N)finite_sum->bool`] o
16457      el 1 o CONJUNCTS) THEN
16458   ASM_REWRITE_TAC[] THEN
16459   DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
16460   ASM_REWRITE_TAC[] THEN
16461   MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`; `w:real^N`; `z:real^N`] THEN
16462   STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
16463   REWRITE_TAC[SUBSET; IN_BALL; dist] THEN DISCH_TAC THEN
16464   MP_TAC(ISPECL
16465    [`u:real^M`; `v:real^M`; `w:real^N`; `z:real^N`;
16466     `(f:real^(M,N)finite_sum->real^P) t`]
16467    INTEGRAL_PASTECART_CONST) THEN
16468   MATCH_MP_TAC(NORM_ARITH
16469    `norm(x - x') <= e / &2 /\ norm(y - y') <= e / &2
16470     ==> x':real^P = y' ==> norm(x - y) <= e`) THEN
16471   REWRITE_TAC[REAL_ARITH `(e / c * d) / &2 = e / &2 / c * d`] THEN
16472   CONJ_TAC THENL
16473    [MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN
16474     EXISTS_TAC `\y. (f:real^(M,N)finite_sum->real^P) y - f t` THEN
16475     ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; REAL_LT_IMP_LE] THEN CONJ_TAC THENL
16476      [MATCH_MP_TAC HAS_INTEGRAL_SUB THEN
16477       REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL; INTEGRABLE_CONST] THEN
16478       ASM_MESON_TAC[INTEGRABLE_CONTINUOUS; INTEGRABLE_ON_SUBINTERVAL];
16479       X_GEN_TAC `y:real^(M,N)finite_sum` THEN DISCH_TAC THEN
16480       MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
16481       MATCH_MP_TAC(TAUT `(a /\ b) /\ (a /\ b ==> c) ==> a /\ b /\ c`) THEN
16482       CONJ_TAC THENL [ASM SET_TAC[]; ASM_MESON_TAC[NORM_SUB; SUBSET]]];
16483     GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [CONTENT_PASTECART] THEN
16484     ONCE_REWRITE_TAC[REAL_ARITH `a * b * c:real = (a * c) * b`] THEN
16485     MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN EXISTS_TAC
16486      `\x. integral (interval [w,z]) (\y. f (pastecart x y)) -
16487            integral (interval [w,z])
16488                     (\y. (f:real^(M,N)finite_sum->real^P) t)` THEN
16489     REPEAT CONJ_TAC THENL
16490      [MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[CONTENT_POS_LE] THEN
16491       ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; REAL_LT_IMP_LE];
16492       MATCH_MP_TAC HAS_INTEGRAL_SUB THEN
16493       REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL; INTEGRABLE_CONST] THEN
16494       MATCH_MP_TAC lemma2 THEN ASM_MESON_TAC[CONTINUOUS_ON_SUBSET];
16495       X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[] THEN
16496       MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN EXISTS_TAC
16497        `\y. (f:real^(M,N)finite_sum->real^P) (pastecart x y) - f t` THEN
16498       ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; REAL_LT_IMP_LE] THEN
16499       CONJ_TAC THENL
16500        [MATCH_MP_TAC HAS_INTEGRAL_SUB THEN
16501         REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL; INTEGRABLE_CONST] THEN
16502         MATCH_MP_TAC lemma1 THEN ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET];
16503         X_GEN_TAC `s:real^N` THEN DISCH_TAC THEN
16504         MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
16505         REPEAT CONJ_TAC THENL
16506          [ASM SET_TAC[];
16507           FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
16508            `s SUBSET t ==> x IN s ==> x IN t`)) THEN
16509           ASM_REWRITE_TAC[GSYM PCROSS_INTERVAL; PCROSS;
16510                           IN_ELIM_PASTECART_THM];
16511           RULE_ASSUM_TAC(REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM]) THEN
16512           ONCE_REWRITE_TAC[NORM_SUB] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
16513           EXISTS_TAC `l:real^(M,N)finite_sum->bool` THEN
16514           ASM_REWRITE_TAC[] THEN
16515           FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
16516            `s SUBSET t ==> x IN s ==> x IN t`)) THEN
16517           ASM_REWRITE_TAC[GSYM PCROSS_INTERVAL; PCROSS;
16518                           IN_ELIM_PASTECART_THM]]]]]);;
16519
16520 let INTEGRAL_SWAP_CONTINUOUS = prove
16521  (`!f:real^M->real^N->real^P a b c d.
16522         (\z. f (fstcart z) (sndcart z))
16523         continuous_on interval[pastecart a c,pastecart b d]
16524         ==> integral (interval[a,b]) (\x. integral (interval[c,d]) (f x)) =
16525             integral (interval[c,d])
16526                      (\y. integral (interval[a,b]) (\x. f x y))`,
16527   REPEAT STRIP_TAC THEN
16528   MP_TAC(ISPECL [`\z. (f:real^M->real^N->real^P) (fstcart z) (sndcart z)`;
16529    `a:real^M`; `b:real^M`; `c:real^N`; `d:real^N`]
16530    INTEGRAL_PASTECART_CONTINUOUS) THEN
16531   ASM_REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; ETA_AX] THEN
16532   DISCH_THEN(SUBST1_TAC o SYM) THEN
16533   MP_TAC(ISPECL [`\z. (f:real^M->real^N->real^P) (sndcart z) (fstcart z)`;
16534    `c:real^N`; `d:real^N`; `a:real^M`; `b:real^M`]
16535    INTEGRAL_PASTECART_CONTINUOUS) THEN
16536   ASM_REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART] THEN ANTS_TAC THENL
16537    [SUBGOAL_THEN
16538      `(\z. (f:real^M->real^N->real^P) (sndcart z) (fstcart z)) =
16539       (\z. (f:real^M->real^N->real^P) (fstcart z) (sndcart z)) o
16540       (\z. pastecart (sndcart z) (fstcart z))`
16541     SUBST1_TAC THENL
16542      [REWRITE_TAC[o_DEF; FSTCART_PASTECART; SNDCART_PASTECART];
16543       ALL_TAC] THEN
16544     MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
16545     SIMP_TAC[CONTINUOUS_ON_PASTECART; LINEAR_CONTINUOUS_ON;
16546              LINEAR_FSTCART; LINEAR_SNDCART] THEN
16547     FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16548       CONTINUOUS_ON_SUBSET)) THEN
16549     REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; PCROSS; GSYM PCROSS_INTERVAL] THEN
16550     REWRITE_TAC[FORALL_IN_GSPEC; IN_ELIM_PASTECART_THM] THEN
16551     SIMP_TAC[FSTCART_PASTECART; SNDCART_PASTECART];
16552     DISCH_THEN(SUBST1_TAC o SYM)] THEN
16553   CONV_TAC SYM_CONV THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
16554   MP_TAC(ISPECL
16555    [`\z. (f:real^M->real^N->real^P) (fstcart z) (sndcart z)`;
16556     `\z:real^(N,M)finite_sum. pastecart (sndcart z) (fstcart z)`;
16557     `\z:real^(M,N)finite_sum. pastecart (sndcart z) (fstcart z)`;
16558     `&1`;
16559     `integral (interval[pastecart a c,pastecart b d])
16560               (\z. (f:real^M->real^N->real^P) (fstcart z) (sndcart z))`;
16561     `pastecart (a:real^M) (c:real^N)`;
16562     `pastecart (b:real^M) (d:real^N)`]
16563   HAS_INTEGRAL_TWIDDLE) THEN
16564   REWRITE_TAC[FSTCART_PASTECART; SNDCART_PASTECART; REAL_INV_1; REAL_LT_01;
16565               PASTECART_FST_SND; VECTOR_MUL_LID; REAL_MUL_LID] THEN
16566   ASM_SIMP_TAC[GSYM HAS_INTEGRAL_INTEGRAL; INTEGRABLE_CONTINUOUS] THEN
16567   REWRITE_TAC[GSYM SIMPLE_IMAGE; FORALL_PASTECART; EXISTS_PASTECART;
16568               FSTCART_PASTECART; SNDCART_PASTECART; PCROSS;
16569               GSYM PCROSS_INTERVAL; IN_ELIM_PASTECART_THM] THEN
16570   REWRITE_TAC[REWRITE_RULE[PCROSS] PCROSS_INTERVAL] THEN
16571   CONV_TAC(ONCE_DEPTH_CONV
16572    (fun t -> if fst(dest_const(fst(strip_comb
16573                 (snd(dest_exists(snd(dest_exists t))))))) = "SETSPEC"
16574              then REWR_CONV SWAP_EXISTS_THM t else NO_CONV t)) THEN
16575   ONCE_REWRITE_TAC[SET_RULE
16576    `{pastecart (y:real^M) (x:real^N) | p x /\ q y} =
16577     {pastecart x y | q x /\ p y}`] THEN
16578   REWRITE_TAC[REWRITE_RULE[PCROSS] PCROSS_INTERVAL] THEN
16579   DISCH_THEN MATCH_MP_TAC  THEN
16580   SIMP_TAC[CONTINUOUS_PASTECART; LINEAR_CONTINUOUS_AT;
16581              LINEAR_FSTCART; LINEAR_SNDCART] THEN
16582   REWRITE_TAC[CONTENT_PASTECART] THEN
16583   REWRITE_TAC[REAL_MUL_SYM] THEN MESON_TAC[]);;
16584
16585 (* ------------------------------------------------------------------------- *)
16586 (* Rectifiable paths and path length defined using variation.                *)
16587 (* ------------------------------------------------------------------------- *)
16588
16589 let rectifiable_path = new_definition
16590  `rectifiable_path (g:real^1->real^N) <=>
16591     path g /\ g has_bounded_variation_on interval[vec 0,vec 1]`;;
16592
16593 let path_length = new_definition
16594  `path_length (g:real^1->real^N) =
16595   vector_variation (interval[vec 0,vec 1]) g`;;
16596
16597 let BOUNDED_RECTIFIABLE_PATH_IMAGE = prove
16598  (`!g:real^1->real^N. rectifiable_path g ==> bounded(path_image g)`,
16599   SIMP_TAC[rectifiable_path; BOUNDED_PATH_IMAGE]);;
16600
16601 let RECTIFIABLE_PATH_IMP_PATH = prove
16602  (`!g:real^1->real^N. rectifiable_path g ==> path g`,
16603   SIMP_TAC[rectifiable_path]);;
16604
16605 let RECTIFIABLE_PATH_LINEPATH = prove
16606  (`!a b:real^N. rectifiable_path(linepath(a,b))`,
16607   REPEAT GEN_TAC THEN REWRITE_TAC[rectifiable_path; PATH_LINEPATH] THEN
16608   REWRITE_TAC[linepath] THEN
16609   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_ADD THEN
16610   REWRITE_TAC[GSYM DROP_VEC; GSYM DROP_SUB] THEN
16611   CONJ_TAC THEN MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_MUL THEN
16612   REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_CONST] THEN
16613   REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_ID] THEN
16614   MATCH_MP_TAC HAS_BOUNDED_VARIATION_ON_SUB THEN
16615   REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_CONST] THEN
16616   REWRITE_TAC[HAS_BOUNDED_VARIATION_ON_ID]);;
16617
16618 let RECTIFIABLE_PATH_REVERSEPATH = prove
16619  (`!g:real^1->real^N. rectifiable_path(reversepath g) <=> rectifiable_path g`,
16620   SUBGOAL_THEN
16621    `!g:real^1->real^N. rectifiable_path g ==> rectifiable_path(reversepath g)`
16622    (fun th -> MESON_TAC[th; REVERSEPATH_REVERSEPATH]) THEN
16623   GEN_TAC THEN REWRITE_TAC[rectifiable_path] THEN
16624   MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[PATH_REVERSEPATH] THEN
16625   REWRITE_TAC[reversepath] THEN DISCH_TAC THEN
16626   GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
16627   MATCH_MP_TAC HAS_BOUNDED_VARIATION_COMPOSE_DECREASING THEN
16628   ASM_REWRITE_TAC[DROP_SUB; VECTOR_SUB_RZERO; VECTOR_SUB_REFL] THEN
16629   REAL_ARITH_TAC);;
16630
16631 let PATH_LENGTH_REVERSEPATH = prove
16632  (`!g:real^1->real^N. path_length(reversepath g) = path_length g`,
16633   GEN_TAC THEN REWRITE_TAC[path_length; reversepath] THEN
16634   REWRITE_TAC[VECTOR_SUB; VECTOR_VARIATION_REFLECT] THEN
16635   REWRITE_TAC[VECTOR_VARIATION_TRANSLATION] THEN
16636   REWRITE_TAC[REFLECT_INTERVAL; GSYM INTERVAL_TRANSLATION] THEN
16637   REWRITE_TAC[GSYM VECTOR_SUB; VECTOR_SUB_REFL; VECTOR_SUB_RZERO]);;
16638
16639 let RECTIFIABLE_PATH_SUBPATH = prove
16640  (`!u v g:real^1->real^N.
16641         rectifiable_path g /\
16642         u IN interval[vec 0,vec 1] /\
16643         v IN interval[vec 0,vec 1]
16644         ==> rectifiable_path(subpath u v g)`,
16645   REPEAT GEN_TAC THEN SIMP_TAC[PATH_SUBPATH; rectifiable_path] THEN
16646   STRIP_TAC THEN REWRITE_TAC[subpath] THEN
16647   ONCE_REWRITE_TAC[VECTOR_ADD_SYM] THEN
16648   REWRITE_TAC[HAS_BOUNDED_VARIATION_AFFINITY_EQ; IMAGE_AFFINITY_INTERVAL] THEN
16649   REWRITE_TAC[UNIT_INTERVAL_NONEMPTY; DROP_SUB; REAL_SUB_LE; REAL_SUB_0] THEN
16650   DISJ2_TAC THEN COND_CASES_TAC THEN
16651   FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
16652         HAS_BOUNDED_VARIATION_ON_SUBSET)) THEN
16653   REWRITE_TAC[SUBSET_INTERVAL_1] THEN
16654   REWRITE_TAC[DROP_ADD; DROP_CMUL; DROP_VEC] THEN
16655   RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1; DROP_VEC]) THEN
16656   ASM_REAL_ARITH_TAC);;
16657
16658 let RECTIFIABLE_PATH_JOIN = prove
16659  (`!g1 g2:real^1->real^N.
16660         pathfinish g1 = pathstart g2
16661         ==> (rectifiable_path(g1 ++ g2) <=>
16662              rectifiable_path g1 /\ rectifiable_path g2)`,
16663   REPEAT GEN_TAC THEN SIMP_TAC[rectifiable_path; PATH_JOIN] THEN
16664   REWRITE_TAC[pathfinish; pathstart] THEN DISCH_TAC THEN
16665   ASM_CASES_TAC `path(g1:real^1->real^N)` THEN ASM_REWRITE_TAC[] THEN
16666   ASM_CASES_TAC `path(g2:real^1->real^N)` THEN ASM_REWRITE_TAC[] THEN
16667   MP_TAC(ISPECL [`g1 ++ g2:real^1->real^N`; `vec 0:real^1`; `vec 1:real^1`;
16668                  `lift(&1 / &2)`]
16669         HAS_BOUNDED_VARIATION_ON_COMBINE) THEN
16670   REWRITE_TAC[DROP_VEC; LIFT_DROP] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
16671   DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[joinpaths] THEN BINOP_TAC THEN
16672   MATCH_MP_TAC EQ_TRANS THENL
16673    [EXISTS_TAC
16674      `(\x. (g1:real^1->real^N)(&2 % x)) has_bounded_variation_on
16675       interval [vec 0,lift(&1 / &2)]` THEN
16676     ONCE_REWRITE_TAC[VECTOR_ARITH `&2 % x:real^N = &2 % x + vec 0`];
16677     EXISTS_TAC
16678      `(\x. (g2:real^1->real^N)(&2 % x - vec 1)) has_bounded_variation_on
16679       interval [lift (&1 / &2),vec 1]` THEN
16680     ONCE_REWRITE_TAC[VECTOR_ARITH `&2 % x - v:real^N = &2 % x + --v`]] THEN
16681   (CONJ_TAC THENL
16682     [ALL_TAC;
16683      REWRITE_TAC[HAS_BOUNDED_VARIATION_AFFINITY_EQ] THEN
16684      REWRITE_TAC[IMAGE_AFFINITY_INTERVAL; INTERVAL_EQ_EMPTY_1] THEN
16685      REWRITE_TAC[DROP_VEC; LIFT_DROP] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
16686      AP_TERM_TAC THEN AP_TERM_TAC THEN
16687      REWRITE_TAC[CONS_11; PAIR_EQ; GSYM DROP_EQ] THEN
16688      REWRITE_TAC[DROP_ADD; DROP_CMUL; LIFT_DROP; DROP_VEC; DROP_NEG] THEN
16689      REAL_ARITH_TAC]) THEN
16690   MATCH_MP_TAC(MESON[HAS_BOUNDED_VARIATION_ON_EQ]
16691    `(!x. x IN s ==> f x = g x)
16692     ==> (f has_bounded_variation_on s <=>
16693          g has_bounded_variation_on s)`) THEN
16694   SIMP_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC] THEN X_GEN_TAC `x:real^1` THEN
16695   COND_CASES_TAC THEN REWRITE_TAC[] THEN STRIP_TAC THEN
16696   SUBGOAL_THEN `&2 % x + --vec 1:real^1 = vec 0 /\ &2 % x = vec 1`
16697     (fun th -> ASM_REWRITE_TAC[th]) THEN
16698   REWRITE_TAC[VECTOR_SUB_EQ; GSYM VECTOR_SUB] THEN
16699   REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_VEC] THEN ASM_REAL_ARITH_TAC);;
16700
16701 let RECTIFIABLE_PATH_JOIN_IMP = prove
16702  (`!g1 g2:real^1->real^N.
16703         rectifiable_path g1 /\ rectifiable_path g2 /\
16704         pathfinish g1 = pathstart g2
16705         ==> rectifiable_path(g1 ++ g2)`,
16706   SIMP_TAC[RECTIFIABLE_PATH_JOIN]);;
16707
16708 let RECTIFIABLE_PATH_JOIN_EQ = prove
16709  (`!g1 g2:real^1->real^N.
16710         rectifiable_path g1 /\ rectifiable_path g2
16711         ==> (rectifiable_path (g1 ++ g2) <=> pathfinish g1 = pathstart g2)`,
16712   REPEAT STRIP_TAC THEN EQ_TAC THEN
16713   ASM_SIMP_TAC[RECTIFIABLE_PATH_JOIN_IMP] THEN
16714   DISCH_TAC THEN MATCH_MP_TAC PATH_JOIN_PATH_ENDS THEN
16715   ASM_SIMP_TAC[RECTIFIABLE_PATH_IMP_PATH]);;
16716
16717 let PATH_LENGTH_JOIN = prove
16718  (`!g1 g2:real^1->real^N.
16719         rectifiable_path g1 /\ rectifiable_path g2 /\
16720         pathfinish g1 = pathstart g2
16721         ==> path_length(g1 ++ g2) = path_length g1 + path_length g2`,
16722   REPEAT STRIP_TAC THEN REWRITE_TAC[path_length] THEN
16723   MP_TAC(ISPECL [`g1 ++ g2:real^1->real^N`; `vec 0:real^1`; `vec 1:real^1`;
16724                  `lift(&1 / &2)`]
16725         VECTOR_VARIATION_COMBINE) THEN
16726   REWRITE_TAC[DROP_VEC; LIFT_DROP] THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
16727   ANTS_TAC THENL
16728    [ASM_MESON_TAC[rectifiable_path; RECTIFIABLE_PATH_JOIN_IMP];
16729     DISCH_THEN(SUBST1_TAC o SYM)] THEN
16730   MATCH_MP_TAC EQ_TRANS THEN EXISTS_TAC
16731    `vector_variation (interval [vec 0,lift (&1 / &2)])
16732                      (\x. (g1:real^1->real^N)(&2 % x)) +
16733     vector_variation (interval [lift (&1 / &2),vec 1])
16734                      (\x.  (g2:real^1->real^N)(&2 % x - vec 1))` THEN
16735   CONJ_TAC THENL
16736    [BINOP_TAC THEN MATCH_MP_TAC VECTOR_VARIATION_EQ THEN
16737     SIMP_TAC[IN_INTERVAL_1; LIFT_DROP; DROP_VEC; joinpaths] THEN
16738     RULE_ASSUM_TAC(REWRITE_RULE[pathfinish; pathstart]) THEN
16739     X_GEN_TAC `x:real^1` THEN
16740     REWRITE_TAC[IN_INTERVAL_1; DROP_VEC; LIFT_DROP] THEN
16741     COND_CASES_TAC THEN REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
16742     SUBGOAL_THEN `&2 % x - vec 1:real^1 = vec 0 /\ &2 % x = vec 1`
16743      (fun th -> ASM_REWRITE_TAC[th]) THEN
16744     REWRITE_TAC[VECTOR_SUB_EQ] THEN
16745     REWRITE_TAC[GSYM DROP_EQ; DROP_CMUL; DROP_VEC] THEN ASM_REAL_ARITH_TAC;
16746     ONCE_REWRITE_TAC[VECTOR_ARITH `&2 % x:real^N = &2 % x + vec 0`] THEN
16747     ONCE_REWRITE_TAC[VECTOR_ARITH
16748      `(&2 % x + vec 0) - v:real^N = &2 % x + --v`] THEN
16749     REWRITE_TAC[VECTOR_VARIATION_AFFINITY; IMAGE_AFFINITY_INTERVAL] THEN
16750     REWRITE_TAC[INTERVAL_EQ_EMPTY_1; LIFT_DROP; DROP_VEC] THEN
16751     CONV_TAC REAL_RAT_REDUCE_CONV THEN BINOP_TAC THEN
16752     AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
16753     REWRITE_TAC[CONS_11; PAIR_EQ; GSYM DROP_EQ] THEN
16754     REWRITE_TAC[DROP_ADD; DROP_CMUL; LIFT_DROP; DROP_VEC; DROP_NEG] THEN
16755     REAL_ARITH_TAC]);;
16756
16757 (* ------------------------------------------------------------------------- *)
16758 (* Useful equivalent formulations where the path is differentiable.          *)
16759 (* ------------------------------------------------------------------------- *)
16760
16761 let RECTIFIABLE_PATH_DIFFERENTIABLE = prove
16762  (`!g:real^1->real^N s.
16763         COUNTABLE s /\ path g /\
16764         (!t. t IN interval[vec 0,vec 1] DIFF s ==> g differentiable at t)
16765         ==> (rectifiable_path g <=>
16766                 (\t. vector_derivative g (at t))
16767                 absolutely_integrable_on interval[vec 0,vec 1])`,
16768   SIMP_TAC[rectifiable_path] THEN REWRITE_TAC[path] THEN
16769   REPEAT STRIP_TAC THEN MATCH_MP_TAC
16770     HAS_BOUNDED_VARIATION_ABSOLUTELY_INTEGRABLE_DERIVATIVE THEN
16771   EXISTS_TAC `s:real^1->bool` THEN ASM_REWRITE_TAC[]);;
16772
16773 let PATH_LENGTH_DIFFERENTIABLE = prove
16774  (`!g:real^1->real^N s.
16775         COUNTABLE s /\ rectifiable_path g /\
16776         (!t. t IN interval[vec 0,vec 1] DIFF s ==> g differentiable at t)
16777         ==> path_length g =
16778                 drop(integral (interval[vec 0,vec 1])
16779                               (\t. lift(norm(vector_derivative g (at t)))))`,
16780   REWRITE_TAC[rectifiable_path; path_length; path] THEN REPEAT STRIP_TAC THEN
16781   MATCH_MP_TAC VECTOR_VARIATION_INTEGRAL_NORM_DERIVATIVE THEN
16782   EXISTS_TAC `s:real^1->bool` THEN ASM_REWRITE_TAC[]);;