(* ========================================================================= *)
(* Kurzweil-Henstock gauge integration in many dimensions.                   *)
(*                                                                           *)
(*              (c) Copyright, John Harrison 1998-2008                       *)
(* ========================================================================= *)
needs "Library/products.ml";;
needs "Library/floor.ml";;
needs "Multivariate/derivatives.ml";;
prioritize_real();;
(* ------------------------------------------------------------------------- *)
(* Some useful lemmas about intervals.                                       *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* This lemma about iterations comes up in a few places.                     *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Bounds on intervals where they exist.                                     *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Content (length, area, volume...) of an interval.                         *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* The notion of a gauge --- simply an open set containing the point.        *)
(* ------------------------------------------------------------------------- *)
(* ------------------------------------------------------------------------- *)
(* Divisions.                                                                *)
(* ------------------------------------------------------------------------- *)
parse_as_infix("division_of",(12,"right"));;
let DIVISION_UNION_INTERVALS_EXISTS = prove
 (`!a b c d:real^N.
        ~(
interval[a,b] = {})
        ==> ?p. (
interval[a,b] 
INSERT p) 
division_of
                (
interval[a,b] 
UNION interval[c,d])`,
  REPEAT STRIP_TAC THEN
  ASM_CASES_TAC `
interval[c:real^N,d] = {}` THENL
   [ASM_REWRITE_TAC[
UNION_EMPTY] THEN ASM_MESON_TAC[
DIVISION_OF_SELF];
    ALL_TAC] THEN
  ASM_CASES_TAC `
interval[a:real^N,b] 
INTER interval[c,d] = {}` THENL
   [EXISTS_TAC `{
interval[c:real^N,d]}` THEN
    ONCE_REWRITE_TAC[SET_RULE `{a,b} = {a} 
UNION {b}`] THEN
    MATCH_MP_TAC 
DIVISION_DISJOINT_UNION THEN
    ASM_SIMP_TAC[
DIVISION_OF_SELF] THEN
    MATCH_MP_TAC(SET_RULE
     `
interior s 
SUBSET s /\ 
interior t 
SUBSET t /\ s 
INTER t = {}
      ==> 
interior s 
INTER interior t = {}`) THEN
    ASM_REWRITE_TAC[
INTERIOR_SUBSET];
    ALL_TAC] THEN
  SUBGOAL_THEN
   `?u v:real^N. 
interval[a,b] 
INTER interval[c,d] = 
interval[u,v]`
  STRIP_ASSUME_TAC THENL [MESON_TAC[
INTER_INTERVAL]; ALL_TAC] THEN
  MP_TAC(ISPECL [`c:real^N`; `d:real^N`; `u:real^N`; `v:real^N`]
                
PARTIAL_DIVISION_EXTEND_1) THEN
  ANTS_TAC THENL [ASM_MESON_TAC[
INTER_SUBSET]; ALL_TAC] THEN
  DISCH_THEN(X_CHOOSE_THEN `p:(real^N->bool)->bool` STRIP_ASSUME_TAC) THEN
  EXISTS_TAC `p 
DELETE interval[u:real^N,v]` THEN
  SUBGOAL_THEN `
interval[a:real^N,b] 
UNION interval[c,d] =
                
interval[a,b] 
UNION UNIONS(p 
DELETE interval[u,v])`
  SUBST1_TAC THENL
   [FIRST_ASSUM(SUBST1_TAC o SYM o last o CONJUNCTS o
                GEN_REWRITE_RULE I [
division_of]) THEN
    ASM SET_TAC[];
    ALL_TAC] THEN
  ONCE_REWRITE_TAC[SET_RULE `x 
INSERT s = {x} 
UNION s`] THEN
  MATCH_MP_TAC 
DIVISION_DISJOINT_UNION THEN
  ASM_SIMP_TAC[
DIVISION_OF_SELF] THEN CONJ_TAC THENL
   [MATCH_MP_TAC 
DIVISION_OF_SUBSET THEN
    EXISTS_TAC `p:(real^N->bool)->bool` THEN
    ASM_MESON_TAC[
DIVISION_OF_UNION_SELF; 
DELETE_SUBSET];
    ALL_TAC] THEN
  REWRITE_TAC[GSYM 
INTERIOR_INTER] THEN
  MATCH_MP_TAC 
EQ_TRANS THEN
  EXISTS_TAC `
interior(
interval[u:real^N,v] 
INTER
              UNIONS (p 
DELETE interval[u,v]))` THEN
  CONJ_TAC THENL
   [AP_TERM_TAC THEN MATCH_MP_TAC(SET_RULE
     `!cd. p 
SUBSET cd /\ uv = ab 
INTER cd
           ==> (ab 
INTER p = uv 
INTER p)`) THEN
    EXISTS_TAC `
interval[c:real^N,d]` THEN
    ASM_REWRITE_TAC[
UNIONS_SUBSET; 
IN_DELETE] THEN
    ASM_MESON_TAC[
division_of];
    REWRITE_TAC[
INTERIOR_INTER] THEN
    MATCH_MP_TAC 
INTER_INTERIOR_UNIONS_INTERVALS THEN
    REWRITE_TAC[
IN_DELETE; 
OPEN_INTERIOR; 
FINITE_DELETE] THEN
    ASM_MESON_TAC[
division_of]]);;
 
let ELEMENTARY_UNION_INTERVAL_STRONG = prove
 (`!p a b:real^N.
        p 
division_of (
UNIONS p)
        ==> ?q. p 
SUBSET q /\ q 
division_of (
interval[a,b] 
UNION UNIONS p)`,
  REPEAT STRIP_TAC THEN ASM_CASES_TAC `p:(real^N->bool)->bool = {}` THENL
   [ASM_REWRITE_TAC[
UNIONS_0; 
UNION_EMPTY; 
EMPTY_SUBSET] THEN
    MESON_TAC[
ELEMENTARY_INTERVAL];
    ALL_TAC] THEN
  ASM_CASES_TAC `
interval[a:real^N,b] = {}` THEN
  ASM_REWRITE_TAC[
UNION_EMPTY] THENL [ASM_MESON_TAC[
SUBSET_REFL]; ALL_TAC] THEN
  ASM_CASES_TAC `
interior(
interval[a:real^N,b]) = {}` THENL
   [EXISTS_TAC `
interval[a:real^N,b] 
INSERT p` THEN
    REWRITE_TAC[
division_of] THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
division_of]) THEN
    SIMP_TAC[
FINITE_INSERT; 
UNIONS_INSERT] THEN ASM SET_TAC[];
    ALL_TAC] THEN
  ASM_CASES_TAC `
interval[a:real^N,b] 
SUBSET UNIONS p` THENL
   [ASM_SIMP_TAC[SET_RULE `s 
SUBSET t ==> s 
UNION t = t`] THEN
    ASM_MESON_TAC[
SUBSET_REFL];
    ALL_TAC] THEN
  SUBGOAL_THEN
   `!k:real^N->bool. k 
IN p
                     ==> ?q. ~(k 
IN q) /\ ~(q = {}) /\
                             (k 
INSERT q) 
division_of (
interval[a,b] 
UNION k)`
  MP_TAC THENL
   [X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
    FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
division_of]) THEN
    DISCH_THEN(MP_TAC o SPEC `k:real^N->bool` o CONJUNCT1 o CONJUNCT2) THEN
    ASM_REWRITE_TAC[] THEN
    REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
    REWRITE_TAC[
LEFT_IMP_EXISTS_THM] THEN
    MAP_EVERY X_GEN_TAC [`c:real^N`; `d:real^N`] THEN
    DISCH_THEN SUBST_ALL_TAC THEN
    ONCE_REWRITE_TAC[
UNION_COMM] THEN
    MP_TAC(ISPECL [`c:real^N`; `d:real^N`; `a:real^N`; `b:real^N`]
        
DIVISION_UNION_INTERVALS_EXISTS) THEN
    ASM_REWRITE_TAC[] THEN
    DISCH_THEN(X_CHOOSE_TAC `q:(real^N->bool)->bool`) THEN
    EXISTS_TAC `q 
DELETE interval[c:real^N,d]` THEN
    ASM_REWRITE_TAC[
IN_DELETE; SET_RULE
     `x 
INSERT (q 
DELETE x) = x 
INSERT q`] THEN
    DISCH_TAC THEN
    UNDISCH_TAC `(
interval[c:real^N,d] 
INSERT q) 
division_of
                 (
interval [c,d] 
UNION interval [a,b])` THEN
    ASM_SIMP_TAC[SET_RULE `s 
DELETE x = {} ==> x 
INSERT s = {x}`] THEN
    REWRITE_TAC[
division_of; 
UNIONS_1] THEN ASM SET_TAC[];
    ALL_TAC] THEN
  GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [
RIGHT_IMP_EXISTS_THM] THEN
  REWRITE_TAC[
SKOLEM_THM] THEN
  DISCH_THEN(X_CHOOSE_TAC `q:(real^N->bool)->(real^N->bool)->bool`) THEN
  MP_TAC(ISPEC `
IMAGE (
UNIONS o (q:(real^N->bool)->(real^N->bool)->bool)) p`
    
ELEMENTARY_INTERS) THEN
  FIRST_ASSUM(ASSUME_TAC o MATCH_MP 
DIVISION_OF_FINITE) THEN
  ASM_SIMP_TAC[
FINITE_IMAGE; 
IMAGE_EQ_EMPTY; 
FORALL_IN_IMAGE] THEN
  ANTS_TAC THENL
   [X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
    EXISTS_TAC `(q:(real^N->bool)->(real^N->bool)->bool) k` THEN
    REWRITE_TAC[
o_THM] THEN MATCH_MP_TAC 
DIVISION_OF_SUBSET THEN
    EXISTS_TAC `(k:real^N->bool) 
INSERT q k` THEN
    CONJ_TAC THENL [ASM_MESON_TAC[
DIVISION_OF_UNION_SELF]; SET_TAC[]];
    DISCH_THEN(X_CHOOSE_TAC `r:(real^N->bool)->bool`)] THEN
  EXISTS_TAC `p 
UNION r:(real^N->bool)->bool` THEN SIMP_TAC[
SUBSET_UNION] THEN
  SUBGOAL_THEN
   `
interval[a:real^N,b] 
UNION UNIONS p =
    
UNIONS p 
UNION INTERS(
IMAGE (
UNIONS o q) p)`
  SUBST1_TAC THENL
   [GEN_REWRITE_TAC I [
EXTENSION] THEN X_GEN_TAC `y:real^N` THEN
    REWRITE_TAC[
IN_UNION] THEN
    ASM_CASES_TAC `(y:real^N) 
IN UNIONS p` THEN ASM_REWRITE_TAC[
IN_INTERS] THEN
    REWRITE_TAC[
FORALL_IN_UNIONS; 
IMP_CONJ; 
FORALL_IN_IMAGE;
                
RIGHT_FORALL_IMP_THM] THEN
    SUBGOAL_THEN
     `!k. k 
IN p ==> 
UNIONS(k 
INSERT q k) = 
interval[a:real^N,b] 
UNION k`
    MP_TAC THENL [ASM_MESON_TAC[
division_of]; ALL_TAC] THEN
    REWRITE_TAC[
UNIONS_INSERT; 
o_THM] THEN
    GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [
EXTENSION] THEN
    REWRITE_TAC[
RIGHT_IMP_FORALL_THM; 
IN_UNION] THEN
    ONCE_REWRITE_TAC[
SWAP_FORALL_THM] THEN
    DISCH_THEN(MP_TAC o SPEC `y:real^N`) THEN
    UNDISCH_TAC `~((y:real^N) 
IN UNIONS p)` THEN
    SIMP_TAC[
IN_UNIONS; 
NOT_EXISTS_THM; TAUT `~(a /\ b) <=> a ==> ~b`] THEN
    ASM_CASES_TAC `(y:real^N) 
IN interval[a,b]` THEN
    ASM_REWRITE_TAC[] THEN ASM SET_TAC[];
    ALL_TAC] THEN
  MATCH_MP_TAC 
DIVISION_DISJOINT_UNION THEN
  ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[
INTER_COMM] THEN
  MATCH_MP_TAC 
INTER_INTERIOR_UNIONS_INTERVALS THEN
  ASM_REWRITE_TAC[
OPEN_INTERIOR] THEN
  CONJ_TAC THENL [ASM_MESON_TAC[
division_of]; ALL_TAC] THEN
  X_GEN_TAC `k:real^N->bool` THEN DISCH_TAC THEN
  ASM_SIMP_TAC[
INTERIOR_FINITE_INTERS; 
FINITE_IMAGE] THEN
  MATCH_MP_TAC(SET_RULE `(?x. x 
IN p /\ f x 
INTER s = {})
                        ==> 
INTERS (
IMAGE f p) 
INTER s = {}`) THEN
  REWRITE_TAC[
EXISTS_IN_IMAGE; 
o_THM] THEN EXISTS_TAC `k:real^N->bool` THEN
  ASM_REWRITE_TAC[] THEN
  ONCE_REWRITE_TAC[
INTER_COMM] THEN
  MATCH_MP_TAC 
INTER_INTERIOR_UNIONS_INTERVALS THEN
  ASM_REWRITE_TAC[
OPEN_INTERIOR] THEN REPEAT CONJ_TAC THENL
   [ASM_MESON_TAC[
division_of; 
FINITE_INSERT; 
IN_INSERT];
    ASM_MESON_TAC[
division_of; 
FINITE_INSERT; 
IN_INSERT];
    ALL_TAC] THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `k:real^N->bool`) THEN
  ASM_REWRITE_TAC[
division_of; 
IN_INSERT] THEN
  REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[]);;
 
let DIVISION_OF_NONTRIVIAL = prove
 (`!s a b:real^N.
        s 
division_of interval[a,b] /\ ~(
content(
interval[a,b]) = &0)
        ==> {k | k 
IN s /\ ~(
content k = &0)} 
division_of interval[a,b]`,
  REPEAT GEN_TAC THEN WF_INDUCT_TAC `
CARD(s:(real^N->bool)->bool)` THEN
  REPEAT STRIP_TAC THEN
  ASM_CASES_TAC `{k:real^N->bool | k 
IN s /\ ~(
content k = &0)} = s` THEN
  ASM_REWRITE_TAC[] THEN
  FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [
EXTENSION]) THEN
  REWRITE_TAC[
IN_ELIM_THM; 
NOT_FORALL_THM; 
LEFT_IMP_EXISTS_THM] THEN
  REWRITE_TAC[TAUT `~(a /\ ~b <=> a) <=> a /\ b`] THEN
  X_GEN_TAC `k:real^N->bool` THEN STRIP_TAC THEN
  FIRST_ASSUM(ASSUME_TAC o MATCH_MP 
DIVISION_OF_FINITE) THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `s 
DELETE (k:real^N->bool)`) THEN
  ASM_SIMP_TAC[
CARD_DELETE; ARITH_RULE `n - 1 < n <=> ~(n = 0)`] THEN
  ASM_SIMP_TAC[
CARD_EQ_0] THEN ANTS_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
  ANTS_TAC THENL
   [ALL_TAC;
    MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN
    ASM SET_TAC[]] THEN
  REWRITE_TAC[
DIVISION_OF] THEN
  FIRST_X_ASSUM(STRIP_ASSUME_TAC o GEN_REWRITE_RULE I [
division_of]) THEN
  ASM_SIMP_TAC[
FINITE_DELETE; 
IN_DELETE] THEN
  FIRST_ASSUM(MP_TAC o C MATCH_MP (ASSUME `(k:real^N->bool) 
IN s`)) THEN
  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
  REWRITE_TAC[
LEFT_IMP_EXISTS_THM] THEN
  MAP_EVERY X_GEN_TAC [`c:real^N`; `d:real^N`] THEN
  DISCH_THEN SUBST_ALL_TAC THEN
  MATCH_MP_TAC(SET_RULE
    `
UNIONS s = i /\ k 
SUBSET UNIONS(s 
DELETE k)
     ==> 
UNIONS(s 
DELETE k) = i`) THEN
  ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(MESON[
CLOSED_LIMPT; 
SUBSET]
   `
closed s /\ (!x. x 
IN k ==> x 
limit_point_of s) ==> k 
SUBSET s`) THEN
  CONJ_TAC THENL
   [MATCH_MP_TAC 
CLOSED_UNIONS THEN
    ASM_REWRITE_TAC[
FINITE_DELETE; 
IN_DELETE] THEN
    ASM_MESON_TAC[
CLOSED_INTERVAL];
    ALL_TAC] THEN
  X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN REWRITE_TAC[
LIMPT_APPROACHABLE] THEN
  X_GEN_TAC `e:real` THEN DISCH_TAC THEN REWRITE_TAC[
dist] THEN
  SUBGOAL_THEN `?y:real^N. y 
IN UNIONS s /\ ~(y 
IN interval[c,d]) /\
                           ~(y = x) /\ 
norm(y - x) < e`
  MP_TAC THENL [ALL_TAC; SET_TAC[]] THEN ASM_REWRITE_TAC[] THEN
  MAP_EVERY UNDISCH_TAC
   [`~(
content(
interval[a:real^N,b]) = &0)`;
    `
content(
interval[c:real^N,d]) = &0`] THEN
  REWRITE_TAC[
CONTENT_EQ_0; 
NOT_EXISTS_THM] THEN
  DISCH_THEN(X_CHOOSE_THEN `i:num` STRIP_ASSUME_TAC) THEN
  DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[
REAL_NOT_LE] THEN
  DISCH_TAC THEN UNDISCH_TAC `~(
interval[c:real^N,d] = {})` THEN
  REWRITE_TAC[
INTERVAL_EQ_EMPTY; 
NOT_EXISTS_THM] THEN
  DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[
REAL_NOT_LT] THEN
  ASM_SIMP_TAC[REAL_ARITH `a <= b ==> (b <= a <=> a = b)`] THEN
  DISCH_THEN(fun 
th -> SUBST_ALL_TAC 
th THEN ASSUME_TAC 
th) THEN
  UNDISCH_TAC `
interval[c:real^N,d] 
SUBSET interval[a,b]` THEN
  REWRITE_TAC[
SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN
  ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
  MP_TAC(ASSUME `(x:real^N) 
IN interval[c,d]`) THEN
  GEN_REWRITE_TAC LAND_CONV [
IN_INTERVAL] THEN
  DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
  ASM_SIMP_TAC[REAL_ARITH `d = c ==> (c <= x /\ x <= d <=> x = c)`] THEN
  DISCH_TAC THEN
  MP_TAC(ASSUME `(x:real^N) 
IN interval[a,b]`) THEN
  GEN_REWRITE_TAC LAND_CONV [
IN_INTERVAL] THEN
  DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
  STRIP_TAC THEN EXISTS_TAC
   `(
lambda j. if j = i then
                 if (c:real^N)$i <= ((a:real^N)$i + (b:real^N)$i) / &2
                 then c$i + min e (b$i - c$i) / &2
                 else c$i - min e (c$i - a$i) / &2
               else (x:real^N)$j):real^N` THEN
  SIMP_TAC[
IN_INTERVAL; 
LAMBDA_BETA; 
CART_EQ] THEN REPEAT CONJ_TAC THENL
   [X_GEN_TAC `j:num` THEN STRIP_TAC THEN
    UNDISCH_TAC `(x:real^N) 
IN interval[a,b]` THEN
    REWRITE_TAC[
IN_INTERVAL] THEN DISCH_THEN(MP_TAC o SPEC `j:num`) THEN
    ASM_REWRITE_TAC[] THEN COND_CASES_TAC THEN REWRITE_TAC[] THEN
    FIRST_X_ASSUM SUBST_ALL_TAC THEN
    ASM_REAL_ARITH_TAC;
    DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
    ASM_REAL_ARITH_TAC;
    DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
    ASM_REAL_ARITH_TAC;
    REWRITE_TAC[
vector_norm; 
dot] THEN
    SIMP_TAC[
LAMBDA_BETA; 
VECTOR_SUB_COMPONENT; GSYM REAL_POW_2] THEN
    REWRITE_TAC[REAL_ARITH
     `((if p then x else y) - y) pow 2 = if p then (x - y) pow 2 else &0`] THEN
    ASM_SIMP_TAC[
SUM_DELTA; 
IN_NUMSEG; 
POW_2_SQRT_ABS] THEN
    ASM_REAL_ARITH_TAC]);;
 
let INTERVAL_BISECTION_STEP = prove
 (`!P. P {} /\
       (!s t. P s /\ P t /\ 
interior(s) 
INTER interior(t) = {}
              ==> P(s 
UNION t))
       ==> !a b:real^N.
                ~(P(
interval[a,b]))
                ==> ?c d. ~(P(
interval[c,d])) /\
                          !i. 1 <= i /\ i <= 
dimindex(:N)
                              ==> a$i <= c$i /\ c$i <= d$i /\ d$i <= b$i /\
                                  &2 * (d$i - c$i) <= b$i - a$i`,
  REPEAT GEN_TAC THEN STRIP_TAC THEN REPEAT GEN_TAC THEN
  ASM_CASES_TAC `!i. 1 <= i /\ i <= 
dimindex(:N)
                     ==> (a:real^N)$i <= (b:real^N)$i` THENL
   [ALL_TAC;
    RULE_ASSUM_TAC(REWRITE_RULE[GSYM 
INTERVAL_NE_EMPTY]) THEN
    ASM_REWRITE_TAC[]] THEN
  SUBGOAL_THEN
   `!f. FINITE f /\
        (!s:real^N->bool. s 
IN f ==> P s) /\
        (!s:real^N->bool. s 
IN f ==> ?a b. s = 
interval[a,b]) /\
        (!s t. s 
IN f /\ t 
IN f /\ ~(s = t)
               ==> 
interior(s) 
INTER interior(t) = {})
        ==> P(
UNIONS f)`
  ASSUME_TAC THENL
   [ONCE_REWRITE_TAC[
IMP_CONJ] THEN MATCH_MP_TAC 
FINITE_INDUCT_STRONG THEN
    ASM_SIMP_TAC[
UNIONS_0; 
UNIONS_INSERT; 
NOT_IN_EMPTY; 
FORALL_IN_INSERT] THEN
    REWRITE_TAC[IMP_IMP] THEN REPEAT GEN_TAC THEN DISCH_THEN(fun 
th ->
      FIRST_X_ASSUM MATCH_MP_TAC THEN STRIP_ASSUME_TAC 
th) THEN
    ASM_REWRITE_TAC[] THEN CONJ_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
    MATCH_MP_TAC 
INTER_INTERIOR_UNIONS_INTERVALS THEN
    ASM_REWRITE_TAC[
OPEN_INTERIOR] THEN REPEAT STRIP_TAC THEN
    FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[
IN_INSERT] THEN
    ASM_MESON_TAC[];
    ALL_TAC] THEN
  DISCH_TAC THEN
  FIRST_X_ASSUM(MP_TAC o SPEC
   `{ 
interval[c,d] |
      !i. 1 <= i /\ i <= 
dimindex(:N)
          ==> ((c:real^N)$i = (a:real^N)$i) /\ (d$i = (a$i + b$i) / &2) \/
              (c$i = (a$i + b$i) / &2) /\ ((d:real^N)$i = (b:real^N)$i)}`) THEN
  ONCE_REWRITE_TAC[
IMP_CONJ] THEN ANTS_TAC THENL
   [MATCH_MP_TAC 
FINITE_SUBSET THEN
    EXISTS_TAC
     `
IMAGE (\s. 
closed_interval
       [(
lambda i. if i 
IN s then (a:real^N)$i else (a$i + b$i) / &2):real^N,
        (
lambda i. if i 
IN s then (a$i + b$i) / &2 else (b:real^N)$i)])
         {s | s 
SUBSET (1..dimindex(:N))}` THEN
    CONJ_TAC THENL
     [SIMP_TAC[
FINITE_POWERSET; 
FINITE_IMAGE; 
FINITE_NUMSEG]; ALL_TAC] THEN
    REWRITE_TAC[
SUBSET; 
IN_ELIM_THM; 
IN_IMAGE] THEN
    X_GEN_TAC `k:real^N->bool` THEN
    DISCH_THEN(X_CHOOSE_THEN `c:real^N` (X_CHOOSE_THEN `d:real^N`
      (CONJUNCTS_THEN2 ASSUME_TAC SUBST1_TAC))) THEN
    EXISTS_TAC `{i | 1 <= i /\ i <= 
dimindex(:N) /\
                     ((c:real^N)$i = (a:real^N)$i)}` THEN
    CONJ_TAC THENL [ALL_TAC; SIMP_TAC[
IN_ELIM_THM; 
IN_NUMSEG]] THEN
    AP_TERM_TAC THEN REWRITE_TAC[
CONS_11; 
PAIR_EQ] THEN
    SIMP_TAC[
CART_EQ; 
LAMBDA_BETA; 
IN_ELIM_THM] THEN
    REPEAT(FIRST_X_ASSUM(MP_TAC o GEN `i:num` o SPEC `i:num`)) THEN
    REWRITE_TAC[IMP_IMP; 
AND_FORALL_THM] THEN
    MATCH_MP_TAC 
MONO_FORALL THEN GEN_TAC THEN
    REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> (a ==> b /\ c)`] THEN
    MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
    COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
    SIMP_TAC[
REAL_EQ_RDIV_EQ; 
REAL_OF_NUM_LT; ARITH] THEN
    REAL_ARITH_TAC;
    ALL_TAC] THEN
  GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN ANTS_TAC THENL
   [UNDISCH_TAC `~P(
interval[a:real^N,b])` THEN MATCH_MP_TAC EQ_IMP THEN
    AP_TERM_TAC THEN AP_TERM_TAC THEN CONV_TAC SYM_CONV THEN
    GEN_REWRITE_TAC I [
EXTENSION] THEN
    REWRITE_TAC[
IN_UNIONS; 
IN_ELIM_THM] THEN X_GEN_TAC `x:real^N` THEN
    REWRITE_TAC[
LEFT_AND_EXISTS_THM] THEN
    ONCE_REWRITE_TAC[TAUT `(a /\ b) /\ c <=> b /\ a /\ c`] THEN
    GEN_REWRITE_TAC LAND_CONV [
SWAP_EXISTS_THM] THEN
    GEN_REWRITE_TAC (LAND_CONV o BINDER_CONV) [
SWAP_EXISTS_THM] THEN
    REWRITE_TAC[
UNWIND_THM2; 
IN_INTERVAL] THEN
    REWRITE_TAC[
AND_FORALL_THM] THEN
    REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> (a ==> b /\ c)`] THEN
    REWRITE_TAC[GSYM 
LAMBDA_SKOLEM] THEN AP_TERM_TAC THEN
    GEN_REWRITE_TAC I [
FUN_EQ_THM] THEN X_GEN_TAC `i:num` THEN
    REWRITE_TAC[] THEN
    MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> ((a ==> b) <=> (a ==> c))`) THEN
    STRIP_TAC THEN
    ONCE_REWRITE_TAC[TAUT `(a \/ b) /\ c <=> ~(a ==> ~c) \/ ~(b ==> ~c)`] THEN
    SIMP_TAC[] THEN
    REWRITE_TAC[TAUT `~(a ==> ~b) <=> a /\ b`; GSYM 
CONJ_ASSOC] THEN
    REWRITE_TAC[
EXISTS_OR_THM; 
RIGHT_EXISTS_AND_THM] THEN
    REWRITE_TAC[
LEFT_EXISTS_AND_THM; 
EXISTS_REFL] THEN
    SIMP_TAC[
REAL_LE_LDIV_EQ; 
REAL_LE_RDIV_EQ; 
REAL_OF_NUM_LT; ARITH] THEN
    REAL_ARITH_TAC;
    ALL_TAC] THEN
  REWRITE_TAC[
FORALL_IN_GSPEC] THEN
  MATCH_MP_TAC(TAUT `b /\ (~a ==> e) /\ c ==> ~(a /\ b /\ c) ==> e`) THEN
  CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN CONJ_TAC THENL
   [REWRITE_TAC[
NOT_FORALL_THM; NOT_IMP] THEN
    REPEAT(MATCH_MP_TAC 
MONO_EXISTS THEN GEN_TAC) THEN
    DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN ASM_REWRITE_TAC[] THEN
    MATCH_MP_TAC 
MONO_FORALL THEN X_GEN_TAC `i:num` THEN
    DISCH_THEN(fun 
th -> REPEAT DISCH_TAC THEN MP_TAC 
th) THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
    REAL_ARITH_TAC;
    ALL_TAC] THEN
  REWRITE_TAC[
IMP_CONJ; 
RIGHT_FORALL_IMP_THM; 
FORALL_IN_GSPEC] THEN
  REWRITE_TAC[IMP_IMP; 
INTERIOR_CLOSED_INTERVAL] THEN
  REWRITE_TAC[
RIGHT_IMP_FORALL_THM] THEN
  MAP_EVERY X_GEN_TAC
   [`c1:real^N`; `d1:real^N`; `c2:real^N`; `d2:real^N`] THEN
  ASM_CASES_TAC `(
c1 = c2:real^N) /\ (d1 = d2:real^N)` THENL
   [ASM_REWRITE_TAC[]; ALL_TAC] THEN
  DISCH_THEN(fun 
th ->
    DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (K ALL_TAC)) THEN MP_TAC 
th) THEN
  REWRITE_TAC[IMP_IMP] THEN
  UNDISCH_TAC `~((
c1 = c2:real^N) /\ (d1 = d2:real^N))` THEN
  REWRITE_TAC[
CART_EQ; 
INTERIOR_CLOSED_INTERVAL] THEN
  REWRITE_TAC[
AND_FORALL_THM] THEN
  REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> (a ==> b /\ c)`] THEN
  REWRITE_TAC[
NOT_FORALL_THM] THEN
  DISCH_THEN(X_CHOOSE_THEN `j:num` (fun 
th ->
    DISCH_THEN(MP_TAC o SPEC `j:num`) THEN MP_TAC 
th)) THEN
  REWRITE_TAC[NOT_IMP] THEN
  DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC MP_TAC) THEN
  ASM_REWRITE_TAC[IMP_IMP] THEN
  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
  ASM_REWRITE_TAC[
EXTENSION; 
IN_INTERVAL; 
NOT_IN_EMPTY; 
IN_INTER] THEN
  SIMP_TAC[
REAL_EQ_RDIV_EQ; 
REAL_EQ_LDIV_EQ; 
REAL_OF_NUM_LT; ARITH] THEN
  REWRITE_TAC[
    REAL_ARITH `~((a * &2 = a + b) /\ (a + b = b * &2)) <=> ~(a = b)`;
    REAL_ARITH `~((a + b = a * &2) /\ (b * &2 = a + b)) <=> ~(a = b)`] THEN
  DISCH_THEN(fun 
th -> X_GEN_TAC `x:real^N` THEN MP_TAC 
th) THEN
  REWRITE_TAC[
AND_FORALL_THM] THEN
  REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> (a ==> b /\ c)`] THEN
  ASM_REWRITE_TAC[CONTRAPOS_THM] THEN
  DISCH_THEN(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN
  REAL_ARITH_TAC);;
 
let INTERVAL_BISECTION = prove
 (`!P. P {} /\
       (!s t. P s /\ P t /\ 
interior(s) 
INTER interior(t) = {}
              ==> P(s 
UNION t))
       ==> !a b:real^N.
                ~(P(
interval[a,b]))
                ==> ?x. x 
IN interval[a,b] /\
                        !e. &0 < e
                            ==> ?c d. x 
IN interval[c,d] /\
                                      
interval[c,d] 
SUBSET ball(x,e) /\
                                      
interval[c,d] 
SUBSET interval[a,b] /\
                                      ~P(
interval[c,d])`,
  REPEAT STRIP_TAC THEN
  SUBGOAL_THEN
   `?A B. (A(0) = a:real^N) /\ (B(0) = b) /\
          !n. ~(P(
interval[A(SUC n),B(SUC n)])) /\
              !i. 1 <= i /\ i <= 
dimindex(:N)
                       ==> A(n)$i <= A(SUC n)$i /\
                           A(SUC n)$i <= B(SUC n)$i /\
                           B(SUC n)$i <= B(n)$i /\
                           &2 * (B(SUC n)$i - A(SUC n)$i) <= B(n)$i - A(n)$i`
  STRIP_ASSUME_TAC THENL
   [MP_TAC(ISPEC `P:(real^N->bool)->bool` 
INTERVAL_BISECTION_STEP) THEN
    ASM_REWRITE_TAC[] THEN
    GEN_REWRITE_TAC (LAND_CONV o TOP_DEPTH_CONV) [
RIGHT_IMP_EXISTS_THM] THEN
    REWRITE_TAC[
SKOLEM_THM] THEN
    DISCH_THEN(X_CHOOSE_THEN `C:real^N->real^N->real^N`
     (X_CHOOSE_THEN `D:real^N->real^N->real^N` ASSUME_TAC)) THEN
    MP_TAC(prove_recursive_functions_exist num_RECURSION
     `(E 0 = a:real^N,b:real^N) /\
      (!n. E(SUC n) = C (
FST(E n)) (
SND(E n)),
                      D (
FST(E n)) (
SND(E n)))`) THEN
    DISCH_THEN(X_CHOOSE_THEN `E:num->real^N#real^N` STRIP_ASSUME_TAC) THEN
    EXISTS_TAC `\n. 
FST((E:num->real^N#real^N) n)` THEN
    EXISTS_TAC `\n. 
SND((E:num->real^N#real^N) n)` THEN
    ASM_REWRITE_TAC[] THEN INDUCT_TAC THEN ASM_SIMP_TAC[];
    ALL_TAC] THEN
  SUBGOAL_THEN
   `!e. &0 < e
        ==> ?n:num. !x y. x 
IN interval[A(n),B(n)] /\ y 
IN interval[A(n),B(n)]
                          ==> 
dist(x,y:real^N) < e`
  ASSUME_TAC THENL
   [X_GEN_TAC `e:real` THEN DISCH_TAC THEN MP_TAC(SPEC
     `
sum(1..dimindex(:N)) (\i. (b:real^N)$i - (a:real^N)$i) / e`
     
REAL_ARCH_POW2) THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
    MAP_EVERY X_GEN_TAC [`x:real^N`; `y:real^N`] THEN STRIP_TAC THEN
    MATCH_MP_TAC 
REAL_LET_TRANS THEN
    EXISTS_TAC `
sum(1..dimindex(:N))(\i. abs((x - y:real^N)$i))` THEN
    REWRITE_TAC[
dist; 
NORM_LE_L1] THEN
    MATCH_MP_TAC 
REAL_LET_TRANS THEN
    EXISTS_TAC `
sum(1..dimindex(:N))
                   (\i. (B:num->real^N)(n)$i - (A:num->real^N)(n)$i)` THEN
    CONJ_TAC THENL
     [MATCH_MP_TAC 
SUM_LE_NUMSEG THEN SIMP_TAC[
VECTOR_SUB_COMPONENT] THEN
      REPEAT STRIP_TAC THEN
      MATCH_MP_TAC(REAL_ARITH `a <= x /\ x <= b /\ a <= y /\ y <= b
                               ==> abs(x - y) <= b - a`) THEN
      UNDISCH_TAC `x 
IN interval[(A:num->real^N) n,B n]` THEN
      UNDISCH_TAC `y 
IN interval[(A:num->real^N) n,B n]` THEN
      REWRITE_TAC[
IN_INTERVAL] THEN ASM_SIMP_TAC[];
      ALL_TAC] THEN
    MATCH_MP_TAC 
REAL_LET_TRANS THEN EXISTS_TAC
     `
sum(1..dimindex(:N)) (\i. (b:real^N)$i - (a:real^N)$i) /
      &2 pow n` THEN
    CONJ_TAC THENL
     [ALL_TAC;
      SIMP_TAC[
REAL_LT_LDIV_EQ; 
REAL_POW_LT; 
REAL_OF_NUM_LT; ARITH] THEN
      ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
      ASM_SIMP_TAC[GSYM 
REAL_LT_LDIV_EQ]] THEN
    REWRITE_TAC[
real_div] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
    REWRITE_TAC[GSYM 
SUM_LMUL] THEN MATCH_MP_TAC 
SUM_LE_NUMSEG THEN
    X_GEN_TAC `j:num` THEN STRIP_TAC THEN REWRITE_TAC[] THEN
    ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN REWRITE_TAC[GSYM 
real_div] THEN
    SPEC_TAC(`n:num`,`m:num`) THEN INDUCT_TAC THEN
    ASM_REWRITE_TAC[
real_pow; 
REAL_DIV_1; 
REAL_LE_REFL] THEN
    ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
    REWRITE_TAC[
real_div; 
REAL_INV_MUL; REAL_MUL_ASSOC] THEN
    SIMP_TAC[GSYM 
real_div; 
REAL_LE_RDIV_EQ; 
REAL_OF_NUM_LT; ARITH] THEN
    ASM_MESON_TAC[
REAL_LE_TRANS; REAL_MUL_SYM];
    ALL_TAC] THEN
  SUBGOAL_THEN `?a:real^N. !n:num. a 
IN interval[A(n),B(n)]` MP_TAC THENL
   [MATCH_MP_TAC 
DECREASING_CLOSED_NEST THEN
    ASM_REWRITE_TAC[
CLOSED_INTERVAL] THEN CONJ_TAC THENL
     [REWRITE_TAC[
INTERVAL_EQ_EMPTY] THEN
      ASM_MESON_TAC[
REAL_NOT_LT; 
REAL_LE_TRANS];
      ALL_TAC] THEN
    REWRITE_TAC[
LE_EXISTS] THEN SIMP_TAC[
LEFT_IMP_EXISTS_THM] THEN
    X_GEN_TAC `m:num` THEN ONCE_REWRITE_TAC[
SWAP_FORALL_THM] THEN
    REWRITE_TAC[GSYM 
LEFT_IMP_EXISTS_THM; 
EXISTS_REFL] THEN
    INDUCT_TAC THEN REWRITE_TAC[
ADD_CLAUSES; 
SUBSET_REFL] THEN
    MATCH_MP_TAC 
SUBSET_TRANS THEN
    EXISTS_TAC `
interval[A(m + d:num):real^N,B(m + d)]` THEN
    ASM_REWRITE_TAC[] THEN
    REWRITE_TAC[
SUBSET; 
IN_INTERVAL] THEN ASM_MESON_TAC[
REAL_LE_TRANS];
    ALL_TAC] THEN
  MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `x0:real^N` THEN
  DISCH_TAC THEN CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
  X_GEN_TAC `e:real` THEN DISCH_TAC THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
  DISCH_THEN(X_CHOOSE_TAC `n:num`) THEN
  MAP_EVERY EXISTS_TAC [`(A:num->real^N) n`; `(B:num->real^N) n`] THEN
  ASM_REWRITE_TAC[] THEN REPEAT CONJ_TAC THENL
   [REWRITE_TAC[
SUBSET; 
IN_BALL] THEN ASM_MESON_TAC[];
    ALL_TAC;
    SPEC_TAC(`n:num`,`p:num`) THEN INDUCT_TAC THEN ASM_REWRITE_TAC[]] THEN
  SUBGOAL_THEN
   `!m n. m <= n ==> 
interval[(A:num->real^N) n,B n] 
SUBSET interval[A m,B m]`
   (fun 
th -> ASM_MESON_TAC[
SUBSET; 
LE_0; 
th]) THEN
  MATCH_MP_TAC 
TRANSITIVE_STEPWISE_LE THEN
  REPEAT(CONJ_TAC THENL [SET_TAC[]; ALL_TAC]) THEN
  REWRITE_TAC[
SUBSET_INTERVAL] THEN ASM_MESON_TAC[]);;
 
let HAS_INTEGRAL_UNIQUE = prove
 (`!f:real^M->real^N i k1 k2.
        (f 
has_integral k1) i /\ (f 
has_integral k2) i ==> k1 = k2`,
  REPEAT GEN_TAC THEN
  SUBGOAL_THEN
   `!f:real^M->real^N a b k1 k2.
       (f 
has_integral k1) (
interval[a,b]) /\
       (f 
has_integral k2) (
interval[a,b])
       ==> k1 = k2`
  MP_TAC THENL
   [REPEAT GEN_TAC THEN REWRITE_TAC[
has_integral] THEN
    REWRITE_TAC[
AND_FORALL_THM] THEN
    REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN
    ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
    ONCE_REWRITE_TAC[GSYM 
VECTOR_SUB_EQ] THEN
    REWRITE_TAC[GSYM 
NORM_POS_LT] THEN DISCH_TAC THEN
    DISCH_THEN(MP_TAC o SPEC `
norm(k1 - k2 :real^N) / &2`) THEN
    ASM_REWRITE_TAC[
REAL_HALF] THEN
    DISCH_THEN(CONJUNCTS_THEN2
     (X_CHOOSE_THEN `d1:real^M->real^M->bool` STRIP_ASSUME_TAC)
     (X_CHOOSE_THEN `d2:real^M->real^M->bool` STRIP_ASSUME_TAC)) THEN
    MP_TAC(ISPEC `\x. ((d1:real^M->real^M->bool) x) 
INTER (d2 x)`
                 
FINE_DIVISION_EXISTS) THEN
    ASM_SIMP_TAC[
GAUGE_INTER] THEN
    DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN
    REPEAT(FIRST_X_ASSUM(MP_TAC o check (is_forall o concl))) THEN
    REWRITE_TAC[] THEN REWRITE_TAC[IMP_IMP; 
NOT_EXISTS_THM] THEN
    REWRITE_TAC[
AND_FORALL_THM] THEN MATCH_MP_TAC 
MONO_FORALL THEN
    GEN_TAC THEN
    MATCH_MP_TAC(TAUT
     `(f0 ==> f1 /\ f2) /\ ~(n1 /\ n2)
      ==> (t /\ f1 ==> n1) /\ (t /\ f2 ==> n2) ==> ~(t /\ f0)`) THEN
    CONJ_TAC THENL [SIMP_TAC[
fine; 
SUBSET_INTER]; ALL_TAC] THEN
    MATCH_MP_TAC(REAL_ARITH `c <= a + b ==> ~(a < c / &2 /\ b < c / &2)`) THEN
    MESON_TAC[
NORM_SUB; 
NORM_TRIANGLE; VECTOR_ARITH
     `k1 - k2:real^N = (k1 - x) + (x - k2)`];
    ALL_TAC] THEN
  DISCH_TAC THEN ONCE_REWRITE_TAC[
has_integral_alt] THEN
  COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
   [ASM_MESON_TAC[]; ALL_TAC] THEN
  DISCH_TAC THEN MATCH_MP_TAC(NORM_ARITH
   `~(&0 < 
norm(x - y)) ==> x = y`) THEN
  DISCH_TAC THEN
  FIRST_X_ASSUM(CONJUNCTS_THEN (MP_TAC o SPEC `
norm(k1 - k2:real^N) / &2`)) THEN
  ASM_REWRITE_TAC[
REAL_HALF] THEN
  DISCH_THEN(X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) THEN
  DISCH_THEN(X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC) THEN
  MP_TAC(ISPEC
   `
ball(
vec 0,B1) 
UNION ball(
vec 0:real^M,B2)`
   
BOUNDED_SUBSET_CLOSED_INTERVAL) THEN
  REWRITE_TAC[
BOUNDED_UNION; 
BOUNDED_BALL; 
UNION_SUBSET; 
NOT_EXISTS_THM] THEN
  MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
  DISCH_THEN(CONJUNCTS_THEN(ANTE_RES_THEN MP_TAC)) THEN
  DISCH_THEN(X_CHOOSE_THEN `w:real^N` STRIP_ASSUME_TAC) THEN
  DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
  SUBGOAL_THEN `w:real^N = z:real^N` SUBST_ALL_TAC THEN
  ASM_MESON_TAC[NORM_ARITH
   `~(
norm(z - k1) < 
norm(k1 - k2) / &2 /\
      
norm(z - k2) < 
norm(k1 - k2) / &2)`]);;
 
let HAS_INTEGRAL_LINEAR = prove
 (`!f:real^M->real^N y s h:real^N->real^P.
        (f 
has_integral y) s /\ 
linear h ==> ((h o f) 
has_integral h(y)) s`,
  SUBGOAL_THEN
    `!f:real^M->real^N y a b h:real^N->real^P.
          (f 
has_integral y) (
interval[a,b]) /\ 
linear h
          ==> ((h o f) 
has_integral h(y)) (
interval[a,b])`
  MP_TAC THENL
   [REPEAT GEN_TAC THEN REWRITE_TAC[
has_integral] THEN STRIP_TAC THEN
    FIRST_ASSUM(MP_TAC o MATCH_MP 
LINEAR_BOUNDED_POS) THEN
    DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
    X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `e:real / B`) THEN
    ASM_SIMP_TAC[
REAL_LT_DIV] THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN GEN_TAC THEN
    STRIP_TAC THEN ASM_SIMP_TAC[] THEN
    X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `p:real^M#(real^M->bool)->bool`) THEN
    ASM_SIMP_TAC[
REAL_LT_RDIV_EQ] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
    MATCH_MP_TAC(REAL_ARITH `x <= y ==> y < e ==> x < e`) THEN
    FIRST_ASSUM(fun 
th -> W(fun (asl,w) ->
      MP_TAC(PART_MATCH rand 
th (rand w)))) THEN
    MATCH_MP_TAC(REAL_ARITH `x <= y ==> y <= e ==> x <= e`) THEN
    FIRST_ASSUM(ASSUME_TAC o MATCH_MP 
TAGGED_DIVISION_OF_FINITE) THEN
    ASM_SIMP_TAC[
LINEAR_SUB; 
LINEAR_VSUM; 
o_DEF; 
LAMBDA_PAIR_THM;
                 
LINEAR_CMUL; 
REAL_LE_REFL];
    ALL_TAC] THEN
  DISCH_TAC THEN REPEAT GEN_TAC THEN
  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
  ONCE_REWRITE_TAC[
has_integral_alt] THEN
  COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
   [ASM_MESON_TAC[]; ALL_TAC] THEN
  DISCH_TAC THEN
  FIRST_ASSUM(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC o MATCH_MP
    
LINEAR_BOUNDED_POS) THEN
  X_GEN_TAC `e:real` THEN DISCH_TAC THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `e / B:real`) THEN
  ASM_SIMP_TAC[
REAL_LT_DIV] THEN
  MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `M:real` THEN
  MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
  REPEAT(MATCH_MP_TAC 
MONO_FORALL THEN GEN_TAC) THEN
  MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
  DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
  EXISTS_TAC `(h:real^N->real^P) z` THEN
  SUBGOAL_THEN
   `(\x. if x 
IN s then ((h:real^N->real^P) o (f:real^M->real^N)) x else 
vec 0)
    = h o (\x. if x 
IN s then f x else 
vec 0)`
  SUBST1_TAC THENL
   [REWRITE_TAC[
FUN_EQ_THM; 
o_THM] THEN ASM_MESON_TAC[
LINEAR_0]; ALL_TAC] THEN
  ASM_SIMP_TAC[GSYM 
LINEAR_SUB] THEN
  MATCH_MP_TAC 
REAL_LET_TRANS THEN EXISTS_TAC `B * 
norm(z - y:real^N)` THEN
  ASM_REWRITE_TAC[] THEN ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
  ASM_SIMP_TAC[GSYM 
REAL_LT_RDIV_EQ]);;
 
let HAS_INTEGRAL_ADD = prove
 (`!f:real^M->real^N g s.
        (f 
has_integral k) s /\ (g 
has_integral l) s
        ==> ((\x. f(x) + g(x)) 
has_integral (k + l)) s`,
  SUBGOAL_THEN
   `!f:real^M->real^N g k l a b.
        (f 
has_integral k) (
interval[a,b]) /\
        (g 
has_integral l) (
interval[a,b])
        ==> ((\x. f(x) + g(x)) 
has_integral (k + l)) (
interval[a,b])`
  ASSUME_TAC THENL
   [REPEAT GEN_TAC THEN REWRITE_TAC[
has_integral; 
AND_FORALL_THM] THEN
    DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[
REAL_HALF] THEN
    DISCH_THEN(CONJUNCTS_THEN2
     (X_CHOOSE_THEN `d1:real^M->real^M->bool` STRIP_ASSUME_TAC)
     (X_CHOOSE_THEN `d2:real^M->real^M->bool` STRIP_ASSUME_TAC)) THEN
    EXISTS_TAC `\x. ((d1:real^M->real^M->bool) x) 
INTER (d2 x)` THEN
    ASM_SIMP_TAC[
GAUGE_INTER] THEN
    REWRITE_TAC[
tagged_division_of; 
tagged_partial_division_of] THEN
    SIMP_TAC[
VSUM_ADD; 
VECTOR_ADD_LDISTRIB; 
LAMBDA_PAIR] THEN
    REWRITE_TAC[GSYM 
LAMBDA_PAIR] THEN
    REWRITE_TAC[GSYM 
tagged_partial_division_of] THEN
    REWRITE_TAC[GSYM 
tagged_division_of; 
FINE_INTER] THEN
    SIMP_TAC[VECTOR_ARITH `(a + b) - (c + d) = (a - c) + (b - d):real^N`] THEN
    REPEAT STRIP_TAC THEN MATCH_MP_TAC 
NORM_TRIANGLE_LT THEN
    MATCH_MP_TAC(REAL_ARITH `x < e / &2 /\ y < e / &2 ==> x + y < e`) THEN
    ASM_SIMP_TAC[];
    ALL_TAC] THEN
  REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[
has_integral_alt] THEN
  COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
   [ASM_MESON_TAC[]; ALL_TAC] THEN
  DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
  FIRST_X_ASSUM(CONJUNCTS_THEN (MP_TAC o SPEC `e / &2`)) THEN
  ASM_REWRITE_TAC[
REAL_HALF] THEN
  DISCH_THEN(X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) THEN
  DISCH_THEN(X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC) THEN
  EXISTS_TAC `max B1 B2:real` THEN ASM_REWRITE_TAC[
REAL_LT_MAX] THEN
  REWRITE_TAC[
BALL_MAX_UNION; 
UNION_SUBSET] THEN
  MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
  DISCH_THEN(CONJUNCTS_THEN(ANTE_RES_THEN MP_TAC)) THEN
  DISCH_THEN(X_CHOOSE_THEN `w:real^N` STRIP_ASSUME_TAC) THEN
  DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
  EXISTS_TAC `w + z:real^N` THEN
  SUBGOAL_THEN
    `(\x. if x 
IN s then (f:real^M->real^N) x + g x else 
vec 0) =
     (\x. (if x 
IN s then f x else 
vec 0) + (if x 
IN s then g x else 
vec 0))`
  SUBST1_TAC THENL
   [REWRITE_TAC[
FUN_EQ_THM] THEN GEN_TAC THEN COND_CASES_TAC THEN
    ASM_REWRITE_TAC[] THEN VECTOR_ARITH_TAC;
    ALL_TAC] THEN
  ASM_SIMP_TAC[] THEN
  REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM 
REAL_NOT_LE])) THEN
  NORM_ARITH_TAC);;
 
let DIVISION_SPLIT = prove
 (`!p a b:real^N k c.
     p 
division_of interval[a,b] /\ 1 <= k /\ k <= 
dimindex(:N)
     ==> {l 
INTER {x | x$k <= c} |l| l 
IN p /\ ~(l 
INTER {x | x$k <= c} = {})}
         
division_of (
interval[a,b] 
INTER {x | x$k <= c}) /\
         {l 
INTER {x | x$k >= c} |l| l 
IN p /\ ~(l 
INTER {x | x$k >= c} = {})}
         
division_of (
interval[a,b] 
INTER {x | x$k >= c})`,
  REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC STRIP_ASSUME_TAC) THEN
  SIMP_TAC[
division_of; 
FINITE_IMAGE] THEN
  SIMP_TAC[SET_RULE `(!x. x 
IN {f x | P x} ==> Q x) <=> (!x. P x ==> Q (f x))`;
           MESON[] `(!x y. x 
IN s /\ y 
IN t /\ Q x y ==> P x y) <=>
                    (!x. x 
IN s ==> !y. y 
IN t ==> Q x y ==> P x y)`;
           
RIGHT_FORALL_IMP_THM] THEN
  REPEAT(MATCH_MP_TAC(TAUT
   `(a ==> a' /\ a'') /\ (b ==> b' /\ b'')
      ==> a /\ b ==> (a' /\ b') /\ (a'' /\ b'')`) THEN CONJ_TAC)
  THENL
   [ONCE_REWRITE_TAC[SET_RULE
    `{f x |x| x 
IN s /\ ~(f x = {})} = {y | y 
IN IMAGE f s /\ ~(y = {})}`] THEN
    SIMP_TAC[
FINITE_RESTRICT; 
FINITE_IMAGE];
    REWRITE_TAC[
AND_FORALL_THM] THEN
    MATCH_MP_TAC 
MONO_FORALL THEN X_GEN_TAC `l:real^N->bool` THEN
    DISCH_THEN(fun 
th -> CONJ_TAC THEN STRIP_TAC THEN MP_TAC 
th) THEN
    (ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_AND THEN
     CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
     STRIP_TAC THEN ASM_MESON_TAC[
INTERVAL_SPLIT]);
    DISCH_THEN(fun 
th -> CONJ_TAC THEN MP_TAC 
th) THEN
    (REPEAT(MATCH_MP_TAC 
MONO_FORALL THEN GEN_TAC) THEN
     DISCH_THEN(fun 
th -> STRIP_TAC THEN MP_TAC 
th) THEN ASM_SIMP_TAC[] THEN
     REPEAT(MATCH_MP_TAC 
MONO_FORALL THEN GEN_TAC) THEN
     DISCH_THEN(fun 
th -> STRIP_TAC THEN MP_TAC 
th) THEN ASM_SIMP_TAC[] THEN
     DISCH_THEN(fun 
th -> STRIP_TAC THEN MP_TAC 
th) THEN ASM_SIMP_TAC[] THEN
     ANTS_TAC THENL [ASM_MESON_TAC[
PAIR_EQ]; ALL_TAC] THEN
     MATCH_MP_TAC(SET_RULE
      `s 
SUBSET s' /\ t 
SUBSET t'
       ==> s' 
INTER t' = {} ==> s 
INTER t = {}`) THEN
     CONJ_TAC THEN MATCH_MP_TAC 
SUBSET_INTERIOR THEN SET_TAC[]);
   DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[
INTER_UNIONS] THEN
   ONCE_REWRITE_TAC[
EXTENSION] THEN REWRITE_TAC[
IN_UNIONS] THEN
   CONJ_TAC THEN GEN_TAC THEN AP_TERM_TAC THEN
   GEN_REWRITE_TAC I [
FUN_EQ_THM] THEN GEN_TAC THEN
   REWRITE_TAC[
IN_ELIM_THM; 
PAIR_EQ] THEN MESON_TAC[
NOT_IN_EMPTY]]);;
 
let HAS_INTEGRAL_SPLIT = prove
 (`!f:real^M->real^N k a b c.
      (f 
has_integral i) (
interval[a,b] 
INTER {x | x$k <= c}) /\
      (f 
has_integral j) (
interval[a,b] 
INTER {x | x$k >= c}) /\
      1 <= k /\ k <= 
dimindex(:M)
      ==> (f 
has_integral (i + j)) (
interval[a,b])`,
  let lemma1 = prove
   (`(!x k. (x,k) IN {x,f k | P x k} ==> Q x k) <=>
     (!x k. P x k ==> Q x (f k))`,
    REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN
    SET_TAC[]) in
  let lemma2 = prove
   (`!f:B->B s:(A#B)->bool.
      FINITE s ==> FINITE {x,f k | (x,k) IN s /\ P x k}`,
    REPEAT STRIP_TAC THEN MATCH_MP_TAC FINITE_SUBSET THEN
    EXISTS_TAC `IMAGE (\(x:A,k:B). x,(f k:B)) s` THEN
    ASM_SIMP_TAC[FINITE_IMAGE] THEN
    REWRITE_TAC[SUBSET; FORALL_PAIR_THM; lemma1; IN_IMAGE] THEN
    REWRITE_TAC[EXISTS_PAIR_THM; PAIR_EQ] THEN MESON_TAC[]) in
  let lemma3 = prove
   (`!f:real^M->real^N g:(real^M->bool)->(real^M->bool) p.
     FINITE p
     ==> vsum {x,g k |x,k| (x,k) IN p /\ ~(g k = {})}
              (\(x,k). content k % f x) =
         vsum (IMAGE (\(x,k). x,g k) p) (\(x,k). content k % f x)`,
    REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN
    ASM_SIMP_TAC[FINITE_IMAGE; lemma2] THEN
    REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE] THEN
    REWRITE_TAC[FORALL_PAIR_THM; SUBSET; IN_IMAGE; EXISTS_PAIR_THM] THEN
    REWRITE_TAC[IN_ELIM_THM; PAIR_EQ; VECTOR_MUL_EQ_0] THEN
    MESON_TAC[CONTENT_EMPTY]) in
  let lemma4 = prove
   (`(\(x,l). content (g l) % f x) =
     (\(x,l). content l % f x) o (\(x,l). x,g l)`,
    REWRITE_TAC[FUN_EQ_THM; o_THM; FORALL_PAIR_THM]) in
  REPEAT GEN_TAC THEN
  ASM_CASES_TAC `1 <= k /\ k <= dimindex(:M)` THEN ASM_REWRITE_TAC[] THEN
  ASM_SIMP_TAC[INTERVAL_SPLIT] THEN REWRITE_TAC[has_integral] THEN
  ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THEN FIRST_X_ASSUM STRIP_ASSUME_TAC THEN
  DISCH_TAC THEN X_GEN_TAC `e:real` THEN STRIP_TAC THEN
  FIRST_X_ASSUM(CONJUNCTS_THEN2 (MP_TAC o SPEC `e / &2`) STRIP_ASSUME_TAC) THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
  DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool`
   (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "I2"))) THEN
  DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool`
   (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "I1"))) THEN
  EXISTS_TAC `\x. if x$k = c then (d1(x:real^M) INTER d2(x)):real^M->bool
                  else ball(x,abs(x$k - c)) INTER d1(x) INTER d2(x)` THEN
  CONJ_TAC THENL
   [REWRITE_TAC[gauge] THEN GEN_TAC THEN
    RULE_ASSUM_TAC(REWRITE_RULE[gauge]) THEN COND_CASES_TAC THEN
    ASM_SIMP_TAC[OPEN_INTER; IN_INTER; OPEN_BALL; IN_BALL] THEN
    ASM_REWRITE_TAC[DIST_REFL; GSYM REAL_ABS_NZ; REAL_SUB_0];
    ALL_TAC] THEN
  X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
  SUBGOAL_THEN
    `(!x:real^M kk. (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k <= c} = {})
                    ==> x$k <= c) /\
     (!x:real^M kk. (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k >= c} = {})
                    ==> x$k >= c)`
  STRIP_ASSUME_TAC THENL
   [CONJ_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
    MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
    MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `kk:real^M->bool` THEN
    DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
    COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL; real_ge] THEN DISCH_THEN
     (MP_TAC o MATCH_MP (SET_RULE `k SUBSET (a INTER b) ==> k SUBSET a`)) THEN
    REWRITE_TAC[SUBSET; IN_BALL; dist] THEN DISCH_TAC THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
    DISCH_THEN(X_CHOOSE_THEN `u:real^M` MP_TAC) THEN
    REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M`) THEN ASM_REWRITE_TAC[] THEN
    ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
    REWRITE_TAC[REAL_NOT_LE; REAL_NOT_LT] THEN STRIP_TAC THEN
    MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((x - u:real^M)$k)` THEN
    ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
    ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
    ASM_REAL_ARITH_TAC;
    ALL_TAC] THEN
  REMOVE_THEN "I2" (MP_TAC o SPEC
   `{(x:real^M,kk INTER {x:real^M | x$k >= c}) |x,kk|
     (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k >= c} = {})}`) THEN
  REMOVE_THEN "I1" (MP_TAC o SPEC
   `{(x:real^M,kk INTER {x:real^M | x$k <= c}) |x,kk|
     (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k <= c} = {})}`) THEN
  MATCH_MP_TAC(TAUT
   `(a /\ b) /\ (a' /\ b' ==> c) ==> (a ==> a') ==> (b ==> b') ==> c`) THEN
  CONJ_TAC THENL
   [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
    REWRITE_TAC[TAGGED_DIVISION_OF] THEN
    REPEAT(MATCH_MP_TAC(TAUT
     `(a ==> (a' /\ a'')) /\ (b ==> (b' /\ d) /\ (b'' /\ e))
      ==> a /\ b ==> ((a' /\ b') /\ d) /\ ((a'' /\ b'') /\ e)`) THEN
      CONJ_TAC) THEN
    REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
    REWRITE_TAC[lemma1] THEN REWRITE_TAC[IMP_IMP] THENL
     [SIMP_TAC[lemma2];
      REWRITE_TAC[AND_FORALL_THM] THEN
      MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
      MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `kk:real^M->bool` THEN
      DISCH_THEN(fun th -> CONJ_TAC THEN STRIP_TAC THEN MP_TAC th) THEN
      (ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
        [SIMP_TAC[IN_INTER; IN_ELIM_THM] THEN ASM_MESON_TAC[]; ALL_TAC]) THEN
      (MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL [SET_TAC[]; ALL_TAC]) THEN
      ASM_MESON_TAC[INTERVAL_SPLIT];
      DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
      (REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
       DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
       REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
       DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
       ANTS_TAC THENL [ASM_MESON_TAC[PAIR_EQ]; ALL_TAC] THEN
       MATCH_MP_TAC(SET_RULE
        `s SUBSET s' /\ t SUBSET t'
         ==> s' INTER t' = {} ==> s INTER t = {}`) THEN
       CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]);
      ALL_TAC] THEN
    MATCH_MP_TAC(TAUT `(a ==> b /\ c) /\ d /\ e
                       ==> (a ==> (b /\ d) /\ (c /\ e))`) THEN
    CONJ_TAC THENL
     [DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
      DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[INTER_UNIONS] THEN
      ONCE_REWRITE_TAC[EXTENSION] THEN REWRITE_TAC[IN_UNIONS] THEN
      X_GEN_TAC `x:real^M` THEN AP_TERM_TAC THEN
      GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `kk:real^M->bool` THEN
      REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN MESON_TAC[NOT_IN_EMPTY];
      ALL_TAC] THEN
    CONJ_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
    REWRITE_TAC[fine; lemma1] THEN
    REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
    DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
    ASM_SIMP_TAC[] THEN SET_TAC[];
    ALL_TAC] THEN
  DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH
   `x < e / &2 /\ y < e / &2 ==> x + y < e`)) THEN
  DISCH_THEN(MP_TAC o MATCH_MP NORM_TRIANGLE_LT) THEN
  MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
  REWRITE_TAC[VECTOR_ARITH
   `(a - i) + (b - j) = c - (i + j) <=> a + b = c:real^N`] THEN
  FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
 MATCH_MP_TAC EQ_TRANS THEN
  EXISTS_TAC
   `vsum p (\(x,l). content (l INTER {x:real^M | x$k <= c}) %
                     (f:real^M->real^N) x) +
    vsum p (\(x,l). content (l INTER {x:real^M | x$k >= c}) %
                     (f:real^M->real^N) x)` THEN
  CONJ_TAC THENL
   [ALL_TAC;
    ASM_SIMP_TAC[GSYM VSUM_ADD] THEN MATCH_MP_TAC VSUM_EQ THEN
    REWRITE_TAC[FORALL_PAIR_THM; GSYM VECTOR_ADD_RDISTRIB] THEN
    MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
    DISCH_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
    DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `l:real^M->bool`] o
               el 1 o CONJUNCTS) THEN
    ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
    ASM_SIMP_TAC[GSYM CONTENT_SPLIT]] THEN
  ASM_SIMP_TAC[lemma3] THEN BINOP_TAC THEN
  (GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [lemma4] THEN
   MATCH_MP_TAC VSUM_IMAGE_NONZERO THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
   REWRITE_TAC[PAIR_EQ] THEN
   ASM_MESON_TAC[TAGGED_DIVISION_SPLIT_LEFT_INJ; VECTOR_MUL_LZERO;
                 TAGGED_DIVISION_SPLIT_RIGHT_INJ]));;  
let OPERATIVE_DIVISION = prove
 (`!op d a b f:(real^N->bool)->A.
    
monoidal op /\ 
operative op f /\ d 
division_of interval[a,b]
    ==> 
iterate(op) d f = f(
interval[a,b])`,
  REPEAT GEN_TAC THEN CONV_TAC(RAND_CONV SYM_CONV) THEN WF_INDUCT_TAC
   `
CARD (
division_points (
interval[a,b]:real^N->bool) d)` THEN
  POP_ASSUM(fun 
th -> REPEAT STRIP_TAC THEN MP_TAC 
th) THEN
  ASM_REWRITE_TAC[] THEN
  ASM_CASES_TAC `
content(
interval[a:real^N,b]) = &0` THENL
   [SUBGOAL_THEN `
iterate op d (f:(real^N->bool)->A) = 
neutral op`
     (fun 
th -> ASM_MESON_TAC[
th; 
operative]) THEN
    MATCH_MP_TAC(REWRITE_RULE[
RIGHT_IMP_FORALL_THM; IMP_IMP]
     
ITERATE_EQ_NEUTRAL) THEN
    FIRST_ASSUM(fun 
th -> REWRITE_TAC[MATCH_MP 
FORALL_IN_DIVISION th]) THEN
    ASM_MESON_TAC[
operative; 
DIVISION_OF_CONTENT_0];
    ALL_TAC] THEN
  FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM 
CONTENT_LT_NZ]) THEN
  REWRITE_TAC[
CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
  FIRST_ASSUM(ASSUME_TAC o MATCH_MP 
DIVISION_OF_FINITE) THEN
  ASM_CASES_TAC `
division_points (
interval[a,b]:real^N->bool) d = {}` THENL
   [DISCH_THEN(K ALL_TAC) THEN
    SUBGOAL_THEN
     `!i. i 
IN d
          ==> ?u v:real^N. i = 
interval[u,v] /\
                           !j. 1 <= j /\ j <= 
dimindex(:N)
                               ==> u$j = (a:real^N)$j /\ v$j = a$j \/
                                   u$j = (b:real^N)$j /\ v$j = b$j \/
                                   u$j = a$j /\ v$j = b$j`
    (LABEL_TAC "*") THENL
     [FIRST_ASSUM(fun 
th -> REWRITE_TAC[MATCH_MP 
FORALL_IN_DIVISION th]) THEN
      MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN DISCH_TAC THEN
      MAP_EVERY EXISTS_TAC [`u:real^N`; `v:real^N`] THEN REWRITE_TAC[] THEN
      REPEAT STRIP_TAC THEN
      FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
division_of]) THEN
      ASM_REWRITE_TAC[] THEN
      DISCH_THEN(MP_TAC o SPEC `
interval[u:real^N,v]` o CONJUNCT1) THEN
      ASM_REWRITE_TAC[
INTERVAL_NE_EMPTY] THEN
      DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (ASSUME_TAC o CONJUNCT1)) THEN
      ASM_REWRITE_TAC[
SUBSET_INTERVAL] THEN STRIP_TAC THEN
      MATCH_MP_TAC(REAL_ARITH
       `a <= u /\ u <= v /\ v <= b /\ ~(a < u /\ u < b \/ a < v /\ v < b)
        ==> u = a /\ v = a \/ u = b /\ v = b \/ u = a /\ v = b`) THEN
      ASM_SIMP_TAC[] THEN DISCH_TAC THEN
      FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
EXTENSION]) THEN
      REWRITE_TAC[
division_points; 
NOT_IN_EMPTY; 
FORALL_PAIR_THM] THEN
      REWRITE_TAC[
IN_ELIM_PAIR_THM] THEN DISCH_THEN(MP_TAC o SPEC `j:num`) THEN
      ASM_REWRITE_TAC[] THEN REWRITE_TAC[
RIGHT_AND_EXISTS_THM] THEN
      REWRITE_TAC[
NOT_EXISTS_THM] THEN ONCE_REWRITE_TAC[
SWAP_FORALL_THM] THEN
      DISCH_THEN(MP_TAC o SPEC `
interval[u:real^N,v]`) THEN
      ASM_SIMP_TAC[
INTERVAL_UPPERBOUND; 
INTERVAL_LOWERBOUND;
                   
REAL_LT_IMP_LE] THEN
      DISCH_THEN(fun 
th ->
        MP_TAC(SPEC `(u:real^N)$j` 
th) THEN
        MP_TAC(SPEC `(v:real^N)$j` 
th)) THEN
      FIRST_X_ASSUM(DISJ_CASES_THEN MP_TAC) THEN REAL_ARITH_TAC;
      ALL_TAC] THEN
    SUBGOAL_THEN `
interval[a:real^N,b] 
IN d` MP_TAC THENL
     [FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
division_of]) THEN
      ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o last o CONJUNCTS) THEN
      REWRITE_TAC[
EXTENSION; 
IN_INTERVAL; 
IN_UNIONS] THEN
      DISCH_THEN(MP_TAC o SPEC `inv(&2) % (a + b:real^N)`) THEN
      MATCH_MP_TAC(TAUT `b /\ (a ==> c) ==> (a <=> b) ==> c`) THEN
      CONJ_TAC THENL
       [SIMP_TAC[
VECTOR_ADD_COMPONENT; 
VECTOR_MUL_COMPONENT] THEN
        X_GEN_TAC `j:num` THEN STRIP_TAC THEN
        FIRST_X_ASSUM(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN
        REAL_ARITH_TAC;
        ALL_TAC] THEN
      DISCH_THEN(X_CHOOSE_THEN `i:real^N->bool`
       (CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
      REMOVE_THEN "*" (MP_TAC o SPEC `i:real^N->bool`) THEN
      ASM_REWRITE_TAC[] THEN REWRITE_TAC[
LEFT_IMP_EXISTS_THM] THEN
      MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN
      DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC) THEN
      SIMP_TAC[
IN_INTERVAL; 
VECTOR_ADD_COMPONENT; 
VECTOR_MUL_COMPONENT] THEN
      REWRITE_TAC[IMP_IMP; 
AND_FORALL_THM] THEN
      REWRITE_TAC[TAUT `(a ==> b) /\ (a ==> c) <=> a ==> b /\ c`] THEN
      ASM_SIMP_TAC[REAL_ARITH
       `a < b
        ==> ((u = a /\ v = a \/ u = b /\ v = b \/ u = a /\ v = b) /\
             u <= inv(&2) * (a + b) /\ inv(&2) * (a +  b) <= v <=>
             u = a /\ v = b)`] THEN
      ASM_MESON_TAC[
CART_EQ];
      ALL_TAC] THEN
    DISCH_THEN(fun 
th -> ASSUME_TAC 
th THEN MP_TAC 
th) THEN
    DISCH_THEN(SUBST1_TAC o MATCH_MP (SET_RULE
     `a 
IN d ==> d = a 
INSERT (d 
DELETE a)`)) THEN
    ASM_SIMP_TAC[
ITERATE_CLAUSES; 
FINITE_DELETE; 
IN_DELETE] THEN
    SUBGOAL_THEN
     `
iterate op (d 
DELETE interval[a,b]) (f:(real^N->bool)->A) = 
neutral op`
     (fun 
th -> ASM_MESON_TAC[
th; 
monoidal]) THEN
    MATCH_MP_TAC(REWRITE_RULE[
RIGHT_IMP_FORALL_THM; IMP_IMP]
     
ITERATE_EQ_NEUTRAL) THEN
    ASM_REWRITE_TAC[] THEN X_GEN_TAC `l:real^N->bool` THEN
    REWRITE_TAC[
IN_DELETE] THEN STRIP_TAC THEN
    SUBGOAL_THEN `
content(l:real^N->bool) = &0`
     (fun 
th -> ASM_MESON_TAC[
th; 
operative]) THEN
    REMOVE_THEN "*" (MP_TAC o SPEC `l:real^N->bool`) THEN
    ASM_REWRITE_TAC[
LEFT_IMP_EXISTS_THM] THEN
    MAP_EVERY X_GEN_TAC [`u:real^N`; `v:real^N`] THEN
    DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC) THEN
    UNDISCH_TAC `~(
interval[u:real^N,v] = 
interval[a,b])` THEN
    ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
    REWRITE_TAC[] THEN DISCH_THEN(fun 
th -> AP_TERM_TAC THEN MP_TAC 
th) THEN
    REWRITE_TAC[
CONS_11; 
PAIR_EQ; 
CART_EQ; 
CONTENT_EQ_0] THEN
    GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
     [TAUT `a ==> b <=> ~a \/ b`] THEN
    REWRITE_TAC[
NOT_FORALL_THM; 
OR_EXISTS_THM] THEN
    REWRITE_TAC[
NOT_EXISTS_THM; 
AND_FORALL_THM] THEN
    MATCH_MP_TAC 
MONO_FORALL THEN X_GEN_TAC `j:num` THEN
    ASM_CASES_TAC `1 <= j /\ j <= 
dimindex(:N)` THEN ASM_REWRITE_TAC[] THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `j:num`) THEN ASM_REWRITE_TAC[] THEN
    REAL_ARITH_TAC;
    ALL_TAC] THEN
  FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM 
MEMBER_NOT_EMPTY]) THEN
  GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [
division_points] THEN
  REWRITE_TAC[
IN_ELIM_THM; 
LEFT_IMP_EXISTS_THM] THEN
  MAP_EVERY X_GEN_TAC [`whatever:num#real`; `k:num`; `c:real`] THEN
  ASM_SIMP_TAC[
INTERVAL_LOWERBOUND; 
INTERVAL_UPPERBOUND; 
REAL_LT_IMP_LE] THEN
  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC (K ALL_TAC)) THEN
  DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
  MP_TAC(ISPECL [`a:real^N`; `b:real^N`; `c:real`; `d:(real^N->bool)->bool`;
        `k:num`] 
DIVISION_POINTS_PSUBSET) THEN
  ASM_REWRITE_TAC[] THEN
  DISCH_THEN(CONJUNCTS_THEN
   (MP_TAC o MATCH_MP (REWRITE_RULE [
IMP_CONJ] 
CARD_PSUBSET))) THEN
  MP_TAC(ISPECL [`d:(real^N->bool)->bool`; `a:real^N`; `b:real^N`; `k:num`;
                 `c:real`]
      
DIVISION_SPLIT) THEN
  ASM_SIMP_TAC[
DIVISION_POINTS_FINITE] THEN
  ASM_SIMP_TAC[
INTERVAL_SPLIT] THEN
  ASM_SIMP_TAC[REAL_ARITH `a < c ==> max a c = c`;
               REAL_ARITH `c < b ==> min b c = c`] THEN
  MAP_EVERY ABBREV_TAC
   [`d1:(real^N->bool)->bool =
     {l 
INTER {x | x$k <= c} | l | l 
IN d /\ ~(l 
INTER {x | x$k <= c} = {})}`;
    `d2:(real^N->bool)->bool =
     {l 
INTER {x | x$k >= c} | l | l 
IN d /\ ~(l 
INTER {x | x$k >= c} = {})}`;
    `cb:real^N = (
lambda i. if i = k then c else (b:real^N)$i)`;
    `ca:real^N = (
lambda i. if i = k then c else (a:real^N)$i)`] THEN
  STRIP_TAC THEN STRIP_TAC THEN STRIP_TAC THEN DISCH_THEN(fun 
th ->
   MP_TAC(SPECL [`a:real^N`; `cb:real^N`; `d1:(real^N->bool)->bool`] 
th) THEN
   MP_TAC(SPECL [`ca:real^N`; `b:real^N`; `d2:(real^N->bool)->bool`] 
th)) THEN
  ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
  MATCH_MP_TAC 
EQ_TRANS THEN
  EXISTS_TAC `op (
iterate op d1 (f:(real^N->bool)->A))
                 (
iterate op d2 (f:(real^N->bool)->A))` THEN
  CONJ_TAC THENL
   [FIRST_ASSUM(MP_TAC o CONJUNCT2 o GEN_REWRITE_RULE I [
operative]) THEN
    DISCH_THEN(MP_TAC o SPECL [`a:real^N`; `b:real^N`; `c:real`; `k:num`]) THEN
    ASM_SIMP_TAC[
INTERVAL_SPLIT] THEN
    ASM_SIMP_TAC[REAL_ARITH `a < c ==> max a c = c`;
                 REAL_ARITH `c < b ==> min b c = c`];
    ALL_TAC] THEN
  MATCH_MP_TAC 
EQ_TRANS THEN
  EXISTS_TAC
   `op (
iterate op d (\l. f(l 
INTER {x | x$k <= c}):A))
       (
iterate op d (\l. f(l 
INTER {x:real^N | x$k >= c})))` THEN
  CONJ_TAC THENL
   [ALL_TAC;
    ASM_SIMP_TAC[GSYM 
ITERATE_OP] THEN
    MATCH_MP_TAC(REWRITE_RULE[
RIGHT_IMP_FORALL_THM; IMP_IMP]
     
ITERATE_EQ) THEN
    ASM_REWRITE_TAC[MATCH_MP 
FORALL_IN_DIVISION
     (ASSUME `d 
division_of interval[a:real^N,b]`)] THEN
    ASM_MESON_TAC[
operative]] THEN
  MAP_EVERY EXPAND_TAC ["d1";
 
let HAS_INTEGRAL_COMPONENT_LE = prove
 (`!f:real^M->real^N g:real^M->real^N s i j k.
        1 <= k /\ k <= 
dimindex(:N) /\
        (f 
has_integral i) s /\ (g 
has_integral j) s /\
        (!x. x 
IN s ==> (f x)$k <= (g x)$k)
        ==> i$k <= j$k`,
  SUBGOAL_THEN
   `!f:real^M->real^N g:real^M->real^N a b i j k.
        1 <= k /\ k <= 
dimindex(:N) /\
        (f 
has_integral i) (
interval[a,b]) /\
        (g 
has_integral j) (
interval[a,b]) /\
        (!x. x 
IN interval[a,b] ==> (f x)$k <= (g x)$k)
        ==> i$k <= j$k`
  ASSUME_TAC THENL
   [REPEAT STRIP_TAC THEN
    MATCH_MP_TAC(REAL_ARITH `~(&0 < i - j) ==> i <= j`) THEN DISCH_TAC THEN
    REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `((i:real^N)$k - (j:real^N)$k) / &3` o
       GEN_REWRITE_RULE I [
has_integral])) THEN
    ASM_SIMP_TAC[
REAL_LT_DIV; 
REAL_OF_NUM_LT; ARITH] THEN
    DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
    DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
    SUBGOAL_THEN `?p. p 
tagged_division_of interval[a:real^M,b] /\
                      d1 
fine p /\ d2 
fine p`
    STRIP_ASSUME_TAC THENL
     [REWRITE_TAC[GSYM 
FINE_INTER] THEN MATCH_MP_TAC 
FINE_DIVISION_EXISTS THEN
      ASM_SIMP_TAC[
GAUGE_INTER];
      ALL_TAC] THEN
    REPEAT
     (FIRST_X_ASSUM(MP_TAC o SPEC `p:real^M#(real^M->bool)->bool`) THEN
      ASM_REWRITE_TAC[] THEN DISCH_THEN(MP_TAC o MATCH_MP 
REAL_LT_IMP_LE) THEN
      DISCH_THEN(MP_TAC o SPEC `k:num` o MATCH_MP 
NORM_BOUND_COMPONENT_LE) THEN
      ASM_SIMP_TAC[
VECTOR_SUB_COMPONENT]) THEN
    SUBGOAL_THEN
     `
vsum p (\(x,l:real^M->bool). 
content l % (f:real^M->real^N) x)$k <=
      
vsum p (\(x,l). 
content l % (g:real^M->real^N) x)$k`
    MP_TAC THENL
     [MATCH_MP_TAC 
RSUM_COMPONENT_LE THEN ASM_MESON_TAC[];
      UNDISCH_TAC `&0 < (i:real^N)$k - (j:real^N)$k` THEN
      SPEC_TAC(`
vsum p (\(x:real^M,l:real^M->bool).
                                
content l % (f x):real^N)$k`,
               `fs:real`) THEN
      SPEC_TAC(`
vsum p (\(x:real^M,l:real^M->bool).
                                
content l % (g x):real^N)$k`,
               `gs:real`) THEN
      REAL_ARITH_TAC];
    ALL_TAC] THEN
  REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[
has_integral_alt] THEN
  COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
  STRIP_TAC THEN REWRITE_TAC[GSYM 
REAL_NOT_LT] THEN DISCH_TAC THEN
  REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC
   `((i:real^N)$k - (j:real^N)$k) / &2`)) THEN
  ASM_REWRITE_TAC[
REAL_HALF; 
REAL_SUB_LT] THEN
  DISCH_THEN(X_CHOOSE_THEN `B1:real` STRIP_ASSUME_TAC) THEN
  DISCH_THEN(X_CHOOSE_THEN `B2:real` STRIP_ASSUME_TAC) THEN
  MP_TAC(ISPEC
   `
ball(
vec 0,B1) 
UNION ball(
vec 0:real^M,B2)`
   
BOUNDED_SUBSET_CLOSED_INTERVAL) THEN
  REWRITE_TAC[
BOUNDED_UNION; 
BOUNDED_BALL; 
UNION_SUBSET; 
NOT_EXISTS_THM] THEN
  MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN
  DISCH_THEN(CONJUNCTS_THEN(ANTE_RES_THEN MP_TAC)) THEN
  DISCH_THEN(X_CHOOSE_THEN `w:real^N` STRIP_ASSUME_TAC) THEN
  DISCH_THEN(X_CHOOSE_THEN `z:real^N` STRIP_ASSUME_TAC) THEN
  SUBGOAL_THEN `(z:real^N)$k <= (w:real^N)$k` MP_TAC THENL
   [FIRST_X_ASSUM MATCH_MP_TAC THEN
    MAP_EVERY EXISTS_TAC
     [`(\x. if x 
IN s then f x else 
vec 0):real^M->real^N`;
      `(\x. if x 
IN s then g x else 
vec 0):real^M->real^N`;
      `a:real^M`; `b:real^M`] THEN
    ASM_MESON_TAC[
REAL_LE_REFL];
    MP_TAC(ISPECL [`w - j:real^N`; `k:num`] 
COMPONENT_LE_NORM) THEN
    MP_TAC(ISPECL [`z - i:real^N`; `k:num`] 
COMPONENT_LE_NORM) THEN
    ASM_REWRITE_TAC[] THEN
    SIMP_TAC[
VECTOR_SUB_COMPONENT; ASSUME `1 <= k`;
              ASSUME `k <= 
dimindex(:N)`] THEN
    REPEAT(FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM 
REAL_NOT_LE])) THEN
    NORM_ARITH_TAC]);;
 
let INTEGRABLE_UNIFORM_LIMIT = prove
 (`!f a b. (!e. &0 < e
                ==> ?g. (!x. x 
IN interval[a,b] ==> 
norm(f x - g x) <= e) /\
                        g 
integrable_on interval[a,b] )
           ==> (f:real^M->real^N) 
integrable_on interval[a,b]`,
  let lemma = prove
   (`x <= norm(a + b) + c ==> x <= norm(a) + norm(b) + c`,
    MESON_TAC[REAL_ADD_AC; NORM_TRIANGLE; REAL_LE_TRANS; REAL_LE_RADD]) in
  let (lemma1,lemma2) = (CONJ_PAIR o prove)
   (`(norm(s2 - s1) <= e / &2 /\
      norm(s1 - i1) < e / &4 /\ norm(s2 - i2) < e / &4
      ==> norm(i1 - i2) < e) /\
     (norm(sf - sg) <= e / &3
      ==> norm(i - s) < e / &3 ==> norm(sg - i) < e / &3 ==> norm(sf - s) < e)`,
    CONJ_TAC THENL
     [REWRITE_TAC[CONJ_ASSOC] THEN
      GEN_REWRITE_TAC (LAND_CONV o LAND_CONV o ONCE_DEPTH_CONV) [NORM_SUB] THEN
      MATCH_MP_TAC(REAL_ARITH
       `w <= x + y + z + &0
        ==> (x <= e / &2 /\ y < e / &4) /\ z < e / &4 ==> w < e`);
      MATCH_MP_TAC(REAL_ARITH
      `w <= x + y + z + &0
      ==> x <= e / &3 ==> y < e / &3 ==> z < e / &3 ==> w < e`)] THEN
    REPEAT(MATCH_MP_TAC lemma) THEN REWRITE_TAC[REAL_ADD_RID] THEN
    MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN VECTOR_ARITH_TAC) in
  REPEAT STRIP_TAC THEN
  ASM_CASES_TAC `&0 < content(interval[a:real^M,b])` THENL
   [ALL_TAC;
    ASM_MESON_TAC[HAS_INTEGRAL_NULL; CONTENT_LT_NZ; integrable_on]] THEN
  FIRST_X_ASSUM(MP_TAC o GEN `n:num` o SPEC `inv(&n + &1)`) THEN
  REWRITE_TAC[REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
  REWRITE_TAC[FORALL_AND_THM; SKOLEM_THM; integrable_on] THEN
  DISCH_THEN(X_CHOOSE_THEN `g:num->real^M->real^N` (CONJUNCTS_THEN2
   ASSUME_TAC (X_CHOOSE_TAC `i:num->real^N`))) THEN
  SUBGOAL_THEN `cauchy(i:num->real^N)` MP_TAC THENL
   [REWRITE_TAC[cauchy] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    MP_TAC(SPEC `e / &4 / content(interval[a:real^M,b])`
        REAL_ARCH_INV) THEN
    ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
    MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
    MAP_EVERY X_GEN_TAC [`m:num`; `n:num`] THEN REWRITE_TAC[GE] THEN
    STRIP_TAC THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV [has_integral]) THEN
    ONCE_REWRITE_TAC[SWAP_FORALL_THM] THEN
    DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
    ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
    DISCH_THEN(fun th -> MP_TAC(SPEC `m:num` th) THEN
      MP_TAC(SPEC `n:num` th)) THEN
    DISCH_THEN(X_CHOOSE_THEN `gn:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
    DISCH_THEN(X_CHOOSE_THEN `gm:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
    MP_TAC(ISPECL [`(\x. gm(x) INTER gn(x)):real^M->real^M->bool`;
                   `a:real^M`; `b:real^M`] FINE_DIVISION_EXISTS) THEN
    ASM_SIMP_TAC[GAUGE_INTER; LEFT_IMP_EXISTS_THM] THEN
    X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
    REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`)) THEN
    FIRST_ASSUM(fun th -> REWRITE_TAC[CONV_RULE(REWR_CONV FINE_INTER) th]) THEN
    SUBGOAL_THEN `norm(vsum p (\(x,k:real^M->bool). content k % g (n:num) x) -
                       vsum p (\(x:real^M,k). content k % g m x :real^N))
                  <= e / &2`
    MP_TAC THENL [ALL_TAC; ASM_REWRITE_TAC[dist] THEN MESON_TAC[lemma1]] THEN
    MATCH_MP_TAC REAL_LE_TRANS THEN
    EXISTS_TAC `&2 / &N * content(interval[a:real^M,b])` THEN CONJ_TAC THENL
     [MATCH_MP_TAC RSUM_DIFF_BOUND;
      ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN
      ASM_REAL_ARITH_TAC] THEN
    ASM_REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
    FIRST_X_ASSUM(fun th -> MP_TAC(SPECL [`n:num`; `x:real^M`] th) THEN
      MP_TAC(SPECL [`m:num`; `x:real^M`] th)) THEN
    ASM_REWRITE_TAC[IMP_IMP] THEN
    GEN_REWRITE_TAC (LAND_CONV o RAND_CONV o LAND_CONV) [NORM_SUB] THEN
    DISCH_THEN(MP_TAC o MATCH_MP REAL_LE_ADD2) THEN
    DISCH_THEN(MP_TAC o MATCH_MP NORM_TRIANGLE_LE) THEN
    MATCH_MP_TAC(REAL_ARITH `u = v /\ a <= inv(x) /\ b <= inv(x) ==>
                                u <= a + b ==> v <= &2 / x`) THEN
    CONJ_TAC THENL [AP_TERM_TAC THEN VECTOR_ARITH_TAC; ALL_TAC] THEN
    CONJ_TAC THEN MATCH_MP_TAC REAL_LE_INV2 THEN
    REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
    ASM_ARITH_TAC;
    ALL_TAC] THEN
  REWRITE_TAC[GSYM CONVERGENT_EQ_CAUCHY] THEN
  MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `s:real^N` THEN DISCH_TAC THEN
  REWRITE_TAC[has_integral] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `e / &3` o GEN_REWRITE_RULE I
   [LIM_SEQUENTIALLY]) THEN
  ASM_SIMP_TAC[dist; REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
  DISCH_THEN(X_CHOOSE_TAC `N1:num`) THEN
  MP_TAC(SPEC `e / &3 / content(interval[a:real^M,b])` REAL_ARCH_INV) THEN
  ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
  DISCH_THEN(X_CHOOSE_THEN `N2:num` STRIP_ASSUME_TAC) THEN
  FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV [has_integral]) THEN
  DISCH_THEN(MP_TAC o SPECL [`N1 + N2:num`; `e / &3`]) THEN
  ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
  MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `g:real^M->real^M->bool` THEN
  STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
  X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `p:real^M#(real^M->bool)->bool`) THEN
  ASM_REWRITE_TAC[] THEN
  FIRST_X_ASSUM(MP_TAC o C MATCH_MP (ARITH_RULE `N1:num <= N1 + N2`)) THEN
  MATCH_MP_TAC lemma2 THEN MATCH_MP_TAC REAL_LE_TRANS THEN
  EXISTS_TAC `inv(&(N1 + N2) + &1) * content(interval[a:real^M,b])` THEN
  CONJ_TAC THENL
   [MATCH_MP_TAC RSUM_DIFF_BOUND THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN
  ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ] THEN
  FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
   `x < a ==> y <= x ==> y <= a`)) THEN
  MATCH_MP_TAC REAL_LE_INV2 THEN
  REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN
  ASM_ARITH_TAC);;  
let TAGGED_DIVISION_FINER = prove
 (`!p a b:real^N d. p 
tagged_division_of interval[a,b] /\ 
gauge d
             ==> ?q. q 
tagged_division_of interval[a,b] /\ d 
fine q /\
                     !x k. (x,k) 
IN p /\ k 
SUBSET d(x) ==> (x,k) 
IN q`,
  let lemma1 = prove
   (`{k | ?x. (x,k) IN p} = IMAGE SND p`,
    REWRITE_TAC[EXTENSION; EXISTS_PAIR_THM; IN_IMAGE; IN_ELIM_THM] THEN
    MESON_TAC[]) in
  SUBGOAL_THEN
   `!a b:real^N d p.
       FINITE p
       ==> p tagged_partial_division_of interval[a,b] /\ gauge d
           ==> ?q. q tagged_division_of (UNIONS {k | ?x. x,k IN p}) /\
                   d fine q /\
                   !x k. (x,k) IN p /\ k SUBSET d(x) ==> (x,k) IN q`
  ASSUME_TAC THENL
   [ALL_TAC;
    REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
    GEN_REWRITE_TAC LAND_CONV [tagged_division_of] THEN
    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (SUBST1_TAC o SYM)) THEN
    FIRST_ASSUM(MATCH_MP_TAC o REWRITE_RULE[IMP_IMP]) THEN
    ASM_MESON_TAC[tagged_partial_division_of]] THEN
  GEN_TAC THEN GEN_TAC THEN GEN_TAC THEN
  MATCH_MP_TAC FINITE_INDUCT_STRONG THEN CONJ_TAC THENL
   [DISCH_THEN(K ALL_TAC) THEN
    REWRITE_TAC[SET_RULE `UNIONS {k | ?x. x,k IN {}} = {}`] THEN
    EXISTS_TAC `{}:real^N#(real^N->bool)->bool` THEN
    REWRITE_TAC[fine; NOT_IN_EMPTY; TAGGED_DIVISION_OF_EMPTY];
    ALL_TAC] THEN
  GEN_REWRITE_TAC I [FORALL_PAIR_THM] THEN MAP_EVERY X_GEN_TAC
   [`x:real^N`; `k:real^N->bool`; `p:real^N#(real^N->bool)->bool`] THEN
  DISCH_THEN(CONJUNCTS_THEN2 MP_TAC ASSUME_TAC) THEN
  DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ANTS_TAC THENL
   [ASM_REWRITE_TAC[] THEN MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_SUBSET THEN
    EXISTS_TAC `(x:real^N,k:real^N->bool) INSERT p` THEN ASM SET_TAC[];
    ALL_TAC] THEN
  DISCH_THEN(X_CHOOSE_THEN `q1:real^N#(real^N->bool)->bool`
    STRIP_ASSUME_TAC) THEN
  SUBGOAL_THEN
   `UNIONS {l:real^N->bool | ?y:real^N. (y,l) IN (x,k) INSERT p} =
    k UNION UNIONS {l | ?y. (y,l) IN p}`
  SUBST1_TAC THENL
   [GEN_REWRITE_TAC I [EXTENSION] THEN REWRITE_TAC[IN_UNION; IN_UNIONS] THEN
    REWRITE_TAC[IN_ELIM_THM; IN_INSERT; PAIR_EQ] THEN MESON_TAC[];
    ALL_TAC] THEN
  SUBGOAL_THEN `?u v:real^N. k = interval[u,v]` MP_TAC THENL
   [ASM_MESON_TAC[IN_INSERT; tagged_partial_division_of]; ALL_TAC] THEN
  DISCH_THEN(REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) THEN
  ASM_CASES_TAC `interval[u,v] SUBSET ((d:real^N->real^N->bool) x)` THENL
   [EXISTS_TAC `{(x:real^N,interval[u:real^N,v])} UNION q1` THEN CONJ_TAC THENL
     [MATCH_MP_TAC TAGGED_DIVISION_UNION THEN ASM_REWRITE_TAC[] THEN
      CONJ_TAC THENL
       [MATCH_MP_TAC TAGGED_DIVISION_OF_SELF THEN
        FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I
         [tagged_partial_division_of]) THEN
        REWRITE_TAC[IN_INSERT; PAIR_EQ] THEN MESON_TAC[];
        ALL_TAC];
      CONJ_TAC THENL
       [MATCH_MP_TAC FINE_UNION THEN ASM_REWRITE_TAC[] THEN
        REWRITE_TAC[fine; IN_SING; PAIR_EQ] THEN ASM_MESON_TAC[];
        ALL_TAC] THEN
      ASM_REWRITE_TAC[IN_INSERT; PAIR_EQ; IN_UNION; IN_SING] THEN
      ASM_MESON_TAC[]];
    FIRST_ASSUM(MP_TAC o SPECL [`u:real^N`; `v:real^N`] o MATCH_MP
      FINE_DIVISION_EXISTS) THEN
    DISCH_THEN(X_CHOOSE_THEN `q2:real^N#(real^N->bool)->bool`
      STRIP_ASSUME_TAC) THEN
    EXISTS_TAC `q2 UNION q1:real^N#(real^N->bool)->bool` THEN CONJ_TAC THENL
     [MATCH_MP_TAC TAGGED_DIVISION_UNION THEN ASM_REWRITE_TAC[];
      ASM_SIMP_TAC[FINE_UNION] THEN
      ASM_REWRITE_TAC[IN_INSERT; PAIR_EQ; IN_UNION; IN_SING] THEN
      ASM_MESON_TAC[]]] THEN
  (MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
   REWRITE_TAC[lemma1; IN_ELIM_THM; LEFT_IMP_EXISTS_THM] THEN
   FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I
      [tagged_partial_division_of]) THEN
   REWRITE_TAC[IN_INSERT; FINITE_INSERT; PAIR_EQ] THEN
   STRIP_TAC THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN CONJ_TAC THENL
    [REWRITE_TAC[INTERIOR_CLOSED_INTERVAL; OPEN_INTERVAL]; ALL_TAC] THEN
   CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
   REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
   ASM_MESON_TAC[]));;  
let HAS_INTEGRAL_SPIKE = prove
 (`!f:real^M->real^N g s t.
        
negligible s /\ (!x. x 
IN (t 
DIFF s) ==> g x = f x) /\
        (f 
has_integral y) t
        ==> (g 
has_integral y) t`,
  SUBGOAL_THEN
   `!f:real^M->real^N g s a b y.
        
negligible s /\ (!x. x 
IN (
interval[a,b] 
DIFF s) ==> g x = f x)
        ==> (f 
has_integral y) (
interval[a,b])
            ==> (g 
has_integral y) (
interval[a,b])`
  ASSUME_TAC THENL
   [REPEAT STRIP_TAC THEN
    SUBGOAL_THEN
     `((\x. (f:real^M->real^N)(x) + (g(x) - f(x))) 
has_integral (y + 
vec 0))
      (
interval[a,b])`
    MP_TAC THENL
     [ALL_TAC;
      REWRITE_TAC[VECTOR_ARITH `f + g - f = g /\ f + 
vec 0 = f`; ETA_AX]] THEN
    MATCH_MP_TAC 
HAS_INTEGRAL_ADD THEN ASM_REWRITE_TAC[] THEN
    MATCH_MP_TAC 
HAS_INTEGRAL_NEGLIGIBLE THEN
    EXISTS_TAC `s:real^M->bool` THEN ASM_REWRITE_TAC[
VECTOR_SUB_EQ] THEN
    ASM_MESON_TAC[];
    ALL_TAC] THEN
  REPEAT GEN_TAC THEN
  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
  ONCE_REWRITE_TAC[
has_integral_alt] THEN COND_CASES_TAC THEN
  ASM_REWRITE_TAC[] THENL
   [FIRST_X_ASSUM(CHOOSE_THEN(CHOOSE_THEN SUBST_ALL_TAC)) THEN ASM_MESON_TAC[];
    ALL_TAC] THEN
  MATCH_MP_TAC 
MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
  REWRITE_TAC[] THEN MATCH_MP_TAC 
MONO_EXISTS THEN GEN_TAC THEN
  MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
  REPEAT(MATCH_MP_TAC 
MONO_FORALL THEN GEN_TAC) THEN
  MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[] THEN
  MATCH_MP_TAC 
MONO_EXISTS THEN GEN_TAC THEN
  MATCH_MP_TAC MONO_AND THEN REWRITE_TAC[] THEN
  FIRST_X_ASSUM MATCH_MP_TAC THEN EXISTS_TAC `s:real^M->bool` THEN
  ASM_REWRITE_TAC[] THEN ASM SET_TAC[]);;
 
let GAUGE_MODIFY = prove
 (`!f:real^M->real^N.
      (!s. open s ==> open {x | f(x) 
IN s})
      ==> !d. 
gauge d ==> 
gauge (\x y. d (f x) (f y))`,
  GEN_TAC THEN DISCH_TAC THEN GEN_TAC THEN
  SIMP_TAC[
gauge; 
IN] THEN DISCH_TAC THEN
  X_GEN_TAC `x:real^M` THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `(f:real^M->real^N) x`) THEN
  DISCH_THEN(ANTE_RES_THEN MP_TAC o CONJUNCT2) THEN
  MATCH_MP_TAC EQ_IMP THEN
  AP_TERM_TAC THEN REWRITE_TAC[
EXTENSION; 
IN_ELIM_THM] THEN
  REWRITE_TAC[
IN]);;
 
let INTEGRAL_HAS_VECTOR_DERIVATIVE = prove
 (`!f:real^1->real^N a b.
     (f 
continuous_on interval[a,b])
     ==> !x. x 
IN interval[a,b]
             ==> ((\u. 
integral (
interval[a,u]) f) 
has_vector_derivative f(x))
                 (
at x 
within interval[a,b])`,
  REWRITE_TAC[
IN_INTERVAL_1] THEN REPEAT STRIP_TAC THEN
  REWRITE_TAC[
has_vector_derivative; 
HAS_DERIVATIVE_WITHIN_ALT] THEN
  CONJ_TAC THENL
   [REWRITE_TAC[
linear; 
DROP_ADD; 
DROP_CMUL] THEN
    CONJ_TAC THEN VECTOR_ARITH_TAC;
    ALL_TAC] THEN
  X_GEN_TAC `e:real` THEN DISCH_TAC THEN REWRITE_TAC[
IN_INTERVAL_1] THEN
  FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[
IMP_CONJ]
    
COMPACT_UNIFORMLY_CONTINUOUS)) THEN
  REWRITE_TAC[
COMPACT_INTERVAL; 
uniformly_continuous_on] THEN
  DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
  MATCH_MP_TAC 
MONO_EXISTS THEN REWRITE_TAC[
dist] THEN
  X_GEN_TAC `d:real` THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
  X_GEN_TAC `y:real^1` THEN STRIP_TAC THEN
  REWRITE_TAC[
NORM_REAL; GSYM 
drop; 
DROP_SUB] THEN
  DISJ_CASES_TAC(REAL_ARITH `
drop x <= 
drop y \/ 
drop y <= 
drop x`) THENL
   [ASM_SIMP_TAC[REAL_ARITH `x <= y ==> abs(y - x) = y - x`];
    ONCE_REWRITE_TAC[VECTOR_ARITH
     `fy - fx - (x - y) % c = --(fx - fy - (y - x) % c)`] THEN
    ASM_SIMP_TAC[
NORM_NEG; REAL_ARITH `x <= y ==> abs(x - y) = y - x`]] THEN
  ASM_SIMP_TAC[GSYM 
CONTENT_1] THEN MATCH_MP_TAC 
HAS_INTEGRAL_BOUND THEN
  EXISTS_TAC `(\u. f(u) - f(x)):real^1->real^N` THEN
  (ASM_SIMP_TAC[
REAL_LT_IMP_LE] THEN CONJ_TAC THENL
   [ALL_TAC;
    REPEAT STRIP_TAC THEN
    MATCH_MP_TAC 
REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
    REPEAT(POP_ASSUM MP_TAC) THEN
    REWRITE_TAC[
IN_INTERVAL_1; 
NORM_REAL; 
DROP_SUB; GSYM 
drop] THEN
    REAL_ARITH_TAC] THEN
   MATCH_MP_TAC 
HAS_INTEGRAL_SUB THEN REWRITE_TAC[
HAS_INTEGRAL_CONST]) THENL
    [SUBGOAL_THEN
      `
integral(
interval[a,x]) f + 
integral(
interval[x,y]) f =
       
integral(
interval[a,y]) f /\
       ((f:real^1->real^N) 
has_integral integral(
interval[x,y]) f)
        (
interval[x,y])`
      (fun 
th -> MESON_TAC[
th;
          VECTOR_ARITH `a + b = c:real^N ==> c - a = b`]);
     SUBGOAL_THEN
      `
integral(
interval[a,y]) f + 
integral(
interval[y,x]) f =
       
integral(
interval[a,x]) f /\
       ((f:real^1->real^N) 
has_integral integral(
interval[y,x]) f)
        (
interval[y,x])`
       (fun 
th -> MESON_TAC[
th;
         VECTOR_ARITH `a + b = c:real^N ==> c - a = b`])] THEN
   (CONJ_TAC THENL
     [MATCH_MP_TAC 
INTEGRAL_COMBINE;
      MATCH_MP_TAC 
INTEGRABLE_INTEGRAL] THEN
    ASM_REWRITE_TAC[] THEN
    MATCH_MP_TAC 
INTEGRABLE_SUBINTERVAL THEN
    MAP_EVERY EXISTS_TAC [`a:real^1`; `b:real^1`] THEN
    ASM_SIMP_TAC[
INTEGRABLE_CONTINUOUS; 
SUBSET_INTERVAL_1] THEN
    ASM_REAL_ARITH_TAC));;
 
let HAS_INTEGRAL_TWIDDLE = prove
 (`!f:real^N->real^P (g:real^M->real^N) h r i a b.
      &0 < r /\
      (!x. h(g x) = x) /\ (!x. g(h x) = x) /\ (!x. g 
continuous at x) /\
      (!u v. ?w z. 
IMAGE g (
interval[u,v]) = 
interval[w,z]) /\
      (!u v. ?w z. 
IMAGE h (
interval[u,v]) = 
interval[w,z]) /\
      (!u v. 
content(
IMAGE g (
interval[u,v])) = r * 
content(
interval[u,v])) /\
      (f 
has_integral i) (
interval[a,b])
      ==> ((\x. f(g x)) 
has_integral (inv r) % i) (
IMAGE h (
interval[a,b]))`,
  let lemma0 = prove
   (`(!x k. (x,k) IN IMAGE (\(x,k). f x,g k) p ==> P x k) <=>
     (!x k. (x,k) IN p ==> P (f x) (g k))`,
    REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM; PAIR_EQ] THEN MESON_TAC[])
  and lemma1 = prove
   (`{k | ?x. (x,k) IN p} = IMAGE SND p`,
    REWRITE_TAC[EXTENSION; EXISTS_PAIR_THM; IN_IMAGE; IN_ELIM_THM] THEN
    MESON_TAC[])
  and lemma2 = prove
   (`SND o (\(x,k). f x,g k) = g o SND`,
    REWRITE_TAC[FUN_EQ_THM; FORALL_PAIR_THM; o_DEF]) in
  REPEAT GEN_TAC THEN ASM_CASES_TAC `interval[a:real^N,b] = {}` THEN
  ASM_SIMP_TAC[IMAGE_CLAUSES; HAS_INTEGRAL_EMPTY_EQ; VECTOR_MUL_RZERO] THEN
  REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
  REWRITE_TAC[has_integral] THEN
  ASM_REWRITE_TAC[has_integral_def; has_integral_compact_interval] THEN
  DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `e * r:real`) THEN
  ASM_SIMP_TAC[REAL_LT_MUL] THEN
  DISCH_THEN(X_CHOOSE_THEN `d:real^N->real^N->bool` STRIP_ASSUME_TAC) THEN
  EXISTS_TAC `\x y:real^M. (d:real^N->real^N->bool) (g x) (g y)` THEN
  CONJ_TAC THENL
   [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [gauge]) THEN
    SIMP_TAC[gauge; IN; FORALL_AND_THM] THEN
    STRIP_TAC THEN X_GEN_TAC `x:real^M` THEN
    SUBGOAL_THEN `(\y:real^M. (d:real^N->real^N->bool) (g x) (g y)) =
                  {y | g y IN (d (g x))}` SUBST1_TAC
    THENL [SET_TAC[]; ASM_SIMP_TAC[CONTINUOUS_OPEN_PREIMAGE_UNIV]];
    ALL_TAC] THEN
  X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN STRIP_TAC THEN
  FIRST_X_ASSUM(MP_TAC o SPEC
   `IMAGE (\(x,k). (g:real^M->real^N) x, IMAGE g k) p`) THEN
  ANTS_TAC THENL
   [CONJ_TAC THENL
     [ALL_TAC;
      FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
      REWRITE_TAC[fine; lemma0] THEN
      STRIP_TAC THEN REPEAT GEN_TAC THEN DISCH_THEN(ANTE_RES_THEN MP_TAC) THEN
      ASM SET_TAC[]] THEN
    SUBGOAL_THEN
     `interval[a,b] = IMAGE ((g:real^M->real^N) o h) (interval[a,b])`
    SUBST1_TAC THENL [SIMP_TAC[o_DEF] THEN ASM SET_TAC[]; ALL_TAC] THEN
    SUBGOAL_THEN `?u v. IMAGE (h:real^N->real^M) (interval[a,b]) =
                        interval[u,v]`
    (REPEAT_TCL CHOOSE_THEN
      (fun th -> SUBST_ALL_TAC th THEN ASSUME_TAC th)) THENL
      [ASM_MESON_TAC[]; ALL_TAC] THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
    REWRITE_TAC[TAGGED_DIVISION_OF; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
    REWRITE_TAC[lemma0] THEN REWRITE_TAC[IMP_IMP; GSYM CONJ_ASSOC] THEN
    REPEAT GEN_TAC THEN STRIP_TAC THEN CONJ_TAC THENL
     [ASM_SIMP_TAC[FINITE_IMAGE]; ALL_TAC] THEN
    CONJ_TAC THENL
     [MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
      DISCH_TAC THEN
      UNDISCH_TAC
       `!x:real^M k.
             x,k IN p
             ==> x IN k /\
                 k SUBSET interval[u,v] /\
                 ?w z. k = interval[w,z]` THEN
      DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `k:real^M->bool`]) THEN
      ASM_REWRITE_TAC[] THEN
      REPEAT(MATCH_MP_TAC MONO_AND THEN CONJ_TAC) THENL
       [SET_TAC[];
        REWRITE_TAC[IMAGE_o] THEN ASM SET_TAC[];
        STRIP_TAC THEN ASM_REWRITE_TAC[]];
      ALL_TAC] THEN
    CONJ_TAC THENL
     [ALL_TAC;
      ASM_REWRITE_TAC[IMAGE_o] THEN FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
      REWRITE_TAC[lemma1; GSYM IMAGE_o; lemma2] THEN
      REWRITE_TAC[IMAGE_o; GSYM IMAGE_UNIONS; ETA_AX]] THEN
    MAP_EVERY X_GEN_TAC [`x1:real^M`; `k1:real^M->bool`] THEN DISCH_TAC THEN
    MAP_EVERY X_GEN_TAC [`x2:real^M`; `k2:real^M->bool`] THEN STRIP_TAC THEN
    UNDISCH_TAC
     `!x1:real^M k1:real^M->bool.
             x1,k1 IN p
             ==> (!x2 k2.
                      x2,k2 IN p /\ ~(x1,k1 = x2,k2)
                      ==> interior k1 INTER interior k2 = {})` THEN
    DISCH_THEN(MP_TAC o SPECL [`x1:real^M`; `k1:real^M->bool`]) THEN
    ASM_REWRITE_TAC[] THEN
    DISCH_THEN(MP_TAC o SPECL [`x2:real^M`; `k2:real^M->bool`]) THEN
    ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
     [ASM_MESON_TAC[PAIR_EQ]; ALL_TAC] THEN
    MATCH_MP_TAC(SET_RULE
     `interior(IMAGE f s) SUBSET IMAGE f (interior s) /\
      interior(IMAGE f t) SUBSET IMAGE f (interior t) /\
      (!x y. f x = f y ==> x = y)
      ==> interior s INTER interior t = {}
          ==> interior(IMAGE f s) INTER interior(IMAGE f t) = {}`) THEN
    REPEAT CONJ_TAC THEN TRY(MATCH_MP_TAC INTERIOR_IMAGE_SUBSET) THEN
    ASM_MESON_TAC[];
    ALL_TAC] THEN
  W(fun (asl,w) -> MP_TAC(PART_MATCH (lhand o rand) VSUM_IMAGE
                (lhand(rand(lhand(lhand w)))))) THEN
  ANTS_TAC THENL
   [FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
    ASM_REWRITE_TAC[FORALL_PAIR_THM; PAIR_EQ] THEN
    REPEAT GEN_TAC THEN DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
    MATCH_MP_TAC MONO_AND THEN CONJ_TAC THEN ASM SET_TAC[];
    ALL_TAC] THEN
  DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM] THEN
  DISCH_TAC THEN MATCH_MP_TAC REAL_LT_LCANCEL_IMP THEN
  EXISTS_TAC `abs r` THEN ASM_SIMP_TAC[REAL_ARITH `&0 < x ==> &0 < abs x`] THEN
  REWRITE_TAC[GSYM NORM_MUL] THEN ASM_SIMP_TAC[real_abs; REAL_LT_IMP_LE] THEN
  FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
   `x < a * b ==> x = y ==> y < b * a`)) THEN
  AP_TERM_TAC THEN REWRITE_TAC[VECTOR_SUB_LDISTRIB] THEN
  ASM_SIMP_TAC[VECTOR_MUL_ASSOC; REAL_MUL_RINV; REAL_LT_IMP_NZ] THEN
  REWRITE_TAC[VECTOR_MUL_LID; GSYM VSUM_LMUL] THEN
  AP_THM_TAC THEN AP_TERM_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
  REWRITE_TAC[FORALL_PAIR_THM; VECTOR_MUL_ASSOC] THEN
  REPEAT STRIP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
  ASM_MESON_TAC[TAGGED_DIVISION_OF]);;  
let HAS_INTEGRAL = prove
 (`!f:real^M->real^N i s.
     (f 
has_integral i) s <=>
        !e. &0 < e
            ==> ?B. &0 < B /\
                    !a b. 
ball(
vec 0,B) 
SUBSET interval[a,b]
                          ==> ?z. ((\x. if x 
IN s then f(x) else 
vec 0)
                                   
has_integral z) (
interval[a,b]) /\
                                  
norm(z - i) < e`,
  REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [
has_integral_alt] THEN
  COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
  POP_ASSUM(X_CHOOSE_THEN `a:real^M` (X_CHOOSE_THEN `b:real^M`
   SUBST_ALL_TAC)) THEN
  MP_TAC(ISPECL [`a:real^M`; `b:real^M`] (CONJUNCT1 
BOUNDED_INTERVAL)) THEN
  REWRITE_TAC[
BOUNDED_POS] THEN
  DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN EQ_TAC THENL
   [DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    EXISTS_TAC `B + &1` THEN ASM_SIMP_TAC[
REAL_LT_ADD; 
REAL_LT_01] THEN
    MAP_EVERY X_GEN_TAC [`c:real^M`; `d:real^M`] THEN
    REWRITE_TAC[
SUBSET; 
IN_BALL; NORM_ARITH `
dist(
vec 0,x) = 
norm x`] THEN
    DISCH_TAC THEN EXISTS_TAC `i:real^N` THEN
    ASM_REWRITE_TAC[
VECTOR_SUB_REFL; 
NORM_0] THEN
    MATCH_MP_TAC 
HAS_INTEGRAL_RESTRICT_CLOSED_SUBINTERVAL THEN
    ASM_MESON_TAC[
SUBSET; REAL_ARITH `n <= B ==> n < B + &1`];
    ALL_TAC] THEN
  DISCH_TAC THEN
  SUBGOAL_THEN `?y. ((f:real^M->real^N) 
has_integral y) (
interval[a,b])`
  MP_TAC THENL
   [SUBGOAL_THEN
     `?c d. 
interval[a,b] 
SUBSET interval[c,d] /\
            (\x. if x 
IN interval[a,b] then (f:real^M->real^N) x
                 else 
vec 0) 
integrable_on interval[c,d]`
    STRIP_ASSUME_TAC THENL
     [FIRST_X_ASSUM(MP_TAC o C MATCH_MP 
REAL_LT_01) THEN
      DISCH_THEN(X_CHOOSE_THEN `C:real` STRIP_ASSUME_TAC) THEN
      ABBREV_TAC `c:real^M = 
lambda i. --(max B C)` THEN
      ABBREV_TAC `d:real^M = 
lambda i. max B C` THEN
      MAP_EVERY EXISTS_TAC [`c:real^M`; `d:real^M`] THEN CONJ_TAC THENL
       [REWRITE_TAC[
SUBSET] THEN X_GEN_TAC `x:real^M` THEN
        DISCH_TAC THEN REWRITE_TAC[
IN_INTERVAL] THEN
        X_GEN_TAC `k:num` THEN MAP_EVERY EXPAND_TAC ["c";
 
let INTEGRABLE_ALT = prove
 (`!f:real^M->real^N s.
        f 
integrable_on s <=>
          (!a b. (\x. if x 
IN s then f x else 
vec 0) 
integrable_on
                 interval[a,b]) /\
          (!e. &0 < e
               ==> ?B. &0 < B /\
                       !a b c d.
                          
ball(
vec 0,B) 
SUBSET interval[a,b] /\
                          
ball(
vec 0,B) 
SUBSET interval[c,d]
                          ==> 
norm(
integral (
interval[a,b])
                                    (\x. if x 
IN s then f x else 
vec 0) -
                                   
integral (
interval[c,d])
                                    (\x. if x 
IN s then f x else 
vec 0)) < e)`,
  REPEAT GEN_TAC THEN
  GEN_REWRITE_TAC LAND_CONV [
integrable_on] THEN
  ONCE_REWRITE_TAC[
HAS_INTEGRAL_ALT] THEN
  REWRITE_TAC[
RIGHT_EXISTS_AND_THM] THEN
  MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> (a /\ b <=> a /\ c)`) THEN
  DISCH_TAC THEN EQ_TAC THENL
   [DISCH_THEN(X_CHOOSE_THEN `y:real^N` STRIP_ASSUME_TAC) THEN
    X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[
REAL_HALF] THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
    MESON_TAC[NORM_ARITH `
norm(a - y) < e / &2 /\ 
norm(b - y) < e / &2
                          ==> 
norm(a - b) < e`];
    ALL_TAC] THEN
  DISCH_TAC THEN
  SUBGOAL_THEN
   `
cauchy (\n. 
integral (
interval[(
lambda i. --(&n)),(
lambda i. &n)])
                         (\x. if x 
IN s then (f:real^M->real^N) x else 
vec 0))`
  MP_TAC THENL
   [REWRITE_TAC[
cauchy] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
    DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
    MP_TAC(SPEC `B:real` 
REAL_ARCH_SIMPLE) THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `N:num` THEN DISCH_TAC THEN
    REPEAT STRIP_TAC THEN REWRITE_TAC[
dist] THEN
    FIRST_X_ASSUM MATCH_MP_TAC THEN
    REWRITE_TAC[
SUBSET; 
IN_BALL; NORM_ARITH `
dist(
vec 0,x) = 
norm x`] THEN
    CONJ_TAC;
    REWRITE_TAC[GSYM 
CONVERGENT_EQ_CAUCHY] THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `i:real^N` THEN
    REWRITE_TAC[
LIM_SEQUENTIALLY] THEN DISCH_THEN(LABEL_TAC "C") THEN
    X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    REMOVE_THEN "C" (MP_TAC o SPEC `e / &2`) THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[
REAL_HALF] THEN
    DISCH_THEN(X_CHOOSE_THEN `B:real` STRIP_ASSUME_TAC) THEN
    DISCH_THEN(X_CHOOSE_THEN `N:num` ASSUME_TAC) THEN
    MP_TAC(SPEC `max (&N) B` 
REAL_ARCH_SIMPLE) THEN
    REWRITE_TAC[
REAL_MAX_LE; REAL_OF_NUM_LE] THEN
    DISCH_THEN(X_CHOOSE_THEN `n:num` STRIP_ASSUME_TAC) THEN
    EXISTS_TAC `&n` THEN CONJ_TAC THENL
     [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
    MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN STRIP_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `n:num`) THEN ASM_REWRITE_TAC[] THEN
    MATCH_MP_TAC(NORM_ARITH
     `
norm(i1 - i2) < e / &2 ==> 
dist(i1,i) < e / &2 ==> 
norm(i2 - i) < e`) THEN
    FIRST_X_ASSUM MATCH_MP_TAC THEN CONJ_TAC THEN
    MATCH_MP_TAC 
SUBSET_TRANS THEN EXISTS_TAC `
ball(
vec 0:real^M,&n)` THEN
    ASM_SIMP_TAC[
SUBSET_BALL] THEN
    REWRITE_TAC[
SUBSET; 
IN_BALL; NORM_ARITH `
dist(
vec 0,x) = 
norm x`]] THEN
  X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
  SIMP_TAC[
IN_INTERVAL; 
LAMBDA_BETA] THEN REPEAT GEN_TAC THEN STRIP_TAC THEN
  REWRITE_TAC[
REAL_BOUNDS_LE] THEN MATCH_MP_TAC 
REAL_LE_TRANS THEN
  EXISTS_TAC `
norm(x:real^M)` THEN ASM_SIMP_TAC[
COMPONENT_LE_NORM] THEN
  REPEAT(POP_ASSUM MP_TAC) THEN REWRITE_TAC[GSYM 
REAL_OF_NUM_GE] THEN
  REAL_ARITH_TAC);;
 
let INTEGRABLE_ALT_SUBSET = prove
 (`!f:real^M->real^N s.
        f 
integrable_on s <=>
          (!a b. (\x. if x 
IN s then f x else 
vec 0) 
integrable_on
                 interval[a,b]) /\
          (!e. &0 < e
               ==> ?B. &0 < B /\
                       !a b c d.
                          
ball(
vec 0,B) 
SUBSET interval[a,b] /\
                          
interval[a,b] 
SUBSET interval[c,d]
                          ==> 
norm(
integral (
interval[a,b])
                                    (\x. if x 
IN s then f x else 
vec 0) -
                                   
integral (
interval[c,d])
                                    (\x. if x 
IN s then f x else 
vec 0)) < e)`,
  REPEAT GEN_TAC THEN GEN_REWRITE_TAC LAND_CONV [
INTEGRABLE_ALT] THEN
  ABBREV_TAC `g:real^M->real^N = \x. if x 
IN s then f x else 
vec 0` THEN
  POP_ASSUM(K ALL_TAC) THEN
  MATCH_MP_TAC(TAUT `(a ==> (b <=> c)) ==> (a /\ b <=> a /\ c)`) THEN
  DISCH_TAC THEN EQ_TAC THENL [MESON_TAC[
SUBSET_TRANS]; ALL_TAC] THEN
  DISCH_TAC THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[
REAL_HALF] THEN
  MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `B:real` THEN
  STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
  MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real^M`; `d:real^M`] THEN
  STRIP_TAC THEN
  FIRST_X_ASSUM(MP_TAC o SPECL
   [`(
lambda i. max ((a:real^M)$i) ((c:real^M)$i)):real^M`;
    `(
lambda i. min ((b:real^M)$i) ((d:real^M)$i)):real^M`]) THEN
  ASM_REWRITE_TAC[GSYM 
INTER_INTERVAL; 
SUBSET_INTER] THEN
  DISCH_THEN(fun 
th ->
    MP_TAC(ISPECL [`a:real^M`; `b:real^M`] 
th) THEN
    MP_TAC(ISPECL [`c:real^M`; `d:real^M`] 
th)) THEN
  ASM_REWRITE_TAC[
INTER_SUBSET] THEN NORM_ARITH_TAC);;
 
let INTEGRAL_SPLIT_SIGNED = prove
 (`!f:real^M->real^N a b t k.
        1 <= k /\ k <= 
dimindex(:M) /\ a$k <= t /\ a$k <= b$k /\
        f 
integrable_on
        interval[a,(
lambda i. if i = k then max (b$k) t else b$i)]
        ==> 
integral (
interval[a,b]) f =
                
integral(
interval
                 [a,(
lambda i. if i = k then t else b$i)]) f +
                (if b$k < t then -- &1 else &1) %
                
integral(
interval
                 [(
lambda i. if i = k then min (b$k) t else a$i),
                  (
lambda i. if i = k then max (b$k) t else b$i)]) f`,
  REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THENL
   [MP_TAC(ISPECL
    [`f:real^M->real^N`;
     `a:real^M`;
     `(
lambda i. if i = k then t else (b:real^M)$i):real^M`;
     `(b:real^M)$k`; `k:num`]
        
INTEGRAL_SPLIT) THEN
    ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
     [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
       (REWRITE_RULE[
IMP_CONJ] 
INTEGRABLE_ON_SUBINTERVAL)) THEN
      ASM_SIMP_TAC[
SUBSET_INTERVAL; 
LAMBDA_BETA] THEN
      REPEAT STRIP_TAC THEN TRY COND_CASES_TAC THEN
      ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC;
      DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC(VECTOR_ARITH
       `x = y /\ w = z
        ==> x:real^N = (y + z) + --(&1) % w`) THEN
      CONJ_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
      REWRITE_TAC[
CONS_11; 
PAIR_EQ; 
CART_EQ] THEN TRY CONJ_TAC THEN
      ASM_SIMP_TAC[
LAMBDA_BETA] THEN
      GEN_TAC THEN STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN
      ASM_REAL_ARITH_TAC];
    MP_TAC(ISPECL
    [`f:real^M->real^N`;
     `a:real^M`;
     `b:real^M`;
     `t:real`; `k:num`]
        
INTEGRAL_SPLIT) THEN
    ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
     [FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
       (REWRITE_RULE[
IMP_CONJ] 
INTEGRABLE_ON_SUBINTERVAL)) THEN
      ASM_SIMP_TAC[
SUBSET_INTERVAL; 
LAMBDA_BETA] THEN
      REPEAT STRIP_TAC THEN TRY COND_CASES_TAC THEN
      ASM_REWRITE_TAC[] THEN ASM_REAL_ARITH_TAC;
      DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[
VECTOR_MUL_LID] THEN
      BINOP_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
      REWRITE_TAC[
CONS_11; 
PAIR_EQ; 
CART_EQ] THEN TRY CONJ_TAC THEN
      ASM_SIMP_TAC[
LAMBDA_BETA] THEN
      GEN_TAC THEN STRIP_TAC THEN COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN
      ASM_REAL_ARITH_TAC]]);;
 
let INTEGRAL_INTERVALS_INCLUSION_EXCLUSION = prove
 (`!f:real^M->real^N a b c d.
        f 
integrable_on interval[a,b] /\
        c 
IN interval[a,b] /\ d 
IN interval[a,b]
        ==> 
integral(
interval[a,d]) f =
                
vsum {s | s 
SUBSET 1..dimindex(:M)}
                    (\s. --(&1) pow 
CARD {i | i 
IN s /\ d$i < c$i} %
                         
integral
                          (
interval[(
lambda i. if i 
IN s
                                               then min (c$i) (d$i)
                                               else (a:real^M)$i),
                                    (
lambda i. if i 
IN s
                                               then max (c$i) (d$i)
                                               else c$i)]) f)`,
  let lemma1 = prove
   (`!f:(num->bool)->real^N n.
          vsum {s | s SUBSET 1..SUC n} f =
          vsum {s | s SUBSET 1..n} f +
          vsum {s | s SUBSET 1..n} (\s. f(SUC n INSERT s))`,
    REPEAT STRIP_TAC THEN
    REWRITE_TAC[NUMSEG_CLAUSES; ARITH_RULE `1 <= SUC n`; POWERSET_CLAUSES] THEN
    W(MP_TAC o PART_MATCH (lhs o rand) VSUM_UNION o lhs o snd) THEN
    ANTS_TAC THENL
     [ASM_SIMP_TAC[FINITE_IMAGE; FINITE_POWERSET; FINITE_NUMSEG] THEN
      REWRITE_TAC[SET_RULE
       `DISJOINT s (IMAGE f t) <=> !x. x IN t ==> ~(f x IN s)`] THEN
      GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM; SUBSET] THEN
      DISCH_THEN(MP_TAC o SPEC `SUC n`) THEN
      REWRITE_TAC[IN_INSERT; IN_NUMSEG] THEN ARITH_TAC;
      DISCH_THEN SUBST1_TAC THEN AP_TERM_TAC THEN
      MATCH_MP_TAC(REWRITE_RULE[o_DEF] VSUM_IMAGE) THEN
      SIMP_TAC[FINITE_POWERSET; FINITE_NUMSEG] THEN
      MAP_EVERY X_GEN_TAC [`s:num->bool`; `t:num->bool`] THEN
      REWRITE_TAC[IN_ELIM_THM] THEN MATCH_MP_TAC(SET_RULE
       `~(a IN i)
        ==> s SUBSET i /\ t SUBSET i /\ a INSERT s = a INSERT t
            ==> s = t`) THEN
      REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC]) in
  let lemma2 = prove
   (`!f:real^M->real^N m a:real^M c:real^M d:real^M.
          f integrable_on (:real^M) /\ m <= dimindex(:M) /\
          (!i. m < i /\ i <= dimindex(:M) ==> a$i = c$i \/ d$i = c$i) /\
          (!i. m < i /\ i <= dimindex(:M) ==> a$i = c$i ==> a$i = d$i) /\
          (!i. 1 <= i /\ i <= dimindex(:M) ==> a$i <= c$i /\ a$i <= d$i)
          ==> integral(interval[a,d]) f =
                  vsum {s | s SUBSET 1..m}
                      (\s. --(&1) pow CARD {i | i IN s /\ d$i < c$i} %
                           integral
                            (interval[(lambda i. if i IN s
                                                 then min (c$i) (d$i)
                                                 else (a:real^M)$i),
                                      (lambda i. if i IN s
                                                 then max (c$i) (d$i)
                                                 else c$i)]) f)`,
    GEN_TAC THEN INDUCT_TAC THENL
     [REWRITE_TAC[NUMSEG_CLAUSES; ARITH; SUBSET_EMPTY; SING_GSPEC] THEN
      REWRITE_TAC[VSUM_SING; NOT_IN_EMPTY; EMPTY_GSPEC; CARD_CLAUSES] THEN
      REWRITE_TAC[real_pow; LAMBDA_ETA; VECTOR_MUL_LID] THEN
      REWRITE_TAC[ARITH_RULE `0 < i <=> 1 <= i`] THEN REPEAT STRIP_TAC THEN
      ASM_CASES_TAC
       `?k. 1 <= k /\ k <= dimindex(:M) /\ (a:real^M)$k = (c:real^M)$k`
      THENL
       [MATCH_MP_TAC(MESON[] `i = vec 0 /\ j = vec 0 ==> i:real^N = j`) THEN
        CONJ_TAC THEN MATCH_MP_TAC INTEGRAL_NULL THEN
        REWRITE_TAC[CONTENT_EQ_0] THEN ASM_MESON_TAC[];
        SUBGOAL_THEN `d:real^M = c:real^M` (fun th -> REWRITE_TAC[th]) THEN
        REWRITE_TAC[CART_EQ] THEN ASM_MESON_TAC[]];
      ALL_TAC] THEN
    REPEAT STRIP_TAC THEN REWRITE_TAC[lemma1] THEN
    SUBGOAL_THEN
     `!s. s SUBSET 1..m
          ==> --(&1) pow CARD {i | i IN SUC m INSERT s /\ d$i < c$i} =
              (if (d:real^M)$(SUC m) < (c:real^M)$(SUC m) then -- &1 else &1) *
              --(&1) pow CARD {i | i IN s /\ d$i < c$i}`
     (fun th -> SIMP_TAC[th; IN_ELIM_THM]) THENL
     [X_GEN_TAC `s:num->bool` THEN DISCH_TAC THEN
      SUBGOAL_THEN `FINITE(s:num->bool)` ASSUME_TAC THENL
       [ASM_MESON_TAC[FINITE_NUMSEG; FINITE_SUBSET]; ALL_TAC] THEN
      COND_CASES_TAC THENL
       [ASM_SIMP_TAC[CARD_CLAUSES; FINITE_RESTRICT; SET_RULE
         `P a ==> {x | x IN a INSERT s /\ P x} =
                  a INSERT {x | x IN s /\ P x}`] THEN
        REWRITE_TAC[IN_ELIM_THM] THEN COND_CASES_TAC THEN
        ASM_REWRITE_TAC[real_pow] THEN
        SUBGOAL_THEN `~(SUC m IN 1..m)` (fun th -> ASM SET_TAC[th]) THEN
        REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC;
        ASM_SIMP_TAC[REAL_MUL_LID; SET_RULE
         `~(P a) ==> {x | x IN a INSERT s /\ P x} = {x | x IN s /\ P x}`]];
      ALL_TAC] THEN
    MP_TAC(ISPECL
     [`f:real^M->real^N`; `a:real^M`; `d:real^M`; `(c:real^M)$SUC m`; `SUC m`]
         INTEGRAL_SPLIT_SIGNED) THEN
    ANTS_TAC THENL
     [ASM_MESON_TAC[ARITH_RULE `1 <= SUC n`; INTEGRABLE_ON_SUBINTERVAL;
                    SUBSET_UNIV];
      DISCH_THEN SUBST1_TAC] THEN
    REWRITE_TAC[VSUM_LMUL; GSYM VECTOR_MUL_ASSOC] THEN
    BINOP_TAC THENL [ALL_TAC; AP_TERM_TAC] THENL
     [FIRST_X_ASSUM(MP_TAC o SPECL
       [`a:real^M`;
        `c:real^M`;
        `(lambda i. if i = SUC m then (c:real^M)$SUC m
                    else (d:real^M)$i):real^M`]);
      FIRST_X_ASSUM(MP_TAC o SPECL
       [`(lambda i. if i = SUC m
                    then min ((d:real^M)$SUC m) ((c:real^M)$SUC m)
                    else (a:real^M)$i):real^M`;
        `(lambda i. if i = SUC m
                    then max ((d:real^M)$SUC m) ((c:real^M)$SUC m)
                    else (c:real^M)$i):real^M`;
        `(lambda i. if i = SUC m
                    then max ((d:real^M)$SUC m) ((c:real^M)$SUC m)
                    else d$i):real^M`])] THEN
    (ANTS_TAC THENL
      [ASM_REWRITE_TAC[] THEN
       CONJ_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
       CONJ_TAC THENL
        [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
         SUBGOAL_THEN `1 <= i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
         ASM_SIMP_TAC[LAMBDA_BETA] THEN
         COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
         FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_ARITH_TAC;
         ALL_TAC] THEN
       CONJ_TAC THENL
        [X_GEN_TAC `i:num` THEN STRIP_TAC THEN
         SUBGOAL_THEN `1 <= i` ASSUME_TAC THENL [ASM_ARITH_TAC; ALL_TAC] THEN
         ASM_SIMP_TAC[LAMBDA_BETA] THEN
         COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
         ASM_MESON_TAC[ARITH_RULE `m < i <=> i = SUC m \/ SUC m < i`];
         X_GEN_TAC `i:num` THEN STRIP_TAC THEN ASM_SIMP_TAC[LAMBDA_BETA] THEN
         COND_CASES_TAC THEN ASM_SIMP_TAC[] THEN TRY REAL_ARITH_TAC THEN
         FIRST_X_ASSUM SUBST_ALL_TAC THEN ASM_REWRITE_TAC[] THEN
         ASM_MESON_TAC[]];
       DISCH_THEN SUBST1_TAC THEN MATCH_MP_TAC VSUM_EQ THEN
       X_GEN_TAC `s:num->bool` THEN REWRITE_TAC[IN_ELIM_THM] THEN
       DISCH_TAC THEN BINOP_TAC THENL
        [AP_TERM_TAC THEN AP_TERM_TAC THEN
         REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
         X_GEN_TAC `i:num` THEN
         ASM_CASES_TAC `(i:num) IN s` THEN ASM_REWRITE_TAC[] THEN
         SUBGOAL_THEN `i IN 1..m` MP_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
         REWRITE_TAC[IN_NUMSEG] THEN STRIP_TAC THEN
         SUBGOAL_THEN `i <= dimindex(:M)` ASSUME_TAC THENL
          [ASM_ARITH_TAC; ALL_TAC] THEN
         ASM_SIMP_TAC[LAMBDA_BETA] THEN
         COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN ASM_ARITH_TAC;
         AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
         REWRITE_TAC[CONS_11; PAIR_EQ] THEN
         SIMP_TAC[CART_EQ; LAMBDA_BETA; AND_FORALL_THM] THEN
         X_GEN_TAC `i:num` THEN
         ASM_CASES_TAC `1 <= i /\ i <= dimindex(:M)` THEN
         ASM_REWRITE_TAC[] THEN
         ASM_CASES_TAC `(i:num) IN s` THEN ASM_REWRITE_TAC[IN_INSERT] THEN
         COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN TRY REAL_ARITH_TAC THEN
         SUBGOAL_THEN `~(SUC m IN 1..m)` (fun th -> ASM SET_TAC[th]) THEN
         REWRITE_TAC[IN_NUMSEG] THEN ARITH_TAC]])) in
  REWRITE_TAC[IN_INTERVAL] THEN REPEAT STRIP_TAC THEN
  MP_TAC(ISPECL
   [`\x. if x IN interval[a,b] then (f:real^M->real^N) x else vec 0`;
    `dimindex(:M)`; `a:real^M`; `c:real^M`; `d:real^M`]
   lemma2) THEN
  ASM_SIMP_TAC[LTE_ANTISYM; INTEGRABLE_RESTRICT_UNIV; LE_REFL] THEN
  MATCH_MP_TAC EQ_IMP THEN BINOP_TAC THENL
   [ALL_TAC;
    MATCH_MP_TAC VSUM_EQ THEN X_GEN_TAC `s:num->bool` THEN
    REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN AP_TERM_TAC] THEN
  MATCH_MP_TAC INTEGRAL_EQ THEN ASM_REWRITE_TAC[] THEN
  MATCH_MP_TAC(SET_RULE
   `i SUBSET j ==> !x. x IN i ==> (if x IN j then f x else b) = f x`) THEN
  ASM_SIMP_TAC[SUBSET_INTERVAL; REAL_LE_REFL; LAMBDA_BETA] THEN
  DISCH_TAC THEN X_GEN_TAC `i:num` THEN STRIP_TAC THEN
  REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN
  ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC);;  
let INTEGRABLE_STRADDLE = prove
 (`!f:real^N->real^1 s.
        (!e. &0 < e
             ==> ?g h i j. (g 
has_integral i) s /\
                           (h 
has_integral j) s /\
                           
norm(i - j) < e /\
                           !x. x 
IN s
                               ==> 
drop(g x) <= 
drop(f x) /\
                                   
drop(f x) <= 
drop(h x))
        ==> f 
integrable_on s`,
  let lemma = prove
   (`&0 <= drop x /\ drop x <= drop y ==> norm x <= norm y`,
    REWRITE_TAC[NORM_REAL; GSYM drop] THEN REAL_ARITH_TAC) in
  REPEAT STRIP_TAC THEN
  SUBGOAL_THEN
   `!a b. (\x. if x IN s then (f:real^N->real^1) x else vec 0)
          integrable_on interval[a,b]`
  ASSUME_TAC THENL
   [RULE_ASSUM_TAC(REWRITE_RULE[HAS_INTEGRAL_ALT]) THEN
    MAP_EVERY X_GEN_TAC [`a:real^N`; `b:real^N`] THEN
    MATCH_MP_TAC INTEGRABLE_STRADDLE_INTERVAL THEN
    X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `e / &4`) THEN
    ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
    REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN
    MAP_EVERY X_GEN_TAC
     [`g:real^N->real^1`; `h:real^N->real^1`; `i:real^1`; `j:real^1`] THEN
    REWRITE_TAC[GSYM CONJ_ASSOC] THEN
    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
    DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `e / &4`) MP_TAC) THEN
    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
    DISCH_THEN(CONJUNCTS_THEN2 (MP_TAC o SPEC `e / &4`) STRIP_ASSUME_TAC) THEN
    ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
    DISCH_THEN(X_CHOOSE_THEN `B2:real`
     (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "H"))) THEN
    DISCH_THEN(X_CHOOSE_THEN `B1:real`
     (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "G"))) THEN
    MAP_EVERY EXISTS_TAC
     [`\x. if x IN s then (g:real^N->real^1) x else vec 0`;
      `\x. if x IN s then (h:real^N->real^1) x else vec 0`;
      `integral(interval[a:real^N,b])
         (\x. if x IN s then (g:real^N->real^1) x else vec 0:real^1)`;
      `integral(interval[a:real^N,b])
         (\x. if x IN s then (h:real^N->real^1) x else vec 0:real^1)`] THEN
    ASM_SIMP_TAC[INTEGRABLE_INTEGRAL] THEN
    CONJ_TAC THENL [ALL_TAC; ASM_MESON_TAC[REAL_LE_REFL]] THEN
    ABBREV_TAC `c:real^N = lambda i. min ((a:real^N)$i) (--(max B1 B2))` THEN
    ABBREV_TAC `d:real^N = lambda i. max ((b:real^N)$i) (max B1 B2)` THEN
    REMOVE_THEN "H" (MP_TAC o SPECL [`c:real^N`; `d:real^N`]) THEN
    REMOVE_THEN "G" (MP_TAC o SPECL [`c:real^N`; `d:real^N`]) THEN
    MATCH_MP_TAC(TAUT
        `(a /\ c) /\ (b /\ d ==> e) ==> (a ==> b) ==> (c ==> d) ==> e`) THEN
    CONJ_TAC THENL
     [CONJ_TAC THEN MAP_EVERY EXPAND_TAC ["c";  
let HENSTOCK_LEMMA_PART1 = prove
 (`!f:real^M->real^N a b d e.
        f 
integrable_on interval[a,b] /\
        &0 < e /\ 
gauge d /\
        (!p. p 
tagged_division_of interval[a,b] /\ d 
fine p
             ==> 
norm (
vsum p (\(x,k). 
content k % f x) -
                       
integral(
interval[a,b]) f) < e)
        ==> !p. p 
tagged_partial_division_of interval[a,b] /\ d 
fine p
                            ==> 
norm(
vsum p (\(x,k). 
content k % f x -
                                                     
integral k f)) <= e`,
  let lemma = prove
   (`(!k. &0 < k ==> x <= e + k) ==> x <= e`,
    DISCH_THEN(MP_TAC o SPEC `(x - e) / &2`) THEN REAL_ARITH_TAC) in
  REPEAT GEN_TAC THEN STRIP_TAC THEN GEN_TAC THEN STRIP_TAC THEN
  MATCH_MP_TAC lemma THEN X_GEN_TAC `k:real` THEN DISCH_TAC THEN
  MP_TAC(ISPECL
    [`IMAGE SND (p:(real^M#(real^M->bool))->bool)`; `a:real^M`; `b:real^M`]
    PARTIAL_DIVISION_EXTEND_INTERVAL) THEN
  ANTS_TAC THENL
   [CONJ_TAC THENL
     [ASM_MESON_TAC[PARTIAL_DIVISION_OF_TAGGED_DIVISION]; ALL_TAC] THEN
    REWRITE_TAC[SUBSET; FORALL_IN_UNIONS] THEN
    REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
    REWRITE_TAC[FORALL_PAIR_THM] THEN
    ASM_MESON_TAC[tagged_partial_division_of; SUBSET];
    ALL_TAC] THEN
  SUBGOAL_THEN `FINITE(p:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
   [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
  DISCH_THEN(X_CHOOSE_THEN `q:(real^M->bool)->bool` STRIP_ASSUME_TAC) THEN
  FIRST_X_ASSUM(MP_TAC o MATCH_MP(SET_RULE
   `s SUBSET t ==> t = s UNION (t DIFF s)`)) THEN
  ABBREV_TAC `r = q DIFF IMAGE SND (p:(real^M#(real^M->bool))->bool)` THEN
  SUBGOAL_THEN `IMAGE SND (p:(real^M#(real^M->bool))->bool) INTER r = {}`
  ASSUME_TAC THENL [EXPAND_TAC "r" THEN SET_TAC[]; ALL_TAC] THEN
  DISCH_THEN SUBST_ALL_TAC THEN
  SUBGOAL_THEN `FINITE(r:(real^M->bool)->bool)` ASSUME_TAC THENL
   [ASM_MESON_TAC[division_of; FINITE_UNION]; ALL_TAC] THEN
  SUBGOAL_THEN
   `!i. i IN r
        ==> ?p. p tagged_division_of i /\ d fine p /\
                norm(vsum p (\(x,j). content j % f x) -
                     integral i (f:real^M->real^N))
                < k / (&(CARD(r:(real^M->bool)->bool)) + &1)`
  MP_TAC THENL
   [X_GEN_TAC `i:real^M->bool` THEN DISCH_TAC THEN
    SUBGOAL_THEN `(i:real^M->bool) SUBSET interval[a,b]` ASSUME_TAC THENL
     [ASM_MESON_TAC[division_of; IN_UNION]; ALL_TAC] THEN
    SUBGOAL_THEN `?u v:real^M. i = interval[u,v]`
     (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
    THENL [ASM_MESON_TAC[division_of; IN_UNION]; ALL_TAC] THEN
    SUBGOAL_THEN `(f:real^M->real^N) integrable_on interval[u,v]` MP_TAC THENL
     [ASM_MESON_TAC[INTEGRABLE_SUBINTERVAL]; ALL_TAC] THEN
    DISCH_THEN(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
    REWRITE_TAC[has_integral] THEN
    DISCH_THEN(MP_TAC o SPEC `k / (&(CARD(r:(real^M->bool)->bool)) + &1)`) THEN
    ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &n + &1`] THEN
    DISCH_THEN(X_CHOOSE_THEN `dd:real^M->real^M->bool` MP_TAC) THEN
    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
    MP_TAC(ISPECL [`d:real^M->real^M->bool`; `dd:real^M->real^M->bool`]
      GAUGE_INTER) THEN
    ASM_REWRITE_TAC[] THEN
    DISCH_THEN(MP_TAC o MATCH_MP FINE_DIVISION_EXISTS) THEN
    DISCH_THEN(MP_TAC o SPECL [`u:real^M`; `v:real^M`]) THEN
    REWRITE_TAC[FINE_INTER] THEN MESON_TAC[];
    ALL_TAC] THEN
  REWRITE_TAC[RIGHT_IMP_EXISTS_THM; SKOLEM_THM] THEN
  REWRITE_TAC[TAUT `(a ==> b /\ c) <=> (a ==> b) /\ (a ==> c)`] THEN
  REWRITE_TAC[FORALL_AND_THM] THEN
  DISCH_THEN(X_CHOOSE_THEN `q:(real^M->bool)->(real^M#(real^M->bool))->bool`
    STRIP_ASSUME_TAC) THEN
  FIRST_X_ASSUM(MP_TAC o SPEC
    `p UNION UNIONS {q (i:real^M->bool) | i IN r}
     :(real^M#(real^M->bool))->bool`) THEN
  ANTS_TAC THENL
   [CONJ_TAC THENL
     [ALL_TAC;
      MATCH_MP_TAC FINE_UNION THEN ASM_REWRITE_TAC[] THEN
      MATCH_MP_TAC FINE_UNIONS THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
      ASM_REWRITE_TAC[FORALL_IN_IMAGE]] THEN
    FIRST_ASSUM(SUBST1_TAC o SYM o last o CONJUNCTS o
                GEN_REWRITE_RULE I [division_of]) THEN
    REWRITE_TAC[UNIONS_UNION] THEN
    MATCH_MP_TAC TAGGED_DIVISION_UNION THEN CONJ_TAC THENL
     [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_OF_UNION_SELF]; ALL_TAC] THEN
    CONJ_TAC THENL
     [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
      MATCH_MP_TAC TAGGED_DIVISION_UNIONS THEN
      FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
      SIMP_TAC[FINITE_UNION; IN_UNION] THEN ASM_MESON_TAC[];
      ALL_TAC] THEN
    MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
    REWRITE_TAC[OPEN_INTERIOR] THEN
    REPEAT(CONJ_TAC THENL
            [ASM_MESON_TAC[division_of; FINITE_UNION; IN_UNION]; ALL_TAC]) THEN
    X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
    ONCE_REWRITE_TAC[INTER_COMM] THEN
    MATCH_MP_TAC INTER_INTERIOR_UNIONS_INTERVALS THEN
    REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM; OPEN_INTERIOR] THEN
    REPEAT(CONJ_TAC THENL
     [ASM_MESON_TAC[tagged_partial_division_of; FINITE_IMAGE]; ALL_TAC]) THEN
    REPEAT STRIP_TAC THEN
    FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
    DISCH_THEN(MATCH_MP_TAC o el 2 o CONJUNCTS) THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
    REWRITE_TAC[NOT_IN_EMPTY; GSYM NOT_EXISTS_THM] THEN
    ASM_REWRITE_TAC[EXISTS_PAIR_THM; IN_IMAGE; IN_INTER; IN_UNION] THEN
    ASM_MESON_TAC[];
    ALL_TAC] THEN
  SUBGOAL_THEN
   `vsum (p UNION UNIONS {q i | i IN r}) (\(x,k). content k % f x) =
    vsum p (\(x:real^M,k:real^M->bool). content k % f x:real^N) +
    vsum (UNIONS {q i | (i:real^M->bool) IN r}) (\(x,k). content k % f x)`
  SUBST1_TAC THENL
   [MATCH_MP_TAC VSUM_UNION_NONZERO THEN ASM_REWRITE_TAC[] THEN
    ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
    ASM_SIMP_TAC[FINITE_UNIONS; FINITE_IMAGE; FORALL_IN_IMAGE] THEN
    CONJ_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF_FINITE]; ALL_TAC] THEN
    REWRITE_TAC[IN_INTER] THEN ONCE_REWRITE_TAC[CONJ_SYM] THEN
    REWRITE_TAC[IMP_CONJ; FORALL_IN_UNIONS; FORALL_IN_IMAGE] THEN
    REWRITE_TAC[FORALL_PAIR_THM; FORALL_IN_IMAGE; RIGHT_FORALL_IMP_THM] THEN
    X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
    MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
    DISCH_TAC THEN
    SUBGOAL_THEN `(l:real^M->bool) SUBSET k` ASSUME_TAC THENL
     [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN DISCH_TAC THEN
    FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
    DISCH_THEN(MP_TAC o SPECL [`k:real^M->bool`; `l:real^M->bool`] o
               el 2 o CONJUNCTS) THEN
    ANTS_TAC THENL
     [ASM_REWRITE_TAC[IN_UNION; IN_IMAGE; EXISTS_PAIR_THM] THEN
      CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
      DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
      FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [EXTENSION]) THEN
      REWRITE_TAC[NOT_IN_EMPTY; GSYM NOT_EXISTS_THM] THEN
      ASM_REWRITE_TAC[EXISTS_PAIR_THM; IN_IMAGE; IN_INTER; IN_UNION] THEN
      ASM_MESON_TAC[];
      ALL_TAC] THEN
    ASM_SIMP_TAC[SUBSET_INTERIOR; SET_RULE `s SUBSET t ==> t INTER s = s`] THEN
    SUBGOAL_THEN `?u v:real^M. l = interval[u,v]`
     (fun th -> REPEAT_TCL CHOOSE_THEN SUBST1_TAC th THEN
                SIMP_TAC[VECTOR_MUL_LZERO; GSYM CONTENT_EQ_0_INTERIOR]) THEN
    ASM_MESON_TAC[tagged_partial_division_of];
    ALL_TAC] THEN
  W(MP_TAC o PART_MATCH (lhand o rand) VSUM_UNIONS_NONZERO o
    rand o lhand o rand o lhand o lhand o snd) THEN
  ANTS_TAC THENL
   [ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN ASM_SIMP_TAC[FINITE_IMAGE] THEN
    REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE; RIGHT_FORALL_IMP_THM] THEN
    CONJ_TAC THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF; IN_UNION]; ALL_TAC] THEN
    X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
    X_GEN_TAC `l:real^M->bool` THEN DISCH_TAC THEN
    DISCH_TAC THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
    MAP_EVERY X_GEN_TAC [`x:real^M`; `m:real^M->bool`] THEN
    DISCH_TAC THEN DISCH_TAC THEN
    REWRITE_TAC[VECTOR_MUL_EQ_0] THEN DISJ1_TAC THEN
    SUBGOAL_THEN `?u v:real^M. m = interval[u,v]`
     (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
    THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF; IN_UNION]; ALL_TAC] THEN
    REWRITE_TAC[CONTENT_EQ_0_INTERIOR] THEN
    MATCH_MP_TAC(SET_RULE `!t. s SUBSET t /\ t = {} ==> s = {}`) THEN
    EXISTS_TAC `interior(k INTER l:real^M->bool)` THEN CONJ_TAC THENL
     [MATCH_MP_TAC SUBSET_INTERIOR THEN REWRITE_TAC[SUBSET_INTER] THEN
      ASM_MESON_TAC[TAGGED_DIVISION_OF];
      ALL_TAC] THEN
    FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
    REWRITE_TAC[INTERIOR_INTER] THEN
    DISCH_THEN(MATCH_MP_TAC o SPECL [`k:real^M->bool`; `l:real^M->bool`] o
               el 2 o CONJUNCTS) THEN
    REWRITE_TAC[IN_IMAGE; EXISTS_PAIR_THM; IN_UNION] THEN ASM_MESON_TAC[];
    ALL_TAC] THEN
  DISCH_THEN SUBST1_TAC THEN ONCE_REWRITE_TAC[SIMPLE_IMAGE] THEN
  W(MP_TAC o PART_MATCH (lhand o rand) VSUM_IMAGE_NONZERO o
    rand o lhand o rand o lhand o lhand o snd) THEN
  ASM_REWRITE_TAC[o_DEF] THEN ANTS_TAC THENL
   [MAP_EVERY X_GEN_TAC [`k:real^M->bool`; `l:real^M->bool`] THEN
    STRIP_TAC THEN MATCH_MP_TAC VSUM_EQ_0 THEN
    REWRITE_TAC[FORALL_PAIR_THM] THEN
    MAP_EVERY X_GEN_TAC [`x:real^M`; `m:real^M->bool`] THEN DISCH_TAC THEN
    MP_TAC(ASSUME `!i:real^M->bool. i IN r ==> q i tagged_division_of i`) THEN
    DISCH_THEN(fun th -> MP_TAC(SPEC `l:real^M->bool` th) THEN
                         ANTS_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC] THEN
                         MP_TAC(SPEC `k:real^M->bool` th) THEN
                         ANTS_TAC THENL [ASM_REWRITE_TAC[]; ALL_TAC]) THEN
    ASM_REWRITE_TAC[tagged_division_of] THEN ASM_MESON_TAC[];
    ALL_TAC] THEN
  DISCH_THEN SUBST1_TAC THEN
  SUBGOAL_THEN
   `vsum p (\(x,k). content k % (f:real^M->real^N) x - integral k f) =
    vsum p (\(x,k). content k % f x) - vsum p (\(x,k). integral k f)`
  SUBST1_TAC THENL [ASM_SIMP_TAC[GSYM VSUM_SUB; LAMBDA_PAIR_THM]; ALL_TAC] THEN
  MATCH_MP_TAC(NORM_ARITH
   `!ir. ip + ir = i /\
         norm(cr - ir) < k
         ==> norm((cp + cr) - i) < e ==> norm(cp - ip) <= e + k`) THEN
  EXISTS_TAC `vsum r (\k. integral k (f:real^M->real^N))` THEN CONJ_TAC THENL
   [MATCH_MP_TAC EQ_TRANS THEN
    EXISTS_TAC `vsum (IMAGE SND (p:(real^M#(real^M->bool))->bool) UNION r)
                     (\k. integral k (f:real^M->real^N))` THEN
    CONJ_TAC THENL
     [ALL_TAC; ASM_MESON_TAC[INTEGRAL_COMBINE_DIVISION_TOPDOWN]] THEN
    MATCH_MP_TAC EQ_TRANS THEN
    EXISTS_TAC `vsum (IMAGE SND (p:(real^M#(real^M->bool))->bool))
                     (\k. integral k (f:real^M->real^N)) +
                vsum r (\k. integral k f)` THEN
    CONJ_TAC THENL
     [ALL_TAC;
      CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_UNION_NONZERO THEN
      ASM_SIMP_TAC[FINITE_IMAGE; NOT_IN_EMPTY]] THEN
    AP_THM_TAC THEN AP_TERM_TAC THEN
    SUBGOAL_THEN `(\(x:real^M,k). integral k (f:real^M->real^N)) =
                  (\k. integral k f) o SND`
    SUBST1_TAC THENL
     [SIMP_TAC[o_THM; FUN_EQ_THM; FORALL_PAIR_THM]; ALL_TAC] THEN
    CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_IMAGE_NONZERO THEN
    ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
    MAP_EVERY X_GEN_TAC
     [`x:real^M`; `l:real^M->bool`; `y:real^M`; `m:real^M->bool`] THEN
    REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
    DISCH_THEN(SUBST_ALL_TAC o SYM) THEN
    FIRST_X_ASSUM(MP_TAC o
      GEN_REWRITE_RULE I [tagged_partial_division_of]) THEN
    DISCH_THEN(CONJUNCTS_THEN MP_TAC o CONJUNCT2) THEN
    DISCH_THEN(MP_TAC o SPECL
     [`x:real^M`; `l:real^M->bool`; `y:real^M`; `l:real^M->bool`]) THEN
    ASM_REWRITE_TAC[INTER_IDEMPOT] THEN DISCH_TAC THEN
    DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `l:real^M->bool`]) THEN
    ASM_REWRITE_TAC[] THEN
    DISCH_THEN(REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC o last o CONJUNCTS) THEN
    MATCH_MP_TAC INTEGRAL_UNIQUE THEN MATCH_MP_TAC HAS_INTEGRAL_NULL THEN
    ASM_REWRITE_TAC[CONTENT_EQ_0_INTERIOR];
    ALL_TAC] THEN
  ASM_SIMP_TAC[GSYM VSUM_SUB] THEN MATCH_MP_TAC REAL_LET_TRANS THEN
  EXISTS_TAC `sum (r:(real^M->bool)->bool) (\x. k / (&(CARD r) + &1))` THEN
  CONJ_TAC THENL
   [MATCH_MP_TAC VSUM_NORM_LE THEN ASM_SIMP_TAC[REAL_LT_IMP_LE];
    ASM_SIMP_TAC[SUM_CONST] THEN
    REWRITE_TAC[real_div; REAL_MUL_ASSOC] THEN
    SIMP_TAC[GSYM real_div; REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &x + &1`] THEN
    REWRITE_TAC[REAL_ARITH `a * k < k * b <=> &0 < k * (b - a)`] THEN
    MATCH_MP_TAC REAL_LT_MUL THEN ASM_REWRITE_TAC[] THEN REAL_ARITH_TAC]);;  
let MONOTONE_CONVERGENCE_INTERVAL = prove
 (`!f:num->real^N->real^1 g a b.
        (!k. (f k) 
integrable_on interval[a,b]) /\
        (!k x. x 
IN interval[a,b] ==> 
drop(f k x) <= 
drop(f (SUC k) x)) /\
        (!x. x 
IN interval[a,b] ==> ((\k. f k x) --> g x) 
sequentially) /\
        
bounded {
integral (
interval[a,b]) (f k) | k 
IN (:num)}
        ==> g 
integrable_on interval[a,b] /\
            ((\k. 
integral (
interval[a,b]) (f k))
             --> 
integral (
interval[a,b]) g) 
sequentially`,
  let lemma = prove
   (`{(x,y) | P x y} = {p | P (FST p) (SND p)}`,
    REWRITE_TAC[EXTENSION; FORALL_PAIR_THM; IN_ELIM_PAIR_THM; IN_ELIM_THM]) in
  REPEAT GEN_TAC THEN STRIP_TAC THEN
  ASM_CASES_TAC `content(interval[a:real^N,b]) = &0` THENL
   [ASM_SIMP_TAC[INTEGRAL_NULL; INTEGRABLE_ON_NULL; LIM_CONST];
    RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONTENT_LT_NZ])] THEN
  SUBGOAL_THEN
   `!x:real^N k:num. x IN interval[a,b] ==> drop(f k x) <= drop(g x)`
  ASSUME_TAC THENL
   [REPEAT STRIP_TAC THEN
    MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LBOUND) THEN
    EXISTS_TAC `\k. (f:num->real^N->real^1) k x` THEN
    ASM_SIMP_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
    EXISTS_TAC `k:num` THEN SPEC_TAC(`k:num`,`k:num`) THEN
    MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN REWRITE_TAC[REAL_LE_TRANS] THEN
    ASM_SIMP_TAC[REAL_LE_REFL];
    ALL_TAC] THEN
  SUBGOAL_THEN
   `?i. ((\k. integral (interval[a,b]) (f k:real^N->real^1)) --> i)
        sequentially`
  CHOOSE_TAC THENL
   [MATCH_MP_TAC BOUNDED_INCREASING_CONVERGENT THEN ASM_REWRITE_TAC[] THEN
    GEN_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_REWRITE_TAC[];
    ALL_TAC] THEN
  SUBGOAL_THEN
   `!k. drop(integral(interval[a,b]) ((f:num->real^N->real^1) k)) <= drop i`
  ASSUME_TAC THENL
    [GEN_TAC THEN MATCH_MP_TAC(ISPEC `sequentially` LIM_DROP_LBOUND) THEN
     EXISTS_TAC `\k. integral(interval[a,b]) ((f:num->real^N->real^1) k)` THEN
     ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY; EVENTUALLY_SEQUENTIALLY] THEN
     EXISTS_TAC `k:num` THEN SPEC_TAC(`k:num`,`k:num`) THEN
     MATCH_MP_TAC TRANSITIVE_STEPWISE_LE THEN
     ASM_REWRITE_TAC[REAL_LE_REFL; REAL_LE_TRANS] THEN
     GEN_TAC THEN MATCH_MP_TAC INTEGRAL_DROP_LE THEN ASM_REWRITE_TAC[];
     ALL_TAC] THEN
  SUBGOAL_THEN
   `((g:real^N->real^1) has_integral i) (interval[a,b])`
  ASSUME_TAC THENL
   [REWRITE_TAC[has_integral] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV
     [HAS_INTEGRAL_INTEGRAL]) THEN
    REWRITE_TAC[has_integral] THEN
    DISCH_THEN(MP_TAC o GEN `k:num` o
      SPECL [`k:num`; `e / &2 pow (k + 2)`]) THEN
    ASM_SIMP_TAC[REAL_LT_DIV; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN
    GEN_REWRITE_TAC LAND_CONV [SKOLEM_THM] THEN
    REWRITE_TAC[LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN
    X_GEN_TAC `b:num->real^N->real^N->bool` THEN STRIP_TAC THEN
    SUBGOAL_THEN
     `?r. !k. r:num <= k
               ==> &0 <= drop i - drop(integral(interval[a:real^N,b]) (f k)) /\
                   drop i - drop(integral(interval[a,b]) (f k)) < e / &4`
    STRIP_ASSUME_TAC THENL
     [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [LIM_SEQUENTIALLY]) THEN
      DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
      ASM_SIMP_TAC[REAL_LT_DIV; REAL_OF_NUM_LT; ARITH] THEN
      MATCH_MP_TAC MONO_EXISTS THEN GEN_TAC THEN
      MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN
      MATCH_MP_TAC MONO_IMP THEN REWRITE_TAC[ABS_DROP; dist; DROP_SUB] THEN
      MATCH_MP_TAC(REAL_ARITH
       `x <= y ==> abs(x - y) < e ==> &0 <= y - x /\ y - x < e`) THEN
      ASM_REWRITE_TAC[];
      ALL_TAC] THEN
    SUBGOAL_THEN
     `!x. x IN interval[a:real^N,b]
          ==> ?n. r:num <= n /\
                  !k. n <= k ==> &0 <= drop(g x) - drop(f k x) /\
                                 drop(g x) - drop(f k x) <
                                   e / (&4 * content(interval[a,b]))`
    MP_TAC THENL
     [X_GEN_TAC `x:real^N` THEN DISCH_TAC THEN
      FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE (BINDER_CONV o RAND_CONV)
        [LIM_SEQUENTIALLY]) THEN
      DISCH_THEN(MP_TAC o SPEC `x:real^N`) THEN ASM_SIMP_TAC[REAL_SUB_LE] THEN
      DISCH_THEN(MP_TAC o SPEC `e / (&4 * content(interval[a:real^N,b]))`) THEN
      ASM_SIMP_TAC[REAL_LT_DIV; REAL_LT_MUL; REAL_OF_NUM_LT; ARITH] THEN
      REWRITE_TAC[dist; ABS_DROP; DROP_SUB] THEN
      ASM_SIMP_TAC[REAL_ARITH `f <= g ==> abs(f - g) = g - f`] THEN
      DISCH_THEN(X_CHOOSE_TAC `N:num`) THEN
      EXISTS_TAC `N + r:num` THEN CONJ_TAC THENL [ARITH_TAC; ALL_TAC] THEN
      ASM_MESON_TAC[ARITH_RULE `N + r:num <= k ==> N <= k`];
      ALL_TAC] THEN
    GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [RIGHT_IMP_EXISTS_THM] THEN
    REWRITE_TAC[SKOLEM_THM] THEN
    REWRITE_TAC[FORALL_AND_THM; TAUT
     `a ==> b /\ c <=> (a ==> b) /\ (a ==> c)`] THEN
    REWRITE_TAC[RIGHT_IMP_FORALL_THM; IMP_IMP] THEN
    DISCH_THEN(X_CHOOSE_THEN `m:real^N->num` STRIP_ASSUME_TAC) THEN
    ABBREV_TAC `d:real^N->real^N->bool = \x. b(m x:num) x` THEN
    EXISTS_TAC `d:real^N->real^N->bool` THEN CONJ_TAC THENL
     [EXPAND_TAC "d" THEN REWRITE_TAC[gauge] THEN
      FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE BINDER_CONV [gauge]) THEN
      SIMP_TAC[];
      ALL_TAC] THEN
    X_GEN_TAC `p:(real^N#(real^N->bool))->bool` THEN STRIP_TAC THEN
    MATCH_MP_TAC(NORM_ARITH
     `!b c. norm(a - b) <= e / &4 /\
            norm(b - c) < e / &2 /\
            norm(c - d) < e / &4
            ==> norm(a - d) < e`) THEN
    EXISTS_TAC `vsum p (\(x:real^N,k:real^N->bool).
                  content k % (f:num->real^N->real^1) (m x) x)` THEN
    EXISTS_TAC `vsum p (\(x:real^N,k:real^N->bool).
                  integral k ((f:num->real^N->real^1) (m x)))` THEN
    FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
    SUBGOAL_THEN `?s:num. !t:real^N#(real^N->bool). t IN p ==> m(FST t) <= s`
    MP_TAC THENL [ASM_SIMP_TAC[UPPER_BOUND_FINITE_SET]; ALL_TAC] THEN
    REWRITE_TAC[FORALL_PAIR_THM] THEN DISCH_THEN(X_CHOOSE_TAC `s:num`) THEN
    REPEAT CONJ_TAC THENL
     [ASM_SIMP_TAC[GSYM VSUM_SUB] THEN REWRITE_TAC[LAMBDA_PAIR_THM] THEN
      REWRITE_TAC[GSYM VECTOR_SUB_LDISTRIB] THEN
      W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
      ASM_REWRITE_TAC[] THEN
      MATCH_MP_TAC(REAL_ARITH `y <= e ==> x <= y ==> x <= e`) THEN
      REWRITE_TAC[LAMBDA_PAIR_THM] THEN MATCH_MP_TAC REAL_LE_TRANS THEN
      EXISTS_TAC
       `sum p (\(x:real^N,k:real^N->bool).
                 content k * e / (&4 * content (interval[a:real^N,b])))` THEN
      CONJ_TAC THENL
       [MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
        MAP_EVERY X_GEN_TAC [`x:real^N`; `k:real^N->bool`] THEN
        DISCH_TAC THEN REWRITE_TAC[NORM_MUL; GSYM VECTOR_SUB_LDISTRIB] THEN
        MATCH_MP_TAC REAL_LE_MUL2 THEN
        REWRITE_TAC[REAL_ABS_POS; NORM_POS_LE] THEN
        REWRITE_TAC[ABS_DROP; DROP_SUB] THEN
        REWRITE_TAC[REAL_ARITH `abs(x) <= x <=> &0 <= x`] THEN CONJ_TAC THENL
         [ASM_MESON_TAC[CONTENT_POS_LE; TAGGED_DIVISION_OF]; ALL_TAC] THEN
        MATCH_MP_TAC(REAL_ARITH
         `&0 <= g - f /\ g - f < e ==> abs(g - f) <= e`) THEN
        CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
        REWRITE_TAC[LE_REFL] THEN ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET];
        ALL_TAC] THEN
      REWRITE_TAC[LAMBDA_PAIR; SUM_RMUL] THEN REWRITE_TAC[LAMBDA_PAIR_THM] THEN
      FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP
       ADDITIVE_CONTENT_TAGGED_DIVISION th]) THEN
      MATCH_MP_TAC REAL_EQ_IMP_LE THEN
      UNDISCH_TAC `&0 < content(interval[a:real^N,b])` THEN
      CONV_TAC REAL_FIELD;
      ASM_SIMP_TAC[GSYM VSUM_SUB] THEN REWRITE_TAC[LAMBDA_PAIR_THM] THEN
      MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC
        `norm(vsum (0..s)
               (\j. vsum {(x:real^N,k:real^N->bool) | (x,k) IN p /\ m(x) = j}
                         (\(x,k). content k % f (m x) x :real^1 -
                                  integral k (f (m x)))))` THEN
      CONJ_TAC THENL
       [MATCH_MP_TAC REAL_EQ_IMP_LE THEN REWRITE_TAC[lemma] THEN
        AP_TERM_TAC THEN MATCH_MP_TAC(GSYM VSUM_GROUP) THEN
        ASM_REWRITE_TAC[SUBSET; FORALL_IN_IMAGE; IN_NUMSEG; LE_0] THEN
        ASM_REWRITE_TAC[FORALL_PAIR_THM];
        ALL_TAC] THEN
      MATCH_MP_TAC REAL_LET_TRANS THEN
      EXISTS_TAC `sum (0..s) (\i. e / &2 pow (i + 2))` THEN CONJ_TAC THENL
       [ALL_TAC;
        REWRITE_TAC[real_div; GSYM REAL_POW_INV; SUM_LMUL] THEN
        REWRITE_TAC[REAL_POW_ADD; SUM_RMUL] THEN REWRITE_TAC[SUM_GP] THEN
        CONV_TAC REAL_RAT_REDUCE_CONV THEN
        ASM_SIMP_TAC[REAL_LT_LMUL_EQ; CONJUNCT1 LT] THEN
        REWRITE_TAC[real_div; GSYM REAL_MUL_ASSOC] THEN
        CONV_TAC REAL_RAT_REDUCE_CONV THEN
        MATCH_MP_TAC(REAL_ARITH `&0 < x * y ==> (&1 - x) * y < y`) THEN
        MATCH_MP_TAC REAL_LT_MUL THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
        MATCH_MP_TAC REAL_POW_LT THEN CONV_TAC REAL_RAT_REDUCE_CONV] THEN
      MATCH_MP_TAC VSUM_NORM_LE THEN REWRITE_TAC[FINITE_NUMSEG] THEN
      X_GEN_TAC `t:num` THEN REWRITE_TAC[IN_NUMSEG; LE_0] THEN DISCH_TAC THEN
      MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
       `norm(vsum {x:real^N,k:real^N->bool | x,k IN p /\ m x:num = t}
                  (\(x,k). content k % f t x - integral k (f t)):real^1)` THEN
      CONJ_TAC THENL
       [MATCH_MP_TAC REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
        MATCH_MP_TAC VSUM_EQ THEN SIMP_TAC[FORALL_PAIR_THM; IN_ELIM_PAIR_THM];
        ALL_TAC] THEN
      MATCH_MP_TAC(REWRITE_RULE[RIGHT_IMP_FORALL_THM; IMP_IMP]
        HENSTOCK_LEMMA_PART1) THEN
      MAP_EVERY EXISTS_TAC
       [`a:real^N`; `b:real^N`; `(b(t:num)):real^N->real^N->bool`] THEN
      ASM_REWRITE_TAC[] THEN
      ASM_SIMP_TAC[REAL_LT_DIV; REAL_POW_LT; REAL_OF_NUM_LT; ARITH] THEN
      CONJ_TAC THENL
       [MATCH_MP_TAC TAGGED_PARTIAL_DIVISION_SUBSET THEN
        EXISTS_TAC `p:(real^N#(real^N->bool))->bool` THEN
        SIMP_TAC[SUBSET; FORALL_PAIR_THM; IN_ELIM_PAIR_THM] THEN
        ASM_MESON_TAC[tagged_division_of];
        ALL_TAC] THEN
      FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
      EXPAND_TAC "d" THEN REWRITE_TAC[fine; IN_ELIM_PAIR_THM] THEN MESON_TAC[];
      MP_TAC(ISPECL [`(f:num->real^N->real^1) s`; `a:real^N`; `b:real^N`;
                     `p:(real^N#(real^N->bool))->bool`]
                    INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN) THEN
      MP_TAC(ISPECL [`(f:num->real^N->real^1) r`; `a:real^N`; `b:real^N`;
                     `p:(real^N#(real^N->bool))->bool`]
                    INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN) THEN
      ASM_SIMP_TAC[ABS_DROP; DROP_SUB; DROP_VSUM; GSYM DROP_EQ] THEN
      REWRITE_TAC[o_DEF; LAMBDA_PAIR_THM] THEN MATCH_MP_TAC(REAL_ARITH
       `sr <= sx /\ sx <= ss /\ ks <= i /\ &0 <= i - kr /\ i - kr < e
        ==> kr = sr ==> ks = ss ==> abs(sx - i) < e`) THEN
      ASM_SIMP_TAC[LE_REFL] THEN CONJ_TAC THEN MATCH_MP_TAC SUM_LE THEN
      ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
      MAP_EVERY X_GEN_TAC [`x:real^N`; `i:real^N->bool`] THEN DISCH_TAC THEN
      (SUBGOAL_THEN `i SUBSET interval[a:real^N,b]` ASSUME_TAC THENL
        [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
       SUBGOAL_THEN `?u v:real^N. i = interval[u,v]`
        (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
       THENL [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC]) THEN
      MATCH_MP_TAC INTEGRAL_DROP_LE THEN
      REPEAT(CONJ_TAC THENL
       [ASM_MESON_TAC[INTEGRABLE_SUBINTERVAL]; ALL_TAC]) THEN
      X_GEN_TAC `y:real^N` THEN DISCH_TAC THEN
      MP_TAC(ISPEC
        `\m n:num. drop (f m (y:real^N)) <= drop (f n y)`
        TRANSITIVE_STEPWISE_LE) THEN
      REWRITE_TAC[REAL_LE_TRANS; REAL_LE_REFL] THEN
      (ANTS_TAC THENL [ASM_MESON_TAC[SUBSET]; ALL_TAC]) THEN
      DISCH_THEN MATCH_MP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
      ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET]];
    ALL_TAC] THEN
  CONJ_TAC THENL [ASM_MESON_TAC[integrable_on]; ALL_TAC] THEN
  FIRST_ASSUM(SUBST1_TAC o MATCH_MP INTEGRAL_UNIQUE) THEN
  ASM_REWRITE_TAC[]);;  
let SETVARIATION_EQUAL_LEMMA = prove
 (`!mf:((real^M->bool)->real^N)->((real^M->bool)->real^N) ms ms'.
        (!s. ms'(ms s) = s /\ ms(ms' s) = s) /\
        (!f a b. ~(
interval[a,b] = {})
                 ==> mf f (ms (
interval[a,b])) = f (
interval[a,b]) /\
                     ?a' b'. ~(
interval[a',b'] = {}) /\
                             ms' (
interval[a,b]) = 
interval[a',b']) /\
        (!t u. t 
SUBSET u ==> ms t 
SUBSET ms u /\ ms' t 
SUBSET ms' u) /\
        (!d t. d 
division_of t
               ==> (
IMAGE ms d) 
division_of ms t /\
                   (
IMAGE ms' d) 
division_of ms' t)
   ==> (!f s. (mf f) 
has_bounded_setvariation_on (ms s) <=>
              f 
has_bounded_setvariation_on s) /\
       (!f s. 
set_variation (ms s) (mf f) = 
set_variation s f)`,
  REPEAT GEN_TAC THEN STRIP_TAC THEN
  REWRITE_TAC[
has_bounded_setvariation_on; 
set_variation] THEN
  MATCH_MP_TAC(MESON[]
   `((!f s. s1 f s = s2 f s) ==> P) /\
    (!f s. s1 f s = s2 f s)
    ==> P /\ (!f s. 
sup (s1 f s) = 
sup (s2 f s))`) THEN
  CONJ_TAC THENL
   [REWRITE_TAC[
EXTENSION; 
IN_ELIM_THM] THEN
    REPEAT(MATCH_MP_TAC 
MONO_FORALL THEN GEN_TAC) THEN MESON_TAC[];
    ALL_TAC] THEN
  REWRITE_TAC[
EXTENSION; 
IN_ELIM_THM] THEN REPEAT GEN_TAC THEN EQ_TAC THEN
  STRIP_TAC THEN ASM_REWRITE_TAC[] THENL
   [EXISTS_TAC `
IMAGE (ms':(real^M->bool)->real^M->bool) d`;
    EXISTS_TAC `
IMAGE (ms:(real^M->bool)->real^M->bool) d`] THEN
  (CONJ_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
   W(MP_TAC o PART_MATCH (lhand o rand) 
SUM_IMAGE o rand o snd) THEN
   ANTS_TAC THENL [ASM_MESON_TAC[]; DISCH_THEN SUBST1_TAC]) THEN
  MATCH_MP_TAC 
SUM_EQ THEN REWRITE_TAC[
o_THM] THEN FIRST_ASSUM
   (fun 
th -> REWRITE_TAC[MATCH_MP 
FORALL_IN_DIVISION_NONEMPTY th]) THEN
  MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`] THEN STRIP_TAC THEN
  AP_TERM_TAC THEN ASM_SIMP_TAC[] THEN
  SUBGOAL_THEN `?a' b':real^M. ~(
interval[a',b'] = {}) /\
                        ms' (
interval[a:real^M,b]) = 
interval[a',b']`
  STRIP_ASSUME_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
  ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[]);;
 
let OPERATIVE_LIFTED_SETVARIATION = prove
 (`!f:(real^M->bool)->real^N.
        
operative(+) f
        ==> 
operative (
lifted(+))
                      (\i. if f 
has_bounded_setvariation_on i
                           then SOME(
set_variation i f) else NONE)`,
  let lemma1 = prove
   (`!f:(real^M->bool)->real B1 B2 k a b.
      1 <= k /\ k <= dimindex(:M) /\
      (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = &0) /\
      (!a b c. f(interval[a,b]) <=
               f(interval[a,b] INTER {x | x$k <= c}) +
               f(interval[a,b] INTER {x | x$k >= c})) /\
      (!d. d division_of (interval[a,b] INTER {x | x$k <= c})
           ==> sum d f <= B1) /\
      (!d. d division_of (interval[a,b] INTER {x | x$k >= c})
           ==> sum d f <= B2)
      ==> !d. d division_of interval[a,b] ==> sum d f <= B1 + B2`,
    REPEAT GEN_TAC THEN
    REPLICATE_TAC 4 (DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
    DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "L") (LABEL_TAC "R")) THEN
    GEN_TAC THEN DISCH_TAC THEN MATCH_MP_TAC REAL_LE_TRANS THEN
    EXISTS_TAC
     `sum {l INTER {x:real^M | x$k <= c} | l | l IN d /\
                                        ~(l INTER {x | x$k <= c} = {})} f +
      sum {l INTER {x | x$k >= c} | l | l IN d /\
                                        ~(l INTER {x | x$k >= c} = {})} f` THEN
    CONJ_TAC THENL
     [ALL_TAC;
      MATCH_MP_TAC REAL_LE_ADD2 THEN CONJ_TAC THEN
      FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[DIVISION_SPLIT]] THEN
    ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
    FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
    W(fun (asl,w) ->
         MP_TAC(PART_MATCH (lhs o rand) SUM_IMAGE_NONZERO (lhand(rand w))) THEN
         MP_TAC(PART_MATCH (lhs o rand) SUM_IMAGE_NONZERO (rand(rand w)))) THEN
    MATCH_MP_TAC(TAUT
     `(a1 /\ a2) /\ (b1 /\ b2 ==> c)
      ==> (a1 ==> b1) ==> (a2 ==> b2) ==> c`) THEN
    CONJ_TAC THENL
     [ASM_SIMP_TAC[FINITE_RESTRICT; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
      REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ] THEN
      FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
      REPEAT STRIP_TAC THEN ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
      FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THENL
       [MATCH_MP_TAC DIVISION_SPLIT_RIGHT_INJ;
        MATCH_MP_TAC DIVISION_SPLIT_LEFT_INJ] THEN
      ASM_MESON_TAC[];
      DISCH_THEN(CONJUNCTS_THEN SUBST1_TAC)] THEN
    MATCH_MP_TAC REAL_LE_TRANS THEN
    EXISTS_TAC
     `sum d (f o (\l. l INTER {x | x$k <= c})) +
      sum d (f o (\l. l INTER {x:real^M | x$k >= c}))` THEN
    CONJ_TAC THENL
     [ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN
      ASM_REWRITE_TAC[o_THM] THEN
      FIRST_ASSUM(fun th -> ASM_REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]);
      MATCH_MP_TAC(REAL_ARITH `x = y /\ w = z ==> x + w <= y + z`) THEN
      CONJ_TAC THEN MATCH_MP_TAC SUM_SUPERSET THEN
      REWRITE_TAC[SET_RULE `{x | x IN s /\ P x} SUBSET s`] THEN
      REWRITE_TAC[SET_RULE `(x IN s /\ ~(x IN {x | x IN s /\ ~P x}) ==> Q x) <=>
                            (x IN s ==> P x ==> Q x)`] THEN
      SIMP_TAC[o_THM] THEN ASM_MESON_TAC[EMPTY_AS_INTERVAL; CONTENT_EMPTY]])
  and lemma2 = prove
   (`!f:(real^M->bool)->real B k.
      1 <= k /\ k <= dimindex(:M) /\
      (!a b. content(interval[a,b]) = &0 ==> f(interval[a,b]) = &0) /\
      (!d. d division_of interval[a,b] ==> sum d f <= B)
      ==> !d1 d2. d1 division_of (interval[a,b] INTER {x | x$k <= c}) /\
                  d2 division_of (interval[a,b] INTER {x | x$k >= c})
                  ==> sum d1 f + sum d2 f <= B`,
    REPEAT STRIP_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `d1 UNION d2:(real^M->bool)->bool`) THEN
    ANTS_TAC THENL
     [SUBGOAL_THEN
       `interval[a,b] = (interval[a,b] INTER {x:real^M | x$k <= c}) UNION
                        (interval[a,b] INTER {x:real^M | x$k >= c})`
      SUBST1_TAC THENL
       [MATCH_MP_TAC(SET_RULE
         `(!x. x IN t \/ x IN u) ==> (s = s INTER t UNION s INTER u)`) THEN
        REWRITE_TAC[IN_ELIM_THM] THEN REAL_ARITH_TAC;
        MATCH_MP_TAC DIVISION_DISJOINT_UNION THEN ASM_REWRITE_TAC[] THEN
        REWRITE_TAC[GSYM INTERIOR_INTER] THEN
        MATCH_MP_TAC(SET_RULE
         `!t. interior s SUBSET interior t /\ interior t = {}
              ==> interior s = {}`) THEN
        EXISTS_TAC `{x:real^M | x$k = c}` THEN CONJ_TAC THENL
         [ALL_TAC; REWRITE_TAC[INTERIOR_STANDARD_HYPERPLANE]] THEN
        MATCH_MP_TAC SUBSET_INTERIOR THEN
        REWRITE_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN REAL_ARITH_TAC];
      MATCH_MP_TAC(REAL_ARITH `x = y ==> x <= b ==> y <= b`) THEN
      MATCH_MP_TAC SUM_UNION_NONZERO THEN
      REPEAT(CONJ_TAC THENL [ASM_MESON_TAC[DIVISION_OF_FINITE]; ALL_TAC]) THEN
      X_GEN_TAC `k:real^M->bool` THEN REWRITE_TAC[IN_INTER] THEN STRIP_TAC THEN
      SUBGOAL_THEN `?u v:real^M. k = interval[u,v]`
        (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
      THENL [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
      FIRST_X_ASSUM MATCH_MP_TAC THEN MATCH_MP_TAC CONTENT_0_SUBSET_GEN THEN
      EXISTS_TAC `interval[a,b] INTER {x:real^M | x$k = c}` THEN CONJ_TAC THENL
       [MATCH_MP_TAC SUBSET_TRANS THEN
        EXISTS_TAC `(interval[a,b] INTER {x:real^M | x$k <= c}) INTER
                    (interval[a,b] INTER {x:real^M | x$k >= c})` THEN
        CONJ_TAC THENL
         [ONCE_REWRITE_TAC[SUBSET_INTER] THEN ASM_MESON_TAC[division_of];
          REWRITE_TAC[SET_RULE
            `(s INTER t) INTER (s INTER u) = s INTER t INTER u`] THEN
          SIMP_TAC[SUBSET; IN_INTER; IN_ELIM_THM] THEN REAL_ARITH_TAC];
        SIMP_TAC[BOUNDED_INTER; BOUNDED_INTERVAL] THEN
        GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
         [REAL_ARITH `x = y <=> x <= y /\ x >= y`] THEN
        REWRITE_TAC[SET_RULE
         `{x | P x /\ Q x} = {x | P x} INTER {x | Q x}`] THEN
        ASM_SIMP_TAC[GSYM INTER_ASSOC; INTERVAL_SPLIT] THEN
        REWRITE_TAC[CONTENT_EQ_0] THEN EXISTS_TAC `k:num` THEN
        ASM_SIMP_TAC[LAMBDA_BETA] THEN REAL_ARITH_TAC]]) in
  REWRITE_TAC[operative; NEUTRAL_VECTOR_ADD] THEN REPEAT GEN_TAC THEN
  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (ASSUME_TAC o GSYM)) THEN
  ASM_SIMP_TAC[HAS_BOUNDED_SETVARIATION_ON_NULL; BOUNDED_INTERVAL;
   MONOIDAL_REAL_ADD; SET_VARIATION_ON_NULL; NEUTRAL_LIFTED;
   NEUTRAL_REAL_ADD] THEN
  MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real`; `k:num`] THEN
  STRIP_TAC THEN ASM_CASES_TAC
   `(f:(real^M->bool)->real^N) has_bounded_setvariation_on interval[a,b]` THEN
  ASM_REWRITE_TAC[] THENL
   [SUBGOAL_THEN
     `(f:(real^M->bool)->real^N) has_bounded_setvariation_on
      interval[a,b] INTER {x | x$k <= c} /\
      (f:(real^M->bool)->real^N) has_bounded_setvariation_on
      interval[a,b] INTER {x | x$k >= c}`
    ASSUME_TAC THENL
     [CONJ_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP
       (REWRITE_RULE[IMP_CONJ] HAS_BOUNDED_SETVARIATION_ON_SUBSET)) THEN
      REWRITE_TAC[INTER_SUBSET];
      ALL_TAC] THEN
    ASM_REWRITE_TAC[lifted] THEN AP_TERM_TAC THEN
    REWRITE_TAC[GSYM REAL_LE_ANTISYM] THEN CONJ_TAC THENL
     [MATCH_MP_TAC SET_VARIATION_UBOUND_ON_INTERVAL THEN ASM_REWRITE_TAC[] THEN
      REPEAT STRIP_TAC THEN MATCH_MP_TAC
       (REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM] lemma1) THEN
      MAP_EVERY EXISTS_TAC [`k:num`; `a:real^M`; `b:real^M`] THEN
      ASM_SIMP_TAC[NORM_0] THEN CONJ_TAC THENL
       [REPEAT GEN_TAC THEN
        MATCH_MP_TAC(NORM_ARITH
          `x:real^N = y + z ==> norm(x) <= norm y + norm z`) THEN
        ASM_SIMP_TAC[];
        FIRST_X_ASSUM(fun th -> MP_TAC th THEN MATCH_MP_TAC MONO_AND) THEN
        ASM_SIMP_TAC[INTERVAL_SPLIT; SET_VARIATION_WORKS_ON_INTERVAL]];
      ONCE_REWRITE_TAC[REAL_ARITH `x + y <= z <=> x <= z - y`] THEN
      ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
      MATCH_MP_TAC SET_VARIATION_UBOUND_ON_INTERVAL THEN
      ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THEN
      X_GEN_TAC `d1:(real^M->bool)->bool` THEN STRIP_TAC THEN
      ONCE_REWRITE_TAC[REAL_ARITH `x <= y - z <=> z <= y - x`] THEN
      ASM_SIMP_TAC[INTERVAL_SPLIT] THEN
      MATCH_MP_TAC SET_VARIATION_UBOUND_ON_INTERVAL THEN
      ASM_SIMP_TAC[GSYM INTERVAL_SPLIT] THEN
      X_GEN_TAC `d2:(real^M->bool)->bool` THEN STRIP_TAC THEN
      REWRITE_TAC[REAL_ARITH `x <= y - z <=> z + x <= y`] THEN
      REPEAT STRIP_TAC THEN MATCH_MP_TAC
       (REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM] lemma2) THEN
      EXISTS_TAC `k:num` THEN
      ASM_SIMP_TAC[NORM_0; SET_VARIATION_WORKS_ON_INTERVAL]];
    REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[lifted]) THEN
    FIRST_X_ASSUM(MP_TAC o check (is_neg o concl)) THEN
    MATCH_MP_TAC(TAUT `p ==> ~p ==> q`) THEN
    REWRITE_TAC[HAS_BOUNDED_SETVARIATION_ON_INTERVAL] THEN
    EXISTS_TAC `set_variation (interval[a,b] INTER {x | x$k <= c})
                              (f:(real^M->bool)->real^N) +
                set_variation (interval[a,b] INTER {x | x$k >= c}) f` THEN
    REPEAT STRIP_TAC THEN MATCH_MP_TAC
       (REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM] lemma1) THEN
      MAP_EVERY EXISTS_TAC [`k:num`; `a:real^M`; `b:real^M`] THEN
      ASM_SIMP_TAC[NORM_0] THEN REPEAT CONJ_TAC THENL
       [REPEAT GEN_TAC THEN
        MATCH_MP_TAC(NORM_ARITH
          `x:real^N = y + z ==> norm(x) <= norm y + norm z`) THEN
        ASM_SIMP_TAC[];
        UNDISCH_TAC
         `(f:(real^M->bool)->real^N) has_bounded_setvariation_on
          (interval[a,b] INTER {x | x$k <= c})` THEN
        ASM_SIMP_TAC[INTERVAL_SPLIT; SET_VARIATION_WORKS_ON_INTERVAL];
        UNDISCH_TAC
         `(f:(real^M->bool)->real^N) has_bounded_setvariation_on
          (interval[a,b] INTER {x | x$k >= c})` THEN
        ASM_SIMP_TAC[INTERVAL_SPLIT; SET_VARIATION_WORKS_ON_INTERVAL]]]);;  
let lemma = prove
 (`!f:A->real^N g s e.
        
sum s (\x. 
norm(f x - g x)) < e
        ==> FINITE s
            ==> abs(
sum s (\x. 
norm(f x)) - 
sum s (\x. 
norm(g x))) < e`,
  REPEAT GEN_TAC THEN SIMP_TAC[GSYM 
SUM_SUB] THEN
  DISCH_THEN(fun 
th -> DISCH_TAC THEN MP_TAC 
th) THEN
  MATCH_MP_TAC(REAL_ARITH `x <= y ==> y < e ==> x < e`) THEN
  W(MP_TAC o PART_MATCH (lhand o rand) 
SUM_ABS o lhand o snd) THEN
  ASM_REWRITE_TAC[] THEN
  MATCH_MP_TAC(REAL_ARITH `y <= z ==> x <= y ==> x <= z`) THEN
  MATCH_MP_TAC 
SUM_LE THEN ASM_REWRITE_TAC[] THEN
  REPEAT STRIP_TAC THEN NORM_ARITH_TAC);;
 
let BOUNDED_SETVARIATION_ABSOLUTELY_INTEGRABLE_INTERVAL = prove
 (`!f:real^M->real^N a b.
        f 
integrable_on interval[a,b] /\
        (\k. 
integral k f) 
has_bounded_setvariation_on interval[a,b]
        ==> f 
absolutely_integrable_on interval[a,b]`,
  REWRITE_TAC[
HAS_BOUNDED_SETVARIATION_ON_INTERVAL] THEN
  REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[
absolutely_integrable_on] THEN
  MP_TAC(ISPEC `
IMAGE (\d. 
sum d (\k. 
norm(
integral k (f:real^M->real^N))))
                      {d | d 
division_of interval[a,b] }`
         
SUP) THEN
  REWRITE_TAC[
FORALL_IN_IMAGE; 
IMAGE_EQ_EMPTY] THEN
  REWRITE_TAC[GSYM 
MEMBER_NOT_EMPTY; 
IN_ELIM_THM] THEN
  ABBREV_TAC
   `i = 
sup (
IMAGE (\d. 
sum d (\k. 
norm(
integral k (f:real^M->real^N))))
                      {d | d 
division_of interval[a,b] })` THEN
  ANTS_TAC THENL
   [REWRITE_TAC[
ELEMENTARY_INTERVAL] THEN ASM_MESON_TAC[]; ALL_TAC] THEN
  STRIP_TAC THEN REWRITE_TAC[
integrable_on] THEN EXISTS_TAC `
lift i` THEN
  REWRITE_TAC[
has_integral] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `i - e / &2`) THEN
  ASM_SIMP_TAC[REAL_ARITH `&0 < e ==> ~(i <= i - e / &2)`] THEN
  REWRITE_TAC[
NOT_FORALL_THM; NOT_IMP; 
REAL_NOT_LE; 
LEFT_IMP_EXISTS_THM] THEN
  X_GEN_TAC `d:(real^M->bool)->bool` THEN STRIP_TAC THEN
  FIRST_ASSUM(ASSUME_TAC o MATCH_MP 
DIVISION_OF_FINITE) THEN
  SUBGOAL_THEN
   `!x. ?e. &0 < e /\
            !i. i 
IN d /\ ~(x 
IN i) ==> 
ball(x:real^M,e) 
INTER i = {}`
  MP_TAC THENL
   [X_GEN_TAC `x:real^M` THEN MP_TAC(ISPECL
     [`
UNIONS {i:real^M->bool | i 
IN d /\ ~(x 
IN i)}`; `x:real^M`]
     
SEPARATE_POINT_CLOSED) THEN
    ANTS_TAC THENL
     [CONJ_TAC THENL [ALL_TAC; SET_TAC[]] THEN
      MATCH_MP_TAC 
CLOSED_UNIONS THEN
      ASM_SIMP_TAC[
FINITE_RESTRICT; 
IN_ELIM_THM; 
IMP_CONJ] THEN
      FIRST_ASSUM(fun t -> REWRITE_TAC[MATCH_MP 
FORALL_IN_DIVISION t]) THEN
      REWRITE_TAC[
CLOSED_INTERVAL];
      ALL_TAC] THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `k:real` THEN
    SIMP_TAC[
FORALL_IN_UNIONS; 
EXTENSION; 
IN_INTER; 
NOT_IN_EMPTY; 
IN_BALL] THEN
    REWRITE_TAC[
IN_ELIM_THM; DE_MORGAN_THM; 
REAL_NOT_LT] THEN MESON_TAC[];
    ALL_TAC] THEN
  REWRITE_TAC[
SKOLEM_THM; 
LEFT_IMP_EXISTS_THM; 
FORALL_AND_THM] THEN
  X_GEN_TAC `k:real^M->
real` THEN STRIP_TAC THEN
  FIRST_ASSUM(MP_TAC o SPEC `e / &2` o MATCH_MP 
HENSTOCK_LEMMA) THEN
  ASM_REWRITE_TAC[
REAL_HALF] THEN
  DISCH_THEN(X_CHOOSE_THEN `g:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
  EXISTS_TAC `\x:real^M. g(x) 
INTER ball(x,k x)` THEN CONJ_TAC THENL
   [MATCH_MP_TAC 
GAUGE_INTER THEN ASM_REWRITE_TAC[] THEN
    ASM_REWRITE_TAC[
gauge; 
CENTRE_IN_BALL; 
OPEN_BALL];
    ALL_TAC] THEN
  REWRITE_TAC[
FINE_INTER] THEN X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN
  STRIP_TAC THEN
  FIRST_ASSUM(ASSUME_TAC o MATCH_MP 
TAGGED_DIVISION_OF_FINITE) THEN
  ABBREV_TAC
   `p' = {(x:real^M,k:real^M->bool) |
                ?i l. x 
IN i /\ i 
IN d /\ (x,l) 
IN p /\ k = i 
INTER l}` THEN
  SUBGOAL_THEN `g 
fine (p':(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
   [EXPAND_TAC "p'" THEN
    MP_TAC(ASSUME `g 
fine (p:(real^M#(real^M->bool))->bool)`) THEN
    REWRITE_TAC[
fine; 
IN_ELIM_PAIR_THM] THEN
    MESON_TAC[SET_RULE `k 
SUBSET l ==> (i 
INTER k) 
SUBSET l`];
    ALL_TAC] THEN
  SUBGOAL_THEN `p' 
tagged_division_of interval[a:real^M,b]` ASSUME_TAC THENL
   [REWRITE_TAC[
TAGGED_DIVISION_OF] THEN EXPAND_TAC "p'" THEN
    REWRITE_TAC[
IN_ELIM_PAIR_THM] THEN
    FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
TAGGED_DIVISION_OF]) THEN
    MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
     [DISCH_TAC THEN MATCH_MP_TAC 
FINITE_SUBSET THEN
      EXISTS_TAC
       `
IMAGE (\(k,(x,l)). x,k 
INTER l)
              {k,xl | k 
IN (d:(real^M->bool)->bool) /\
                      xl 
IN (p:(real^M#(real^M->bool))->bool)}` THEN
      ASM_SIMP_TAC[
FINITE_IMAGE; 
FINITE_PRODUCT] THEN
      EXPAND_TAC "p'" THEN REWRITE_TAC[
SUBSET; 
FORALL_PAIR_THM] THEN
      REWRITE_TAC[
IN_ELIM_PAIR_THM; 
IN_IMAGE; 
EXISTS_PAIR_THM; 
PAIR_EQ] THEN
      MESON_TAC[];
      ALL_TAC] THEN
    MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
     [DISCH_TAC THEN MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
      REWRITE_TAC[
LEFT_IMP_EXISTS_THM] THEN
      MAP_EVERY X_GEN_TAC [`i:real^M->bool`; `l:real^M->bool`] THEN
      STRIP_TAC THEN FIRST_X_ASSUM SUBST_ALL_TAC THEN
      ASM_SIMP_TAC[
IN_INTER] THEN CONJ_TAC THENL
       [MATCH_MP_TAC(SET_RULE `l 
SUBSET s ==> (k 
INTER l) 
SUBSET s`) THEN
        ASM_MESON_TAC[];
        ALL_TAC] THEN
      FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `l:real^M->bool`]) THEN
      ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
      FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
division_of]) THEN
      DISCH_THEN(MP_TAC o SPEC `i:real^M->bool` o el 1 o CONJUNCTS) THEN
      ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
      ASM_REWRITE_TAC[
INTER_INTERVAL] THEN MESON_TAC[];
      ALL_TAC] THEN
    MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
     [DISCH_TAC THEN MAP_EVERY X_GEN_TAC
       [`x1:real^M`; `k1:real^M->bool`; `x2:real^M`; `k2:real^M->bool`] THEN
      DISCH_THEN(CONJUNCTS_THEN2
       (X_CHOOSE_THEN `i1:real^M->bool` (X_CHOOSE_THEN `l1:real^M->bool`
          STRIP_ASSUME_TAC)) MP_TAC) THEN
      FIRST_X_ASSUM SUBST_ALL_TAC THEN
      DISCH_THEN(CONJUNCTS_THEN2
       (X_CHOOSE_THEN `i2:real^M->bool` (X_CHOOSE_THEN `l2:real^M->bool`
          STRIP_ASSUME_TAC)) ASSUME_TAC) THEN
      FIRST_X_ASSUM SUBST_ALL_TAC THEN
      MATCH_MP_TAC(SET_RULE
       `(
interior(i1) 
INTER interior(i2) = {} \/
         
interior(
l1) 
INTER interior(l2) = {}) /\
        
interior(i1 
INTER l1) 
SUBSET interior(i1) /\
        
interior(i2 
INTER l2) 
SUBSET interior(i2) /\
        
interior(i1 
INTER l1) 
SUBSET interior(
l1) /\
        
interior(i2 
INTER l2) 
SUBSET interior(l2)
        ==> 
interior(i1 
INTER l1) 
INTER interior(i2 
INTER l2) = {}`) THEN
      SIMP_TAC[
SUBSET_INTERIOR; 
INTER_SUBSET] THEN
      FIRST_X_ASSUM(MP_TAC o SPECL
       [`x1:real^M`; `l1:real^M->bool`; `x2:real^M`; `l2:real^M->bool`]) THEN
      ASM_REWRITE_TAC[] THEN
      FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
division_of]) THEN
      DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
      DISCH_THEN(MP_TAC o SPECL [`i1:real^M->bool`; `i2:real^M->bool`]) THEN
      ASM_REWRITE_TAC[] THEN
      FIRST_X_ASSUM(MP_TAC o check(is_neg o concl)) THEN
      ASM_REWRITE_TAC[
PAIR_EQ] THEN MESON_TAC[];
      ALL_TAC] THEN
    DISCH_TAC THEN MATCH_MP_TAC 
SUBSET_ANTISYM THEN CONJ_TAC THENL
     [REWRITE_TAC[
UNIONS_SUBSET; 
IN_ELIM_THM] THEN
      REPEAT STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
      MATCH_MP_TAC(SET_RULE `i 
SUBSET s ==> (i 
INTER k) 
SUBSET s`) THEN
      ASM_MESON_TAC[
division_of];
      ALL_TAC] THEN
    REWRITE_TAC[
SUBSET] THEN X_GEN_TAC `y:real^M` THEN DISCH_TAC THEN
    REWRITE_TAC[
IN_UNIONS; 
IN_ELIM_THM] THEN
    REWRITE_TAC[
LEFT_AND_EXISTS_THM; GSYM 
CONJ_ASSOC] THEN
    REWRITE_TAC[MESON[]
     `p /\ q /\ r /\ x = t /\ P x <=> x = t /\ p /\ q /\ r /\ P t`] THEN
    ONCE_REWRITE_TAC[MESON[]
     `(?a b c d. P a b c d) <=> (?d b c a. P a b c d)`] THEN
    REWRITE_TAC[
IN_INTER; 
UNWIND_THM2] THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
EXTENSION]) THEN
    DISCH_THEN(MP_TAC o SPEC `y:real^M`) THEN ASM_REWRITE_TAC[] THEN
    REWRITE_TAC[
IN_UNIONS; 
IN_ELIM_THM; 
LEFT_AND_EXISTS_THM] THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `l:real^M->bool` THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `x:real^M` THEN
    STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
    FIRST_X_ASSUM(MP_TAC o last o CONJUNCTS o
        GEN_REWRITE_RULE I [
division_of]) THEN
    REWRITE_TAC[
EXTENSION] THEN DISCH_THEN(MP_TAC o SPEC `y:real^M`) THEN
    ASM_REWRITE_TAC[
IN_UNIONS] THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `k:real^M->bool` THEN
    STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
    FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `k:real^M->bool`]) THEN
    GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN
    ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN
    REWRITE_TAC[GSYM 
MEMBER_NOT_EMPTY] THEN
    EXISTS_TAC `y:real^M` THEN ASM_REWRITE_TAC[
INTER; 
IN_ELIM_THM] THEN
    UNDISCH_TAC `(\x:real^M. 
ball (x,k x)) 
fine p` THEN
    REWRITE_TAC[
fine; 
SUBSET] THEN ASM_MESON_TAC[];
    ALL_TAC] THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `p':(real^M#(real^M->bool))->bool`) THEN
  ASM_REWRITE_TAC[] THEN
  ANTS_TAC THENL [ASM_MESON_TAC[
tagged_division_of]; ALL_TAC] THEN
  FIRST_ASSUM(ASSUME_TAC o MATCH_MP 
TAGGED_DIVISION_OF_FINITE) THEN
  REWRITE_TAC[
LAMBDA_PAIR] THEN DISCH_THEN(MP_TAC o MATCH_MP 
lemma) THEN
  ASM_SIMP_TAC[
DROP_VSUM; 
o_DEF; 
SUM_SUB; 
DROP_SUB; 
ABS_DROP] THEN
  REWRITE_TAC[
LAMBDA_PAIR_THM; 
DROP_CMUL; 
NORM_MUL; 
LIFT_DROP] THEN
  MATCH_MP_TAC(REAL_ARITH
    `!sni. i - e / &2 < sni /\
           sni' <= i /\ sni <= sni' /\ sf' = sf
              ==> abs(sf' - sni') < e / &2
                  ==> abs(sf - i) < e`) THEN
  EXISTS_TAC `
sum d (\k. 
norm (
integral k (f:real^M->real^N)))` THEN
  ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
   [MP_TAC(ISPECL [`\k. 
norm(
integral k (f:real^M->real^N))`;
                   `p':(real^M#(real^M->bool))->bool`;
                   `
interval[a:real^M,b]`] 
SUM_OVER_TAGGED_DIVISION_LEMMA) THEN
    ASM_SIMP_TAC[
INTEGRAL_NULL; 
NORM_0] THEN DISCH_THEN SUBST1_TAC THEN
    FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_MESON_TAC[
DIVISION_OF_TAGGED_DIVISION];
    ALL_TAC] THEN
  SUBGOAL_THEN
   `p' = {x:real^M,(i 
INTER l:real^M->bool) |
            (x,l) 
IN p /\ i 
IN d /\ ~(i 
INTER l = {})}`
  (LABEL_TAC "p'") THENL
   [EXPAND_TAC "p'" THEN GEN_REWRITE_TAC I [
EXTENSION] THEN
    REWRITE_TAC[
FORALL_PAIR_THM; 
IN_ELIM_PAIR_THM] THEN
    REWRITE_TAC[
IN_ELIM_THM] THEN
    MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
    REWRITE_TAC[
PAIR_EQ; GSYM 
CONJ_ASSOC] THEN
    GEN_REWRITE_TAC RAND_CONV [
SWAP_EXISTS_THM] THEN
    AP_TERM_TAC THEN GEN_REWRITE_TAC I [
FUN_EQ_THM] THEN
    X_GEN_TAC `i:real^M->bool` THEN REWRITE_TAC[] THEN
    CONV_TAC(RAND_CONV UNWIND_CONV) THEN
    AP_TERM_TAC THEN GEN_REWRITE_TAC I [
FUN_EQ_THM] THEN
    X_GEN_TAC `l:real^M->bool` THEN REWRITE_TAC[] THEN
    ASM_CASES_TAC `k:real^M->bool = i 
INTER l` THEN ASM_REWRITE_TAC[] THEN
    ASM_REWRITE_TAC[
IN_INTER; GSYM 
MEMBER_NOT_EMPTY] THEN
    EQ_TAC THENL [ASM_MESON_TAC[
TAGGED_DIVISION_OF]; ALL_TAC] THEN
    REPEAT(DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC)) THEN
    DISCH_THEN(X_CHOOSE_THEN `y:real^M` STRIP_ASSUME_TAC) THEN
    ASM_REWRITE_TAC[] THEN
    FIRST_X_ASSUM(MP_TAC o SPECL [`x:real^M`; `i:real^M->bool`]) THEN
    GEN_REWRITE_TAC LAND_CONV [GSYM CONTRAPOS_THM] THEN
    ASM_REWRITE_TAC[] THEN DISCH_THEN MATCH_MP_TAC THEN
    REWRITE_TAC[GSYM 
MEMBER_NOT_EMPTY] THEN
    EXISTS_TAC `y:real^M` THEN ASM_REWRITE_TAC[
INTER; 
IN_ELIM_THM] THEN
    UNDISCH_TAC `(\x:real^M. 
ball (x,k x)) 
fine p` THEN
    REWRITE_TAC[
fine; 
SUBSET] THEN ASM_MESON_TAC[];
    ALL_TAC] THEN
  CONJ_TAC THENL
   [MP_TAC(ISPECL
     [`\y. 
norm(
integral y (f:real^M->real^N))`;
      `p':(real^M#(real^M->bool))->bool`;
      `
interval[a:real^M,b]`]
     
SUM_OVER_TAGGED_DIVISION_LEMMA) THEN
    ASM_SIMP_TAC[
INTEGRAL_NULL; 
NORM_0] THEN DISCH_THEN SUBST1_TAC THEN
    MATCH_MP_TAC 
REAL_LE_TRANS THEN
    EXISTS_TAC `
sum {i 
INTER l | i 
IN d /\
                 (l 
IN IMAGE SND (p:(real^M#(real^M->bool))->bool))}
                    (\k. 
norm(
integral k (f:real^M->real^N)))` THEN
    CONJ_TAC THENL
     [ALL_TAC;
      MATCH_MP_TAC 
REAL_EQ_IMP_LE THEN MATCH_MP_TAC 
SUM_SUPERSET THEN
      CONJ_TAC THENL
       [REWRITE_TAC[
SUBSET; 
FORALL_IN_IMAGE] THEN
        REWRITE_TAC[
FORALL_PAIR_THM] THEN
        REWRITE_TAC[
IN_ELIM_THM; 
IN_IMAGE; 
PAIR_EQ; 
EXISTS_PAIR_THM] THEN
        MESON_TAC[];
        ALL_TAC] THEN
      REWRITE_TAC[
IN_ELIM_THM; 
LEFT_AND_EXISTS_THM; 
LEFT_IMP_EXISTS_THM] THEN
      MAP_EVERY X_GEN_TAC
       [`kk:real^M->bool`; `i:real^M->bool`; `l:real^M->bool`] THEN
      ASM_CASES_TAC `kk:real^M->bool = i 
INTER l` THEN ASM_REWRITE_TAC[] THEN
      REWRITE_TAC[
IN_IMAGE; 
EXISTS_PAIR_THM; 
UNWIND_THM1] THEN
      DISCH_THEN(CONJUNCTS_THEN2
       (CONJUNCTS_THEN2 ASSUME_TAC (X_CHOOSE_TAC `x:real^M`)) MP_TAC) THEN
      REWRITE_TAC[
IN_ELIM_THM; 
PAIR_EQ; 
NOT_EXISTS_THM] THEN
      DISCH_THEN(MP_TAC o SPECL
       [`x:real^M`; `x:real^M`; `i:real^M->bool`; `l:real^M->bool`]) THEN
      ASM_SIMP_TAC[
INTEGRAL_EMPTY; 
NORM_0]] THEN
    SUBGOAL_THEN
     `{k 
INTER l | k 
IN d /\ l 
IN IMAGE SND (p:(real^M#(real^M->bool))->bool)} =
      
IMAGE (\(k,l). k 
INTER l) {k,l | k 
IN d /\ l 
IN IMAGE SND p}`
    SUBST1_TAC THENL
     [GEN_REWRITE_TAC I [
EXTENSION] THEN
      REWRITE_TAC[
IN_ELIM_THM; 
IN_IMAGE; 
EXISTS_PAIR_THM; 
FORALL_PAIR_THM] THEN
      REWRITE_TAC[
PAIR_EQ] THEN
      CONV_TAC(REDEPTH_CONV UNWIND_CONV) THEN MESON_TAC[];
      ALL_TAC] THEN
    W(MP_TAC o PART_MATCH (lhand o rand) 
SUM_IMAGE_NONZERO o rand o snd) THEN
    ANTS_TAC THENL
     [ASSUME_TAC(MATCH_MP 
DIVISION_OF_TAGGED_DIVISION
        (ASSUME `p 
tagged_division_of interval[a:real^M,b]`)) THEN
      ASM_SIMP_TAC[
FINITE_PRODUCT; 
FINITE_IMAGE] THEN
      REWRITE_TAC[
FORALL_PAIR_THM; 
IN_ELIM_PAIR_THM] THEN
      MAP_EVERY X_GEN_TAC
       [`l1:real^M->bool`; `k1:real^M->bool`;
        `l2:real^M->bool`; `k2:real^M->bool`] THEN
      REWRITE_TAC[
PAIR_EQ] THEN STRIP_TAC THEN
      SUBGOAL_THEN `
interior(l2 
INTER k2:real^M->bool) = {}` MP_TAC THENL
       [ALL_TAC;
        MP_TAC(ASSUME `d 
division_of interval[a:real^M,b]`) THEN
        REWRITE_TAC[
division_of] THEN
        DISCH_THEN(MP_TAC o SPEC `l2:real^M->bool` o el 1 o CONJUNCTS) THEN
        ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
        MP_TAC(ASSUME
         `(
IMAGE SND (p:(real^M#(real^M->bool))->bool))
                
division_of interval[a:real^M,b]`) THEN
        REWRITE_TAC[
division_of] THEN
        DISCH_THEN(MP_TAC o SPEC `k2:real^M->bool` o el 1 o CONJUNCTS) THEN
        ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
        ASM_REWRITE_TAC[
INTER_INTERVAL] THEN DISCH_TAC THEN
        REWRITE_TAC[
NORM_EQ_0] THEN
        MATCH_MP_TAC 
INTEGRAL_NULL THEN
        ASM_REWRITE_TAC[
CONTENT_EQ_0_INTERIOR]] THEN
      MATCH_MP_TAC(SET_RULE
       `(
interior(k1) 
INTER interior(k2) = {} \/
         
interior(
l1) 
INTER interior(l2) = {}) /\
        
interior(
l1 INTER k1) 
SUBSET interior(k1) /\
        
interior(l2 
INTER k2) 
SUBSET interior(k2) /\
        
interior(
l1 INTER k1) 
SUBSET interior(
l1) /\
        
interior(l2 
INTER k2) 
SUBSET interior(l2) /\
        
interior(
l1 INTER k1) = 
interior(l2 
INTER k2)
        ==> 
interior(l2 
INTER k2) = {}`) THEN
      SIMP_TAC[
SUBSET_INTERIOR; 
INTER_SUBSET] THEN ASM_REWRITE_TAC[] THEN
      MP_TAC(ASSUME `d 
division_of interval[a:real^M,b]`) THEN
      REWRITE_TAC[
division_of] THEN DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
      DISCH_THEN(MP_TAC o SPECL [`l1:real^M->bool`; `l2:real^M->bool`]) THEN
      ASM_REWRITE_TAC[] THEN
      MP_TAC(ASSUME
       `(
IMAGE SND (p:(real^M#(real^M->bool))->bool))
              
division_of interval[a:real^M,b]`) THEN
      REWRITE_TAC[
division_of] THEN DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
      DISCH_THEN(MP_TAC o SPECL [`k1:real^M->bool`; `k2:real^M->bool`]) THEN
      ASM_REWRITE_TAC[] THEN ASM_MESON_TAC[];
      ALL_TAC] THEN
    DISCH_THEN SUBST1_TAC THEN
    GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM ETA_AX] THEN
    GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [
LAMBDA_PAIR_THM] THEN
    ASM_SIMP_TAC[GSYM 
SUM_SUM_PRODUCT; 
FINITE_IMAGE] THEN
    MATCH_MP_TAC 
SUM_LE THEN ASM_REWRITE_TAC[] THEN
    X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN REWRITE_TAC[
o_DEF] THEN
    MATCH_MP_TAC 
REAL_LE_TRANS THEN
    EXISTS_TAC
     `
sum { k 
INTER l |
             l 
IN IMAGE SND (p:(real^M#(real^M->bool))->bool)}
          (\k. 
norm(
integral k (f:real^M->real^N)))` THEN
    CONJ_TAC THENL
     [ALL_TAC;
      ONCE_REWRITE_TAC[
SIMPLE_IMAGE] THEN
      W(MP_TAC o PART_MATCH (lhs o rand) 
SUM_IMAGE_NONZERO o lhand o snd) THEN
      ANTS_TAC THENL [ALL_TAC; SIMP_TAC[
o_DEF; 
REAL_LE_REFL]] THEN
      ASM_SIMP_TAC[
FINITE_IMAGE] THEN
      MAP_EVERY X_GEN_TAC [`k1:real^M->bool`; `k2:real^M->bool`] THEN
      STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
      SUBGOAL_THEN `
interior(k 
INTER k2:real^M->bool) = {}` MP_TAC THENL
       [ALL_TAC;
        MP_TAC(MATCH_MP 
DIVISION_OF_TAGGED_DIVISION
         (ASSUME `p 
tagged_division_of interval[a:real^M,b]`)) THEN
        MP_TAC(ASSUME `d 
division_of interval[a:real^M,b]`) THEN
        REWRITE_TAC[
division_of] THEN
        DISCH_THEN(MP_TAC o SPEC `k:real^M->bool` o el 1 o CONJUNCTS) THEN
        ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
        DISCH_THEN(MP_TAC o SPEC `k2:real^M->bool` o el 1 o CONJUNCTS) THEN
        ASM_REWRITE_TAC[
INTER_INTERVAL; GSYM 
CONTENT_EQ_0_INTERIOR] THEN
        STRIP_TAC THEN ASM_REWRITE_TAC[
INTER_INTERVAL] THEN
        SIMP_TAC[GSYM 
CONTENT_EQ_0_INTERIOR; 
INTEGRAL_NULL; 
NORM_0]] THEN
      MATCH_MP_TAC(SET_RULE
       `
interior(k 
INTER k2) 
SUBSET interior(k1 
INTER k2) /\
        
interior(k1 
INTER k2) = {}
        ==> 
interior(k 
INTER k2) = {}`) THEN
      CONJ_TAC THENL
       [MATCH_MP_TAC 
SUBSET_INTERIOR THEN ASM SET_TAC[]; ALL_TAC] THEN
      MP_TAC(MATCH_MP 
DIVISION_OF_TAGGED_DIVISION
         (ASSUME `p 
tagged_division_of interval[a:real^M,b]`)) THEN
      REWRITE_TAC[
division_of] THEN
      DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
      REWRITE_TAC[
INTERIOR_INTER] THEN DISCH_THEN MATCH_MP_TAC THEN
      ASM_REWRITE_TAC[]] THEN
    SUBGOAL_THEN `?u v:real^M. k = 
interval[u,v]`
     (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
    THENL [ASM_MESON_TAC[
division_of]; ALL_TAC] THEN
    SUBGOAL_THEN `
interval[u:real^M,v] 
SUBSET interval[a,b]` ASSUME_TAC THENL
     [ASM_MESON_TAC[
division_of]; ALL_TAC] THEN
    ABBREV_TAC `d' =
        {
interval[u,v] 
INTER l |l|
                l 
IN IMAGE SND (p:(real^M#(real^M->bool))->bool) /\
                ~(
interval[u,v] 
INTER l = {})}` THEN
    MATCH_MP_TAC 
REAL_LE_TRANS THEN
    EXISTS_TAC
     `
sum d' (\k. 
norm (
integral k (f:real^M->real^N)))` THEN
    CONJ_TAC THENL
     [ALL_TAC;
      MATCH_MP_TAC 
REAL_EQ_IMP_LE THEN CONV_TAC SYM_CONV THEN
      MATCH_MP_TAC 
SUM_SUPERSET THEN
      EXPAND_TAC "d'" THEN REWRITE_TAC[
SUBSET; SET_RULE
       `a 
IN {f x |x| x 
IN s /\ ~(f x = b)} <=>
        a 
IN {f x | x 
IN s} /\ ~(a = b)`] THEN
      SIMP_TAC[
IMP_CONJ; 
INTEGRAL_EMPTY; 
NORM_0]] THEN
    SUBGOAL_THEN `d' 
division_of interval[u:real^M,v]` ASSUME_TAC THENL
     [EXPAND_TAC "d'" THEN MATCH_MP_TAC 
DIVISION_INTER_1 THEN
      EXISTS_TAC `
interval[a:real^M,b]` THEN
      ASM_SIMP_TAC[
DIVISION_OF_TAGGED_DIVISION];
      ALL_TAC] THEN
    MATCH_MP_TAC 
REAL_LE_TRANS THEN
    EXISTS_TAC `
norm(
vsum d' (\i. 
integral i (f:real^M->real^N)))` THEN
    CONJ_TAC THENL
     [MATCH_MP_TAC 
REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
      MATCH_MP_TAC 
INTEGRAL_COMBINE_DIVISION_TOPDOWN THEN
      ASM_MESON_TAC[
INTEGRABLE_ON_SUBINTERVAL];
      ALL_TAC] THEN
    MATCH_MP_TAC 
VSUM_NORM_LE THEN
    REWRITE_TAC[
REAL_LE_REFL] THEN ASM_MESON_TAC[
division_of];
    ALL_TAC] THEN
  REMOVE_THEN "p'" SUBST_ALL_TAC THEN
  MATCH_MP_TAC 
EQ_TRANS THEN
  EXISTS_TAC `
sum {x,i 
INTER l | (x,l) 
IN p /\ i 
IN d}
                  (\(x,k:real^M->bool).
                      abs(
content k) * 
norm((f:real^M->real^N) x))` THEN
  CONJ_TAC THENL
   [CONV_TAC SYM_CONV THEN MATCH_MP_TAC 
SUM_SUPERSET THEN
    CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
    REWRITE_TAC[
FORALL_PAIR_THM] THEN
    MAP_EVERY X_GEN_TAC [`x:real^M`; `i:real^M->bool`] THEN
    ASM_CASES_TAC `i:real^M->bool = {}` THEN
    ASM_SIMP_TAC[
CONTENT_EMPTY; 
REAL_ABS_NUM; 
REAL_MUL_LZERO] THEN
    MATCH_MP_TAC(TAUT `(a <=> b) ==> a /\ ~b ==> c`) THEN
    REWRITE_TAC[
IN_ELIM_THM] THEN
    REPEAT(AP_TERM_TAC THEN ABS_TAC) THEN
    REWRITE_TAC[
PAIR_EQ] THEN ASM_MESON_TAC[];
    ALL_TAC] THEN
  SUBGOAL_THEN
   `{x,i 
INTER l | x,l 
IN (p:(real^M#(real^M->bool))->bool) /\ i 
IN d} =
    
IMAGE (\((x,l),k). x,k 
INTER l) {m,k | m 
IN p /\ k 
IN d}`
  SUBST1_TAC THENL
   [GEN_REWRITE_TAC I [
EXTENSION] THEN
    REWRITE_TAC[
IN_ELIM_THM; 
IN_IMAGE; 
EXISTS_PAIR_THM; 
FORALL_PAIR_THM] THEN
    REWRITE_TAC[
PAIR_EQ] THEN
    CONV_TAC(REDEPTH_CONV UNWIND_CONV) THEN MESON_TAC[];
    ALL_TAC] THEN
  W(MP_TAC o PART_MATCH (lhand o rand) 
SUM_IMAGE_NONZERO o lhand o snd) THEN
  ANTS_TAC THENL
   [ASM_SIMP_TAC[
FINITE_PRODUCT] THEN
    REWRITE_TAC[
FORALL_PAIR_THM; 
IN_ELIM_PAIR_THM] THEN
    MAP_EVERY X_GEN_TAC
     [`x1:real^M`; `l1:real^M->bool`; `k1:real^M->bool`;
      `x2:real^M`; `l2:real^M->bool`; `k2:real^M->bool`] THEN
    REWRITE_TAC[
PAIR_EQ] THEN
    ASM_CASES_TAC `x1:real^M = x2` THEN ASM_REWRITE_TAC[] THEN
    STRIP_TAC THEN
    REWRITE_TAC[
REAL_ENTIRE] THEN DISJ1_TAC THEN
    REWRITE_TAC[
REAL_ABS_ZERO] THEN
    SUBGOAL_THEN `
interior(k2 
INTER l2:real^M->bool) = {}` MP_TAC THENL
     [ALL_TAC;
      FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
division_of]) THEN
      DISCH_THEN(MP_TAC o SPEC `k2:real^M->bool` o el 1 o CONJUNCTS) THEN
      ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
      MP_TAC(ASSUME `p 
tagged_division_of interval[a:real^M,b]`) THEN
      REWRITE_TAC[
TAGGED_DIVISION_OF] THEN
      DISCH_THEN(MP_TAC o el 1 o CONJUNCTS) THEN
      DISCH_THEN(MP_TAC o SPECL [`x2:real^M`; `l2:real^M->bool`]) THEN
      ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
      ASM_REWRITE_TAC[
INTER_INTERVAL; 
CONTENT_EQ_0_INTERIOR]] THEN
    MATCH_MP_TAC(SET_RULE
     `(
interior(k1) 
INTER interior(k2) = {} \/
       
interior(
l1) 
INTER interior(l2) = {}) /\
      
interior(k1 
INTER l1) 
SUBSET interior(k1) /\
      
interior(k2 
INTER l2) 
SUBSET interior(k2) /\
      
interior(k1 
INTER l1) 
SUBSET interior(
l1) /\
      
interior(k2 
INTER l2) 
SUBSET interior(l2) /\
      
interior(k1 
INTER l1) = 
interior(k2 
INTER l2)
      ==> 
interior(k2 
INTER l2) = {}`) THEN
    SIMP_TAC[
SUBSET_INTERIOR; 
INTER_SUBSET] THEN ASM_REWRITE_TAC[] THEN
    FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
division_of]) THEN
    DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
    DISCH_THEN(MP_TAC o SPECL [`k1:real^M->bool`; `k2:real^M->bool`]) THEN
    MP_TAC(ASSUME `p 
tagged_division_of interval[a:real^M,b]`) THEN
    REWRITE_TAC[
TAGGED_DIVISION_OF] THEN
    DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
    DISCH_THEN(MP_TAC o SPECL
     [`x2:real^M`; `l1:real^M->bool`; `x2:real^M`; `l2:real^M->bool`]) THEN
    ASM_REWRITE_TAC[
PAIR_EQ] THEN ASM_MESON_TAC[];
    ALL_TAC] THEN
  DISCH_THEN SUBST1_TAC THEN
  GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [GSYM ETA_AX] THEN
  GEN_REWRITE_TAC (LAND_CONV o RAND_CONV) [
LAMBDA_PAIR_THM] THEN
  ASM_SIMP_TAC[GSYM 
SUM_SUM_PRODUCT] THEN
  MATCH_MP_TAC 
SUM_EQ THEN REWRITE_TAC[
FORALL_PAIR_THM] THEN
  MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
  DISCH_TAC THEN REWRITE_TAC[
o_THM; 
SUM_RMUL] THEN
  AP_THM_TAC THEN AP_TERM_TAC THEN
  SUBGOAL_THEN `?u v:real^M. l = 
interval[u,v]`
   (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
  THENL [ASM_MESON_TAC[
TAGGED_DIVISION_OF]; ALL_TAC] THEN
  MATCH_MP_TAC 
EQ_TRANS THEN
  EXISTS_TAC `
sum d (\k. 
content(k 
INTER interval[u:real^M,v]))` THEN
  CONJ_TAC THENL
   [MATCH_MP_TAC 
SUM_EQ THEN REWRITE_TAC[
real_abs] THEN
    X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
    SUBGOAL_THEN `?w z:real^M. k = 
interval[w,z]`
      (REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC)
    THENL [ASM_MESON_TAC[
division_of]; ALL_TAC] THEN
    REWRITE_TAC[
INTER_INTERVAL; 
CONTENT_POS_LE];
    ALL_TAC] THEN
  MATCH_MP_TAC 
EQ_TRANS THEN
  EXISTS_TAC `
sum {k 
INTER interval[u:real^M,v] | k 
IN d} 
content` THEN
  CONJ_TAC THENL
   [ONCE_REWRITE_TAC[
SIMPLE_IMAGE] THEN ONCE_REWRITE_TAC[GSYM 
o_DEF] THEN
    CONV_TAC SYM_CONV THEN MATCH_MP_TAC 
SUM_IMAGE_NONZERO THEN
    ASM_REWRITE_TAC[] THEN
    MAP_EVERY X_GEN_TAC [`k1:real^M->bool`; `k2:real^M->bool`] THEN
    STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
    SUBGOAL_THEN `
interior(k2 
INTER interval[u:real^M,v]) = {}` MP_TAC THENL
     [ALL_TAC;
      FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
division_of]) THEN
      DISCH_THEN(MP_TAC o SPEC `k2:real^M->bool` o el 1 o CONJUNCTS) THEN
      ASM_REWRITE_TAC[] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
      ASM_REWRITE_TAC[
INTER_INTERVAL; 
CONTENT_EQ_0_INTERIOR]] THEN
    MATCH_MP_TAC(SET_RULE
     `
interior(k2 
INTER i) 
SUBSET interior(k1 
INTER k2) /\
      
interior(k1 
INTER k2) = {}
      ==> 
interior(k2 
INTER i) = {}`) THEN
    CONJ_TAC THENL
     [MATCH_MP_TAC 
SUBSET_INTERIOR THEN ASM SET_TAC[]; ALL_TAC] THEN
    FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
division_of]) THEN
    DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN
    REWRITE_TAC[
INTERIOR_INTER] THEN DISCH_THEN MATCH_MP_TAC THEN
    ASM_REWRITE_TAC[];
    ALL_TAC] THEN
  SUBGOAL_THEN `
interval[u:real^M,v] 
SUBSET interval[a,b]` ASSUME_TAC THENL
   [ASM_MESON_TAC[
TAGGED_DIVISION_OF]; ALL_TAC] THEN
  MATCH_MP_TAC 
EQ_TRANS THEN
  EXISTS_TAC `
sum {k 
INTER interval[u:real^M,v] |k|
                      k 
IN d /\ ~(k 
INTER interval[u,v] = {})} 
content` THEN
  CONJ_TAC THENL
   [MATCH_MP_TAC 
SUM_SUPERSET THEN
    REWRITE_TAC[
SUBSET; SET_RULE
     `a 
IN {f x |x| x 
IN s /\ ~(f x = b)} <=>
      a 
IN {f x | x 
IN s} /\ ~(a = b)`] THEN
    SIMP_TAC[
IMP_CONJ; 
CONTENT_EMPTY];
    ALL_TAC] THEN
  MATCH_MP_TAC 
ADDITIVE_CONTENT_DIVISION THEN
  ONCE_REWRITE_TAC[
INTER_COMM] THEN MATCH_MP_TAC 
DIVISION_INTER_1 THEN
  EXISTS_TAC `
interval[a:real^M,b]` THEN ASM_REWRITE_TAC[]);;
 
let FUNDAMENTAL_THEOREM_OF_CALCULUS_STRONG = prove
 (`!f:real^1->real^N f' s a b.
        
COUNTABLE s /\
        
drop a <= 
drop b /\ f 
continuous_on interval[a,b] /\
        (!x. x 
IN interval[a,b] 
DIFF s
             ==> (f 
has_vector_derivative f'(x)) (
at x 
within interval[a,b]))
        ==> (f' 
has_integral (f(b) - f(a))) (
interval[a,b])`,
  REPEAT STRIP_TAC THEN
  MATCH_MP_TAC 
HAS_INTEGRAL_SPIKE THEN
  EXISTS_TAC `(\x. if x 
IN s then 
vec 0 else f' x):real^1->real^N` THEN
  EXISTS_TAC `s:real^1->bool` THEN
  ASM_SIMP_TAC[
NEGLIGIBLE_COUNTABLE; 
IN_DIFF] THEN
  SUBGOAL_THEN
   `?f t. s = 
IMAGE (f:num->real^1) t /\
          (!m n. m 
IN t /\ n 
IN t /\ f m = f n ==> m = n)`
  MP_TAC THENL
   [ASM_CASES_TAC `FINITE(s:real^1->bool)` THENL
     [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
FINITE_INDEX_NUMSEG]) THEN
      ASM_MESON_TAC[];
      MP_TAC(ISPEC `s:real^1->bool` 
COUNTABLE_AS_INJECTIVE_IMAGE) THEN
      ASM_REWRITE_TAC[
INFINITE] THEN MESON_TAC[
IN_UNIV]];
    REWRITE_TAC[
LEFT_IMP_EXISTS_THM; 
INJECTIVE_ON_LEFT_INVERSE] THEN
    MAP_EVERY X_GEN_TAC [`r:num->real^1`; `t:num->bool`] THEN
    DISCH_THEN(CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC) THEN
    DISCH_THEN(X_CHOOSE_TAC `n:real^1->num`)] THEN
  REWRITE_TAC[
HAS_INTEGRAL_FACTOR_CONTENT] THEN
  X_GEN_TAC `e:real` THEN DISCH_TAC THEN
  SUBGOAL_THEN
   `!x. ?d. &0 < d /\
            (x 
IN interval[a,b]
             ==> (x 
IN IMAGE (r:num->real^1) t
                  ==> !y. 
norm(y - x) < d /\ y 
IN interval[a,b]
                          ==> 
norm(f y - f x)
                              <= e / &2 pow (4 + n x) * 
norm(b - a)) /\
                 (~(x 
IN IMAGE r t)
                  ==> !y. 
norm(y - x) < d /\ y 
IN interval[a,b]
                          ==> 
norm(f y - f x - 
drop(y - x) % f' x:real^N)
                                <= e / &2 * 
norm(y - x)))`
  MP_TAC THENL
   [X_GEN_TAC `x:real^1` THEN
    ASM_CASES_TAC `(x:real^1) 
IN interval[a,b]` THENL
     [ALL_TAC; EXISTS_TAC `&1` THEN ASM_REWRITE_TAC[
REAL_LT_01]] THEN
    ASM_CASES_TAC `x 
IN IMAGE (r:num->real^1) t` THEN ASM_REWRITE_TAC[] THENL
     [FIRST_ASSUM(MP_TAC o MATCH_MP (REAL_ARITH
       `a <= b ==> a = b \/ a < b`)) THEN
      REWRITE_TAC[
DROP_EQ] THEN STRIP_TAC THENL
       [EXISTS_TAC `&1` THEN REWRITE_TAC[
REAL_LT_01] THEN
        UNDISCH_TAC `(x:real^1) 
IN interval[a,b]` THEN
        ASM_SIMP_TAC[
INTERVAL_SING; 
IN_SING; 
VECTOR_SUB_REFL; 
NORM_0] THEN
        REAL_ARITH_TAC;
        FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
continuous_on]) THEN
        DISCH_THEN(MP_TAC o SPEC `x:real^1`) THEN ASM_REWRITE_TAC[
dist] THEN
        DISCH_THEN(MP_TAC o SPEC
         `e / &2 pow (4 + n(x:real^1)) * 
norm(b - a:real^1)`) THEN
        ASM_SIMP_TAC[
REAL_LT_DIV; 
REAL_LT_MUL; 
NORM_POS_LT; 
VECTOR_SUB_EQ;
                     
REAL_LT_POW2; GSYM 
DROP_EQ; 
REAL_LT_IMP_NE] THEN
        MESON_TAC[
REAL_LT_IMP_LE]];
      FIRST_X_ASSUM(MP_TAC o SPEC `x:real^1`) THEN
      ASM_REWRITE_TAC[
IN_DIFF; 
has_vector_derivative;
                      
HAS_DERIVATIVE_WITHIN_ALT] THEN
      DISCH_THEN(MP_TAC o SPEC `e / &2` o CONJUNCT2) THEN
      ASM_REWRITE_TAC[
REAL_HALF] THEN MESON_TAC[]];
    GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [
RIGHT_IMP_EXISTS_THM] THEN
    REWRITE_TAC[
SKOLEM_THM; 
LEFT_IMP_EXISTS_THM; 
FORALL_AND_THM; IMP_IMP;
                TAUT `p ==> q /\ r <=> (p ==> q) /\ (p ==> r)`] THEN
    X_GEN_TAC `d:real^1->
real` THEN
    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN
    DISCH_THEN(CONJUNCTS_THEN2 (LABEL_TAC "E") (LABEL_TAC "U"))] THEN
  EXISTS_TAC `\x. 
ball(x:real^1,d(x))` THEN
  ASM_SIMP_TAC[
GAUGE_BALL_DEPENDENT] THEN
  X_GEN_TAC `p:(real^1#(real^1->bool))->bool` THEN STRIP_TAC THEN
  MP_TAC(ISPECL [`f:real^1->real^N`; `p:(real^1#(real^1->bool))->bool`;
                 `a:real^1`; `b:real^1`]
                
ADDITIVE_TAGGED_DIVISION_1) THEN
  ASM_SIMP_TAC[
CONTENT_1] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
  FIRST_ASSUM(ASSUME_TAC o MATCH_MP 
TAGGED_DIVISION_OF_FINITE) THEN
  ASM_SIMP_TAC[GSYM 
VSUM_SUB; 
LAMBDA_PAIR_THM] THEN
  SUBGOAL_THEN
   `p:(real^1#(real^1->bool))->bool =
    {(x,k) | (x,k) 
IN p /\ x 
IN IMAGE r (t:num->bool)} 
UNION
    {(x,k) | (x,k) 
IN p /\ ~(x 
IN IMAGE r (t:num->bool))}`
  SUBST1_TAC THENL
   [REWRITE_TAC[
EXTENSION; 
FORALL_PAIR_THM; 
IN_ELIM_PAIR_THM; 
IN_UNION] THEN
    MESON_TAC[];
    ALL_TAC] THEN
  W(MP_TAC o PART_MATCH (lhs o rand) 
VSUM_UNION o rand o lhand o snd) THEN
  ANTS_TAC THENL
   [REWRITE_TAC[SET_RULE `
DISJOINT s t <=> !x. x 
IN s ==> ~(x 
IN t)`] THEN
    SIMP_TAC[
FORALL_IN_GSPEC; 
IN_ELIM_PAIR_THM] THEN CONJ_TAC THEN
    MATCH_MP_TAC 
FINITE_SUBSET THEN
    EXISTS_TAC `p:(real^1#(real^1->bool))->bool` THEN
    ASM_SIMP_TAC[
SUBSET; 
FORALL_IN_GSPEC; 
IN_ELIM_PAIR_THM];
    DISCH_THEN SUBST1_TAC] THEN
  SUBGOAL_THEN
   `(!P. FINITE {(x:real^1,k:real^1->bool) | (x,k) 
IN p /\ P x k}) /\
    (!P x. FINITE {(x:real^1,k:real^1->bool) |k| (x,k) 
IN p /\ P x k})`
  STRIP_ASSUME_TAC THENL
   [REPEAT STRIP_TAC THEN MATCH_MP_TAC 
FINITE_SUBSET THEN
    EXISTS_TAC `p:real^1#(real^1->bool)->bool` THEN
    ASM_SIMP_TAC[
SUBSET; 
FORALL_IN_GSPEC];
    ALL_TAC] THEN
  MATCH_MP_TAC(NORM_ARITH
   `
norm(x:real^N) <= e / &2 * a /\ 
norm(y) <= e / &2 * a
    ==> 
norm(x + y) <= e * a`) THEN
  CONJ_TAC THENL
   [MATCH_MP_TAC 
REAL_LE_TRANS THEN EXISTS_TAC
     `
norm(
vsum {(x,k) | (x,k) 
IN p /\ x 
IN IMAGE (r:num->real^1) t /\
                         ~(
content k = &0)}
                (\(x,k). --(f(
interval_upperbound k) -
                            (f:real^1->real^N)(
interval_lowerbound k))))` THEN
    CONJ_TAC THENL
     [MATCH_MP_TAC 
REAL_EQ_IMP_LE THEN AP_TERM_TAC THEN
      MATCH_MP_TAC 
VSUM_EQ_SUPERSET THEN
      ASM_REWRITE_TAC[
FORALL_IN_GSPEC; 
IMP_CONJ] THEN
      CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
      SIMP_TAC[VECTOR_ARITH `a % 
vec 0 - x:real^N = --x`] THEN
      REWRITE_TAC[
IN_ELIM_PAIR_THM] THEN
      MAP_EVERY X_GEN_TAC [`x:real^1`; `k:real^1->bool`] THEN DISCH_TAC THEN
      SUBGOAL_THEN `?u v:real^1. k = 
interval[u,v] /\ x 
IN interval[u,v]`
      STRIP_ASSUME_TAC THENL
       [ASM_MESON_TAC[
TAGGED_DIVISION_OF]; ALL_TAC] THEN
      ASM_REWRITE_TAC[
CONTENT_EQ_0_1] THEN
      FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
IN_INTERVAL_1]) THEN
      DISCH_THEN(MP_TAC o MATCH_MP 
REAL_LE_TRANS) THEN
      SIMP_TAC[
INTERVAL_LOWERBOUND_1; 
INTERVAL_UPPERBOUND_1;
               
INTERVAL_EQ_EMPTY; 
REAL_NOT_LE; 
REAL_NOT_LT] THEN
      REPEAT STRIP_TAC THEN MATCH_MP_TAC(VECTOR_ARITH
       `x:real^N = y ==> --(x - y) = 
vec 0`) THEN
      AP_TERM_TAC THEN ASM_REWRITE_TAC[GSYM 
DROP_EQ; GSYM REAL_LE_ANTISYM];
      ALL_TAC] THEN
    MATCH_MP_TAC 
REAL_LE_TRANS THEN EXISTS_TAC
     `
sum {(x,k:real^1->bool) | (x,k) 
IN p /\ x 
IN IMAGE (r:num->real^1) t /\
                                ~(
content k = &0)}
          ((\(x,k). e / &2 pow (3 + n x) * 
norm (b - a:real^1)))` THEN
    CONJ_TAC THENL
     [MATCH_MP_TAC 
VSUM_NORM_LE THEN
      ASM_REWRITE_TAC[
FORALL_IN_GSPEC; 
IMP_CONJ] THEN
      MAP_EVERY X_GEN_TAC [`x:real^1`; `k:real^1->bool`] THEN DISCH_TAC THEN
      SUBGOAL_THEN `?u v:real^1. k = 
interval[u,v] /\ x 
IN interval[u,v]`
      MP_TAC THENL [ASM_MESON_TAC[
TAGGED_DIVISION_OF]; ALL_TAC] THEN
      DISCH_THEN(REPEAT_TCL CHOOSE_THEN
        (CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC)) THEN
      SIMP_TAC[
CONTENT_EQ_0_1; 
REAL_NOT_LE; 
REAL_LT_IMP_LE; 
IN_INTERVAL_1;
               
INTERVAL_LOWERBOUND_1; 
INTERVAL_UPPERBOUND_1] THEN
      REPEAT STRIP_TAC THEN
      REMOVE_THEN "E" (MP_TAC o SPEC `x:real^1`) THEN ANTS_TAC THENL
       [ASM_MESON_TAC[
TAGGED_DIVISION_OF; 
SUBSET]; ALL_TAC] THEN
      DISCH_THEN(fun 
th ->
        MP_TAC(ISPEC `u:real^1` 
th) THEN MP_TAC(ISPEC `v:real^1` 
th)) THEN
      FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
fine]) THEN
      DISCH_THEN(MP_TAC o SPECL [`x:real^1`; `
interval[u:real^1,v]`]) THEN
      ASM_REWRITE_TAC[
SUBSET; 
IN_BALL] THEN
      DISCH_THEN(fun 
th ->
        MP_TAC(ISPEC `u:real^1` 
th) THEN MP_TAC(ISPEC `v:real^1` 
th)) THEN
      ASM_REWRITE_TAC[
dist; 
ENDS_IN_INTERVAL; 
INTERVAL_NE_EMPTY_1] THEN
      ASM_SIMP_TAC[
REAL_LT_IMP_LE; 
NORM_SUB] THEN DISCH_TAC THEN DISCH_TAC THEN
      SUBGOAL_THEN `
interval[u:real^1,v] 
SUBSET interval[a,b]` ASSUME_TAC THENL
       [ASM_MESON_TAC[
TAGGED_DIVISION_OF]; ALL_TAC] THEN
      REPEAT(ANTS_TAC THENL
       [ASM_MESON_TAC[
ENDS_IN_INTERVAL; 
SUBSET; 
INTERVAL_NE_EMPTY_1;
                      
REAL_LT_IMP_LE];
        ONCE_REWRITE_TAC[TAUT `p ==> q ==> r <=> q ==> p ==> r`]]) THEN
      REWRITE_TAC[
REAL_POW_ADD; 
real_div; 
REAL_INV_MUL] THEN NORM_ARITH_TAC;
      ALL_TAC] THEN
    MP_TAC(ISPECL
     [`FST:real^1#(real^1->bool)->real^1`;
      `\(x:real^1,k:real^1->bool). e / &2 pow (3 + n x) * 
norm (b - a:real^1)`;
      `{(x,k:real^1->bool) | (x,k) 
IN p /\ x 
IN IMAGE (r:num->real^1) t /\
                                ~(
content k = &0)}`;
      `
IMAGE (r:num->real^1) t`
     ] 
SUM_GROUP) THEN
    ANTS_TAC THENL
     [ASM_REWRITE_TAC[] THEN
      SIMP_TAC[
SUBSET; 
FORALL_IN_IMAGE; 
FORALL_IN_GSPEC];
      DISCH_THEN(SUBST1_TAC o SYM)] THEN
    MATCH_MP_TAC 
REAL_LE_TRANS THEN EXISTS_TAC
     `
sum (
IMAGE (r:num->real^1) t)
          (\x. 
sum {(x,k:real^1->bool) |k|
                    (x,k) 
IN p /\ ~(
content k = &0)}
                   (\yk. e / &2 pow (3 + n x) * 
norm(b - a:real^1)))` THEN
    CONJ_TAC THENL
     [MATCH_MP_TAC 
REAL_EQ_IMP_LE THEN MATCH_MP_TAC 
SUM_EQ THEN
      X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN REWRITE_TAC[] THEN
      MATCH_MP_TAC 
SUM_EQ_SUPERSET THEN
      ASM_REWRITE_TAC[
SUBSET; 
FORALL_IN_GSPEC; 
IMP_CONJ] THEN
      REWRITE_TAC[
IN_ELIM_THM; 
PAIR_EQ] THEN ASM_MESON_TAC[];
      ALL_TAC] THEN
    ASM_SIMP_TAC[
SUM_CONST] THEN
    REWRITE_TAC[
SUM_RMUL; 
NORM_1; 
DROP_SUB; REAL_MUL_ASSOC] THEN
    ASM_REWRITE_TAC[
real_abs; 
REAL_SUB_LE] THEN MATCH_MP_TAC 
REAL_LE_RMUL THEN
    ASM_REWRITE_TAC[
REAL_SUB_LE; 
REAL_POW_ADD; 
real_div; 
REAL_INV_MUL] THEN
    ONCE_REWRITE_TAC[REAL_ARITH
     `p * e * inv(&2 pow 3) * n = e / &8 * (p * n)`] THEN
    ASM_SIMP_TAC[
REAL_LE_LMUL_EQ; 
SUM_LMUL; REAL_ARITH
     `e / &8 * x <= e * inv(&2) <=> e * x <= e * &4`] THEN
    MATCH_MP_TAC 
REAL_LE_TRANS THEN EXISTS_TAC
     `
sum (
IMAGE (r:num->real^1) t 
INTER
           IMAGE (FST:real^1#(real^1->bool)->real^1) p)
          (\x. &(
CARD {(x,k:real^1->bool) | k |
                      (x,k) 
IN p /\ ~(
content k = &0)}) *
               inv(&2 pow n x))` THEN
    CONJ_TAC THENL
     [MATCH_MP_TAC 
REAL_EQ_IMP_LE THEN MATCH_MP_TAC 
SUM_SUPERSET THEN
      REWRITE_TAC[
INTER_SUBSET; 
IMP_CONJ; 
FORALL_IN_IMAGE] THEN
      SIMP_TAC[
IN_INTER; 
FUN_IN_IMAGE] THEN
      REWRITE_TAC[
IN_IMAGE; 
EXISTS_PAIR_THM] THEN
      REPEAT STRIP_TAC THEN REWRITE_TAC[
REAL_ENTIRE] THEN
      DISJ1_TAC THEN AP_TERM_TAC THEN
      MATCH_MP_TAC(MESON[
CARD_CLAUSES] `s = {} ==> 
CARD s = 0`) THEN
      ASM SET_TAC[];
      ALL_TAC] THEN
    MATCH_MP_TAC 
REAL_LE_TRANS THEN EXISTS_TAC
     `
sum (
IMAGE (r:num->real^1) t 
INTER
           IMAGE (FST:real^1#(real^1->bool)->real^1) p)
          (\x. &2 / &2 pow (n x))` THEN
    CONJ_TAC THENL
     [MATCH_MP_TAC 
SUM_LE THEN
      ASM_SIMP_TAC[
FINITE_IMAGE; 
FINITE_INTER] THEN
      GEN_TAC THEN DISCH_TAC THEN REWRITE_TAC[
real_div] THEN
      MATCH_MP_TAC 
REAL_LE_RMUL THEN
      SIMP_TAC[
REAL_LE_INV_EQ; 
REAL_POW_LE; 
REAL_POS; REAL_OF_NUM_LE] THEN
      GEN_REWRITE_TAC RAND_CONV [ARITH_RULE `2 = 2 
EXP 1`] THEN
      GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [GSYM DIMINDEX_1] THEN
      MATCH_MP_TAC 
TAGGED_PARTIAL_DIVISION_COMMON_TAGS THEN
      ASM_MESON_TAC[
tagged_division_of];
      ALL_TAC] THEN
    REWRITE_TAC[
real_div; 
SUM_LMUL; REAL_ARITH `&2 * x <= &4 <=> x <= &2`;
                
REAL_INV_POW] THEN
    SUBGOAL_THEN
     `(\x:real^1. inv (&2) pow n x) = (\n. inv(&2) pow n) o n`
    SUBST1_TAC THENL [REWRITE_TAC[
o_DEF]; ALL_TAC] THEN
    W(MP_TAC o PART_MATCH (rand o rand) 
SUM_IMAGE o lhand o snd) THEN
    ANTS_TAC THENL [ASM SET_TAC[]; DISCH_THEN(SUBST1_TAC o SYM)] THEN
    SUBGOAL_THEN
     `?m. 
IMAGE (n:real^1->num)
                (
IMAGE (r:num->real^1) t 
INTER
                IMAGE (FST:real^1#(real^1->bool)->real^1) p) 
SUBSET 0..m`
    STRIP_ASSUME_TAC THENL
     [REWRITE_TAC[
SUBSET; 
IN_NUMSEG; 
LE_0] THEN
      MATCH_MP_TAC 
UPPER_BOUND_FINITE_SET THEN
      ASM_SIMP_TAC[
FINITE_IMAGE; 
FINITE_INTER];
      ALL_TAC] THEN
    MATCH_MP_TAC 
REAL_LE_TRANS THEN
    EXISTS_TAC `
sum(0..m) (\n. inv(&2) pow n)` THEN CONJ_TAC THENL
     [MATCH_MP_TAC 
SUM_SUBSET THEN
      ASM_SIMP_TAC[
FINITE_IMAGE; 
FINITE_INTER; 
FINITE_NUMSEG] THEN
      SIMP_TAC[
REAL_LE_INV_EQ; 
REAL_POW_LE; 
REAL_POS] THEN ASM SET_TAC[];
      REWRITE_TAC[
SUM_GP; 
LT; 
SUB_0] THEN
      CONV_TAC REAL_RAT_REDUCE_CONV THEN
      REWRITE_TAC[REAL_ARITH `(&1 - x) / (&1 / &2) <= &2 <=> &0 <= x`] THEN
      MATCH_MP_TAC 
REAL_POW_LE THEN CONV_TAC REAL_RAT_REDUCE_CONV];
    MP_TAC(ISPECL [`\x:real^1. x`; `p:(real^1#(real^1->bool))->bool`;
                   `a:real^1`; `b:real^1`]
                  
ADDITIVE_TAGGED_DIVISION_1) THEN
    ASM_SIMP_TAC[] THEN DISCH_THEN(MP_TAC o AP_TERM `
drop`) THEN
    ASM_SIMP_TAC[
DROP_VSUM; 
DROP_SUB] THEN DISCH_THEN(SUBST1_TAC o SYM) THEN
    REWRITE_TAC[GSYM 
SUM_LMUL] THEN MATCH_MP_TAC 
REAL_LE_TRANS THEN
    EXISTS_TAC
     `
sum {(x:real^1,k:real^1->bool) |
           (x,k) 
IN p /\ ~(x 
IN IMAGE r (t:num->bool))}
          (\x. e / &2 * (
drop o
            (\(x,k). 
interval_upperbound k - 
interval_lowerbound k)) x)` THEN
    CONJ_TAC THENL
     [MATCH_MP_TAC 
VSUM_NORM_LE THEN ASM_REWRITE_TAC[
FORALL_IN_GSPEC] THEN
      SIMP_TAC[
o_DEF] THEN
      REWRITE_TAC[NORM_ARITH `
norm(a - (b - c):real^N) = 
norm(b - c - a)`] THEN
      MAP_EVERY X_GEN_TAC [`x:real^1`; `k:real^1->bool`] THEN STRIP_TAC THEN
      SUBGOAL_THEN `?u v:real^1. k = 
interval[u,v] /\ x 
IN interval[u,v]`
      MP_TAC THENL [ASM_MESON_TAC[
TAGGED_DIVISION_OF]; ALL_TAC] THEN
      DISCH_THEN(REPEAT_TCL CHOOSE_THEN
       (CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC)) THEN
      REWRITE_TAC[
IN_INTERVAL_1] THEN DISCH_THEN(fun 
th ->
        ASSUME_TAC 
th THEN MP_TAC(MATCH_MP 
REAL_LE_TRANS th)) THEN
      SIMP_TAC[
CONTENT_1; 
INTERVAL_LOWERBOUND_1; 
INTERVAL_UPPERBOUND_1] THEN
      DISCH_TAC THEN REMOVE_THEN "U" (MP_TAC o SPEC `x:real^1`) THEN
      ASM_REWRITE_TAC[] THEN
      SUBGOAL_THEN `
interval[u:real^1,v] 
SUBSET interval[a,b]` ASSUME_TAC THENL
       [ASM_MESON_TAC[
TAGGED_DIVISION_OF]; ALL_TAC] THEN
      ANTS_TAC THENL [ASM_MESON_TAC[
SUBSET; 
IN_INTERVAL_1]; ALL_TAC] THEN
      DISCH_THEN(fun 
th ->
        MP_TAC(ISPEC `u:real^1` 
th) THEN MP_TAC(ISPEC `v:real^1` 
th)) THEN
      FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
fine]) THEN
      DISCH_THEN(MP_TAC o SPECL [`x:real^1`; `
interval[u:real^1,v]`]) THEN
      ASM_REWRITE_TAC[
SUBSET; 
IN_BALL] THEN
      DISCH_THEN(fun 
th ->
        MP_TAC(ISPEC `u:real^1` 
th) THEN MP_TAC(ISPEC `v:real^1` 
th)) THEN
      ASM_REWRITE_TAC[
dist; 
ENDS_IN_INTERVAL; 
INTERVAL_NE_EMPTY_1] THEN
      ASM_SIMP_TAC[
REAL_LT_IMP_LE; 
NORM_SUB] THEN DISCH_TAC THEN DISCH_TAC THEN
      REPEAT(ANTS_TAC THENL
       [ASM_MESON_TAC[
ENDS_IN_INTERVAL; 
SUBSET; 
INTERVAL_NE_EMPTY_1;
                      
REAL_LT_IMP_LE];
        ONCE_REWRITE_TAC[TAUT `p ==> q ==> r <=> q ==> p ==> r`]]) THEN
      REWRITE_TAC[
NORM_1; 
DROP_SUB] THEN
      ASM_SIMP_TAC[REAL_ARITH `a <= b ==> abs(a - b) = b - a`;
                   REAL_ARITH `b <= a ==> abs(a - b) = a - b`] THEN
      REWRITE_TAC[
REAL_SUB_LDISTRIB] THEN MATCH_MP_TAC(NORM_ARITH
       `x - y:real^N = z ==> 
norm(x) <= c - b
                   ==> 
norm(y) <= b - a ==> 
norm(z) <= c - a`) THEN
      VECTOR_ARITH_TAC;
      MATCH_MP_TAC 
SUM_SUBSET_SIMPLE THEN ASM_REWRITE_TAC[] THEN
      CONJ_TAC THENL [ASM SET_TAC[]; REWRITE_TAC[
FORALL_PAIR_THM]] THEN
      REWRITE_TAC[
IN_DIFF; 
IN_ELIM_PAIR_THM] THEN
      MAP_EVERY X_GEN_TAC [`x:real^1`; `k:real^1->bool`] THEN STRIP_TAC THEN
      SUBGOAL_THEN `?u v:real^1. k = 
interval[u,v] /\ x 
IN interval[u,v]`
      MP_TAC THENL [ASM_MESON_TAC[
TAGGED_DIVISION_OF]; ALL_TAC] THEN
      DISCH_THEN(REPEAT_TCL CHOOSE_THEN
       (CONJUNCTS_THEN2 SUBST_ALL_TAC MP_TAC)) THEN
      REWRITE_TAC[
IN_INTERVAL_1; 
o_THM] THEN
      DISCH_THEN(MP_TAC o MATCH_MP 
REAL_LE_TRANS) THEN
      SIMP_TAC[
INTERVAL_LOWERBOUND_1; 
INTERVAL_UPPERBOUND_1] THEN
      REPEAT STRIP_TAC THEN MATCH_MP_TAC 
REAL_LE_MUL THEN
      ASM_REWRITE_TAC[
DROP_SUB] THEN ASM_REAL_ARITH_TAC]]);;
 
let EQUIINTEGRABLE_ON_SPLIT = prove
 (`!fs:(real^M->real^N)->bool k a b c.
      fs 
equiintegrable_on (
interval[a,b] 
INTER {x | x$k <= c}) /\
      fs 
equiintegrable_on (
interval[a,b] 
INTER {x | x$k >= c}) /\
      1 <= k /\ k <= 
dimindex(:M)
      ==> fs 
equiintegrable_on (
interval[a,b])`,
  let lemma1 = prove
   (`(!x k. (x,k) IN {x,f k | P x k} ==> Q x k) <=>
     (!x k. P x k ==> Q x (f k))`,
    REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN
    SET_TAC[]) in
  let lemma2 = prove
   (`!f:B->B s:(A#B)->bool.
      FINITE s ==> FINITE {x,f k | (x,k) IN s /\ P x k}`,
    REPEAT STRIP_TAC THEN MATCH_MP_TAC FINITE_SUBSET THEN
    EXISTS_TAC `IMAGE (\(x:A,k:B). x,(f k:B)) s` THEN
    ASM_SIMP_TAC[FINITE_IMAGE] THEN
    REWRITE_TAC[SUBSET; FORALL_PAIR_THM; lemma1; IN_IMAGE] THEN
    REWRITE_TAC[EXISTS_PAIR_THM; PAIR_EQ] THEN MESON_TAC[]) in
  let lemma3 = prove
   (`!f:real^M->real^N g:(real^M->bool)->(real^M->bool) p.
     FINITE p
     ==> vsum {x,g k |x,k| (x,k) IN p /\ ~(g k = {})}
              (\(x,k). content k % f x) =
         vsum (IMAGE (\(x,k). x,g k) p) (\(x,k). content k % f x)`,
    REPEAT STRIP_TAC THEN CONV_TAC SYM_CONV THEN MATCH_MP_TAC VSUM_SUPERSET THEN
    ASM_SIMP_TAC[FINITE_IMAGE; lemma2] THEN
    REWRITE_TAC[IMP_CONJ; FORALL_IN_IMAGE] THEN
    REWRITE_TAC[FORALL_PAIR_THM; SUBSET; IN_IMAGE; EXISTS_PAIR_THM] THEN
    REWRITE_TAC[IN_ELIM_THM; PAIR_EQ; VECTOR_MUL_EQ_0] THEN
    MESON_TAC[CONTENT_EMPTY]) in
  let lemma4 = prove
   (`(\(x,l). content (g l) % f x) =
     (\(x,l). content l % f x) o (\(x,l). x,g l)`,
    REWRITE_TAC[FUN_EQ_THM; o_THM; FORALL_PAIR_THM]) in
  REPEAT GEN_TAC THEN
  ASM_CASES_TAC `1 <= k /\ k <= dimindex(:M)` THEN ASM_REWRITE_TAC[] THEN
  REWRITE_TAC[equiintegrable_on] THEN
  MATCH_MP_TAC(TAUT
   `(a /\ b ==> c) /\ (a /\ b /\ c ==> a' /\ b' ==> c')
    ==> (a /\ a') /\ (b /\ b') ==> c /\ c'`) THEN
  CONJ_TAC THENL
   [REWRITE_TAC[integrable_on] THEN ASM MESON_TAC[HAS_INTEGRAL_SPLIT];
    STRIP_TAC] THEN
  SUBGOAL_THEN
   `!f:real^M->real^N.
        f IN fs
        ==> integral (interval[a,b]) f =
                integral (interval [a,b] INTER {x | x$k <= c}) f +
                integral (interval [a,b] INTER {x | x$k >= c}) f`
   (fun th -> SIMP_TAC[th])
  THENL
   [REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRAL_UNIQUE THEN
    MATCH_MP_TAC HAS_INTEGRAL_SPLIT THEN
    MAP_EVERY EXISTS_TAC [`k:num`; `c:real`] THEN
    ASM_SIMP_TAC[GSYM HAS_INTEGRAL_INTEGRAL];
    ALL_TAC] THEN
  DISCH_TAC THEN X_GEN_TAC `e:real` THEN STRIP_TAC THEN
  FIRST_X_ASSUM(CONJUNCTS_THEN2 (MP_TAC o SPEC `e / &2`) STRIP_ASSUME_TAC) THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[REAL_HALF] THEN
  DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool`
   (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "I2"))) THEN
  DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool`
   (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "I1"))) THEN
  EXISTS_TAC `\x. if x$k = c then (d1(x:real^M) INTER d2(x)):real^M->bool
                  else ball(x,abs(x$k - c)) INTER d1(x) INTER d2(x)` THEN
  CONJ_TAC THENL
   [REWRITE_TAC[gauge] THEN GEN_TAC THEN
    RULE_ASSUM_TAC(REWRITE_RULE[gauge]) THEN COND_CASES_TAC THEN
    ASM_SIMP_TAC[OPEN_INTER; IN_INTER; OPEN_BALL; IN_BALL] THEN
    ASM_REWRITE_TAC[DIST_REFL; GSYM REAL_ABS_NZ; REAL_SUB_0];
    ALL_TAC] THEN
  X_GEN_TAC `f:real^M->real^N` THEN
  X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
  SUBGOAL_THEN
    `(!x:real^M kk. (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k <= c} = {})
                    ==> x$k <= c) /\
     (!x:real^M kk. (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k >= c} = {})
                    ==> x$k >= c)`
  STRIP_ASSUME_TAC THENL
   [CONJ_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
    MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
    MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `kk:real^M->bool` THEN
    DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
    COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL; real_ge] THEN DISCH_THEN
     (MP_TAC o MATCH_MP (SET_RULE `k SUBSET (a INTER b) ==> k SUBSET a`)) THEN
    REWRITE_TAC[SUBSET; IN_BALL; dist] THEN DISCH_TAC THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM MEMBER_NOT_EMPTY]) THEN
    DISCH_THEN(X_CHOOSE_THEN `u:real^M` MP_TAC) THEN
    REWRITE_TAC[IN_INTER; IN_ELIM_THM] THEN REPEAT STRIP_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `u:real^M`) THEN ASM_REWRITE_TAC[] THEN
    ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
    REWRITE_TAC[REAL_NOT_LE; REAL_NOT_LT] THEN STRIP_TAC THEN
    MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC `abs((x - u:real^M)$k)` THEN
    ASM_SIMP_TAC[COMPONENT_LE_NORM] THEN
    ASM_SIMP_TAC[VECTOR_SUB_COMPONENT] THEN
    ASM_REAL_ARITH_TAC;
    ALL_TAC] THEN
  REMOVE_THEN "I2" (MP_TAC o SPEC
   `{(x:real^M,kk INTER {x:real^M | x$k >= c}) |x,kk|
     (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k >= c} = {})}` o
   SPEC `f:real^M->real^N`) THEN
  REMOVE_THEN "I1" (MP_TAC o SPEC
   `{(x:real^M,kk INTER {x:real^M | x$k <= c}) |x,kk|
     (x,kk) IN p /\ ~(kk INTER {x:real^M | x$k <= c} = {})}` o
   SPEC `f:real^M->real^N`) THEN
  ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT
   `(a /\ b) /\ (a' /\ b' ==> c) ==> (a ==> a') ==> (b ==> b') ==> c`) THEN
  CONJ_TAC THENL
   [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
    REWRITE_TAC[TAGGED_DIVISION_OF] THEN
    REPEAT(MATCH_MP_TAC(TAUT
     `(a ==> (a' /\ a'')) /\ (b ==> (b' /\ d) /\ (b'' /\ e))
      ==> a /\ b ==> ((a' /\ b') /\ d) /\ ((a'' /\ b'') /\ e)`) THEN
      CONJ_TAC) THEN
    REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
    REWRITE_TAC[lemma1] THEN REWRITE_TAC[IMP_IMP] THENL
     [SIMP_TAC[lemma2];
      REWRITE_TAC[AND_FORALL_THM] THEN
      MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `x:real^M` THEN
      MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `kk:real^M->bool` THEN
      DISCH_THEN(fun th -> CONJ_TAC THEN STRIP_TAC THEN MP_TAC th) THEN
      (ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL
        [SIMP_TAC[IN_INTER; IN_ELIM_THM] THEN ASM_MESON_TAC[]; ALL_TAC]) THEN
      (MATCH_MP_TAC MONO_AND THEN CONJ_TAC THENL [SET_TAC[]; ALL_TAC]) THEN
      ASM_MESON_TAC[INTERVAL_SPLIT];
      DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
      (REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
       DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
       REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
       DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_SIMP_TAC[] THEN
       ANTS_TAC THENL [ASM_MESON_TAC[PAIR_EQ]; ALL_TAC] THEN
       MATCH_MP_TAC(SET_RULE
        `s SUBSET s' /\ t SUBSET t'
         ==> s' INTER t' = {} ==> s INTER t = {}`) THEN
       CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]);
      ALL_TAC] THEN
    MATCH_MP_TAC(TAUT `(a ==> b /\ c) /\ d /\ e
                       ==> (a ==> (b /\ d) /\ (c /\ e))`) THEN
    CONJ_TAC THENL
     [DISCH_THEN(fun th -> CONJ_TAC THEN MP_TAC th) THEN
      DISCH_THEN(SUBST1_TAC o SYM) THEN REWRITE_TAC[INTER_UNIONS] THEN
      ONCE_REWRITE_TAC[EXTENSION] THEN REWRITE_TAC[IN_UNIONS] THEN
      X_GEN_TAC `x:real^M` THEN AP_TERM_TAC THEN
      GEN_REWRITE_TAC I [FUN_EQ_THM] THEN X_GEN_TAC `kk:real^M->bool` THEN
      REWRITE_TAC[IN_ELIM_THM; PAIR_EQ] THEN MESON_TAC[NOT_IN_EMPTY];
      ALL_TAC] THEN
    CONJ_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
    REWRITE_TAC[fine; lemma1] THEN
    REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
    DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN
    ASM_SIMP_TAC[] THEN SET_TAC[];
    ALL_TAC] THEN
  DISCH_THEN(MP_TAC o MATCH_MP (REAL_ARITH
   `x < e / &2 /\ y < e / &2 ==> x + y < e`)) THEN
  DISCH_THEN(MP_TAC o MATCH_MP NORM_TRIANGLE_LT) THEN
  MATCH_MP_TAC EQ_IMP THEN AP_THM_TAC THEN AP_TERM_TAC THEN AP_TERM_TAC THEN
  REWRITE_TAC[VECTOR_ARITH
   `(a - i) + (b - j) = c - (i + j) <=> a + b = c:real^N`] THEN
  FIRST_ASSUM(ASSUME_TAC o MATCH_MP TAGGED_DIVISION_OF_FINITE) THEN
 MATCH_MP_TAC EQ_TRANS THEN
  EXISTS_TAC
   `vsum p (\(x,l). content (l INTER {x:real^M | x$k <= c}) %
                     (f:real^M->real^N) x) +
    vsum p (\(x,l). content (l INTER {x:real^M | x$k >= c}) %
                     (f:real^M->real^N) x)` THEN
  CONJ_TAC THENL
   [ALL_TAC;
    ASM_SIMP_TAC[GSYM VSUM_ADD] THEN MATCH_MP_TAC VSUM_EQ THEN
    REWRITE_TAC[FORALL_PAIR_THM; GSYM VECTOR_ADD_RDISTRIB] THEN
    MAP_EVERY X_GEN_TAC [`x:real^M`; `l:real^M->bool`] THEN
    DISCH_TAC THEN AP_THM_TAC THEN AP_TERM_TAC THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
    DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `l:real^M->bool`] o
               el 1 o CONJUNCTS) THEN
    ASM_REWRITE_TAC[] THEN STRIP_TAC THEN
    ASM_SIMP_TAC[GSYM CONTENT_SPLIT]] THEN
  ASM_SIMP_TAC[lemma3] THEN BINOP_TAC THEN
  (GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [lemma4] THEN
   MATCH_MP_TAC VSUM_IMAGE_NONZERO THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
   REWRITE_TAC[PAIR_EQ] THEN
   ASM_MESON_TAC[TAGGED_DIVISION_SPLIT_LEFT_INJ; VECTOR_MUL_LZERO;
                 TAGGED_DIVISION_SPLIT_RIGHT_INJ]));;  
let EQUIINTEGRABLE_LIMIT = prove
 (`!f g:real^M->real^N a b.
        {f n | n 
IN (:num)} 
equiintegrable_on interval[a,b] /\
        (!x. x 
IN interval[a,b] ==> ((\n. f n x) --> g x) 
sequentially)
        ==> g 
integrable_on interval[a,b] /\
            ((\n. 
integral(
interval[a,b]) (f n)) --> 
integral(
interval[a,b]) g)
            
sequentially`,
  REPEAT GEN_TAC THEN STRIP_TAC THEN
  ASM_CASES_TAC `
content(
interval[a:real^M,b]) = &0` THEN
  ASM_SIMP_TAC[
INTEGRABLE_ON_NULL; 
INTEGRAL_NULL; 
LIM_CONST] THEN
  SUBGOAL_THEN `
cauchy (\n. 
integral(
interval[a,b]) (f n :real^M->real^N))`
  MP_TAC THENL
   [REWRITE_TAC[
cauchy] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
equiintegrable_on]) THEN
    REWRITE_TAC[
IMP_CONJ; 
RIGHT_FORALL_IMP_THM; 
FORALL_IN_GSPEC; 
IN_UNIV] THEN
    DISCH_TAC THEN REWRITE_TAC[IMP_IMP; GSYM 
CONJ_ASSOC] THEN
    DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
    ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
    DISCH_THEN(X_CHOOSE_THEN `d:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
    FIRST_ASSUM(MP_TAC o MATCH_MP 
FINE_DIVISION_EXISTS) THEN
    DISCH_THEN(MP_TAC o SPECL [`a:real^M`; `b:real^M`]) THEN
    DISCH_THEN(X_CHOOSE_THEN `p:(real^M#(real^M->bool))->bool`
        STRIP_ASSUME_TAC) THEN
    FIRST_ASSUM(ASSUME_TAC o MATCH_MP 
TAGGED_DIVISION_OF_FINITE) THEN
    FIRST_X_ASSUM(MP_TAC o GEN `n:num` o SPECL
     [`n:num`; `p:(real^M#(real^M->bool))->bool`]) THEN
    ASM_REWRITE_TAC[] THEN DISCH_TAC THEN SUBGOAL_THEN
     `
cauchy (\n. 
vsum p (\(x,k:real^M->bool).
               
content k % (f:num->real^M->real^N) n x))`
    MP_TAC THENL
     [MATCH_MP_TAC 
CONVERGENT_IMP_CAUCHY THEN
      EXISTS_TAC `
vsum p (\(x,k:real^M->bool).
          
content k % (g:real^M->real^N) x)` THEN
      MATCH_MP_TAC
       (REWRITE_RULE[
LAMBDA_PAIR_THM]
        (REWRITE_RULE[
FORALL_PAIR_THM]
         (ISPEC `\(x:real^M,k:real^M->bool) (n:num).
                  
content k % (f n x:real^N)` 
LIM_VSUM))) THEN
      ASM_REWRITE_TAC[] THEN
      MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
      MATCH_MP_TAC 
LIM_CMUL THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
      FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
TAGGED_DIVISION_OF]) THEN
      ASM_SIMP_TAC[
SUBSET] THEN ASM_MESON_TAC[];
      REWRITE_TAC[
cauchy] THEN DISCH_THEN(MP_TAC o SPEC `e / &3`) THEN
      ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
      REWRITE_TAC[IMP_IMP; 
RIGHT_IMP_FORALL_THM; 
GE] THEN
      MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
      MATCH_MP_TAC 
MONO_FORALL THEN X_GEN_TAC `m:num` THEN
      MATCH_MP_TAC 
MONO_FORALL THEN X_GEN_TAC `n:num` THEN
      ASM_CASES_TAC `N:num <= m /\ N <= n` THEN ASM_REWRITE_TAC[] THEN
      MATCH_MP_TAC(NORM_ARITH
       `
norm(sm - gm:real^N) < e / &3 /\ 
norm(sn - gn) < e / &3
        ==> 
dist(sm,sn) < e / &3 ==> 
dist(gm,gn) < e`) THEN
      ASM_REWRITE_TAC[]];
    REWRITE_TAC[GSYM 
CONVERGENT_EQ_CAUCHY] THEN
    DISCH_THEN(X_CHOOSE_TAC `l:real^N`) THEN
    SUBGOAL_THEN `((g:real^M->real^N) 
has_integral l) (
interval[a,b])`
     (fun 
th -> ASM_MESON_TAC[
th; 
integrable_on; 
INTEGRAL_UNIQUE]) THEN
    REWRITE_TAC[
has_integral] THEN X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
equiintegrable_on]) THEN
    REWRITE_TAC[
IMP_CONJ; 
RIGHT_FORALL_IMP_THM; 
FORALL_IN_GSPEC; 
IN_UNIV] THEN
    DISCH_TAC THEN REWRITE_TAC[IMP_IMP; GSYM 
CONJ_ASSOC] THEN
    DISCH_THEN(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[
REAL_HALF] THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
    STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
    X_GEN_TAC `p:(real^M#(real^M->bool))->bool` THEN STRIP_TAC THEN
    MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
    ASM_REWRITE_TAC[] THEN
    MATCH_MP_TAC(ISPEC `
sequentially` 
LIM_NORM_UBOUND) THEN
    EXISTS_TAC `\n:num. 
vsum p (\(x,k:real^M->bool). 
content k % f n x) -
                       
integral (
interval [a,b]) (f n :real^M->real^N)` THEN
    ASM_SIMP_TAC[
TRIVIAL_LIMIT_SEQUENTIALLY; 
REAL_LT_IMP_LE] THEN
    REWRITE_TAC[
EVENTUALLY_TRUE] THEN
    MATCH_MP_TAC 
LIM_SUB THEN ASM_REWRITE_TAC[] THEN
    FIRST_ASSUM(ASSUME_TAC o MATCH_MP 
TAGGED_DIVISION_OF_FINITE) THEN
    MATCH_MP_TAC
     (REWRITE_RULE[
LAMBDA_PAIR_THM]
      (REWRITE_RULE[
FORALL_PAIR_THM]
       (ISPEC `\(x:real^M,k:real^M->bool) (n:num).
                
content k % (f n x:real^N)` 
LIM_VSUM))) THEN
    ASM_REWRITE_TAC[] THEN
    MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
    MATCH_MP_TAC 
LIM_CMUL THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
TAGGED_DIVISION_OF]) THEN
    ASM_SIMP_TAC[
SUBSET] THEN ASM_MESON_TAC[]]);;
 
let EQUIINTEGRABLE_UNION = prove
 (`!fs:(real^M->real^N)->bool gs s.
        fs 
equiintegrable_on s /\ gs 
equiintegrable_on s
        ==> (fs 
UNION gs) 
equiintegrable_on s`,
  REPEAT GEN_TAC THEN REWRITE_TAC[
equiintegrable_on; 
IN_UNION] THEN
  REWRITE_TAC[TAUT `a \/ b ==> c <=> (a ==> c) /\ (b ==> c)`] THEN
  REWRITE_TAC[
FORALL_AND_THM] THEN STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
  X_GEN_TAC `e:real` THEN DISCH_TAC THEN
  REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `e:real`)) THEN ASM_REWRITE_TAC[] THEN
  DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
  DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
  EXISTS_TAC `\x. (d1:real^M->real^M->bool) x 
INTER d2 x` THEN
  ASM_SIMP_TAC[
GAUGE_INTER; 
FINE_INTER] THEN
  REPEAT STRIP_TAC THEN ASM_SIMP_TAC[]);;
 
let EQUIINTEGRABLE_EQ = prove
 (`!fs gs:(real^M->real^N)->bool s.
        fs 
equiintegrable_on s /\
        (!g. g 
IN gs ==> ?f. f 
IN fs /\ (!x. x 
IN s ==> f x = g x))
        ==> gs 
equiintegrable_on s`,
  REPEAT GEN_TAC THEN REWRITE_TAC[
equiintegrable_on] THEN
  DISCH_THEN(CONJUNCTS_THEN2 STRIP_ASSUME_TAC (LABEL_TAC "*")) THEN
  CONJ_TAC THENL
   [X_GEN_TAC `g:real^M->real^N` THEN DISCH_TAC THEN
    REMOVE_THEN "*" (MP_TAC o SPEC `g:real^M->real^N`) THEN
    ASM_REWRITE_TAC[
LEFT_IMP_EXISTS_THM] THEN
    X_GEN_TAC `f:real^M->real^N` THEN STRIP_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `f:real^M->real^N`) THEN
    ASM_MESON_TAC[
INTEGRABLE_SPIKE; 
IN_DIFF; 
NEGLIGIBLE_EMPTY];
    X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
    STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
    MAP_EVERY X_GEN_TAC
     [`g:real^M->real^N`;`p:(real^M#(real^M->bool))->bool`] THEN
    STRIP_TAC THEN REMOVE_THEN "*" (MP_TAC o SPEC `g:real^M->real^N`) THEN
    ASM_REWRITE_TAC[
LEFT_IMP_EXISTS_THM] THEN
    X_GEN_TAC `f:real^M->real^N` THEN STRIP_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPECL
     [`f:real^M->real^N`;`p:(real^M#(real^M->bool))->bool`]) THEN
    ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(MESON[]
     `x:real^N = y /\ a = b ==> 
norm(x - a) < e ==> 
norm(y - b) < e`) THEN
    CONJ_TAC THENL
     [MATCH_MP_TAC 
VSUM_EQ THEN REWRITE_TAC[
FORALL_PAIR_THM] THEN
      RULE_ASSUM_TAC(REWRITE_RULE[
TAGGED_DIVISION_OF; 
SUBSET]) THEN
      ASM_MESON_TAC[];
      ASM_MESON_TAC[
INTEGRAL_EQ]]]);;
 
let EQUIINTEGRABLE_ADD = prove
 (`!fs:(real^M->real^N)->bool gs s.
        fs 
equiintegrable_on s /\ gs 
equiintegrable_on s
        ==> {(\x. f x + g x) | f 
IN fs /\ g 
IN gs} 
equiintegrable_on s`,
  REPEAT GEN_TAC THEN
  SIMP_TAC[
equiintegrable_on; 
INTEGRABLE_ADD; 
FORALL_IN_GSPEC] THEN
  DISCH_THEN(CONJUNCTS_THEN2
   (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "f"))
   (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "g"))) THEN
  X_GEN_TAC `e:real` THEN DISCH_TAC THEN
  REWRITE_TAC[
IMP_CONJ; 
RIGHT_FORALL_IMP_THM; 
FORALL_IN_GSPEC] THEN
  ASM_SIMP_TAC[
RIGHT_IMP_FORALL_THM; 
INTEGRAL_ADD; IMP_IMP] THEN
  REMOVE_THEN "g" (MP_TAC o SPEC `e / &2`) THEN
  REMOVE_THEN "f" (MP_TAC o SPEC `e / &2`) THEN
  ASM_REWRITE_TAC[
REAL_HALF] THEN
  DISCH_THEN(X_CHOOSE_THEN `d1:real^M->real^M->bool`
   (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "f"))) THEN
  DISCH_THEN(X_CHOOSE_THEN `d2:real^M->real^M->bool`
   (CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "g"))) THEN
  EXISTS_TAC `\x. (d1:real^M->real^M->bool) x 
INTER d2 x` THEN
  ASM_SIMP_TAC[
GAUGE_INTER; 
FINE_INTER] THEN
  MAP_EVERY X_GEN_TAC [`f:real^M->real^N`; `g:real^M->real^N`;
                       `p:(real^M#(real^M->bool))->bool`] THEN STRIP_TAC THEN
  REMOVE_THEN "g" (MP_TAC o SPECL
   [`g:real^M->real^N`; `p:(real^M#(real^M->bool))->bool`]) THEN
  REMOVE_THEN "f" (MP_TAC o SPECL
   [`f:real^M->real^N`; `p:(real^M#(real^M->bool))->bool`]) THEN
  ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(NORM_ARITH
   `s + s' = t
    ==> 
norm(s - i) < e / &2 ==> 
norm(s' - i') < e / &2
        ==> 
norm(t - (i + i')) < e`) THEN
  FIRST_ASSUM(ASSUME_TAC o MATCH_MP 
TAGGED_DIVISION_OF_FINITE) THEN
  ASM_SIMP_TAC[GSYM 
VSUM_ADD] THEN
  REWRITE_TAC[
LAMBDA_PAIR_THM; 
VECTOR_ADD_LDISTRIB]);;
 
let EQUIINTEGRABLE_UNIFORM_LIMIT = prove
 (`!fs:(real^M->real^N)->bool a b.
        fs 
equiintegrable_on interval[a,b]
        ==> {g | !e. &0 < e
                     ==> ?f. f 
IN fs /\
                             !x. x 
IN interval[a,b] ==> 
norm(g x - f x) < e}
            
equiintegrable_on interval[a,b]`,
  REPEAT STRIP_TAC THEN
  FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
equiintegrable_on]) THEN
  REWRITE_TAC[
equiintegrable_on; 
IN_ELIM_THM] THEN REPEAT GEN_TAC THEN
  STRIP_TAC THEN CONJ_TAC THENL
   [ASM_MESON_TAC[
INTEGRABLE_UNIFORM_LIMIT; 
REAL_LT_IMP_LE]; ALL_TAC] THEN
  X_GEN_TAC `e:real` THEN DISCH_TAC THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `e / &2`) THEN ASM_REWRITE_TAC[
REAL_HALF] THEN
  MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `d:real^M->real^M->bool` THEN
  STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MAP_EVERY X_GEN_TAC
   [`g:real^M->real^N`;`p:(real^M#(real^M->bool))->bool`] THEN
  STRIP_TAC THEN
  FIRST_ASSUM(ASSUME_TAC o MATCH_MP 
TAGGED_DIVISION_OF_FINITE) THEN
  SUBGOAL_THEN `(g:real^M->real^N) 
integrable_on interval[a,b]`
  ASSUME_TAC THENL
   [ASM_MESON_TAC[
INTEGRABLE_UNIFORM_LIMIT; 
REAL_LT_IMP_LE]; ALL_TAC] THEN
  FIRST_X_ASSUM(MP_TAC o GEN `n:num` o SPEC `inv(&n + &1)`) THEN
  REWRITE_TAC[
REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
  REWRITE_TAC[
SKOLEM_THM; 
FORALL_AND_THM; 
LEFT_IMP_EXISTS_THM] THEN
  X_GEN_TAC `f:num->real^M->real^N` THEN STRIP_TAC THEN
  SUBGOAL_THEN
   `!x. x 
IN interval[a,b]
        ==> ((\n. f n x) --> (g:real^M->real^N) x) 
sequentially`
  ASSUME_TAC THENL
   [X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
    REWRITE_TAC[
LIM_SEQUENTIALLY] THEN X_GEN_TAC `k:real` THEN DISCH_TAC THEN
    MP_TAC(SPEC `k:real` 
REAL_ARCH_INV) THEN ASM_REWRITE_TAC[] THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `N:num` THEN
    STRIP_TAC THEN X_GEN_TAC `n:num` THEN DISCH_TAC THEN
    REWRITE_TAC[NORM_ARITH `
dist(a:real^N,b) = 
norm(b - a)`] THEN
    MATCH_MP_TAC 
REAL_LT_TRANS THEN EXISTS_TAC `inv(&n + &1)` THEN
    ASM_SIMP_TAC[] THEN
    MATCH_MP_TAC 
REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN
    ASM_REWRITE_TAC[] THEN MATCH_MP_TAC 
REAL_LE_INV2 THEN
    REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; 
REAL_OF_NUM_LT] THEN
    ASM_ARITH_TAC;
    ALL_TAC] THEN
  MP_TAC(ISPECL [`f:num->real^M->real^N`; `g:real^M->real^N`;
                 `a:real^M`; `b:real^M`] 
EQUIINTEGRABLE_LIMIT) THEN
  ANTS_TAC THENL
   [ASM_REWRITE_TAC[] THEN MATCH_MP_TAC 
EQUIINTEGRABLE_SUBSET THEN
    EXISTS_TAC `fs:(real^M->real^N)->bool` THEN ASM SET_TAC[];
    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "*"))] THEN
  SUBGOAL_THEN
   `((\n. 
vsum p (\(x,k:real^M->bool).
                    
content k % (f:num->real^M->real^N) n x)) -->
     
vsum p (\(x,k). 
content k % g x)) 
sequentially`
   (LABEL_TAC "+")
  THENL
   [MATCH_MP_TAC
       (REWRITE_RULE[
LAMBDA_PAIR_THM]
        (REWRITE_RULE[
FORALL_PAIR_THM]
         (ISPEC `\(x:real^M,k:real^M->bool) (n:num).
                  
content k % (f n x:real^N)` 
LIM_VSUM))) THEN
    ASM_REWRITE_TAC[] THEN
    MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
    MATCH_MP_TAC 
LIM_CMUL THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
TAGGED_DIVISION_OF]) THEN
    ASM_SIMP_TAC[
SUBSET] THEN ASM_MESON_TAC[];
    ALL_TAC] THEN
  REMOVE_THEN "*" (MP_TAC o REWRITE_RULE[
LIM_SEQUENTIALLY]) THEN
  DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
  ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[
dist]] THEN
  DISCH_THEN(X_CHOOSE_THEN `N1:num` (LABEL_TAC "*")) THEN
  REMOVE_THEN "+" (MP_TAC o REWRITE_RULE[
LIM_SEQUENTIALLY]) THEN
  DISCH_THEN(MP_TAC o SPEC `e / &4`) THEN
  ANTS_TAC THENL [ASM_REAL_ARITH_TAC; REWRITE_TAC[
dist]] THEN
  DISCH_THEN(X_CHOOSE_THEN `N2:num` (LABEL_TAC "+")) THEN
  SUBGOAL_THEN `?n:num. N1 <= n /\ N2 <= n` STRIP_ASSUME_TAC THENL
   [EXISTS_TAC `N1 + N2:num` THEN ARITH_TAC; ALL_TAC] THEN
  REMOVE_THEN "*" (MP_TAC o SPEC `n:num`) THEN
  REMOVE_THEN "+" (MP_TAC o SPEC `n:num`) THEN
  FIRST_X_ASSUM(MP_TAC o SPECL
   [`(f:num->real^M->real^N) n`;`p:(real^M#(real^M->bool))->bool`]) THEN
  ASM_REWRITE_TAC[] THEN NORM_ARITH_TAC);;
 
let SUM_CONTENT_AREA_OVER_THIN_DIVISION = prove
 (`!d a b:real^M s i c.
        d 
division_of s /\ s 
SUBSET interval[a,b] /\
        1 <= i /\ i <= 
dimindex(:M) /\ a$i <= c /\ c <= b$i /\
        (!k. k 
IN d ==> ~(k 
INTER {x | x$i = c} = {}))
        ==> (b$i - a$i) *
            
sum d (\k. 
content k /
                       (
interval_upperbound k$i - 
interval_lowerbound k$i))
            <= &2 * 
content(
interval[a,b])`,
  let lemma0 = prove
   (`!k:real^M->bool i.
          1 <= i /\ i <= dimindex(:M)
          ==> content k / (interval_upperbound k$i - interval_lowerbound k$i) =
              if content k = &0 then &0
              else product ((1..dimindex(:M)) DELETE i)
                           (\j. interval_upperbound k$j -
                                interval_lowerbound k$j)`,
    REPEAT STRIP_TAC THEN COND_CASES_TAC THEN
    ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO] THEN
    REWRITE_TAC[content] THEN
    COND_CASES_TAC THENL [ASM_MESON_TAC[CONTENT_EMPTY]; ALL_TAC] THEN
    SUBGOAL_THEN
     `1..dimindex(:M) = i INSERT ((1..dimindex(:M)) DELETE i)`
    MP_TAC THENL
     [REWRITE_TAC[SET_RULE `s = x INSERT (s DELETE x) <=> x IN s`] THEN
      ASM_REWRITE_TAC[IN_NUMSEG];
      DISCH_THEN(fun th -> GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV)
       [th])] THEN
    ASM_SIMP_TAC[PRODUCT_CLAUSES; IN_NUMSEG; FINITE_DELETE; FINITE_NUMSEG;
                 IN_DELETE] THEN
    MATCH_MP_TAC(REAL_FIELD `~(y = &0) ==> (y * x) * inv y = x`) THEN
    DISCH_TAC THEN
    UNDISCH_TAC `~(content(k:real^M->bool) = &0)` THEN
    ASM_REWRITE_TAC[content; PRODUCT_EQ_0_NUMSEG] THEN ASM_MESON_TAC[])
  and lemma1 = prove
   (`!d a b:real^M s i.
          d division_of s /\ s SUBSET interval[a,b] /\
          1 <= i /\ i <= dimindex(:M) /\
          ((!k. k IN d
                ==> ~(content k = &0) /\ ~(k INTER {x | x$i = a$i} = {})) \/
           (!k. k IN d
                ==> ~(content k = &0) /\ ~(k INTER {x | x$i = b$i} = {})))
          ==> (b$i - a$i) *
              sum d (\k. content k /
                         (interval_upperbound k$i - interval_lowerbound k$i))
              <= content(interval[a,b])`,
    REPEAT GEN_TAC THEN DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
    FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
    ABBREV_TAC
     `extend =
      \k:real^M->bool. interval
           [(lambda j. if j = i then (a:real^M)$i
                       else interval_lowerbound k$j):real^M,
            (lambda j. if j = i then (b:real^M)$i
                       else interval_upperbound k$j)]` THEN
    SUBGOAL_THEN `!k. k IN d ==> k SUBSET interval[a:real^M,b]`
    ASSUME_TAC THENL
     [RULE_ASSUM_TAC(REWRITE_RULE[division_of]) THEN ASM SET_TAC[];
      ALL_TAC] THEN
    SUBGOAL_THEN `!k:real^M->bool. k IN d ==> ~(k = {})` ASSUME_TAC THENL
     [ASM_MESON_TAC[division_of]; ALL_TAC] THEN
    SUBGOAL_THEN
     `(!k. k IN d ==> ~((extend:(real^M->bool)->(real^M->bool)) k = {})) /\
      (!k. k IN d ==> extend k SUBSET interval[a,b])`
    STRIP_ASSUME_TAC THENL
     [FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
      CONJ_TAC THEN MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN
      (DISCH_TAC THEN EXPAND_TAC "extend" THEN
       SUBGOAL_THEN `interval[u:real^M,v] SUBSET interval[a,b]` MP_TAC THENL
        [ASM_SIMP_TAC[]; ALL_TAC] THEN
       SUBGOAL_THEN `~(interval[u:real^M,v] = {})` MP_TAC THENL
        [ASM_SIMP_TAC[]; ALL_TAC] THEN
       SIMP_TAC[SUBSET_INTERVAL; INTERVAL_NE_EMPTY; LAMBDA_BETA;
                INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN
       MESON_TAC[REAL_LE_TRANS; REAL_LE_REFL]);
      ALL_TAC] THEN
    SUBGOAL_THEN
     `!k1 k2. k1 IN d /\ k2 IN d /\ ~(k1 = k2)
              ==> interior((extend:(real^M->bool)->(real^M->bool)) k1) INTER
                  interior(extend k2) = {}`
    ASSUME_TAC THENL
     [REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
      FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
      MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN DISCH_TAC THEN
      MAP_EVERY X_GEN_TAC [`w:real^M`; `z:real^M`] THEN DISCH_TAC THEN
      DISCH_TAC THEN
      FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
      DISCH_THEN(MP_TAC o el 2 o CONJUNCTS) THEN DISCH_THEN(MP_TAC o SPECL
       [`interval[u:real^M,v]`; `interval[w:real^M,z]`]) THEN
      ASM_REWRITE_TAC[INTERIOR_CLOSED_INTERVAL] THEN
      ONCE_REWRITE_TAC[GSYM CONTRAPOS_THM] THEN
      REWRITE_TAC[GSYM MEMBER_NOT_EMPTY; IN_INTER] THEN
      EXPAND_TAC "extend" THEN
      SIMP_TAC[INTERIOR_CLOSED_INTERVAL; IN_INTERVAL; LAMBDA_BETA] THEN
      SUBGOAL_THEN `~(interval[u:real^M,v] = {}) /\
                    ~(interval[w:real^M,z] = {})`
      MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
      SIMP_TAC[SUBSET_INTERVAL; INTERVAL_NE_EMPTY; LAMBDA_BETA;
               INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND] THEN
      STRIP_TAC THEN DISCH_THEN(X_CHOOSE_THEN `x:real^M` MP_TAC) THEN
      MP_TAC(MESON[]
       `(!P. (!j:num. P j) <=> P i /\ (!j. ~(j = i) ==> P j))`) THEN
      DISCH_THEN(fun th -> GEN_REWRITE_TAC
       (LAND_CONV o ONCE_DEPTH_CONV) [th]) THEN
      ASM_SIMP_TAC[IMP_IMP] THEN STRIP_TAC THEN
      FIRST_X_ASSUM(DISJ_CASES_THEN
       (fun th -> MP_TAC(SPEC `interval[u:real^M,v]` th) THEN
                  MP_TAC(SPEC `interval[w:real^M,z]` th))) THEN
      ASM_REWRITE_TAC[CONTENT_EQ_0_INTERIOR; INTERIOR_CLOSED_INTERVAL] THEN
      REWRITE_TAC[IMP_CONJ; GSYM MEMBER_NOT_EMPTY; IN_INTER; IN_ELIM_THM] THEN
      REWRITE_TAC[IN_INTERVAL; LEFT_IMP_EXISTS_THM] THEN
      X_GEN_TAC `q:real^M` THEN STRIP_TAC THEN
      X_GEN_TAC `r:real^M` THEN STRIP_TAC THEN
      X_GEN_TAC `s:real^M` THEN STRIP_TAC THEN
      X_GEN_TAC `t:real^M` THEN STRIP_TAC THENL
       [EXISTS_TAC `(lambda j. if j = i then min ((q:real^M)$i) ((s:real^M)$i)
                               else (x:real^M)$j):real^M`;
        EXISTS_TAC `(lambda j. if j = i then max ((q:real^M)$i) ((s:real^M)$i)
                               else (x:real^M)$j):real^M`] THEN
      (SIMP_TAC[AND_FORALL_THM; LAMBDA_BETA] THEN X_GEN_TAC `j:num` THEN
       ASM_CASES_TAC `j:num = i` THEN ASM_SIMP_TAC[] THEN
       UNDISCH_THEN `j:num = i` SUBST_ALL_TAC THEN
       SUBGOAL_THEN `interval[u:real^M,v] SUBSET interval[a,b] /\
                     interval[w:real^M,z] SUBSET interval[a,b]`
       MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
       SUBGOAL_THEN `~(interval[u:real^M,v] = {}) /\
                     ~(interval[w:real^M,z] = {})`
       MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
       SIMP_TAC[INTERVAL_NE_EMPTY; SUBSET_INTERVAL] THEN
       REPEAT STRIP_TAC THEN
       REPEAT(FIRST_X_ASSUM(MP_TAC o SPEC `i:num`)) THEN ASM_REWRITE_TAC[] THEN
       ASM_REAL_ARITH_TAC);
      ALL_TAC] THEN
    MATCH_MP_TAC REAL_LE_TRANS THEN EXISTS_TAC
     `sum (IMAGE (extend:(real^M->bool)->(real^M->bool)) d) content` THEN
    CONJ_TAC THENL
     [W(MP_TAC o PART_MATCH (lhs o rand) SUM_IMAGE_NONZERO o rand o snd) THEN
      ANTS_TAC THENL
       [ASM_REWRITE_TAC[] THEN
        MAP_EVERY X_GEN_TAC [`k1:real^M->bool`; `k2:real^M->bool`] THEN
        STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o SPECL
         [`k1:real^M->bool`; `k2:real^M->bool`]) THEN
        ASM_REWRITE_TAC[INTER_IDEMPOT] THEN
        EXPAND_TAC "extend" THEN REWRITE_TAC[CONTENT_EQ_0_INTERIOR];
        DISCH_THEN SUBST1_TAC THEN REWRITE_TAC[GSYM SUM_LMUL] THEN
        MATCH_MP_TAC SUM_LE THEN ASM_REWRITE_TAC[] THEN
        FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
        MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN DISCH_TAC THEN
        ASM_CASES_TAC `content(interval[u:real^M,v]) = &0` THENL
         [ASM_REWRITE_TAC[real_div; REAL_MUL_LZERO; REAL_MUL_RZERO; o_THM] THEN
          EXPAND_TAC "extend" THEN REWRITE_TAC[CONTENT_POS_LE];
          ALL_TAC] THEN
        FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM CONTENT_LT_NZ]) THEN
        DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
        REWRITE_TAC[CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
        ASM_SIMP_TAC[INTERVAL_LOWERBOUND; INTERVAL_UPPERBOUND;
                     REAL_LT_IMP_LE; real_div; REAL_MUL_ASSOC] THEN
        ASM_SIMP_TAC[GSYM real_div; REAL_LE_LDIV_EQ; REAL_SUB_LT] THEN
        SUBGOAL_THEN
         `~((extend:(real^M->bool)->(real^M->bool)) (interval[u,v]) = {})`
        MP_TAC THENL [ASM_SIMP_TAC[]; ALL_TAC] THEN
        EXPAND_TAC "extend" THEN ASM_SIMP_TAC[content; o_THM] THEN
        ASM_SIMP_TAC[INTERVAL_NE_EMPTY; INTERVAL_LOWERBOUND;
                     INTERVAL_UPPERBOUND; REAL_LT_IMP_LE] THEN
        DISCH_THEN(K ALL_TAC) THEN
        SUBGOAL_THEN
         `1..dimindex(:M) = i INSERT ((1..dimindex(:M)) DELETE i)`
        SUBST1_TAC THENL
         [MATCH_MP_TAC(SET_RULE `x IN s ==> s = x INSERT (s DELETE x)`) THEN
          ASM_REWRITE_TAC[IN_NUMSEG];
          ALL_TAC] THEN
        SIMP_TAC[PRODUCT_CLAUSES; FINITE_NUMSEG; FINITE_DELETE] THEN
        ASM_SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA] THEN
        MATCH_MP_TAC REAL_EQ_IMP_LE THEN MATCH_MP_TAC(REAL_RING
          `x:real = y ==> ab * uv * x = (ab * y) * uv`) THEN
        MATCH_MP_TAC PRODUCT_EQ THEN
        SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA]];
      MATCH_MP_TAC SUBADDITIVE_CONTENT_DIVISION THEN EXISTS_TAC
       `UNIONS (IMAGE (extend:(real^M->bool)->(real^M->bool)) d)` THEN
      ASM_SIMP_TAC[UNIONS_SUBSET; division_of; FINITE_IMAGE] THEN
      REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_IMAGE] THEN
      FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
      REPEAT CONJ_TAC THEN MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN
      DISCH_TAC THENL
       [CONJ_TAC THENL [ASM SET_TAC[]; ASM_SIMP_TAC[]] THEN
        EXPAND_TAC "extend" THEN REWRITE_TAC[] THEN MESON_TAC[];
        ASM_MESON_TAC[];
        ASM_SIMP_TAC[]]]) in
  REPEAT STRIP_TAC THEN
  ASM_CASES_TAC `content(interval[a:real^M,b]) = &0` THENL
   [MATCH_MP_TAC(REAL_ARITH `x = &0 /\ &0 <= y ==> x <= &2 * y`) THEN
    REWRITE_TAC[CONTENT_POS_LE; REAL_ENTIRE] THEN DISJ2_TAC THEN
    MATCH_MP_TAC SUM_EQ_0 THEN X_GEN_TAC `k:real^M->bool` THEN
    DISCH_TAC THEN REWRITE_TAC[real_div; REAL_ENTIRE] THEN DISJ1_TAC THEN
    MATCH_MP_TAC CONTENT_0_SUBSET THEN
    MAP_EVERY EXISTS_TAC [`a:real^M`; `b:real^M`] THEN
    ASM_MESON_TAC[division_of; SUBSET_TRANS];
    ALL_TAC] THEN
  FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM CONTENT_LT_NZ]) THEN
  DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
  REWRITE_TAC[CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
  FIRST_ASSUM(ASSUME_TAC o MATCH_MP DIVISION_OF_FINITE) THEN
  MP_TAC(ISPECL
   [`{k | k IN {l INTER {x | x$i <= c} | l |
                l IN d /\ ~(l INTER {x:real^M | x$i <= c} = {})} /\
          ~(content k = &0)}`;
    `a:real^M`;
    `(lambda j. if j = i then c else (b:real^M)$j):real^M`;
    `UNIONS {k | k IN {l INTER {x | x$i <= c} | l |
                       l IN d /\ ~(l INTER {x:real^M | x$i <= c} = {})} /\
                 ~(content k = &0)}`;
    `i:num`] lemma1) THEN
  MP_TAC(ISPECL
   [`{k | k IN {l INTER {x | x$i >= c} | l |
                l IN d /\ ~(l INTER {x:real^M | x$i >= c} = {})} /\
          ~(content k = &0)}`;
    `(lambda j. if j = i then c else (a:real^M)$j):real^M`;
    `b:real^M`;
    `UNIONS {k | k IN {l INTER {x | x$i >= c} | l |
                       l IN d /\ ~(l INTER {x:real^M | x$i >= c} = {})} /\
                 ~(content k = &0)}`;
    `i:num`] lemma1) THEN
  ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(TAUT
   `(p1 /\ p2) /\ (q1 /\ q2 ==> r) ==> (p2 ==> q2) ==> (p1 ==> q1) ==> r`) THEN
  CONJ_TAC THENL
   [CONJ_TAC THEN
    (REPEAT CONJ_TAC THENL
     [REWRITE_TAC[division_of] THEN CONJ_TAC THENL
       [MATCH_MP_TAC FINITE_RESTRICT THEN
        ONCE_REWRITE_TAC[SIMPLE_IMAGE_GEN] THEN
        MATCH_MP_TAC FINITE_IMAGE THEN MATCH_MP_TAC FINITE_RESTRICT THEN
        ASM_REWRITE_TAC[];
        ALL_TAC] THEN
      REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ; RIGHT_FORALL_IMP_THM] THEN
      CONJ_TAC THENL
       [FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
        MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN
        REPEAT DISCH_TAC THEN ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
         [REWRITE_TAC[IN_ELIM_THM; SUBSET; IN_UNIONS] THEN ASM_MESON_TAC[];
          ASM_SIMP_TAC[INTERVAL_SPLIT] THEN MESON_TAC[]];
        X_GEN_TAC `k:real^M->bool` THEN REPEAT DISCH_TAC THEN
        X_GEN_TAC `l:real^M->bool` THEN REPEAT DISCH_TAC THEN
        FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [division_of]) THEN
        DISCH_THEN(MP_TAC o SPECL [`k:real^M->bool`; `l:real^M->bool`] o
          el 2 o CONJUNCTS) THEN
        ANTS_TAC THENL [ASM_MESON_TAC[]; ALL_TAC] THEN
        MATCH_MP_TAC(SET_RULE
         `s SUBSET s' /\ t SUBSET t'
          ==> s' INTER t' = {} ==> s INTER t = {}`) THEN
        CONJ_TAC THEN MATCH_MP_TAC SUBSET_INTERIOR THEN SET_TAC[]];
      REWRITE_TAC[UNIONS_SUBSET; FORALL_IN_GSPEC; IMP_CONJ] THEN
      X_GEN_TAC `k:real^M->bool` THEN REPEAT DISCH_TAC THEN
      SUBGOAL_THEN `k SUBSET interval[a:real^M,b]` MP_TAC THENL
       [ASM_MESON_TAC[division_of; SUBSET_TRANS]; ALL_TAC] THEN
      MATCH_MP_TAC(SET_RULE
       `i INTER h SUBSET j ==> k SUBSET i ==> k INTER h SUBSET j`) THEN
      ASM_SIMP_TAC[INTERVAL_SPLIT; SUBSET_INTERVAL; LAMBDA_BETA] THEN
      MATCH_MP_TAC MONO_FORALL THEN GEN_TAC THEN MATCH_MP_TAC MONO_IMP THEN
      REAL_ARITH_TAC;
      ALL_TAC])
    THENL [DISJ2_TAC; DISJ1_TAC] THEN
    REWRITE_TAC[FORALL_IN_GSPEC; IMP_CONJ] THEN
    ASM_SIMP_TAC[LAMBDA_BETA; real_ge] THEN ASM SET_TAC[REAL_LE_REFL];
    ASM_SIMP_TAC[LAMBDA_BETA]] THEN
  SUBGOAL_THEN
   `sum {k | k IN
             { l INTER {x | x$i <= c} | l |
               l IN d /\ ~(l INTER {x:real^M | x$i <= c} = {})} /\
             ~(content k = &0)}
        (\k. content k /
             (interval_upperbound k$i - interval_lowerbound k$i)) =
    sum d ((\k. content k /
             (interval_upperbound k$i - interval_lowerbound k$i)) o
           (\k. k INTER {x | x$i <= c})) /\
    sum {k | k IN
             { l INTER {x | x$i >= c} | l |
               l IN d /\ ~(l INTER {x:real^M | x$i >= c} = {})} /\
             ~(content k = &0)}
        (\k. content k /
             (interval_upperbound k$i - interval_lowerbound k$i)) =
    sum d ((\k. content k /
             (interval_upperbound k$i - interval_lowerbound k$i)) o
           (\k. k INTER {x | x$i >= c}))`
  (CONJUNCTS_THEN SUBST1_TAC) THENL
   [CONJ_TAC THEN
    (W(MP_TAC o PART_MATCH (rand o rand) SUM_IMAGE_NONZERO o rand o snd) THEN
     ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
      [MAP_EVERY X_GEN_TAC [`k:real^M->bool`; `l:real^M->bool`] THEN
       STRIP_TAC THEN
       REWRITE_TAC[real_div; REAL_ENTIRE] THEN DISJ1_TAC THEN
       (MATCH_MP_TAC DIVISION_SPLIT_LEFT_INJ ORELSE
        MATCH_MP_TAC DIVISION_SPLIT_RIGHT_INJ) THEN ASM_MESON_TAC[];
       DISCH_THEN(SUBST1_TAC o SYM) THEN CONV_TAC SYM_CONV THEN
       MATCH_MP_TAC SUM_SUPERSET THEN CONJ_TAC THENL [SET_TAC[]; ALL_TAC] THEN
       GEN_TAC THEN DISCH_THEN(MP_TAC o MATCH_MP (SET_RULE
        `x IN IMAGE f d /\
         ~(x IN {x | x IN {f y |y| y IN d /\ ~(f y = a)} /\ ~P x})
         ==> (!y. f y = a ==> P(f y)) ==> P x`)) THEN
       SIMP_TAC[CONTENT_EMPTY; real_div; REAL_MUL_LZERO]]);
     ALL_TAC] THEN
  MAP_EVERY (fun (t,tac) ->
    ASM_CASES_TAC t THENL
     [FIRST_X_ASSUM SUBST_ALL_TAC THEN DISCH_THEN(MP_TAC o tac) THEN
      MATCH_MP_TAC(REAL_ARITH `x = y /\ a <= b ==> x <= a ==> y <= b`) THEN
      CONJ_TAC THENL
       [AP_TERM_TAC THEN MATCH_MP_TAC SUM_EQ THEN
        X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
        PURE_REWRITE_TAC[o_THM] THEN AP_TERM_TAC THEN
        REWRITE_TAC[real_ge; SET_RULE
         `k INTER {x | P x} = k <=> (!x. x IN k ==> P x)`] THEN
        X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
        SUBGOAL_THEN `x IN interval[a:real^M,b]` MP_TAC THENL
         [ASM_MESON_TAC[SUBSET; division_of]; ALL_TAC] THEN
        ASM_SIMP_TAC[IN_INTERVAL];
        MATCH_MP_TAC(REAL_ARITH `&0 <= y /\ x <= y ==> x <= &2 * y`) THEN
        REWRITE_TAC[CONTENT_POS_LE] THEN MATCH_MP_TAC CONTENT_SUBSET THEN
        SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA] THEN
        MESON_TAC[REAL_LE_REFL]];
      ALL_TAC])
    [`c = (a:real^M)$i`,CONJUNCT2; `c = (b:real^M)$i`,CONJUNCT1] THEN
  SUBGOAL_THEN `(a:real^M)$i < c /\ c < (b:real^M)$i` STRIP_ASSUME_TAC THENL
   [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
  ONCE_REWRITE_TAC[REAL_MUL_SYM] THEN
  ASM_SIMP_TAC[GSYM REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN
  REWRITE_TAC[REAL_ARITH `(x * &2) / y = &2 * x / y`] THEN
  MATCH_MP_TAC(REAL_ARITH
   `s <= s1 + s2 /\ c1 = c /\ c2 = c
    ==> s1 <= c1 /\ s2 <= c2 ==> s <= &2 * c`) THEN
  CONJ_TAC THENL
   [ASM_SIMP_TAC[GSYM SUM_ADD] THEN MATCH_MP_TAC SUM_LE THEN
    ASM_SIMP_TAC[lemma0] THEN
    FIRST_ASSUM(fun th -> REWRITE_TAC[MATCH_MP FORALL_IN_DIVISION th]) THEN
    MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`] THEN DISCH_TAC THEN
    SUBGOAL_THEN
     `~(interval[u:real^M,v] = {}) /\ interval[u,v] SUBSET interval[a,b]`
    MP_TAC THENL [ASM_MESON_TAC[division_of; SUBSET_TRANS]; ALL_TAC] THEN
    SIMP_TAC[INTERVAL_NE_EMPTY; SUBSET_INTERVAL; IMP_CONJ] THEN
    REPEAT STRIP_TAC THEN REWRITE_TAC[o_THM] THEN
    MATCH_MP_TAC(REAL_ARITH
     `&0 <= x /\ c1 + c2 = c /\
      (~(c1 = &0) ==> x1 = x) /\ (~(c2 = &0) ==> x2 = x)
      ==> (if c = &0 then &0 else x) <=
          (if c1 = &0 then &0 else x1) +
          (if c2 = &0 then &0 else x2)`) THEN
    ASM_SIMP_TAC[GSYM CONTENT_SPLIT] THEN
    ASM_SIMP_TAC[INTERVAL_SPLIT; CONTENT_POS_LE] THEN CONJ_TAC THENL
     [MATCH_MP_TAC PRODUCT_POS_LE THEN
      ASM_SIMP_TAC[FINITE_DELETE; FINITE_NUMSEG; IN_DELETE; IN_NUMSEG;
                   INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_SUB_LE];
      REWRITE_TAC[CONTENT_EQ_0; REAL_NOT_LE; MESON[]
       `~(?i. P i /\ Q i /\ R i) <=> (!i. P i /\ Q i ==> ~R i)`] THEN
      SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; REAL_LT_IMP_LE] THEN
      REPEAT STRIP_TAC THEN MATCH_MP_TAC PRODUCT_EQ THEN
      ASM_SIMP_TAC[INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND; IN_DELETE;
                   IN_NUMSEG; LAMBDA_BETA]];
    SUBGOAL_THEN
     `~(interval[a,b] = {}) /\
      ~(interval[a:real^M,(lambda j. if j = i then c else b$j)] = {}) /\
      ~(interval[(lambda j. if j = i then c else a$j):real^M,b] = {})`
    MP_TAC THENL
     [SIMP_TAC[INTERVAL_NE_EMPTY; LAMBDA_BETA] THEN
      ASM_MESON_TAC[REAL_LT_IMP_LE; REAL_LE_REFL];
      ALL_TAC] THEN
    SIMP_TAC[content] THEN
    SIMP_TAC[INTERVAL_NE_EMPTY; INTERVAL_UPPERBOUND; INTERVAL_LOWERBOUND] THEN
    STRIP_TAC THEN
    SUBGOAL_THEN
     `1..dimindex(:M) = i INSERT ((1..dimindex(:M)) DELETE i)`
    SUBST1_TAC THENL
     [MATCH_MP_TAC(SET_RULE `x IN s ==> s = x INSERT (s DELETE x)`) THEN
      ASM_REWRITE_TAC[IN_NUMSEG];
      ALL_TAC] THEN
    SIMP_TAC[PRODUCT_CLAUSES; FINITE_NUMSEG; FINITE_DELETE] THEN
    ASM_SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA] THEN
    CONJ_TAC THEN MATCH_MP_TAC(REAL_FIELD
     `y < x /\ z < w /\ a = b
      ==> ((x - y) * a) / (x - y) = ((w - z) * b) / (w - z)`) THEN
    ASM_SIMP_TAC[] THEN MATCH_MP_TAC PRODUCT_EQ THEN
    SIMP_TAC[IN_DELETE; IN_NUMSEG; LAMBDA_BETA]]);;  
let BOUNDED_EQUIINTEGRAL_OVER_THIN_TAGGED_PARTIAL_DIVISION = prove
 (`!fs f:real^M->real^N a b e.
    fs 
equiintegrable_on interval[a,b] /\ f 
IN fs /\
    (!h x. h 
IN fs /\ x 
IN interval[a,b] ==> 
norm(h x) <= 
norm(f x)) /\
    &0 < e
    ==> ?d. 
gauge d /\
            !c i p h. c 
IN interval[a,b] /\ 1 <= i /\ i <= 
dimindex(:M) /\
                      p 
tagged_partial_division_of interval[a,b] /\
                      d 
fine p /\
                      h 
IN fs /\
                      (!x k. (x,k) 
IN p ==> ~(k 
INTER {x | x$i = c$i} = {}))
                      ==> 
sum p(\(x,k). 
norm(
integral k h)) < e`,
  REPEAT STRIP_TAC THEN
  ASM_CASES_TAC `
content(
interval[a:real^M,b]) = &0` THENL
   [EXISTS_TAC `\x:real^M. 
ball(x,&1)` THEN REWRITE_TAC[
GAUGE_TRIVIAL] THEN
    REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REAL_ARITH
     `&0 < e ==> x = &0 ==> x < e`)) THEN
    MATCH_MP_TAC 
SUM_EQ_0 THEN REWRITE_TAC[
FORALL_PAIR_THM] THEN
    GEN_TAC THEN X_GEN_TAC `k:real^M->bool` THEN DISCH_TAC THEN
    SUBGOAL_THEN
     `?u v:real^M. k = 
interval[u,v] /\ 
interval[u,v] 
SUBSET interval[a,b]`
    STRIP_ASSUME_TAC THENL
     [ASM_MESON_TAC[
tagged_partial_division_of]; ALL_TAC] THEN
    ASM_REWRITE_TAC[
NORM_EQ_0] THEN MATCH_MP_TAC 
INTEGRAL_NULL THEN
    ASM_MESON_TAC[
CONTENT_0_SUBSET];
    ALL_TAC] THEN
  FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM 
CONTENT_LT_NZ]) THEN
  DISCH_THEN(fun 
th -> ASSUME_TAC 
th THEN MP_TAC 
th) THEN
  REWRITE_TAC[
CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
  SUBGOAL_THEN
   `?d. 
gauge d /\
        !p h. p 
tagged_partial_division_of interval [a,b] /\
              d 
fine p /\ (h:real^M->real^N) 
IN fs
              ==> 
sum p (\(x,k). 
norm(
content k % h x - 
integral k h)) <
                  e / &2`
   (X_CHOOSE_THEN `g0:real^M->real^M->bool` STRIP_ASSUME_TAC)
  THENL
   [FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [
equiintegrable_on]) THEN
    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (MP_TAC o SPEC
      `e / &5 / (&(
dimindex(:N)) + &1)`)) THEN
    ASM_SIMP_TAC[
REAL_LT_DIV; REAL_ARITH `&0 < &5 /\ &0 < &n + &1`] THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `g:real^M->real^M->bool` THEN
    STRIP_TAC THEN ASM_REWRITE_TAC[] THEN MAP_EVERY X_GEN_TAC
     [`p:(real^M#(real^M->bool))->bool`; `h:real^M->real^N`] THEN
    STRIP_TAC THEN
    MP_TAC(ISPECL [`h:real^M->real^N`; `a:real^M`; `b:real^M`;
           `g:real^M->real^M->bool`; `e / &5 / (&(
dimindex(:N)) + &1)`]
        
HENSTOCK_LEMMA_PART2) THEN
    ASM_SIMP_TAC[
REAL_LT_DIV; REAL_ARITH `&0 < &5 /\ &0 < &n + &1`] THEN
    DISCH_THEN(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN
    ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
     `a < b ==> x <= a ==> x < b`) THEN
    REWRITE_TAC[REAL_ARITH `&2 * d * e / &5 / (d + &1) =
                            (e * &2 / &5 * d) / (d + &1)`] THEN
    SIMP_TAC[
REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
    MATCH_MP_TAC(REAL_ARITH
     `&0 < e /\ &0 < e * d ==> e * &2 / &5 * d < e / &2 * (d + &1)`) THEN
    ASM_REWRITE_TAC[] THEN MATCH_MP_TAC 
REAL_LT_MUL THEN
    ASM_SIMP_TAC[
REAL_OF_NUM_LT; 
LE_1; 
DIMINDEX_GE_1];
    ALL_TAC] THEN
  ABBREV_TAC
   `g:real^M->real^M->bool =
       \x. g0(x) 
INTER
           ball(x,(e / &8 / (
norm(f x:real^N) + &1)) *
                  
inf(
IMAGE (\m. b$m - a$m) (1..dimindex(:M))) /
                  
content(
interval[a:real^M,b]))` THEN
  SUBGOAL_THEN `
gauge(g:real^M->real^M->bool)` ASSUME_TAC THENL
   [EXPAND_TAC "g" THEN MATCH_MP_TAC 
GAUGE_INTER THEN ASM_REWRITE_TAC[] THEN
    REWRITE_TAC[
gauge; 
OPEN_BALL; 
CENTRE_IN_BALL] THEN
    X_GEN_TAC `x:real^M` THEN MATCH_MP_TAC 
REAL_LT_MUL THEN
    ASM_SIMP_TAC[
REAL_LT_DIV; NORM_ARITH
     `&0 < &8 /\ &0 < 
norm(x:real^N) + &1`] THEN
    MATCH_MP_TAC 
REAL_LT_DIV THEN ASM_REWRITE_TAC[] THEN
    W(MP_TAC o PART_MATCH (lhand o rand) 
REAL_LT_INF_FINITE o snd) THEN
    ANTS_TAC THENL
     [ASM_SIMP_TAC[
FINITE_IMAGE; 
FINITE_NUMSEG; 
FINITE_RESTRICT] THEN
      SIMP_TAC[
IMAGE_EQ_EMPTY; 
NUMSEG_EMPTY;
               GSYM 
NOT_LE; 
DIMINDEX_GE_1] THEN
      FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [
CART_EQ]) THEN
      REWRITE_TAC[
EXTENSION; 
IN_ELIM_THM; 
NOT_IN_EMPTY; 
IN_NUMSEG] THEN
      MESON_TAC[];
      DISCH_THEN SUBST1_TAC THEN
      REWRITE_TAC[
FORALL_IN_IMAGE] THEN
      ASM_SIMP_TAC[
REAL_SUB_LT; 
IN_NUMSEG; GSYM 
REAL_ABS_NZ; 
REAL_SUB_0;
                   
IN_ELIM_THM]];
    ALL_TAC] THEN
  EXISTS_TAC `g:real^M->real^M->bool` THEN ASM_REWRITE_TAC[] THEN
  MAP_EVERY X_GEN_TAC
   [`c:real^M`; `i:num`; `p:(real^M#(real^M->bool))->bool`;
    `h:real^M->real^N`] THEN
  STRIP_TAC THEN
  SUBGOAL_THEN
   `
interval[c:real^M,b] 
SUBSET interval[a,b]`
  ASSUME_TAC THENL
   [UNDISCH_TAC `c 
IN interval[a:real^M,b]` THEN
    SIMP_TAC[
IN_INTERVAL; 
SUBSET_INTERVAL; 
REAL_LE_REFL];
    ALL_TAC] THEN
  SUBGOAL_THEN `FINITE(p:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
   [ASM_MESON_TAC[
tagged_partial_division_of]; ALL_TAC] THEN
  MP_TAC(ASSUME `(g:real^M->real^M->bool) 
fine p`) THEN
  EXPAND_TAC "g" THEN REWRITE_TAC[
FINE_INTER] THEN
  DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC (LABEL_TAC "F")) THEN
  FIRST_X_ASSUM(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN
  DISCH_THEN(MP_TAC o SPEC `h:real^M->real^N`) THEN
  ANTS_TAC THENL
   [ASM_MESON_TAC[
TAGGED_PARTIAL_DIVISION_OF_SUBSET]; ALL_TAC] THEN
  MATCH_MP_TAC(REAL_ARITH
   `x - y <= e / &2 ==> y < e / &2 ==> x < e`) THEN
  ASM_SIMP_TAC[GSYM 
SUM_SUB] THEN
  ONCE_REWRITE_TAC[
LAMBDA_PAIR_THM] THEN REWRITE_TAC[] THEN
  MATCH_MP_TAC 
REAL_LE_TRANS THEN
  EXISTS_TAC
   `
sum p (\(x:real^M,k:real^M->bool). 
norm(
content k % h x:real^N))` THEN
  CONJ_TAC THENL
   [MATCH_MP_TAC 
SUM_LE THEN ASM_REWRITE_TAC[
FORALL_PAIR_THM] THEN
    REWRITE_TAC[NORM_ARITH `
norm y - 
norm(x - y:real^N) <= 
norm x`];
    ALL_TAC] THEN
  MATCH_MP_TAC 
REAL_LE_TRANS THEN
  EXISTS_TAC
   `
sum p (\(x:real^M,k).
                   e / &4 * (b$i - a$i) / 
content(
interval[a:real^M,b]) *
                   
content(k:real^M->bool) /
                   (
interval_upperbound k$i - 
interval_lowerbound k$i))` THEN
  CONJ_TAC THENL
   [MATCH_MP_TAC 
SUM_LE THEN ASM_REWRITE_TAC[
FORALL_PAIR_THM] THEN
    MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
    ASM_CASES_TAC `
content(k:real^M->bool) = &0` THENL
     [ASM_REWRITE_TAC[
real_div; 
REAL_MUL_LZERO; 
VECTOR_MUL_LZERO; 
NORM_0;
                      
REAL_MUL_RZERO; 
REAL_LE_REFL];
      ALL_TAC] THEN
    REWRITE_TAC[REAL_ARITH `a * b * 
content k / d = 
content k * (a * b) / d`;
                
NORM_MUL] THEN
    SUBGOAL_THEN `&0 < 
content(k:real^M->bool)` ASSUME_TAC THENL
     [ASM_MESON_TAC[
CONTENT_LT_NZ; 
tagged_partial_division_of]; ALL_TAC] THEN
    ASM_SIMP_TAC[
real_abs; 
REAL_LT_IMP_LE; 
REAL_LE_LMUL_EQ] THEN
    MATCH_MP_TAC(REAL_ARITH `x + &1 <= y ==> x <= y`) THEN
    SUBGOAL_THEN `?u v. k = 
interval[u:real^M,v]` MP_TAC THENL
     [ASM_MESON_TAC[
tagged_partial_division_of]; ALL_TAC] THEN
    DISCH_THEN(REPEAT_TCL CHOOSE_THEN SUBST_ALL_TAC) THEN
    MP_TAC(ISPECL [`u:real^M`; `v:real^M`] 
CONTENT_POS_LT_EQ) THEN
    ASM_SIMP_TAC[
INTERVAL_UPPERBOUND; 
INTERVAL_LOWERBOUND; 
REAL_LT_IMP_LE] THEN
    DISCH_TAC THEN
    W(MP_TAC o PART_MATCH (lhand o rand) 
REAL_LE_RDIV_EQ o snd) THEN
    ASM_SIMP_TAC[
REAL_SUB_LT] THEN DISCH_THEN SUBST1_TAC THEN
    GEN_REWRITE_TAC LAND_CONV [REAL_MUL_SYM] THEN
    SIMP_TAC[GSYM 
REAL_LE_RDIV_EQ; NORM_ARITH `&0 < 
norm(x:real^N) + &1`] THEN
    REMOVE_THEN "F" MP_TAC THEN REWRITE_TAC[
fine] THEN
    DISCH_THEN(MP_TAC o SPECL [`x:real^M`; `
interval[u:real^M,v]`]) THEN
    ASM_REWRITE_TAC[
SUBSET] THEN
    DISCH_THEN(fun 
th -> MP_TAC(SPEC `v:real^M` 
th) THEN
                         MP_TAC(SPEC `u:real^M` 
th)) THEN
    ASM_SIMP_TAC[
INTERVAL_NE_EMPTY; 
REAL_LT_IMP_LE; 
ENDS_IN_INTERVAL] THEN
    REWRITE_TAC[
IN_BALL; IMP_IMP] THEN
    MATCH_MP_TAC(NORM_ARITH
     `abs(vi - ui) <= 
norm(v - u:real^N) /\ &2 * a <= b
      ==> 
dist(x,u) < a /\ 
dist(x,v) < a ==> vi - ui <= b`) THEN
    ASM_SIMP_TAC[GSYM 
VECTOR_SUB_COMPONENT; 
COMPONENT_LE_NORM] THEN
    REWRITE_TAC[REAL_ARITH `&2 * e / &8 / x * y = e / &4 * y / x`] THEN
    REWRITE_TAC[
real_div; GSYM REAL_MUL_ASSOC] THEN
    MATCH_MP_TAC 
REAL_LE_LMUL THEN ASM_SIMP_TAC[
REAL_LT_IMP_LE] THEN
    MATCH_MP_TAC 
REAL_LE_LMUL THEN CONV_TAC REAL_RAT_REDUCE_CONV THEN
    ONCE_REWRITE_TAC[REAL_ARITH `a * inv b * inv c:real = (a / c) / b`] THEN
    ASM_SIMP_TAC[
REAL_LE_DIV2_EQ] THEN
    MATCH_MP_TAC(REAL_ARITH `abs x <= e ==> x <= e`) THEN
    REWRITE_TAC[
real_div; 
REAL_ABS_MUL] THEN MATCH_MP_TAC 
REAL_LE_MUL2 THEN
    REWRITE_TAC[
REAL_ABS_POS] THEN CONJ_TAC THENL
     [MATCH_MP_TAC(REAL_ARITH `&0 <= x /\ x <= y ==> abs x <= y`) THEN
      SIMP_TAC[
REAL_INF_LE_FINITE; 
FINITE_IMAGE; 
IMAGE_EQ_EMPTY; 
FINITE_NUMSEG;
               
NUMSEG_EMPTY; 
NOT_LT; 
DIMINDEX_GE_1; 
REAL_LE_INF_FINITE] THEN
      REWRITE_TAC[
FORALL_IN_IMAGE; 
EXISTS_IN_IMAGE; 
IN_NUMSEG] THEN
      ASM_SIMP_TAC[
VECTOR_SUB_COMPONENT; 
REAL_LE_REFL; 
REAL_SUB_LE;
                   
REAL_LT_IMP_LE] THEN
      ASM_MESON_TAC[
REAL_LE_REFL];
      REWRITE_TAC[
REAL_ABS_INV] THEN MATCH_MP_TAC 
REAL_LE_INV2 THEN
      CONJ_TAC THENL [NORM_ARITH_TAC; ALL_TAC] THEN
      MATCH_MP_TAC(REAL_ARITH `x <= y ==> x + &1 <= abs(y + &1)`) THEN
      FIRST_X_ASSUM MATCH_MP_TAC THEN
      ASM_MESON_TAC[
tagged_partial_division_of; 
SUBSET]];
    ALL_TAC] THEN
  FIRST_ASSUM(MP_TAC o MATCH_MP 
TAGGED_PARTIAL_DIVISION_OF_UNION_SELF) THEN
  DISCH_THEN(MP_TAC o MATCH_MP (REWRITE_RULE[
IMP_CONJ]
    
SUM_OVER_TAGGED_DIVISION_LEMMA)) THEN
  DISCH_THEN(fun 
th ->
    W(MP_TAC o PART_MATCH (lhs o rand) 
th o lhand o snd)) THEN
  REWRITE_TAC[] THEN ANTS_TAC THENL
   [SIMP_TAC[
real_div; 
REAL_MUL_LZERO; 
REAL_MUL_RZERO];
    DISCH_THEN SUBST1_TAC] THEN
  REWRITE_TAC[
SUM_LMUL; REAL_ARITH
   `e / &4 * ba / c * s <= e / &2 <=> e * (ba * s) / c <= e * &2`] THEN
  ASM_SIMP_TAC[
REAL_LE_LMUL_EQ] THEN ASM_SIMP_TAC[
REAL_LE_LDIV_EQ] THEN
  MATCH_MP_TAC 
SUM_CONTENT_AREA_OVER_THIN_DIVISION THEN
  EXISTS_TAC `
UNIONS(
IMAGE SND (p:(real^M#(real^M->bool))->bool))` THEN
  EXISTS_TAC `(c:real^M)$i` THEN
  RULE_ASSUM_TAC(REWRITE_RULE[
IN_INTERVAL]) THEN ASM_SIMP_TAC[] THEN
  REPEAT CONJ_TAC THENL
   [MATCH_MP_TAC 
DIVISION_OF_TAGGED_DIVISION THEN
    ASM_MESON_TAC[
TAGGED_PARTIAL_DIVISION_OF_UNION_SELF];
    REWRITE_TAC[
UNIONS_SUBSET; 
FORALL_IN_IMAGE; 
FORALL_PAIR_THM] THEN
    ASM_MESON_TAC[
tagged_partial_division_of];
    ASM_REWRITE_TAC[
FORALL_IN_IMAGE; 
FORALL_PAIR_THM]]);;
 
let EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_LE = prove
 (`!fs f:real^M->real^N a b.
        fs 
equiintegrable_on interval[a,b] /\ f 
IN fs /\
        (!h x. h 
IN fs /\ x 
IN interval[a,b] ==> 
norm(h x) <= 
norm(f x))
        ==> { (\x. if x$i <= c then h x else 
vec 0) |
              i 
IN 1..dimindex(:M) /\ c 
IN (:real) /\ h 
IN fs }
            
equiintegrable_on interval[a,b]`,
  let lemma = prove
   (`(!x k. (x,k) IN IMAGE (\(x,k). f x k,g x k) s ==> Q x k) <=>
     (!x k. (x,k) IN s ==> Q (f x k) (g x k))`,
    REWRITE_TAC[IN_IMAGE; PAIR_EQ; EXISTS_PAIR_THM] THEN SET_TAC[]) in
  REPEAT STRIP_TAC THEN
  ASM_CASES_TAC `content(interval[a:real^M,b]) = &0` THEN
  ASM_SIMP_TAC[EQUIINTEGRABLE_ON_NULL] THEN
  FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM CONTENT_LT_NZ]) THEN
  DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
  REWRITE_TAC[CONTENT_POS_LT_EQ] THEN STRIP_TAC THEN
  REWRITE_TAC[equiintegrable_on] THEN
  REWRITE_TAC[IMP_CONJ; RIGHT_FORALL_IMP_THM; FORALL_IN_GSPEC] THEN
  REWRITE_TAC[IN_UNIV; IMP_IMP; GSYM CONJ_ASSOC; RIGHT_IMP_FORALL_THM;
              IN_NUMSEG] THEN
  FIRST_ASSUM(ASSUME_TAC o CONJUNCT1 o REWRITE_RULE[equiintegrable_on]) THEN
  MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
   [REPEAT GEN_TAC THEN
    ONCE_REWRITE_TAC[SET_RULE `x$i <= c <=> x IN {x:real^N | x$i <= c}`] THEN
    REWRITE_TAC[INTEGRABLE_RESTRICT_INTER] THEN
    ONCE_REWRITE_TAC[INTER_COMM] THEN SIMP_TAC[INTERVAL_SPLIT] THEN
    REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_ON_SUBINTERVAL THEN
    EXISTS_TAC `interval[a:real^M,b]` THEN ASM_SIMP_TAC[] THEN
    SIMP_TAC[SUBSET_INTERVAL; LAMBDA_BETA; REAL_LE_REFL] THEN
    REPEAT STRIP_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
    REAL_ARITH_TAC;
    DISCH_TAC] THEN
  X_GEN_TAC `e:real` THEN DISCH_TAC THEN
  MP_TAC(ISPECL [`fs:(real^M->real^N)->bool`; `f:real^M->real^N`;
                 `a:real^M`; `b:real^M`; `e / &12`]
        BOUNDED_EQUIINTEGRAL_OVER_THIN_TAGGED_PARTIAL_DIVISION) THEN
  ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &12`] THEN
  DISCH_THEN(X_CHOOSE_THEN `g0:real^M->real^M->bool` STRIP_ASSUME_TAC) THEN
  SUBGOAL_THEN
   `?d. gauge d /\
        !p h. p tagged_partial_division_of interval [a,b] /\
              d fine p /\ (h:real^M->real^N) IN fs
              ==> sum p (\(x,k). norm(content k % h x - integral k h)) <
                  e / &3`
   (X_CHOOSE_THEN `g1:real^M->real^M->bool` STRIP_ASSUME_TAC)
  THENL
   [FIRST_ASSUM(MP_TAC o CONJUNCT2 o REWRITE_RULE[equiintegrable_on]) THEN
    DISCH_THEN(MP_TAC o SPEC `e / &7 / (&(dimindex(:N)) + &1)`) THEN
    ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &7 /\ &0 < &n + &1`] THEN
    MATCH_MP_TAC MONO_EXISTS THEN
    X_GEN_TAC `d:real^M->real^M->bool` THEN STRIP_TAC THEN
    ASM_REWRITE_TAC[] THEN
    MAP_EVERY X_GEN_TAC
     [`p:(real^M#(real^M->bool))->bool`; `h:real^M->real^N`] THEN
    STRIP_TAC THEN
    MP_TAC(ISPECL [`h:real^M->real^N`; `a:real^M`; `b:real^M`;
           `d:real^M->real^M->bool`; `e / &7 / (&(dimindex(:N)) + &1)`]
        HENSTOCK_LEMMA_PART2) THEN
    ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &7 /\ &0 < &n + &1`] THEN
    DISCH_THEN(MP_TAC o SPEC `p:(real^M#(real^M->bool))->bool`) THEN
    ASM_REWRITE_TAC[] THEN MATCH_MP_TAC(REAL_ARITH
     `a < b ==> x <= a ==> x < b`) THEN
    REWRITE_TAC[REAL_ARITH `&2 * d * e / &7 / (d + &1) =
                            (e * &2 / &7 * d) / (d + &1)`] THEN
    SIMP_TAC[REAL_LT_LDIV_EQ; REAL_ARITH `&0 < &n + &1`] THEN
    MATCH_MP_TAC(REAL_ARITH
     `&0 < e /\ &0 < e * d ==> e * &2 / &7 * d < e / &3 * (d + &1)`) THEN
    ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LT_MUL THEN
    ASM_SIMP_TAC[REAL_OF_NUM_LT; LE_1; DIMINDEX_GE_1];
    ALL_TAC] THEN
  EXISTS_TAC `\x. (g0:real^M->real^M->bool) x INTER g1 x` THEN
  ASM_SIMP_TAC[GAUGE_INTER; FINE_INTER] THEN
  X_GEN_TAC `i:num` THEN
  ASM_CASES_TAC `1 <= i` THEN ASM_REWRITE_TAC[] THEN
  ASM_CASES_TAC `i <= dimindex(:M)` THEN ASM_REWRITE_TAC[] THEN
  MP_TAC(MESON[]
   `!P. ((!c. (a:real^M)$i <= c /\ c <= (b:real^M)$i ==> P c) ==> (!c. P c)) /\
        (!c. (a:real^M)$i <= c /\ c <= (b:real^M)$i ==> P c)
        ==> !c. P c`) THEN
  DISCH_THEN MATCH_MP_TAC THEN CONJ_TAC THENL
   [DISCH_THEN(LABEL_TAC "*") THEN
    X_GEN_TAC `c:real` THEN
    ASM_CASES_TAC `(a:real^M)$i <= c /\ c <= (b:real^M)$i` THENL
     [REMOVE_THEN "*" MATCH_MP_TAC THEN ASM_REWRITE_TAC[]; ALL_TAC] THEN
    REMOVE_THEN "*" (MP_TAC o SPEC `(b:real^M)$i`) THEN
    ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_LE_REFL] THEN
    MATCH_MP_TAC MONO_FORALL THEN X_GEN_TAC `h:real^M->real^N` THEN
    MATCH_MP_TAC MONO_FORALL THEN
    X_GEN_TAC `p:real^M#(real^M->bool)->bool` THEN
    DISCH_THEN(fun th -> STRIP_TAC THEN MP_TAC th) THEN ASM_REWRITE_TAC[] THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [DE_MORGAN_THM]) THEN
    REWRITE_TAC[REAL_NOT_LE] THEN STRIP_TAC THENL
     [DISCH_TAC THEN MATCH_MP_TAC(NORM_ARITH
       `x:real^N = vec 0 /\ y = vec 0 /\ &0 < e ==> norm(x - y) < e`) THEN
      ASM_REWRITE_TAC[] THEN CONJ_TAC THENL
       [MATCH_MP_TAC VSUM_EQ_0 THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
        MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
        COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN
        SUBGOAL_THEN `(x:real^M) IN interval[a,b]` MP_TAC THENL
         [ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET]; ALL_TAC] THEN
        REWRITE_TAC[IN_INTERVAL] THEN
        DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
        ASM_REAL_ARITH_TAC;
        MATCH_MP_TAC EQ_TRANS THEN
        EXISTS_TAC `integral(interval[a,b]) ((\x. vec 0):real^M->real^N)` THEN
        CONJ_TAC THENL [ALL_TAC; REWRITE_TAC[INTEGRAL_0]] THEN
        MATCH_MP_TAC INTEGRAL_EQ THEN REWRITE_TAC[] THEN GEN_TAC THEN
        COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL] THEN
        DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
        ASM_REAL_ARITH_TAC];
      MATCH_MP_TAC(NORM_ARITH
       `x:real^N = y /\ w = z ==> norm(x - w) < e ==> norm(y - z) < e`) THEN
      CONJ_TAC THENL
       [MATCH_MP_TAC VSUM_EQ THEN REWRITE_TAC[FORALL_PAIR_THM] THEN
        MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN DISCH_TAC THEN
        SUBGOAL_THEN `(x:real^M) IN interval[a,b]` MP_TAC THENL
         [ASM_MESON_TAC[TAGGED_DIVISION_OF; SUBSET]; ALL_TAC] THEN
        REWRITE_TAC[IN_INTERVAL] THEN
        DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
        STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
        COND_CASES_TAC THEN ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN
        ASM_REAL_ARITH_TAC;
        MATCH_MP_TAC INTEGRAL_EQ THEN REWRITE_TAC[] THEN GEN_TAC THEN
        COND_CASES_TAC THEN ASM_REWRITE_TAC[IN_INTERVAL] THEN
        DISCH_THEN(MP_TAC o SPEC `i:num`) THEN ASM_REWRITE_TAC[] THEN
        ASM_REAL_ARITH_TAC]];
    ALL_TAC] THEN
  X_GEN_TAC `c:real` THEN DISCH_TAC THEN
  MAP_EVERY X_GEN_TAC [`h:real^M->real^N`;
                  `p:(real^M#(real^M->bool))->bool`] THEN STRIP_TAC THEN
  ABBREV_TAC
   `q:(real^M#(real^M->bool))->bool =
        {(x,k) | (x,k) IN p /\ ~(k INTER {x | x$i <= c} = {})}` THEN
  MP_TAC(ISPECL
   [`\x. if x$i <= c then (h:real^M->real^N) x else vec 0`;
    `a:real^M`; `b:real^M`; `p:(real^M#(real^M->bool))->bool`]
        INTEGRAL_COMBINE_TAGGED_DIVISION_TOPDOWN) THEN
  ASM_SIMP_TAC[] THEN DISCH_THEN SUBST1_TAC THEN
  SUBGOAL_THEN `FINITE(p:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
   [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
  SUBGOAL_THEN `q SUBSET (p:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
   [EXPAND_TAC "q" THEN SIMP_TAC[SUBSET; FORALL_PAIR_THM; IN_ELIM_PAIR_THM];
    ALL_TAC] THEN
  SUBGOAL_THEN `FINITE(q:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
   [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN
  ASM_SIMP_TAC[GSYM VSUM_SUB] THEN ONCE_REWRITE_TAC[LAMBDA_PAIR_THM] THEN
  REWRITE_TAC[] THEN
  SUBGOAL_THEN `q tagged_partial_division_of interval[a:real^M,b] /\
                g0 fine q /\ g1 fine q`
  STRIP_ASSUME_TAC THENL
   [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_SUBSET; tagged_division_of;
                  FINE_SUBSET];
    ALL_TAC] THEN
  MATCH_MP_TAC(MESON[] `!q. vsum p s = vsum q s /\ norm(vsum q s) < e
                            ==> norm(vsum p s:real^N) < e`) THEN
  EXISTS_TAC `q:(real^M#(real^M->bool))->bool` THEN CONJ_TAC THENL
   [MATCH_MP_TAC VSUM_SUPERSET THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
    EXPAND_TAC "q" THEN REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
    MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
    SUBGOAL_THEN `(x:real^M) IN k` ASSUME_TAC THENL
     [ASM_MESON_TAC[TAGGED_DIVISION_OF]; ALL_TAC] THEN
    DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
    REWRITE_TAC[EXTENSION] THEN DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN
    REWRITE_TAC[IN_INTER; NOT_IN_EMPTY] THEN ASM_REWRITE_TAC[] THEN
    REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN
    ASM_REWRITE_TAC[VECTOR_MUL_RZERO] THEN
    REWRITE_TAC[VECTOR_NEG_EQ_0; VECTOR_SUB_LZERO] THEN
    MATCH_MP_TAC EQ_TRANS THEN
    EXISTS_TAC `integral k ((\x. vec 0):real^M->real^N)` THEN
    CONJ_TAC THENL [ALL_TAC; REWRITE_TAC[INTEGRAL_0]] THEN
    MATCH_MP_TAC INTEGRAL_EQ THEN ASM SET_TAC[];
    ALL_TAC] THEN
  SUBGOAL_THEN
   `norm(vsum q (\(x,k). content k % h x - integral k (h:real^M->real^N)))
        < e / &3`
  MP_TAC THENL
   [MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `sum q
      (\(x,k). norm(content k % h x - integral k (h:real^M->real^N)))` THEN
    ASM_SIMP_TAC[] THEN MATCH_MP_TAC VSUM_NORM_LE THEN
    ASM_REWRITE_TAC[FORALL_PAIR_THM; REAL_LE_REFL];
    ALL_TAC] THEN
  MATCH_MP_TAC(NORM_ARITH
   `norm(x - y:real^N) <= &2 * e / &3
    ==> norm(x) < e / &3 ==> norm(y) < e`) THEN
  ASM_SIMP_TAC[GSYM VSUM_SUB] THEN ONCE_REWRITE_TAC[LAMBDA_PAIR_THM] THEN
  REWRITE_TAC[] THEN
  ABBREV_TAC
   `r:(real^M#(real^M->bool))->bool =
        {(x,k) | (x,k) IN q /\ ~(k SUBSET {x | x$i <= c})}` THEN
  SUBGOAL_THEN `r SUBSET (q:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
   [EXPAND_TAC "r" THEN SIMP_TAC[SUBSET; FORALL_PAIR_THM; IN_ELIM_PAIR_THM];
    ALL_TAC] THEN
  SUBGOAL_THEN `FINITE(r:(real^M#(real^M->bool))->bool)` ASSUME_TAC THENL
   [ASM_MESON_TAC[FINITE_SUBSET]; ALL_TAC] THEN
  SUBGOAL_THEN `r tagged_partial_division_of interval[a:real^M,b] /\
                g0 fine r /\ g1 fine r`
  STRIP_ASSUME_TAC THENL
   [ASM_MESON_TAC[TAGGED_PARTIAL_DIVISION_SUBSET; FINE_SUBSET];
    ALL_TAC] THEN
  MATCH_MP_TAC(MESON[] `!r. vsum q s = vsum r s /\ norm(vsum r s) <= e
                            ==> norm(vsum q s:real^N) <= e`) THEN
  EXISTS_TAC `r:(real^M#(real^M->bool))->bool` THEN CONJ_TAC THENL
   [MATCH_MP_TAC VSUM_SUPERSET THEN ASM_REWRITE_TAC[FORALL_PAIR_THM] THEN
    EXPAND_TAC "r" THEN REWRITE_TAC[IN_ELIM_PAIR_THM] THEN
    MAP_EVERY X_GEN_TAC [`x:real^M`; `k:real^M->bool`] THEN
    DISCH_THEN(CONJUNCTS_THEN2 ASSUME_TAC MP_TAC) THEN ASM_REWRITE_TAC[] THEN
    SUBGOAL_THEN `(x:real^M) IN k` ASSUME_TAC THENL
     [ASM_MESON_TAC[tagged_partial_division_of]; ALL_TAC] THEN
    DISCH_THEN(fun th -> ASSUME_TAC th THEN MP_TAC th) THEN
    REWRITE_TAC[SUBSET] THEN DISCH_THEN(MP_TAC o SPEC `x:real^M`) THEN
    ASM_REWRITE_TAC[IN_ELIM_THM] THEN DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
    REWRITE_TAC[VECTOR_ARITH `c - i - (c - j):real^N = j - i`] THEN
    REWRITE_TAC[VECTOR_SUB_EQ] THEN MATCH_MP_TAC INTEGRAL_EQ THEN
    ASM SET_TAC[];
    ALL_TAC] THEN
  W(MP_TAC o PART_MATCH (lhand o rand) VSUM_NORM o lhand o snd) THEN
  ASM_REWRITE_TAC[] THEN
  MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] REAL_LE_TRANS) THEN
  ONCE_REWRITE_TAC[LAMBDA_PAIR_THM] THEN REWRITE_TAC[] THEN
  MAP_EVERY ABBREV_TAC
   [`s:(real^M#(real^M->bool))->bool =
        {(x,k) | (x,k) IN r /\ x IN {x | x$i <= c}}`;
    `t:(real^M#(real^M->bool))->bool =
        {(x,k) | (x,k) IN r /\ ~(x IN {x | x$i <= c})}`] THEN
  SUBGOAL_THEN
   `(s:(real^M#(real^M->bool))->bool) SUBSET r /\
    (t:(real^M#(real^M->bool))->bool) SUBSET r`
  STRIP_ASSUME_TAC THENL
   [MAP_EVERY EXPAND_TAC ["s";  
let INDEFINITE_INTEGRAL_CONTINUOUS = prove
 (`!f:real^M->real^N a b c d e.
        f 
integrable_on interval[a,b] /\
        c 
IN interval[a,b] /\ d 
IN interval[a,b] /\ &0 < e
        ==> ?k. &0 < k /\
                !c' d'. c' 
IN interval[a,b] /\
                        d' 
IN interval[a,b] /\
                        
norm(c' - c) <= k /\ 
norm(d' - d) <= k
                        ==> 
norm(
integral(
interval[c',d']) f -
                                 
integral(
interval[c,d]) f) < e`,
  REPEAT STRIP_TAC THEN
  ONCE_REWRITE_TAC[MESON[] `(?k. P k /\ Q k) <=> ~(!k. P k ==> ~Q k)`] THEN
  DISCH_THEN(MP_TAC o GEN `n:num` o SPEC `inv(&n + &1)`) THEN
  PURE_REWRITE_TAC[
NOT_FORALL_THM; NOT_IMP] THEN
  REWRITE_TAC[
REAL_LT_INV_EQ; REAL_ARITH `&0 < &n + &1`; 
SKOLEM_THM] THEN
  REWRITE_TAC[
NOT_EXISTS_THM; 
REAL_NOT_LT; GSYM 
CONJ_ASSOC] THEN
  MAP_EVERY X_GEN_TAC [`u:num->real^M`; `v:num->real^M`] THEN
  REWRITE_TAC[
FORALL_AND_THM] THEN STRIP_TAC THEN
  ABBREV_TAC
   `k:real^M->bool =
    
UNIONS (
IMAGE (\i. {x | x$i = (c:real^M)$i} 
UNION {x | x$i = (d:real^M)$i})
                  (1..dimindex(:M)))` THEN
  SUBGOAL_THEN `
negligible(k:real^M->bool)` ASSUME_TAC THENL
   [EXPAND_TAC "k" THEN MATCH_MP_TAC 
NEGLIGIBLE_UNIONS THEN
    SIMP_TAC[
FINITE_IMAGE; 
FINITE_NUMSEG; 
FORALL_IN_IMAGE] THEN
    X_GEN_TAC `i:num` THEN REWRITE_TAC[
IN_NUMSEG] THEN STRIP_TAC THEN
    ASM_SIMP_TAC[
NEGLIGIBLE_UNION; 
NEGLIGIBLE_STANDARD_HYPERPLANE];
    ALL_TAC] THEN
  MP_TAC(ISPECL
   [`\n:num x. if x 
IN interval[u n,v n] then
                 if x 
IN k then 
vec 0 else (f:real^M->real^N) x
               else 
vec 0`;
    `\x. if x 
IN interval[c,d] then
            if x 
IN k then 
vec 0 else (f:real^M->real^N) x
         else 
vec 0`;
    `a:real^M`; `b:real^M`] 
EQUIINTEGRABLE_LIMIT) THEN
  REWRITE_TAC[NOT_IMP] THEN REPEAT CONJ_TAC THENL
   [SUBGOAL_THEN
     `(\x. if x 
IN k then 
vec 0 else (f:real^M->real^N) x)
      
integrable_on interval[a,b]`
    MP_TAC THENL
     [UNDISCH_TAC `(f:real^M->real^N) 
integrable_on interval[a,b]` THEN
      MATCH_MP_TAC 
INTEGRABLE_SPIKE THEN EXISTS_TAC `k:real^M->bool` THEN
      ASM_REWRITE_TAC[] THEN SET_TAC[];
      ALL_TAC] THEN
    DISCH_THEN(MP_TAC o MATCH_MP
      
EQUIINTEGRABLE_CLOSED_INTERVAL_RESTRICTIONS) THEN
    MATCH_MP_TAC(REWRITE_RULE[
IMP_CONJ_ALT] 
EQUIINTEGRABLE_SUBSET) THEN
    REWRITE_TAC[
SUBSET; 
FORALL_IN_GSPEC; 
IN_UNIV] THEN
    REWRITE_TAC[
IN_ELIM_THM] THEN
    X_GEN_TAC `n:num` THEN MAP_EVERY EXISTS_TAC
     [`(u:num->real^M) n`; `(v:num->real^M) n`] THEN
    REWRITE_TAC[];
    X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
    ASM_CASES_TAC `(x:real^M) 
IN k` THEN
    ASM_REWRITE_TAC[
COND_ID; 
LIM_CONST] THEN MATCH_MP_TAC 
LIM_EVENTUALLY THEN
    REWRITE_TAC[
EVENTUALLY_SEQUENTIALLY] THEN
    MP_TAC(SPEC `
inf (
IMAGE (\i. min (abs((x:real^M)$i - (c:real^M)$i))
                                     (abs((x:real^M)$i - (d:real^M)$i)))
                            (1..dimindex(:M)))` 
REAL_ARCH_INV) THEN
    SIMP_TAC[
REAL_LT_INF_FINITE; 
FINITE_IMAGE; 
IMAGE_EQ_EMPTY;
             
FINITE_NUMSEG; 
NUMSEG_EMPTY; 
NOT_LT; 
DIMINDEX_GE_1] THEN
    ASM_SIMP_TAC[
FORALL_IN_IMAGE; 
REAL_LT_MIN; 
IN_NUMSEG] THEN
    UNDISCH_TAC `~((x:real^M) 
IN k)` THEN EXPAND_TAC "k" THEN
    REWRITE_TAC[
UNIONS_IMAGE; 
IN_ELIM_THM; 
NOT_EXISTS_THM] THEN
    REWRITE_TAC[
IN_NUMSEG; SET_RULE
     `~(p /\ x 
IN (s 
UNION t)) <=> p ==> ~(x 
IN s) /\ ~(x 
IN t)`] THEN
    REWRITE_TAC[
IN_ELIM_THM; REAL_ARITH `&0 < abs(x - y) <=> ~(x = y)`] THEN
    DISCH_TAC THEN ASM_REWRITE_TAC[] THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `N:num` THEN STRIP_TAC THEN
    X_GEN_TAC `n:num` THEN DISCH_TAC THEN
    SUBGOAL_THEN `x 
IN interval[(u:num->real^M) n,v n] <=> x 
IN interval[c,d]`
     (fun 
th -> REWRITE_TAC[
th]) THEN
    REWRITE_TAC[
IN_INTERVAL] THEN AP_TERM_TAC THEN
    GEN_REWRITE_TAC I [
FUN_EQ_THM] THEN X_GEN_TAC `i:num` THEN
    ASM_CASES_TAC `1 <= i /\ i <= 
dimindex(:M)` THEN ASM_REWRITE_TAC[] THEN
    MATCH_MP_TAC(REAL_ARITH
     `!N n. abs(u - c) <= n /\ abs(v - d) <= n /\
            N < abs(x - c) /\ N < abs(x - d) /\ n <= N
      ==> (u <= x /\ x <= v <=> c <= x /\ x <= d)`) THEN
    MAP_EVERY EXISTS_TAC [`inv(&N)`; `inv(&n + &1)`] THEN
    ASM_SIMP_TAC[] THEN REPEAT (CONJ_TAC THENL
     [ASM_MESON_TAC[
REAL_LE_TRANS; 
COMPONENT_LE_NORM; 
VECTOR_SUB_COMPONENT];
      ALL_TAC]) THEN
    MATCH_MP_TAC 
REAL_LE_INV2 THEN
    REWRITE_TAC[REAL_OF_NUM_ADD; REAL_OF_NUM_LE; 
REAL_OF_NUM_LT] THEN
    ASM_ARITH_TAC;
    DISCH_THEN(MP_TAC o CONJUNCT2) THEN
    REWRITE_TAC[
INTEGRAL_RESTRICT_INTER] THEN
    SUBGOAL_THEN
     `
interval[c:real^M,d] 
INTER interval[a,b] = 
interval[c,d] /\
      !n:num. 
interval[u n,v n] 
INTER interval[a,b] = 
interval[u n,v n]`
     (fun 
th -> SIMP_TAC[
th])
    THENL
     [REWRITE_TAC[SET_RULE `s 
INTER t = s <=> s 
SUBSET t`] THEN
      REWRITE_TAC[
SUBSET_INTERVAL] THEN
      RULE_ASSUM_TAC(REWRITE_RULE[
IN_INTERVAL]) THEN ASM_MESON_TAC[];
      ALL_TAC] THEN
    REWRITE_TAC[
LIM_SEQUENTIALLY] THEN
    DISCH_THEN(MP_TAC o SPEC `e:real`) THEN ASM_REWRITE_TAC[] THEN
    DISCH_THEN(X_CHOOSE_THEN `N:num` (MP_TAC o SPEC `N:num`)) THEN
    REWRITE_TAC[
LE_REFL; 
REAL_NOT_LT] THEN
    FIRST_ASSUM(fun 
th -> MP_TAC(SPEC `N:num` 
th) THEN MATCH_MP_TAC
    (NORM_ARITH `x = a /\ y = b ==> e <= 
norm(x - y) ==> e <= 
dist(a,b)`)) THEN
    CONJ_TAC THEN MATCH_MP_TAC 
INTEGRAL_SPIKE THEN
    EXISTS_TAC `k:real^M->bool` THEN ASM_SIMP_TAC[
IN_DIFF]]);;
 
let SECOND_MEAN_VALUE_THEOREM_FULL = prove
 (`!f:real^1->real^1 g a b.
        ~(
interval[a,b] = {}) /\
        f 
integrable_on interval [a,b] /\
        (!x y. x 
IN interval[a,b] /\ y 
IN interval[a,b] /\ 
drop x <= 
drop y
               ==> g x <= g y)
        ==> ?c. c 
IN interval [a,b] /\
                ((\x. g x % f x) 
has_integral
                 (g(a) % 
integral (
interval[a,c]) f +
                  g(b) % 
integral (
interval[c,b]) f)) (
interval[a,b])`,
  let lemma1 = prove
   (`!f:real->real s.
      (!x. x IN s ==> &0 <= f x /\ f x <= &1)
      ==> (!n x. x IN s /\ ~(n = 0)
                 ==> abs(f x -
                         sum(1..n) (\k. if &k / &n <= f(x)
                                        then inv(&n) else &0)) < inv(&n))`,
    REPEAT STRIP_TAC THEN
    SUBGOAL_THEN `?m. floor(&n * (f:real->real) x) = &m` CHOOSE_TAC THENL
     [MATCH_MP_TAC FLOOR_POS THEN ASM_SIMP_TAC[REAL_LE_MUL; REAL_POS];
      ALL_TAC] THEN
    SUBGOAL_THEN `!k. &k / &n <= (f:real->real) x <=> k <= m` ASSUME_TAC THENL
     [REWRITE_TAC[GSYM REAL_OF_NUM_LE] THEN
      FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN
      ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_OF_NUM_LT; LE_1] THEN
      SIMP_TAC[REAL_LE_FLOOR; INTEGER_CLOSED; REAL_MUL_SYM];
      ALL_TAC] THEN
    ASM_REWRITE_TAC[GSYM SUM_RESTRICT_SET] THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `n + 1`) THEN
    REWRITE_TAC[GSYM REAL_OF_NUM_ADD; real_div; REAL_ADD_RDISTRIB] THEN
    ASM_SIMP_TAC[REAL_MUL_RINV; REAL_MUL_LID; REAL_OF_NUM_EQ] THEN
    ASM_SIMP_TAC[REAL_ARITH `y <= &1 /\ &0 < i ==> ~(&1 + i <= y)`;
                 REAL_LT_INV_EQ; REAL_OF_NUM_LT; LE_1; NOT_LE] THEN
    SIMP_TAC[IN_NUMSEG; ARITH_RULE
     `m < n + 1 ==> ((1 <= k /\ k <= n) /\ k <= m <=> 1 <= k /\ k <= m)`] THEN
    DISCH_TAC THEN REWRITE_TAC[GSYM numseg; SUM_CONST_NUMSEG; ADD_SUB] THEN
    MATCH_MP_TAC REAL_LT_LCANCEL_IMP THEN EXISTS_TAC `abs(&n)` THEN
    REWRITE_TAC[GSYM REAL_ABS_MUL] THEN
    ASM_SIMP_TAC[REAL_ABS_NUM; REAL_MUL_RINV; REAL_OF_NUM_EQ] THEN
    ASM_SIMP_TAC[REAL_OF_NUM_LT; LE_1; REAL_SUB_LDISTRIB; GSYM real_div] THEN
    ASM_SIMP_TAC[REAL_DIV_LMUL; REAL_OF_NUM_EQ] THEN
    MATCH_MP_TAC(REAL_ARITH `f <= x /\ x < f + &1 ==> abs(x - f) < &1`) THEN
    FIRST_X_ASSUM(SUBST1_TAC o SYM) THEN REWRITE_TAC[FLOOR]) in
  let lemma2 = prove
   (`!f:real^1->real^N g a b.
          f integrable_on interval[a,b] /\
          (!x y. drop x <= drop y ==> g(x) <= g(y))
          ==> {(\x. if c <= g(x) then f x else vec 0) | c IN (:real)}
              equiintegrable_on interval[a,b]`,
    REPEAT STRIP_TAC THEN
    FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [GSYM EQUIINTEGRABLE_ON_SING]) THEN
    DISCH_THEN(fun th ->
     MP_TAC(SPEC `f:real^1->real^N` (MATCH_MP (REWRITE_RULE[IMP_CONJ]
       EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GE) th)) THEN
     MP_TAC(SPEC `f:real^1->real^N` (MATCH_MP (REWRITE_RULE[IMP_CONJ]
       EQUIINTEGRABLE_HALFSPACE_RESTRICTIONS_GT) th)) THEN
      MP_TAC th) THEN
    SIMP_TAC[IN_SING; REAL_LE_REFL] THEN
    SUBGOAL_THEN `{(\x. vec 0):real^1->real^N} equiintegrable_on interval[a,b]`
    MP_TAC THENL
     [REWRITE_TAC[EQUIINTEGRABLE_ON_SING; INTEGRABLE_CONST]; ALL_TAC] THEN
    REPEAT(ONCE_REWRITE_TAC[IMP_IMP] THEN
           DISCH_THEN(MP_TAC o MATCH_MP EQUIINTEGRABLE_UNION)) THEN
    REWRITE_TAC[NUMSEG_SING; DIMINDEX_1; IN_SING] THEN
    REWRITE_TAC[SET_RULE `{m i c h | i = 1 /\ c IN (:real) /\ h = f} =
                          {m 1 c f | c IN (:real)}`] THEN
    MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
    REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_UNIV] THEN
    X_GEN_TAC `y:real` THEN
    ASM_CASES_TAC `!x. y <= (g:real^1->real) x` THENL
     [ASM_REWRITE_TAC[ETA_AX; IN_UNION; IN_SING]; ALL_TAC] THEN
    ASM_CASES_TAC `!x. ~(y <= (g:real^1->real) x)` THENL
     [ASM_REWRITE_TAC[ETA_AX; IN_UNION; IN_SING]; ALL_TAC] THEN
    MP_TAC(ISPEC `IMAGE drop {x | y <= (g:real^1->real) x}` INF) THEN
    REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM; IMAGE_EQ_EMPTY] THEN
    ANTS_TAC THENL
     [ASM_REWRITE_TAC[EXTENSION; IN_ELIM_THM; NOT_IN_EMPTY] THEN
      ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL];
      STRIP_TAC THEN REWRITE_TAC[real_gt; real_ge]] THEN
    REWRITE_TAC[IN_UNION; GSYM DISJ_ASSOC] THEN
    ASM_CASES_TAC `y <= g(lift(inf(IMAGE drop {x | y <= g x})))` THENL
     [REPEAT DISJ2_TAC; REPLICATE_TAC 2 DISJ2_TAC THEN DISJ1_TAC] THEN
    REWRITE_TAC[IN_ELIM_THM] THEN
    EXISTS_TAC `inf(IMAGE drop {x | y <= g x})` THEN
    REWRITE_TAC[FUN_EQ_THM] THEN
    MATCH_MP_TAC(MESON[]
     `(!x. P x <=> Q x)
      ==> !x. (if P x then f x else b) = (if Q x then f x else b)`) THEN
    X_GEN_TAC `x:real^1` THEN REWRITE_TAC[GSYM REAL_NOT_LE; GSYM drop] THEN
    ASM_MESON_TAC[REAL_LE_TOTAL; REAL_LT_ANTISYM; REAL_LE_TRANS; LIFT_DROP]) in
  let lemma3 = prove
   (`!f:real^1->real^N g a b.
          f integrable_on interval[a,b] /\
          (!x y. drop x <= drop y ==> g(x) <= g(y))
          ==> {(\x. vsum (1..n)
                     (\k. if &k / &n <= g x then inv(&n) % f(x) else vec 0)) |
               ~(n = 0)}
              equiintegrable_on interval[a,b]`,
    REPEAT GEN_TAC THEN DISCH_THEN(MP_TAC o
     MATCH_MP lemma2) THEN
    DISCH_THEN(MP_TAC o MATCH_MP
     (INST_TYPE [`:num`,`:A`] EQUIINTEGRABLE_SUM)) THEN
    MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ_ALT] EQUIINTEGRABLE_SUBSET) THEN
    REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_UNIV] THEN X_GEN_TAC `n:num` THEN
    DISCH_TAC THEN REWRITE_TAC[IN_ELIM_THM] THEN
    MAP_EVERY EXISTS_TAC [`1..n`; `\k:num. inv(&n)`;
     `\k x. if &k / &n <= g x then (f:real^1->real^N) x else vec 0`] THEN
    ASM_SIMP_TAC[SUM_CONST_NUMSEG; ADD_SUB; REAL_MUL_RINV; REAL_OF_NUM_EQ] THEN
    REWRITE_TAC[FINITE_NUMSEG; COND_RAND; COND_RATOR; VECTOR_MUL_RZERO] THEN
    X_GEN_TAC `k:num` THEN
    REWRITE_TAC[IN_NUMSEG; REAL_LE_INV_EQ; REAL_POS] THEN STRIP_TAC THEN
    EXISTS_TAC `&k / &n` THEN REWRITE_TAC[]) in
  let lemma4 = prove
   (`!f:real^1->real^1 g a b.
          ~(interval[a,b] = {}) /\
          f integrable_on interval[a,b] /\
          (!x y. drop x <= drop y ==> g(x) <= g(y)) /\
          (!x. x IN interval[a,b] ==> &0 <= g x /\ g x <= &1)
          ==> (\x. g(x) % f(x)) integrable_on interval[a,b] /\
              ?c. c IN interval[a,b] /\
                  integral (interval[a,b]) (\x. g(x) % f(x)) =
                  integral (interval[c,b]) f`,
    REPEAT GEN_TAC THEN STRIP_TAC THEN
    SUBGOAL_THEN
     `?m M. IMAGE (\x. integral (interval[x,b]) (f:real^1->real^1))
                  (interval[a,b]) = interval[m,M]`
    STRIP_ASSUME_TAC THENL
     [REWRITE_TAC[GSYM CONNECTED_COMPACT_INTERVAL_1] THEN CONJ_TAC THENL
       [MATCH_MP_TAC CONNECTED_CONTINUOUS_IMAGE;
        MATCH_MP_TAC COMPACT_CONTINUOUS_IMAGE] THEN
      ASM_SIMP_TAC[INDEFINITE_INTEGRAL_CONTINUOUS_LEFT; CONVEX_CONNECTED;
                   CONVEX_INTERVAL; COMPACT_INTERVAL];
      ALL_TAC] THEN
    MP_TAC(ISPECL[`f:real^1->real^1`; `g:real^1->real`; `a:real^1`; `b:real^1`]
          lemma3) THEN
    ASM_REWRITE_TAC[] THEN DISCH_TAC THEN
    SUBGOAL_THEN
     `!n. ?c. c IN interval[a,b] /\
              integral (interval[c,b]) (f:real^1->real^1) =
              integral (interval[a,b])
                (\x. vsum (1..n)
                    (\k. if &k / &n <= g x then inv(&n) % f x else vec 0))`
    MP_TAC THENL
     [X_GEN_TAC `n:num` THEN ASM_CASES_TAC `n = 0` THENL
       [ASM_REWRITE_TAC[VSUM_CLAUSES_NUMSEG; ARITH_EQ; INTEGRAL_0] THEN
        EXISTS_TAC `b:real^1` THEN ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN
        SIMP_TAC[INTEGRAL_NULL; CONTENT_EQ_0_1; REAL_LE_REFL];
        ALL_TAC] THEN
      MP_TAC(ISPECL [`f:real^1->real^1`; `g:real^1->real`;
                     `a:real^1`; `b:real^1`] lemma2) THEN
      ASM_REWRITE_TAC[equiintegrable_on; FORALL_IN_GSPEC; IN_UNIV] THEN
      DISCH_THEN(ASSUME_TAC o CONJUNCT1) THEN
      REWRITE_TAC[MESON[VECTOR_MUL_RZERO]
       `(if p then a % x else vec 0:real^1) =
        a % (if p then x else vec 0)`] THEN
      ASM_SIMP_TAC[VSUM_LMUL; INTEGRAL_CMUL; INTEGRABLE_VSUM; ETA_AX;
                   FINITE_NUMSEG; INTEGRAL_VSUM] THEN
      SUBGOAL_THEN
       `!y:real. ?d:real^1.
          d IN interval[a,b] /\
          integral (interval[a,b]) (\x. if y <= g x then f x else vec 0) =
          integral (interval[d,b]) (f:real^1->real^1)`
      MP_TAC THENL
       [X_GEN_TAC `y:real` THEN
        SUBGOAL_THEN
         `{x | y <= g x} = {} \/
          {x | y <= g x} = (:real^1) \/
          (?a. {x | y <= g x} = {x | a <= drop x}) \/
          (?a. {x | y <= g x} = {x | a < drop x})`
        MP_TAC THENL
         [MATCH_MP_TAC(TAUT `(~a /\ ~b ==> c \/ d) ==> a \/ b \/ c \/ d`) THEN
          DISCH_TAC THEN
          MP_TAC(ISPEC `IMAGE drop {x | y <= (g:real^1->real) x}` INF) THEN
          ASM_REWRITE_TAC[FORALL_IN_IMAGE; IN_ELIM_THM; IMAGE_EQ_EMPTY] THEN
          ANTS_TAC THENL
           [FIRST_ASSUM(MP_TAC o CONJUNCT2) THEN
            REWRITE_TAC[EXTENSION; IN_ELIM_THM; IN_UNIV] THEN
            ASM_MESON_TAC[REAL_LE_TRANS; REAL_LE_TOTAL];
            STRIP_TAC] THEN
          ASM_CASES_TAC `y <= g(lift(inf(IMAGE drop {x | y <= g x})))` THENL
           [DISJ1_TAC; DISJ2_TAC] THEN
          REWRITE_TAC[EXTENSION; IN_ELIM_THM] THEN
          EXISTS_TAC `inf(IMAGE drop {x | y <= g x})` THEN
          REWRITE_TAC[FUN_EQ_THM] THEN
          X_GEN_TAC `x:real^1` THEN
          REWRITE_TAC[GSYM REAL_NOT_LE; GSYM drop] THEN
          ASM_MESON_TAC[REAL_LE_TOTAL; REAL_LT_ANTISYM;
                        REAL_LE_TRANS; LIFT_DROP];
          REWRITE_TAC[EXTENSION; IN_UNIV; NOT_IN_EMPTY; IN_ELIM_THM] THEN
          DISCH_THEN(DISJ_CASES_THEN2 ASSUME_TAC MP_TAC) THENL
           [EXISTS_TAC `b:real^1` THEN ASM_REWRITE_TAC[] THEN
            SIMP_TAC[INTEGRAL_NULL; CONTENT_EQ_0_1; REAL_LE_REFL] THEN
            ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTEGRAL_0];
            ALL_TAC] THEN
          DISCH_THEN(DISJ_CASES_THEN2 ASSUME_TAC MP_TAC) THENL
           [EXISTS_TAC `a:real^1` THEN
            ASM_REWRITE_TAC[ETA_AX; ENDS_IN_INTERVAL];
            ALL_TAC] THEN
          GEN_REWRITE_TAC LAND_CONV [OR_EXISTS_THM] THEN
          REWRITE_TAC[EXISTS_DROP] THEN
          DISCH_THEN(X_CHOOSE_THEN `d:real^1` ASSUME_TAC) THEN
          ASM_CASES_TAC `drop d < drop a` THENL
           [EXISTS_TAC `a:real^1` THEN
            ASM_REWRITE_TAC[ETA_AX; ENDS_IN_INTERVAL] THEN
            MATCH_MP_TAC INTEGRAL_EQ THEN
            REWRITE_TAC[IN_DIFF; IN_INTERVAL_1; NOT_IN_EMPTY] THEN
            GEN_TAC THEN COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
            UNDISCH_TAC `~(y <= (g:real^1->real) x)` THEN
            FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
            ASM_REAL_ARITH_TAC;
            ALL_TAC] THEN
          ASM_CASES_TAC `drop b < drop d` THENL
           [EXISTS_TAC `b:real^1` THEN
            SIMP_TAC[INTEGRAL_NULL; CONTENT_EQ_0_1; REAL_LE_REFL] THEN
            ASM_REWRITE_TAC[ENDS_IN_INTERVAL; INTEGRAL_0] THEN
            MATCH_MP_TAC INTEGRAL_EQ_0 THEN REWRITE_TAC[IN_INTERVAL_1] THEN
            REPEAT STRIP_TAC THEN
            COND_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
            UNDISCH_TAC `y <= (g:real^1->real) x` THEN
            FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
            ASM_REAL_ARITH_TAC;
            ALL_TAC] THEN
          EXISTS_TAC `d:real^1` THEN
          ASM_REWRITE_TAC[IN_INTERVAL_1; GSYM REAL_NOT_LT] THEN
          ONCE_REWRITE_TAC[SET_RULE
            `~((g:real^1->real) x < y) <=> x IN {x | ~(g x < y)}`] THEN
          REWRITE_TAC[INTEGRAL_RESTRICT_INTER] THEN
          MATCH_MP_TAC INTEGRAL_SPIKE_SET THEN
          MATCH_MP_TAC NEGLIGIBLE_SUBSET THEN EXISTS_TAC `{d:real^1}` THEN
          REWRITE_TAC[NEGLIGIBLE_SING; REAL_NOT_LT; SUBSET] THEN GEN_TAC THEN
          REWRITE_TAC[SUBSET; IN_UNION; IN_INTER; IN_DIFF; IN_INTERVAL_1;
                      IN_ELIM_THM; IN_SING; GSYM DROP_EQ] THEN
          FIRST_X_ASSUM DISJ_CASES_TAC THEN ASM_REWRITE_TAC[] THEN
          ASM_REAL_ARITH_TAC];
        DISCH_THEN(MP_TAC o GEN `k:num` o SPEC `&k / &n`) THEN
        REWRITE_TAC[SKOLEM_THM; FORALL_AND_THM; LEFT_IMP_EXISTS_THM] THEN
        X_GEN_TAC `d:num->real^1` THEN STRIP_TAC THEN
        FIRST_ASSUM(MP_TAC o MATCH_MP (SET_RULE
         `IMAGE f s = t ==> !y. y IN t ==> ?x. x IN s /\ f x = y`)) THEN
        REWRITE_TAC[GSYM VSUM_LMUL] THEN DISCH_THEN MATCH_MP_TAC THEN
        MATCH_MP_TAC(REWRITE_RULE[CONVEX_INDEXED]
         (CONJUNCT1(SPEC_ALL CONVEX_INTERVAL))) THEN
        REWRITE_TAC[SUM_CONST_NUMSEG; ADD_SUB; REAL_LE_INV_EQ; REAL_POS] THEN
        ASM_SIMP_TAC[REAL_MUL_RINV; REAL_OF_NUM_EQ] THEN ASM SET_TAC[]];
      REWRITE_TAC[SKOLEM_THM; LEFT_IMP_EXISTS_THM; FORALL_AND_THM] THEN
      X_GEN_TAC `c:num->real^1` THEN DISCH_THEN(STRIP_ASSUME_TAC o GSYM)] THEN
    SUBGOAL_THEN `compact(interval[a:real^1,b])` MP_TAC THENL
     [REWRITE_TAC[COMPACT_INTERVAL]; REWRITE_TAC[compact]] THEN
    DISCH_THEN(MP_TAC o SPEC `c:num->real^1`) THEN
    ASM_REWRITE_TAC[LEFT_IMP_EXISTS_THM] THEN MAP_EVERY X_GEN_TAC
     [`d:real^1`; `s:num->num`] THEN STRIP_TAC THEN
    MP_TAC(ISPECL
     [`\n:num x. vsum (1..(s n))
                      (\k. if &k / &(s n) <= g x
                           then inv(&(s n)) % (f:real^1->real^1) x
                           else vec 0)`;
      `\x. g x % (f:real^1->real^1) x`; `a:real^1`; `b:real^1`]
     EQUIINTEGRABLE_LIMIT) THEN
    ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
     [CONJ_TAC THENL
       [MATCH_MP_TAC EQUIINTEGRABLE_SUBSET THEN
        EXISTS_TAC
         `{\x. vsum(1..0) (\k. if &k / &0 <= g x
                               then inv(&0) % (f:real^1->real^1) x else vec 0)}
          UNION
          {\x. vsum (1..n)
                    (\k. if &k / &n <= g x then inv (&n) % f x else vec 0)
           | ~(n = 0)}` THEN
        CONJ_TAC THENL
         [MATCH_MP_TAC EQUIINTEGRABLE_UNION THEN ASM_REWRITE_TAC[] THEN
          REWRITE_TAC[EQUIINTEGRABLE_ON_SING; VSUM_CLAUSES_NUMSEG;
                      ARITH_EQ] THEN
          REWRITE_TAC[INTEGRABLE_0];
          REWRITE_TAC[SUBSET; FORALL_IN_GSPEC; IN_UNIV; IN_UNION] THEN
          REWRITE_TAC[IN_ELIM_THM; IN_SING] THEN
          X_GEN_TAC `n:num` THEN ASM_CASES_TAC `(s:num->num) n = 0` THEN
          ASM_REWRITE_TAC[] THEN DISJ2_TAC THEN
          EXISTS_TAC `(s:num->num) n` THEN ASM_REWRITE_TAC[]];
        X_GEN_TAC `x:real^1` THEN DISCH_TAC THEN REWRITE_TAC[] THEN
        ONCE_REWRITE_TAC[MESON[VECTOR_MUL_LZERO]
         `(if p then a % x else vec 0) = (if p then a else &0) % x`] THEN
        REWRITE_TAC[VSUM_RMUL] THEN MATCH_MP_TAC LIM_VMUL THEN
        REWRITE_TAC[LIM_SEQUENTIALLY; o_DEF; DIST_LIFT] THEN
        X_GEN_TAC `e:real` THEN DISCH_TAC THEN
        MP_TAC(ISPEC `e:real` REAL_ARCH_INV) THEN
        ASM_REWRITE_TAC[] THEN MATCH_MP_TAC MONO_EXISTS THEN
        X_GEN_TAC `N:num` THEN STRIP_TAC THEN X_GEN_TAC `n:num` THEN
        DISCH_TAC THEN
        ONCE_REWRITE_TAC[REAL_ABS_SUB] THEN
        MATCH_MP_TAC REAL_LT_TRANS THEN EXISTS_TAC `inv(&n)` THEN
        CONJ_TAC THENL
         [MP_TAC(ISPECL
           [`(g:real^1->real) o lift`; `IMAGE drop (interval[a,b])`]
            lemma1) THEN
          ASM_REWRITE_TAC[FORALL_IN_IMAGE; o_DEF; LIFT_DROP; IMP_CONJ;
                          RIGHT_FORALL_IMP_THM] THEN
          REWRITE_TAC[IMP_IMP] THEN DISCH_TAC THEN
          MATCH_MP_TAC REAL_LTE_TRANS THEN
          EXISTS_TAC `inv(&((s:num->num) n))` THEN CONJ_TAC THENL
           [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[];
            MATCH_MP_TAC REAL_LE_INV2 THEN
            REWRITE_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_LT]] THEN
          FIRST_ASSUM(MP_TAC o SPEC `n:num` o MATCH_MP MONOTONE_BIGGER) THEN
          ASM_ARITH_TAC;
          MATCH_MP_TAC REAL_LET_TRANS THEN EXISTS_TAC `inv(&N)` THEN
          ASM_REWRITE_TAC[] THEN MATCH_MP_TAC REAL_LE_INV2 THEN
          REWRITE_TAC[REAL_OF_NUM_LE; REAL_OF_NUM_LT] THEN ASM_ARITH_TAC]];
      STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
      EXISTS_TAC `d:real^1` THEN ASM_REWRITE_TAC[] THEN
      MATCH_MP_TAC(ISPEC `sequentially` LIM_UNIQUE) THEN
      EXISTS_TAC `\n. integral (interval [c((s:num->num) n),b])
                               (f:real^1->real^1)` THEN
      ASM_REWRITE_TAC[TRIVIAL_LIMIT_SEQUENTIALLY] THEN
      MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`]
          INDEFINITE_INTEGRAL_CONTINUOUS_LEFT) THEN
      ASM_REWRITE_TAC[CONTINUOUS_ON_EQ_CONTINUOUS_WITHIN] THEN
      DISCH_THEN(MP_TAC o SPEC `d:real^1`) THEN ASM_REWRITE_TAC[] THEN
      REWRITE_TAC[CONTINUOUS_WITHIN_SEQUENTIALLY] THEN
      DISCH_THEN(MP_TAC o SPEC `(c:num->real^1) o (s:num->num)`) THEN
      ASM_REWRITE_TAC[] THEN ASM_REWRITE_TAC[o_DEF]]) in
  REPEAT GEN_TAC THEN STRIP_TAC THEN
  SUBGOAL_THEN `(g:real^1->real) a <= g b` MP_TAC THENL
   [FIRST_X_ASSUM MATCH_MP_TAC THEN ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN
    ASM_MESON_TAC[INTERVAL_EQ_EMPTY_1; REAL_LET_TOTAL];
    ALL_TAC] THEN
  REWRITE_TAC[REAL_LE_LT] THEN STRIP_TAC THENL
   [ALL_TAC;
    SUBGOAL_THEN
     `!x. x IN interval[a,b] ==> g(x) % (f:real^1->real^1)(x) = g(a) % f x`
    ASSUME_TAC THENL
     [X_GEN_TAC `x:real^1` THEN
      REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN
      AP_THM_TAC THEN AP_TERM_TAC THEN
      RULE_ASSUM_TAC(REWRITE_RULE
       [IN_INTERVAL_1; INTERVAL_EQ_EMPTY_1; REAL_NOT_LT]) THEN
      ASM_MESON_TAC[REAL_LE_ANTISYM; REAL_LE_TRANS; REAL_LE_TOTAL];
      ALL_TAC] THEN
    EXISTS_TAC `a:real^1` THEN ASM_REWRITE_TAC[ENDS_IN_INTERVAL] THEN
    MATCH_MP_TAC HAS_INTEGRAL_EQ THEN
    EXISTS_TAC `\x. g(a:real^1) % (f:real^1->real^1) x` THEN
    ASM_SIMP_TAC[INTEGRAL_NULL; CONTENT_EQ_0_1; REAL_LE_REFL] THEN
    ASM_SIMP_TAC[INTEGRAL_CMUL; VECTOR_MUL_RZERO; VECTOR_ADD_LID] THEN
    MATCH_MP_TAC HAS_INTEGRAL_CMUL THEN
    ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL]] THEN
  MP_TAC(ISPECL
   [`f:real^1->real^1`;
    `\x. if drop x < drop a then &0
         else if drop b < drop x then &1
         else (g(x) - g(a)) / (g(b) - g(a))`;
    `a:real^1`; `b:real^1`]
   lemma4) THEN ASM_REWRITE_TAC[] THEN
  ANTS_TAC THENL
   [CONJ_TAC THEN
    REPEAT GEN_TAC THEN
    REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_POS; REAL_LE_REFL]) THEN
    TRY ASM_REAL_ARITH_TAC THEN
    ASM_SIMP_TAC[IN_INTERVAL_1; REAL_LE_DIV2_EQ; REAL_SUB_LT] THEN
    ASM_SIMP_TAC[REAL_LE_LDIV_EQ; REAL_LE_RDIV_EQ; REAL_SUB_LT] THEN
    ASM_REWRITE_TAC[REAL_MUL_LZERO; REAL_MUL_LID; REAL_SUB_LE;
                    REAL_ARITH `x - a <= y - a <=> x <= y`] THEN
    REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
    REWRITE_TAC[IN_INTERVAL_1] THEN ASM_REAL_ARITH_TAC;
    ALL_TAC] THEN
  REWRITE_TAC[RIGHT_AND_EXISTS_THM] THEN
  MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `c:real^1` THEN
  ONCE_REWRITE_TAC[TAUT `a /\ b /\ c ==> d <=> b ==> a /\ c ==> d`] THEN
  DISCH_TAC THEN ASM_REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRABLE_INTEGRAL] THEN
  DISCH_THEN(MP_TAC o SPEC `(g:real^1->real) b - g a` o
        MATCH_MP HAS_INTEGRAL_CMUL) THEN
  FIRST_ASSUM(MP_TAC o MATCH_MP INTEGRABLE_INTEGRAL) THEN
  DISCH_THEN(MP_TAC o SPEC `(g:real^1->real)(a)` o
      MATCH_MP HAS_INTEGRAL_CMUL) THEN REWRITE_TAC[IMP_IMP] THEN
  DISCH_THEN(MP_TAC o MATCH_MP HAS_INTEGRAL_ADD) THEN
  MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`; `c:real^1`]
        INTEGRAL_COMBINE) THEN
  ANTS_TAC THENL [ASM_MESON_TAC[IN_INTERVAL_1]; ALL_TAC] THEN
  DISCH_THEN(SUBST1_TAC o SYM) THEN
  REWRITE_TAC[VECTOR_ARITH
   `ga % (i1 + i2) + (gb - ga) % i2:real^N = ga % i1 + gb % i2`] THEN
  MATCH_MP_TAC(REWRITE_RULE[IMP_CONJ] HAS_INTEGRAL_EQ) THEN
  X_GEN_TAC `x:real^1` THEN REWRITE_TAC[IN_INTERVAL_1] THEN STRIP_TAC THEN
  ASM_SIMP_TAC[GSYM REAL_NOT_LE; VECTOR_MUL_ASSOC] THEN
  ASM_SIMP_TAC[REAL_DIV_LMUL; REAL_LT_IMP_NZ; REAL_SUB_LT] THEN
  VECTOR_ARITH_TAC);;  
let SECOND_MEAN_VALUE_THEOREM_GEN_FULL = prove
 (`!f:real^1->real^1 g a b u v.
        ~(
interval[a,b] = {}) /\ f 
integrable_on interval [a,b] /\
        (!x. x 
IN interval(a,b) ==> u <= g x /\ g x <= v) /\
        (!x y. x 
IN interval[a,b] /\ y 
IN interval[a,b] /\ 
drop x <= 
drop y
               ==> g x <= g y)
        ==> ?c. c 
IN interval [a,b] /\
                ((\x. g x % f x) 
has_integral
                 (u % 
integral (
interval[a,c]) f +
                  v % 
integral (
interval[c,b]) f)) (
interval[a,b])`,
 
let SECOND_MEAN_VALUE_THEOREM_GEN = prove
 (`!f:real^1->real^1 g a b u v.
        ~(
interval[a,b] = {}) /\ f 
integrable_on interval [a,b] /\
        (!x. x 
IN interval(a,b) ==> u <= g x /\ g x <= v) /\
        (!x y. x 
IN interval[a,b] /\ y 
IN interval[a,b] /\ 
drop x <= 
drop y
               ==> g x <= g y)
        ==> ?c. c 
IN interval [a,b] /\
                
integral (
interval[a,b]) (\x. g x % f x) =
                u % 
integral (
interval[a,c]) f +
                v % 
integral (
interval[c,b]) f`,
 
let INTEGRABLE_INCREASING_PRODUCT_UNIV = prove
 (`!f:real^1->real^N g B.
        f 
integrable_on (:real^1) /\
        (!x y. 
drop x <= 
drop y ==> g x <= g y) /\
        (!x. abs(g x) <= B)
         ==> (\x. g x % f x) 
integrable_on (:real^1)`,
  let lemma = prove
   (`!f:real^1->real^1 g B.
          f integrable_on (:real^1) /\
          (!x y. drop x <= drop y ==> g x <= g y) /\
          (!x. abs(g x) <= B)
           ==> (\x. g x % f x) integrable_on (:real^1)`,
    REPEAT GEN_TAC THEN ONCE_REWRITE_TAC[INTEGRABLE_ALT_SUBSET] THEN
    REWRITE_TAC[IN_UNIV; ETA_AX] THEN STRIP_TAC THEN
    MATCH_MP_TAC(TAUT `a /\ (a ==> b) ==> a /\ b`) THEN CONJ_TAC THENL
     [REPEAT GEN_TAC THEN MATCH_MP_TAC INTEGRABLE_INCREASING_PRODUCT THEN
      ASM_SIMP_TAC[];
      DISCH_TAC] THEN
    X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    FIRST_X_ASSUM(MP_TAC o SPEC `e / (&8 * abs B + &8)`) THEN
    ASM_SIMP_TAC[REAL_LT_DIV; REAL_ARITH `&0 < &8 * abs B + &8`] THEN
    MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `C:real` THEN STRIP_TAC THEN
    ASM_REWRITE_TAC[] THEN
    SUBGOAL_THEN `~(ball(vec 0:real^1,C) = {})` ASSUME_TAC THENL
     [ASM_REWRITE_TAC[BALL_EQ_EMPTY; REAL_NOT_LE]; ALL_TAC] THEN
    MAP_EVERY X_GEN_TAC [`a:real^1`; `b:real^1`; `c:real^1`; `d:real^1`] THEN
    STRIP_TAC THEN SUBGOAL_THEN
     `~(interval[a:real^1,b] = {}) /\ ~(interval[c:real^1,d] = {})`
    MP_TAC THENL [ASM SET_TAC[]; ALL_TAC] THEN
    REWRITE_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN STRIP_TAC THEN
    FIRST_ASSUM(MP_TAC o GEN_REWRITE_RULE I [SUBSET_INTERVAL_1]) THEN
    ASM_REWRITE_TAC[GSYM REAL_NOT_LE] THEN STRIP_TAC THEN
    MP_TAC(ISPECL [`\x. g x % (f:real^1->real^1) x`;
                   `c:real^1`; `b:real^1`; `a:real^1`] INTEGRAL_COMBINE) THEN
    MP_TAC(ISPECL [`\x. g x % (f:real^1->real^1) x`;
                   `c:real^1`; `d:real^1`; `b:real^1`] INTEGRAL_COMBINE) THEN
    ASM_REWRITE_TAC[] THEN
    ANTS_TAC THENL [ASM_REAL_ARITH_TAC; DISCH_THEN(SUBST1_TAC o SYM)] THEN
    DISCH_THEN(SUBST1_TAC o SYM) THEN
    REWRITE_TAC[REAL_NOT_LE; NORM_ARITH
     `norm(ab - ((ca + ab) + bd):real^1) = norm(ca + bd)`] THEN
    MP_TAC(ISPECL[`f:real^1->real^1`; `g:real^1->real`; `c:real^1`; `a:real^1`]
          SECOND_MEAN_VALUE_THEOREM) THEN
    ASM_SIMP_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN
    DISCH_THEN(X_CHOOSE_THEN `u:real^1` STRIP_ASSUME_TAC) THEN
    MP_TAC(ISPECL[`f:real^1->real^1`; `g:real^1->real`; `b:real^1`; `d:real^1`]
          SECOND_MEAN_VALUE_THEOREM) THEN
    ASM_SIMP_TAC[INTERVAL_EQ_EMPTY_1; REAL_NOT_LT] THEN
    DISCH_THEN(X_CHOOSE_THEN `v:real^1` STRIP_ASSUME_TAC) THEN
    ASM_REWRITE_TAC[] THEN
    SUBGOAL_THEN
     `!x y. drop y <= drop a
            ==> norm(integral (interval[x,y]) (f:real^1->real^1))
                < e / (&4 * abs B + &4)`
     (LABEL_TAC "L")
    THENL
     [REPEAT STRIP_TAC THEN
      ASM_CASES_TAC `drop x <= drop y` THENL
       [FIRST_X_ASSUM(fun th ->
         MP_TAC(SPECL[`a:real^1`; `b:real^1`; `y:real^1`; `b:real^1`] th) THEN
         MP_TAC(SPECL[`a:real^1`; `b:real^1`; `x:real^1`; `b:real^1`] th)) THEN
        ASM_REWRITE_TAC[SUBSET_INTERVAL_1; REAL_LE_REFL] THEN
        ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
        MP_TAC(ISPECL [`f:real^1->real^1`; `x:real^1`; `b:real^1`; `y:real^1`]
          INTEGRAL_COMBINE) THEN
        ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
         [ASM_ARITH_TAC; DISCH_THEN(SUBST1_TAC o SYM)] THEN
        MATCH_MP_TAC(NORM_ARITH
         `&2 * d = e
          ==> norm(ab - (xy + yb)) < d
              ==> norm(ab - yb) < d
                  ==> norm(xy:real^1) < e`) THEN
        CONV_TAC REAL_FIELD;
        SUBGOAL_THEN `interval[x:real^1,y] = {}` SUBST1_TAC THENL
         [REWRITE_TAC[INTERVAL_EQ_EMPTY_1] THEN ASM_REAL_ARITH_TAC;
          REWRITE_TAC[INTEGRAL_EMPTY; NORM_0] THEN
          MATCH_MP_TAC REAL_LT_DIV THEN ASM_REAL_ARITH_TAC]];
      ALL_TAC] THEN
    SUBGOAL_THEN
     `!x y. drop b <= drop x
            ==> norm(integral (interval[x,y]) (f:real^1->real^1))
                < e / (&4 * abs B + &4)`
     (LABEL_TAC "R")
    THENL
     [REPEAT STRIP_TAC THEN
      ASM_CASES_TAC `drop x <= drop y` THENL
       [FIRST_X_ASSUM(fun th ->
         MP_TAC(SPECL[`a:real^1`; `b:real^1`; `a:real^1`; `x:real^1`] th) THEN
         MP_TAC(SPECL[`a:real^1`; `b:real^1`; `a:real^1`; `y:real^1`] th)) THEN
        ASM_REWRITE_TAC[SUBSET_INTERVAL_1; REAL_LE_REFL] THEN
        ANTS_TAC THENL [ASM_REAL_ARITH_TAC; ALL_TAC] THEN
        MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `y:real^1`; `x:real^1`]
          INTEGRAL_COMBINE) THEN
        ASM_REWRITE_TAC[] THEN ANTS_TAC THENL
         [ASM_ARITH_TAC; DISCH_THEN(SUBST1_TAC o SYM)] THEN
        MATCH_MP_TAC(NORM_ARITH
         `&2 * d = e
          ==> norm(ab - (ax + xy)) < d
              ==> norm(ab - ax) < d
                  ==> norm(xy:real^1) < e`) THEN
        CONV_TAC REAL_FIELD;
        SUBGOAL_THEN `interval[x:real^1,y] = {}` SUBST1_TAC THENL
         [REWRITE_TAC[INTERVAL_EQ_EMPTY_1] THEN ASM_REAL_ARITH_TAC;
          REWRITE_TAC[INTEGRAL_EMPTY; NORM_0] THEN
          MATCH_MP_TAC REAL_LT_DIV THEN ASM_REAL_ARITH_TAC]];
      ALL_TAC] THEN
    RULE_ASSUM_TAC(REWRITE_RULE[IN_INTERVAL_1]) THEN
    MATCH_MP_TAC REAL_LET_TRANS THEN
    EXISTS_TAC `&4 * B * e / (&4 * abs B + &4)` THEN CONJ_TAC THENL
     [MATCH_MP_TAC(NORM_ARITH
       `(norm a <= e /\ norm b <= e) /\ (norm c <= e /\ norm d <= e)
        ==> norm((a + b) + (c + d):real^1) <= &4 * e`) THEN
      REWRITE_TAC[NORM_MUL] THEN CONJ_TAC THENL
       [CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
        ASM_REWRITE_TAC[NORM_POS_LE; REAL_ABS_POS] THEN
        MATCH_MP_TAC REAL_LT_IMP_LE THEN
        REMOVE_THEN "L" MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC;
        CONJ_TAC THEN MATCH_MP_TAC REAL_LE_MUL2 THEN
        ASM_REWRITE_TAC[NORM_POS_LE; REAL_ABS_POS] THEN
        MATCH_MP_TAC REAL_LT_IMP_LE THEN
        REMOVE_THEN "R" MATCH_MP_TAC THEN ASM_REAL_ARITH_TAC];
      REWRITE_TAC[REAL_ARITH
       `&4 * B * e / y < e <=> e * (&4 * B) / y < e * &1`] THEN
      ASM_SIMP_TAC[REAL_LT_LMUL_EQ; REAL_LT_LDIV_EQ;
                   REAL_ARITH `&0 < &4 * abs B + &4`] THEN
      REAL_ARITH_TAC]) in
  GEN_TAC THEN ONCE_REWRITE_TAC[INTEGRABLE_COMPONENTWISE] THEN
  REWRITE_TAC[] THEN REPEAT STRIP_TAC THEN
  REWRITE_TAC[VECTOR_MUL_COMPONENT; LIFT_CMUL] THEN
  MATCH_MP_TAC lemma THEN EXISTS_TAC `B:real` THEN ASM_SIMP_TAC[]);;  
let HAS_BOUNDED_VARIATION_DARBOUX_STRONG = prove
 (`!f a b.
     f 
has_bounded_variation_on interval[a,b]
     ==> ?g h. (!x. f x = g x - h x) /\
               (!x y. x 
IN interval[a,b] /\ y 
IN interval[a,b] /\
                      
drop x <= 
drop y
                      ==> 
drop(g x) <= 
drop(g y)) /\
               (!x y. x 
IN interval[a,b] /\ y 
IN interval[a,b] /\
                      
drop x <= 
drop y
                      ==> 
drop(h x) <= 
drop(h y)) /\
               (!x y. x 
IN interval[a,b] /\ y 
IN interval[a,b] /\
                      
drop x < 
drop y
                      ==> 
drop(g x) < 
drop(g y)) /\
               (!x y. x 
IN interval[a,b] /\ y 
IN interval[a,b] /\
                      
drop x < 
drop y
                      ==> 
drop(h x) < 
drop(h y)) /\
               (!x. x 
IN interval[a,b] /\
                    f 
continuous (
at x 
within interval[a,x])
                    ==> g 
continuous (
at x 
within interval[a,x]) /\
                        h 
continuous (
at x 
within interval[a,x])) /\
               (!x. x 
IN interval[a,b] /\
                    f 
continuous (
at x 
within interval[x,b])
                    ==> g 
continuous (
at x 
within interval[x,b]) /\
                        h 
continuous (
at x 
within interval[x,b])) /\
               (!x. x 
IN interval[a,b] /\
                    f 
continuous (
at x 
within interval[a,b])
                    ==> g 
continuous (
at x 
within interval[a,b]) /\
                        h 
continuous (
at x 
within interval[a,b]))`,
 
let HAS_BOUNDED_VARIATION_COUNTABLE_DISCONTINUITIES = prove
 (`!f:real^1->real^1 a b.
        f 
has_bounded_variation_on interval[a,b]
        ==> 
COUNTABLE {x | x 
IN interval[a,b] /\ ~(f 
continuous at x)}`,
  SUBGOAL_THEN
   `!f a b.
        (!x y. x 
IN interval[a,b] /\ y 
IN interval[a,b] /\ 
drop x <= 
drop y
               ==> 
drop(f x) <= 
drop(f y))
        ==> 
COUNTABLE {x | x 
IN interval[a,b] /\ ~(f 
continuous at x)}`
  ASSUME_TAC THENL
   [ALL_TAC;
    REPEAT STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o
     GEN_REWRITE_RULE I [
HAS_BOUNDED_VARIATION_DARBOUX]) THEN
    REWRITE_TAC[
LEFT_IMP_EXISTS_THM] THEN
    MAP_EVERY X_GEN_TAC [`g:real^1->real^1`; `h:real^1->real^1`] THEN
    STRIP_TAC THEN FIRST_X_ASSUM(fun 
th ->
      MP_TAC(ISPECL [`g:real^1->real^1`; `a:real^1`; `b:real^1`] 
th) THEN
      MP_TAC(ISPECL [`h:real^1->real^1`; `a:real^1`; `b:real^1`] 
th)) THEN
    ASM_REWRITE_TAC[IMP_IMP; GSYM 
COUNTABLE_UNION] THEN
    MATCH_MP_TAC(REWRITE_RULE[
IMP_CONJ_ALT] 
COUNTABLE_SUBSET) THEN
    REWRITE_TAC[
SUBSET; 
IN_UNION; 
IN_ELIM_THM] THEN GEN_TAC THEN
    MATCH_MP_TAC(TAUT
     `(p /\ q ==> r) ==> a /\ ~r ==> a /\ ~p \/ a /\ ~q`) THEN
    GEN_REWRITE_TAC (RAND_CONV o LAND_CONV) [GSYM ETA_AX] THEN
    ASM_SIMP_TAC[
CONTINUOUS_SUB]] THEN
  REPEAT STRIP_TAC THEN ASM_CASES_TAC `
interval[a:real^1,b] = {}` THEN
  ASM_REWRITE_TAC[
NOT_IN_EMPTY; 
EMPTY_GSPEC; 
COUNTABLE_EMPTY] THEN
  RULE_ASSUM_TAC(REWRITE_RULE[
INTERVAL_EQ_EMPTY_1; 
REAL_NOT_LT]) THEN
  ASM_SIMP_TAC[
CLOSED_OPEN_INTERVAL_1] THEN
  MATCH_MP_TAC 
COUNTABLE_SUBSET THEN EXISTS_TAC
   `a 
INSERT b 
INSERT
    {x | x 
IN interval(a,b) /\ ~((f:real^1->real^1) 
continuous at x)}` THEN
  CONJ_TAC THENL [REWRITE_TAC[
COUNTABLE_INSERT]; SET_TAC[]] THEN
  SUBGOAL_THEN
   `(!c:real^1. c 
IN interval(a,b) ==> c 
limit_point_of interval[a,c]) /\
    (!c:real^1. c 
IN interval(a,b) ==> c 
limit_point_of interval[c,b])`
  STRIP_ASSUME_TAC THENL
   [SIMP_TAC[
IN_INTERVAL_1; 
REAL_LE_REFL; 
LIMPT_OF_CONVEX;
             
CONVEX_INTERVAL; 
REAL_LT_IMP_LE] THEN
    REWRITE_TAC[GSYM 
INTERVAL_SING; GSYM 
SUBSET_ANTISYM_EQ] THEN
    REWRITE_TAC[
SUBSET_INTERVAL_1] THEN REAL_ARITH_TAC;
    ALL_TAC] THEN
  MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`]
        
INCREASING_LEFT_LIMIT_1) THEN
  ASM_REWRITE_TAC[
RIGHT_IMP_EXISTS_THM; 
SKOLEM_THM] THEN
  DISCH_THEN(X_CHOOSE_THEN `l:real^1->real^1` (LABEL_TAC "l")) THEN
  MP_TAC(ISPECL [`f:real^1->real^1`; `a:real^1`; `b:real^1`]
        
INCREASING_RIGHT_LIMIT_1) THEN
  ASM_REWRITE_TAC[
RIGHT_IMP_EXISTS_THM; 
SKOLEM_THM] THEN
  DISCH_THEN(X_CHOOSE_THEN `r:real^1->real^1` (LABEL_TAC "r")) THEN
  SUBGOAL_THEN
   `!c. c 
IN interval(a:real^1,b)
        ==> 
drop(l c) <= 
drop(f c) /\ 
drop(f c) <= 
drop(r c)`
  ASSUME_TAC THENL
   [REPEAT STRIP_TAC THENL
     [MATCH_MP_TAC(ISPEC `
at c 
within interval[a:real^1,c]`
        
LIM_DROP_UBOUND);
      MATCH_MP_TAC(ISPEC `
at c 
within interval[c:real^1,b]`
        
LIM_DROP_LBOUND)] THEN
    EXISTS_TAC `f:real^1->real^1` THEN
    ASM_SIMP_TAC[REWRITE_RULE[
SUBSET] 
INTERVAL_OPEN_SUBSET_CLOSED;
                 
TRIVIAL_LIMIT_WITHIN; 
EVENTUALLY_WITHIN] THEN
    EXISTS_TAC `&1` THEN REWRITE_TAC[
REAL_LT_01; 
IN_INTERVAL_1] THEN
    REPEAT STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
    REWRITE_TAC[
IN_INTERVAL_1] THEN
    RULE_ASSUM_TAC(REWRITE_RULE[
IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
    ALL_TAC] THEN
  SUBGOAL_THEN
   `(!c x. c 
IN interval(a:real^1,b) /\ x 
IN interval[a,b] /\ 
drop x < 
drop c
           ==> 
drop(f x) <= 
drop(l c)) /\
    (!c x. c 
IN interval(a:real^1,b) /\ x 
IN interval[a,b] /\ 
drop c < 
drop x
           ==> 
drop(r c) <= 
drop(f x))`
  STRIP_ASSUME_TAC THENL
   [REPEAT STRIP_TAC THENL
     [MATCH_MP_TAC(ISPEC `
at c 
within interval[a:real^1,c]`
        
LIM_DROP_LBOUND);
      MATCH_MP_TAC(ISPEC `
at c 
within interval[c:real^1,b]`
        
LIM_DROP_UBOUND)] THEN
    EXISTS_TAC `f:real^1->real^1` THEN
    ASM_SIMP_TAC[REWRITE_RULE[
SUBSET] 
INTERVAL_OPEN_SUBSET_CLOSED;
                 
TRIVIAL_LIMIT_WITHIN; 
EVENTUALLY_WITHIN]
    THENL
     [EXISTS_TAC `
drop c - 
drop x`; EXISTS_TAC `
drop x - 
drop c`] THEN
    ASM_REWRITE_TAC[
REAL_SUB_LT] THEN
    X_GEN_TAC `y:real^1` THEN
    REWRITE_TAC[
IN_INTERVAL_1; 
IN_ELIM_THM; 
DIST_REAL; GSYM 
drop] THEN
    STRIP_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
    ASM_REWRITE_TAC[
IN_INTERVAL_1] THEN
    RULE_ASSUM_TAC(REWRITE_RULE[
IN_INTERVAL_1]) THEN ASM_REAL_ARITH_TAC;
    ALL_TAC] THEN
  REWRITE_TAC[
COUNTABLE; 
ge_c] THEN
  TRANS_TAC 
CARD_LE_TRANS `
rational` THEN
  GEN_REWRITE_TAC RAND_CONV [GSYM 
ge_c] THEN
  REWRITE_TAC[
COUNTABLE_RATIONAL; GSYM 
COUNTABLE; 
le_c] THEN
  SUBGOAL_THEN
   `!c. c 
IN interval(a,b) /\ ~((f:real^1->real^1) 
continuous at c)
          ==> 
drop(l(c:real^1)) < 
drop(r c)`
  ASSUME_TAC THENL
   [REPEAT STRIP_TAC THEN REWRITE_TAC[
REAL_LT_LE] THEN
    CONJ_TAC THENL [ASM_MESON_TAC[
REAL_LE_TRANS]; ALL_TAC] THEN
    REWRITE_TAC[
DROP_EQ] THEN DISCH_TAC THEN
    SUBGOAL_THEN `l c = (f:real^1->real^1) c /\ r c = f c` ASSUME_TAC THENL
     [ASM_MESON_TAC[REAL_LE_ANTISYM; 
DROP_EQ]; ALL_TAC] THEN
    FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE RAND_CONV [
CONTINUOUS_AT]) THEN
    REWRITE_TAC[] THEN
    SUBGOAL_THEN
     `((f:real^1->real^1) --> f c) (
at c 
within interval(a,b))`
    MP_TAC THENL
     [ALL_TAC; ASM_SIMP_TAC[
OPEN_INTERVAL; 
LIM_WITHIN_OPEN]] THEN
    MATCH_MP_TAC 
LIM_WITHIN_SUBSET THEN
    EXISTS_TAC `
interval[a:real^1,c] 
UNION interval[c,b]` THEN
    REWRITE_TAC[
LIM_WITHIN_UNION] THEN CONJ_TAC THENL
     [ASM_MESON_TAC[REWRITE_RULE[
SUBSET] 
INTERVAL_OPEN_SUBSET_CLOSED];
      REWRITE_TAC[
SUBSET; 
IN_UNION; 
IN_INTERVAL_1] THEN REAL_ARITH_TAC];
    ALL_TAC] THEN
  SUBGOAL_THEN
   `!c. c 
IN interval(a,b) /\ ~((f:real^1->real^1) 
continuous at c)
        ==> ?q. 
rational q /\ 
drop(l c) < q /\ q < 
drop(r c)`
  MP_TAC THENL
   [REPEAT STRIP_TAC THEN
    SUBGOAL_THEN `
drop(l(c:real^1)) < 
drop(r c)` ASSUME_TAC THENL
     [ASM_MESON_TAC[]; ALL_TAC] THEN
    MP_TAC(ISPECL [`(
drop(l(c:real^1)) + 
drop(r c)) / &2`;
                   `(
drop(r c) - 
drop(l(c:real^1))) / &2`]
      
RATIONAL_APPROXIMATION) THEN
    ASM_REWRITE_TAC[
REAL_HALF; 
REAL_SUB_LT] THEN
    MATCH_MP_TAC 
MONO_EXISTS THEN SIMP_TAC[] THEN REAL_ARITH_TAC;
    ALL_TAC] THEN
  GEN_REWRITE_TAC (LAND_CONV o ONCE_DEPTH_CONV) [
RIGHT_IMP_EXISTS_THM] THEN
  REWRITE_TAC[
SKOLEM_THM; 
IN_ELIM_THM; 
IN_INTERVAL_1] THEN
  MATCH_MP_TAC 
MONO_EXISTS THEN X_GEN_TAC `q:real^1->
real` THEN
  SIMP_TAC[
IN] THEN DISCH_THEN(LABEL_TAC "*") THEN
  MATCH_MP_TAC(MESON[
REAL_LE_TOTAL]
   `(!x y. P x y ==> P y x) /\ (!x y. 
drop x <= 
drop y ==> P x y)
    ==> !x y. P x y`) THEN
  CONJ_TAC THENL [MESON_TAC[]; ALL_TAC] THEN
  MAP_EVERY X_GEN_TAC [`x:real^1`; `y:real^1`] THEN
  REWRITE_TAC[
REAL_LE_LT; 
DROP_EQ] THEN
  ASM_CASES_TAC `x:real^1 = y` THEN ASM_REWRITE_TAC[] THEN
  REPEAT STRIP_TAC THEN
  SUBGOAL_THEN `q(x:real^1) < q(y)` MP_TAC THENL
   [ALL_TAC; ASM_REWRITE_TAC[
REAL_LT_REFL]] THEN
  MATCH_MP_TAC 
REAL_LTE_TRANS THEN EXISTS_TAC `
drop(r(x:real^1))` THEN
  ASM_SIMP_TAC[
REAL_LT_IMP_LE] THEN
  MATCH_MP_TAC 
REAL_LE_TRANS THEN EXISTS_TAC `
drop(l(y:real^1))` THEN
  ASM_SIMP_TAC[
REAL_LT_IMP_LE] THEN
  MATCH_MP_TAC 
REAL_LE_TRANS THEN
  EXISTS_TAC `
drop(f(inv(&2) % (x + y):real^1))` THEN
  CONJ_TAC THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
  ASM_REWRITE_TAC[
IN_INTERVAL_1; 
DROP_CMUL; 
DROP_ADD] THEN
  ASM_REAL_ARITH_TAC);;
 
let INTEGRAL_PASTECART_CONTINUOUS = prove
 (`!f:real^(M,N)finite_sum->real^P a b c d.
        f 
continuous_on interval[
pastecart a c,
pastecart b d]
        ==> 
integral (
interval[
pastecart a c,
pastecart b d]) f =
            
integral (
interval[a,b])
                     (\x. 
integral (
interval[c,d])
                                   (\y. f(
pastecart x y)))`,
  let lemma1 = prove
   (`!(f:real^(M,N)finite_sum->real^P) a b c d x.
          f continuous_on interval [pastecart a c,pastecart b d] /\
          x IN interval[a,b]
          ==> (\y. (f:real^(M,N)finite_sum->real^P) (pastecart x y))
              integrable_on interval[c,d]`,
    REPEAT STRIP_TAC THEN MATCH_MP_TAC INTEGRABLE_CONTINUOUS THEN
    GEN_REWRITE_TAC LAND_CONV [GSYM o_DEF] THEN
    MATCH_MP_TAC CONTINUOUS_ON_COMPOSE THEN
    SIMP_TAC[CONTINUOUS_ON_PASTECART; CONTINUOUS_ON_CONST;
             CONTINUOUS_ON_ID] THEN
    FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
      CONTINUOUS_ON_SUBSET)) THEN
    ASM_SIMP_TAC[SUBSET; FORALL_IN_IMAGE; GSYM PCROSS_INTERVAL; PCROSS;
                 IN_ELIM_PASTECART_THM]) in
  let lemma2 = prove
   (`!(f:real^(M,N)finite_sum->real^P) a b c d.
      f continuous_on interval [pastecart a c,pastecart b d]
      ==> (\x. integral (interval [c,d]) (\y. f (pastecart x y))) integrable_on
          interval [a,b]`,
    REPEAT STRIP_TAC THEN
    FIRST_ASSUM(ASSUME_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ] lemma1)) THEN
    MATCH_MP_TAC INTEGRABLE_CONTINUOUS THEN REWRITE_TAC[continuous_on] THEN
    X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN
    X_GEN_TAC `e:real` THEN DISCH_TAC THEN
    ASM_SIMP_TAC[dist; GSYM INTEGRAL_SUB] THEN
    ASM_CASES_TAC `content(interval[c:real^N,d]) = &0` THENL
     [ASM_SIMP_TAC[INTEGRAL_NULL; NORM_0] THEN MESON_TAC[REAL_LT_01];
      ALL_TAC] THEN
    FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
          COMPACT_UNIFORMLY_CONTINUOUS)) THEN
    REWRITE_TAC[COMPACT_INTERVAL; uniformly_continuous_on] THEN
    RULE_ASSUM_TAC(REWRITE_RULE[GSYM CONTENT_LT_NZ]) THEN
    DISCH_THEN(MP_TAC o SPEC `e / &2 / content(interval[c:real^N,d])`) THEN
    ASM_SIMP_TAC[REAL_LT_DIV; REAL_HALF; FORALL_PASTECART] THEN
    MATCH_MP_TAC MONO_EXISTS THEN X_GEN_TAC `d:real` THEN
    REWRITE_TAC[GSYM PCROSS_INTERVAL; PCROSS; dist;
                IN_ELIM_PASTECART_THM] THEN
    STRIP_TAC THEN ASM_REWRITE_TAC[] THEN
    X_GEN_TAC `x':real^M` THEN DISCH_TAC THEN
    MATCH_MP_TAC(REAL_ARITH `&0 < e /\ x <= e / &2 ==> x < e`) THEN
    ASM_REWRITE_TAC[] THEN
    SUBGOAL_THEN
     `e / &2 = e / &2 / content(interval[c:real^N,d]) * content(interval[c,d])`
    SUBST1_TAC THENL
     [UNDISCH_TAC `&0 < content(interval[c:real^N,d])` THEN
      CONV_TAC REAL_FIELD;
      MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN
      EXISTS_TAC `\y. (f:real^(M,N)finite_sum->real^P) (pastecart x' y) -
                      (f:real^(M,N)finite_sum->real^P) (pastecart x y)` THEN
      ASM_SIMP_TAC[REAL_LT_IMP_LE; REAL_HALF; REAL_LT_DIV;
                   GSYM HAS_INTEGRAL_INTEGRAL; INTEGRABLE_SUB; lemma1] THEN
      REPEAT STRIP_TAC THEN
      MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
      ASM_SIMP_TAC[NORM_PASTECART; PASTECART_SUB; VECTOR_SUB_REFL; NORM_0] THEN
      CONV_TAC REAL_RAT_REDUCE_CONV THEN
      ASM_SIMP_TAC[REAL_ADD_RID; POW_2_SQRT; NORM_POS_LE]]) in
  let lemma3 = prove
   (`!f:real^(M,N)finite_sum->real^P e s.
      &0 < e /\ f continuous_on s
      ==> operative(/\)
           (\k. !a b c d.
                interval[pastecart a c,pastecart b d] SUBSET k /\
                interval[pastecart a c,pastecart b d] SUBSET s
                ==> norm(integral (interval[pastecart a c,pastecart b d]) f -
                         integral (interval[a,b])
                           (\x. integral (interval[c,d])
                                    (\y. f(pastecart x y))))
                    <= e * content(interval[pastecart a c,pastecart b d]))`,
    REPEAT STRIP_TAC THEN REWRITE_TAC[operative; NEUTRAL_AND] THEN
    CONJ_TAC THEN MAP_EVERY X_GEN_TAC
     [`A:real^(M,N)finite_sum`;`B:real^(M,N)finite_sum`] THENL
     [DISCH_TAC THEN
      MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real^N`; `d:real^N`] THEN
      DISCH_TAC THEN
      SUBGOAL_THEN
       `content(interval[pastecart (a:real^M) (c:real^N),pastecart b d]) = &0`
       (fun th -> ASSUME_TAC th THEN MP_TAC th)
      THENL [ASM_MESON_TAC[CONTENT_0_SUBSET]; ALL_TAC] THEN
      REWRITE_TAC[CONTENT_PASTECART; REAL_ENTIRE] THEN STRIP_TAC THEN
      ASM_SIMP_TAC[INTEGRAL_NULL; REAL_MUL_LZERO; REAL_MUL_RZERO;
                   VECTOR_SUB_REFL; NORM_0; REAL_LE_REFL; INTEGRAL_0];
      MAP_EVERY X_GEN_TAC [`l:real`; `k:num`] THEN STRIP_TAC THEN EQ_TAC THENL
       [REWRITE_TAC[AND_FORALL_THM] THEN
        REPEAT(MATCH_MP_TAC MONO_FORALL THEN GEN_TAC) THEN
        MATCH_MP_TAC(TAUT
         `(P1 ==> P) /\ (P2 ==> P)
          ==> (P ==> Q) ==> (P1 ==> Q) /\ (P2 ==> Q)`) THEN
        SET_TAC[];
        DISCH_TAC]] THEN
    MAP_EVERY X_GEN_TAC [`a:real^M`; `b:real^M`; `c:real^N`; `d:real^N`] THEN
    STRIP_TAC THEN RULE_ASSUM_TAC(REWRITE_RULE[DIMINDEX_FINITE_SUM]) THEN
    ASM_CASES_TAC `k <= dimindex(:M)` THENL
     [FIRST_X_ASSUM(CONJUNCTS_THEN2
       (MP_TAC o SPECL
         [`a:real^M`;
          `(lambda i. if i = k then min (b$k) l else (b:real^M)$i):real^M`;
          `c:real^N`; `d:real^N`])
       (MP_TAC o SPECL
         [`(lambda i. if i = k then max (a$k) l else (a:real^M)$i):real^M`;
          `b:real^M`; `c:real^N`; `d:real^N`])) THEN
      ASM_SIMP_TAC[GSYM INTERVAL_SPLIT; GSYM PCROSS_INTERVAL; PCROSS] THEN
      SUBGOAL_THEN
       `!P Q. { pastecart (x:real^M) (y:real^N) |
                x IN interval[a,b] INTER {x | P (x$k)} /\ Q y} =
              {pastecart x y | x IN interval[a,b] /\ Q y} INTER {x | P (x$k)}`
       (fun th -> REWRITE_TAC[th])
      THENL
       [REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_PASTECART_THM;
                    IN_INTER] THEN
        ASM_SIMP_TAC[pastecart; IN_ELIM_THM; LAMBDA_BETA; DIMINDEX_FINITE_SUM;
                     ARITH_RULE `i:num <= m ==> i <= m + n`] THEN
        MESON_TAC[];
        ALL_TAC] THEN
      REWRITE_TAC[REWRITE_RULE[PCROSS] PCROSS_INTERVAL] THEN
      ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER u SUBSET t INTER u`] THEN
      ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER u SUBSET t`] THEN
      MATCH_MP_TAC(NORM_ARITH
       `y = y1 + y2 /\ x = x1 + x2 /\ e = e1 + e2
        ==> norm(y2 - x2:real^N) <= e2 ==> norm(y1 - x1) <= e1
            ==> norm(y - x) <= e`) THEN
      REPEAT CONJ_TAC THENL
       [MATCH_MP_TAC(SIMP_RULE[GSYM INTERVAL_SPLIT] INTEGRAL_SPLIT) THEN
        ASM_SIMP_TAC[DIMINDEX_FINITE_SUM;
                     ARITH_RULE `i:num <= m ==> i <= m + n`] THEN
        ASM_MESON_TAC[INTEGRABLE_CONTINUOUS; CONTINUOUS_ON_SUBSET];
        MATCH_MP_TAC(SIMP_RULE[GSYM INTERVAL_SPLIT] INTEGRAL_SPLIT) THEN
        ASM_REWRITE_TAC[] THEN MATCH_MP_TAC lemma2 THEN
        ASM_MESON_TAC[CONTINUOUS_ON_SUBSET];
        REWRITE_TAC[GSYM REAL_ADD_LDISTRIB] THEN AP_TERM_TAC THEN
        MATCH_MP_TAC CONTENT_SPLIT THEN
        ASM_REWRITE_TAC[DIMINDEX_FINITE_SUM]];
      FIRST_X_ASSUM(CONJUNCTS_THEN2
       (MP_TAC o SPECL
         [`a:real^M`; `b:real^M`; `c:real^N`;
          `(lambda i. if i = k - dimindex(:M)
                      then min (d$(k - dimindex(:M))) l
                      else (d:real^N)$i):real^N`])
       (MP_TAC o SPECL
         [`a:real^M`; `b:real^M`;
          `(lambda i. if i = k - dimindex(:M)
                      then max (c$(k - dimindex(:M))) l
                      else (c:real^N)$i):real^N`;
          `d:real^N`])) THEN
      ASM_SIMP_TAC[GSYM INTERVAL_SPLIT; GSYM PCROSS_INTERVAL; PCROSS;
                ARITH_RULE `~(i <= m) ==> 1 <= i - m`;
                ARITH_RULE `~(i <= m) /\ i:num <= m + n ==> i - m <= n`] THEN
      SUBGOAL_THEN
       `!P Q. { pastecart (x:real^M) (y:real^N) |
              P x /\ y IN interval[c,d] INTER {y | Q (y$(k - dimindex(:M)))}} =
              {pastecart x y | P x /\ y IN interval[c,d]} INTER
              {x | Q (x$k)}`
       (fun th -> REWRITE_TAC[th])
      THENL
       [REWRITE_TAC[EXTENSION; FORALL_PASTECART; IN_ELIM_PASTECART_THM;
                    IN_INTER] THEN
        ASM_SIMP_TAC[pastecart; IN_ELIM_THM; LAMBDA_BETA;
                     DIMINDEX_FINITE_SUM] THEN
        MESON_TAC[];
        ALL_TAC] THEN
      REWRITE_TAC[REWRITE_RULE[PCROSS] PCROSS_INTERVAL] THEN
      ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER u SUBSET t INTER u`] THEN
      ASM_SIMP_TAC[SET_RULE `s SUBSET t ==> s INTER u SUBSET t`] THEN
      MATCH_MP_TAC(NORM_ARITH
       `y = y1 + y2 /\ x = x1 + x2 /\ e = e1 + e2
        ==> norm(y2 - x2:real^N) <= e2 ==> norm(y1 - x1) <= e1
            ==> norm(y - x) <= e`) THEN
      REPEAT CONJ_TAC THENL
       [MATCH_MP_TAC(SIMP_RULE[GSYM INTERVAL_SPLIT] INTEGRAL_SPLIT) THEN
        ASM_SIMP_TAC[DIMINDEX_FINITE_SUM;
                     ARITH_RULE `i:num <= m ==> i <= m + n`] THEN
        ASM_MESON_TAC[INTEGRABLE_CONTINUOUS; CONTINUOUS_ON_SUBSET];
        W(MP_TAC o PART_MATCH (rand o rand) INTEGRAL_ADD o rand o snd) THEN
        REWRITE_TAC[] THEN ANTS_TAC THENL
         [ASM_SIMP_TAC[INTERVAL_SPLIT; DIMINDEX_FINITE_SUM;
                 ARITH_RULE `~(i <= m) ==> 1 <= i - m`;
                 ARITH_RULE `~(i <= m) /\ i:num <= m + n ==> i - m <= n`] THEN
          CONJ_TAC THEN MATCH_MP_TAC lemma2 THEN
          MATCH_MP_TAC CONTINUOUS_ON_SUBSET THEN
          EXISTS_TAC `s:real^(M,N)finite_sum->bool` THEN
          ASM_REWRITE_TAC[] THEN FIRST_X_ASSUM(MATCH_MP_TAC o
             MATCH_MP (REWRITE_RULE[IMP_CONJ_ALT] SUBSET_TRANS)) THEN
          REWRITE_TAC[SUBSET_INTERVAL] THEN DISCH_THEN(K ALL_TAC) THEN
          ASM_SIMP_TAC[pastecart; LAMBDA_BETA; DIMINDEX_FINITE_SUM;
                  ARITH_RULE `~(i <= m) ==> 1 <= i - m`;
                  ARITH_RULE `~(i <= m) /\ i:num <= m + n ==> i - m <= n`] THEN
          REPEAT STRIP_TAC THEN
          REPEAT(COND_CASES_TAC THEN ASM_REWRITE_TAC[REAL_LE_REFL]) THEN
          REAL_ARITH_TAC;
          DISCH_THEN(SUBST1_TAC o SYM) THEN MATCH_MP_TAC INTEGRAL_EQ THEN
          X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[] THEN
          MATCH_MP_TAC(SIMP_RULE[GSYM INTERVAL_SPLIT] INTEGRAL_SPLIT) THEN
          CONJ_TAC THENL [ALL_TAC; ASM_ARITH_TAC] THEN
          MATCH_MP_TAC lemma1 THEN ASM_MESON_TAC[CONTINUOUS_ON_SUBSET]];
        REWRITE_TAC[GSYM REAL_ADD_LDISTRIB] THEN AP_TERM_TAC THEN
        MATCH_MP_TAC CONTENT_SPLIT THEN
        ASM_REWRITE_TAC[DIMINDEX_FINITE_SUM]]]) in
  REPEAT STRIP_TAC THEN ASM_CASES_TAC
   `content(interval[pastecart(a:real^M) (c:real^N),pastecart b d]) = &0` THEN
  ASM_SIMP_TAC[INTEGRAL_NULL] THEN
  RULE_ASSUM_TAC(REWRITE_RULE[CONTENT_PASTECART]) THEN
  RULE_ASSUM_TAC(REWRITE_RULE[REAL_ENTIRE; DE_MORGAN_THM]) THENL
   [FIRST_X_ASSUM DISJ_CASES_TAC THEN
    ASM_SIMP_TAC[INTEGRAL_NULL; INTEGRAL_0];
    ALL_TAC] THEN
  SUBGOAL_THEN
   `&0 < content(interval[pastecart(a:real^M) (c:real^N),pastecart b d])`
  ASSUME_TAC THENL
   [ASM_REWRITE_TAC[CONTENT_LT_NZ; CONTENT_PASTECART; REAL_ENTIRE];
    ALL_TAC] THEN
  ONCE_REWRITE_TAC[GSYM VECTOR_SUB_EQ] THEN
  ONCE_REWRITE_TAC[GSYM NORM_EQ_0] THEN
  MATCH_MP_TAC(MESON[REAL_ARITH
   `~(x = &0) ==> &0 < abs x / &2 /\ ~(abs x <= abs x / &2)`]
   `(!e. &0 < e ==> abs x <= e) ==> x = &0`) THEN
  X_GEN_TAC `e:real` THEN DISCH_TAC THEN REWRITE_TAC[REAL_ABS_NORM] THEN
  MP_TAC(ISPECL
   [`f:real^(M,N)finite_sum->real^P`;
    `e / content(interval[pastecart(a:real^M) (c:real^N),pastecart b d])`;
    `interval[pastecart(a:real^M) (c:real^N),pastecart b d]`]
   lemma3) THEN
  ASM_SIMP_TAC[REAL_LT_DIV] THEN DISCH_THEN(MP_TAC o MATCH_MP
   (REWRITE_RULE[IMP_CONJ] OPERATIVE_DIVISION_AND)) THEN
  REWRITE_TAC[] THEN
  FIRST_ASSUM(MP_TAC o MATCH_MP (REWRITE_RULE[IMP_CONJ]
    COMPACT_UNIFORMLY_CONTINUOUS)) THEN
  REWRITE_TAC[COMPACT_INTERVAL; uniformly_continuous_on] THEN
  DISCH_THEN(MP_TAC o SPEC
    `e / &2 /
     content(interval[pastecart(a:real^M) (c:real^N),pastecart b d])`) THEN
  ASM_SIMP_TAC[dist; REAL_HALF; REAL_LT_DIV] THEN
  DISCH_THEN(X_CHOOSE_THEN `k:real` STRIP_ASSUME_TAC) THEN
  SUBGOAL_THEN
   `?p. p tagged_division_of
        interval[pastecart(a:real^M) (c:real^N),pastecart b d] /\
        (\x. ball(x,k)) fine p`
  STRIP_ASSUME_TAC THENL
   [ASM_MESON_TAC[FINE_DIVISION_EXISTS; GAUGE_BALL]; ALL_TAC] THEN
  DISCH_THEN(MP_TAC o SPEC
  `IMAGE SND (p:real^(M,N)finite_sum#(real^(M,N)finite_sum->bool)->bool)`) THEN
  DISCH_THEN(MP_TAC o SPECL
   [`pastecart(a:real^M) (c:real^N)`; `pastecart(b:real^M) (d:real^N)`]) THEN
  ASM_SIMP_TAC[DIVISION_OF_TAGGED_DIVISION] THEN
  REWRITE_TAC[FORALL_IN_IMAGE; FORALL_PAIR_THM] THEN
  MATCH_MP_TAC(TAUT `(b ==> c) /\ a ==> (a <=> b) ==> c`) THEN CONJ_TAC THENL
   [DISCH_THEN(MP_TAC o SPECL
     [`a:real^M`; `b:real^M`; `c:real^N`; `d:real^N`]) THEN
    ASM_SIMP_TAC[REAL_DIV_RMUL; REAL_LT_IMP_NZ; SUBSET_REFL];
    ALL_TAC] THEN
  MAP_EVERY X_GEN_TAC
   [`t:real^(M,N)finite_sum`; `l:real^(M,N)finite_sum->bool`] THEN
  DISCH_TAC THEN
  FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [TAGGED_DIVISION_OF]) THEN
  DISCH_THEN(MP_TAC o SPECL
    [`t:real^(M,N)finite_sum`; `l:real^(M,N)finite_sum->bool`] o
     el 1 o CONJUNCTS) THEN
  ASM_REWRITE_TAC[] THEN
  DISCH_THEN(REPEAT_TCL CONJUNCTS_THEN ASSUME_TAC) THEN
  ASM_REWRITE_TAC[] THEN
  MAP_EVERY X_GEN_TAC [`u:real^M`; `v:real^M`; `w:real^N`; `z:real^N`] THEN
  STRIP_TAC THEN FIRST_X_ASSUM(MP_TAC o GEN_REWRITE_RULE I [fine]) THEN
  REWRITE_TAC[SUBSET; IN_BALL; dist] THEN DISCH_TAC THEN
  MP_TAC(ISPECL
   [`u:real^M`; `v:real^M`; `w:real^N`; `z:real^N`;
    `(f:real^(M,N)finite_sum->real^P) t`]
   INTEGRAL_PASTECART_CONST) THEN
  MATCH_MP_TAC(NORM_ARITH
   `norm(x - x') <= e / &2 /\ norm(y - y') <= e / &2
    ==> x':real^P = y' ==> norm(x - y) <= e`) THEN
  REWRITE_TAC[REAL_ARITH `(e / c * d) / &2 = e / &2 / c * d`] THEN
  CONJ_TAC THENL
   [MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN
    EXISTS_TAC `\y. (f:real^(M,N)finite_sum->real^P) y - f t` THEN
    ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; REAL_LT_IMP_LE] THEN CONJ_TAC THENL
     [MATCH_MP_TAC HAS_INTEGRAL_SUB THEN
      REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL; INTEGRABLE_CONST] THEN
      ASM_MESON_TAC[INTEGRABLE_CONTINUOUS; INTEGRABLE_ON_SUBINTERVAL];
      X_GEN_TAC `y:real^(M,N)finite_sum` THEN DISCH_TAC THEN
      MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
      MATCH_MP_TAC(TAUT `(a /\ b) /\ (a /\ b ==> c) ==> a /\ b /\ c`) THEN
      CONJ_TAC THENL [ASM SET_TAC[]; ASM_MESON_TAC[NORM_SUB; SUBSET]]];
    GEN_REWRITE_TAC (RAND_CONV o RAND_CONV) [CONTENT_PASTECART] THEN
    ONCE_REWRITE_TAC[REAL_ARITH `a * b * c:real = (a * c) * b`] THEN
    MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN EXISTS_TAC
     `\x. integral (interval [w,z]) (\y. f (pastecart x y)) -
           integral (interval [w,z])
                    (\y. (f:real^(M,N)finite_sum->real^P) t)` THEN
    REPEAT CONJ_TAC THENL
     [MATCH_MP_TAC REAL_LE_MUL THEN REWRITE_TAC[CONTENT_POS_LE] THEN
      ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; REAL_LT_IMP_LE];
      MATCH_MP_TAC HAS_INTEGRAL_SUB THEN
      REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL; INTEGRABLE_CONST] THEN
      MATCH_MP_TAC lemma2 THEN ASM_MESON_TAC[CONTINUOUS_ON_SUBSET];
      X_GEN_TAC `x:real^M` THEN DISCH_TAC THEN REWRITE_TAC[] THEN
      MATCH_MP_TAC HAS_INTEGRAL_BOUND THEN EXISTS_TAC
       `\y. (f:real^(M,N)finite_sum->real^P) (pastecart x y) - f t` THEN
      ASM_SIMP_TAC[REAL_HALF; REAL_LT_DIV; REAL_LT_IMP_LE] THEN
      CONJ_TAC THENL
       [MATCH_MP_TAC HAS_INTEGRAL_SUB THEN
        REWRITE_TAC[GSYM HAS_INTEGRAL_INTEGRAL; INTEGRABLE_CONST] THEN
        MATCH_MP_TAC lemma1 THEN ASM_MESON_TAC[CONTINUOUS_ON_SUBSET; SUBSET];
        X_GEN_TAC `s:real^N` THEN DISCH_TAC THEN
        MATCH_MP_TAC REAL_LT_IMP_LE THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
        REPEAT CONJ_TAC THENL
         [ASM SET_TAC[];
          FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
           `s SUBSET t ==> x IN s ==> x IN t`)) THEN
          ASM_REWRITE_TAC[GSYM PCROSS_INTERVAL; PCROSS;
                          IN_ELIM_PASTECART_THM];
          RULE_ASSUM_TAC(REWRITE_RULE[IMP_IMP; RIGHT_IMP_FORALL_THM]) THEN
          ONCE_REWRITE_TAC[NORM_SUB] THEN FIRST_X_ASSUM MATCH_MP_TAC THEN
          EXISTS_TAC `l:real^(M,N)finite_sum->bool` THEN
          ASM_REWRITE_TAC[] THEN
          FIRST_X_ASSUM(MATCH_MP_TAC o MATCH_MP (SET_RULE
           `s SUBSET t ==> x IN s ==> x IN t`)) THEN
          ASM_REWRITE_TAC[GSYM PCROSS_INTERVAL; PCROSS;
                          IN_ELIM_PASTECART_THM]]]]]);;